Skipped UUID-shaped positional normalization while startup parsing still contains unrecognized extension flags, then normalized the extension-aware parse.
Signed-off-by: Christian Stewart <christian@aperture.us>
Normalized UUID-shaped --continue targets on the extension-aware argument parse so the session id cannot leak back into the initial prompt.
Signed-off-by: Christian Stewart <christian@aperture.us>
Treated a UUID passed after --continue as an explicit session target so a missing id cannot fall back to the latest persisted session.
Signed-off-by: Christian Stewart <christian@aperture.us>
Close pending tool turns recorded during normal shutdown and apply interrupted-tail recovery when switching or reloading sessions.
Signed-off-by: Christian Stewart <christian@aperture.us>
Skip interrupted-turn recovery when an error or aborted assistant already closed its tool calls with synthetic results.
Signed-off-by: Christian Stewart <christian@aperture.us>
Detect pending tool calls from assistant content and use the selected model metadata to terminate first-turn user tails after abnormal process exits.
Signed-off-by: Christian Stewart <christian@aperture.us>
Appended one terminal aborted assistant record when a persisted abnormal-exit diagnostic follows a non-terminal transcript tail, preserving partial history while making resumed context valid.
Signed-off-by: Christian Stewart <christian@aperture.us>
- Removed the `computeTokensPerSecond` helper function in favor of a direct calculation.
- Standardized throughput to use total request duration instead of post-TTFT decode time.
- Updated UI usage display to calculate tokens per second against total duration.
- Prevented over-inflation of throughput metrics caused by hidden reasoning tokens.
- Integrated performance statistics (TPS/TTFT) into ModelBrowser and ModelHub components with adaptive visibility.
- Decoupled mouse wheel behavior from selection logic to enable smoother viewport panning.
- Improved UI navigation by preventing unwanted wrapping in role indexes and adding viewport snapping logic.
- Added comprehensive test suites to verify performance display rendering and corrected input interaction behavior.
- Added `model_perf` table to store persistent, recency-weighted TPS and TTFT statistics per model.
- Introduced `AgentStorage.recordModelPerf` to asynchronously capture and aggregate turn timing metrics.
- Implemented a background backfill mechanism to migrate historical request data from `stats.db` into new performance aggregates.
- Updated `AgentSession` to record performance metrics upon turn completion.
- Bumped `SCHEMA_VERSION` to 6 and cleared existing performance data to account for improved duration-based TPS calculation.
- Relocated `AsyncDrain` class from `coding-agent` to `utils` package.
- Updated `HistoryStorage` to import `AsyncDrain` from shared utilities.
- Centralized the utility to allow reuse across the codebase.
AgentSession defers and coalesces the wire-level agent_end while a
prompt is in flight (#emitSessionEvent), so a multi-attempt retry saga
often surfaces only ONE agent_end to EventController — which can be
the final settle, not an intermediate attempt. Consuming #retryPending
against whichever agent_end arrived first (previous commit) could
therefore discard the real final failure notification.
Switch to gating purely on the retry lifecycle: #retryPending is set
by auto_retry_start and cleared only by auto_retry_end (both
outcomes), never consumed by sendErrorNotification itself. Those
lifecycle events are never deferred, so they reliably bracket the
window a retry is actually outstanding regardless of how agent_end
coalescing lands.
Close the residual gap this creates: #handleRetryableError's
classifier-refusal and Fireworks-fallback-ineligible branches could
short-circuit a saga that already announced auto_retry_start without
ever emitting auto_retry_end, latching #retryPending open forever.
Both branches now emit a final auto_retry_end(false) when a prior
attempt already started the saga. #handleAgentStart also clears
#retryPending defensively so a saga that still somehow never resolves
cannot suppress a later, unrelated turn's notification.
A retryable error's agent_end fires with the failed assistant message
(stopReason === 'error') the instant #handleRetryableError schedules a
retry (auto_retry_start), before the retry has a chance to recover.
sendErrorNotification read that transient agent_end the same as a real
final settle, so error.notify=on raised a 'Stopped with error' toast
even for turns that went on to succeed on retry.
Track a #retryPending flag set on auto_retry_start and consumed
(check-then-clear) by sendErrorNotification, so exactly one mid-retry
agent_end is suppressed per attempt. #handleAutoRetryEnd also clears it
directly on both success and failure so a recovered retry never leaves
it stuck; consuming it on read (rather than only via auto_retry_end)
keeps it self-healing for the classifier-refusal short-circuit path,
which can return from #handleRetryableError without ever emitting a
fresh auto_retry_end.
- Prioritized fuzzy match quality over the most-recently-used model order when filtering the model browser.
- Added bucketing to match scores to ensure stable sorting when match quality is identical.
- Added unit tests to verify that exact query matches take precedence over the MRU model.
- Implemented `/queue` command and `->`/`=>` shorthands to support deferred, sequential message processing.
- Added a robust parsing utility to handle various list-based queue inputs and automate yield management.
- Integrated visual decorations and state tracking to provide real-time feedback on queueing status.
- Enabled non-cursor line text decoration in the TUI to support dynamic queue header rendering and list numbering.
- Implemented model-specific keys and provider wildcards for `retry.fallbackChains` with updated resolution logic.
- Added interactive fallback chain management in the model roles UI, including support for reordering and editing.
- Improved fallback chain specificity rules and added comprehensive validation with startup warnings.
- Fixed mouse interaction alignment and hover state coordinate mapping in the roles view.
- Prevent selected chips from being hidden when the role strip row overflows.
- Implement horizontal scrolling with a leading ellipsis to maintain visibility of the selection and lookahead context.
- Added an `invalidate` action to the usage CLI to clear cached usage reports for specific or all providers.
- Updated `invalidateUsageCache` in `AuthStorage` to be asynchronous and notify the underlying store of invalidations.
- Updated task synchronization to include all todo phases regardless of completion status.
- Removed logic that filtered out completed or abandoned tasks during session synchronization.
Removed accepted empty Auto-Learn capture stops from live and persisted context, including the hidden capture prompt when it directly parents the no-op stop.
Extended the regression to prove the next real prompt does not replay the stale Auto-Learn nudge.
Fixes#5211
- Forwarded the session provider state map to ephemeral side-channel turns so Codex can allocate websocket transport state for the side request session id.
- Extended the /btw side-channel regression to assert providerSessionState reaches the stream options with the websocket preference.
Fixes#5213
- Preserved the session websocket preference for ephemeral /btw side-channel turns so Codex websocket-only models do not fall back to SSE.
- Prioritized active /btw and /omfg panels in Esc handling before loop, maintenance, and main-turn interrupts.
- Added regression coverage for side-channel websocket options and /btw Escape priority.
Fixes#5213
Cleared the terminal empty-stop acceptance flag for every agent-initiated prompt so non-opt-in custom turns cannot inherit Auto-Learn capture behavior.
Added a regression covering a non-opt-in custom turn after a non-empty Auto-Learn capture response.
Fixes#5211
Marked Auto-Learn capture turns as accepting terminal empty assistant stops so the empty-stop guard does not retry the expected no-reply completion.
Added a focused AgentSession regression covering the auto-continue capture turn.
Fixes#5211
Treat content-less advisor stop completions as failed turns so the advisor retry/drop path handles silent provider responses instead of accepting them as successful reviews.
Fixes#5212
Blockers from final review:
- runtime.ts:457 TS2741: #collectAndMaintainBatch now returns wip in its
result type; #drain destructures it and passes it to the retry-requeue
unshift — a WIP batch that fails retry no longer silently loses its
[in progress] heading.
- agent-session.ts import order: annotateForStaleness moved before
formatAdvisorBatchContent (biome enforces case-insensitive alpha order).
Cap edge case (advisor nit + review CONCERN): final round of the
coalescing for-loop now breaks BEFORE the late-item splice so any
deltas that arrived during round MAX_COALESCE_ROUNDS-1's
maintainContext call stay in #pending for the next drain iteration
instead of being merged into an unbudgeted batch. Doc comment updated
to match ('left for the next drain iteration' is now accurate).
Cap test: bounded version that only pushes new turns for the first 3
maintainContext calls so the drain while-loop terminates cleanly after
a second iteration. The previous unbounded version created an infinite
drain loop (each maintainContext call unconditionally pushed another
turn) and timed out.
Blocker: wip field added to PendingDelta and threaded into the reprime
path. #collectAndMaintainBatch now captures the most-recent WIP state
from each delta batch and forwards it to #renderDelta in both the
normal and reprime branches, so a willContinue:true turn never loses
its [in progress] heading through a reprime.
Safety cap: MAX_COALESCE_ROUNDS=3 constant defined and used in the
coalescing for-loop, preventing indefinite dispatch stall under
pathological fast-primary + slow-maintainContext conditions.
Testability: annotateForStaleness extracted as an exported pure function
in advise-tool.ts and used in AgentSession#routeAdvice. Three unit
tests added in advisor.test.ts covering the no-staleness, staleness,
and note-preservation contracts. This addresses the ReviewSession
regression-test concern without requiring a full AgentSession harness.
Reprime turn-tally coverage: new test 'backlog stays accurate when a
delta arrives during the reprime-triggering maintainContext' asserts
runtime.backlog === 0 after all three turns, catching a deleted
turns += reduce(...) line.
Fragile double-await tests converted: sends-batch-when-maintenance-fails
and expands-plan-mode-context now use Promise.withResolvers signals
instead of counted await Promise.resolve() hops.
Docs: onTurnEnd JSDoc added; hasFreshBacklog comment broadened to cover
all drain-busy phases (not just agent.prompt).
Three related changes that address the pattern of the advisor flagging things
the primary already fixed:
Fix 1 — coalesce late-arriving deltas before agent.prompt (runtime.ts)
Refactored #drain into a reusable #collectAndMaintainBatch helper that loops
until the pending queue is stable (no new deltas arrive during a maintenance
check) before calling agent.prompt. Previously, any turn queued during the
maintainContext await was deferred a full extra model-call cycle; now it is
merged into the current batch after re-checking the token budget for the
expanded payload. Every await in the loop has an epoch guard so a
reset/dispose mid-await cannot leak a stale batch. finalTurns always counts
all merged turns so #backlog decrements correctly.
Fix 2 — hasFreshBacklog + delivery-time staleness annotation (runtime.ts, agent-session.ts)
Added AdvisorRuntime.hasFreshBacklog getter (true when #pending.length > 0
while agent.prompt is running — i.e., newer primary turns arrived after the
reviewed window). #routeAdvice checks it at delivery time and appends a
lightweight caveat to the note so the primary agent knows to verify before
acting. Uses #pending.length not #backlog, which is always > 0 mid-call.
Fix 3 — willContinue WIP marker in rendered delta + system prompt (runtime.ts, agent-session.ts, system.md)
onTurnEnd now accepts { willContinue } and passes it through to #renderDelta,
which tags the heading '[in progress — more steps follow]' for intermediate
turns. The agent-session.ts call site passes context.willContinue. The advisor
system prompt instructs the model to withhold critique on WIP updates.
Also fixed pre-existing inline casts in #renderDelta and #dedupContextMessage
that suppressed the type checker instead of using the narrowing already provided
by the role discriminant.
All 75 advisor tests pass; pre-existing type errors in cursor.ts are unrelated.
- Removed the bash command fixup system and associated logic from both the Rust and TypeScript components.
- Deleted the redundant fixup module and its exported implementations.
- Updated technical documentation and configuration settings to reflect the removal of pre-execution bash command rewriting.
- Added `conflict://*` support to the `write` tool, allowing resolution of multiple conflicts in a single call using per-id directives.
- Implemented `parseBulkDirectives` to interpret `ID: @side` mappings from the raw input content.
- Enabled partial bulk resolution where unlisted conflict IDs remain registered for subsequent operations.
- Updated conflict documentation and tool summaries to reflect the new bulk resolution capability.
- Enabled persistence of dangling tool calls during transcript rebuilds by adding `keepDanglingToolCalls` configuration.
- Integrated `seal()` logic for pending tool blocks to properly finalize history during idle session states.
- Enhanced UI helpers and session context to preserve assistant turns during streaming or mid-turn rebuilds.
- Added comprehensive unit and integration tests to verify correct tool call tracking and transcript integrity.
- Included the current session name in the fullscreen pause UI.
- Updated `renderPauseScreen` and `InteractiveModeContext` to propagate and display the session title.
- Added test coverage for both full and compact pause screen layouts.
- Replaced silent budget-based termination with a graceful stop and forced-yield mechanism.
- Implemented resumable subagent states to preserve agent context upon budget exhaustion.
- Increased default soft request budget to 200 and updated IRC bus signaling to distinguish between active, resumable, and hard-aborted statuses.
- Added comprehensive status-aware prompts and unit tests to verify non-terminal abort behavior.
- Introduced an `AgentPauseGate` mechanism to suspend and resume agent loops and tool executions safely.
- Added a `/pause` slash command to trigger a new fullscreen UI that manages agent suspension and lifecycle.
- Integrated pause checks into the core agent loop and tool execution pipeline to ensure responsive state handling.
- Provided a new pause screen component to facilitate user interaction and resume control during suspension.
- Update `IrcBus.wait` to accept a `liveness` configuration, automatically aborting waits if the specified sender or relevant peers transition to an idle state.
- Enhance `IrcTool` to utilize liveness monitoring during `wait` operations, ensuring the agent does not hang if target peers become unreachable.
- Refactor `IrcBus.wait` to unify internal settlement logic and improve cleanup robustness.
- Implemented logic to automatically detect and trim redundant lines duplicating adjacent file content within conflict markers.
- Added delimiter balancing and boundary tracking to ensure accurate removal of echoed text while preserving EOL formatting.
- Updated user feedback to report the number of trimmed echo lines during write and conflict resolution operations.
- Expanded test coverage to include multi-line echo scenarios and integration validation of the repair process.