Repository navigation
Guides Contributing Send To Starting
The path from a submitted prompt to the transcript's "Starting..." row, and how to profile the delay between them.
This traces what happens between a user submitting a prompt and the transcript
showing the Starting... processing row.
- The composer calls
handleSend(...)insrc/client/app/useKannaState.ts. - The client immediately inserts an optimistic
user_promptentry into local state. - The client sends a
chat.sendWebSocket command. - The server handles
chat.sendinsrc/server/ws-router-chat.ts, which delegates toAgentCoordinator.send(...)insrc/server/agent-coordinator.ts. - If this is a new chat, the server creates the chat before starting the turn.
-
startTurnForChat(...)runs the preflight work: it sets the provider if missing, persists plan mode, applies an optimistic title for the first message of a new chat, appends the realuser_prompttranscript entry, and recordsturn_started. - The server boots the provider turn. Claude creates or reuses its session, then sends the prompt; Codex starts its session, then starts the turn.
- The server registers the turn in
activeTurnswith runtime statusrunning(Claude) orstarting(Codex). -
AgentCoordinatorcallsonStateChange(), andbroadcastSnapshots()insrc/server/ws-router-broadcast.tspushes fresh snapshots. -
deriveChatSnapshot(...)insrc/server/read-models.tsmerges the persisted transcript with the in-memory runtime status. - The client's chat subscription receives the new
ChatSnapshot, anduseKannaState(...)resolvesruntime.statusfrom it. - The chat page renders
<ProcessingMessage status="starting" />while the chat is processing andruntime.status === "starting";ProcessingMessage.tsxmapsstartingtoStarting....
Starting... appears only after the server has accepted chat.send, started the
turn, registered the runtime as starting, and rebroadcast a snapshot that the
client then received and rendered. Any latency in that chain widens the gap between
the optimistic prompt and the loading row.
Each send carries a clientTraceId; client and server log checkpoints against it.
Client. In the browser console, then reload:
sessionStorage.setItem("kanna:profile-send-to-starting", "1")Logs carry the prefix [kanna/send->starting][client]. Checkpoints:
handle_send_called, optimistic_prompt_added, chat_send_ack_received,
chat_snapshot_received, runtime_status_starting, starting_render_committed,
and starting_not_observed.
Server. Start Kanna with the flag set:
KANNA_PROFILE_SEND_TO_STARTING=1 bun run ./src/server/cli.tsLogs carry the prefix [kanna/send->starting][server] and come from four modules:
chat_send.* from claude-send-command.ts, start_turn.* from
claude-turn-starter.ts, ws.snapshot_sent from ws-router-broadcast.ts, and
ws.chat_send_ack from ws-router-chat.ts. In order: chat_send.received,
chat_send.chat_created, start_turn.begin, start_turn.provider_set,
start_turn.plan_mode_set, start_turn.optimistic_title_set,
start_turn.user_prompt_appended, start_turn.turn_started_recorded,
start_turn.provider_boot.begin, start_turn.session_ready,
start_turn.provider_boot.ready, start_turn.active_turn_registered,
start_turn.state_change_emitted, start_turn.claude_prompt_sent,
chat_send.ready_for_ack, ws.snapshot_sent, ws.chat_send_ack.
Match the client and server logs for one send by trace id, then compare these buckets:
| Bucket | From | To |
|---|---|---|
| Client preflight | handle_send_called |
optimistic_prompt_added |
| WebSocket round trip | optimistic_prompt_added |
chat_send_ack_received |
| Server pre-turn work | chat_send.received |
start_turn.turn_started_recorded |
| Provider startup | start_turn.provider_boot.begin |
start_turn.provider_boot.ready |
| Snapshot propagation |
start_turn.state_change_emitted / ws.snapshot_sent
|
chat_snapshot_received |
| UI commit | runtime_status_starting |
starting_render_committed |
A delay that grows over time usually points at one of: a WebSocket command backlog, event-store writes for the transcript append and turn events, provider session startup, snapshot broadcast cost, or client snapshot reconciliation and render cost.
This wiki is generated from wiki/src/content/docs in cuongtranba/kanna.
Edit the docs there: changes made on this wiki are overwritten on the next sync.
The same docs are published at https://kanna-wiki.lowbit.link.
Getting Started
Features
- Providers & Models
- Chat & Transcript
- Generative UI
- Projects & Sessions
- Boards
- Multi-repo Stacks
- Slash Commands
- Cron Jobs
- Loops
- Beacons
- Kanna Plugins
- Package Auto-Update
- Advanced
- Security
Guides
- User Guide
- Contributing
- Ops & Self-Host
Sharing
Reference