Architecture: TODO-Based Execution Plan Architecture
Date: 2025-11-05
How It Worksβ
1. Prompt Changes (prompt_config.deep_agent.yaml)β
Old Workflow:
1. Stream text-based execution plan with β¦...β§ markers
2. [Agent could complete here without calling tools! β]
3. Call agents/tools
4. Create TODOs
5. Update TODOs
New Workflow:
1. Call write_todos immediately (forces tool execution β
)
2. Execute tasks
3. Update TODOs with merge=true
4. Synthesize results
2. Agent Binding Changes (agent.py)β
When write_todos tool completes:
-
Initial plan (merge=False, has pending/in_progress items) β Emitted as
execution_plan_updateartifact β Clients display in execution plan panel -
TODO updates (merge=true, status changes) β Emitted as
execution_plan_status_updateartifact β Clients update execution plan panel in-place (no new chat messages)
# In agent.py ToolMessage handler
if tool_name == "write_todos":
if is_initial_plan:
yield {
"artifact": {
"name": "execution_plan_update",
"description": "TODO-based execution plan",
"text": tool_content
}
}
else:
# Status update - client updates execution plan in-place
yield {
"artifact": {
"name": "execution_plan_status_update",
"description": "TODO progress update",
"text": tool_content
}
}
3. Client Compatibilityβ
agent-chat-cli:
- Still looks for
execution_plan_updateartifact β - Displays in cyan Panel with "π― Execution Plan" title β
- No changes needed
agent-forge:
- Still looks for
execution_plan_updateartifact β - Displays in execution plan panel β
- No changes needed
Example Flowβ
User Queryβ
"show PRs in cnoe-io/ai-platform-engineering and tabulate status"
Agent Responseβ
Step 1: Immediate tool call (write_todos)
write_todos(
merge=False,
todos=[
{"id": "1", "content": "Query GitHub for PR information", "status": "in_progress"},
{"id": "2", "content": "Tabulate results", "status": "pending"},
{"id": "3", "content": "Synthesize findings", "status": "pending"}
]
)
Client displays (execution plan panel):
π Execution Plan
- π Query GitHub for PR information
- βΈοΈ Tabulate results
- βΈοΈ Synthesize findings
Step 2: Execute first task
github(query="list PRs in cnoe-io/ai-platform-engineering")
Step 3: Update TODOs
write_todos(
merge=True,
todos=[
{"id": "1", "content": "Query GitHub for PR information", "status": "completed"},
{"id": "2", "content": "Tabulate results", "status": "in_progress"},
{"id": "3", "content": "Synthesize findings", "status": "pending"}
]
)
Client displays (execution plan panel updates in-place):
π― Execution Plan
- β
Query GitHub for PR information
- π Tabulate results
- βΈοΈ Synthesize findings
Note: The execution plan panel updates in-place using ANSI escape codes. No new messages appear in the main chat for status updates.
Implementation Filesβ
-
Prompt:
charts/ai-platform-engineering/data/prompt_config.deep_agent.yaml- Enforces TODO-first workflow
- Provides clear examples
-
Deep Agent:
ai_platform_engineering/multi_agents/platform_engineer/deep_agent.py- Simplified architecture (no post_model_hook needed)
- TODOs enforce tool execution naturally
-
A2A Binding:
ai_platform_engineering/multi_agents/platform_engineer/protocol_bindings/a2a/agent.py- Detects initial TODO creation vs status updates
- Emits initial plan as
execution_plan_updateartifact - Emits status updates as
execution_plan_status_updateartifact
-
agent-chat-cli:
agent_chat_cli/a2a_client.pyβ UPDATED- Handles
execution_plan_update(initial display) - Handles
execution_plan_status_update(in-place updates with ANSI codes) - Clean separation of execution plan vs content
- Handles
-
agent-forge:
workspaces/agent-forge/plugins/agent-forge/src/components/AgentForgePage.tsxβ³ NEEDS UPDATE- Already handles
execution_plan_update - Needs to handle
execution_plan_status_updateto update execution plan buffer in-place - Similar approach: update state without adding new message
- Already handles
Relatedβ
- Spec: spec.md