Type Alias: AgentPaneEvent
agentmux / agent-pane-state-store / AgentPaneEvent
AgentPaneEvent = {
type:"init-ready"; } | {reason:string;type:"init-failed"; } | {at:number;type:"stream-subscribed"; } | {at:number;type:"stream-unsubscribed"; } | {at:number;lastKind:KindBeforeDisconnect;reason:DisconnectReason;type:"stream-disconnected"; } | {addedCount:number;type:"stream-flush-observed"; } | {idleSinceMs:number;recoverThresholdMs:number;thresholdMs:number;type:"stream-stuck"; } | {idleSinceMs:number;thresholdMs:number;type:"working-recovered"; } | {at:number;type:"turn-started"; } | {type:"turn-active-reconciled"; } | {at:number;type:"turn-inactive-reconciled"; } | {tokens:number;type:"context-reconciled-at-mount"; } | {model:string|null;reason:string;source:ContextSource;tokens:number;type:"context-reading-rejected";window:number|null; } | {model:string;reported:number;tokens:number;type:"context-window-refuted";window:number; } | {outcome:TurnOutcome;statsMerged:boolean;stoppingCleared:boolean;type:"turn-ended"; } | {type:"turn-reset"; } | {type:"turn-start-failed"; } | {reason:string;type:"turn-start-suppressed"; } | {name:string;type:"tool-started"; } | {type:"tool-ended"; } | {input:number|null;output:number|null;type:"tokens-updated"; } | {boundaryUuid?:string|null;durationMs?:number;frameTimestamp?:string|null;source:"real"|"heuristic";tokensAfter:number;tokensBefore:number;trigger?:"manual"|"auto";type:"context-compacted"; } | {trigger:"manual"|"auto";type:"compaction-started"; } | {trigger:"manual"|"auto";type:"compaction-started-buffered"; } | {reason:"rate_limited";type:"provider-waiting"; } | {code:AgentFailure["code"];turnWasEnded:boolean;type:"failure-observed"; } | {type:"failure-cleared"; } | {at:number;type:"stop-requested"; } | {type:"stop-failed"; } | {deadlineMs:number;type:"schedule-interrupt-timeout"; } | {at:number;type:"interrupt-timed-out"; } | {deadlineMs:number;type:"schedule-submit-timeout"; } | {at:number;type:"submit-timed-out"; } | {id:string;type:"pending-flush-started"; } | {id:string;type:"pending-queued"; } | {id:string;type:"pending-accepted";wasPresent:boolean; } | {id:string;type:"pending-rejected";wasPresent:boolean; } | {ageMs:number;id:string;queuedAt:number;type:"pending-expired";wasPresent:boolean; } | {question?:string;questionCount?:number;type:"waiting-for-input"; } | {reason:"submitted"|"typing"|"closed";type:"waiting-ended"; } | {at:number;type:"attached-task-observed"; } | {type:"attached-task-cleared"; } | {at:number;type:"registry-attached-task-observed"; } | {type:"registry-attached-task-cleared"; } | {at:number;type:"resume-retry-started"; } | {type:"resume-retry-resolved"; }
Defined in: agent-pane-state/types.ts:1069
Union Members
Section titled “Union Members”Type Literal
Section titled “Type Literal”{ type: "init-ready"; }
Type Literal
Section titled “Type Literal”{ reason: string; type: "init-failed"; }
Type Literal
Section titled “Type Literal”{ at: number; type: "stream-subscribed"; }
Type Literal
Section titled “Type Literal”{ at: number; type: "stream-unsubscribed"; }
Type Literal
Section titled “Type Literal”{ at: number; lastKind: KindBeforeDisconnect; reason: DisconnectReason; type: "stream-disconnected"; }
PR F: the stream tore down while a turn was in flight
(Submitting / Streaming / Interrupting). Surfaced alongside the
generic stream-unsubscribed so the view can drive a dedicated
“Disconnected — reconnecting…” banner without re-deriving from
turnPhase.kind. Emitted ONLY on the working-set → Disconnected
transition; idle-state unsubscribes do not emit it.
Type Literal
Section titled “Type Literal”{ addedCount: number; type: "stream-flush-observed"; }
Type Literal
Section titled “Type Literal”{ idleSinceMs: number; recoverThresholdMs: number; thresholdMs: number; type: "stream-stuck"; }
idleSinceMs
Section titled “idleSinceMs”idleSinceMs:
number
recoverThresholdMs
Section titled “recoverThresholdMs”recoverThresholdMs:
number
The bar that would actually force this turn back to Idle. Always
larger than thresholdMs, and larger still under a rate-limit
backoff. Reported because a diagnostic that shows only the warning
bar reads as “past the threshold and still stuck”, which is how a
real 5h stall was misread while it was in progress.
thresholdMs
Section titled “thresholdMs”thresholdMs:
number
The WARNING bar (STUCK_THRESHOLD_MS). Crossing it is cosmetic.
type:
"stream-stuck"
Stream has been silent for idleSinceMs while subscribed —
exceeds thresholdMs. Surfaced for diagnostics / UI badge.
Type Literal
Section titled “Type Literal”{ idleSinceMs: number; thresholdMs: number; type: "working-recovered"; }
idleSinceMs
Section titled “idleSinceMs”idleSinceMs:
number
thresholdMs
Section titled “thresholdMs”thresholdMs:
number
type:
"working-recovered"
The watchdog force-recovered a hung Streaming turn to Idle
after idleSinceMs ≥ LIVENESS_RECOVERY_MS with no tool active
and no rate-limit wait — i.e. a turn whose terminal session_end
was never observed (the persistent-mode stuck-”Working” class).
Surfaced for telemetry; the phase change is the real effect.
See SPEC_WORKING_STATE_LIVENESS_MODEL_2026_06_29.md.
Type Literal
Section titled “Type Literal”{ at: number; type: "turn-started"; }
Type Literal
Section titled “Type Literal”{ type: "turn-active-reconciled"; }
ReconcileTurnActive promoted the phase to Streaming because the
backend reported a turn already in flight — either the mount-default
Idle (the original case) or a settled Done.completed episode (the
focus-triggered reconcile’s missed-live-turn-start case). Surfaced
for diagnostics — distinguishes this from a normal user-initiated
turn-started. Not “-at-mount” anymore since it can now fire well
after mount.
Type Literal
Section titled “Type Literal”{ at: number; type: "turn-inactive-reconciled"; }
ReconcileTurnActive demoted a stuck Streaming phase to Idle
because the backend’s authoritative turn_active reported the turn
has ended (the result event fired) but the frontend never observed
the terminal session_end — the class behind the Agent1 stuck-”Working”
and Agent2 stuck-”Queued” incidents. Completes #2005’s reconciliation
symmetry (which only promoted Idle→Streaming). Surfaced for telemetry;
the phase change is the real effect. See
docs/retro/retro-agent2-stuck-queued-message-2026-07-16.md.
Type Literal
Section titled “Type Literal”{ tokens: number; type: "context-reconciled-at-mount"; }
ReconcileContextFromHistory seeded context from the restored
transcript’s last main-agent call at mount. Surfaced for diagnostics only.
Type Literal
Section titled “Type Literal”{ model: string | null; reason: string; source: ContextSource; tokens: number; type: "context-reading-rejected"; window: number | null; }
A reading that can’t be true (more tokens than its window, or than any
known window with none) was refused or will not display. Logged by the
pane store; the meter shows nothing rather than a wrong number. See
context-reading.ts implausibleReason.
Type Literal
Section titled “Type Literal”{ model: string; reported: number; tokens: number; type: "context-window-refuted"; window: number; }
An accepted prompt was larger than the window Claude Code reported for
its model, so the reported window can’t be right; the meter uses the
next known tier above the prompt instead. Logged once per model by the
pane store. context-reading.ts refutedReportedWindow.
Type Literal
Section titled “Type Literal”{ outcome: TurnOutcome; statsMerged: boolean; stoppingCleared: boolean; type: "turn-ended"; }
outcome
Section titled “outcome”outcome:
TurnOutcome
statsMerged
Section titled “statsMerged”statsMerged:
boolean
stoppingCleared
Section titled “stoppingCleared”stoppingCleared:
boolean
type:
"turn-ended"
A turn finished and the phase transitioned to Done. Since
the sound-notifications subsystem (SPEC_SOUND_NOTIFICATIONS_
2026_06_05.md §3.2), the event carries the outcome directly
so downstream consumers (notification sounds, telemetry,
future UI affordances) don’t have to snapshot the slot to
read it back from state.turnPhase.outcome. The reducer
already computes outcome two lines earlier — this is a
pure forwarding of an existing value.
Type Literal
Section titled “Type Literal”{ type: "turn-reset"; }
Type Literal
Section titled “Type Literal”{ type: "turn-start-failed"; }
Type Literal
Section titled “Type Literal”{ reason: string; type: "turn-start-suppressed"; }
reason
Section titled “reason”reason:
string
type:
"turn-start-suppressed"
Invariant fire: TurnStart while streaming inactive OR initPhase.kind === “InitPending” — dropped.
Type Literal
Section titled “Type Literal”{ name: string; type: "tool-started"; }
Type Literal
Section titled “Type Literal”{ type: "tool-ended"; }
Type Literal
Section titled “Type Literal”{ input: number | null; output: number | null; type: "tokens-updated"; }
Type Literal
Section titled “Type Literal”{ boundaryUuid?: string | null; durationMs?: number; frameTimestamp?: string | null; source: "real" | "heuristic"; tokensAfter: number; tokensBefore: number; trigger?: "manual" | "auto"; type: "context-compacted"; }
source: "real" — sourced from an authoritative CompactionBoundary
event (trigger/durationMs present). source: "heuristic" —
inferred from a ≥50%-drop in TokensIn (the pre-existing
cross-provider fallback; trigger/durationMs absent). See
docs/specs/SPEC_COMPACTION_DETECTION_AND_HANDLING_2026_07_31.md §4.3.
boundaryUuid?
Section titled “boundaryUuid?”
optionalboundaryUuid?:string|null
source: "real" only — see CompactionBoundary command’s doc comment.
durationMs?
Section titled “durationMs?”
optionaldurationMs?:number
frameTimestamp?
Section titled “frameTimestamp?”
optionalframeTimestamp?:string|null
source: "real" only — see CompactionBoundary command’s doc comment.
source
Section titled “source”source:
"real"|"heuristic"
tokensAfter
Section titled “tokensAfter”tokensAfter:
number
tokensBefore
Section titled “tokensBefore”tokensBefore:
number
trigger?
Section titled “trigger?”
optionaltrigger?:"manual"|"auto"
type:
"context-compacted"
Type Literal
Section titled “Type Literal”{ trigger: "manual" | "auto"; type: "compaction-started"; }
CompactionStarted landed — compaction is in progress.
Type Literal
Section titled “Type Literal”{ trigger: "manual" | "auto"; type: "compaction-started-buffered"; }
CompactionStarted arrived before turnPhase was confirmed working
— buffered onto state.pendingCompactionPing rather than dropped.
See SPEC_COMPACTION_STARTED_RECONCILIATION_RACE_2026_09_02.md.
Type Literal
Section titled “Type Literal”{ reason: "rate_limited"; type: "provider-waiting"; }
Type Literal
Section titled “Type Literal”{ code: AgentFailure["code"]; turnWasEnded: boolean; type: "failure-observed"; }
A failure was observed and recorded on state.failure. turnWasEnded
is true iff the pane’s turn was actually working (Submitting /
Streaming / Interrupting) at the time — surfaced for diagnostics
(e.g. distinguishing a genuine mid-turn failure from a stray late
event arriving after the pane was already idle).
Type Literal
Section titled “Type Literal”{ type: "failure-cleared"; }
state.failure was cleared (explicit dismiss, or implicitly by TurnStart).
Type Literal
Section titled “Type Literal”{ at: number; type: "stop-requested"; }
Type Literal
Section titled “Type Literal”{ type: "stop-failed"; }
Type Literal
Section titled “Type Literal”{ deadlineMs: number; type: "schedule-interrupt-timeout"; }
Reducer signal: a turn has just entered Interrupting. The
dispatch layer (view / saga) is expected to start a setTimeout
for INTERRUPT_TIMEOUT_MS and fire InterruptTimeoutElapsed
when it expires — gated by a shared cancel flag (analogous to
Arc<AtomicBool>) so a later RequestStop doesn’t double-fire.
deadlineMs is at + INTERRUPT_TIMEOUT_MS so the caller can
compute the remaining slice deterministically. Spec §8.
Type Literal
Section titled “Type Literal”{ at: number; type: "interrupt-timed-out"; }
Reducer signal: the bounded Interrupting → Done.{interrupted}
force-transition fired because no graceful ack arrived within
INTERRUPT_TIMEOUT_MS. The view can surface this as
“interrupt timed out — assuming dead” if needed. Spec §8.
Type Literal
Section titled “Type Literal”{ deadlineMs: number; type: "schedule-submit-timeout"; }
Reducer signal: a turn has just entered Submitting. The dispatch
layer is expected to start a setTimeout for SUBMIT_TIMEOUT_MS
and fire SubmitTimeoutElapsed when it expires — gated by a
shared cancel flag so a graceful promotion to Streaming (via
StreamFlushObserved or bumpEvent from tool / token activity)
cancels the timer before it fires. deadlineMs is
at + SUBMIT_TIMEOUT_MS so the caller can compute the remaining
slice deterministically. PR D — spec §8 / issue #728 gap 2.
Type Literal
Section titled “Type Literal”{ at: number; type: "submit-timed-out"; }
Reducer signal: the bounded Submitting → Done.{errored}
force-transition fired because no stream activity arrived within
SUBMIT_TIMEOUT_MS. Carries the firing wall-clock for audit.
PR D — spec §8 / issue #728 gap 2.
Type Literal
Section titled “Type Literal”{ id: string; type: "pending-flush-started"; }
Type Literal
Section titled “Type Literal”{ id: string; type: "pending-queued"; }
Type Literal
Section titled “Type Literal”{ id: string; type: "pending-accepted"; wasPresent: boolean; }
Type Literal
Section titled “Type Literal”{ id: string; type: "pending-rejected"; wasPresent: boolean; }
Type Literal
Section titled “Type Literal”{ ageMs: number; id: string; queuedAt: number; type: "pending-expired"; wasPresent: boolean; }
ageMs:
number
id:
string
queuedAt
Section titled “queuedAt”queuedAt:
number
type:
"pending-expired"
Pending entry expired and was removed; queuedAt for log/audit.
wasPresent
Section titled “wasPresent”wasPresent:
boolean
Type Literal
Section titled “Type Literal”{ question?: string; questionCount?: number; type: "waiting-for-input"; }
Emitted when the pane enters the waiting-for-input state: turn completed with a question, composer empty. The sound service starts the looping ambient tone on this event. Spec: SPEC_AGENT_WAITING_AMBIENT_SOUND_2026_06_19.md §6.3.
question?
Section titled “question?”
optionalquestion?:string
Text of the first pending question, when known. Consumed by the OS notification bridge, which forwards it to the srv router for redaction (SPEC_OS_NOTIFICATIONS_SYSTEM_2026_09_24.md §9.2).
questionCount?
Section titled “questionCount?”
optionalquestionCount?:number
How many questions the pending call asks — the toast adds ” (+N more)” when it’s more than one.
type:
"waiting-for-input"
Type Literal
Section titled “Type Literal”{ reason: "submitted" | "typing" | "closed"; type: "waiting-ended"; }
Emitted when the waiting state ends — user submitted or started typing, pane closed, or the 5-minute safety cutoff fired.
Type Literal
Section titled “Type Literal”{ at: number; type: "attached-task-observed"; }
AttachedTaskObserved set state.attachedTask (0→1 edge).
Type Literal
Section titled “Type Literal”{ type: "attached-task-cleared"; }
AttachedTaskCleared cleared state.attachedTask (1→0 edge).
Type Literal
Section titled “Type Literal”{ at: number; type: "registry-attached-task-observed"; }
RegistryAttachedTaskObserved set state.registryAttachedTaskSince.
Type Literal
Section titled “Type Literal”{ type: "registry-attached-task-cleared"; }
RegistryAttachedTaskCleared cleared state.registryAttachedTaskSince.
Type Literal
Section titled “Type Literal”{ at: number; type: "resume-retry-started"; }
ResumeRetryStarted set state.reconnecting (0→1 edge).
Type Literal
Section titled “Type Literal”{ type: "resume-retry-resolved"; }
ResumeRetryResolved cleared state.reconnecting (1→0 edge).