Skip to main content
When someone sends a message, your agent follows a series of steps — from receiving the message to sending back a reply. This page walks through that journey.

The message journey

Every message travels through the same pipeline. Here is the full flow from the moment you type a message to the moment you see a reply:

Step by step

Here is what each step means for your message:

1. Message arrives

Your message can come from any connected platform — Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE, or the web dashboard. It does not matter which one. Comis normalizes every message into a common format so your agent sees them all the same way.

2. Queue serializes work

Messages enter a queue that controls the order of processing. The queue serializes work through a concurrency gate so your agent processes messages in a sensible order without getting overwhelmed. See Message Queue for details on per-session lanes and queue modes.

3. Router picks agent

If you run multiple agents, the router checks your routing rules to decide which agent should handle this message. Rules are checked from most specific to least specific — a rule targeting a specific user beats a rule targeting an entire platform. If no rule matches, the default agent handles it.

4. Session loaded

Your agent loads the current conversation. A session tracks the messages exchanged between you and your agent, so it can follow along without starting from scratch each time. Sessions expire after a period of inactivity and start fresh automatically. See Sessions for how conversation tracking works.

5. Identity files loaded

Your agent reads its workspace files — a set of Markdown documents that define who it is. These include its personality (SOUL.md), its name and character (IDENTITY.md), information about you (USER.md), its operating instructions (AGENTS.md), and its role-specific behavior (ROLE.md). This is how your agent knows how to behave.

6. Memories recalled

Before responding, your agent searches its long-term memory for anything relevant to the current conversation. If you talked about a project last week, those notes surface automatically. This is called memory recall — it works like flipping through a filing cabinet of past conversations to find useful context.

7. Agent thinks

With the message, identity, and memories all assembled, the request goes to your configured AI provider (Anthropic, OpenAI, Google, and others). The provider generates a response based on everything your agent knows.

8. Tools (if needed)

Sometimes the agent needs to take action or gather more information. It might search the web, check a calendar, send a message to another channel, or analyze an image. After each tool use, the agent thinks again with the new information. This loop can repeat multiple times until the agent has everything it needs. The number of tool steps is limited by a step counter (default: 150 steps per execution) to prevent runaway loops. See Safety for details.

9. Response sent

Once the agent has a final answer, it formats the response for your platform and sends it back to the same chat where you sent the original message. Platform differences are handled automatically — your agent knows how to format for Discord, Telegram, and every other supported platform.

10. Session saved

The conversation is saved so your agent can pick up where you left off next time. Messages are also processed for long-term memory — important facts and context are stored for future recall. The context engine automatically manages conversation length — trimming old content, masking stale tool results, and summarizing when needed — so your agent’s memory stays efficient without losing important information.

The thinking loop

Steps 7 and 8 — thinking and using tools — deserve a closer look because they form the core of your agent’s intelligence. This is where your agent reasons through a problem, decides whether it needs more information, and takes action. The prompt includes everything: your message, the agent’s identity, recalled memories, and (if this is a follow-up loop) the results from previous tool calls. Before sending to the AI provider, the context engine optimizes what is included — trimming old thinking blocks, windowing history, and masking old tool results to keep costs down. Each trip through this loop counts as one “step.” The default limit is 150 steps, but most conversations only need 1 to 3.

What keeps your agent safe

Throughout this entire process, multiple safety systems are running in the background:
  • Budget limits prevent your agent from using too many tokens (and costing too much money) in a single run, per hour, or per day
  • Circuit breaker acts like a fuse — if the AI provider fails repeatedly, the breaker trips and stops sending requests until the provider recovers
  • Step counter limits how many tool-use loops the agent can run before stopping (default: 150)
These safety features work automatically with sensible defaults. You can adjust them in the Safety settings.

Sub-agent lifecycle

When your agent spawns a sub-agent (using the sessions_spawn tool), the sub-agent goes through its own version of this lifecycle — but with additional context management. The sub-agent receives a structured spawn packet with the task, artifact references, and an optional objective. When it finishes, its result is condensed and formatted before being returned to the parent. See Subagent Context Lifecycle for the complete sub-agent flow.

End-to-end walkthrough

Here is a concrete example: a Telegram user sends “What’s the weather in Tokyo?” to an agent named Atlas. The conversation goes through these stages, and you can verify each one by tailing ~/.comis/logs/comis.log.
# 1. Inbound webhook → channel adapter
INFO  [channel.telegram] message received { chatId: 12345, senderId: 67890, textChars: 28 }

# 2. Queue serializes per session
DEBUG [queue.command] enqueued { lane: "normal", sessionKey: "telegram:67890:12345", depth: 0 }

# 3. Router picks the agent
DEBUG [routing.message-router] resolved agent { agentId: "atlas", binding: "channelType=telegram" }

# 4. Session loaded (or created on first contact)
INFO  [session.lifecycle] loadOrCreate { sessionKey: "telegram:67890:12345", isNew: false, messageCount: 12 }

# 5. Identity files loaded
DEBUG [identity.loader] loaded { agents: true, sizeChars: 8842 }

# 6. RAG memory recall
DEBUG [rag.retriever] retrieved { hits: 3, contextChars: 1240, durationMs: 45 }

# 7-8. Agent thinks → tools → thinks (the loop)
DEBUG [executor.prompt-runner] runPrompt start { agentId: "atlas", model: "claude-sonnet-4-5-20250929" }
DEBUG [executor.tool] tool call { toolName: "web_search", args: { query: "Tokyo weather today" } }
DEBUG [executor.tool] tool result { toolName: "web_search", durationMs: 1340, sizeChars: 2100 }
DEBUG [executor.prompt-runner] turn complete { tokensIn: 9450, tokensOut: 312, cacheRead: 8800 }

# 9. Response sent to channel
INFO  [delivery.queue] delivered { channelType: "telegram", chatId: 12345, messageId: "abc", durationMs: 187 }

# 10. Session saved + post-execution
INFO  [executor.post] execution complete { agentId: "atlas", toolCalls: 1, totalCost: 0.0042, durationMs: 2150 }
Each line corresponds to one stage in the diagram above. Stages 7-8 (the thinking loop) repeat once per tool call — a simple weather lookup uses one tool call; a complex research task may use 5-10.

Behind the scenes

The pipeline is implemented as a series of components in packages/agent:
StageComponentSource path
QueueCommandQueuepackages/orchestrator/src/queue/command-queue.ts
RoutingMessageRouterpackages/orchestrator/src/routing/message-router.ts
SessionSessionLifecyclepackages/agent/src/session/session-lifecycle.ts
IdentityloadIdentityFilespackages/agent/src/identity/identity-loader.ts
Memory recallRagRetrieverpackages/agent/src/rag/rag-retriever.ts
Context enginesetupContextEnginepackages/agent/src/executor/executor-context-engine-setup.ts
Tool assemblyassembleToolspackages/agent/src/executor/executor-tool-assembly.ts
LLM executionrunPrompt (PiExecutor)packages/agent/src/executor/executor-prompt-runner.ts
Post-executionpostExecutionpackages/agent/src/executor/executor-post-execution.ts
You do not need to call these directly — the daemon wires them up automatically when an agent starts. They are listed here so you can find the right file when investigating logs or extending behavior.

Identity

The workspace files that shape your agent’s personality.

Sessions

How conversations are tracked and managed.

Memory Recall

How your agent remembers past conversations.

Safety

Budget limits, circuit breaker, and step counter.

Sub-Agent Lifecycle

The specialized lifecycle for spawned sub-agents.