Pi · 2 of 5
One turn through source
The coding session prepares product context, then hands the protocol to a small reusable loop. After the loop settles, the session decides whether retry, compaction, or queued work requires continuation.
§1
The coding-agent entry does preflight first
The public coding-session prompt path handles extension commands, project input interception, skill/template expansion, streaming queue mode, model and API-key validation, and prompt/resource assembly before starting the reusable agent. _runAgentPrompt() calls agent.prompt(), then loops through post-run handling and uses agent.continue() when retry, compaction, or queued work requires another run. Source · run wrapper Source · prompt preflight
§2
The reusable core loop
| Stage | Core behavior | Event/state result | Source |
|---|---|---|---|
| Start | agentLoop() creates an event stream and delegates to runAgentLoop(). | The returned stream ends on agent_end. | lines 27–54 |
| Append prompt | Copy context, append prompt messages, emit agent/turn/message events. | New messages are accumulated separately for the caller. | lines 95–118 |
| Prepare request | Inject pending steering messages, transform context, convert messages, stream assistant output. | Assistant message is appended and emitted through deltas. | lines 152–187 |
| Handle calls | Reject possibly truncated call arguments after a length stop; otherwise prepare, execute, and finalize calls. | Tool-result messages enter context in source order. | lines 188–220 |
| Continue | Apply next-turn snapshot/stop hook; poll steering and follow-up queues. | Another turn starts only when calls or queued messages remain. | lines 221–280 |
§3
Transformation happens at the LLM boundary
The loop carries AgentMessage values until it is about to call the provider. transformContext may prune or inject; convertToLlm must produce provider-understood messages. Source · boundary
This allows coding-session entries and extension messages to remain richer than the provider transcript. The conversion is also a risk boundary: dropping the wrong custom message changes what the model can know.
§4
Tool work has preflight and finalization
Validated argument parsing precedes beforeToolCall. The hook may block and return a result. Allowed calls execute, then afterToolCall can replace or annotate the result before final tool events and model-facing messages are emitted.
The core supports global parallel or sequential execution. If any call targets a tool marked sequential, the whole batch is sequential. In parallel mode, completion events can follow wall-clock completion while persisted tool-result messages remain in assistant source order. Source · event/tool order
§5
Steering, follow-up, and post-run continuation are distinct
Steering messages are polled into the next turn while the inner loop is active. Follow-ups can start work after the current natural stop. The coding session adds another edge: extension handlers can queue messages around agent_end, so _handlePostAgentRun() checks the queues after handling retry and compaction.
A retryable error can prepare a continuation; context overflow is routed to compaction rather than the ordinary retry policy. Only after those checks does the session decide it is settled. Source · post-run handling
§6
A termination hint is not an abort
Tools and pre/post hooks may return terminate: true. The batch skips the automatic follow-up only when every finalized tool result carries the hint. shouldStopAfterTurn runs after normal completion, before queues are polled. Neither mechanism rewrites the assistant stop reason or retroactively cancels tools.