Current behavior
OrchestratorNode.__call__ builds the orchestrator's prompt from the wrong field, and only uses one of the two prompt files:
https://github.com/extra-org/extra/blob/main/src/agent_engine/engine/langgraph/nodes.py#L535
base_prompt = load_file(self._base_dir, self._spec.prompts.system) or self._spec.description
Per the documented contract (docs/PROMPT_RENDERING.md), an orchestrator node has two distinct, complementary prompt files:
| Field |
Purpose |
Required |
system |
node behavior/persona |
no |
orchestrator |
routing instructions |
yes |
Both are meant to be attached to the LLM call. Instead, the code only ever reads .system and falls back to the one-line YAML description when it's empty — .orchestrator (the required routing-instructions file) is never read at all, and .system and .orchestrator are never combined.
Since most orchestrator configs (see examples/enterprise-knowledge-assistant/agents.yaml) set both system and orchestrator files, in practice: system.md content silently replaces orchestrator.md content, and the routing instructions the orchestrator actually needs are dropped entirely, with no error or warning.
For contrast, AgentNode (nodes.py:187) correctly uses self._spec.prompts.system, since agents only have one prompt field (system). Looks like this orchestrator branch was copy-pasted from the agent branch without accounting for the orchestrator's two-prompt shape.
Steps to reproduce
- Define an orchestrator node in
agent.yml with a description, a prompts.system file, and a prompts.orchestrator file, e.g.:
orchestrators:
research_router:
description: "Routes research queries"
prompts:
system: prompts/research_router/system.md
orchestrator: prompts/research_router/orchestrator.md
- Put distinct, identifiable content in each file (e.g. persona text in
system.md, routing rules in orchestrator.md).
- Run the graph and inspect the system prompt actually sent to the orchestrator's LLM call (or log
base_prompt in OrchestratorNode.__call__).
- Observe only
system.md's content appears (or description, if system isn't set) — orchestrator.md's routing instructions never appear anywhere in the prompt.
Goal
OrchestratorNode.__call__ should load both self._spec.prompts.system and self._spec.prompts.orchestrator and combine them into the final prompt (plus _ORCHESTRATOR_CONTRACT), not read one instead of the other. description should remain only as a last-resort fallback when neither prompt file is configured.
Current behavior
OrchestratorNode.__call__builds the orchestrator's prompt from the wrong field, and only uses one of the two prompt files:https://github.com/extra-org/extra/blob/main/src/agent_engine/engine/langgraph/nodes.py#L535
Per the documented contract (
docs/PROMPT_RENDERING.md), an orchestrator node has two distinct, complementary prompt files:systemorchestratorBoth are meant to be attached to the LLM call. Instead, the code only ever reads
.systemand falls back to the one-line YAMLdescriptionwhen it's empty —.orchestrator(the required routing-instructions file) is never read at all, and.systemand.orchestratorare never combined.Since most orchestrator configs (see
examples/enterprise-knowledge-assistant/agents.yaml) set bothsystemandorchestratorfiles, in practice:system.mdcontent silently replacesorchestrator.mdcontent, and the routing instructions the orchestrator actually needs are dropped entirely, with no error or warning.For contrast,
AgentNode(nodes.py:187) correctly usesself._spec.prompts.system, since agents only have one prompt field (system). Looks like this orchestrator branch was copy-pasted from the agent branch without accounting for the orchestrator's two-prompt shape.Steps to reproduce
agent.ymlwith adescription, aprompts.systemfile, and aprompts.orchestratorfile, e.g.:system.md, routing rules inorchestrator.md).base_promptinOrchestratorNode.__call__).system.md's content appears (ordescription, ifsystemisn't set) —orchestrator.md's routing instructions never appear anywhere in the prompt.Goal
OrchestratorNode.__call__should load bothself._spec.prompts.systemandself._spec.prompts.orchestratorand combine them into the final prompt (plus_ORCHESTRATOR_CONTRACT), not read one instead of the other.descriptionshould remain only as a last-resort fallback when neither prompt file is configured.