Commit Graph
1076 Commits
Author SHA1 Message Date
can1357 95b91c7f73 feat(coding-agent/tools)!: replaced paths arrays with path strings
- Replaced `grep`, `glob`, and `ast_grep` `paths` inputs with optional single `path` strings while preserving default workspace-root behavior.
- Added shared `toPathList` normalization for legacy arrays and JSON-encoded arrays across tool execution and TUI renderers.
- Updated prompts, fixtures, shims, transcript summaries, and tests to send and display the new `path` argument.
- Updated collab-web search tool cards to read `path` while falling back to legacy `paths` for historical transcripts.
- Recorded the contiguous coding-agent changelog run for the tool-path breaking change and adjacent TTS entries.
2026-07-02 08:30:33 +02:00
can1357 c4c0331345 fix(coding-agent/session): prevented data loss in session serialization
- Persist signed message blocks (`text`, `thinking`, `toolCall`) and encrypted reasoning payloads verbatim during session serialization instead of clearing or truncating them.
- Preserve signature keys instead of replacing them with empty strings when they exceed persistence size limits.
- Exempt official first-party OpenAI and Anthropic API endpoints from the leaked-thinking stream healing wrapper to prevent misfires on legitimate visible text fences.
2026-07-02 03:58:10 +02: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
can1357 af748c3e90 fix(coding-agent/session): prevented truncation of signed thinking and redacted reasoning blocks
- Excluded signed `thinking` blocks and `redactedThinking` blobs from size-based persistence truncation.
- Preserved signature-bound reasoning verbatim to prevent provider validation failures on session replay.
- Maintained normal truncation behavior for unsigned thinking and standard text blocks.
2026-07-02 03:39: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 db53707b8e Merge remote-tracking branch 'origin/farm/32976ff8/anthropic-fable-fallback' 2026-07-02 02:04:02 +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
roboomp 1bbd0c92f6 feat(anthropic): opt-in server-side fallback beta chain
Added AnthropicOptions.fallbacks + wire types + response parsing gated on the opt-in — server-side fallback stays fully inert on every request that does not set the option.

Coding-agent surfaces the feature via providers.anthropic.serverSideFallback (default off). When enabled, Fable/Mythos requests inject fallbacks: [{ model: claude-opus-4-8 }]; caller-supplied fallbacks always win.

transformMessages centrally strips persisted fallback blocks on cross-provider hops and non-official Anthropic replays so a stored fallback turn never wedges downstream converters. Retry resets restore output.model to the requested id.

Fixes #4177
2026-07-01 23:34:48 +00: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 5ca07b1759 Merge PR #3759: Merge remote-tracking branch 'can1357/main' into fix/compaction-summary-chronological-position (@DarkPhilosophy)
# Conflicts:
#	packages/coding-agent/src/session/session-context.ts
2026-07-01 22:04:47 +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 8fd35c4324 Merge PR #3862: perf: cut edit-pipeline and session-branch hot-path complexity (@oldschoola) 2026-07-01 21:47:55 +02:00
can1357 ac8ad5972b Merge PR #3849: perf(coding-agent): speed up large-session resume with Bun.JSONL (@oldschoola) 2026-07-01 21:47: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
can1357 2ad5a433ea Merge remote-tracking branch 'origin/farm/3fc23c45/linear-session-path-rebuild' 2026-07-01 04:47:04 +02: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
roboomp 19b85bca70 fix(browser): reap Chromium/Puppeteer on aborted open and session dispose
Two termination boundaries in the browser tool leaked browser-owned OS resources into the long-lived coding-agent process.

1. Aborted 'open' published an orphan. #open wrapped acquisition in untilAborted, which rejects its outer wrapper on abort but lets the inner launch resolve in the background; acquireBrowser then unconditionally stored the resolved handle in the module-global browsers map. releaseAllTabs walks tabs, not browsers, so the refCount:0 handle stayed alive to process exit.

2. Session dispose had no browser teardown. Browser/tab state lives in module-global maps, and AgentSession.dispose() had no hook to walk them, so headless/spawned Chromium the session opened survived it.

acquireBrowser now short-circuits before launch on a pre-aborted signal and disposes the handle when the launch completes after abort. TabSession records the creating session's id (opts.ownerSessionId, threaded through BrowserTool.#open), preserved across reuse so a subagent re-driving an existing tab does not yank teardown responsibility. AgentSession.dispose() invokes releaseTabsForOwner bounded by withTimeout(3s), mirroring the async-job/MCP disposal pattern.

Regression tests exercise both boundaries via spied CmuxSocketClient (no real puppeteer/socket) and cover: pre-aborted open short-circuit, aborted-mid-launch cleanup, releaseTabsForOwner reaping only owned tabs, and reuse preserving original ownership.

Fixes #3963
2026-07-01 02:09:04 +00:00
roboomp a1a393cdc5 fix(session): linearized session path rebuilds
- Replaced leaf-to-root unshift path assembly with push plus one reverse in buildSessionContext and SessionEntryIndex.pathTo.
- Added regression coverage that keeps deep linear context and branch paths root-to-leaf without Array.unshift work.

Fixes #3961
2026-07-01 01:59:34 +00:00