Commit Graph
824 Commits
Author SHA1 Message Date
Matt Wilkinson e86a6ede24 fix(session): drop content-less provider-rejection turns from persisted history
A request the provider rejects (e.g. 413 oversized payload) yields a
synthesized assistant turn with empty content and stopReason 'error'.
That turn is written to session.jsonl, so on reload it replays as an
empty assistant turn and re-sends the same rejected context. Keep the
rejection UI-only (pinned error) and out of persisted history so a
reloaded session resumes from the last good turn.
2026-07-03 09:21:53 -04:00
can1357 43856f70d9 Merge remote-tracking branch 'origin/farm/8994bf65/rebind-advisor-model-role' 2026-07-02 23:43:09 +02:00
can1357 234a46fa3f feat(session): delayed session termination for pending async background jobs
- Added `#hasPendingAsyncWake` to detect running or pending background jobs owned by the agent.
- Deferred todo reminders and `session_stop` hook passes until all agent-owned background async jobs complete.
- Ensured scheduling pauses caused by async jobs do not trigger terminal session stops or premature todo nags.
2026-07-02 23:14:22 +02:00
can1357 d82b9bdc5f feat(agent): allowed dynamic model resolution per LLM call
- Added `getModel` to `AgentLoopConfig` to allow runtime model resolution.
- Updated `streamAssistantResponse` to resolve the model dynamically per provider call instead of using the stale configuration snapshot.
- Enabled mid-run model switches to take effect immediately for context promotion and retry fallbacks.
2026-07-02 22:43:11 +02:00
roboomp d41d0c4253 fix(agent): kept advisor enable idempotent
Compared the resolved advisor runtime inputs before rebuilding on explicit enable so unchanged /advisor on calls keep the live advisor agent and history.

Added regression coverage for the unchanged-config path preserving advisor context.

Fixes #4302
2026-07-02 11:36:07 +00:00
roboomp f3834dfce8 fix(agent): rebuilt advisor on explicit enable
Rebuilt live advisor runtimes when the explicit enable path runs so changed modelRoles.advisor values are re-resolved without restarting the session.

Added a regression test covering a live advisor moving from one role model to another through setAdvisorEnabled(true).

Fixes #4302
2026-07-02 11:27:47 +00:00
can1357 88f0aab994 style: formatted eval fix commits with biome 2026-07-02 10:34:53 +02:00
can1357 71209f025d fix(session): drop stale plan-mode-decision tool choice on skip/exit
The settle-time reminder queues a hard 'required' tool choice paired with a
scheduled continuation. If that continuation never runs (user prompt bumps
the generation, dispose, compaction/handoff) or plan mode is exited first,
the queued directive leaked onto the next unrelated turn as a forced tool
call. Remove it by label on continuation skip, on user-initiated prompts,
and when plan mode is disabled.
2026-07-02 10:30:51 +02:00
can1357 2875dd3349 merge PR #3911: fix(session): converge plan mode on ask/resolve across continuation paths (@metaphorics)
# Conflicts:
#	packages/coding-agent/src/session/agent-session.ts
2026-07-02 10:30:51 +02:00
can1357 4940a053ad merge PR #3777: Fix todo HUD and goal context follow-ups (@jeffscottward) 2026-07-02 10:30:12 +02:00
roboomp a06d0c54b3 fix(session): switched models during goal recovery
Removed the live-context guard that let default model selection persist a new role without changing the active session model. The next prompt's compaction path now owns oversized-context recovery after a switch.

Fixes #4219
2026-07-02 06:48:30 +00:00
can1357 0d96c2b6ec Merge remote-tracking branch 'origin/farm/bf21f607/frame-rewind-completion'
# Conflicts:
#	packages/coding-agent/src/session/agent-session.ts
#	packages/coding-agent/test/agent-session-checkpoint-rewind-branch.test.ts
2026-07-02 03:56:59 +02:00
roboomp 0b8164facb fix(agent): restored active checkpoints when rehydrating rewind state
The branch-scan rehydrator only rebuilt `#lastCompletedRewind` and wiped
`#checkpointState` unconditionally at entry — so a branch whose latest
checkpoint had not yet been rewound came back with neither an active
checkpoint nor completed-rewind guidance. Reloading such a session (or
`switchSession()` on the same file) made the next `rewind` fail with
"No active checkpoint" even though the checkpoint entry was still the
branch leaf.

Extended the walker to also track the last unresolved checkpoint entry
and, when the branch ends without a rewind-report, seed `#checkpointState`
from that entry (id, `details.startedAt`) so `rewind` can complete
normally. Renamed the method to `#rehydrateCheckpointRewindState` to
reflect the widened responsibility and added a regression test that
truncates the branch to the checkpoint entry, resumes into a fresh
`AgentSession`, and calls `rewind` end-to-end.

Fixes #4187
2026-07-02 01:33:21 +00:00
can1357 3660b0973a chore: revert brain damage 2026-07-02 03:29:30 +02:00
roboomp a030373665 fix(agent): cleared rewind state on session resets
Cleared checkpoint rewind runtime state when starting new sessions or creating branch sessions so stale completed-rewind guidance cannot leak into unrelated contexts.

Added regression coverage for /new and branch reset paths.

Fixes #4187
2026-07-02 01:19:18 +00:00
roboompandcan1357 cf570a90f0 fix(agent): rehydrated completed rewind state
Reconstructed the completed rewind marker from the active branch so resumed sessions keep repeat-rewind recovery guidance.

Covered resume rehydration with the checkpoint rewind branch regression test.

Fixes #4187
2026-07-02 03:17:17 +02:00
roboomp 125dd36ead fix(agent): rehydrated completed rewind state
Reconstructed the completed rewind marker from the active branch so resumed sessions keep repeat-rewind recovery guidance.

Covered resume rehydration with the checkpoint rewind branch regression test.

Fixes #4187
2026-07-02 01:09:44 +00:00
can1357 0159d86023 Merge remote-tracking branch 'origin/farm/bf21f607/frame-rewind-completion' 2026-07-02 03:08:23 +02:00
can1357 b149cfce71 feat(coding-agent): implemented targeted mid-run todo nudges for mutating tools
- Refactored the mid-run todo nudge to trigger on mutating tools (bash, eval, edit, write, ast_edit) rather than overall tool turns.
- Simplified the nudge prompt template to a concise, non-escalating reminder.
- Migrated nudge messages from "developer" role with public events to a hidden "custom" role that is excluded from the TUI and transcript.
- Introduced a separate per-cycle reminder cap of 2 to decouple mid-run hints from the user-visible stop-time escalation budget.
- Avoided triggering the todo nudge when read-only exploration tools (e.g. grep, read, glob, lsp) or errored results are returned.
2026-07-02 03:03:23 +02:00
roboomp 1109c25629 fix(agent): framed completed rewind context
Wrapped retained rewind reports with completion guidance so the post-rewind turn knows the checkpoint is closed.

Added repeat-rewind recovery errors and regression coverage for both the retained context and no-active-checkpoint path.

Fixes #4187
2026-07-02 00:56:06 +00:00
can1357 0e2feab742 refactor(coding-agent): reduced session log footprint
- Projected full tool-call arguments down to a compact summary containing only `command` and `path`.
- Truncated summarized argument fields to 200 characters to prevent inflating session log sizes.
- Replaced routine clean session disposal warnings with debug logs to reduce noise.
- Streamlined debug context in assistant message removal and agent continuation skip paths.
- Extracted duplicate user-facing compaction warning strings into a helper function.
2026-07-02 02:40:08 +02:00
can1357 1b458f2e61 fix(coding-agent): preserved teardown exit reasons during session disposal
- Thread the postmortem reason through the session teardown pipeline to the session dispose process.
- Prevent generic "dispose" logs from overwriting real triggers like SIGTERM, SIGHUP, or uncaught exceptions.
- Ensure the first teardown trigger's reason is preserved when concurrent disposal calls occur.
- Add comprehensive test coverage verifying signal-specific reason mapping inside exit diagnostics.
- Fix a minor unhandled-exception test utility expectation in input controller tests.
2026-07-02 01:51:10 +02:00
can1357 73ef29bd00 fix(session): corrected branch traversal order breaking ctrl+p cycling
- Removed a duplicated branch.reverse() left by the PR #3862 merge in
  SessionEntryIndex.pathTo(), which returned branches leaf-to-root and made
  getLastModelChangeRole() read the oldest model change instead of the
  newest — pinning the ctrl+p cycle to one slot and breaking session model
  restore.
- Hardened getRoleModelCycle() to trust the recorded role only while its
  resolved model still equals the active model, falling back to matching by
  model after switches through alt+m, /model, or retry fallback.
- Added mutation-verified regression tests for branch ordering and the
  stale-role fallback.
2026-07-01 23:48:26 +02:00
can1357 1bf06d9cec Merge PR #3640 (selective): advisor inherits main agent promptCacheKey (@roboomp)
Ports only the advisor cache-key fix (advisorPromptCacheKey = agent.promptCacheKey ?? advisorSessionId) + its provider-options parity regression. tan/shared sessions read the parent provider cache shard byte-for-byte. Excludes the unrelated CI-isolation test commit e3160a09c. Fixes #3639.
2026-07-01 22:34:13 +02:00
can1357 2e53c40c9e Merge PR #3412 (selective): clamp compaction reserve budget for small windows (@wolfiesch)
Cherry-pick of the reserve-budget clamp only (resolveBudgetReserveTokens + no-op compaction guard): applies compaction.ts + agent-session.ts + compaction/shake/progress-guard tests. Excludes unrelated Julia prelude timeout and ai/test churn from the PR head.
2026-07-01 22:29:53 +02:00
can1357 a5a7b5b77c fix(coding-agent): limit mnemopi shutdown timeout to interactive exit 2026-07-01 22:22:09 +02:00
roboompandcan1357 efaad3ffb5 fix(coding-agent): bounded mnemopi consolidate-on-dispose so /quit returns within ~2 s
/quit and /exit hung for many seconds because AgentSession.dispose()
awaited MnemopiSessionState.dispose() unconditionally, and that path
runs consolidate() (state.ts:421) which fires a fresh LLM fact
extraction for the just-retained transcript and then awaits
flushExtractions() per owned bank. One LLM round-trip per shutdown,
no upper bound, no visible status.

- Add a timeoutMs option to MnemopiSessionState.dispose. When the cap
  fires the in-flight consolidate is detached to the background and the
  SQLite handles close once it settles, so writes never race a closed
  handle.
- AgentSession.dispose passes SHUTDOWN_CONSOLIDATE_BUDGET_MS = 1_500 on
  the user-visible shutdown path. Per-turn maybeRetainOnAgentEnd has
  already retained earlier turns, so the worst case is losing episodic
  promotion for the last few turns. State-replacement disposes
  (mnemopiBackend.start) stay unbounded.
- InteractiveMode.shutdown surfaces a 'Closing session…' status before
  dispose runs so the brief pause is explained rather than mysterious.

Two regression tests in memory-tools.test.ts cover (1) dispose returns
within the budget when flushExtractions stalls and the deferred close
still runs once consolidate settles, and (2) unbounded dispose still
runs the full #2320 consolidate-then-close pipeline.

Fixes #3641
2026-07-01 22:18:44 +02:00
can1357 9403df1abd fix(session): avoid empty exit-marker sessions 2026-07-01 21:55:01 +02:00
can1357 b8ae1e21b1 Merge PR #2607: fix(session): detected pending tool calls without toolUse (@roboomp)
# Conflicts:
#	packages/coding-agent/src/session/agent-session.ts
2026-07-01 21:55:01 +02:00
can1357 569b83d5a6 Merge PR #4166: fix(agent): preserve approved plan path (@roboomp) 2026-07-01 21:53:19 +02:00
can1357 021d4fc1e3 Merge PR #4161: fix(agent): interrupt waits for IRC delivery (@roboomp) 2026-07-01 21:53:19 +02:00
can1357 debe71ae0e Merge PR #4129: fix(coding-agent): preserved explicit :auto suffix in modelRoles (@roboomp) 2026-07-01 21:53:17 +02:00
can1357 1479b689d8 Merge PR #4121: fix(coding-agent): route SIGTERM/SIGHUP/uncaughtException through session teardown (@roboomp) 2026-07-01 21:53:16 +02:00
can1357 9ae2b48b10 Merge PR #4077: fix(agent): add retry path diagnostics (@roboomp) 2026-07-01 21:53:14 +02:00
can1357 826517dc69 Merge PR #3969: fix: preserve bash cwd without hidden pwd probe (@jeffscottward) 2026-07-01 21:50:54 +02:00
can1357 b3b4a762ac Merge PR #3736: fix(coding-agent): replan title refresh honors TITLE_SYSTEM.md override (@roboomp) 2026-07-01 21:42:25 +02:00
can1357 97b72df087 fix(coding-agent): reset mid-run todo counter after stop reminder 2026-07-01 21:42:24 +02:00
can1357 2d734f65c4 Merge PR #3652: fix(coding-agent): nudge todo reconciliation mid-run instead of only at stop (@roboomp) 2026-07-01 21:42:23 +02:00
roboomp 6cd93546cb fix(agent): preserved approved plan path
Approved plan execution now requires reading the durable local plan file instead of embedding the plan body in synthetic execution prompts. This keeps execution recoverable when Headroom-compressed inline content expires.

Fixes #4164
2026-07-01 17:19:20 +00:00
roboomp f8241aee9d refactor(irc): moved parent IRC steer text into a prompt file 2026-07-01 17:08:49 +00:00
roboomp 619bfda3eb fix(agent): interrupted irc waits
Fixes #4160
2026-07-01 16:56:08 +00:00
roboomp 9f3e648e5a fix(coding-agent): gated :auto suffix behind allowAutoAlias
Follow-up on the review: the widened parseThinkingSuffix recognized :auto unconditionally, so parseModelString and extractExplicitThinkingSelector would silently strip a literal provider/model:auto id before the isLiteralModelId guard the :max path already uses.

- Add allowAutoAlias option and require callers to opt in, mirroring allowMaxAlias.

- MAX_THINKING_SUFFIX_OPTIONS enables both aliases; parseModelPatternWithContext still tries exact match first, so a real :auto id wins there too.

- sdk.ts (session restore x2), agent-session.ts (retry fallback selector, context-promotion/compaction targets), and model-registry.ts (normalizeSuppressedSelector) now pass allowAutoAlias: true alongside allowMaxAlias.

- Regressions: literal example/runtime:auto wins over the sentinel in parseModelPattern, parseModelString (with and without isLiteralModelId), resolveModelFromString, and extractExplicitThinkingSelector; auto is still extracted when the id isn't literal.
2026-07-01 08:30:58 +00:00
roboomp a4ae4c130c fix(coding-agent): preserved explicit :auto suffix in modelRoles
The model selector's persistence path dropped the `:auto` selector when parsing role values, producing a warning ('Invalid thinking level "auto"') and rendering the badge as `inherit` instead of `auto`. Reload of the default role also lost the auto state whenever the role value carried an explicit `:auto` suffix instead of relying on `defaultThinkingLevel`.

Widen the resolver chain (`parseThinkingSuffix`, `splitThinkingSuffix`, `parseModelString`, `parseModelPattern*`, `ResolvedModelRoleValue`, `ResolvedRoleModel`, `ResolveCliModelResult`) to carry the `AUTO_THINKING` sentinel end to end, and coerce it back to `undefined` at concrete-only boundaries (glob scope patterns, retry fallback, advisor, commit pipeline, guided-goal, bench).

Regression tests cover:

- `resolveModelRoleValue("provider/model:auto")` returns explicit auto without a warning.

- `ModelSelector` renders `DEFAULT (auto)` and `SMOL (auto)` when the role value has `:auto`.

- `cycleRoleModels` activates auto thinking on entering a `:auto` role.

- Startup resume activates auto thinking when `modelRoles.default` carries `:auto`.

Fixes #4128
2026-07-01 08:18:42 +00:00
roboomp 73a12c7ea2 fix(coding-agent): routed SIGTERM/SIGHUP/uncaughtException through session teardown
The postmortem SIGTERM/SIGHUP/uncaughtException handlers only ran the registered
cleanup callback list before process.exit, and the only session-related callback
was session-manager-flush. So a real kernel signal (terminal close, process
manager killing omp, IDE stop) skipped saveDraft, session.dispose (session_shutdown
emit, owned async job disposal, kernel disposal, MCP disconnect, browser tab
release), and violated the SessionShutdownEvent docstring contract that promises
delivery on SIGINT/SIGTERM. The LSP client also owned its own SIGINT/SIGTERM
handlers that called shutdownAll then process.exit(0), which could race postmortem's
async runCleanup and short-circuit the session teardown.

- Extracted a promise-memoized createSessionTeardown helper (modes/session-teardown.ts)
  that snapshots the editor draft, persists it via sessionManager.saveDraft, then
  invokes session.dispose. A saveDraft failure is logged but never aborts disposal.
- Memoized AgentSession.dispose so the keypress path and the signal path share one
  settled promise and cannot double-emit session_shutdown or double-drain the owned
  AsyncJobManager.
- Registered the teardown on postmortem as "session-teardown" in InteractiveMode.init,
  replacing the narrower session-manager-flush callback. InteractiveMode.shutdown
  now delegates the draft+dispose steps to the same helper.
- Replaced the LSP client's SIGINT/SIGTERM handlers with a "lsp-shutdown" postmortem
  callback so LSP cleanup runs alongside every other session teardown instead of
  racing them via process.exit(0). beforeExit is unchanged.
- Added session-teardown.test.ts covering: draft-then-dispose ordering, disposal
  after saveDraft rejects, empty-string clears stale sidecar, promise memoization
  under concurrent invocation, and snapshot-at-first-call semantics.

Fixes #4080
2026-07-01 07:19:30 +00:00
roboomp 9009d5b8f7 fix(agent): added retry path diagnostics
Logged assistant-tail removal outcomes and scheduled continuation state for transient retry failures.

Fixes #4070
2026-07-01 06:55:03 +00:00
Jeff Scott Ward 3da25618ea fix: preserve bash cwd without pwd probe 2026-06-30 23:51:28 -04:00
can1357 ef7636805b feat(coding-agent): removed canonical model variant selection and tracking
- Removed the canonical model variant indexing, selection, and tracking logic from the model registry and resolver.
- Eliminated the `canonical` sub-command, tab view, search tokens, and equivalence configuration structures from the CLI and model selector components.
- Refined model identification, lookup, and provider fallback resolution to bind exclusively to standard, raw model IDs.
- Relocated the equivalence utility script within the catalog package to support script-only policy generation.
2026-07-01 05:22:42 +02:00
can1357 8e8c3e92ce Merge remote-tracking branch 'origin/farm/e0aafd27/cross-turn-tool-call-loop-guard' 2026-07-01 05:08:41 +02:00
roboomp cf52840c18 fix(agent): detected repeated tool-call turns
Added a cross-turn tool-call loop guard that hashes canonical tool names and arguments, ignores intent metadata, and injects a hidden redirect when identical calls reach the configured threshold.

Fixes #3971
2026-07-01 02:47:08 +00:00
roboomp dff941d5fe fix(coding-agent): preserved bash status while syncing cwd
Propagated the native shell working directory in ShellRunResult so AgentSession can refresh cwd without running a hidden pwd command in the persistent shell.

Added regression coverage for cd plus a failing command followed by echo $?, proving cwd sync no longer overwrites the user's last shell status.

Fixes #3958
2026-07-01 02:27:05 +00:00