Commit Graph

5863 Commits

Author SHA1 Message Date
can1357 a82d68ef49 feat(coding-agent): added experimental snapcompact inline imaging for system prompt and tool results
- Added `renderSnapcompactFrames()` and `snapcompactFrameCount()` to @oh-my-pi/snapcompact for paging arbitrary text into PNG image blocks without dim-marker bookkeeping.
- Widened the agent loop's `transformProviderContext` hook to `(context, model) => Context` so per-request transforms can gate on the dispatch model's capabilities.
- Added `SnapcompactInlineTransformer` rendering the system prompt and large historical tool results as snapcompact frames on vision models: vision gate, per-provider image budgets, 3k-token floor, savings-margin gate, skip-last rule, and hash-keyed render caches swept to live tool calls.
- Added default-off `snapcompact.systemPrompt` and `snapcompact.toolResults` settings under a new Context → Experimental group, composed after secret obfuscation in `sdk.ts` so frames are built per-request and never persisted to session.jsonl.
- Added prompt stubs (`snapcompact-system-stub.md`, `snapcompact-system-frames-note.md`, `snapcompact-toolresult-note.md`) and unit tests covering frame paging, no-mutate guarantees, budget caps, gates, and render caching.
2026-06-12 03:27:50 +02:00
Can Bölük 92a4ab4ad4 Merge branch 'main' into fix/local-memory-consolidation-instructions 2026-06-12 03:26:50 +02:00
Can Bölük 5a2a33658a Merge pull request #2256 from H4vC/accent-colors
session accent: derive from theme mode with collision avoidance
2026-06-12 02:36:45 +02:00
can1357 dd202786b2 test(coding-agent): aligned the settings search Escape test with the global search banner
- Updated `settings-selector-memory-refresh.test.ts` to assert the cross-tab search banner's cursor rendering (`b▌`) instead of the old `Search: b` label when verifying Escape clears the search before closing the selector.
2026-06-12 02:33:49 +02:00
can1357 8fd5171768 ux(coding-agent): capped collapsed bash, ssh, and eval previews to a viewport tail window
- Replaced the fixed `CALL_PREVIEW_MAX_LINES` cap in `render-utils.ts` with a dynamic `previewWindowRows()` (terminal rows minus a chrome reserve); `capPreviewLines` now returns lines untouched when expanded and windows them otherwise.
- Applied the cap in every render state for bash and ssh command previews — streaming and final render identically instead of snapping fully open on completion — and included the preview window in bash's render cache key so terminal resizes invalidate it.
- Capped eval cell code previews via the same window; previously cell code was never capped at all, with `ctrl+o` remaining the only way to uncap.
- Added stream-vs-final parity coverage in `bash-sixel-render.test.ts`, `ssh-render.test.ts`, and the new `eval-code-preview.test.ts`, and a changelog entry.
2026-06-12 02:33:49 +02:00
can1357 7c3407ac65 fix(coding-agent): converted Zod tool-parameter schemas to wire schema in five consumers
- Fixed `/dump` output (`session-dump-format.ts`) and the RPC `get_state` `dumpTools` payload (`rpc-mode.ts`) serializing Zod schema instances — leaking `def`/`shape` internals and stringified methods — by converting parameters through `zodToWireSchema` like providers receive.
- Fixed context-usage token estimation stringifying the Zod `def` tree, which overcounted tool schema tokens in the status line.
- Fixed tool-discovery indexing (`tool-index.ts`) returning empty `schemaKeys` for Zod tools, weakening BM25 ranking; keys are now recovered via wire conversion.
- Fixed the extension inspector panel rendering "(no arguments)" for Zod tools by reading properties off the converted wire schema.
- Added coverage in `tool-index.test.ts` plus new `context-usage.test.ts` and `session-dump-format.test.ts`, and a changelog entry.
2026-06-12 02:33:49 +02:00
can1357 4ad797d274 feat(coding-agent): added global type-to-search across /settings tabs
- Added a `SettingsSearchHeader` banner to `SettingsSelectorComponent`, permanently mounted under the top border and rendering only while a cross-tab search is active.
- Typing now filters settings across every tab via `getSettingItemFilterText` + `fuzzyFilter`, with per-tab first-match ids so Tab jumps between tabs that have matches; non-matching tabs render muted and the pre-search tab is restored on exit.
- Moved the tab bar below the tab content, disabled `SettingsList`'s own type-to-search in favor of the selector-owned global search, and only advertised PgUp/PgDn in the hint when multiple sections exist.
- Wired the new `mutedTab` style into `getTabBarTheme` in `modes/shared.ts`.
2026-06-12 02:33:48 +02:00
can1357 c276cd6eff feat(coding-agent): reorganized /settings into titled sections with a sidebar layout
Also normalizes setting labels/descriptions and carries the package changelog entries for this batch (adjacent unreleased bullets are not splittable per commit), restoring section placement disturbed by the two prior changelog hunks.
2026-06-12 02:33:48 +02:00
can1357 23a1e244ba fix(coding-agent): froze detached task shimmer once blocks leave the transcript live region 2026-06-12 02:33:48 +02:00
can1357 49ad75709b fix(coding-agent): reset Responses provider session on stale replay errors before retrying 2026-06-12 02:33:47 +02:00
can1357 9360d24793 fix(coding-agent): resolved image-generation credentials through the model registry with typed errors 2026-06-12 02:33:47 +02:00
can1357 49cdf56993 fix(coding-agent): resolved Kagi, TTS, and model-discovery bearers through withAuth 2026-06-12 02:33:47 +02:00
can1357 503b2b7156 fix(coding-agent): routed web-search OAuth bearers through withOAuthAccess 2026-06-12 02:33:47 +02:00
can1357 98fddec509 fix(mnemopi): resolved API keys per request through withAuth and typed HTTP errors 2026-06-12 02:33:47 +02:00
can1357 c234d00def fix(coding-agent): handed compaction and summarization per-candidate API-key resolvers 2026-06-12 02:33:47 +02:00
can1357 9629842f33 feat(coding-agent): accepted a model directly in ModelRegistry.resolver 2026-06-12 02:33:46 +02:00
can1357 f27f885eae fix(coding-agent/modes): handled plugin settings failures and Escape close during loading
- Caught and logged npm `PluginManager.list()` rejections in `PluginSettingsComponent`, returning an empty plugin list so the settings tab no longer stays blank when plugin listing fails.
- Added tests covering Escape handling while lists are loading and marketplace rendering when npm listing rejects.
2026-06-12 02:33:45 +02:00
can1357 ad276e931c feat(ai): added Codex Lite options and improved response stream resilience
- Added `responsesLite`, `reasoningContext`, `clientMetadata`, and `onModerationMetadata` options.
- Changed Lite request transformation to default `reasoning.context` to `all_turns`.
- Changed request shaping to strip image `detail` fields and force `parallel_tool_calls` off in Lite mode.
- Fixed streaming behavior by excluding `client_metadata` from websocket append diffs and swallowing moderation metadata errors.
2026-06-12 02:33:45 +02:00
can1357 15bddcea80 Merge branch 'main' into farm/92afd68d/fix-lsp-format-tabsize-default 2026-06-12 02:33:19 +02:00
can1357 d4b2c18b39 Merge branch 'main' into farm/270f5057/settings-esc-submenu-back 2026-06-12 01:15:48 +02:00
can1357 49919bd73f Merge remote-tracking branch 'origin/farm/36668129/fallback-issue-state-reason' 2026-06-12 00:05:04 +02:00
roboomp fa613d438d fix(agent): inherited default for unset designer role
Unconfigured pi/designer now follows modelRoles.default before consulting the Gemini priority chain, matching the smol and slow fallback behavior while preserving priority defaults when no default is configured.

Added regression coverage and updated the coding-agent changelog.

Fixes #2336
2026-06-11 20:40:08 +00:00
roboomp 9a94faac0d fix(agent): expanded inherited default role aliases
When modelRoles.default points at another role alias (e.g. "pi/slow") and the inheriting role is unset, the resolver now recurses through resolveConfiguredRolePattern with a visited-role set so downstream one-layer expanders like completion-bridge's resolveTierModel see concrete model patterns instead of pi/<role>. Self-aliased defaults still collapse to the role's built-in priority chain.

Added regression coverage for both cross-role expansion paths.

Fixes #2336
2026-06-11 20:37:07 +00:00
roboomp d79b761aca fix(agent): preserved self-aliased role priorities
When modelRoles.default points at pi/smol or pi/slow, unset matching roles now expand back to their built-in priority chain instead of returning the alias as a literal model pattern.

Added regression coverage for self-aliased smol and slow defaults.

Fixes #2336
2026-06-11 20:30:23 +00:00
roboomp 18994b863e style: bun run fix 2026-06-11 20:24:54 +00:00
roboomp da5a2baace fix(agent): used default for unset smol and slow roles
Unconfigured pi/smol and pi/slow role aliases now inherit modelRoles.default before consulting the cloud-priority list, avoiding silent paid-provider routing for local-default setups.

Added resolver coverage for both roles and updated the coding-agent changelog.

Fixes #2336
2026-06-11 20:24:43 +00:00
roboomp 5bc96d6408 fix(tool): tolerated missing issue state reason
Older GitHub CLI releases reject the optional issue stateReason JSON field. Retried single issue reads without it and stopped requesting it for issue listings.\n\nFixes #2333
2026-06-11 19:55:22 +00:00
can1357 37faeb6a6d chore: bump version to 15.11.3 2026-06-11 21:28:47 +02:00
can1357 c3e5b60174 feat(catalog): added requestModelId routing and Copilot long-context discovery support
- Added optional `requestModelId` to the `Model` interface for upstream wire overrides.
- Prioritized `model.requestModelId` when resolving request model IDs for Anthropic and OpenAI paths.
- Used `COPILOT_API_HEADERS` in Copilot discovery and policy calls with API version `2026-06-01`.
- Synthesized Copilot `-1m` long-context sibling models with dedicated upstream IDs and pricing data.
2026-06-11 21:28:32 +02:00
can1357 97445ebb9b fix(coding-agent/tools): fanned out explicit file targets for multi-path searches
- Added `fanOutFileItems` plumbing through `resolveSearchPathItems`/`resolveExplicitSearchPaths` and `ToolScopeOptions` so plain-file entries can be scanned as explicit targets instead of being folded into an unrequested ancestor walk.
- Search tool now enabled `fanOutFileTargets` and deduplicated overlapping results by tracking a `path\0line` key before merging matches.
- Expanded multi-path tests for shared non-root ancestors, explicit `.git/config` targets, and overlap deduplication behavior.
2026-06-11 21:24:30 +02:00
roboomp 89ecd38639 fix(settings): delegated escape to open submenu
Removed the dead settings selector submenu guard so Escape reaches the active settings or plugins child component. Added a regression test for closing an open settings submenu before the parent selector.

Fixes #2331
2026-06-11 19:12:21 +00:00
can1357 edbdda6fbd fix(git): disable tag following during pushes
Programmatic `git push` operations should not follow annotated tags configured by a user's `push.followTags = true`. This setting can lead to push failures if the remote rejects tag creation (e.g., in PR-head forks), even if the branch update itself is valid.

Adding `--no-follow-tags` explicitly overrides this user setting, ensuring only the specified refspec is pushed and preventing rejections.
2026-06-11 21:05:26 +02:00
roboomp 79ccb61d0c style: bun run fix 2026-06-11 21:03:49 +02:00
roboomp 2f4ba21a62 fix(lsp): resolved per-file format options from editorconfig and content
The format-on-write path sent a hardcoded {tabSize:3, insertSpaces:true}
on every textDocument/formatting request from two duplicated DEFAULT_FORMAT_OPTIONS
constants. Servers that honour tabSize for re-indent (yaml-language-server, the
common YAML/Kustomize/Flux case) reserialized 2-space files at a 3-space stride
on every write — exactly the corruption reported on Kubernetes/Flux YAML repos.

Replace both constants with a single resolveFormatOptions(filePath, content)
helper that layers, in order:
- .editorconfig (indent_style, indent_size, tab_width) via the new
  getEditorConfigFormatting() helper in pi-utils — strict, no fallback.
- Indent sniffed from the in-memory content the agent is about to write
  (first indented line decides spaces vs tabs; GCD of space-indent widths
  fixes the unit).
- Hardcoded 2-space fallback. The previous 3-space stride was an unusual
  default that actively damaged every file with a 2/4-space convention.

Tests cover the editorconfig and content-sniffing paths plus a direct
regression check that 2-space YAML stays 2-space (the issue's repro).

Fixes #2329
2026-06-11 21:03:49 +02:00
Can Bölük 56017a1401 Merge branch 'main' into fix-working-loader-scrollback 2026-06-11 21:03:37 +02:00
can1357 6d2935f1a1 fix(tui): keep the topmost native-scrollback live seam when multiple root children report one
The root compose recorded seams last-writer-wins, so the status
container's new seam (mounted loader) overwrote the transcript's seam
whenever both reported in the same frame. With a volatile live block
(no commit-safe end) the boundary then moved below the transcript's
still-mutable rows and committed them as stale history — the same
duplication class this PR fixes for the loader, relocated upward.

Commits are prefix-only: the first child reporting a live region (plus
its own commit-safe extension) already bounds everything below it, so
the topmost seam now wins. Adds a two-reporter regression test and
documents the multi-reporter contract on NativeScrollbackLiveRegion.
2026-06-11 21:02:11 +02:00
roboomp 77327f61dd style: bun run fix 2026-06-11 18:59:43 +00:00
roboomp 8b0ac67f40 fix(lsp): resolved per-file format options from editorconfig and content
The format-on-write path sent a hardcoded {tabSize:3, insertSpaces:true}
on every textDocument/formatting request from two duplicated DEFAULT_FORMAT_OPTIONS
constants. Servers that honour tabSize for re-indent (yaml-language-server, the
common YAML/Kustomize/Flux case) reserialized 2-space files at a 3-space stride
on every write — exactly the corruption reported on Kubernetes/Flux YAML repos.

Replace both constants with a single resolveFormatOptions(filePath, content)
helper that layers, in order:
- .editorconfig (indent_style, indent_size, tab_width) via the new
  getEditorConfigFormatting() helper in pi-utils — strict, no fallback.
- Indent sniffed from the in-memory content the agent is about to write
  (first indented line decides spaces vs tabs; GCD of space-indent widths
  fixes the unit).
- Hardcoded 2-space fallback. The previous 3-space stride was an unusual
  default that actively damaged every file with a 2/4-space convention.

Tests cover the editorconfig and content-sniffing paths plus a direct
regression check that 2-space YAML stays 2-space (the issue's repro).

Fixes #2329
2026-06-11 18:59:38 +00:00
Bingxuan LU ac8736e2bb Fix working loader scrollback duplication 2026-06-12 02:44:57 +08:00
roboomp 9d4fcdb536 fix(mnemopi): keep consolidate() reachable from aliased subagent enqueue
The previous refactor dropped `if (this.aliasOf) return` into
consolidate(), which made `/memory enqueue` invoked from inside a
subagent a no-op. The old enqueue() body short-circuited only
forceRetainCurrentSession (via its own guard) but still flushed
extractions and slept on state.memory, which for aliased states points
at the parent's shared retain bank.

Moved the alias guard back out of consolidate(): forceRetainCurrentSession
keeps its own early-return (the subagent's transcript is the parent's
concern), so consolidate() runs the SQL-level flush+sleep on every
owned bank for both primary and aliased states. The lifecycle guard
stays in dispose() so disposing a subagent still does not flush, sleep,
or close the parent's memory.

Added a regression test: a /memory enqueue routed through the aliased
child state calls flushExtractions + sleepAllSessions(false) on the
parent's owned memory exactly once, and forceRetainCurrentSession runs
on the child (where its own guard returns early) but not on the parent.

Addresses #2327 review.
2026-06-11 18:34:53 +00:00
roboomp 6abe6401bc fix(mnemopi): skip consolidation when clearing memory
`/memory clear` (mnemopiBackend.clear) calls dispose() right before
removing the SQLite files. Running the consolidation pass first would
make a destructive clear spend tokens/time creating memories that get
deleted on the very next line, and a slow extraction could block the
clear path under llmMode: remote.

Added a `{ consolidate?: boolean }` option to
MnemopiSessionState.dispose; defaults to true so normal shutdown still
runs the SHMR/beam pipeline. mnemopiBackend.clear passes
`{ consolidate: false }` so the close path stays unsubscribe + close
only. Added a regression test that spies on forceRetainCurrentSession,
consolidate, flushExtractions, and sleepAllSessions to pin the new
behavior, while close still runs once per owned bank.

Addresses #2327 review.
2026-06-11 18:29:23 +00:00
roboomp aba01289d0 fix(mnemopi): consolidate working memory on session shutdown
MnemopiSessionState.dispose() now drains pending fact extractions and
runs sleepAllSessions on every owned bank before closing handles, and
AgentSession.dispose() awaits the result. This matches the manual
`/memory enqueue` slash command which was the only caller of the
consolidation pipeline.

Without the shutdown hook, episodic_memory, gists, consolidation_log,
graph_edges, and triples stayed empty for every deployment that never
typed `/memory enqueue|rebuild` — working memory accumulated forever
and long-term recall never formed.

Factored the consolidate step out of `mnemopiBackend.enqueue` into a
shared MnemopiSessionState#consolidate so the slash command and the
shutdown path share one implementation. Added two regression tests
verifying owned-bank consolidation order (flush -> sleep -> close, per
bank) and that aliased subagent dispose stays a no-op against the
parent.

Fixes #2320
2026-06-11 18:24:11 +00:00
can1357 23dedc5086 chore: bump version to 15.11.2 2026-06-11 18:15:52 +02:00
can1357 f2f8081ecc chore: update changelogs 2026-06-11 18:15:24 +02:00
can1357 ce4ebad726 feat(agent): added per-call tool concurrency resolver and parallel bash execution
- Extended `AgentTool.concurrency` to accept per-call resolver functions and resolved concurrency mode from each tool call, falling back to exclusive on resolver errors.
- Updated BashTool to schedule non-PTY calls as shared and PTY calls as exclusive so non-interactive bash calls can run in parallel within one message.
- Tracked in-use persistent shell sessions in the bash executor and routed overlapping calls on the same session key to isolated one-shot shells while preserving owner session availability.
2026-06-11 18:13:07 +02:00
can1357 926dfdea39 fix(coding-agent): restored side-channel IRC auto-reply for busy recipients when async execution is disabled
A subagent's send await:true to Main during a blocking task spawn was a structural deadlock: deliverIrcMessage queues mid-turn messages as step-boundary asides, but Main's next boundary requires the sender's own batch to finish, so the sender always burned the full irc.timeoutMs. Awaited sends now pass expectsReply through IrcBus.send; a mid-turn recipient with async.enabled off generates an ephemeral no-tools reply via runEphemeralTurn, records an irc:autoreply aside in its own history, and delivers it back over the bus with replyTo threading so the sender's waiter resolves.
2026-06-11 18:12:22 +02:00
can1357 abc152e5ca fix(test): write loader fixtures before module resolution warms Bun dir cache
PR #2297's new test interleaved fixture writes with loader calls in one temp
dir; Bun's resolver caches directory entries process-wide, so tool.ts written
after loadExtensions() resolved extension.ts was invisible to the subsequent
dynamic import on macOS. Write all fixtures up front.
2026-06-11 18:08:51 +02:00
can1357 64f081397c Merge PR #2263: fix(tools): normalize Windows search paths 2026-06-11 18:00:44 +02:00
can1357 defdf0a0ab ux(coding-agent/tools): refined job status output messaging
- Removed the running count from the status meta list so only completed, failed, and cancelled counts are shown.
- Updated the waiting message to use singular/plural job labels and simplify wording when all jobs are running.
2026-06-11 18:00:42 +02:00
can1357 965c5d4000 Merge PR #2262: feat(rpc): expose slash command metadata 2026-06-11 17:59:40 +02:00