feat: multi-error validation, node-kind catalog, graph patch-ops#11
Conversation
Add validate_all(graph) -> Vec<ValidationError> that collects every independent structural error in one pass, and redefine validate() as its first element so the historical fail-fast single-error contract (and all existing tests) is preserved with zero duplication. Also add ValidationError::code() (stable snake_case identifier) and node_id() accessors so a host can build a structured, per-node validation report instead of parsing Display strings. A host validating an author's/agent's graph now surfaces all problems at once — fixing five costs one validate call, not five round-trips.
Add a host-agnostic catalog of NodeKindContract — one per node kind — with config fields, ports, an example node, and authoring gotchas, exposed via all_contracts()/contract_for(kind). Makes the free-form per-kind config shape a machine-readable source of truth instead of prose a downstream host has to maintain by hand. Strictly model-level: opaque fields (tool_call slug, connection_ref) are described as the engine sees them; NodeKindContract::with_note lets a host layer its own facts (what a slug resolves to, output wrapping, which triggers dispatch) without editing the crate.
Add a patch-op layer so a caller can change a WorkflowGraph with a small list of ops instead of re-emitting the whole graph (token-heavy, the tinyhumansai#1 source of dropped-node/mangled-edge regressions). GraphOp: add_node, update_node_config (RFC 7386 merge patch), set_node_name, rename_node (rewires edges), remove_node (drops incident edges), add_edge, remove_edge, set_node_position. apply_ops applies them in order with precise per-op errors ('op 3 (add_edge): ...'), purely structural — validate_all runs after. Host-agnostic: no knowledge of config semantics.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc68254b07
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| summary: "Passthrough today; no config required.".to_string(), | ||
| description: "A passthrough node reserved for structured-output parsing. Requires no \ | ||
| config." | ||
| .to_string(), | ||
| config_fields: vec![], |
There was a problem hiding this comment.
Expose output_parser schema fields in the catalog
When a host or authoring agent relies on contract_for("output_parser"), this contract says the node is only a passthrough and exposes no config fields. The executor in src/nodes/integration/output_parser.rs actually reads config.schema, auto_fix, and connection_ref to perform schema validation/repair, so catalog-driven authors have no way to discover the node's primary behavior and will generate parser nodes that just pass data through. Please list those optional fields and update the description/example accordingly.
Useful? React with 👍 / 👎.
What & why
Three additive, host-agnostic capabilities the OpenHuman host needs to make its Flows product agent-friendly (structured editing, a queryable DSL schema, and all-at-once validation). Each is independent and fully tested; nothing changes existing runtime behaviour.
1.
validate::validate_all— multi-error validationvalidate()stopped at the first structural error, so an author fixing five problems paid five round-trips. Addsvalidate_all(graph) -> Vec<ValidationError>that accumulates every independent error in one pass;validate()is now redefined as its first element, so the historical fail-fast single-error contract (and every existing test) is byte-for-byte preserved. Also addsValidationError::code()(stablesnake_caseid) andnode_id()so a host can build a structured, per-node report instead of parsingDisplaystrings.2.
catalog— typed, queryable node-kind contractsThe per-kind
configshape lived only in prose in downstream hosts. Adds a host-agnosticNodeKindContractper node kind (config fields, ports, an example node, authoring gotchas) viaall_contracts()/contract_for(kind). Strictly model-level — opaque fields (tool_callslug,connection_ref) are described as the engine sees them;NodeKindContract::with_notelets a host layer its own vendor facts without editing the crate (respecting the host-agnostic invariant).3.
graph_ops— structured incremental graph editsAdds a patch-op layer so a caller can change a
WorkflowGraphwith a smallGraphOplist (add_node,update_node_config[RFC 7386 merge-patch],set_node_name,rename_node[rewires edges],remove_node,add_edge,remove_edge,set_node_position) instead of re-emitting the whole graph.apply_opsapplies them in order with precise per-op errors (op 3 (add_edge): …), purely structurally —validate_allruns after.Testing
cargo test --features mock— full lib suite green (adds ~30 tests across the three modules)cargo clippy --all-targetsclean;cargo fmt --checkclean#![forbid(unsafe_code)]/#![warn(missing_docs)]upheldNotes
compile/engine/existingvalidatesemantics.