Commit Graph

18639 Commits

Author SHA1 Message Date
can1357 c41f65ec89 Merge PR #8723: fix(launch): scope daemon prune to the daemons container (@roboomp) 2026-08-19 01:36:03 +02:00
can1357 1037bca4be Merge PR #8722: fix(ai): strip leaked ```thinking delimiters from Gemini thought summaries (@roboomp) 2026-08-19 01:36:03 +02:00
can1357 e88fb70afe Merge PR #8720: fix(compaction): honor /clear reset boundary in prepareCompaction (@roboomp) 2026-08-19 01:36:03 +02:00
can1357 68c636f0b5 Merge PR #8717: fix(pi-ai): honor onPayload replacement payloads in openai-completions, bedrock and cursor (@ranxianglei) 2026-08-19 01:36:03 +02:00
can1357 0d50c53d4c Merge PR #8715: fix(snapcompact): disambiguate digit zero from letter O in frame fonts (@roboomp) 2026-08-19 01:36:03 +02:00
can1357 a3fc18fd16 Merge PR #8704: fix(cli): exit cleanly after printing shell completions (@czchen) 2026-08-19 01:36:03 +02:00
can1357 43fcfb4475 Merge PR #8688: fix(mcp): preserve image tool results (@roboomp) 2026-08-19 01:36:02 +02:00
can1357 565d53515b feat(coding-agent): added providers.cacheRetention setting for prompt caching
- Add the `providers.cacheRetention` setting to control prompt-cache retention options per request.
- Forward configured cache retention preferences through the settings-aware stream function.
- Update documentation and test coverage for long cache retention behaviors.
2026-08-19 00:56:50 +02:00
can1357 bf490ae024 fix: added reasoning effort support for qwen templates
- Added `reasoning_effort` kwarg and top-level support for Qwen 3.8+ templates.
- Introduced `qwenTemplateReasoningEffort` compatibility option and identity helpers.
- Enabled default reasoning enforcement and updated cache provider invalidation.
- Added comprehensive unit and compatibility test suites for Qwen reasoning dials.
2026-08-19 00:47:11 +02:00
usr-bin-roygbiv 2a8ad4ad9a fix(coding-agent): allow auth oauth without apiKey in models.yml 2026-08-18 21:44:23 +00:00
djdembeck e599d58f21 fix(robomp): thread commit_id/head_sha/patch through proxy backend
Follow-up fix round for 71d608aae6 (validate PR review comment
anchors against the diff before submitting). The validation path
broke in several places the original commit did not cover:

- GitHubBackend.submit_review gained no commit_id parameter, so
  submitting through GitHubProxyClient raised a production
  TypeError on a path the validation code depended on.
- PullRequestInfo lacked head_sha, so the Forgejo commit_id
  fallback raised AttributeError; it is now parsed in
  _pr_from_payload and carried through the proxy round-trip.
- _pr_file_from dropped the file patch, silently no-oping anchor
  validation for anything routed through the proxy; the patch is
  now forwarded.
- The hunk parser treated any +++/--- line as a file header,
  desyncing line counters when added/removed content began with
  those prefixes; file headers are now recognized only before
  the first hunk.
- Reworded the comment to "Forgejo only" to match the actual
  backend behavior.

Adds tests for forgejo commit_id fetch, fallback double-failure,
empty-patch fail-open, LEFT-side anchoring, proxy commit_id
validation, and file-creation hunk boundaries.
2026-08-18 16:25:52 -05:00
Samuel Reed 93e95c7dfc fix(catalog): derive Codex -wm cap and cost from the canonical plain slug
Review follow-up: a safe `-wm` row previously kept backend-parsed capability metadata (no 1M floor, no daybreak pricing) while its synthesized plain listing was enriched — the same model reported two different contexts. Both listings now derive fallback window, the 1M floor, and daybreak cost from the canonical plain slug; unknown `-wm` SKUs and non-worker models keep their verbatim slug-derived metadata.

The authoritative-discovery test now resolves the configured `openai-codex/gpt-5.6-luna` through the real model resolver and asserts the exact bound id (and that an explicit `-wm` config still resolves verbatim) instead of only checking `ids.toContain`.
2026-08-18 16:34:24 -04:00
Samuel Reed 51fd17a8c3 fix(catalog): register plain Codex route for worker -wm SKUs
Codex backend discovery advertises worker-mode SKUs under a `-wm` suffix (gpt-5.6-luna-wm). Authoritative discovery replaced the bundled catalog and kept those slugs verbatim, so a configured `openai-codex/gpt-5.6-luna` vanished from the resolved catalog and the resolver's fuzzy fallback selected `-wm` instead — a route some ChatGPT accounts reject.

Model discovery now recognizes the `-wm` suffix: when the bundled Codex catalog ships the plain SKU, the `-wm` row is also registered under its plain id (re-derived so the 1M-window floor and daybreak pricing keyed on that slug still apply). Unknown `-wm` SKUs keep their authoritative verbatim slug and non-worker models are untouched, so distinct models and other providers are unaffected.
2026-08-18 16:23:02 -04:00
Samuel Reed 761abf5777 style: biome safe-fixes for model-resolver import order and formatting
organizeImports sorts the type GeneratedProvider specifier ahead of the named imports, and the formatter collapses the preferred-match arrow chain to one line. Both are biome safe fixes; no behavior change. Resolves the two biome errors that were leaving the 8833 branch's check gate red.
2026-08-18 16:19:04 -04:00
Samuel Reed 46f31296a1 fix: skip non-UTF-8 host env entries instead of panicking at startup
std::env::vars() panics the moment a host env key or value is not valid
Unicode, before any command can run. A corrupt GHOSTTY_BIN_DIR (bytes 9d d9 50)
staged by cmux/Ghostty tripped both sinks:

- pi-shell's session env copy in create_session_for_run (also merged PATH)
- brush-core's get_host_env_vars, which process builtins (sleep, timeout,
  pgrep, ...) use to inherit the host env into the shells they build

Both now read via std::env::vars_os() and skip entries that cannot be decoded
as Unicode: a corrupt entry carries no usable meaning. PATH merge behavior is
unchanged. Regression tests inject a non-UTF-8 key and value and assert the
shell still starts and PATH survives.

Reported in issue #8925.
2026-08-18 16:18:59 -04:00
Damon Montague 309d5712af fix(catalog): mark coreweave discovery authoritative
CoreWeave Serverless Inference (W&B Inference) is a reseller with a
rotating model menu, but its catalog entry omitted
dynamicModelsAuthoritative. Runtime /v1/models discovery therefore
merged into the frozen bundled slice instead of replacing it, so stale
ids (e.g. moonshotai/Kimi-K3, Kimi-K2.5) stayed selectable and 404 at
request time. Matches sibling resellers (baseten, gmi-cloud, aiand,
bedrock-mantle). Bundled models remain the offline/failure fallback via
the authoritativeFreshProviders gating in ModelRegistry.
2026-08-18 12:45:37 -07:00
PaleRoses 753c86ea72 fix(compaction): bound summarization input and stop retrying overflow
A session that crossed a provider boundary compacted 90 times in three days
without ever succeeding: every attempt asked the summarizer to read the whole
re-expanded span in one call (2.33M tokens on 08-15, 3.03M by 08-17, against a
1M cap), and every rejection was retried ten times.

Three independent defects:

1. `generateSummary` serialized the entire span into one prompt with no budget
   check. It now plans windows that fit the summarizer's context and folds them
   with the update prompt that iterative compaction already uses, so a stranded
   boundary is recovered instead of rejected. A provider that rejects a window
   the catalog said would fit (claude-sonnet-4-5 advertises 1M but is
   beta-gated to 200k on OAuth credentials) halves what was actually sent and
   re-plans, because only the rejection knows the real cap.

2. `TRANSIENT_TRANSPORT_PATTERN` matched bare status codes, so the random id in
   the `raw-http-request=.../1787022540720-3o503gxo48bvb.json` pointer omp
   appends to its own errors classified a deterministic 400 as a transient 503.
   Statuses are now word-boundaried, matching AUTH_FAILURE_PATTERN.

3. Neither retry layer vetoed ContextOverflow, so one failure became up to 30
   identical calls (10 outer x 3 oneshot). A oneshot replays a fixed prompt, so
   an input that does not fit never fits; both layers now fail fast to the next
   candidate.

The boundary scan that decides which compaction entry a model can actually read
is extracted as `findReadableCompactionIndex`, since the fold and
`prepareCompaction` both need it.

Verified by replaying the session that failed: 7,096 messages summarize in 3
calls with a largest prompt of 773,705 tokens under the real 1M cap, and in 15
calls with a largest prompt of 196,148 tokens under a simulated 200k cap.
2026-08-18 12:25:13 -07:00
re2zero adf2595931 fix(sdk): accept flattened array argument paths from providers
Some providers (notably Gemini) serialize array tool arguments with
flattened property paths — questions[0].id, questions[0].options[0].label —
instead of a nested questions array. The schema sees only unrecognized extra
keys and rejects the call (e.g. the ask tool).

Add a pre-validation normalization pass (alongside the existing LLM-quirk
passes) that rebuilds the nested structure. Conservative: fires only when a
key is a well-formed array-index path, preserves non-flattened siblings, and
aborts wholesale on any shape conflict so genuine schema mistakes still
surface as validation errors.

Fixes #8886
2026-08-19 02:33:47 +08:00
re2zero 73e0366121 fix(tui): treat bare LF as Shift+Enter in the /tree selector
The composer accepts three encodings for Shift+Enter (kitty CSI-u, the
legacy \x1b[13;2~ form, and a bare LF from the iTerm2 mapping e.g. Claude
Code's /terminal-setup). The /tree selector only handled the kitty form and
silently routed a bare LF into the plain-Enter branch, so summarize-and-
switch never fired for those terminals.

Mirror the composer: fall through a bare LF to summarize-and-switch while
plain CR (or the decoded Enter key) still does a plain switch.

Fixes #8821
2026-08-19 02:33:40 +08:00
re2zero 6fad3772fb fix(session): only advertise --resume when the session is on disk
Persistence is lazy: getSessionFile() returns an allocated path from the
start, but the JSONL is only materialized once an assistant message (or an
explicit ensureOnDisk()) crosses the persistence gate. The shutdown banner
printed the resume hint based solely on the path, so any session that ended
before the first assistant message advertised a copy-pasteable command that
always fails with Session not found.

Gate the hint on the new SessionManager#isSessionOnDisk() (file exists in
the active storage backend) and add unit tests.

Fixes #8860
2026-08-19 02:33:34 +08:00
qiyi71w 8c55d224c5 fix(session): scope in-flight title latch to session id
A boolean latch survived /new and unnamed session switches, so the
replacement session skipped titling and could inherit the previous
skill's title. Bind the latch and the apply check to the originating
session id.
2026-08-19 02:32:27 +08:00
qiyi71w 1b122fa289 fix(session): skip queued /skill title starts while one is in flight
maybeStartTitleGeneration used to fire again for every untitled skill
prompt, so a queued /skill: during the first title request could race
and rename the session. Latch until the first request settles.
2026-08-19 02:23:14 +08:00
qiyi71w 9dc6eeae93 fix(session): show tiny-title download progress for /skill starts
Interactive /skill: titling now reuses the input-controller download UI.
Replace the queueChipText identity test with a chip-vs-args precedence check.
2026-08-19 02:13:06 +08:00
Oleg Pulatov 71ebe88850 fix(coding-agent): explain external thinking prelude 2026-08-18 19:51:49 +02:00
qiyi71w 1213f52093 style(session): satisfy biome and SkillPromptDetails typing 2026-08-19 01:50:25 +08:00
qiyi71w ecd800ef8f fix(session): title user /skill invocations from name and args
Session titles ignored /skill:<name> <args> because the invocation is a
custom skill-prompt, not a user turn. Feed the chip or reconstructed
/skill line into first-title generation and replan context, never the
expanded SKILL.md body.
2026-08-19 00:59:31 +08:00
Samuel Reed 301c1879b2 fix: blocker advisory always steers a new turn, immune window exempts it
The post-interrupt immune-window downgraded end-of-turn blockers to non-interrupting asides, so a blocker that means the agent handed off broken work never woke a new turn. Concerns keep the cooldown; blockers now bypass it and steer a triggered turn, consistent with the #5628 blocker-after-terminal-answer exception.
2026-08-18 12:22:09 -04:00
Daniel Young fb7c2e1a52 [mcp] Expand extension package environment
Apply the same recursive placeholder expansion used by native MCP configs before extension-package servers are validated and surfaced. This prevents stdio credentials and remote headers from reaching servers as literal placeholders.\n\nSolves: Extension-package MCP environment expansion\nTests: bun test packages/coding-agent/test/discovery/omp-plugins.test.ts
2026-08-18 12:14:25 -04:00
Daniel Young 480d72ffd2 Merge branch 'can1357:main' into main 2026-08-18 12:10:24 -04:00
poorpaper 6862ac08f0 fix(settings): hide excluded search providers from summary 2026-08-18 22:30:03 +08:00
Daniel Young 1496a139ce [mcp] Revert plugin env expansion
Keep host-specific secret injection in the maintained plugin layer instead
of carrying a behavioral divergence in the OMP fork.

Solves: Unwanted fork maintenance for MCP injection
Tests: Reverts only drycode/oh-my-pi PR #1
2026-08-18 08:50:06 -04:00
Daniel Young a52c2fc2fb [mcp] Expand Claude plugin stdio env (#1)
Claude marketplace plugins may reference runtime secrets in stdio
server environment values. Resolve those placeholders after plugin-root
substitution so child processes receive credentials instead of literal
template strings.

Solves: Stdio MCP credentials remain unexpanded
Tests: Claude plugin discovery tests; coding-agent check; live CH auth
2026-08-18 08:49:10 -04:00
bnivanov f5976d7129 fix(session): resume Cursor idle stalls after unmarked MCP results
The idle watchdog aborts the request signal and cursor.ts closes
the Connect stream, so there is no in-flight server exec to race.
Unmarked MCP/todo blocks can continue once every emitted call has
a matching result, same as HTTP/2 RST.
2026-08-18 14:48:45 +02:00
bnivanov 271e7ba892 fix(cursor): answer interactionQuery so hosted fetch can continue
Cursor hosted web search / Exa / unnamed field-9 WebFetch send
interaction_query and block the Run RPC until the client writes
interaction_response. Dropping the frame leaves the HTTP/2 stream
alive on heartbeats that are not semantic progress, so the 300s
idle watchdog aborts with "Provider stream stalled while waiting
for the next event".

Approve network permission gates and reject interactive
ask / switch-mode / create-plan. Leave VM setup unanswered
rather than inventing a success result.
2026-08-18 14:48:45 +02:00
djdembeck 71d608aae6 fix(robomp): validate PR review comment anchors against the diff before submitting
A single comment on a line outside a diff hunk 422s the whole review on
GitHub, which the 422/500 fallback (ported here from the Forgejo work,
including payload shaping and commit_id) then degraded into plain issue
comments. Now we fetch /pulls/{n}/files, compute per-hunk anchorable line
sets, drop non-anchorable comments, fold them into the review summary, and
only fall back to issue comments for genuine 422/500s that survive
filtering. Files-fetch failure fails open (submit unfiltered).
2026-08-18 03:54:00 -05:00
can1357 8500092296 chore: bump version to 17.3.7
Retry: widened agent dequeue-hook deadline budgets from 25ms to 1s — the run loop checks the deadline before invoking dequeue hooks, so a cold or CPU-starved mock roundtrip expired the deadline first and the hooks never ran (deterministic failure in isolation, flaky under CI parallel load).
2026-08-18 11:34:10 +03:00
chuzui 21d8ef9fb3 fix(coding-agent): stop pinning worker subprocess cwd to the install dir
Workers spawned via resolveWorkerSpawnCmd ran with cwd anchored at the CLI
install directory and shared the agent's foreground process group. Terminal
cwd heuristics such as kitty's new_tab_with_cwd read the newest process in
that group, so new terminal tabs opened in
~/.bun/install/global/node_modules/@oh-my-pi/pi-coding-agent/dist while any
worker was alive. Spawn workers with the absolute host entry and inherit the
agent cwd instead; the bun-test fallback branch keeps its cwd-relative form.
2026-08-18 16:29:21 +08:00
can1357 adfa211bbf chore: bump version to 17.3.7
Retry: deflaked tui IME preedit border test (#5563) — VirtualTerminal.waitForRender's fixed 40ms sleep raced TUI's throttled render timer on starved CI runners, reading the pre-input frame; waitForRender now takes an optional settle predicate polled up to 2s and the test keys on the rendered content.
2026-08-18 11:24:23 +03:00
naruto cbd748046d fix(web-search): abort-protect browser fallback setup and teardown
browseHtmlPage wrapped its navigations in untilAborted(signal) but awaited
applyViewport, applyStealthPatches, and the finally-block page.close() raw.
When the shared headless daemon or the page target dies mid-setup, those
puppeteer calls never settle: the search hard timeout fires into a signal
with no listener at those await points, the provider promise hangs past
SEARCH_HARD_TIMEOUT_MS, and the turn never ends (only kill -9 recovers).

- Wrap applyViewport/applyStealthPatches in untilAborted(signal) so the
  existing hard timeout can abort a dead-session setup.
- Bound the teardown page.close() with a fresh 5s deadline; .catch() only
  covers rejection, not a hang, and the caller signal may already be fired.

Fixes #8865
2026-08-18 11:08:49 +03:00
Kenneth Watson 49543d798e fix(tui): detect SIXEL outside Windows Terminal
The startup graphics probe only ran on ConPTY hosts with WT_SESSION, so a
SIXEL-capable terminal that exposes no identifying environment variable
(foot exports TERM=foot and COLORTERM=truecolor only) resolved the
trueColor capability row, kept imageProtocol null, and rendered every
image as the "[Image: …]" text card.

The XTSMGRAPHICS branch also had its status inverted: per xterm ctlseqs a
reply of `CSI ? 2 ; Ps ; Pv S` carries Ps = 0 on success, and a terminal
without SIXEL reports a zero maximum geometry, so a successful reply was
read as unsupported.

Drop the dead DA1 half of the probe with it: ProcessTerminal swallows
every `CSI ? … c` reply for the whole session so a late one cannot leak
into the composer (#8542), which means the attribute list never reached
the probe's input listener on any platform. The bare `CSI c` it wrote was
also unaccounted for in the DA1 sentinel FIFO, so its reply consumed
another probe's sentinel.

PI_FORCE_IMAGE_PROTOCOL, including its off/none kill switch, still wins
over the probe.
2026-08-18 14:47:20 +08:00
唐鳳 a073cd1763 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-18 13:42:47 +08:00
Vu Anh Nguyen cea6ecd3d7 fix(tui): render xdev tool images inline 2026-08-18 12:09:39 +07:00
Audrey Tang f7df5d4970 fix(catalog): map aliased Gemini Flash minimal to LOW on Cloud Code Assist
When a collapsed Gemini 3.6/3.7 Flash family routes user minimal onto the
same Cloud Code Assist wire id as low, emit thinkingLevel LOW. Those -low
SKUs reject MINIMAL with HTTP 400.
2026-08-18 12:19:11 +08:00
ata 602c89ae80 docs(changelog): collapse HUD label notes into one Unreleased bullet
Keep the 17.3.6 notes verbatim and record the HUD/handle split as a
single Unreleased fix.
2026-08-18 13:48:44 +10:00
ata 96cb5b5d95 fix(task): treat case-insensitive Name-N labels as handle echoes
The exact-echo check used accent-insensitive compare, but the collision
suffix path was a case-sensitive startsWith. AuthLoader-3 vs authloader
therefore leaked through as a real description.
2026-08-18 13:48:00 +10:00
ata 4509c128df style: biome-format HUD and task-label files
CI lint failed on line wrapping and extra blank lines in the HUD
role/label changes. No behavior change.
2026-08-18 13:48:00 +10:00
ata 8a83fb0e5d fix(task): stop using the spawn handle as the HUD description
The first HUD commit hid Name: Name. The cause was earlier: task
name was copied into identity.label, which became progress.description
and skipped generateTaskLabel. Keep the handle for id allocation, but
only treat eval label as a real UI description so the tiny-model
summary can run.
2026-08-18 13:48:00 +10:00
ata 94417ec99b test(tui): use generic names in subagent HUD fixtures
Keep the role-badge and echoed-id cases, but drop the session-specific
spawn handle from the source tree.
2026-08-18 13:48:00 +10:00
ata 54ba7fa4ab fix(tui): treat Name-N HUD labels as echoed spawn ids
Collision suffixes such as HindsightMcpFunnel-3 were still shown as
Name-3: Name because the first pass only compared the raw id.
2026-08-18 13:48:00 +10:00
ata aacf42c7eb fix(tui): show subagent role and drop echoed HUD labels
The anchored Subagents list printed only `Id: description` and treated a
label that repeated the spawn handle as a real description. Show the same
⟨role⟩ badge as inline task rows and omit descriptions that only echo the id.
2026-08-18 13:48:00 +10:00