* fix(ai): tool calls fail when an unsupported schema keyword is nested
The strip walked only properties, items, anyOf, oneOf and allOf, copying every
other value through untouched. A keyword the model rejects therefore survived
inside additionalProperties, prefixItems, patternProperties, contains,
propertyNames, not, if/then/else, dependentSchemas and $defs, and the request
was refused by the provider even though the strip reported success.
Walk the same containers the caller already enumerates in
agent-tools-parameter-schema.ts.
* fix(ai): cover all nested schema containers
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(ai): avoid websocket cache clobber on stale reused release
* fix(ai): prefer-const holdFirstReuse in websocket cache race test
* fix(ai): avoid websocket cache release clobber
* fix(ai): add curly braces for websocket cache delete guard
* fix(ai): owner-check websocket cache deletes without LOC growth
* ci: bump plugin SDK public surface budget pins to match main tip
* fix(ai): satisfy curly lint for websocket cache owner delete
* ci: allowlist readonly state db and format SDK surface pins
* style: oxfmt plugin-sdk surface report
* ci: drop duplicate readonly state db kysely allowlist entry
* test(ai): prove cached websocket lease ownership
Move the contributor stale-release regression into the canonical cached transport suite and prove authenticated real WebSocket close, cancellation, and queued idle expiry cannot evict a replacement lease.
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Honor existing per-turn timeout and retry controls across OpenAI Responses, Azure Responses, and OpenAI-compatible Chat Completions. Add real SDK HTTP regressions for all three transports.\n\nRefs: #114203
Preserve trusted policy-required message delivery and native image/computer tools across Code Mode catalogs and provider transports. Keep preferred Gemini capability metadata during live discovery, escape MCP declaration keywords, and reject suspended-run resumes with missing owner identity. Add before-and-after regressions for each user path. Closes#114753.
* feat(models): add Claude Opus 5 support
* test(models): align Opus 5 setup fixtures
* test(models): update ambient Opus 5 detection
* fix(models): reconcile Opus 5 support with main
* feat(anthropic): add Claude Opus 5 model support
Wire claude-opus-5 through the Claude 5 contract seams: adaptive-by-default
thinking with the full low..max effort range, default-sampling and prefill
stripping, streaming refusal contract, model-bound thinking replay, and 1M/128k
catalog metadata across anthropic, claude-cli, Vertex, Bedrock, and Mantle.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(anthropic-vertex): normalize explicit Vertex Opus 5 model rows
Extend normalizeAnthropicVertexResolvedModel so user-configured Vertex Opus 5
rows regain reasoning, image input, 1M/128k limits, and the native thinking
map; update the live-model priority expectation and regenerate docs_map.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* refactor(ai): invert plugin coupling behind the transport host port
* fix(ai): queue custom transport registrations until the host is configured
* refactor(ai): remove relocated transport sources from src/agents
* fix(ai): source core stream types from canonical packages and fix tarball fixtures
* fix(ai): invert plugin transport host wiring
* fix(ai): harden managed transport projection
* test(ai): register synchronous stream in transport mock
* fix(ai): lazily install transport runtime host
* fix(ai): preserve completion compat detection
* fix(ai): provider-billed totals desync the cost breakdown and drop cache writes
`applyProviderReportedUsageCost` overwrote only `cost.total`, leaving the
per-component estimates in place, so `input + output + cacheRead + cacheWrite`
stopped summing to the total and the replaced estimate was unrecoverable. The
repo rebuilds that sum in four other places; this helper was the only writer
breaking it. Retain the replaced estimate in a new optional `cost.estimatedTotal`
instead of inverting the override: free OpenRouter models report `cost: 0`, and
`shouldPreserveRecordedZeroCost` depends on a provider-billed zero staying
authoritative, so holding the estimate in `total` would write phantom spend.
`parseTransportChunkUsage` also hard-coded `cacheWrite: 0` and never read
`prompt_tokens_details.cache_write_tokens`, while its plugin-sdk sibling reads it
and documents the contract. Writes were dropped from `cacheWrite` and wrongly
counted inside `input`. OpenRouter routes through this lane.
Fixing that shifts tokens out of `input`, which `resolveContextInputTokens` used
as a proxy for prompt size, so context-overflow and length-stop detection are
aligned with the Anthropic lane's `input + cacheRead + cacheWrite`.
Related: #9016
* @
refactor(ai): drop the retained estimatedTotal cost surface
ClawSweeper blocked the branch three review cycles running on the same P1: the
new `Usage.cost.estimatedTotal` field crossed both the plugin SDK and the closed
worker transcript schema, making it an upgrade contract that a bug-fix PR cannot
decide on its own.
Measurement settles it: the field was written in one place and forwarded through
four transport layers, but nothing ever read it. It also did not repair the
invariant it was introduced for -- `input + output + cacheRead + cacheWrite` still
disagrees with a provider-billed `total`; the field only parked the discarded
estimate beside it.
Removing it drops eight files, retires the compatibility merge risk, and leaves
the two fixes that carry real runtime evidence: OpenRouter `cache_write_tokens`
mapping and the context-overflow accounting that depends on it.
@
* refactor(agents): tighten OpenRouter usage contract
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>