Commit Graph
1442 Commits
Author SHA1 Message Date
can1357 2c42715263 fix(compaction): charged pre-archive kept region in rescue budget
Also stamped dead-end warnings before the auto_compaction_end event so the result-driven TUI rebuild shows the badge (Codex round 6 on #6362).
2026-07-23 17:30:15 +02:00
can1357 15f1fb2c7c Merge PR #6362: fix(compaction): rescue snapcompact archives stuck past the maintenance threshold (@HugoLopes45) 2026-07-23 17:30:14 +02:00
Hugo Lopes d8554c92d0 fix(compaction): charge the kept tail in the rescue budget and badge the active entry
Review follow-ups (Codex on #6362, round 5):
- #computeSnapcompactRescueMaxFrames now subtracts the kept tail AFTER the
  archive (plus the existing fixed-context reserves) so the budget mirrors
  what #compactionCreatedHeadroom will measure, and returns 0 when not even
  one frame fits — the rescue bails instead of appending a rebuild that can
  never create headroom (and would wedge prepareCompaction behind its
  last-entry guard once elide fixes the real tail).
- Dead-end warnings now stamp the branch's LATEST compaction entry: the
  post-pass path no longer badges the entry the rescue just superseded, and
  the no-preparation path badges the rebuilt entry when the rescue appended
  without creating headroom.

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 14:03:12 +02:00
Hugo Lopes f48004a182 fix(compaction): only frame-rescue archives that are the actual overflow source
Review follow-up (Codex on #6362, round 4): rebuilding a non-tail archive
appends the replacement compaction at the leaf, so the branch tail becomes a
compaction entry that prepareCompaction's last-entry guard can never
summarize past — even after elide shrinks the oversized kept tool result
that was the real culprit. The rescue now estimates the kept tail AFTER the
latest archive and bails when it alone exceeds the recovery band, leaving
that shape to the elide/image tiers.

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 13:15:23 +02:00
Hugo Lopes d9417927bc fix(compaction): surface the frame rescue as a real compaction to the TUI and extensions
Review follow-ups (Codex on #6362):
- #rescueSnapcompactFrameOverflow now returns the CompactionResult and emits
  session_compact for the rebuilt entry, so extensions see the entry that is
  actually active instead of (only) the one the rescue superseded.
- The no-preparation auto_compaction_end now carries that result instead of
  {result: undefined, skipped: true} when the rescue rewrote history — the
  TUI rebuilds the transcript on result, so a successful rescue is no longer
  presented as a benign no-op.

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 12:59:15 +02:00
can1357 8205d3ee31 style: applied biome formatting to merged fix commits 2026-07-23 11:39:15 +02:00
Hugo Lopes ef952c6d88 fix(compaction): mirror post-compaction bookkeeping in the frame rescue
Review follow-up (Codex on #6362): the rescue's replaceMessages() rebuild
drops the transient plan-reference message, so clear #planReferenceSent
(#1246) and reset advisor runtimes / todo phases exactly like the regular
compaction append path.

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 11:37:59 +02:00
can1357 db3a6a1407 Merge PR #6318: fix(tui): show fallback models in Agent Hub (@roboomp) 2026-07-23 11:37:13 +02:00
can1357 e488d09751 fix(coding-agent): keep failed tails visible in read-only session history
Route loadSessionMessagesReadOnly through transcript mode (collapsed to the
latest compaction) so history:// transcripts of on-disk sessions retain
failed/aborted assistant tails that the provider-context builder now drops.
2026-07-23 11:37:10 +02:00
can1357 6fe0cc99bc Merge PR #6357: fix(coding-agent): guard session context replay tail (@honsunrise) 2026-07-23 11:37:10 +02:00
Hugo Lopes 42f530f187 fix(compaction): gate frame-rescue success on real headroom and cap rescue frames
Review follow-ups (Codex on #6362):
- The !preparation frame rescue now counts as complete only when the rebuild
  actually created headroom; otherwise the elide/image tiers still run and the
  no-progress warning stays — a frame-count shrink alone must not suppress it
  when the oversized tail is a kept message/tool result the archive rescue
  cannot touch.
- #computeSnapcompactRescueMaxFrames now applies the same MAX_FRAMES_DEFAULT /
  maxFramesForDataBudget caps as #computeSnapcompactMaxFrames, so a
  threshold-derived count can never exceed what the rebuilt prompt can attach.

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 11:35:09 +02:00
Hugo Lopes 756fed844c fix(compaction): rescue trailing snapcompact archives past the maintenance threshold
A branch whose last entry is a snapcompact CompactionEntry billed past the
compaction threshold (FRAME_TOKEN_ESTIMATE x frames) dead-ended on every
resume: prepareCompaction returns undefined (nothing after the entry to
summarize), and the #4786 elide/image rescue tiers only inspect
"message"/"custom_message" entries, so a type:"compaction" tail escaped both
and the "Compaction freed too little context" warning re-fired forever.

Add a dedicated first rescue tier that rebuilds the SAME archive locally (no
LLM, no network) by re-running snapcompact.compact() over the entry's
carried-forward source text at a maxFrames derived from the trigger
threshold's recovery band instead of the window-fit budget: planArchive
truncates the oldest chars to fit, so the rebuilt entry genuinely shrinks.
Persisting through appendCompaction lets the write-time
superseded-compaction elision drop the stale frame payload from the JSONL,
and the pass skips the misleading no-progress warning.

Fixes the loop reported in
https://github.com/can1357/oh-my-pi/issues/4786#issuecomment-5056055342

Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
2026-07-23 11:31:00 +02:00
can1357 b4a3abe445 feat: added hasProvider method to detect known model providers
- Implemented ModelRegistry.hasProvider to return true when a provider has live models, is discoverable, or is registered at runtime.
- Replaced AgentSession's internal provider check with #isKnownProvider that delegates to the new hasProvider method, updating related fallback logic.
2026-07-23 11:17:00 +02:00
Honsun Zhu 6fae89aaea fix(coding-agent): guard session context replay tail 2026-07-23 16:38:22 +08:00
can1357 08a0af909c fix(session): keep content-less overflow rejections out of persisted terminal error turns
- #6253's dead-end persist now skips context-overflow errors so the auto-compaction progress guard's contract (live-UI-only overflow rejections) still holds; non-overflow terminal provider errors keep persisting per #6249/#6250.
2026-07-22 21:40:05 +02:00
can1357 741aaa301d Merge PR #5895: feat(tui): allow re-answering a past ask from the session tree (@Mathews-Tom) 2026-07-22 21:13:23 +02:00
can1357 9c54d25a4e Merge PR #6298: fix(cli): dispose model-listing extensions (@roboomp) 2026-07-22 21:13:22 +02:00
can1357 13e7f29bc4 Merge PR #6296: fix(tools): cap per-tool default timeout with tools.maxTimeout (@roboomp) 2026-07-22 21:13:20 +02:00
can1357 6039f1a377 Merge PR #6270: fix(agent): bound OpenRouter thinking stream retries (@riverpilot) 2026-07-22 21:13:17 +02:00
can1357 1ed10c5cef Merge PR #6197: fix(todo): prevent stale batch state replay (@roboomp) 2026-07-22 21:13:15 +02:00
can1357 29a94ac49c Merge PR #6200: fix(session): retry past synthetic tool results after mid-tool-call stall (@roboomp) 2026-07-22 21:13:15 +02:00
can1357 e05419a354 Merge PR #6234: fix(session): log provider turn errors at warn with error fields (@roboomp) 2026-07-22 21:13:15 +02:00
can1357 e912efaa79 Merge PR #6226: fix(session): skip stop hooks during aborts (@roboomp) 2026-07-22 21:13:15 +02:00
can1357 6542641ad8 Merge PR #6253: fix(session): persist terminal empty error turns ending the run (@roboomp) 2026-07-22 21:13:14 +02:00
roboomp f9a56ff94f fix(tui): showed fallback models in agent hub
- Exposed the active retry fallback selector from live agent sessions.
- Rendered fallback rows with an explicit marker and resolved provider/model.
- Added an end-to-end fallback-to-Agent-Hub regression assertion.

Fixes #6316
2026-07-22 19:08:32 +00:00
roboomp 29f773ece2 fix(cli): disposed model-listing extensions
Emitted session_shutdown after model rendering and centralized managed timer cleanup across one-shot listings and agent sessions.

Added regression coverage for the extension shutdown lifecycle.

Fixes #6297
2026-07-22 15:51:47 +00:00
roboomp 1b6588e520 fix(tools): cap per-tool default timeout with tools.maxTimeout
clampTimeout resolved the per-tool default (bash 300s) whenever the agent
omitted `timeout` and only enforced the tool's own min/max, so the
tools.maxTimeout global ceiling — applied solely in sdk.ts on explicitly
numeric args — was bypassed on the common default-fallback path.

Thread maxTimeout into clampTimeout so the resolved effective timeout,
including the default path, is capped before the per-tool floor/ceiling
apply. Explicit values below the cap still win; maxTimeout <= 0 stays
no-cap. Applied at every call site (bash, eval, browser, debug, lsp,
fetch, and the session-level bash executor), and the bash clamp notice
now names the global ceiling when it is the binding limit.

Fixes #6294
2026-07-22 15:18:27 +00:00
Alexander Kirilin 298fea76bd chore(agent): clean retry helper formatting 2026-07-22 09:49:55 -04:00
roboomp b257a6dcbf fix(session): preserved startup fallback ownership
- Carried startup-selected fallback role and primary selector into AgentSession.
- Continued remaining role fallback entries after the startup fallback fails.
- Added regression coverage for chained startup failover.

Fixes #6283
2026-07-22 11:11:30 +00:00
Alexander Kirilin 5abac0245a fix(agent): bound OpenRouter thinking stream retries 2026-07-22 03:21:00 -04:00
roboomp 615d3c6dc5 fix(session): persisted terminal empty error turns ending the run
A non-retriable provider error on the continuation turn after a failed
tool result ended the run, but #persistSessionMessageIfMissing dropped
the empty error turn as reload poison, so the session JSONL stopped at
the last tool result and the provider errorMessage was lost with no
durable record of why the run stopped. When retry, model fallback, and
compaction all decline the turn, the non-retry terminal error tail now
persists it via the same helper the retry-lifecycle dead-ends use; the
empty turn stays off the wire on reload via the transform-messages
empty-assistant filter, matching the existing retry-exhaustion path.

Fixes #6249
2026-07-22 02:29:05 +00:00
roboomp ee9c08a5c1 fix(session): log provider turn errors at warn with error fields
The agent_end handler only recorded stopReason/provider/model at debug and dropped errorMessage/errorStatus/errorId, so a session dying repeatedly on provider stream failures left no actionable trace in the main log. Extract logProviderTurnError and emit one warn-level entry carrying provider, model, errorMessage, errorStatus, and errorId when a turn ends in stopReason:error.

Fixes #6177
2026-07-21 22:06:57 +00:00
roboomp 7c96386e29 fix(session): skipped stop hooks during aborts
Short-circuited session_stop emission when an abort or disposal is already in progress, avoiding extension work whose result cannot be used.

Added deterministic coverage for an abort racing the final settle pass.

Fixes #6134
2026-07-21 21:31:46 +00:00
roboomp 31e0c8a9ee fix(session): retry past synthetic tool results after mid-tool-call stall
A stream that stalls or aborts mid-tool-call ends the assistant turn with
stopReason error/aborted, then appends a synthetic tool_result per un-run
tool call to keep the provider's tool_use/tool_result pairing intact. That
placeholder trailed the failed turn, so AgentSession.retry() — which only
inspected the last message and required role assistant — short-circuited to
false and /retry printed 'Nothing to retry'.

retry() now walks back over trailing synthetic tool results (details
__synthetic true) before the assistant + stopReason check, stripping both
the placeholders and the failed turn. Only synthetic results are skipped, so
a turn whose tools actually ran stays non-retryable. Adds an exported
isSyntheticToolResultMessage guard in agent-loop.ts.

Fixes #6056
2026-07-21 20:30:44 +00:00
roboomp aa0884d51b fix(todo): prevented stale batch state replay
- Stopped asynchronous tool-result handling from overwriting newer todo state.
- Added an AgentSession regression for six exclusive completion calls.

Fixes #6148
2026-07-21 20:18:22 +00:00
Mathews-Tom d7f6ce5e04 Merge remote-tracking branch 'upstream/main' into feat/tree-ask-reanswer 2026-07-21 19:25:33 +05:30
can1357 4577f064cb Merge PR #5736: fix(session): persist /new boundary so autoResume does not resume pre-/new transcript (@roboomp) 2026-07-20 22:50:05 +02:00
can1357 091dad0f90 Merge PR #6088: fix(thinking): persist auto selector receipt (@moomooskycow) 2026-07-20 22:50:04 +02:00
can1357 29f25f537e Merge PR #6020: fix(coding-agent): enable plan mode for print prompts (@roboomp) 2026-07-20 22:50:04 +02:00
phrazzld f04741eac2 fix(thinking): persist auto selector receipt 2026-07-19 19:11:30 -05:00
Victor Araújo 1d667039d1 refactor(coding-agent): share tool presentation apply path 2026-07-19 14:45:41 -03:00
Victor Araújo 7f10e13bbe fix(coding-agent): preserve plan tool presentation 2026-07-19 14:45:41 -03:00
vmcall 4088c20ecb fix(coding-agent): gated workflowz on eval
Require active eval and task tools before injecting Workflowz notices, and provide Python and JavaScript eval examples.
2026-07-19 13:16:08 +02:00
Mathews-Tom ab1d7db7d1 Merge remote-tracking branch 'upstream/main' into feat/tree-ask-reanswer
# Conflicts:
#	packages/coding-agent/src/modes/controllers/selector-controller.ts
2026-07-19 15:02:33 +05:30
roboomp c4053918fe fix(coding-agent): handled headless plan proposals
Installed the normal plan proposal handler in print mode, persisted the resolved plan artifact, and silently stopped the completed planning turn for later review.

Shared plan proposal validation with interactive mode and added regression coverage.

Fixes #6017
2026-07-18 21:46:03 +00:00
can1357 ba385a2946 fix(coding-agent): port no-preparation dead-end rescue to the tiered #rescueCompactionDeadEnd API
Main renamed/refactored #tryShakeRescueForDeadEnd + #emitShakeRescueNotice into
the tiered #rescueCompactionDeadEnd (elide, then image drop, notices emitted
internally), so a textually-clean merge of this branch left calls to undefined
private methods. Re-express the !preparation rescue through the new API:
progress = prepareCompaction succeeding on the rewritten branch, skipElide when
falling through from a shake pass (the image tier still gets a chance), and
historyRewritten flagged whenever a tier freed content even without progress.

Restore the baseline dead-end remedy text (image drop is automated now, so the
manual /shake images suggestion is stale) and align the rescue-refit regression
test with main's continuation gating (auto-continue after compaction now
requires an active goal or queued work).
2026-07-18 21:01:58 +02:00
can1357 401fca701b Merge PR #5448: fix(coding-agent): rescue snapcompact dead-end when nothing is summarizable (@roboomp) 2026-07-18 21:01:41 +02:00
can1357 a762379363 Merge PR #5792: fix(session): resume stalled Cursor tool turns (@roboomp) 2026-07-18 20:12:47 +02:00
can1357 3863a1fac6 Merge PR #5911: fix(subagent): skip session title generation for headless subagents (@roboomp) 2026-07-18 19:57:44 +02:00
can1357 8af064002f Merge PR #5941: fix(coding-agent): parallelize session teardown (@roboomp) 2026-07-18 19:57:43 +02:00