Interface: AgentPaneState
agentmux / agent-pane-state-store / AgentPaneState
Defined in: agent-pane-state/types.ts:318
The reducer’s state. Each field maps 1:1 to a Solid signal that the
agent pane projects from. The reducer enforces invariants ACROSS
fields (e.g. a turn can’t enter Submitting/Streaming while the
stream is unsubscribed — see the TurnStart arm).
PR G cleanup: turnActive / stopping (top-level) and active (on
streaming) have all been removed. state.turnPhase.kind is the
sole working-state encoding; “is the stream subscribed?” is now
derived from state.lastEventMs !== null (cleared atomically with
the stream on StreamSubscribe / StreamUnsubscribe).
Properties
Section titled “Properties”activity
Section titled “activity”activity:
ActivityState
Defined in: agent-pane-state/types.ts:353
What the agent is doing right now (see ActivityState).
attachedTask
Section titled “attachedTask”attachedTask:
AttachedTaskState
Defined in: agent-pane-state/types.ts:493
Live “attached long-running task” state, or null — see
AttachedTaskState. Deliberately NOT cleared by any TurnPhase
transition (TurnEnd/TurnReset/etc.): a task attached in one turn can
legitimately survive into later turns, so only its own two commands
(AttachedTaskObserved/AttachedTaskCleared) ever touch this field.
compacting
Section titled “compacting”compacting:
CompactionState
Defined in: agent-pane-state/types.ts:485
Live “compaction in progress” state, or null. See CompactionState.
context
Section titled “context”context:
ContextReading
Defined in: agent-pane-state/types.ts:452
The context meter’s reading: tokens in context, the model’s window, and
where each came from — see store/agent-pane-state/context-reading.ts.
Set by TokensIn (live) and ReconcileContextFromHistory (the
restored transcript, only while contextSeedable). Unlike turnTokens
it is NOT cleared at TurnEnd, so the meter shows the last known fill
between turns. Cleared on TurnReset (session wipe), ContextInvalidated
(the conversation was replaced) and CompactionBoundary (it no longer
measures anything until the next call). Displays read it through
plausibleReading, never directly.
contextSeedable
Section titled “contextSeedable”contextSeedable:
boolean
Defined in: agent-pane-state/types.ts:460
True until something more current than the restored transcript has
spoken: a live reading, an invalidation, a compaction or a reset.
ReconcileContextFromHistory seeds only while it holds — context
being null can’t tell “nothing yet” from “invalidated while history was
still loading”, and seeding the latter restores a dead conversation.
currentTool
Section titled “currentTool”currentTool:
string
Defined in: agent-pane-state/types.ts:329
currentToolArg
Section titled “currentToolArg”currentToolArg:
string
Defined in: agent-pane-state/types.ts:332
First significant argument of the active tool (file path, command, etc.). Cleared alongside currentTool on ToolEnd / TurnEnd / TurnReset.
detailsOpen
Section titled “detailsOpen”detailsOpen:
boolean
Defined in: agent-pane-state/types.ts:423
Whether the composer details panel — the Shell drawer, holding the
interactive terminal — is open. Default false. Persists across
renders within a pane lifetime; resets to false on pane unmount
(because a new pane gets a fresh state via initialState()). Not
persisted to backend — a per-session ephemeral preference.
It used to host the session banners and the Archive/Export/Restore
actions as well; those moved to AgentSessionNotices (above the
composer) and the AgentSessionStats popover respectively, and the
runtime dropdowns moved to the strip before that — leaving the drawer
to the shell alone. See
SPEC_AGENT_SHELL_DRAWER_INFO_PANEL_2026_09_19.md §3.
SPEC_AGENT_COMPOSER_SLIM_STATUS_2026_05_26.md §5.4. Previously
auto-collapsed on TurnStart; removed once the panel started
hosting a live interactive shell (AgentShellSubblock) that needs
to survive sending more messages, not close on every send.
failure
Section titled “failure”failure:
PaneFailure
Defined in: agent-pane-state/types.ts:483
Active classified failure for this pane, or null. Set by
FailureObserved (which also force-ends a working turn — see the
command’s reducer case), cleared by FailureCleared or implicitly
by the next TurnStart (a fresh turn always ends the failure
episode). See PaneFailure.
initPhase
Section titled “initPhase”initPhase:
InitPhase
Defined in: agent-pane-state/types.ts:383
Init phase — InitPending until history fetch resolves (or fails).
Discriminated union; failure reason lives in the InitFailed
variant’s reason payload — no separate initError field.
lastCompactionBoundaryAt
Section titled “lastCompactionBoundaryAt”lastCompactionBoundaryAt:
number
Defined in: agent-pane-state/types.ts:532
Wall-clock ms of the most recent REAL CompactionBoundary event
(backend-sourced, exact — not the ≥50%-drop heuristic below). The
TokensIn heuristic checks this before firing its own synthetic
context-compacted event, so a Claude session that just got a
real boundary doesn’t also get a duplicate heuristic-sourced one
for the very next turn’s token drop. Providers without a
structured signal (codex/gemini/copilot) never set this, so the
heuristic remains their only detection path. See
docs/specs/SPEC_COMPACTION_DETECTION_AND_HANDLING_2026_07_31.md §4.3.
lastContextModel
Section titled “lastContextModel”lastContextModel:
string
Defined in: agent-pane-state/types.ts:475
Resolved model id of the main agent’s latest reply (message.model).
The Runtime menu shows it; the context reading is measured on it.
lastEventMs
Section titled “lastEventMs”lastEventMs:
number
Defined in: agent-pane-state/types.ts:394
Wall-clock ms of the last observable stream activity (subscribe, flush, tool, tokens). Drives the stuck-stream watchdog.
Doubles as the “is the stream subscribed?” gate since PR G:
lastEventMs !== null ⇔ the pane has seen a StreamSubscribe
that no subsequent StreamUnsubscribe has cleared. Both fields
always moved in lockstep when the legacy streaming.active
boolean existed, so the substitution is exact.
learnedContextWindows
Section titled “learnedContextWindows”learnedContextWindows:
ContextWindowMap
Defined in: agent-pane-state/types.ts:472
Context windows proven per model by an accepted prompt larger than the
window we had (context-reading.ts learnedWindowsAfter). Outlive
TurnReset for the same reason as reportedContextWindows.
pending
Section titled “pending”pending:
PendingMessage[]
Defined in: agent-pane-state/types.ts:377
pendingCompactionPing
Section titled “pendingCompactionPing”pendingCompactionPing:
object
Defined in: agent-pane-state/types.ts:548
A compaction_started ping the reducer rejected because turnPhase
wasn’t (yet) working, but which arrived on a phase a LATER
authoritative signal could still legitimately promote for THIS SAME
turn — ReconcileTurnActive(active: true) or StreamFlushObserved’s
own promotion arm, both of which retroactively apply it into
compacting on promotion. Cleared whenever that promotion happens,
whenever an authoritative signal proves the turn is genuinely NOT
running (ReconcileTurnActive(active: false), even when that’s a
same-ref no-op for turnPhase itself), by a fresh unrelated
TurnStart (not the turn this ping was about), or by any of the
other “whatever compaction was in flight is now moot” terminal
transitions compacting itself already clears on. See
docs/specs/SPEC_COMPACTION_STARTED_RECONCILIATION_RACE_2026_09_02.md.
startedAt
Section titled “startedAt”startedAt:
number
trigger
Section titled “trigger”trigger:
"manual"|"auto"
pendingCompactTurn
Section titled “pendingCompactTurn”pendingCompactTurn:
boolean
Defined in: agent-pane-state/types.ts:376
True for the duration of a turn started specifically to send a
manual “/compact” (the composer’s “Compact now” button, or a user
typing it) — set on TurnStart when command.content === "/compact",
consumed and reset by CompactionBoundary. Exists because a manual
CompactionBoundary.trigger alone is NOT a safe signal that THIS
pane’s currently-working turn is the synthetic one that action
opened: the reducer’s own tests deliberately model a manual
boundary landing while an unrelated real turn is already streaming
(compaction_started/compact_boundary travel over independent
transports with no ordering guarantee against the primary NDJSON
stream — see the CompactionStarted race-guard tests). Only end the
turn when we know FOR THIS PANE that its own working turn is the
one the manual compact opened. codex P1 on PR #2659.
reconnecting
Section titled “reconnecting”reconnecting:
ResumeRetryState
Defined in: agent-pane-state/types.ts:500
Live “reconnecting after a stale --resume session id” state, or
null — see ResumeRetryState. Owned exclusively by
ResumeRetryStarted/ResumeRetryResolved, dispatched from
useResumeRetryStream.ts.
registryAttachedTaskSince
Section titled “registryAttachedTaskSince”registryAttachedTaskSince:
number
Defined in: agent-pane-state/types.ts:520
Earliest started_at_ms among this block’s currently-Running
db_background_tasks rows (Phase A/B of
docs/specs/SPEC_BACKGROUND_TASK_DASHBOARD_INTELLIGENCE_2026_08_20.md),
or null. A SEPARATE floor signal, not a duplicate of attachedTask
above: the durable registry can know about a task the live transcript
has no record of at all (e.g. it survived a session restart under a
fresh controller generation — Phase B). Deliberately owned
EXCLUSIVELY by its own two commands
(RegistryAttachedTaskObserved/RegistryAttachedTaskCleared,
dispatched only from useBackgroundTaskRegistry.ts) — no other
command touches it, specifically so the transcript-derived
attachedTask axis’s own independent recompute-and-clear effect
(agent-view.tsx’s attached-task effect) can never stomp on it. The
effect instead READS this field and combines it with its own
transcript-derived value (registry ∪ transcript, earliest start
wins) rather than treating either source as sole truth. See the
Codex P1 finding on PR #2685 this was written to address.
reportedContextWindows
Section titled “reportedContextWindows”reportedContextWindows:
ReportedContextWindows
Defined in: agent-pane-state/types.ts:466
Context windows Claude Code reported in result.modelUsage, per model
id. They outrank the model-name table for any reading on that model, and
outlive TurnReset: a model’s window is a fact about the model.
sessionStats
Section titled “sessionStats”sessionStats:
SessionStats
Defined in: agent-pane-state/types.ts:320
sessionTotals
Section titled “sessionTotals”sessionTotals:
SessionStats
Defined in: agent-pane-state/types.ts:328
Cumulative cost/tokens/duration across every completed turn in this
pane’s lifetime — unlike sessionStats (which is replaced, not
accumulated, on each TurnEnd), this sums into the previous value.
Feeds the composer-strip “totals” display near the input. Cleared
only on TurnReset. See SPEC_AGENT_SESSION_COST_TOTALS_2026_07_02.md.
stashOpen
Section titled “stashOpen”stashOpen:
boolean
Defined in: agent-pane-state/types.ts:440
Whether the Stash drawer (the per-agent Accounts/Memory/MCP/Skills/ Startup/Registration surface) is open, top-anchored under the pane header — SPEC_AGENT_STASH_PANE_MIGRATION_2026_09_22.md §3.3.
A SEPARATE axis from detailsOpen (the bottom-anchored shell
drawer), deliberately: the two are independent surfaces a user can
have open at once, and mutual exclusion would silently close a live
shell holding real terminal state (§6 open question 1, answered in
favor of independence). The transcript is protected from being
squeezed by a CSS max-height on the Stash drawer, not by forcing
one of the two closed.
Like detailsOpen, NOT auto-collapsed on TurnStart — sending a
message must not yank a surface the user deliberately opened.
streaming
Section titled “streaming”streaming:
StreamingState
Defined in: agent-pane-state/types.ts:319
turnCarry
Section titled “turnCarry”turnCarry:
TurnCarry
Defined in: agent-pane-state/types.ts:360
Each pass’s own figures (its TurnEnd stats), summed over the turn srv
reported it in. For providers whose passes srv doesn’t count (ACP, App
Server, one-shot subprocess: no result usage reaches the ledger), the
Worked line reports the turn from this.
turnLedger
Section titled “turnLedger”turnLedger:
TurnLedger
Defined in: agent-pane-state/types.ts:351
The turn as the user sees it, over however many CLI passes: srv’s
agentturn event, verbatim (turn-ledger.ts). Null until srv has
published one for this block. The working row runs its clock and counter
from it; turnPhase and turnTokens stay per pass.
turnPhase
Section titled “turnPhase”turnPhase:
TurnPhase
Defined in: agent-pane-state/types.ts:402
Single-source-of-truth turn phase. PR A added it with dual-write
against the legacy turnActive / stopping / streaming.active
booleans; PR B migrated every view consumer onto it via
isWorking(state) / isDisconnected(state) /
state.turnPhase.kind; PR G removed the legacy fields.
turnTokens
Section titled “turnTokens”turnTokens:
TurnTokens
Defined in: agent-pane-state/types.ts:344
The current turn’s live usage, from the stream. Its lifetime follows the
stream’s own order: set by TokensIn, cleared by that turn’s TurnEnd,
or by StreamSessionStarted when the process died before a result.
Nothing outside the stream clears it on a normal turn end:
ReconcileTurnActive, the liveness recovery and TurnStart all leave
it alone, because srv sends the turn-ended push before it forwards the
result line, so the turn’s session_end (and sometimes earlier calls)
still follow, and a queued message or the next turn can start in that
gap. Hard ends (disconnect, failure, timeouts, reset) clear it.