Commit Graph
851 Commits
Author SHA1 Message Date
can1357 ccf8789693 Merge remote-tracking branch 'origin/farm/f45f9d5d/get-session-stats-context-usage' 2026-07-06 07:39:07 +02:00
can1357 f572841c60 Merge remote-tracking branch 'origin/farm/4a9a5787/fix-irc-between-wait-replies' 2026-07-06 07:38:42 +02:00
roboomp 5f44151903 fix(rpc): included context usage in session stats
Added contextUsage to SessionStats so get_session_stats mirrors the existing getContextUsage data used by state responses.

Fixes #4668
2026-07-06 03:16:13 +00:00
roboomp 06f6762103 fix(agent): surfaced pending irc replies to wait
Drained pending IRC asides before parking irc wait so replies that arrive between wait calls are returned instead of being treated only as queued interrupts.

Added regression coverage for the already-aborted queued-IRC signal path and documented the fix in the coding-agent changelog.

Fixes #4657
2026-07-06 02:36:35 +00:00
roboomp 3a962c54c7 fix(agent): reset IRC wake maintenance state
Reset per-turn maintenance counters before IRC wake prompts so yielded subagents do not carry stale yield termination into later wake turns.

Add regression coverage for empty-stop retry after an IRC wake following a yielded run.

Fixes #4658
2026-07-06 02:34:23 +00:00
can1357 3458b037ae chore: update tests 2026-07-05 16:53:07 +02:00
can1357 b3c661f164 Merge PR #4272: perf(session): cache persisted-message keys, invalidate on branch change (@metaphorics) 2026-07-05 13:39:11 +02:00
can1357 734aed4c03 Merge PR #4382: fix(compaction): keep plan-mode guidance off the session_before_compact hook (@roboomp) 2026-07-05 13:25:28 +02:00
can1357 36c3e26fee Merge PR #4381: fix(coding-agent): queue approved plan behind turns flushed by compaction (@roboomp) 2026-07-05 13:25:27 +02:00
can1357 eb3ded68ea Merge PR #4357: fix(session): harden runEphemeralTurn against dropped provider content on idle recap (@roboomp) 2026-07-05 13:25:24 +02:00
can1357 8ec34a7662 Merge PR #4349: fix(session): handle malformed custom messages (@roboomp) 2026-07-05 13:25:24 +02:00
can1357 2f67fb3728 Merge PR #4387: fix(fast): enable custom OpenAI-compatible providers (@roboomp) 2026-07-05 13:10:27 +02:00
can1357 d5d13c2cf2 fix(session): keep empty error turns out of rollback persistence 2026-07-05 13:10:26 +02:00
can1357 05fc11394e Merge PR #4457: fix(session): drop content-less provider-rejection turns from persisted history (@mattwilkinsonn) 2026-07-05 13:10:26 +02:00
can1357 a868a7d2d5 Merge PR #4471: fix(ai): separate Codex orchestration usage (@roboomp) 2026-07-05 13:03:08 +02:00
can1357 7f3832a263 Merge PR #4489: fix(snapcompact): select silver shape for CJK-heavy auto text (@roboomp) 2026-07-05 13:03:08 +02:00
roboomp a1f60f6584 fix(advisor): clamped advisor default thinking against the resolved model
`#resolveAdvisorRuntimeDescriptors` hardcoded `ThinkingLevel.Medium` when
no thinking suffix was configured. For reasoning models with no
controllable effort surface (`devin-agent`: `reasoning: true`,
`thinking: undefined` — Cascade selects effort by routing to sibling
model ids, not a wire param), that default tripped
`requireSupportedEffort` on the first advisor prompt with an empty
`Supported efforts:` list, disabling the advisor session-wide.

Route the default through `resolveThinkingLevelForModel(model, level)`
which preserves explicit `off`, clamps a concrete effort into the
model's supported range, and returns `undefined` for reasoning models
without controllable efforts — falling back to `Inherit` so no effort is
sent while reasoning stays enabled. Matches the `auto`-path fix
(`clampAutoThinkingEffort`) and the Autonomous Memory clamp
(`clampThinkingLevelForModel`).

Fixes #4579
2026-07-05 00:46:01 +00:00
can1357 6e2bba871e feat(agent): implemented automated retry recovery and transcript compaction
- Introduced an automated retry recovery system to track, manage, and persist recovered error states within agent sessions.
- Enabled compact transcript rendering for recovered auto-retry errors by removing heuristic commit machinery.
- Improved raw read tracking and provenance in the ReadTool to support refined file snapshot recording and hashline editing.
- Excluded recovered assistant messages from default model context and updated event controllers to handle retry recovery life cycles.
2026-07-04 11:22:04 +02:00
roboomp a8add580d9 fix(snapcompact): selected silver for cjk auto shape
- Made resolveShapeForText choose silver16-bw for CJK-heavy auto transcripts while preserving explicit variants and unsafe glyph protection.
- Added silver16-bw to the snapcompact shape settings submenu and renamed unsupported-glyph warnings.
- Covered auto shape selection, explicit variant precedence, unsafe glyph scans, and settings option parity.

Fixes #4486
2026-07-04 03:54:55 +00:00
roboomp a52ed682c7 fix(ai): separated codex orchestration usage
- Added a Usage.orchestration sidecar for provider-side service tokens so Responses/Codex totals and costs stay accurate without inflating visible prompt input/cache buckets.
- Updated Codex/WebSocket usage, session/status aggregates, and usage reporting to preserve orchestration-aware totals.
- Added regressions for OpenAI Responses accounting, Codex WebSocket terminal usage, cost calculation, and session aggregation.

Fixes #4469
2026-07-03 16:44:12 +00:00
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
roboomp da4ac01c71 fix(fast): enabled custom openai-compatible providers
- Classified OpenAI-compatible custom relays serving OpenAI model ids into the OpenAI service-tier family.
- Passed the model into OpenAI service-tier wire gating so custom relays emit service_tier when eligible.
- Reported /fast on as unavailable when the active model has no service-tier family.

Fixes #4386
2026-07-03 03:11:26 +00:00
roboomp 72df91c3c8 fix(compaction): route plan-mode guidance via internalGuidance channel
Plan-approval's 'Approve and compact context' used to pass the rendered
plan-mode-compact-instructions prompt as the first positional argument
to handleCompactCommand -> session.compact(), which landed on the
session_before_compact extension hook as customInstructions. Extensions
treating that field as user focus (e.g. to bias a query-focused summary)
would then see plan-mode boilerplate instead of operator intent and
produce query-biased compactions.

Add CompactOptions.internalGuidance: a private summarizer-only channel.
session.compact() reads it into the fallback-model summarizer while the
session_before_compact hook payload still only carries the public
customInstructions arg (undefined for the plan-compact path). The
snapcompact-disable predicate and the /compact rejectsFocus guard cover
both fields so a directed summary is never silently downgraded.

Extend the interactive-mode handleCompactCommand facade + command
controller with a fourth internalGuidance parameter, and switch the
plan-approval callsite in interactive-mode.ts to route the plan prompt
through it.

Fixes #4359
2026-07-03 00:36:38 +00:00
roboomp d168188337 fix(coding-agent): queue approved plan behind turns flushed by compaction
Selecting "Approve and compact context" while a user turn was typed during
compaction surfaced `Failed to finalize approved plan: Agent is already
processing` and silently discarded the operator's queued turn.
`flushCompactionQueue` fires the queued user turn (fire-and-forget) before
`handleCompactCommand` returns, so by the time `#approvePlan` resumed, the
session was streaming. The previous shape aborted the queued turn and still
raced into `AgentBusyError` when `session.prompt()` ran before abort settled.

The finalize path now queues the plan-approved directive as a synthetic
follow-up when the session is streaming, and catches a racing `AgentBusyError`
from `prompt()` with the same fallback. `AgentSession.followUp()` gained a
`{ synthetic, expandPromptTemplates, attribution }` option so the hidden
execution directive lands as an agent-attributed developer message on the
follow-up queue, without flipping advisor auto-resume the user-follow-up path
does.

Fixes #4358
2026-07-03 00:35:06 +00:00
roboomp 337ec0d16c fix(session): harden runEphemeralTurn against dropped provider content
Idle recap crashed with `TypeError: undefined is not an object (evaluating
'H.content.filter')` when the reporter's session_stop block-decision extension
poisoned the transcript with eight persisted `session-stop-continuation`
custom entries. The primary block-reason continuation flow was intact — the
custom message correctly renders as a `role: "developer"` LLM message —
but the follow-on idle recap fired 4 minutes later, and the side-channel
provider stream handed back a `done` event whose `message.content` had been
dropped. `runEphemeralTurn`'s sanitize step at
`assistantMessage.content.filter(block => block.type !== "toolCall")` then
tripped the TypeError, propagated as "Idle recap turn failed" in the debug
log while silently muting the session.

- Normalized the provider "done" event's `message.content` to `[]` when
  the shape is not an array, so a wrapper stream that drops content surfaces
  as an empty recap reply instead of an unrecoverable side-channel crash.
- Guarded `#buildEphemeralSnapshot`'s in-flight-assistant preservation
  branch with `Array.isArray(streaming.content)` for the same reason.
- Added a regression test that seeds the reporter's transcript shape (one
  real turn, eight persisted `session-stop-continuation` customs carrying a
  multi-line block reason with U+2717 glyphs) and drives a recap through a
  side stream that returns `content: undefined` on `done`. The test
  fails on the pre-fix tree with the exact reporter TypeError and passes
  after the guard lands.

Fixes #4323
2026-07-03 00:16:07 +00: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 8da17ba3b5 fix(session): handled malformed custom messages
Normalized extension custom-message payloads before session state or persistence, including bare string sendMessage shorthands. Skipped legacy bare custom_message entries during context rebuilds and dropped malformed custom/hook messages before LLM conversion. Added regression coverage for the poisoned-session resume crash.\n\nFixes #4345
2026-07-02 20:34:15 +00: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
metaphorics 7d93fd206c fix: address cubic review feedback (iteration 4)
Replace scattered persisted-message cache invalidation (11 call sites across branch-mutation flows) with use-time validation: the memoized key set is anchored to (session file, leaf id) and rebuilds itself whenever the anchor moved. Every branch mutation changes the leaf by definition, so staleness is structurally unrepresentable and no mutation path has to remember to invalidate. Incremental append extends the cache only when it was fresh for the branch the append lands on.
2026-07-02 18:44:44 +09: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
metaphorics e09b72810a perf(session): cache persisted-message keys, invalidate on branch change
AgentSession.#sessionMessageAlreadyPersisted previously called SessionManager.getBranch() on every message_end event, rebuilding the root-to-leaf path and JSON-comparing each entry; for long sessions this is O(n) per message and O(n²) over a growing transcript. Add #persistedMessageKeys, a memoized Set<string> of persistence keys for the current branch, so the common missing-key check uses Set.has and only falls back to a branch walk on rare key collisions. Invalidate the cache whenever the leaf path changes (newSession, createBranchedSession, resetLeaf, branch, and branchWithSummary) and incrementally warm it after each real append. Verified with git diff --check, a scoped bun build of agent-session.ts, and bun test packages/coding-agent/test/agent-session-persisted-keys-cache.test.ts (2/2 passing).

Closes #4243
2026-07-02 17:29:34 +09: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