Skip to content

Turn Lifecycle

A "turn" is one user message followed by the agent's response. This page traces the full lifecycle of a workstream turn from user input through post-turn processing.

Overview

User Message
    |
    v
Pre-Turn Setup (run registration, compaction wait)
    |
    v
Context Building (history, memory, state, attachments)
    |
    v
Agent Execution (streaming response)
    |
    v
Message Persistence
    |
    v
Post-Turn Processing (memory, compaction, title, skills)
    |
    v
Run Cleanup

1. Pre-Turn Setup

When a new message arrives at a workstream chat endpoint:

  1. Compaction wait -- if the workstream is currently compacting (isCompacting = true), the request waits for the active compaction job to finish before proceeding.
  2. Run registration -- a new serverRunId is generated and registered in the chatRunRegistry. An AbortController is created for cancellation support.
  3. Active run ID -- the workstream's activeRunId is set to the new run ID, marking it as busy.
  4. User message persistence -- the incoming user message is persisted to the workstream message history.

2. Context Building

Before the agent executes, the runtime assembles the full context:

History Messages

  • All persisted messages are loaded from the workstream.
  • If a compactionSummary exists and lastCompactedMessageId is set, it is prepended as a synthetic system message.
  • File attachment URLs are re-signed with fresh presigned URLs.

Memory Retrieval

  • Pre-seeded memories -- high-importance core memories loaded without a query via getTopMemories().
  • Retrieved knowledge -- semantic search against organization and agent memory scopes using the latest user message as the query.

Workstream State

  • The structured WorkstreamState (decisions, tasks, risks, etc.) is formatted as an XML <workstream-state> section.

Execution Plan State

  • If an active execution plan exists, it is formatted as <execution-plan-state> and injected before the workstream state.

Extra Instruction Sections

  • The buildExtraInstructionSections hook allows consumers to inject additional context (organization details, foundation data, etc.).

Upload Metadata

  • Readable file attachments from message history are listed and their metadata is made available for tool access.

3. Agent Execution

The agent streams its response through the AI SDK streaming protocol:

  1. Agent resolution -- the resolveAgent hook determines which agent handles this turn, its model, reasoning profile, and tool set.
  2. Streaming -- the agent produces a UIMessageStream that emits text, reasoning, tool calls, and data parts.
  3. Step control -- the agent runs in a tool loop with configurable step limits and stop conditions.
  4. Approval handling -- if a tool requires approval, the stream ends with approval-requested parts. A subsequent continuation request executes the approved tool.

Streaming Details

Responses stream with throttled emission for natural pacing:

  • Server-side: chunks of 36-72 characters
  • Client-side: reveal chunks of 8-24 characters with configurable delays
  • Sentence boundaries get a slight pause for natural reading rhythm

4. Message Persistence

After the stream completes:

  • All assistant messages are persisted to the workstream message history via upsertMessages.
  • The workstream's updatedAt timestamp is refreshed.

5. Post-Turn Processing

Several background jobs are enqueued after a successful turn:

Memory Extraction

  • Onboarding turns -- immediate post-chat-memory extraction (extracts up to 16 facts per turn).
  • Post-onboarding turns -- a delayed regular-chat-memory-digest job is enqueued with 15-minute deduplication per organization. The digest processes all post-onboarding transcript slices since the last cursor.

Context Compaction Assessment

  • The finalizeTurnRun function checks if the uncompacted message history exceeds the compaction threshold (70% of 200K token budget).
  • If so, a context-compaction job is enqueued.

Title Generation

  • For workstreams with a default title ("New Workstream"), a title is generated from the conversation content.

Skill Extraction

  • A skill-extraction job identifies reusable procedures from the conversation.

Recent Activity

  • A recent-activity-title-refinement job updates the sidebar recent activity entry with a refined title.

6. Run Cleanup

Whether the turn succeeds or fails:

  1. The run is unregistered from chatRunRegistry.
  2. The workstream's activeRunId is cleared (only if it still matches the current run).
  3. The abort controller is disposed.

Approval Continuations

When a tool's needsApproval triggers:

  1. The initial stream ends with approval-requested message parts.
  2. The client renders approval UI from the persisted message.
  3. On user approval, a continuation request is sent.
  4. isApprovalContinuationRequest detects this and routes to createWorkstreamApprovalContinuationStream.
  5. The approved tool executes and the agent continues its response.

Abort and Stop

  • User stop -- stopActiveRun() aborts the in-flight run via the registered AbortController.
  • Browser disconnect -- does not stop the server run. The response continues and is persisted. The client polls for the final state via persisted messages and the isRunning flag.