Commit Graph
7787 Commits
Author SHA1 Message Date
can1357 d8bf177af7 refactor(coding-agent/task): moved taskToolRenderer to separate module
- Extracted taskToolRenderer to a dedicated renderer file to resolve circular dependencies.
- Updated all references to the renderer to point to the new location.
2026-06-28 07:27:02 +02:00
can1357 4fb1490747 feat(coding-agent/task): updated assistant review prompt and export renderer
- Updated the reviewer prompt instructions for clarity.
- Reordered export statements to address potential circular dependency issues during tool registration.
2026-06-28 07:27:02 +02:00
can1357 a8b12047ac Merge remote-tracking branch 'origin/farm/355ab5d8/fix-snapcompact-visual-fallback' 2026-06-28 07:27:02 +02:00
can1357 33d367aae5 Merge remote-tracking branch 'origin/farm/566ed2aa/keep-other-question-context' 2026-06-28 07:27:01 +02:00
can1357 2900730aa6 fix(eval): serialize vm link passes across concurrent local imports
Concurrent graph-root loads in the JS eval kernel segfaulted Bun
(SIGSEGV at 0xFFFFFFFFFFFFFFF8, getImportedModule on a null record in
JSC::AbstractModuleRecord::innerModuleLinking). Two roots loaded at once
over an overlapping local-import graph — e.g.
Promise.all([import("./a.ts"), import("./b.ts")]) sharing a dependency —
each launched its own module.link() over the same shared
vm.SourceTextModule instances. The async link resolver yields
mid-instantiation, letting the two link passes interleave and re-enter
Bun's node:vm linker, which crashes instead of throwing.

The earlier single-pass fix (15.7.2) only serialized linking within one
graph root; it did not guard two concurrent roots over shared modules.

LocalModuleLoader now routes every module.link() through a promise-chain
mutex (#serializeLink), so the linker is never re-entered
mid-instantiation. The lock is held only across link(), not evaluate(),
so a dynamic import during evaluation re-acquires it without deadlock,
and the chain swallows rejections so a failed link cannot wedge later
imports. Reproduced and verified against the user crash trace: the
concurrent-diamond repro went from 5/6 crashes to 0/N with correct
namespaces.
2026-06-28 07:27:01 +02:00
can1357 289dd770c8 feat(coding-agent): reworked subagent yields for incremental results
- Extended `tools/yield.ts` with typed incremental sections, raw last-turn terminal results, and updated yield guidance in the subagent system prompts.
- Reworked `task/executor.ts`, `task/render.ts`, and `task/types.ts` to assemble typed yield sections, render reviewer results from incremental yield data, and preserve the typed result shape.
- Switched `prompts/agents/reviewer.md`, `review-request.md`, and `review-custom-request.md` from `report_finding` calls to incremental `yield` sections.
- Added incremental-yield coverage in `test/task/executor-warnings.test.ts`, `test/task/render-yield-shape.test.ts`, `test/tools/yield-extraction.test.ts`, and `test/tools/yield.test.ts`.
2026-06-28 07:27:01 +02:00
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 d18e2c2f4d feat(agent): introduced idle progress recaps and optional session titles
- Added idle recap functionality to EventController to display goals and next actions when the agent is inactive.
- Updated session parsing in gc-cli and memories to correctly support optional title entries in session files.
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 46278588ea test(session): implemented persistent session management and testing
- Implemented mutable session titles with audit tracking, including storage persistence for SQL and Redis backends.
- Added comprehensive session management features such as idle recap triggers, incremental subagent yield submissions, and automated title refreshing.
- Enhanced task tracking in the TodoTool with progress prioritization and improved session cleanup logic.
- Introduced citation tag handling for OpenAI-compatible source markers and improved edit parsing.
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 a36f12be83 feat(config): introduced schema for idle recap and title refresh
- Added configuration schema for idle recap feature including enabled state and idle duration settings.
- Added configuration schema to refresh session titles automatically upon replanning tasks.
- Updated settings interfaces to include RecapSettings and TitleSettings types.
- Recap.enabled.
- Recap.idleSeconds.
- Title.refreshOnReplan.
2026-06-28 07:27:00 +02:00
roboomp 1c6d3ca5a8 style: bun run fix 2026-06-27 14:00:25 +00:00
roboomp 6a83f0a4aa fix(tui): preserved ask other context
Kept the ask tool question and options visible when switching to the Other custom input editor.

Added a regression test for the custom editor title context.

Fixes #3660
2026-06-27 13:59:19 +00:00
roboomp 24318ff2ea fix(compaction): downgraded auto snapcompact for text-only models
Auto snapcompact now switches automatic maintenance to context-full when the active model cannot read image frames, preserving manual snapcompact's local-only failure contract while keeping text-only sessions running.

Fixes #3659
2026-06-27 13:56:47 +00:00
can1357 24341e4abf chore: bump version to 16.2.2 2026-06-27 13:24:46 +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 3c12b9a650 refactor(ai): restructured codex stream processing and runtime lifecycle
- Replaced functional streaming logic with a stateful `CodexStreamProcessor` class.
- Converted `CodexStreamRuntime` into a class with explicit state initializers and lifecycle methods.
- Encapsulated tool call delta tracking and interruption logic within dedicated class methods.
- Integrated `textSignature` generation into text-type output blocks using versioned encoders.
2026-06-27 13:07:51 +02: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 96a838ee90 chore(extensibility): updated legacy registry modules with utility helpers
- Added block-symbols and settings-stream-fn utility modules.
- Removed the deprecated strip utility module from the bundle.
2026-06-27 12:26:11 +02:00
can1357 0bb0547f17 fix(ui): reordered project path display for homedir priority
- Prioritized homedir projects over /work in status line path display.
2026-06-27 12:26:11 +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
roboompandcan1357 a98dc285a3 fix(tests): isolated CI-environment assumptions across the coding-agent suite
The CI gate failed in several non-overlapping ways once the full coding-agent suite ran here: tests wrote into the real $HOME (`/srv/agent-home`) which is read-only, a fixture rotated stored Anthropic API keys but Settings reloaded the user models.yml and shadowed them, an OAuth callback server bound to `hostname:"localhost"` (loopback unreachable in this runtime), a built-in tool metadata assertion only saw `github` when `gh` was installed, and the GithubTool `pr_checkout` worktree assertions assumed `~/.omp/wt` but `XDG_DATA_HOME` redirected `getWorktreesDir()` to `$XDG_DATA_HOME/omp/wt`.

Fixes:

- `packages/ai/src/registry/oauth/callback-server.ts`: drop `hostname: "localhost"` when no caller-supplied hostname overrides it. Bun on Linux refused inbound connections to the listener when bound explicitly to `localhost`; defaulting to Bun.serves default binding restores loopback connectivity.

- `packages/coding-agent/test/status-line-path.test.ts`: route the `~/Projects` fixtures through a writable temp home (spy `os.homedir()`), housed under the repo `.wt/` worktree scratch so the temp home is not classified as a status-line scratch root.

- `packages/coding-agent/test/skills.test.ts`: ditto for the `~/.pi-skills-test-*` mkdtemp in the tilde-expansion test.

- `packages/coding-agent/test/marketplace/project-scope.test.ts`: stop writing `~/.git`; build the entire home-dir guard fixture in a temp dir and spy `os.homedir()`.

- `packages/coding-agent/test/oauth-flow.test.ts`: wrap each callback fetch in a brief retry so the simulated browser redirect tolerates the few-ms gap before the Bun callback server starts accepting connections.

- `packages/coding-agent/test/tools/gh.test.ts`: extend `setupTempHome()` to clear `XDG_DATA_HOME`/`XDG_STATE_HOME`/`XDG_CACHE_HOME` for the duration of the test so the rebuilt dirs resolver routes `getWorktreesDir()` back through the spied home, then restore them on cleanup.

- `packages/coding-agent/test/tool-discovery/initial-tools.test.ts`: instantiate `GithubTool` directly in the metadata fixture so the assertion runs even when `gh` is unavailable (GithubTool.createIf returns null without `gh`).

- `packages/coding-agent/test/agent-session-retry-cap.test.ts`: pass an isolated `models.yml` path to `ModelRegistry` so the two-Anthropic-key fixture is the authoritative credential source instead of any user-level command-backed Anthropic key.

Verification:

- `bun check` → passed

- `bun run test` (full coding-agent suite, 4 buckets, all chunks) → 0 fails

Fixes #3639
2026-06-27 11:15:44 +02:00
can1357 00b9b236c8 refactor: consolidated error handling logic using AIError utilities
- Added `isTransientStatus` to determine retryable HTTP status codes.
- Replaced fragmented manual status/message checks with unified `AIError` classification and helper methods.
- Standardized auth failure detection across `coding-agent`, `mnemopi`, and provider clients.
2026-06-27 11:14:58 +02:00
can1357 27fa777c59 Merge remote-tracking branch 'origin/farm/80bbf566/advisor-provider-options-parity' 2026-06-27 10:46:12 +02:00
roboompandcan1357 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 c424888ce0 style: bun run fix 2026-06-27 08:01:16 +00:00
roboomp bc41348f04 fix(tui): removed stale subagent hub hint calls
Removed the remaining callers of StatusLineComponent.setSubagentHubHint after the status-line subagent hub hint display was simplified away. The status-line cache test already asserts the hub hint is absent, so the stale setter call only broke type checking.

Fixes #3639
2026-06-27 08:01:06 +00: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 053da98ddc feat: removed pi dialect and its associated infrastructure
- Removed the pi dialect implementation and associated source files.
- Updated dialect resolution, factory registration, and type definitions to exclude pi.
- Cleaned up settings schema and user options to remove pi-related configurations.
- Deleted corresponding test suites covering pi dialect functionality, in-band tools, and examples.
2026-06-27 08:37:25 +02:00
can1357 b96c341532 refactor(coding-agent/modes): removed unused subagent hub hint integration
- Removed dead code responsible for setting the subagent hub hint in the interactive mode initialization.
2026-06-27 08:24:16 +02:00
roboompandcan1357 db377d417c fix(advisor): surfaced state.error from a cleanly resolved prompt
Agent.#runLoop catches provider/stream failures internally and resolves prompt() cleanly with the message recorded on state.error, so AdvisorRuntime treated the OpenRouter 404/no-endpoints turn as a success and never reached notifyFailure. Inspect state.error after each prompt and throw so the retry/notify path runs on real provider failures.

Fixes #3635
2026-06-27 08:20:46 +02:00
can1357 98b7db0c84 feat(coding-agent): simplified subagent status line display
- Removed "running" status and hub hint details from the subagent badge text.
- Updated relevant status line tests to expect the simplified badge format.
2026-06-27 08:18:58 +02:00
can1357 3da3a7c1ba Merge remote-tracking branch 'origin/farm/148b0ac6/marketplace-plugins-duplicates' 2026-06-27 08:12:09 +02: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 934b998d14 Merge remote-tracking branch 'origin/farm/68718b4d/tavily-recency-empty-retry' 2026-06-27 08:11:21 +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 639daccbd7 fix(coding-agent): prevented auto-generated titles from re-shouting all-caps input
- Updated `reconcileTitleCasing` to ignore purely uppercase words when restoring source casing.
- Restricted restoration logic to mixed-case identifiers (e.g., `TinyVMM`, `iOS`) to avoid overriding the model's clean sentence case with emphatic user shouting.
- Added regression tests to ensure all-caps input does not trigger title re-shouting.
2026-06-27 08:01:00 +02:00
roboomp f228c56b28 fix(web-search): retried empty tavily recency results
Retry Tavily recency-filtered searches once without time_range when the filtered HTTP 200 response contains no renderable content.

Fixes #3633
2026-06-27 05:58:58 +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
roboomp e3fb8956a2 fix(coding-agent): treated legacy scope-less marketplace entries as user
Coerced missing scope on installed_plugins.json entries to user before suppressing them, matching listClaudePluginRoots semantics, so users carrying registries written before the scope field still see marketplace plugins hidden from plugin list and doctor.

Fixes #3628
2026-06-27 05:19:03 +00:00
roboomp cf3425cc61 fix(coding-agent): suppressed package-less marketplace plugins
Derived marketplace runtime package names from plugin IDs when package.json is absent, preserving suppression for config-only marketplace installs. Added regression coverage for package-less LSP plugin installs in plugin list and doctor.

Fixes #3628
2026-06-27 05:16:54 +00:00
roboomp a4256d6507 fix(coding-agent): preserved same-name plugin links
Compared marketplace runtime entries by realpath before suppressing link-only plugin-manager entries. Added a regression where a local runtime link reuses a marketplace package name but points at a different path.

Fixes #3628
2026-06-27 05:12:57 +00:00