Session / Subagent Levels
July 5, 2026 ยท View on GitHub
Backchat keeps three levels separate:
-
Native subagent
- Created by the provider runtime, not by Backchat GUI.
- Current supported providers: Codex (
codex-acp) and Claude Code (claude-acp/ CC). - Evidence source must be structured runtime data: ACP events, native Codex
collab events, or adapter
_metafields such as_meta.claudeCode.parentToolUseId. - Do not parse natural-language result text like
agentId: ...as the primary identifier.
-
Side chat
- Created by Backchat GUI in the right rail.
- Stored as a side session with
sideKind: "chat"and asideParentlink. - If the active ACP agent advertises
sessionCapabilities.fork, Backchat starts the side chat through ACPsession/forkso it inherits context. - It remains subordinate while it lives in the side rail.
-
Fork
- A fully independent main session that inherited context.
- Promoting a side chat clears
sideParentand moves it tokind: "main".
Current Evidence
- ACP fork plumbing is covered by
packages/acp/src/session.test.tsandsrc/main/session-manager.test.ts. Those tests prove Backchat passesforkFromAcpSessionIdinto the SDK's unstablesession/forksurface and returnssupports_session_forkto the renderer. - Renderer side-chat behavior is covered by
src/renderer/src/lib/session-store.test.ts. Those tests prove a side chat carriessideParent, and promotion clears that link. - GUI creation is guarded by
src/main/session-level-gui-contract.test.ts. The right rail can createSide chat; it must not expose native subagent creation actions. - Native runtime event normalization is covered by
src/renderer/src/lib/native-agent-events.test.ts:- Codex
collab_tool_callandspawn_agent/wait_agentevents become native subagent activity. - Claude
Task/Agenttool calls become native subagent activity only when the parent session is a Claude Code adapter. - Plain result text containing
agentId: ...is not treated as a structured child id.
- Codex
- Local Claude Code transcripts show structured task results can contain
toolUseResult.agentId,agentType, andprompt. That is useful evidence for CC's native model, but Backchat should consume it only if an adapter exposes it structurally through ACP /_meta, not through transcript scanning. - The dev dependency
@agentclientprotocol/claude-agent-acp@0.55.0was inspected and smoke-tested. Its compiled adapter emits_meta.claudeCode.toolNamefor tool calls and_meta.claudeCode.parentToolUseIdfor subagent-originated messages/tool updates. Those names match Backchat'sreduce-turnextraction path. - A real
claude-agent-acp@0.55.0smoke run is available throughpnpm run smoke:claude-acp-meta. The captured output attest-results/native-agent-experiments/claude-agent-acp-meta-smoke.jsonshowed:supportsSessionFork: true- Agent/Task updates with
_meta.claudeCode.toolName: "Agent" - a structured async child id in
_meta.claudeCode.toolResponse.agentIdBackchat treats that structured_metachild id as authoritative and keeps async-launched Claude subagents inrunningstate.
pnpm exec tsx scripts/smoke-claude-agent-acp-fork.tsperforms a realsession/forksmoke againstclaude-agent-acp@0.55.0: a parent session is asked to remember a random token, a child ACP session is created withforkFromAcpSessionId, and the child is asked for the token. The latest local run returnedparentSupportsSessionFork: true,childSupportsSessionFork: true, andchildMentionedToken: true.- On July 3, 2026, the ACP registry entry for
claude-acpreportedversion: "0.55.0"with distributionnpx @agentclientprotocol/claude-agent-acp@0.55.0, matching the smoke-tested dev dependency. - A real Codex CLI 0.142.5 run produced structured
collab_tool_callitems forspawn_agent,wait, andclose_agent; the child id appeared inreceiver_thread_ids, and the child result appeared inagents_states[child_id].message. The parser supports both barecollab_tool_callobjects and theitem.completedwrappers used bycodex exec --json; this shape is captured insrc/renderer/src/lib/native-agent-events.test.ts. - The dev dependency
@agentclientprotocol/codex-acp@1.1.0was added so the Codex ACP native-subagent shape is reproducible in development. A realpnpm run smoke:codex-acp-nativerun showed the adapter maps native multi-agent activity into ACPtool_call/tool_call_updateevents with titlesspawnAgent,wait, andcloseAgent. The child id is inrawInput.receiverThreadIds; child state/result is inrawInput.agentsStates; the latest local run captured one child id andCHILD_OK. Backchat normalizes this camelCase ACP shape too. The same smoke reportedsupportsSessionFork: false, so GUI side chats against currentcodex-acpshould start as subordinate fresh side sessions, not ACP-forked sessions.
Verification Notes
- The full Electron GUI path is covered by a static contract test plus renderer
screenshots of the right rail: the GUI can create
Side chat, cannot create native subagents, and passes ACP fork parameters only when the active runtime advertises session fork support.