Skip to content

fix(flows): reject an unknown agent_ref at author time instead of mid-run#5114

Merged
graycyrus merged 4 commits into
tinyhumansai:mainfrom
graycyrus:fix/flows-validate-agent-ref
Jul 22, 2026
Merged

fix(flows): reject an unknown agent_ref at author time instead of mid-run#5114
graycyrus merged 4 commits into
tinyhumansai:mainfrom
graycyrus:fix/flows-validate-agent-ref

Conversation

@graycyrus

@graycyrus graycyrus commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What & why

A flow agent node picks which agent runs via config.agent_ref (resolved through the registry in tinyflows/caps.rs). Previously an unknown agent_ref was only caught at run timerun_via_registry_fallback hard-errors "unknown agent_ref '…'" mid-run — so the builder could propose/save a graph that's doomed to fail when it executes.

This adds a validate_agent_refs gate to run_builder_gates, so propose / edit / save reject a graph whose agent node references an unregistered agent, naming the bad id. Fail-fast at author time instead of a mid-run capability error.

Behavior

  • agent node with an unknown agent_ref → rejected at propose/save, error names the id.
  • agent node with a real registered agent_ref (built-in harness agent) → passes.
  • Plain agent node with no agent_ref (runs on the default completion) → passes (not rejected).

Note: this is a fail-fast UX improvement — the runtime already hard-errors on an unknown id; this just moves the failure to author time so a bad graph never gets saved.

Tests

Added unit tests for all three cases (unknown → rejected with id, valid → passes, no-agent_ref → passes). flows::ops suite: 194 pass, cargo check clean, cargo fmt clean.

Summary by CodeRabbit

  • Bug Fixes
    • Workflow validation now checks that every specified agent reference resolves successfully (including custom registered agents) and rejects unknown or disabled ones before saving or submission.
    • Invalid agent references are surfaced during author-time validation, avoiding later runtime “unknown agent reference” failures.
    • Agent nodes with no reference (or only whitespace) continue to validate normally.
  • Tests
    • Added coverage for the new agent reference validation behavior, including acceptance and rejection cases.

…-run

A flow `agent` node selects which agent runs via config.agent_ref. Previously
an unknown agent_ref only failed at RUN time (run_via_registry_fallback hard-
errors). Add a validate_agent_refs gate to run_builder_gates so propose/edit/
save reject a graph whose agent node references an unregistered agent, naming
the bad id — fail-fast UX. A plain agent node with no agent_ref, and nodes
referencing a real registered agent, pass.
@graycyrus
graycyrus requested a review from a team July 22, 2026 08:55
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f4e2c525-b385-44f2-a1e1-57e254938c1b

📥 Commits

Reviewing files that changed from the base of the PR and between 14c7134 and 3980ad0.

📒 Files selected for processing (2)
  • src/openhuman/flows/ops.rs
  • src/openhuman/flows/ops_tests.rs

📝 Walkthrough

Walkthrough

Adds asynchronous agent-reference validation to the builder hard-gate pipeline. Agent references resolve to harness agents or enabled custom registry entries; invalid references reject graphs before later validation and persistence. Tests cover blank, known, and unknown references.

Changes

Agent Reference Validation

Layer / File(s) Summary
Agent reference gate integration
src/openhuman/flows/ops.rs, src/openhuman/flows/ops_tests.rs
Adds validate_agent_refs, handles blank, unknown, disabled, and registry-error cases, invokes it before later builder checks, and tests accepted and rejected references.

Estimated code review effort: 4 (Complex) | ~40 minutes

Sequence Diagram(s)

sequenceDiagram
  participant run_builder_gates
  participant validate_agent_refs
  participant CustomAgentRegistry
  run_builder_gates->>validate_agent_refs: Validate agent_ref values in WorkflowGraph
  validate_agent_refs->>CustomAgentRegistry: Look up custom agent entries
  CustomAgentRegistry-->>validate_agent_refs: Return registry result
  validate_agent_refs-->>run_builder_gates: Return errors or continue to later gates
Loading

Possibly related PRs

Suggested labels: bug, agent

Suggested reviewers: senamakel

Poem

I hop through the graph with a reference to check,
Unknown agents stop at the builder’s deck.
Blank ones pass, enabled ones run,
Disabled ones wait beneath the registry sun.
Clear gates let the workflow onward go.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: rejecting invalid agent_ref values during authoring instead of at runtime.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. bug labels Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/openhuman/flows/ops.rs (1)

1239-1293: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Registry lookup reloads config once per RegistryFallback node.

agent_registry::get_agent delegates to list_agents(true), which calls config_rpc::load_config_with_timeout().await on every invocation (see src/openhuman/agent_registry/ops.rs:19-33). A graph with several custom agent_ref nodes therefore triggers N sequential config reads inside this loop. Consider fetching the registry list once (lazily, on the first RegistryFallback hit, to keep the all-Harness/no-custom-ref case free of any config read) and resolving each ref against that cached snapshot, preserving the current per-lookup fail-open behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/flows/ops.rs` around lines 1239 - 1293, Update the
RegistryFallback handling in the flow validation loop to lazily load the
custom-agent registry once on the first such node, cache that snapshot, and
resolve subsequent agent_ref values against it instead of calling
agent_registry::get_agent repeatedly. Keep all-Harness flows free of registry
reads and preserve the current enabled, disabled, unknown, and lookup-error
outcomes, including fail-open behavior when loading the snapshot fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/openhuman/flows/ops.rs`:
- Around line 1239-1293: Update the RegistryFallback handling in the flow
validation loop to lazily load the custom-agent registry once on the first such
node, cache that snapshot, and resolve subsequent agent_ref values against it
instead of calling agent_registry::get_agent repeatedly. Keep all-Harness flows
free of registry reads and preserve the current enabled, disabled, unknown, and
lookup-error outcomes, including fail-open behavior when loading the snapshot
fails.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0d2c3539-b14d-4db9-8d7c-b9d141f2dc1a

📥 Commits

Reviewing files that changed from the base of the PR and between 0eeee12 and 14c7134.

📒 Files selected for processing (1)
  • src/openhuman/flows/ops.rs

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14c7134495

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openhuman/flows/ops.rs Outdated
// `RegistryFallback` "unknown agent_ref" hard error mid-run. Almost always a
// pure in-memory harness-registry lookup; only a ref that ISN'T a harness
// definition falls through to a local config read (custom agent registry).
let agent_ref_errors = validate_agent_refs(graph).await;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the active config when resolving agent refs

When run_builder_gates is reached before the server bootstrap has initialized the global AgentDefinitionRegistry (for example via the generic CLI/RPC path) and the flow uses a valid workspace TOML agent under <workspace>/agents, this call gives validate_agent_refs no Config/workspace to initialize or load definitions from. route_for_agent_ref then sees an empty global registry and falls through to agent_registry::get_agent, which only merges the default/config agent registry entries, so a real harness agent definition can be rejected as an unknown agent_ref even though the runtime would load it from the active workspace. Pass the active config through and resolve against that workspace before rejecting.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in — you're right: validate_agent_refs now takes &Config and defensively calls AgentDefinitionRegistry::init_global (idempotent OnceLock) before resolving refs, so one-shot CLI/RPC paths (where default_state never bootstraps the registry) no longer falsely reject every agent_ref. +tests proving it under the scoped flows::ops filter.

@graycyrus
graycyrus marked this pull request as draft July 22, 2026 09:48
… (codex tinyhumansai#5114)

validate_agent_refs relied on the process-global AgentDefinitionRegistry, which
is NOT initialized on one-shot CLI/RPC paths (default_state never calls
bootstrap_core_runtime) — it would falsely reject every agent_ref there. Now
takes &Config, defensively AgentDefinitionRegistry::init_global (idempotent),
and lazily caches the custom-agent snapshot instead of reloading config per
node (CodeRabbit). +3 unit tests (plain node passes / blank ref absent / harness
ref resolves under defensive init).
@graycyrus
graycyrus marked this pull request as ready for review July 22, 2026 10:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 429bedc887

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

#[tokio::test]
async fn agent_ref_resolving_to_a_harness_definition_is_accepted() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Cover the agent-ref rejection path

The new tests only exercise absent/blank refs and the harness-success path, leaving the newly added RegistryFallback branch that actually rejects unknown or disabled agent_refs unexecuted. Since this repo enforces ≥80% coverage on changed lines, the changed error-construction paths in validate_agent_refs are likely to fail the Rust diff coverage gate, and the main behavior advertised by this fix is not pinned; add at least an unknown-ref test through validate_agent_refs or run_builder_gates.

AGENTS.md reference: AGENTS.md:L86-L88

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c154c2c — added agent_ref_unknown_is_rejected: a graph with an unregistered agent_ref (no_such_agent_xyz) is asserted to be rejected by validate_agent_refs, with the offending id present in the error. That exercises the RegistryFallback error-construction branch the plain/blank/harness tests left uncovered, so the changed error paths are now covered.

)

Add agent_ref_unknown_is_rejected — a graph with an unregistered agent_ref must
be rejected by validate_agent_refs with the offending id named. Exercises the
RegistryFallback error-construction branch the existing plain/blank/harness
tests left uncovered (diff-coverage gate).
…agent-ref

# Conflicts:
#	src/openhuman/flows/ops.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. bug

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant