-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add node fallback #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,16 @@ use super::task::{TaskNode, TaskNodeBlock}; | |
| use super::value::ValueNode; | ||
| use serde::Deserialize; | ||
|
|
||
| #[derive(Deserialize, Debug, Clone)] | ||
| pub struct FallbackNode { | ||
| #[serde(default = "fallback_node_id")] | ||
| pub node_id: NodeId, | ||
| } | ||
|
|
||
| fn fallback_node_id() -> NodeId { | ||
| NodeId::from("fallback".to_owned()) | ||
| } | ||
|
|
||
| #[derive(Deserialize, Debug, Clone)] | ||
| #[serde(untagged)] | ||
| pub enum Node { | ||
|
|
@@ -18,6 +28,7 @@ pub enum Node { | |
| Service(ServiceNode), | ||
| Condition(ConditionNode), | ||
| Value(ValueNode), | ||
| FallBack(FallbackNode), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 命名一致性:将枚举变体从 FallBack 重命名为 Fallback 现有命名与其它变体(Task/Subflow/Service/...)不一致。该变体是新公开 API,建议立即更正,避免之后的 API 震荡。 - FallBack(FallbackNode),
+ Fallback(FallbackNode),
@@
- Node::FallBack(fallback) => &fallback.node_id,
+ Node::Fallback(fallback) => &fallback.node_id,
@@
- Node::FallBack(_fallback) => default_concurrency(),
+ Node::Fallback(_fallback) => default_concurrency(),
@@
- Node::FallBack(_) => None,
+ Node::Fallback(_) => None,
@@
- Node::FallBack(_) => true,
+ Node::Fallback(_) => true,
@@
- Node::FallBack(_) => false,
+ Node::Fallback(_) => false,Also applies to: 43-43, 55-55, 66-66, 77-77, 92-92 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| impl Node { | ||
|
|
@@ -29,6 +40,7 @@ impl Node { | |
| Node::Service(service) => &service.node_id, | ||
| Node::Condition(condition) => &condition.node_id, | ||
| Node::Value(value) => &value.node_id, | ||
| Node::FallBack(fallback) => &fallback.node_id, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -40,6 +52,7 @@ impl Node { | |
| Node::Service(service) => service.concurrency, | ||
| Node::Condition(condition) => condition.concurrency, | ||
| Node::Value(_value) => default_concurrency(), | ||
| Node::FallBack(_fallback) => default_concurrency(), | ||
| } | ||
| } | ||
| pub fn inputs_from(&self) -> Option<&Vec<NodeInputFrom>> { | ||
|
|
@@ -50,6 +63,7 @@ impl Node { | |
| Node::Service(service) => service.inputs_from.as_ref(), | ||
| Node::Condition(condition) => condition.inputs_from.as_ref(), | ||
| Node::Value(_) => None, | ||
| Node::FallBack(_) => None, | ||
| } | ||
| } | ||
| pub fn should_ignore(&self) -> bool { | ||
|
|
@@ -60,6 +74,7 @@ impl Node { | |
| Node::Service(service) => service.ignore, | ||
| Node::Condition(condition) => condition.ignore, | ||
| Node::Value(value) => value.ignore, | ||
| Node::FallBack(_) => true, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -74,6 +89,62 @@ impl Node { | |
| Node::Service(_) => false, | ||
| Node::Condition(_) => false, | ||
| Node::Value(_) => false, | ||
| Node::FallBack(_) => false, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| use serde_yaml; | ||
|
|
||
| #[test] | ||
| fn test_fallback_node() { | ||
| let yaml = r#" | ||
| a: c | ||
| "#; | ||
|
|
||
| let node: FallbackNode = serde_yaml::from_str(yaml).unwrap(); | ||
| assert_eq!(node.node_id, NodeId::from("fallback".to_owned())); | ||
| } | ||
|
|
||
|
Comment on lines
+97
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 测试用例应要求显式的 当前用 - let yaml = r#"
- a: c
- "#;
+ let yaml = r#"
+ fallback: {}
+ "#;🤖 Prompt for AI Agents |
||
| #[test] | ||
| fn test_nodes() { | ||
| let yaml = r#" | ||
| - task: example_task | ||
| node_id: example_node | ||
| inputs_from: | ||
| - handle: input_handle | ||
| value: null | ||
| concurrency: 5 | ||
| ignore: false | ||
| - slot: example_slot | ||
| node_id: slot_node | ||
| - service: example_service | ||
| node_id: service_node | ||
| - condition: | ||
| handle: condition_handle | ||
| node_id: condition_node | ||
| - value: | ||
| key: example_key | ||
| value: example_value | ||
| node_id: value_node | ||
| - fallback: | ||
| node_id: fallback_node | ||
| - comment: This is a comment and should be ignored | ||
| "#; | ||
|
|
||
| let nodes: Vec<Node> = serde_yaml::from_str(yaml).unwrap(); | ||
| assert_eq!(nodes.len(), 7); | ||
| assert_eq!(nodes[0].node_id(), &NodeId::from("example_node".to_owned())); | ||
| assert_eq!(nodes[1].node_id(), &NodeId::from("slot_node".to_owned())); | ||
| assert_eq!(nodes[2].node_id(), &NodeId::from("service_node".to_owned())); | ||
| assert_eq!( | ||
| nodes[3].node_id(), | ||
| &NodeId::from("condition_node".to_owned()) | ||
| ); | ||
| assert_eq!(nodes[4].node_id(), &NodeId::from("value_node".to_owned())); | ||
| assert_eq!(nodes[5].node_id(), &NodeId::from("fallback".to_owned())); | ||
| } | ||
|
Comment on lines
+112
to
+149
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. YAML 形状不一致且隐藏配置错误:
建议统一形状并修复断言: - - fallback:
- node_id: fallback_node
- - comment: This is a comment and should be ignored
+ - fallback: {}
+ node_id: fallback_node
@@
- assert_eq!(nodes.len(), 7);
+ assert_eq!(nodes.len(), 6);
@@
- assert_eq!(nodes[5].node_id(), &NodeId::from("fallback".to_owned()));
+ assert_eq!(nodes[5].node_id(), &NodeId::from("fallback_node".to_owned()));🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复:untagged 变体充当“吞掉一切”的兜底,导致任意 YAML 条目都会被反序列化为 Fallback
当前 FallbackNode 只有一个带默认值的字段,且未拒绝未知字段。配合
#[serde(untagged)],它会匹配几乎任何映射(例如测试里的comment: ...),从而静默吞掉拼写错误/未知节点,削弱配置校验,并改变现有变体的匹配优先级。必须要求出现显式的fallback键,且拒绝未知字段,避免误匹配。建议修改如下:
Also applies to: 18-20