Commit Graph

3925 Commits

Author SHA1 Message Date
can1357 4ddc2d2cd4 chore: rewrite changelogs + fix stale tests 2026-08-03 15:32:19 +02:00
can1357 f6b0d0debf feat(ai/dialect): added jsdoc-style tool example rendering for inventory
- Add `renderToolExamplesJsdoc` to generate `@example` comment lines for tool inventories.
- Extract `bareStringArg` helper to simplify single-argument checks across renderers.
- Update tool inventory rendering to use the new JSDoc example format.
2026-08-03 15:17:46 +02:00
can1357 9fdb989c63 docs(changelog): restored released sections and normalized unreleased entries
- Union changelog merges interleaved stale pre-17.2.5 PR-branch entries into
  released sections; released bodies are restored byte-for-byte from the
  pre-merge main state.
- [Unreleased] now carries exactly the entries for PR #7080 and the nine
  merged fixes (#7495, #7460, #7466, #7468, #7473, #7481, #7477, #7368, #7453).
2026-08-03 14:51:01 +02:00
can1357 1fb9daa3f6 Merge PR #7466: fix(ai): guarantee ollama user turn and surface done_reason load (@roboomp) 2026-08-03 14:46:23 +02:00
can1357 e06ccbd907 Merge PR #7080: fix(ai): add authenticated Bedrock Mantle routing (@anatoli-tsinovoy)
# Conflicts:
#	packages/ai/src/registry/registry.ts
#	packages/catalog/scripts/generated-policies.ts
#	packages/catalog/src/models.json
2026-08-03 14:36:52 +02:00
roboomp 2586c422ec fix(ai): guarantee ollama user turn and surface done_reason load
An agent-attributed developer turn (e.g. a plan-approval handoff into a
fresh session) maps to Ollama's `system` role, so a request whose only
non-system message is that turn carried zero `user`-role turns. Ollama
answers such a request with `done_reason: "load"`, generating nothing,
and `mapDoneReason` laundered it into a clean `stopReason: "stop"` with
zero usage — indistinguishable from a legitimate empty completion, so
every recovery layer retried the impossible request until the cap
surfaced a misleading empty-stop error.

- convertMessages now demotes the last non-prefix `system` turn to
  `user` when no user turn survives, keeping the static system-prompt
  prefix intact for prefix caching.
- mapDoneReason maps `done_reason: "load"` to `error` with an explicit
  message so it surfaces immediately instead of being retried.

Fixes #7465
2026-08-03 07:33:56 +00:00
can1357 c53b85aaf4 chore: bump version to 17.2.5 2026-08-03 05:53:12 +02:00
can1357 63b07f8ec0 chore: rewrite changelogs 2026-08-03 05:52:53 +02:00
can1357 2c370ae524 Merge PR #7447: fix(openai): preserve Codex native image results (@roboomp) 2026-08-03 05:15:02 +02:00
can1357 a58584ff3c feat: implemented shared serialization utilities and standardized inventories
- Added shared Python call and literal serialization utilities with multiline verbatim support.
- Standardized tool inventories to format as an OpenAI-Harmony functions namespace using TypeScript declarations.
- Updated tool normalization and rendering functions to accept options objects and default to Python-syntax examples.
- Refactored Gemini dialect rendering to leverage shared serialization functions directly.
2026-08-03 05:06:49 +02:00
roboomp a3d1f35099 fix(openai): preserved Codex native image results
- Normalized result-bearing Codex image items on terminal output events and emitted standard image content.

- Preserved result-bearing image calls during full Responses history replay despite stale provider status.

- Added stream and replay regressions for the Codex path.

Fixes #7445
2026-08-03 02:41:03 +00:00
can1357 cc2265f681 feat: use simple form replace when replace is the edit mode 2026-08-03 01:00:51 +02:00
can1357 10625d2e9a Merge PR #7376: feat(coding-agent): add OpenAI service tier override (@paralin)
# Conflicts:
#	packages/coding-agent/src/commands/launch.ts
2026-08-02 21:22:41 +02:00
can1357 3177f6bdf7 test(catalog): cover DeepSeek policy without bundled models 2026-08-02 20:55:16 +02:00
can1357 46ca4c6095 Merge PR #7317: fix(catalog): downgrade forced tool choice for deepseek reasoning models (@roboomp) 2026-08-02 20:55:16 +02:00
can1357 965d1239cf Merge PR #7310: fix(omp): refresh context budget after shake (@oleksoleksoleks) 2026-08-02 20:53:46 +02:00
can1357 13242a94c5 fix(auth): guard auth broker config resolver env lookup 2026-08-02 20:53:20 +02:00
can1357 3f61117994 Merge PR #7362: fix(auth): guard config-value resolvers against case-insensitive env hijack (@roboomp) 2026-08-02 20:53:20 +02:00
can1357 d5f5f15bb5 Merge PR #7326: fix(ai): cache stable system prefix across cwd/date footer changes (@roboomp) 2026-08-02 20:52:07 +02:00
can1357 a872d77068 chore: cleanup dumb tests 2026-08-02 20:39:23 +02:00
Alexander Kirilin e50138f2a6 fix(omp): refresh context budget after shake 2026-08-02 12:12:07 -04:00
Christian Stewart 9d69db481a feat(coding-agent): add OpenAI service tier override
The OpenAI service tier could only be chosen through the `tier.openai`
setting, or for a resumed session through whatever tier that session
recorded. Wanting flex or priority for a single run meant editing
settings and putting them back afterwards, while `bench` already took a
`--service-tier` flag that the session CLI did not offer.

Add `--service-tier` to the root command. The flag wins over the
configured setting and over a resumed session's recorded tier, leaves
the Anthropic and Google entries untouched, and records the resulting
map so a later resume keeps it. `none` removes the OpenAI entry, which
omits `service_tier` from the request.

Signed-off-by: Christian Stewart <christian@aperture.us>
2026-08-02 05:07:33 -07:00
roboomp a6521f07ed fix(auth): guarded config-value resolvers against case-insensitive env hijack
On Windows process.env/Bun.env lookups are case-insensitive, so the
"env var name, else literal" resolvers turned a literal /login key like
`public` (OpenCode Zen's free key) into the built-in PUBLIC=C:\Users\Public,
sending `Authorization: Bearer C:\Users\Public` and 401ing every request.

Added `$envExact` in pi-utils, which trusts an env lookup only when an
exact-case key is enumerated (the only case-preserving signal on Windows;
the getter and hasOwnProperty/getOwnPropertyDescriptor traps are all
case-insensitive there). Wired it into all three resolvers:
resolve-config-value.ts, model-registry.ts, and auth-storage.ts.

Fixes #7361
2026-08-02 06:53:18 +00:00
can1357 4e65a685ae fix(ai): addressed anthropic stream truncation errors for tool call recovery
- Added `isStreamEnvelopeErrorText` to packages/ai/src/error/flags.ts to recognize stream envelope truncation errors.
- Updated `streamAnthropicOnce` in packages/ai/src/providers/anthropic.ts to throw an envelope error when streams die mid-generation without a terminal frame.
- Updated `recoverTransientErrorToolTurn` in packages/agent/src/agent-loop.ts to recognize Anthropic stream envelope truncation errors for tool call salvage.
2026-08-02 06:14:01 +02:00
roboomp 51fe5c935c fix(ai): preserved cache slot for real assistant turns
Exclude the synthetic trailing Continue. user pad from Anthropic's message cache window and anchor selection on the preceding assistant instead.

This preserves the only remaining message breakpoint when three system breakpoints consume the rest of Anthropic's four-slot budget.

Fixes #7324
2026-08-01 23:15:31 +00:00
roboomp 1488be016d fix(ai): cached stable prefix before active repo context
Cache up to the last three eligible Anthropic system blocks so the stable-prefix breakpoint remains before the volatile project footer when an active-repo context block follows it.

Prioritize the newest message when the four-breakpoint budget leaves one message slot, and cover the active-repo block order with a regression test.

Fixes #7324
2026-08-01 23:06:01 +00:00
roboomp b5025b125c fix(ai): kept OAuth billing header uncached without system prompt
Classify any Anthropic system array beginning with the generated billing header as the Claude Code layout, including the two-block billing-plus-identity case.

Added a request-payload regression test proving both cloak blocks remain uncached while the user message retains its breakpoint.

Fixes #7324
2026-08-01 22:55:46 +00:00
roboomp 79a7f309a4 fix(ai): cache stable system prefix across cwd/date footer changes
applyPromptCaching placed its only Anthropic system breakpoint on the last block, which is omp's volatile project footer (cwd, date, workspace tree). A new working directory or a midnight rollover therefore re-wrote the entire cached system prefix instead of reusing it.

System caching now also marks the block that ends the stable prefix (the block before the footer) via cacheSystemPrefixBreakpoints, skipping the OAuth cloak blocks (billing header + Claude Code identity). A footer change now only re-writes its own delta.

Does not cover open-weight chat templates that render tool schemas after the system block; that needs relocating the footer out of the system message (maintainer-owned prompt change).

Fixes #7324
2026-08-01 22:48:29 +00:00
can1357 d595332fc6 chore: bump version to 17.2.4 2026-08-02 00:19:30 +02:00
roboomp 93fe2ca9a9 fix(catalog): match opencode gateway by url for deepseek downgrade
Use isOpenCodeHost (provider id + baseUrl markers) instead of the built-in
provider-id check so DeepSeek reasoning models declared under a custom provider
id pointed at the OpenCode gateway URL also downgrade a forced tool_choice to
auto.

Fixes #7315
2026-08-01 20:23:07 +00:00
roboomp 879d8276c1 fix(catalog): scoped deepseek forced choice downgrade
Limit the DeepSeek forced tool-choice downgrade to the OpenCode Zen and Go
gateways whose default thinking mode rejects named selectors. Preserve forced
tool selection on NVIDIA and other gateways that can disable thinking for the
request.

Add regression coverage for both the affected OpenCode path and an unaffected
NVIDIA DeepSeek route.

Fixes #7315
2026-08-01 20:17:16 +00:00
roboomp 114a10d340 fix(catalog): downgrade forced tool choice for deepseek reasoning models
DeepSeek reasoning models on the OpenCode Zen/Go gateways 400 with
"Thinking mode does not support this tool_choice" when a specific tool is
forced. The compat descriptor already drops reasoning_effort via
disableReasoningOnToolChoice, but that does not turn off the gateway's
default thinking mode, so the forced named selector still trips DeepSeek's
thinking+tool_choice guard.

Mark forced tool_choice unsupported for DeepSeek reasoning models so
buildParams downgrades the selector to "auto" while keeping the tool
advertised, mirroring the Anthropic and direct-DeepSeek paths.

Fixes #7315
2026-08-01 20:05:27 +00:00
can1357 30163ed91c fix(ai): closed corruption-latch gaps from cred-latch review
- #readPersistedCredentialBlockReconcileAfter no longer rethrows
  non-corruption errors; transient failures (e.g. SQLITE_BUSY) log at
  debug and fall back to the in-memory probe window, mirroring
  #readPersistedCredentialBlock.
- Constructor's best-effort cleanExpiredCredentialBlocks now routes
  errors through #handlePersistedBlockStoreError so init-time corruption
  latches immediately instead of deferring to the first block read.
- reload() latches and surfaces repair guidance when listAuthCredentials
  throws on a corrupt store, then still rethrows: continuing with zero
  credentials would silently log the user out of every provider.
2026-08-01 21:44:26 +02:00
can1357 5af413d694 Merge PR #7305: fix(ai): latch and surface a corrupt credential-block store (@roboomp) 2026-08-01 21:42:22 +02:00
can1357 3b84fde884 test(ai): replaced busy-handler ordering spy with real lock contention
- The #7298 test asserted PRAGMA-vs-DDL ordering by spying on
  Database.prototype.run SQL strings — implementation plumbing.
- Now a child process creates the db and holds BEGIN EXCLUSIVE for 750ms
  (past open()'s ~700ms retry budget, under the 1000ms headless
  busy_timeout), signaling readiness via a filesystem sentinel; open()
  only survives if the busy handler is installed before the leases DDL.
- Verified the test fails with the ordering fix reverted.
2026-08-01 21:42:05 +02:00
can1357 3e978e95c0 Merge PR #7304: fix(ai): install auth-db busy handler before open()-path leases DDL (@roboomp) 2026-08-01 21:42:05 +02:00
roboomp af11e78796 fix(ai): rejected broker block writes after corruption
Fail broker-facing block mutations on the first corrupt SQLite write and every later latched call instead of returning a false durability acknowledgement. Internal request-path persistence remains an in-memory no-op, preserving local availability.

Verify RemoteAuthCredentialStore keeps its optimistic rate-limit block and does not refresh an empty snapshot when the broker rejects persistence.
2026-08-01 19:13:42 +00:00
roboomp ae91e7e136 fix(ai): guarded block reconcile reads after corruption
Route credential-block reconcile-after reads through the same corruption latch used by persisted block reads and writes. A latched store now returns an immediate zero probe time without touching SQLite; a first corruption from reconcile-after latches and reports once, while transient errors still propagate.

Add a Codex regression covering a corrupt block write followed by healthy usage reconciliation.
2026-08-01 19:05:57 +00:00
roboomp 1dc976b8cb fix(ai): guarded broker block operations after corruption
Route the broker-facing list, upsert, and delete methods through the same per-process corruption latch as credential selection. Preserve transient error propagation while returning safe empty/no-op fallbacks for SQLITE_CORRUPT and SQLITE_NOTADB.

Add table-driven coverage proving each public block operation independently reports once and short-circuits every later store call.
2026-08-01 18:56:48 +00:00
roboomp ff557b7a98 fix(ai): latch and surface a corrupt credential-block store
AuthStorage caught unrecoverable SQLite errors (SQLITE_CORRUPT family /
SQLITE_NOTADB) from the persisted credential-block read and write paths
at debug level with no latch. A corrupt agent.db therefore re-queried the
broken store on every credential evaluation while persisted rate-limit
blocks silently stopped applying, failing open in the direction that
hammers rate-limited accounts.

Detect the corruption family via isSqliteCorruptionError, report it once
at error level with the store location and repair guidance, and
short-circuit every later persisted-block read/write for the process
lifetime. Availability is preserved through the in-memory backoff map;
only cross-process persistence is lost.

Fixes #7296
2026-08-01 18:47:19 +00:00
roboomp ce277939ae fix(ai): install auth-db busy handler before open()-path leases DDL
SqliteAuthCredentialStore.open() ran #ensureAuthCredentialRefreshLeasesTable
(CREATE TABLE/INDEX for auth_credential_refresh_leases) with Bun's default
busy_timeout=0, before the constructor's #initializeSchema installed the
handler. Under a concurrent write lock (WAL recovery on parallel omp
startups) the lock-taking DDL failed immediately; the error was not
BUSY-classified, so open()'s bounded retry loop was bypassed.

Install the busy handler on the connection right after it opens, before any
lock-taking statement, via a shared #installBusyTimeout helper reused by
#initializeSchema. Honors the issue-#2421 invariant on every entry path.

Fixes #7298
2026-08-01 18:47:10 +00:00
can1357 03e54555f9 Merge PR #7065: fix(xdg): fix files and folder for xdg-maintained (@Parsifa1) 2026-08-01 20:39:29 +02:00
can1357 943bbd393e fix(ai): restored cache-retention-aware prompt cache key after codex compaction merge 2026-08-01 20:17:01 +02:00
can1357 9f65d3ae71 chore: applied biome formatting to sweep fix commits 2026-08-01 20:15:15 +02:00
can1357 44c7421462 chore: normalized changelog entries after merging sweep fixes 2026-08-01 20:14:51 +02:00
can1357 b1ba3a8f73 fix(ai): preserve strict tools for detailed OpenRouter errors 2026-08-01 20:14:40 +02:00
can1357 57356552b5 Merge PR #7265: fix(ai): retry opaque OpenRouter strict-tool errors (@roboomp) 2026-08-01 20:14:40 +02:00
can1357 b6e12240c9 Merge PR #7240: fix(coding-agent): bound synchronous SQLite busy-waits in headless hosts (@pi3123) 2026-08-01 20:13:39 +02:00
can1357 40007abeb5 Merge PR #7230: fix(ai): honor model.compat.streamIdleTimeoutMs in the Anthropic idle watchdog (@excniesNIED) 2026-08-01 20:13:39 +02:00
can1357 81cb1818fe fix(ai): roll back failed compaction metadata 2026-08-01 20:13:28 +02:00