CHAPTER 12 · SESSION RUNTIME

Session Actor: Thread, State & Cancellation Boundaries

Each Session runs a current-thread Tokio runtime and LocalSet on a dedicated OS thread. SessionActor coordinates turns, ChatStateActor serially owns the conversation state, and CancellationToken handles cooperative termination.

Learning Objective
Be able to explain how thread isolation, Actor state ownership, and cancellation signals work together, and accurately describe the Agent's "effectively immutable" boundary.
KEY VISUAL · ANNOTATED RUNTIME DIAGRAM
Session OS thread · ses-<id> Tokio current-thread runtime + LocalSet SessionActorSessionCommandturn completion / events ChatStateActorconversationtokens / timing / persistenceexclusive state, no shared lock SamplerActorrequest taskSamplingEvent CancellationToken / handle drop drives cooperative shutdown
TRUE RESPONSIBILITIES OF THE TURN LOOP

SessionActor Coordination

  • run_session simultaneously receives SessionCommand, ChatStateEvent, SessionEvent, and turn completion.
  • maybe_start_running_task starts a pending turn.
  • After a turn completes, it handles completion, turn-end, and follow-up notification processing.

ChatStateActor Owns State

  • Exclusively owns conversation, tokens, configuration, and persistence.
  • Processes commands serially via mpsc::UnboundedReceiver.
  • A cancelled token triggers exit; dropping all handles also ends the loop.
AGENT'S ACTUAL FIELD BOUNDARIES
definition

AgentDefinition — defines identity, mode, and strategy inputs.

prompt_context

PromptContext supporting inspection, re-rendering, and serialization.

system_prompt

Rendered and cached string from the prompt context.

tool_bridge

Arc<ToolBridge> — bridge for tool registration and session context.

reminder_policy

Session-level reminder policy.

compaction_policy

Auto-compaction, memory flush, and two-pass configuration.

hosted_tools

Backend-hosted tool definitions sent to the API.

backend_search_enabled

Server-side search toggle at build time.

Precise wording: Source code comments describe the Agent as "effectively immutable" after construction. It still provides finalize_prompt(&mut self) to update the build timestamp and re-render the prompt, so it cannot be described as absolutely immutable.
SOURCE CODE EVIDENCE
crates/codegen/xai-grok-shell/src/session/acp_session_impl/spawn.rs
let join_handle = std::thread::Builder::new()
  .name(thread_name)
  .stack_size(8 * 1024 * 1024)
  .spawn(move || {
    let rt = tokio::runtime::Builder
      ::new_current_thread().enable_all().build()?;
    let local = tokio::task::LocalSet::new();
  });
crates/codegen/xai-grok-agent/src/agent.rs
/// Re-render the system prompt
pub async fn finalize_prompt(&mut self) {
  self.prompt_context.build_timestamp_utc =
    chrono::Utc::now().to_rfc3339();
  self.system_prompt = self.prompt_context
    .render(&self.tool_bridge).await
    .unwrap_or_default();
}
Source snapshot note: This page is based on a locally synced copy. That copy has no .git metadata, so no specific commit version is claimed.
CLASS EXERCISE

Assign a Sole Owner to Each State

Place conversation, system_prompt, tool registry, and sampling request into ChatStateActor, Agent, ToolBridge, and SamplerActor respectively. Then explain why cancellation token and message priority are different concepts, and that this codebase has no general "high-priority message at queue head" design.

Takeaway: The Session isolation unit is an OS thread plus LocalSet. SessionActor handles turn orchestration, ChatStateActor owns conversation state, and CancellationToken manages cancellation. The Agent is primarily effectively immutable, while retaining an explicit re-render entry point.