Chat Branching

Fork any conversation at any message to explore alternative paths, test different prompts, or preserve a working state before experimenting.

Overview

Chat branching lets you create multiple independent conversation threads within a single chat session. Each branch starts from a point in the conversation history and continues independently from that point forward. Branches share the same document workspace and uploaded files, but their message histories are separate.

Every chat starts with one branch (the default branch). You can create as many additional branches as needed. Common use cases include:

  • A/B testing prompts -- fork after your initial setup and try different approaches in parallel branches without losing either result.
  • Exploring alternatives -- ask the model to try a different approach in a new branch while keeping the original intact.
  • Rolling back -- fork before a risky or experimental direction so you can return to the fork point if things go wrong.
  • Isolating concerns -- use separate branches for different subtopics in a long-running project.

Each branch is identified by a unique external ID in branch_xxx format and has a user-supplied display name. Branches record which branch they were forked from (their parent) and at which message sequence number the fork occurred.

Note: Documents uploaded to the workspace are shared across all branches within a chat. A document uploaded on one branch is searchable on all other branches.

Creating a Branch

You can create a new branch at any time from the Branches panel in the chat toolbar. This creates a branch forked from the end of the current active branch -- all current messages are included in the new branch's history.

  1. Open the chat toolbar and click the Branches button (the branch icon).
  2. Click the New Branch button at the bottom of the panel.
  3. Enter a display name for the branch. The name is required.
  4. Optionally select a system prompt template to apply to the new branch.
  5. Click Create. The branch is created and you are switched to it automatically.

The branch selector in the toolbar updates to show the new branch as the active selection.

Fork from a Message

You can also fork a branch at a specific point in the conversation history by clicking the fork icon on any individual message. This creates a branch that diverges at that message -- messages after the fork point on the current branch are not included in the new branch's history.

  1. Hover over any message in the conversation to reveal its action buttons.
  2. Click the fork icon (git-fork) on the message.
  3. The fork modal opens with the fork point pre-set to that message's sequence number.
  4. Enter a display name and optionally select a system prompt template.
  5. Click Create. The new branch starts from that point in the history.

The forkAfterSequence field on the branch record stores the sequence number at which the fork occurred, giving you a precise record of the branch's origin in the parent's history.

Switching Branches

The branch selector dropdown in the toolbar always shows all available branches for the current chat. Select a branch from the dropdown to switch to it immediately. The message list clears and reloads with the selected branch's history.

Switching a branch also restores the branch's system prompt override, if one was configured when the branch was created.

You can also switch branches from the Branches panel by clicking a branch name in the tree list.

Branch Panel

The Branches panel provides a visual overview of all branches in the chat using a git-tree style layout. Open it by clicking the branch icon in the toolbar.

The panel renders branches as a flat tree. Each branch is displayed as a row with:

  • A colored lane indicator dot (each branch lane has a distinct color).
  • The branch display name as a clickable button that switches to that branch.
  • A delete button (available when more than one branch exists).

The currently active branch is visually highlighted. Child branches are indented under their parent to reflect the parent-child tree structure.

A New Branch button at the bottom of the panel opens the fork modal to create a branch from the current position in the active branch.

Branch System Prompts

Each branch can carry an optional system prompt override. When a branch has a system prompt set, that prompt replaces the chat-level system prompt during context assembly for all messages on that branch.

Branch system prompts are set at fork time by selecting a template from the template selector in the fork modal. Templates are fetched from GET /chat/api/templates and appear as options in the dropdown. If no template is selected, the branch inherits the chat's default system prompt.

Switching branches automatically restores the target branch's system prompt in the canvas state so subsequent messages on that branch use the correct prompt.

Note: System prompt overrides apply per-branch. Changing the chat-level system prompt does not affect branches that have an override already set.

Automatic Forking

The system can automatically fork the conversation when the context window approaches its limit. When this happens, the active branch is forked automatically into a new branch with a generated name, and the user is notified by a toast message:

Toast Example
Context limit approaching -- forked to "Branch Name"

This automatic fork is triggered by a server-sent x_context_fork event in the streaming response. The new branch ID and name are provided in the event payload. The branch selector is updated automatically and the active branch switches to the new fork without requiring any user action.

Each branch maintains a rolling summary of older messages and a summaryThroughSequence counter so that summarized history can be reconstructed efficiently within the token budget.

Deleting Branches

Branches can be deleted from the Branches panel. Click the delete icon on any branch row to remove it. Deleting a branch requires confirmation.

The last remaining branch cannot be deleted -- at least one branch must always exist in a chat. If you attempt to delete the last branch, a toast error is shown and the operation is cancelled.

Deleting a branch also deletes all of its sub-branches (child branches that were forked from it). The confirmation dialog notes this.

Branches are soft-deleted in the database. The record remains with a deleted_at timestamp but is excluded from all list queries. If the active branch is deleted, the UI automatically switches to the first remaining branch.

Branch API

All branch operations are available via the chat API. All endpoints require authentication.

List Branches

GET /chat/api/{chatId}/branches

Returns all active branches for the chat ordered by creation date.

curl
curl https://api.xerotier.ai/chat/api/550e8400-e29b-41d4-a716-446655440000/branches \ -H "Cookie: session=your_session_token"
Response
{ "branches": [ { "id": "branch_ABCdef123456789012345678", "name": "Main", "parentId": null, "systemPrompt": null, "createdAt": "2026-04-07T10:00:00Z" }, { "id": "branch_XYZabc987654321098765432", "name": "Experiment A", "parentId": "branch_ABCdef123456789012345678", "systemPrompt": "You are a concise assistant.", "createdAt": "2026-04-07T10:15:00Z" } ] }

Create Branch

POST /chat/api/{chatId}/branch

Creates a new branch forked from the current active branch.

Request Body

FieldTypeRequiredDescription
namerequired string Yes Display name for the new branch.
branchrequired string Yes The ID of the parent branch to fork from.
atSequenceoptional integer No Fork after this message sequence number. When omitted, the fork point is the end of the parent branch.
templateIdoptional string No System prompt template ID to apply to the new branch.
curl
curl -X POST https://api.xerotier.ai/chat/api/550e8400-e29b-41d4-a716-446655440000/branch \ -H "Cookie: session=your_session_token" \ -H "Content-Type: application/json" \ -d '{ "name": "Experiment A", "branch": "branch_ABCdef123456789012345678", "atSequence": 12 }'

Delete Branch

DELETE /chat/api/{chatId}/branch/{branchId}

Soft-deletes a branch and all of its sub-branches. Returns HTTP 400 if deleting the last branch is attempted. Returns HTTP 204 on success.

curl
curl -X DELETE https://api.xerotier.ai/chat/api/550e8400-e29b-41d4-a716-446655440000/branch/branch_XYZabc987654321098765432 \ -H "Cookie: session=your_session_token"

Data Model

Each branch is persisted as a chat_branches record linked to the parent chat. The key fields are:

FieldTypeDescription
id string External branch identifier in branch_xxx format (24 random alphanumeric characters after the prefix).
name string User-supplied display name for the branch.
parentId string (nullable) External ID of the parent branch this was forked from. Null for the root branch.
forkAfterSequence integer (nullable) Sequence number after which the fork occurred. Null when forked from the end of the parent.
systemPrompt string (nullable) Optional system prompt override for this branch. When set, replaces the chat-level system prompt during context assembly.
rollingSummary string (nullable) Periodically generated summary of older messages on this branch, used to keep context within the token budget.
summaryThroughSequence integer (nullable) The highest sequence number covered by the rolling summary. Messages after this point are included verbatim in context.
lastResponseId string (nullable) Most recent Responses API response ID for conversation chaining. Updated after each completed assistant response on this branch.
createdAt string ISO 8601 timestamp when the branch was created.
deletedAt string (nullable) ISO 8601 timestamp when the branch was soft-deleted. Null for active branches.

Related Pages

  • Chat Memory -- saving and recalling per-workspace knowledge across conversations.
  • Document Workspace -- uploading documents that are shared across all branches.