Agent Orchestration
Relevant source files
The following files were used as context for generating this wiki page:
- server/agents/interaction_agent/agent.py
- server/agents/interaction_agent/runtime.py
- server/agents/interaction_agent/tools.py
- server/agents/execution_agent/agent.py
- server/agents/execution_agent/runtime.py
- server/agents/execution_agent/batch_manager.py
- server/services/execution/log_store.py
- server/services/conversation/log.py
The Agent Orchestration system in OpenPoke is designed as a split-responsibility architecture consisting of an Interaction Agent and multiple Execution Agents. The Interaction Agent serves as the primary interface for the user, handling conversation flow, personality, and task delegation. Execution Agents act as specialized "engines" that perform specific background tasks (such as email processing or reminder management) using a variety of tools.
This dual-layer structure ensures that the user interface remains responsive while complex tasks are processed asynchronously. The orchestration logic manages state persistence via structured XML-tagged logs, concurrent execution of multiple agents, and the synchronization of task results back into the user-facing conversation.
Sources: server/agents/interaction_agent/system_prompt.md, server/agents/execution_agent/system_prompt.md, README.md:4-9
Orchestration Architecture
The orchestration lifecycle is triggered by a user message, which is processed by the InteractionAgentRuntime. This runtime coordinates tool calls and manages the transition between the user conversation and background task execution.
High-Level Component Flow
The following diagram illustrates the flow of a request through the orchestration layers:
The InteractionAgentRuntime uses _run_interaction_loop to iteratively query the LLM until a final response is generated or a maximum of 8 tool iterations is reached.
Sources: server/agents/interaction_agent/runtime.py:53-125, server/agents/execution_agent/batch_manager.py:46-78
Interaction Agent Layer
The Interaction Agent is the central controller. It is responsible for maintaining the "human" voice of the assistant and deciding when specialized help is needed from Execution Agents.
Key Components
| Component | Description | File Reference |
|---|---|---|
InteractionAgentRuntime | Main class managing the LLM interaction loop and tool execution. | runtime.py |
prepare_message_with_history | Bundles conversation transcript, active agents, and current turn for LLM context. | agent.py |
handle_tool_call | Routes LLM tool requests to specific Python functions. | tools.py |
ConversationLog | Persists the user-visible transcript and internal markers (like <wait>). | log.py |
Interaction Toolset
The Interaction Agent has access to a specific set of orchestration tools defined in TOOL_SCHEMAS:
send_message_to_agent: Dispatches instructions to a specialized execution agent.send_message_to_user: Records a message for the user to see.send_draft: Displays an email draft to the user for confirmation.wait: Silently pauses to avoid duplicate responses when a result is already pending.
Sources: server/agents/interaction_agent/tools.py:27-101, server/agents/interaction_agent/agent.py:18-32
Execution Agent Layer
Execution Agents are ephemeral or persistent workers focused on task completion. They do not communicate with the user directly but return results to the Interaction Agent.
Execution Lifecycle
Execution agents follow a "reason-then-act" pattern. The ExecutionAgentRuntime manages an internal loop where the agent can call multiple tools (e.g., searching emails, then drafting a reply) before returning a final summary.
State and Persistence
Each agent maintains its own history in server/data/execution_agents/. This allows agents to have "memory" of previous tasks related to their specific purpose (e.g., a "Job Search" agent remembers which emails it already processed).
| Data Structure | Purpose |
|---|---|
<agent_request> | The initial instruction from the Interaction Agent. |
<agent_action> | A log of a specific tool call initiated by the agent. |
<tool_response> | The raw data returned by a tool (e.g., Gmail API results). |
<agent_response> | The final summary sent back to the orchestrator. |
Sources: server/agents/execution_agent/runtime.py:50-134, server/services/execution/log_store.py:90-115, server/agents/execution_agent/agent.py:65-95
Batch Management and Synchronization
The ExecutionBatchManager coordinates concurrent tasks. If the Interaction Agent triggers multiple send_message_to_agent calls in a single turn, the Batch Manager groups them.
- Registration: Each task is assigned a
request_idand associated with abatch_id. - Execution: Tasks run asynchronously using
asyncio.create_task. - Completion: As each agent finishes, the
_complete_executionmethod decrements the pending count. - Dispatch: When the batch is empty (
pending == 0), the aggregated results are formatted into a single message and sent toInteractionAgentRuntime.handle_agent_message.
Sources: server/agents/execution_agent/batch_manager.py:46-135
Configuration and Implementation Details
API and Models
The orchestration system relies on OpenRouter for LLM completions. Different models can be configured for interaction and execution roles via environment variables.
| Setting | Usage | Default/Example |
|---|---|---|
interaction_agent_model | Handles conversation and delegation. | Configured in .env |
execution_agent_model | Handles tool-use and task execution. | Configured in .env |
MAX_TOOL_ITERATIONS | Prevents infinite loops in LLM tool use. | 8 |
Code Snippet: Tool Routing
The following implementation shows how the system bridges LLM tool calls to Python logic:
# server/agents/interaction_agent/tools.py:176-189
def handle_tool_call(name: str, arguments: Any) -> ToolResult:
"""Handle tool calls from interaction agent."""
if name == "send_message_to_agent":
return send_message_to_agent(**args)
if name == "send_message_to_user":
return send_message_to_user(**args)
if name == "send_draft":
return send_draft(**args)
if name == "wait":
return wait(**args)
Sources: server/agents/interaction_agent/runtime.py:38-51, server/agents/execution_agent/runtime.py:35-48
Conclusion
Agent Orchestration in OpenPoke enables a sophisticated "Manager-Worker" relationship between AI models. By isolating user interaction from technical execution and using a centralized batch manager, the system provides a robust framework for handling multi-step asynchronous tasks like email management and reminders while maintaining a consistent and helpful user experience.