fix: agent broken — migrate to service_agent_v3 template #36

Closed
opened 2026-04-17 08:12:44 +00:00 by timur · 0 comments
Owner

Problem

The router agent (router.agent.run) is fully broken after hero_logic's build_node_input() refactor (commit 2c8299f). Edge-mapped outputs are now namespaced under outputs.* instead of flattened to root.

The old service_agent (v1) template uses bare {{code_generation}} which stays literal, causing Python NameError.

Root cause

hero_logic's build_node_input() was restructured:

Old (flat): { "prompt": "...", "code_generation": "<python>" }
New (namespaced): { "inputs": {...}, "outputs": {"code_generation": "<python>"}, "prompt": "..." }

Workflow inputs are still flattened to root, but edge-mapped outputs live only under outputs.*. hero_proc's template engine resolves {{code_generation}} against root — doesn't find it — leaves it literal.

Plan

1. Fix {{var}}{{outputs.var}} in both hero_logic templates

templates/service_agent.json (v1):

  • {{service_selection}}{{outputs.service_selection}}
  • {{code_generation}}{{outputs.code_generation}}
  • {{script_execution}}{{outputs.script_execution}}
  • {{error_output}}{{outputs.error_output}}
  • Leave {{prompt}}, {{scripts_dir}}, {{model}} as-is (workflow inputs, flat at root)

templates/service_agent_v3.json:

  • {{fetch_catalog}}{{outputs.fetch_catalog}}
  • {{service_selection}}{{outputs.service_selection}}
  • {{compile_stubs}}{{outputs.compile_stubs}}
  • {{code_generation}}{{outputs.code_generation}}
  • {{error_output}}{{outputs.error_output}}
  • {{execution_output}}{{outputs.execution_output}}
  • {{debugged_code}}{{outputs.debugged_code}}

2. Migrate hero_router run_agent() to use v3 template

The v3 template is self-contained — fetch_catalog and compile_stubs nodes call the router's Python client directly. The router no longer needs to pre-compute catalog/stubs/interfaces in Rust.

Simplify run_agent() in agent.rs:

  • Remove all Rust-side precomputation: build_service_catalog(), stage_client_library(), get_service_interface()
  • Change template name from "service_agent" to "service_agent_v3"
  • Simplify input_data to just {"prompt": ..., "model": ...}
  • For per-service filter: prepend constraint to prompt string ("Only use service: X")

Update extract_agent_response():

  • Node IDs (service_selection, code_generation, script_execution) are the same in v3
  • Add check for retry_execution node (v3 has error retry loop)
  • For attempts: count both script_execution and retry_execution
  • For raw_result: check retry_execution first, fall back to script_execution

Delete dead code:

  • build_service_catalog() (lines 326-389)
  • stage_client_library() (lines 285-320)
  • get_service_interface() (lines 262-282)
  • Unused python_codegen imports

Verification

# After rebuilding both hero_logic and hero_router:
curl -s --unix-socket ~/hero/var/sockets/hero_router/rpc.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"router.agent.run","params":{"prompt":"List 3 available services","max_retries":1,"model":"openai/gpt-4o-mini"}}'

Expect: success: true, non-empty answer, play_sid pointing to an 8-node v3 play.

Relates to #34

## Problem The router agent (`router.agent.run`) is fully broken after hero_logic's `build_node_input()` refactor (commit `2c8299f`). Edge-mapped outputs are now namespaced under `outputs.*` instead of flattened to root. The old `service_agent` (v1) template uses bare `{{code_generation}}` which stays literal, causing Python `NameError`. ## Root cause hero_logic's `build_node_input()` was restructured: **Old** (flat): `{ "prompt": "...", "code_generation": "<python>" }` **New** (namespaced): `{ "inputs": {...}, "outputs": {"code_generation": "<python>"}, "prompt": "..." }` Workflow inputs are still flattened to root, but edge-mapped outputs live only under `outputs.*`. hero_proc's template engine resolves `{{code_generation}}` against root — doesn't find it — leaves it literal. ## Plan ### 1. Fix `{{var}}` → `{{outputs.var}}` in both hero_logic templates **`templates/service_agent.json` (v1):** - `{{service_selection}}` → `{{outputs.service_selection}}` - `{{code_generation}}` → `{{outputs.code_generation}}` - `{{script_execution}}` → `{{outputs.script_execution}}` - `{{error_output}}` → `{{outputs.error_output}}` - Leave `{{prompt}}`, `{{scripts_dir}}`, `{{model}}` as-is (workflow inputs, flat at root) **`templates/service_agent_v3.json`:** - `{{fetch_catalog}}` → `{{outputs.fetch_catalog}}` - `{{service_selection}}` → `{{outputs.service_selection}}` - `{{compile_stubs}}` → `{{outputs.compile_stubs}}` - `{{code_generation}}` → `{{outputs.code_generation}}` - `{{error_output}}` → `{{outputs.error_output}}` - `{{execution_output}}` → `{{outputs.execution_output}}` - `{{debugged_code}}` → `{{outputs.debugged_code}}` ### 2. Migrate hero_router `run_agent()` to use v3 template The v3 template is self-contained — `fetch_catalog` and `compile_stubs` nodes call the router's Python client directly. The router no longer needs to pre-compute catalog/stubs/interfaces in Rust. **Simplify `run_agent()` in `agent.rs`:** - Remove all Rust-side precomputation: `build_service_catalog()`, `stage_client_library()`, `get_service_interface()` - Change template name from `"service_agent"` to `"service_agent_v3"` - Simplify `input_data` to just `{"prompt": ..., "model": ...}` - For per-service filter: prepend constraint to prompt string ("Only use service: X") **Update `extract_agent_response()`:** - Node IDs (`service_selection`, `code_generation`, `script_execution`) are the same in v3 - Add check for `retry_execution` node (v3 has error retry loop) - For `attempts`: count both `script_execution` and `retry_execution` - For `raw_result`: check `retry_execution` first, fall back to `script_execution` **Delete dead code:** - `build_service_catalog()` (lines 326-389) - `stage_client_library()` (lines 285-320) - `get_service_interface()` (lines 262-282) - Unused `python_codegen` imports ## Verification ```bash # After rebuilding both hero_logic and hero_router: curl -s --unix-socket ~/hero/var/sockets/hero_router/rpc.sock \ -X POST http://localhost/rpc \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"router.agent.run","params":{"prompt":"List 3 available services","max_retries":1,"model":"openai/gpt-4o-mini"}}' ``` Expect: `success: true`, non-empty `answer`, `play_sid` pointing to an 8-node v3 play. Relates to #34
timur changed title from fix: agent broken after hero_logic input namespace change to fix: agent broken — migrate to service_agent_v3 template 2026-04-17 08:18:02 +00:00
timur closed this issue 2026-04-17 09:05:34 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_router#36
No description provided.