Commit Graph

958 Commits

Author SHA1 Message Date
can1357 e18a14ec10 fix(coding-agent/session): preserved interrupted thinking after user aborts
- Added `INTERRUPTED_THINKING_MESSAGE_TYPE` and `demoteInterruptedThinking` in `session/messages.ts` for stripping unfinished thinking into durable context.
- Persisted hidden interrupted-thinking context from `session/agent-session.ts` immediately after user-interrupted assistant turns.
- Added the `prompts/system/interrupted-thinking.md` envelope used for replaying interrupted reasoning.
- Added focused interrupted-thinking coverage in `test/agent-session-interrupted-thinking.test.ts` and `test/session/interrupted-thinking-demote.test.ts`.
2026-06-28 07:27:01 +02:00
can1357 222b036a11 feat(session): implemented audit logging for session title changes
- Introduced `TitleChangeEntry` type and `TITLE_CHANGE_ENTRY_TYPE` to record title modifications in session logs.
- Added `titleUpdatedAt` and `hasTitleSlot` to `SessionManager` state for persistent tracking of metadata.
- Updated `setSessionName` to serialize title changes into the session file via dedicated title slots.
- Modified session file output to include a title slot header for improved auditability.
2026-06-28 07:27:01 +02:00
can1357 0ce330ab79 feat(session): implemented persistent session title tracking
- Added a fixed-width title slot system to serialize and persist session titles across physical files and backend storage.
- Integrated automated session title updates triggered by todo replan operations using conversation history context.
- Extended storage interfaces across memory, file-system, Redis, and SQL backends to support independent title metadata updates.
- Implemented title metadata parsing within session loaders and list utilities to ensure accurate retrieval and display.
2026-06-28 07:27:00 +02:00
can1357 1e2817d37d Merge remote-tracking branch 'origin/farm/329514e4/ttsr-hashline-edit-path-extraction' 2026-06-27 13:24:24 +02:00
roboomp ae87caeb2a fix(coding-agent): split per-file TTSR digests for multi-file edits
PR #3648 review (codex): the first iteration emitted every envelope
path alongside one combined digest, so a multi-file payload that added
`: any` to a README.md hunk and merely touched src/ok.ts would surface
a *.ts path in the TTSR match context and trip the bundled
tool:edit(*.ts) ts-no-any rule on text that belonged to the Markdown
hunk — aborting valid edits under interruptMode:always.

Add a per-file matcherEntries(args) hook on AgentTool / EditStreaming-
Strategy returning [{ path, digest }] entries, one per touched file
(same-path sections/hunks merged):
- replace / patch: one entry from the top-level path + matcherDigest
- hashline: regex-split by [path#TAG] section, body added-lines per
  entry (tolerant of streaming partial payloads)
- apply_patch: expandApplyPatchToPreviewEntries grouped by path

AgentSession.#checkTtsrStream / #checkTtsrAstStream now prefer
matcherEntries and iterate per-file with isolated filePaths + streamKey,
so each file's buffer and repeat-tracking are independent. Tools
without matcherEntries keep the existing combined matcherDigest +
matcherPaths path.
2026-06-27 11:22:32 +00:00
can1357 62a52f28ea fix(coding-agent/session): improved auto-retry classification for aborted turns
- Standardized retry logic to ensure mocked assistant turns and generic aborts share the same reset path as live provider failures.
- Introduced a classification helper that forces retry policy alignment with the currently active session model.
- Enabled retries for generic reason-less abort sentinels and stale OpenAI response errors.
2026-06-27 13:21:52 +02:00
roboomp 33e425594e fix(coding-agent): route hashline + apply_patch edit paths into TTSR
AgentSession's TTSR match context only scanned top-level path/paths
arguments, so hashline and apply_patch edit streams (whose only target
path lives inside the wire payload — section headers or envelope
markers — not as a top-level argument) arrived without any filePaths
and silently skipped path-scoped rules like the bundled ts-no-any
(scope: tool:edit(*.ts)).

Add an optional AgentTool.matcherPaths(args) hook, companion to the
existing matcherDigest(args), so tools whose wire grammar embeds paths
can surface them. Implement on each edit streaming strategy:
- replace / patch: top-level path
- hashline: parse [path#TAG] (and tag-less [path]) section headers
  tolerant of streaming partial payloads
- apply_patch: parse *** Add/Update/Delete File: markers, also tolerant
  of pre-End-Patch buffers

AgentSession.#getTtsrToolMatchContext consults tool.matcherPaths first,
normalising its output through the existing path-candidate helper, and
falls back to the generic top-level argument scan for tools that don't
implement it.

Fixes #3646
2026-06-27 11:11:50 +00:00
can1357 8266d9f776 feat(agent): introduced configurable text verbosity for responses
- Added textVerbosity configuration schema to allow user control over model response length.
- Integrated textVerbosity into settings-aware stream processing for "openai-responses" and "openai-codex-responses" APIs.
- Updated settings stream tests to verify that verbosity settings correctly apply while respecting caller overrides.
2026-06-27 13:05:57 +02:00
can1357 357c29224d feat: implemented symbol-based streaming state for isolated metadata
- Migrated internal streaming state from string-based properties to symbol-keyed properties for improved data isolation and safety.
- Replaced the deprecated `stripVariant` utility with centralized `clearStreamingPartialJson` and symbol-specific helper methods across all provider implementations.
- Implemented `stripStreamingBlockSymbols` and updated deep equality checks to ensure metadata does not interfere with content comparisons.
- Standardized streaming metadata access through a new `block-symbols` utility module.
2026-06-27 12:07:08 +02:00
can1357 27fa777c59 Merge remote-tracking branch 'origin/farm/80bbf566/advisor-provider-options-parity' 2026-06-27 10:46:12 +02:00
roboomp 540eb73bcf fix(advisor): rolled back failed turns before retry or drop
Agent.#runLoop appends the user batch and a synthetic stopReason: "error" assistant turn to state.messages before resolving prompt() with state.error set. AdvisorRuntime now snapshots state.messages.length before each prompt, restores it on failure (via a new AdvisorAgent.rollbackTo hook that also resets the advisor's append-only sync cursor), and clears state.error so retries replay a clean baseline and the drop-after-3 path never leaks orphan failed turns into the next successful run's context.

Fixes #3635
2026-06-27 10:46:08 +02:00
can1357 c3f7e849e5 refactor: centralized AI error handling into a dedicated module
- Migrated 288 lines of scattered error classification logic from `utils/error-id.ts` into a cohesive `packages/ai/src/error/` module with 13 specialized submodules covering flags, classes, OAuth, providers, rate-limiting, and finalization.
- Replaced 100+ generic `Error` throws across 60+ provider and registry files with semantic `AIError.*` classes (e.g., `AIError.MissingApiKeyError`, `AIError.OAuthError`, `AIError.ProviderResponseError`), improving error diagnostics and retry logic.
- Consolidated error utility imports from `pi-utils` and scattered classification functions into a single `AIError` namespace, reducing coupling and simplifying error handling across all packages.
2026-06-27 10:44:13 +02:00
roboomp 750e20e5cc fix(advisor): inherited provider-shaping options from the session
AgentSession.#buildAdvisorRuntime constructed the advisor Agent without the provider-shaping options the SDK installs on the main agent: the streamFn wrapper that applies providers.openrouterVariant / providers.antigravityEndpoint / providers.maxInFlightRequests / model.loopGuard.*, the onPayload/onResponse/onSseEvent hooks, the shared providerSessionState map, transformProviderContext (snapcompact, secret obfuscation, image clamping), and a stable promptCacheKey. Advisor turns therefore dropped the OpenRouter sticky-routing variant suffix, used a different prompt_cache_key than the main turn, and skipped the per-session provider hooks — producing intermittent OpenRouter response-cache misses across consecutive advisor calls.

Extract the inline streamFn wrapper in sdk.ts into a shared createSettingsAwareStreamFn helper (packages/coding-agent/src/session/settings-stream-fn.ts) and pass it (plus transformProviderContext) through AgentSessionConfig as advisorStreamFn / transformProviderContext. #buildAdvisorRuntime now hands the advisor Agent the same streamFn, hooks, providerSessionState, promptCacheKey (= advisor session id), and transformProviderContext as the main turn. Adds getAdvisorAgent() accessor on AgentSession for diagnostics and parity tests.

Fixes #3639
2026-06-27 07:35:34 +00:00
can1357 af149e39e0 Merge remote-tracking branch 'origin/farm/5bd56871/tui-thought-stream-freezes-and-session-p' 2026-06-27 08:12:05 +02:00
can1357 14e4122fd8 Merge remote-tracking branch 'origin/farm/1386763e/notify-unavailable-advisor-model' 2026-06-27 08:11:17 +02:00
roboomp 22b840399c style: bun run fix 2026-06-27 06:07:06 +00:00
roboomp 38550db31d fix(advisor): notified when advisor model failed
Surfaced non-recovering advisor prompt failures through session notices so provider errors like OpenRouter ZDR endpoint rejection are visible in the main session.

Fixes #3635
2026-06-27 06:06:42 +00:00
can1357 f0f7a5ba89 feat(coding-agent): introduced tiny model role for background tasks
- Added `tiny` as a first-class model role to override online models for lightweight background tasks.
- Updated session title generation, auto-thinking difficulty classification, unexpected-stop detection, and mnemopi backend to resolve via the `tiny` role before falling back to `smol`.
- Updated configuration schema and documentation to reflect the new role precedence.
2026-06-27 07:56:27 +02:00
roboomp e8e7cefe20 fix(agent-session): cut mid-run persistence check from O(n²) to O(n)
On a long subagent-heavy run the TUI thought stream froze for 1.5–4 s
at a time, with the loop watchdog blaming `subagent:*` phases and the
log carrying ~1,255 `Skipping mid-run compaction because turn persistence
is out of order` debug lines per session (issue #3629).

`#persistTurnMessagesForMidRunCompaction` and the persistence-check
helpers it calls were doing two O(n²) things per `onTurnEnd`:

1. Every call rebuilt the branch path via `SessionManager.getBranch()`
   (O(branchSize) `unshift` per call), once per turn message twice (once
   in `#sessionMessageAlreadyPersisted`, once in
   `#hasPersistedLaterTurnMessage`).
2. Every pairwise message comparison serialized full message content
   through `#messageValueSignature` (=`JSON.stringify`), even though
   the content was almost always orthogonal to the identity decision.

Replace the structural comparator with a stable persistence key
(timestamp + role-specific discriminators) extracted to a sibling module
`session/turn-persistence.ts` and drive the planner off one snapshot of
the branch built per `onTurnEnd`. Content equality is retained as the
slow-path tiebreaker for the rare case where two messages collide on the
cheap key (e.g. two assistant turns at the same millisecond with
`undefined` responseId — the shape the test harness emits).

The new helpers (`sessionMessagePersistenceKey`, `planTurnPersistence`,
`sameMessageContent`) are pure functions covered by direct unit tests
in `test/turn-persistence.test.ts`; the existing mid-run / eager
compaction integration tests prove the end-to-end behavior is preserved.

Fixes #3629
2026-06-27 05:28:00 +00:00
can1357 e83c59547a Merge remote-tracking branch 'origin/farm/6de3a278/fix-acp-generate-image-blob-refs' 2026-06-27 06:35:18 +02:00
can1357 a6ac86fe7e feat(coding-agent): enabled project context injection for advisor prompts
- Added formatAdvisorContextPrompt to render project context files into the advisor's system prompt.
- Updated AgentSession to accept and inject advisorContextPrompt into the session system prompt.
- Registered project context files for the advisor to ensure the reviewer evaluates the agent against standing project instructions like AGENTS.md.
2026-06-27 06:34:42 +02:00
roboomp 9d5b1f245d fix(acp): resolved generated image blob refs
Resolved live ACP generate_image payloads through the blob store before emitting image content while keeping rawOutput compact.

Added regression coverage for content[] image blocks and details.images entries without duplicating blob refs as fallback text.

Fixes #3623
2026-06-27 03:46:05 +00:00
can1357 8bc99a616f feat(coding-agent): supported advisor model role with independent resolution
- Added `resolveAdvisorRoleSelection` to handle the advisor role's distinct configuration logic.
- Implemented `rolePriorityDefaults` to allow the advisor role to alias the `slow` model priority chain.
- Updated `AgentSession` to utilize the new advisor-specific resolution logic during session operations.
2026-06-27 04:35:20 +02:00
can1357 577d2a8eb8 style: biome format/organize-imports across integrated PRs 2026-06-27 02:06:38 +02:00
can1357 3273d0de68 Fix /move session cleanup ownership 2026-06-27 02:04:50 +02:00
can1357 bc2d3c2c86 Merge PR #3401: feat(move): interactive /move overlay with fresh session (@oldschoola) 2026-06-27 02:04:50 +02:00
can1357 14cc9cba0f Merge PR #3106: fix(compaction): enable custom provider remote compaction (@roboomp) 2026-06-27 01:39:34 +02:00
can1357 b72b83884d Merge PR #3216: feat: add provider in-flight request limits (@H4vC)
# Conflicts:
#	packages/coding-agent/src/modes/components/settings-selector.ts
2026-06-27 01:39:32 +02:00
can1357 14c8e09e26 fix(coding-agent/session): handled mid-turn context promotion
- Added a check to promote the context model before triggering mid-turn compaction.
- Prevented unnecessary compaction during long tool loops that cross threshold limits by enabling window expansion instead.
2026-06-27 01:04:09 +02:00
can1357 71e044cfe1 feat(coding-agent): added Gemini reasoning runaway detection and interruption
- Implemented a monitoring system to identify Gemini model runaway behavior during thinking steps using consecutive header detection.
- Introduced a configurable tool-call reminder prompt to inject corrective context when reasoning stalls.
- Added session-level logic to automatically interrupt and prune stalled assistant turns from the conversation history.
- Provided comprehensive test coverage for the detection logic and stream interruption scenarios.
2026-06-27 01:01:02 +02:00
can1357 ae1650d689 refactor: renamed search and find tools to grep and glob
- Renamed the `find` and `search` tools to `glob` and `grep` respectively across the codebase to improve command clarity.
- Implemented full-stack support for the renamed tools, including CLI arguments, system prompts, SDK exports, and tool registration.
- Added automated migration logic in `settings` to transform legacy `find` and `search` configuration keys to their new equivalents.
- Updated the `collab-web` renderer registry to ensure backwards compatibility with legacy tool outputs.
2026-06-27 00:57:55 +02:00
can1357 b612e8c792 feat(hashline): allowed file deletion and movement operations
- Implemented file deletion (`REM`) and movement (`MV`) operations within the hashline grammar and parser.
- Added filesystem support for executing delete and move commands while maintaining snapshot history migration.
- Integrated file operation detection and parsing logic into the coding agent and patcher components.
- Added comprehensive integration tests and documentation for the new file-level operation syntax.
2026-06-27 00:33:31 +02:00
Wolfgang Schoenberger 261b7b6d00 fix(coding-agent): treat disabled compaction continue as dead-end
(cherry picked from commit c55b9885e012baec1ca02da8ab292699daf5e77a)
2026-06-26 23:42:51 +02:00
Wolfgang Schoenberger e7be60929f fix(coding-agent): block follow-up continuations after compaction dead-end
(cherry picked from commit aefb744d04a6401f999bab9f7f5b11ca9bd05ad8)
2026-06-26 23:42:51 +02:00
Wolfgang Schoenberger 6958b86822 fix(coding-agent): treat at-band residual as compaction headroom
The post-maintenance headroom guard returned residualTokens < triggerContextTokens
as a secondary check after the recovery-band test. When stale/tool-output pruning
already drove the trigger (postMaintenanceContextTokens) below the band before this
pass, that strict-less comparison made a residual which merely held the line at/under
the band report a false no-progress, suppressing a valid auto-continue and emitting a
spurious warning even though the next turn could no longer re-trip threshold compaction.

The recovery band sits strictly under the compaction threshold, so reaching it already
guarantees the next turn cannot re-trip. Make the band authoritative (residual <= band)
and drop the trigger argument. Adds a regression covering the sub-band trigger case.

(cherry picked from commit 31cf2dc7a30c4134f7a351d61065eca76543f154)
2026-06-26 23:42:51 +02:00
Wolfgang Schoenberger ed418324c3 fix(coding-agent): drain queued messages after stalled compaction
(cherry picked from commit c2197e41d333e9018bbb9f1993e552cd582df411)
2026-06-26 23:42:50 +02:00
Wolfgang Schoenberger 699e07fea7 fix(coding-agent): separate overflow-retry fit check from auto-continue band
Addresses PR #3412 review (roboomp blocking + codex P2 + Copilot nits):

- The overflow/incomplete retry no longer reuses the COMPACTION_RECOVERY_BAND
  hysteresis. Reusing it required residual context below 0.8×threshold, which
  turned a recoverable overflow (e.g. 150k on a 200k window, under the ~170k
  threshold) into a manual dead-end. Add #compactionCreatedRetryFit, which
  measures the rebuilt prompt against the usable fit budget
  (contextWindow - effectiveReserveTokens) and is evaluated AFTER the failed
  assistant is dropped, so the just-failed turn is excluded.
- The threshold auto-continue keeps the stricter recovery-band check
  (#compactionCreatedHeadroom) — that path is the snapcompact thrash guard.
- Split the no-progress warning so each path warns on its own signal.
- Alias errorIsFromBeforeCompaction as assistantPredatesCompaction in the
  threshold-usage path for clarity; de-duplicate the rationale comment.

Adds two regression tests (recoverable overflow retries; non-fitting overflow
pauses + warns), mutation-verified against the band-vs-fit split.

(cherry picked from commit f8cf45b2740f04d8776a84521ba563b779d65b25)
2026-06-26 23:42:50 +02:00
Wolfgang Schoenberger 6a55205b68 fix(coding-agent): stop auto-compaction thrash when a single turn exceeds the threshold
prepareCompaction keeps the most-recent turn verbatim (findCutPoint never
cuts at tool results), so when that single turn already exceeds the
compaction threshold the rewritten context stays above threshold. The
context-full / snapcompact auto-compaction success tail scheduled the
agent-authored auto-continue (and the overflow/incomplete retry)
unconditionally, so the next agent_end re-entered #checkCompaction over
the same oversized tail and re-fired forever.

This is the residual loop left after #3247 capped snapcompact's own frame
projection: once #computeSnapcompactMaxFrames drops the frame cap below
one frame, snapcompact is skipped and the context-full summarizer path
still creates no headroom, so the loop persists on that path.

- #runAutoCompaction now gates the continuation and the overflow/
  incomplete retry on a post-maintenance headroom check
  (#compactionCreatedHeadroom), reusing the shake recovery-band
  hysteresis from #2275 (consolidated as the shared
  COMPACTION_RECOVERY_BAND). When a pass frees too little it pauses
  automatic maintenance and emits a single warning instead of looping.
- The post-turn threshold check ignores an assistant's stale
  pre-compaction usage so the scheduled auto-continue can't re-trip on
  the kept assistant's old high token count.

Adds a regression test covering the no-headroom (pause + warn, no
continuation) and headroom (auto-continue, no warn) paths; both
assertions are mutation-verified against the guard.

(cherry picked from commit 6fcbbe2b3075827ee621acaee8efa2c586eedd3e)
2026-06-26 23:42:50 +02:00
can1357 4e3a0a0f46 Merge PR #3523: fix(advisor): filter content-free advisor notes at enqueue boundary (@roboomp)
# Conflicts:
#	packages/coding-agent/src/session/agent-session.ts
2026-06-26 23:42:40 +02:00
can1357 c50af68125 Merge PR #3594: fix(session): prune classifier refusals from context (@roboomp) 2026-06-26 23:42:15 +02:00
roboomp 061c0ffb43 fix(compaction): kept snapcompact local on preflight failure
Stopped snapcompact preflight failures from falling through to the provider-backed LLM summarizer and covered manual plus auto compaction paths.

Fixes #3599
2026-06-26 20:37:50 +00:00
roboomp 11c96c9ae3 fix(session): preserved refusal stop payloads
Passed the settled assistant message into session_stop emission so refusal-as-error turns can be pruned from replay context without hiding their stop details from extension hooks.

Expanded the refusal regression test to assert the session_stop payload still exposes the refusal as last_assistant_message.

Fixes #3591
2026-06-26 18:06:09 +00:00
roboomp db61ca0274 fix(session): kept session_stop hooks on classifier refusals
Removed the early return after refusal pruning so the agent_end tail still reaches `#emitSessionStopEvent`, restoring `session_stop` extension hooks (block/continue/telemetry) for refusal-as-error stops.

Regression test wires an extensionRunner with a session_stop handler and asserts it fires for both the refusal turn and the following clean turn.

Fixes #3591
2026-06-26 17:59:26 +00:00
roboomp fbcc157b75 fix(session): pruned classifier refusals from context
Stopped API-level classifier refusal messages from being persisted or replayed as assistant dialogue after the failed turn settles.

Fixes #3591
2026-06-26 17:53:48 +00:00
can1357 5d4203d52b fix(coding-agent): preserved resume scoping after PR merges 2026-06-26 17:17:43 +02:00
can1357 d07d03d2af Merge PR #3565: compact long tool loops mid-turn (@riverpilot) 2026-06-26 17:12:09 +02:00
can1357 b6b0379a3b Merge PR #3540: manual coding-agent GC command (@Kenmege)
# Conflicts:
#	packages/coding-agent/test/issue-3461-repro.test.ts
2026-06-26 17:09:24 +02:00
can1357 80c6528c93 fix(coding-agent): resolved PR 3562 merge fallout 2026-06-26 17:08:53 +02:00
Alexander Kirilin e9530895a1 Merge remote-tracking branch 'origin/main' into fix/mid-turn-auto-compaction-3525 2026-06-26 11:02:40 -04:00
Alexander Kirilin d2b6bde571 fix(agent): preserve mid-turn tool persistence order 2026-06-26 10:57:36 -04:00