Sessions & Trees
A session is an AI conversation. Unlike a CLI where conversations scroll up and disappear, Agor sessions can branch (fork siblings, spawn children, or ask side questions), building a genealogy tree you can navigate, resume, and reason about.
Every session lives inside exactly one branch. Multiple sessions on the same branch share a filesystem but have independent conversations.
Branch: "auth-feature"
└─ Session: "Build authentication system" (Claude)
├─ Fork: "Write tests for auth" (Claude)
├─ Fork: "Build user profile that uses auth" (Claude)
├─ Spawn: "Research OAuth2 best practices" (Codex)
│ └─ Spawn: "Evaluate PKCE vs implicit flow" (Gemini)
└─ BTW: "What's the version of node here?" (ephemeral)
A coordinator session fanned out to eight parallel security-review children, each its own introspectable conversation.
Three ways to branch
Fork — copy the context, keep the conversation
A fork creates a sibling session with a copy of the parent’s conversation context at that moment. Same accumulated knowledge, but the two diverge from there.
Session: "Built user authentication feature"
├─ Fork: "Write comprehensive unit tests for auth"
├─ Fork: "Build user profile page that uses auth"
└─ Fork: "Generate API documentation"Use forks when downstream work needs the same starting knowledge but different focus. Agor supports session forks for Claude Code and Codex. Gemini, OpenCode, GitHub Copilot, and Cursor do not currently support session forks in Agor.
Spawn — delegate with fresh context
A spawn creates a child session with a fresh context window. The parent decides what context to pass via the spawn prompt; the child is a focused subagent.
Parent: "Build complete e-commerce checkout flow"
├─ Spawn: "Implement payment gateway integration"
├─ Spawn: "Build inventory validation service"
└─ Spawn: "Create order confirmation email templates"Use spawns when the parent is orchestrating and you want children to do focused work without dragging in the parent’s full history.
BTW — ephemeral side question
A btw is an ephemeral fork that runs concurrently and auto-archives when done. The parent never blocks. The answer is delivered back as a message in the parent’s conversation.
The “btw” button (❓) sits next to the prompt input. Click it, type your question, and it runs in a separate ephemeral session. When it completes, the result is injected back into the parent.
For orchestrating agents, the same thing is exposed via agor_sessions_prompt with mode: "btw". Agents can ask peer sessions quick questions without breaking their flow.
BTW uses session forking under the hood and is supported for Claude Code and Codex. For tools without fork support (Gemini, OpenCode, GitHub Copilot, and Cursor), use
mode: "subsession"instead.
A btw question runs in an ephemeral fork; the answer is delivered back inline in the parent’s timeline.
Why genealogy matters
Linear conversations are lossy. When an agent goes down a wrong path, you either start over or live with the corrupted context.
Branched conversations are exploratory. Every fork/spawn is:
- Introspectable: Full conversation history kept on disk; click any node and read it.
- Composable: Fork from forks, spawn from spawns, build deep delegation trees.
- Multiplayer-friendly: Teammates see the tree on the branch card and understand the exploration.
- Resumable: Prompt any session in the tree at any time, even after it “completed.”
The tree is rendered on the branch card on the board, and in full detail in the session view.
Large session lists
Branch cards and the branch teammate panel keep manual and gateway genealogy trees in a virtual, scrollable viewport. Board cards keep a 400-pixel maximum; the teammate panel sizes trees to its available height and resizes with its container. Expanded manual and gateway trees share the remaining space; short trees release unused space to overflowing siblings. On board cards, two-finger scrolling over a session tree pans the canvas, and pinching zooms it; drag the tree’s scrollbar to reach older sessions. In the branch teammate panel, scroll inside the tree normally. Collapsing a parent still hides its descendants. Expanded, overflowing descriptions and task peeks retain ordinary inner scrolling on board cards, while pinching still zooms the canvas. Scheduled runs and panel search results show 20 sessions per page. Search matches the loaded collection, not just the current page. The branch settings Sessions tab also paginates its table.
These are rendering bounds, not a retention policy or a data-fetch limit: the UI still hydrates accessible sessions, and no sessions are deleted or archived because a list is large.
For integrations, agor_sessions_list supports optional branchId and boardId
filters; omitting both lists across the caller’s accessible branches in the
authenticated workspace, not across tenants. A session must belong to a branch,
but a list query need not name one. MCP list pages default to 25 records, with
a maximum requested limit of 100. The derived sessionType filter scans at most
10,000 candidate sessions; if the complete candidate set does not fit, the tool
returns an error rather than an incomplete result. Narrow with branch, board,
status, or archive filters, or omit sessionType and page normally. The Feathers API uses branch_id / board_id
and $limit / $skip instead. Use find() for one page: the TypeScript client’s
findAll() follows continuation pages and accumulates the entire result, even
when its query includes $limit.
Spawned subsessions with callbacks
Spawning is more than “start a child.” Subsessions in Agor have first-class callback semantics:
- Non-blocking: The parent stays responsive while children run. If a callback arrives while the parent is mid-prompt, it queues.
- Automatic reports: When a child completes, it sends a callback message to the parent: status, summary, tool usage count, optional final message.
- Persistent: Children don’t disappear after completing. You can prompt them again (“can you fix the tests you broke?”) or have them spawn their own children.
- Cross-tool: Spawn a Codex child from a Claude parent, or a Gemini child from a Codex parent. Pick the right tool per subtask.
Configuration options
When spawning, you can override:
- Agentic tool: Claude Code, Codex, Gemini, OpenCode
- Model: Use a different model than the parent
- Permissions: Stricter or looser approval requirements
- MCP servers: Different tool sets (Codex MCP support pending)
- Callback content: Include last message (default on), include original prompt (default off), extra formatting instructions
Comparison with Claude Code’s native subagents
If you’ve used Claude Code’s subagent feature , Agor’s subsessions go further:
| Feature | Claude Code Subagents | Agor Subsessions |
|---|---|---|
| Parent blocking | Parent locks while subagent runs | Parent stays responsive |
| Callback queuing | N/A | Callbacks queue if parent is busy |
| Introspection | Limited | Full conversation & git history |
| Post-completion prompting | No | Can prompt child after it’s done |
| Hierarchical spawning | No | Children can spawn their own children |
| Multi-tool support | Claude Code only | Claude, Codex, Gemini, OpenCode |
Codex also has a native multi-agent feature, but Agor deliberately disables it in Agor-launched Codex processes. Use Agor subsessions instead: they keep child work visible in the session tree and provide durable status and callback semantics. Agor provides the same observable orchestration boundary for every supported agent.
Real patterns
Parallel test generation
Parent (Claude): "Generate unit tests for these 5 files in parallel"
├─ Spawn (Codex): "Write tests for src/auth/login.ts"
├─ Spawn (Codex): "Write tests for src/auth/oauth.ts"
├─ Spawn (Codex): "Write tests for src/auth/jwt.ts"
├─ Spawn (Codex): "Write tests for src/auth/session.ts"
└─ Spawn (Codex): "Write tests for src/auth/refresh.ts"Five callbacks stream in as each child finishes. The parent reviews quality, runs the test suite, and decides next steps. Five-way parallelism on independent files, no merge conflicts.
Cross-agent code review
Claude (implements feature)
└─ Spawn Codex: "Review the implementation across these 6 files"
└─ Callback: critical bug found at file:lineDifferent agent, fresh eyes. Codex isn’t defending its own implementation choices. It’s just looking at the code. Especially effective for security audits, validating cross-SDK consistency, and catching bugs before PR submission.
Hierarchical delegation
Session A (architect)
├─ Session B (backend dev)
│ ├─ Session C (API implementation)
│ └─ Session D (database schema)
└─ Session E (frontend dev)
└─ Session F (UI components)Each level delegates to specialized agents. Each session has a focused context window with only what it needs.
Best practices
Keep prompts focused. Subsessions work best with specific, isolated tasks. “Update the JWT token validation logic” beats “fix the auth system.”
Mind the filesystem. Forks and spawns share the branch’s filesystem. Independent edits = no conflict. Parallel edits to the same file = git conflict. Plan accordingly.
Use callbacks wisely. Include the last message for quick status updates. Include the original prompt only when context might be lost. Add extra instructions when you need a specific report format (“include line numbers for all changes”).
Use the current caller for self callbacks. With agor_sessions_create, set enableCallback: true and omit callbackSessionId to receive completion in the calling session—even from a fork, nested coordinator, or across branches. Only supply callbackSessionId for an intentional authorized alternate destination. Inherited conversation examples and shared workspace IDs may refer to an earlier session; the runtime-supplied Agor session identity is distinct from fork ancestry and the provider SDK thread ID.
Remote callbacks stay linked by default. Sessions created with callbacks report after each completion until you unlink callbacks from the session relationship control. Unlinking stops delivery without deleting the relationship; select once when you only want the next completion. Spawned subsessions and btw side questions remain one-shot.
Post-prompt anytime. Subsessions persist after completion. “Can you add error handling to the code you wrote?” is a valid follow-up at any point.
Configuration on a session
A session has more knobs than a CLI invocation:
- Model: Switch model mid-session from the panel footer
- Effort: Explicit reasoning depth for Claude and Codex sessions. Unset Codex sessions inherit the runtime’s project, user, or model default.
- Permissions: How tool calls are gated (auto-approve, supervised, manual)
- MCP servers: Which tool sets are attached
- Environment variables: Select name-only grants for variables you marked
Sessionin Profile → Env Vars. Global variables are eligible automatically for tasks executing as you. Selections take effect on the next task; they do not mutate a running process. - Effort and context capacity: Supported Claude Code models expose separate 200k and
[1m]choices; availability still depends on the connected account and provider
All of this is changeable at any point. You don’t have to start a new session to dial things up or down.
Session Settings modal: model, effort, permissions, MCP, env vars, callbacks, all editable mid-session for supported runtimes.
Forks and spawned children copy selection names for continuity, never stored values. Each child resolves the copied names against its attributed owner. When a collaborator forks or spawns from a shared branch-scoped session, the child is attributed to that collaborator, so a copied name cannot borrow the parent’s secret. Execution-home sessions cannot be continued across users. Callbacks carry message content, not an environment grant.
Codex runtime notices and tool failures
A Codex runtime notice is non-fatal at the time it is emitted, not proof that an MCP operation failed or succeeded. Codex uses the same item shape for several kinds of warnings, including configuration and deprecation notices, without preserving their classification. Agor keeps the notice visible but does not copy provider error text, which can contain sensitive data.
A failed MCP tool result remains marked as an error even if Codex continues and completes the turn. Before retrying a write, check its resulting state: a transport error can occur after a change has committed. An empty tool catalog is not itself an error, and a failed turn is separate from an individual tool failure.
Recurring notices and failed MCP calls include a diagnostic reference. Give that reference and the task to an authorized administrator. The reference correlates bounded, content-free executor operational logs; it does not grant access to logs or expose the provider payload. High-volume diagnostics are summarized after the per-run log limit, without hiding notices or tool failures in the conversation.
Historical Claude CLI sessions
Agor previously included an experimental claude-code-cli runtime. That integration has been
removed. Existing database rows keep their original tool identifier, transcript, task/message
history, and historical runtime metadata so their attribution remains accurate and readable.
Agor does not convert those rows into Claude Agent SDK (claude-code) sessions. Historical
sessions cannot be prompted, resumed, forked, spawned from, or restarted, and the removed tool is
not offered for new sessions, schedules, gateway channels, or MCP calls. Create a new Claude Code
session to continue the work with a supported runtime.
Historical schedules, gateway channels, and zone triggers also retain the removed identifier. They do not fall back to Claude Code: execution is rejected, and edit screens require an explicit supported-tool selection before saving. Due cron schedules advance to their next occurrence without creating a session, avoiding repeated retries while their configuration awaits migration.
Related
- Branches: The container for sessions
- Agor MCP Server: How agents introspect and spawn each other programmatically
- Rich Chat UX: Token accounting, context window viz, tool blocks, queueing
- In-Conversation Widgets: Agent-rendered inline forms (env vars today, more soon) that capture input without it ever entering the model’s context
- SDK Comparison: What each agent SDK supports