Skip to main content
Version: 0.8.0

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) or POST /api/v1/chat-multipart (file uploads)
  • AWS Lambda: API Gateway event routed by the Lambda handler
  • 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 /mcp or /a2a routes
  • 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)
  1. Session lock: async with session serializes concurrent requests per session and makes Session.current() available.
  2. 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.
  3. Runner.run(): converts requests to the framework's native format, restores framework session state, executes, and converts the result back to an AgentReply (AgentReplyText, AgentReplyImage, or AgentReplyAny for structured output).
  4. Post-hooks: system hooks (output guardrails) first, then agent hooks.
  5. Persistence: the session store saves the session; the volatile cache is cleared in a finally block.

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 StreamChunk with error set and done: true.
  • Framework support: OpenAI Agents SDK, LangGraph, and Google ADK stream natively. CrewAI and Smolagents raise NotImplementedError in stream mode.
  • On AWS serverless, the same StreamChunks are delivered as WebSocket STREAM_CHUNK messages 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_sync holds the HTTP connection and polls the response store server-side; rest_async returns a request_id immediately 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 exceeding max_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.modeTransportReply deliveryQueuesResponse storeAvailable on
(unset) / defaultHTTPJSON on the same connection--Everywhere RESTAPI/CLI runs
rest_syncHTTPJSON on the same connection (server polls store)RequiredRequiredAWS Lambda, AWS ECS
rest_asyncHTTPClient polls with request_idRequiredRequiredAWS Lambda, AWS ECS
asyncWebSocketSingle CHAT_RESPONSE pushOptionalNot usedAWS Lambda
streamSSE (REST) or WebSocket (AWS serverless)Token-level StreamChunksOptional (WebSocket path)Not usedREST 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.

Ready to Ship Your
First Agent?

Free, open-source, Apache 2.0. No licensing costs, no vendor lock-in. Join hundreds of developers building production AI agents with Agent Kernel.

Agent Kernel
Ask Agent Kernel