Investigate: no auto delegation to the crew #99

Closed
opened 2026-06-09 11:54:14 +00:00 by salmaelsoly · 3 comments
Member
No description provided.
rawan self-assigned this 2026-06-11 07:57:03 +00:00
Member

Investigation: no auto delegation to the crew

Summary

The delegation machinery itself is healthy. delegate_task, delegate_parallel, ask_agent, and run_crew all resolve targets and dispatch sub-agents correctly. The reason the main agent never auto-delegates to installed crew specialists is a discovery gap: the agent is instructed to delegate to a named crew member, but at runtime it has no way to learn which crew members exist.

Root cause

  1. The base system prompt (crates/hero_shrimp_engine/src/prompts/agent_minimal_base.md, the "Routing multi-step work to specialised crew agents" section) tells the agent to dispatch via:

    delegate_task { task: "...", agent: "<agent name from agent.list>" }
    

    and explicitly references agent.list ("e.g. local-git-implementer, forgejo-tester").

  2. But agent.list is only a server-side JSON-RPC method (crates/hero_shrimp_server/src/rpc/methods/agent.rs:16). It is not a tool in the engine's LLM tool catalog. The model cannot call it. The catalog exposes delegate_task, delegate_parallel, ask_agent, and run_crew only - none of which lists the installed crew.

  3. No prompt context provider injects the crew roster either. The default PromptContextEngine (crates/hero_shrimp_engine/src/agent_core/agent/agent_options.rs:560-574) registers eleven providers (reality, operator-guidance, active-jobs, work-scope, dream-insight, autonomy-lessons, playbook, memory, project-rules, repo-context, persona). None of them surfaces the loaded agent profiles.

Net effect: the agent is told to "delegate to an agent from agent.list" but never sees that list. It therefore either does the work itself (no delegation) or guesses a name that does not resolve, in which case delegate_task returns unknown agent (delegation_ops.rs:57-67). Either way: no auto delegation to the crew.

What already works (not the bug)

  • delegate_task resolves agent: "<name>" -> runtime.agent_profile(name) and applies the profile's prompt, tool allowlist, and model override.
  • ask_agent resolves a target via the durable registry db.list_agents() with idle-aware load balancing.
  • run_crew runs the fixed Researcher -> Planner -> Executor -> Critic pipeline.
  • Profile loading was previously fixed for bare-string model: values (commit 15c06f4d).

Proposed fix

Add a CrewRosterProvider prompt context provider that injects the installed crew into the system prompt, gated so it is a no-op when there is no crew:

  • Reads the loaded agent profiles via RuntimeContext::global().agent_profiles().
  • Renders only when delegate_task is present in the active tool slice and at least one crew profile is installed.
  • Emits a short section listing each specialist (name, role/extends, description) plus a one-line reminder to dispatch via delegate_task { agent: "<name>" }.
  • Returns None when no crew is installed, so single-agent behaviour is unchanged.
  • Registered in PromptContextEngine::default().

This closes the discovery gap so the routing guidance in agent_minimal_base.md becomes actionable, and replaces the dangling agent.list reference with a roster the model can actually see.

## Investigation: no auto delegation to the crew ### Summary The delegation machinery itself is healthy. `delegate_task`, `delegate_parallel`, `ask_agent`, and `run_crew` all resolve targets and dispatch sub-agents correctly. The reason the main agent never auto-delegates to installed crew specialists is a **discovery gap**: the agent is instructed to delegate to a named crew member, but at runtime it has no way to learn which crew members exist. ### Root cause 1. The base system prompt (`crates/hero_shrimp_engine/src/prompts/agent_minimal_base.md`, the "Routing multi-step work to specialised crew agents" section) tells the agent to dispatch via: ``` delegate_task { task: "...", agent: "<agent name from agent.list>" } ``` and explicitly references `agent.list` ("e.g. local-git-implementer, forgejo-tester"). 2. But `agent.list` is only a **server-side JSON-RPC method** (`crates/hero_shrimp_server/src/rpc/methods/agent.rs:16`). It is **not** a tool in the engine's LLM tool catalog. The model cannot call it. The catalog exposes `delegate_task`, `delegate_parallel`, `ask_agent`, and `run_crew` only - none of which lists the installed crew. 3. No prompt context provider injects the crew roster either. The default `PromptContextEngine` (`crates/hero_shrimp_engine/src/agent_core/agent/agent_options.rs:560-574`) registers eleven providers (reality, operator-guidance, active-jobs, work-scope, dream-insight, autonomy-lessons, playbook, memory, project-rules, repo-context, persona). None of them surfaces the loaded agent profiles. **Net effect:** the agent is told to "delegate to an agent from `agent.list`" but never sees that list. It therefore either does the work itself (no delegation) or guesses a name that does not resolve, in which case `delegate_task` returns `unknown agent` (`delegation_ops.rs:57-67`). Either way: no auto delegation to the crew. ### What already works (not the bug) - `delegate_task` resolves `agent: "<name>"` -> `runtime.agent_profile(name)` and applies the profile's prompt, tool allowlist, and model override. - `ask_agent` resolves a target via the durable registry `db.list_agents()` with idle-aware load balancing. - `run_crew` runs the fixed Researcher -> Planner -> Executor -> Critic pipeline. - Profile loading was previously fixed for bare-string `model:` values (commit 15c06f4d). ### Proposed fix Add a `CrewRosterProvider` prompt context provider that injects the installed crew into the system prompt, gated so it is a no-op when there is no crew: - Reads the loaded agent profiles via `RuntimeContext::global().agent_profiles()`. - Renders only when `delegate_task` is present in the active tool slice **and** at least one crew profile is installed. - Emits a short section listing each specialist (name, role/`extends`, description) plus a one-line reminder to dispatch via `delegate_task { agent: "<name>" }`. - Returns `None` when no crew is installed, so single-agent behaviour is unchanged. - Registered in `PromptContextEngine::default()`. This closes the discovery gap so the routing guidance in `agent_minimal_base.md` becomes actionable, and replaces the dangling `agent.list` reference with a roster the model can actually see.
Member

Fix implemented: crew roster now injected into the system prompt

Closed the discovery gap identified in the investigation above. The agent now sees the installed crew at runtime, so the delegation guidance in agent_minimal_base.md is actionable and auto delegation can actually happen.

Changes

  • crates/hero_shrimp_engine/src/agent_core/agent/context_providers.rs

    • New CrewRosterProvider prompt context provider. It discovers installed specialists from the loaded profile store (RuntimeContext::global().agent_profiles() — the same set delegate_task { agent: <name> } resolves against) and injects an [installed crew] section listing each specialist by exact dispatch name, role, and description, with a one-line instruction to delegate via delegate_task.
    • The gating + formatting live in a pure helper build_crew_roster_body(has_delegate_task, entries) so the no-op guarantees are unit tested.
    • Emits nothing when delegate_task is not in the active tool slice, or when no crew is installed — single-agent setups are unchanged.
  • crates/hero_shrimp_engine/src/agent_core/agent/agent_options.rs

    • Registered CrewRosterProvider in PromptContextEngine::default() (priority 22, right after persona) and added it to the provider import list.

Tests

Added a crew_roster_tests module covering the behaviour:

  • no_section_when_delegate_task_unavailable — no roster when the agent cannot delegate.
  • no_section_when_no_crew_installed — no roster when nothing is installed (single-agent unchanged).
  • lists_each_specialist_with_delegate_instruction — every installed specialist is listed by exact name + role, with the delegate_task instruction.

Test results

  • Targeted: 3 passed, 0 failed (crew_roster_tests).
  • Context providers: 70 passed, 0 failed.
  • Full engine lib suite: 1670 passed, 0 failed, 1 ignored (pre-existing).
  • cargo build -p hero_shrimp_engine: clean.

Notes

  • The delegation machinery (delegate_task, delegate_parallel, ask_agent, run_crew) was already correct and is unchanged.
  • The dangling agent.list reference in the prompt is now backed by a roster the model can actually see. A follow-up could also expose agent.list as a first-class LLM tool for on-demand lookups, but injecting the roster directly is the lower-friction fix and covers the reported behaviour.
  • Changes are not committed or pushed, per the request on this task.
## Fix implemented: crew roster now injected into the system prompt Closed the discovery gap identified in the investigation above. The agent now sees the installed crew at runtime, so the delegation guidance in `agent_minimal_base.md` is actionable and auto delegation can actually happen. ### Changes - `crates/hero_shrimp_engine/src/agent_core/agent/context_providers.rs` - New `CrewRosterProvider` prompt context provider. It discovers installed specialists from the loaded profile store (`RuntimeContext::global().agent_profiles()` — the same set `delegate_task { agent: <name> }` resolves against) and injects an `[installed crew]` section listing each specialist by exact dispatch name, role, and description, with a one-line instruction to delegate via `delegate_task`. - The gating + formatting live in a pure helper `build_crew_roster_body(has_delegate_task, entries)` so the no-op guarantees are unit tested. - Emits nothing when `delegate_task` is not in the active tool slice, or when no crew is installed — single-agent setups are unchanged. - `crates/hero_shrimp_engine/src/agent_core/agent/agent_options.rs` - Registered `CrewRosterProvider` in `PromptContextEngine::default()` (priority 22, right after persona) and added it to the provider import list. ### Tests Added a `crew_roster_tests` module covering the behaviour: - `no_section_when_delegate_task_unavailable` — no roster when the agent cannot delegate. - `no_section_when_no_crew_installed` — no roster when nothing is installed (single-agent unchanged). - `lists_each_specialist_with_delegate_instruction` — every installed specialist is listed by exact name + role, with the `delegate_task` instruction. ### Test results - Targeted: 3 passed, 0 failed (`crew_roster_tests`). - Context providers: 70 passed, 0 failed. - Full engine lib suite: 1670 passed, 0 failed, 1 ignored (pre-existing). - `cargo build -p hero_shrimp_engine`: clean. ### Notes - The delegation machinery (`delegate_task`, `delegate_parallel`, `ask_agent`, `run_crew`) was already correct and is unchanged. - The dangling `agent.list` reference in the prompt is now backed by a roster the model can actually see. A follow-up could also expose `agent.list` as a first-class LLM tool for on-demand lookups, but injecting the roster directly is the lower-friction fix and covers the reported behaviour. - Changes are not committed or pushed, per the request on this task.
Member

Opened PR #110 with the fix (branch int_delegate_crew -> integration, not merged): #110

Root causes addressed: the orchestrator could not see the installed crew (dead agent.list reference, no roster injected), and delegate_task sub-agents never wrote to the crew mailbox so delegated work was invisible in the per-member chat threads. The PR injects the crew roster into both the chat and autonomy prompts and bridges delegations into the crew mailbox.

Opened PR #110 with the fix (branch `int_delegate_crew` -> `integration`, not merged): https://forge.ourworld.tf/lhumina_code/hero_shrimp/pulls/110 Root causes addressed: the orchestrator could not see the installed crew (dead `agent.list` reference, no roster injected), and `delegate_task` sub-agents never wrote to the crew mailbox so delegated work was invisible in the per-member chat threads. The PR injects the crew roster into both the chat and autonomy prompts and bridges delegations into the crew mailbox.
rawan closed this issue 2026-06-11 13:39:31 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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_shrimp#99
No description provided.