Interactive Sessions: Features
Complete feature reference for interactive sessions.
Table of Contents
- Session Creation & Configuration
- Provisioning & Worker Assignment
- Conversation Threads
- Real-Time Conversation
- File & Code Operations
- Git & Version Control
- Pause & Resume
- Attachments & Extensions
- Preview Apps
- Budget & Limits
- Pipeline Integration
- Session Forking
- 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:
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:
| Strategy | Behavior |
|---|---|
auto_create | Automatically creates a new branch when the agent makes changes |
use_existing | Uses the repository's selected existing branch context |
none | No SCM integration |
1{
2 "agentRef": "engineering-assistant@3",
3 "repositoryId": "repo-123",
4 "branchStrategy": "auto_create"
5}Budget Limit
Set a token budget to control costs:
1{
2 "agentRef": "engineering-assistant@3",
3 "budgetLimit": 200000
4}When the budget is near exhaustion:
- A
budget_warningevent 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:
| Phase | What's Happening |
|---|---|
queued | Waiting for a worker to become available |
worker_launching | Worker container spinning up |
worker_waiting_ready | Container up, waiting for agent process |
credentials_injecting | Resolving approved credential bindings for the runtime; long-lived provider secrets are not Agent configuration |
workspace_preparing | Mounting repos, knowledge base, deliverable specs |
config_writing | Writing agent configuration files |
config_reloading | Agent reloading its configuration |
ready | Provisioning complete ✓ |
failed | Error 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.
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}/threadsMessages, 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:
| Event | Description |
|---|---|
text_delta | Streaming text output from the agent |
thinking | Agent's reasoning process (visible when model supports it) |
tool_call | Agent is invoking a tool |
file_change | A file was created, edited, or deleted |
todo_updated | Agent's task list was updated |
question_asked | Agent has a question that needs your answer |
permission_asked | Agent wants permission to do something (e.g., delete files) |
done | Agent finished responding |
error | An error occurred |
Idempotent Message Sending
Messages support idempotency via a header, preventing duplicate sends on network retries:
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:
1event: question_asked
2data: {
3 "questionId": "q_123",
4 "question": "Should I use JWT or session cookies for authentication?"
5}You answer:
1curl -X POST .../sessions/{sessionId}/questions/q_123/answer \
2 -d '{"answer": "JWT, with 15-minute expiry and refresh tokens"}'Agent requests permission:
1event: permission_asked
2data: {
3 "permissionId": "perm_456",
4 "action": "delete",
5 "resource": "/src/legacy/old-auth.ts"
6}You grant or deny:
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:
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:
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:
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:
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:
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:
1POST /sessions/{id}/pauseWhen paused:
- Session must be
activewith every thread idle (wait for any in-flight turn to finish) - The full workspace snapshot (files, agent memory, conversation history) is saved
- The worker is released back to the pool
- Session transitions to
paused
No work is lost — the session remembers everything.
Resuming
1POST /sessions/{id}/resumeWhen resuming:
- A fresh worker is acquired from the pool
- The saved session state is restored
- The logical session continues from exactly where it left off
Pause reasons
A session records why it paused:
| Reason | Resumes |
|---|---|
user | Only when you resume it explicitly. |
allocation_lost | Automatically, on the next message. |
worker_replaced | Automatically, 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:
- Records
allocation_lostas the pause reason - Transitions to a recoverable state
- 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.
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:
1PATCH /sessions/{id}/tools
2{ "selection": [] }Skills
Attach domain knowledge to guide the agent:
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:
| Kind | Description |
|---|---|
kb_page | A knowledge base page |
uploaded_file | A file you uploaded |
internal_url | An internal resource URL |
repo_ref | A reference to a specific file or path in a repo |
org_document | An organization-level document |
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
- Agent starts a dev server (e.g.,
npm run dev) - Xema detects the server process and exposed port
- A proxied public URL is created
- 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
| Status | Description |
|---|---|
detected | Xema noticed a server starting |
installing | Installing dependencies |
starting | Server process is starting |
running | Server ready and accessible via URL |
crashed | Server exited unexpectedly |
stopped | Intentionally stopped |
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:
1{
2 "tokenUsage": {
3 "inputTokens": 45200,
4 "outputTokens": 23100
5 },
6 "budgetLimit": 200000
7}Budget warnings are emitted as events:
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:
pipelineRunIdis 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:
- Workflow run starts (e.g., triggered by PR)
- Analysis jobs run automatically
- Pipeline reaches an engineering job → spawns an interactive session
- Engineer and agent collaborate in the session
- Agent creates a PR or completes deliverables
- Session completes → pipeline resumes
- 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:
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
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=42Message History
1# Get a thread's conversation history
2GET /sessions/{id}/threads/{threadId}/messagesSession List
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-456Next: API Reference for complete endpoint documentation.