Interactive Sessions: Features

Complete feature reference for interactive sessions.

Table of Contents

  1. Session Creation & Configuration
  2. Provisioning & Worker Assignment
  3. Conversation Threads
  4. Real-Time Conversation
  5. File & Code Operations
  6. Git & Version Control
  7. Pause & Resume
  8. Attachments & Extensions
  9. Preview Apps
  10. Budget & Limits
  11. Pipeline Integration
  12. Session Forking
  13. Audit & History

Session Creation & Configuration

Agent reference

Every generic session names a published Agent with agentRef, as a bare slug or a version pin such as engineering-assistant@3. The resolved Agent is the source of truth for its prompt, recursive subagents, intrinsic Skills and Tools, capability envelope, workspace configuration, and launch policy.

When sessionDomainKey and sessionDomainRef bind the session to a domain object, the server may resolve the Agent deterministically from that registered domain mapping instead of accepting an explicit agentRef.

Model Override

You can override the model for a specific session:

json
1{
2  "agentRef": "architecture-reviewer@2",
3  "modelId": "anthropic/claude-opus-4-5",
4  "title": "Deep architecture review"
5}

Available models are resolved per-invocation by the Model Resolution Matrix.

Repository & Branch Strategy

Link a session to a repository and choose how branches are managed:

StrategyBehavior
auto_createAutomatically creates a new branch when the agent makes changes
use_existingUses the repository's selected existing branch context
noneNo SCM integration
json
1{
2  "agentRef": "engineering-assistant@3",
3  "repositoryId": "repo-123",
4  "branchStrategy": "auto_create"
5}

Budget Limit

Set a token budget to control costs:

json
1{
2  "agentRef": "engineering-assistant@3",
3  "budgetLimit": 200000
4}

When the budget is near exhaustion:

  • A budget_warning event is emitted
  • You're notified in the session stream
  • The agent wraps up current work

Provisioning & Worker Assignment

Sessions go through a detailed provisioning sequence before becoming active. Each phase is observable:

PhaseWhat's Happening
queuedWaiting for a worker to become available
worker_launchingWorker container spinning up
worker_waiting_readyContainer up, waiting for agent process
credentials_injectingResolving approved credential bindings for the runtime; long-lived provider secrets are not Agent configuration
workspace_preparingMounting repos, knowledge base, deliverable specs
config_writingWriting agent configuration files
config_reloadingAgent reloading its configuration
readyProvisioning complete ✓
failedError occurred ✗

If provisioning fails, failureReason and provisioningPhase will indicate what went wrong.


Conversation Threads

A session is the workspace — one worker, one set of files, one git checkout. The conversations that run on it are threads. Every session is created with one default thread (Main); open more to run parallel conversations against the same workspace.

  • Each thread keeps its own message history and its own turn lock (turnState).
  • Threads share the session's worker, files, tools, and git state.
  • Threads run independently — one can be mid-turn while you type in another.
  • A session always keeps at least one active thread; archiving or deleting the last one is rejected with 409.
bash
1# Open a new thread on a session
2POST /sessions/{id}/threads
3{ "title": "Explore an alternative fix" }
4
5# List the session's threads
6GET /sessions/{id}/threads

Messages, history, and the streaming response are all addressed per thread — see Real-Time Conversation below and the API Reference.


Real-Time Conversation

Streaming Messages

When you send a message, the response streams back as Server-Sent Events (SSE). Each event type represents something the agent is doing:

EventDescription
text_deltaStreaming text output from the agent
thinkingAgent's reasoning process (visible when model supports it)
tool_callAgent is invoking a tool
file_changeA file was created, edited, or deleted
todo_updatedAgent's task list was updated
question_askedAgent has a question that needs your answer
permission_askedAgent wants permission to do something (e.g., delete files)
doneAgent finished responding
errorAn error occurred

Idempotent Message Sending

Messages support idempotency via a header, preventing duplicate sends on network retries:

bash
1curl -X POST .../sessions/{sessionId}/threads/{threadId}/messages \
2  -H "Idempotency-Key: $(uuidgen)" \
3  -d '{"content": "Review authentication code"}'

Question & Permission Cycles

Agents can pause and ask you questions or request permission:

Agent asks a question:

text
1event: question_asked
2data: {
3  "questionId": "q_123",
4  "question": "Should I use JWT or session cookies for authentication?"
5}

You answer:

bash
1curl -X POST .../sessions/{sessionId}/questions/q_123/answer \
2  -d '{"answer": "JWT, with 15-minute expiry and refresh tokens"}'

Agent requests permission:

text
1event: permission_asked
2data: {
3  "permissionId": "perm_456",
4  "action": "delete",
5  "resource": "/src/legacy/old-auth.ts"
6}

You grant or deny:

bash
1curl -X POST .../sessions/{sessionId}/permissions/perm_456/reply \
2  -d '{"granted": true}'

Questions, permission asks and attendance

Each question and each permission ask is a decision. The first answer wins: once one answer is committed, a later answer is refused.

Always allow. Choosing always-allow on a permission ask creates a grant that lasts for that session only. List the grants with GET /sessions/:id/permission-grants, and revoke one at the same path.

Attended and unattended. A session is attended when it was launched by a user token from the web app or the shell, and unattended otherwise. This is fixed at launch from the verified caller. In an unattended session nobody is there to answer, so every question and permission ask is denied at once, and the reason is recorded as interaction_answered_unattended.


File & Code Operations

Agents can read and modify your codebase with full visibility:

What the Agent Can Do

  • Read files — Navigate the repository structure
  • Create files — Generate new code, tests, docs
  • Edit files — Refactor, fix bugs, add features
  • Delete files — Remove obsolete code
  • Search codebase — Find usages, definitions, patterns

Observability

Every file change appears in the event stream in real time:

text
1event: file_change
2data: {
3  "operation": "edited",
4  "path": "src/auth/jwt.service.ts",
5  "diff": "...",
6  "timestamp": "2026-04-27T10:30:00Z"
7}

Git & Version Control

Sessions can manage the full git workflow:

Branch Management

When branchStrategy: auto_create, the agent automatically creates a branch for the session (e.g., interactive/fix-auth-abc123). You can also:

bash
1# Create a specific branch
2POST /sessions/{id}/git/branch
3{ "branchName": "feature/improved-auth" }

Committing Work

The agent can commit work at any time:

bash
1POST /sessions/{id}/git/commit
2{ "message": "Refactor JWT auth to use RS256", "files": ["src/auth/jwt.service.ts"] }

Pull Requests

When work is ready, the agent can open a pull request:

bash
1POST /sessions/{id}/git/pull-requests
2{
3  "title": "Refactor JWT authentication",
4  "description": "Migrates from HS256 to RS256 with key rotation support",
5  "baseBranch": "main"
6}

The PR URL is stored on the session (prUrl).

Git Status

Check the current git state at any time:

bash
1GET /sessions/{id}/git/status
2# Returns: { branch, status, changes, commits, pullRequest? }
3
4GET /sessions/{id}/git/merge-check?baseBranch=main
5# Returns: { canMerge, conflicts, checks }

Pause & Resume

Pausing

Pause a session when you need to stop and continue later:

bash
1POST /sessions/{id}/pause

When paused:

  1. Session must be active with every thread idle (wait for any in-flight turn to finish)
  2. The full workspace snapshot (files, agent memory, conversation history) is saved
  3. The worker is released back to the pool
  4. Session transitions to paused

No work is lost — the session remembers everything.

Resuming

bash
1POST /sessions/{id}/resume

When resuming:

  1. A fresh worker is acquired from the pool
  2. The saved session state is restored
  3. The logical session continues from exactly where it left off

Pause reasons

A session records why it paused:

ReasonResumes
userOnly when you resume it explicitly.
allocation_lostAutomatically, on the next message.
worker_replacedAutomatically, on the next message.

An ephemeral session (the default) also pauses when it is idle. A persistent session never pauses for idleness. The stuck-turn reaper applies to both.

Automatic Recovery

If a worker crashes while a session is active (e.g., infra failure), the session automatically:

  1. Records allocation_lost as the pause reason
  2. Transitions to a recoverable state
  3. Auto-resumes on the next message you send

You don't need to manually intervene.


Attachments & Extensions

MCP Tool Selection

Pick the tools the agent is allowed to call on this session. The selection is a single, ordered list — entries reference either an entire provider (all its tools) or one specific tool from a provider.

bash
1PATCH /sessions/{id}/tools
2{
3  "selection": [
4    { "kind": "provider", "providerKind": "mcp_server",            "resourceId": "<uuid>" },
5    { "kind": "provider", "providerKind": "catalog",               "resourceId": "default-dev-tools" },
6    { "kind": "tool",     "providerKind": "org_database_explorer", "resourceId": "<database-id>", "toolName": "run-query" }
7  ]
8}

The PATCH replaces the selection atomically. The platform's resolver expands every entry into the agent's MCP config on next boot/resume.

Use cases:

  • Attach a database MCP server to query databases.
  • Curate a per-project catalog of tools every session inherits.
  • Surface a biome's workflow as a single callable tool.
  • Surface a biome's typed handler function as a single callable tool.

Drop everything with an empty list — the agent boots with no MCP tools beyond the built-ins:

bash
1PATCH /sessions/{id}/tools
2{ "selection": [] }

Skills

Attach domain knowledge to guide the agent:

bash
1POST /sessions/{id}/skill-attachments
2{
3  "skillSlug": "backend-best-practices"
4}

Skills are markdown files that inject patterns, conventions, and guidance into the agent's context (e.g., "always use dependency injection", "follow our API naming conventions").

File Attachments

Attach specific files and resources:

KindDescription
kb_pageA knowledge base page
uploaded_fileA file you uploaded
internal_urlAn internal resource URL
repo_refA reference to a specific file or path in a repo
org_documentAn organization-level document
bash
1POST /sessions/{id}/attachments
2{
3  "kind": "kb_page",
4  "externalRef": "kb-page-456",
5  "metadata": { "displayName": "API Design Standards" }
6}

Preview Apps

Sessions can run live development servers that you can preview in real time:

How It Works

  1. Agent starts a dev server (e.g., npm run dev)
  2. Xema detects the server process and exposed port
  3. A proxied public URL is created
  4. You can open the URL and see the live app

Supported Runtimes

  • Next.js dev server
  • Modern JavaScript bundler dev servers
  • Python uvicorn
  • Any HTTP server on a detectable port

Preview Lifecycle

StatusDescription
detectedXema noticed a server starting
installingInstalling dependencies
startingServer process is starting
runningServer ready and accessible via URL
crashedServer exited unexpectedly
stoppedIntentionally stopped
bash
1# List preview apps in session
2GET /sessions/{id}/preview-apps
3
4# Returns:
5[{
6  "id": "preview-123",
7  "kind": "next_dev",
8  "status": "running",
9  "url": "https://preview.xema.dev/s/abc123/3000",
10  "port": 3000
11}]

Budget & Limits

Track token usage in real time:

json
1{
2  "tokenUsage": {
3    "inputTokens": 45200,
4    "outputTokens": 23100
5  },
6  "budgetLimit": 200000
7}

Budget warnings are emitted as events:

text
1event: budget_warning
2data: {
3  "usedTokens": 180000,
4  "budgetLimit": 200000,
5  "percentage": 90
6}

At budget exhaustion, the session will not accept new messages until you increase the limit or end the session.


Pipeline Integration

Sessions can be spawned by a workflow pipeline. When bound to a pipeline:

  • pipelineRunId is set on the session
  • The session receives the pipeline's context (deliverable specs, mount plan)
  • The pipeline pauses at a human collaboration step while the session runs
  • When the session completes, the pipeline resumes

A typical pipeline pattern:

  1. Workflow run starts (e.g., triggered by PR)
  2. Analysis jobs run automatically
  3. Pipeline reaches an engineering job → spawns an interactive session
  4. Engineer and agent collaborate in the session
  5. Agent creates a PR or completes deliverables
  6. Session completes → pipeline resumes
  7. Remaining workflow steps execute (review, publish, notify)

See Pipeline Integration for detailed examples.


Session Forking

Fork a session to create an independent copy from its current state:

bash
1POST /sessions/{id}/fork
2{
3  "title": "Explore alternative approach"
4}

The forked session:

  • Starts from the exact same workspace state
  • Has a different worker and history from this point on
  • References the original session via parentSessionId

Use forking to explore multiple approaches without affecting the main session.


Audit & History

Event Stream Query

bash
1# Get all events for a session
2GET /sessions/{id}/events
3
4# Filter by type
5GET /sessions/{id}/events?type=file_created
6
7# Since a sequence number (for polling)
8GET /sessions/{id}/events?afterSeq=42

Message History

bash
1# Get a thread's conversation history
2GET /sessions/{id}/threads/{threadId}/messages

Session List

bash
1# List sessions for a project
2GET /sessions?projectId=proj-123
3
4# Filter by status
5GET /sessions?status=active
6
7# Filter by pipeline
8GET /sessions?pipelineRunId=run-456

Next: API Reference for complete endpoint documentation.