Execution Flow
How requests flow through Agent Kernel from user input to agent response: synchronously, streamed, or through queues.
Request Lifecycle
Every execution surface converges on the same core pipeline: ChatService/AgentService → Runtime.run() (or Runtime.stream()) → pre-hooks → Runner → framework → post-hooks → session persistence.
Detailed Flow
1. Request Reception
The request enters through one of the execution surfaces:
- CLI: interactive terminal input
- REST API: HTTP
POST /api/v1/chat(JSON) orPOST /api/v1/chat-multipart(file uploads) - AWS Lambda: API Gateway event routed by the
Lambdahandler - SQS queue: in queue mode, a request message consumed by the agent-runner Lambda or ECS consumer threads
- WebSocket: a message on the configured chat route via AWS API Gateway WebSocket (async/stream modes)
- MCP/A2A: protocol-specific request against the mounted
/mcpor/a2aroutes - Messaging platforms: webhook events from Slack, WhatsApp, Messenger, Instagram, Telegram, Teams, or Gmail
2. Request Building and Agent Resolution
ChatService validates the payload and builds a list of typed requests (AgentRequestText, AgentRequestImage, AgentRequestFile, plus AgentRequestAny entries for any additional context fields). It then selects the agent and session through AgentService:
from agentkernel.core.service import AgentService
service = AgentService()
service.select(name="assistant", session_id="user-123") # loads or creates the session
Under the hood the agent registry lives on the runtime:
from agentkernel.core import Runtime
runtime = Runtime.current()
agent = runtime.agents().get("assistant")
session = runtime.sessions().get("user-123") or runtime.sessions().new("user-123")
If conversation threads are enabled, user_id is required and the thread manager records the user message (and stores any attachments) before the run.
3. Agent Execution
Runtime.run() acquires the session lock, runs the hook pipeline, and delegates to the framework-specific runner:
reply = await runtime.run(agent, session, requests)
- Session lock:
async with sessionserializes concurrent requests per session and makesSession.current()available. - Pre-hooks: agent hooks first, then system hooks (input guardrails, multimodal preprocessing). A pre-hook may rewrite the request list or halt by returning an
AgentReply. Runner.run(): converts requests to the framework's native format, restores framework session state, executes, and converts the result back to anAgentReply(AgentReplyText,AgentReplyImage, orAgentReplyAnyfor structured output).- Post-hooks: system hooks (output guardrails) first, then agent hooks.
- Persistence: the session store saves the session; the volatile cache is cleared in a
finallyblock.
4. Response Return
The reply travels back through the surface it arrived on: JSON body for REST, Lambda response for API Gateway, a message on the output queue in queue mode, or a WebSocket push. Thread-enabled deployments also append the assistant reply to the conversation thread.
Synchronous Flow (Sequence)
Streaming Flow (execution.mode: stream)
With execution.mode: stream, the REST API switches POST /api/v1/chat (and /chat-multipart) to a Server-Sent Events response, driven by Runtime.stream():
- If a pre-hook halts (e.g., an input guardrail trips), the stream yields a single
StreamChunkwitherrorset anddone: true. - Framework support: OpenAI Agents SDK, LangGraph, and Google ADK stream natively. CrewAI and Smolagents raise
NotImplementedErrorin stream mode. - On AWS serverless, the same
StreamChunks are delivered as WebSocketSTREAM_CHUNKmessages instead of SSE; see below.
Queue-Based Flow (AWS)
In queue mode (execution.queues.* configured), the HTTP request and the agent execution are decoupled by SQS FIFO queues. This is the recommended production topology on AWS for both Lambda and ECS:
rest_syncholds the HTTP connection and polls the response store server-side;rest_asyncreturns arequest_idimmediately for the client to poll.- FIFO queues use
MessageGroupId = session_id(per-session ordering) and deduplication IDs; failed messages are retried after the visibility timeout, and dead-letter queues catch messages exceedingmax_receive_count. - See the Queue Mode Guide for retry/DLQ details and ECS threading internals.
WebSocket Flow (AWS Serverless)
In async and stream modes, clients hold a WebSocket connection to API Gateway. Connection IDs are recorded in DynamoDB by a connection-handler Lambda, and replies are pushed back through the still-open socket:
See AWS Serverless Deployment for configuration, authentication, and Terraform wiring.
Mode Selection Cheat Sheet
execution.mode | Transport | Reply delivery | Queues | Response store | Available on |
|---|---|---|---|---|---|
| (unset) / default | HTTP | JSON on the same connection | - | - | Everywhere RESTAPI/CLI runs |
rest_sync | HTTP | JSON on the same connection (server polls store) | Required | Required | AWS Lambda, AWS ECS |
rest_async | HTTP | Client polls with request_id | Required | Required | AWS Lambda, AWS ECS |
async | WebSocket | Single CHAT_RESPONSE push | Optional | Not used | AWS Lambda |
stream | SSE (REST) or WebSocket (AWS serverless) | Token-level StreamChunks | Optional (WebSocket path) | Not used | REST API surfaces; AWS Lambda WebSocket |
Multimodal Flow
When multimodal support is enabled and a request carries images or files, the system pre-hook transforms the request before the agent sees it:
The agent's conversation history stays free of binary data; the auto-registered analyze_attachments tool retrieves stored attachments on demand. See Multimodal.
