Commit Graph

1146 Commits

Author SHA1 Message Date
Vincent Koc a1c689e375 fix(outbound): preserve fenced tool call examples (#117089) 2026-08-01 08:13:05 +08:00
Peter Steinberger e4d6e5603d refactor(ai): unify Anthropic streaming policy and usage accounting (#117086)
* refactor(ai): unify Anthropic streaming policy and usage accounting

* fix(ai): align shared cache TTL types with Anthropic SDK
2026-07-31 16:28:53 -07:00
Peter Steinberger ed84162454 fix(openai): canonical Chat cache-hit and billing accounting (#117043)
* fix(ai): preserve cached usage in managed chat completions

* test(ai): use canonical managed chat reasoning option

---------

Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 15:19:15 -07:00
Peter Steinberger 3cadc08593 fix(google): restore canonical Gemini and Vertex provider invariants (#117042)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 14:31:34 -07:00
Yiğit ERDOĞAN c9932f3cca fix(ai): malformed Anthropic stream frames expose raw event payloads (#116938)
The provider stream path interpolated the rejected SSE frame and its raw lines
into the thrown error, so text the model had generated reached logs and the
operator's error surface. The transport path already answers this exact condition
with the shared MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE and keeps the
SyntaxError on cause, and the user-facing substitution in
formatRawAssistantErrorForUi matches that constant exactly. Align the provider
path with it so the same failure reads the same way on both paths.

The error-event branch is left as is: its payload is parsed downstream to build a
meaningful operator message, so redacting it would be a regression.

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-07-31 15:25:14 -05:00
SunnyShu 1b7aa90c97 fix(agents): preserve tool-call pairing after mid-turn abort (#116642)
* [AI] fix(agents): emit aborted tool results for skipped tool calls on mid-turn abort

When an abort fires mid-batch in executeToolCalls (after the assistant
message with tool_use is committed but before all tool_results are
written), the sequential and parallel dispatch loops break out and skip
the remaining tool calls. The committed assistant turn retains N tool_use
blocks but only M < N tool_results land in context.messages, leaving
orphaned tool_use that corrupts retries/continuation and triggers provider
400 errors on providers that do not synthesize missing results
(allowSyntheticToolResults=false, e.g. openai-completions/DeepSeek).

Emit aborted tool results (createErrorToolResult("Operation aborted")) for
the skipped tail in both executeToolCallsSequential and
executeToolCallsParallel so every tool_use keeps a paired tool_result.
This complements the existing write-side guard (which only covers
synthetic-enabled providers) and the persisted replay repair.

The aborted tail outcomes are routed through finalizeToolCallOutcome (via
a shared finalizeAbortedToolCall helper) so config.afterToolOutcome hooks
(audit, redaction, metadata, error-normalization) observe these skipped
calls just like every immediate or executed outcome, instead of bypassing
the outcome contract. Regression tests assert afterToolOutcome fires for
every skipped call in both dispatch modes.

Fixes #116379

Co-Authored-By: Maas <noreply@anthropic.com>

* [AI] fix(agents): emit tool_execution_start before aborted end for skipped calls

The abort-tail backfill added in #116379 emits tool_execution_end (and a
paired tool_result) for tool calls the dispatch loop never reached, but it
skipped the matching tool_execution_start. Channel/client subscribers that
pair start→end events received an end for an unknown tool-call id during
abort recovery.

Emit tool_execution_start for each skipped call before its aborted end/result,
mirroring the start event every dispatched (including immediate non-executed)
call already emits. Covers both sequential and parallel dispatch, with
regression assertions that every skipped call has a start before its end and
that start/end counts stay paired.

Co-Authored-By: Maas <noreply@anthropic.com>

* fix(agents): complete aborted tool tails safely

Fixes #116379

---------

Co-authored-by: Maas <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-01 03:30:13 +08:00
Vincent Koc 2b58380ec9 merge: refresh local provider setup branch
* origin/main:
  fix(gateway): preserve plugin-only session change events (#116948)
  fix(media): recognize AIFF attachments across audio workflows (#116907)
  fix(openai): recover missing terminal response output (#116910)
  fix(telegram): preserve outbound media metadata and rejected photos (#116886)
  fix(agents): preserve bounded truthful subagent outcomes (#116932)
2026-08-01 01:01:35 +08:00
Peter Steinberger a4fccb7734 fix(media): recognize AIFF attachments across audio workflows (#116907)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 09:45:11 -07:00
Peter Steinberger e64b7041ec fix(openai): recover missing terminal response output (#116910)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 09:35:15 -07:00
Vincent Koc 0e24d596c0 improve(setup): clarify local provider actions 2026-08-01 00:26:40 +08:00
Peter Steinberger 4a8ce9c336 fix(openai): finalize Chat tool calls from authoritative terminals (#116922)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 09:21:40 -07:00
Peter Steinberger b186d81c46 fix(media): preserve display metadata and attachment formats (#116928)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 09:12:37 -07:00
Peter Steinberger 8c16b18a79 fix(agents): preserve atomic compaction and truthful bounded diagnostics (#116895)
* fix(agents): preserve compacted tool outcomes and summary bounds

* fix(agents): retain diagnostics outside compacted result tails

* fix(agents): honor valid explicit branch summary reservations

* fix(agents): avoid masking earlier failures with routine result tails

* fix(agents): never trade retained diagnostics for result footers

* fix(agents): anchor bounded result tails to terminal diagnostics

* fix(agents): avoid overlapping compacted diagnostic windows

---------

Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 08:38:21 -07:00
Peter Steinberger d2047364a8 fix(google): preserve streamed termination and usage facts (#116822)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 05:29:40 -07:00
Peter Steinberger 754fddbc79 fix(anthropic-vertex): correct multi-region endpoints (#116757)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 04:50:24 -07:00
Peter Steinberger 0d40cfbb53 fix(google): surface blocked Gemini prompts (#116756)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 04:29:06 -07:00
Vincent Koc 9b736a42c6 feat(models): expose tool support to clients 2026-07-31 18:43:47 +08:00
Vincent Koc 20e68e01df fix(gateway): sign device proofs with challenge time (#116679) 2026-07-31 16:45:53 +08:00
Vincent Koc b3ce00b480 refactor(schema): share config validation runtime (#116622) 2026-07-31 12:40:48 +08:00
Vincent Koc b015925bc3 test(core): remove dead and duplicate coverage (#116641)
* test(markdown): make code table style coverage assertive

* test(core): remove duplicate regression coverage
2026-07-31 11:48:46 +08:00
Vincent Koc 2bd9329af2 merge: sync origin/main
* origin/main:
  fix(ai): prevent websocket cache clobber on concurrent acquire (#116216)
  test(ui): settle custodian mobile layout assertions (#116613)
  fix(agents): resume Code Mode through gateway restarts (#116605)
2026-07-31 09:43:10 +08:00
Miorbnli 834fb2e3c2 fix(ai): prevent websocket cache clobber on concurrent acquire (#116216)
* fix(ai): prevent websocket cache clobber on concurrent acquire

The WebSocket session cache acquire path (expired or non-reusable cached
entry) used unconditional delete/set around the connectWebSocket() await.
A concurrent request could install a newer entry during that await, which
the resuming acquire then clobbered, orphaning the socket that carried the
real previous_response_id continuation and corrupting multi-turn Codex
conversations.

Mirror the release path's owner-checked helpers: delete via
deleteOwnedWebSocketSession, and install via a new setOwnedWebSocketSession
that only writes when the cache still matches what this acquire left behind
(the stale entry, or undefined after removing it / on first connect). A
different cached entry means a concurrent request already won the session.
The busy-cached branch is unaffected: it returns a transient socket and
never writes the cache.

* fix(ai): close CAS loser websocket promptly without leaking its socket

* fix(ai): correct verifyClient callback type in race regression test

* fix(ai): remove unused variable and fix lint in race regression test

* test(ai): prove concurrent websocket loser closes

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-31 09:36:33 +08:00
Vincent Koc 32036c473d fix(agents): resume Code Mode through gateway restarts (#116605)
* fix(agents): preserve Code Mode restart recovery

* chore(protocol): regenerate Swift agent params
2026-07-31 09:22:27 +08:00
Vincent Koc 94b85cba5f feat(setup): improve local model onboarding 2026-07-31 08:53:13 +08:00
Josh Avant ce67ffb70e feat(agents): add tool-free isolated completion (#114343)
* feat: add isolated pure-inference completion

* fix(google): block ambient system prompt writes

* docs: refresh generated map
2026-07-30 13:24:45 -05:00
Vincent Koc 0822e8d39e fix(qa): preserve missing Ollama cache telemetry (#116424) 2026-07-30 16:37:54 +00:00
Peter Steinberger 7fa95e2656 feat(ui): add composable skill references (#116330)
* feat(ui): add composable skill references

* fix(ui): align skill reference CI contracts

* fix(ui): scope skill references to WebChat
2026-07-30 04:07:02 -07:00
pash-openai e52354ea13 fix(build): pin typebox to a published release (#116333) 2026-07-30 09:58:51 +00:00
Riive 82af1bf7d4 fix(cron): stop replaying old schedule slots after a cron job is edited (#115779)
* fix(cron): bound restart catch-up to the active schedule

Editing a recurring job's schedule made the gateway fire it immediately on
the next restart. Startup catch-up compares the new schedule's previous slot
against lastRunAtMs, which still belongs to the retired schedule, so a slot
that never existed under the old schedule counted as missed.

Record when scheduling inputs take effect and replay a missed slot only when
it is newer than that. Jobs whose schedule never changed carry no stamp and
keep replaying every computed slot, so catch-up is unchanged for them.

The missed-slot predicate was duplicated in the runnable check and the
backoff-deferral pass; both now share one helper so the bound cannot drift.

Fixes #91944

* fix(cron): protect schedule activation ownership

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 10:07:13 +08:00
Vincent Koc 12e5eb6a23 fix(ui): clarify model setup flows (#116086) 2026-07-30 09:47:57 +08:00
Peter Steinberger 25d3c39130 fix(protocol): allow config hint documentation URLs (#116063) 2026-07-29 16:09:11 -04:00
Peter Steinberger e0ab154e5e fix(ui): explain unavailable MCP tool catalogs (#115994)
* fix(ui): explain undiscovered MCP tools

* fix(ui): scope MCP discovery notices to the viewed connector
2026-07-29 15:12:08 -04:00
Shakker 2cdedd7eeb test: isolate gateway sequence lifecycle coverage 2026-07-29 20:05:56 +01:00
Shakker 403a9b778b test: cover gateway sequence reset on restart 2026-07-29 20:05:56 +01:00
Shakker dbcd479007 test: cover gateway sequence reset on reconnect 2026-07-29 20:05:56 +01:00
Shakker ab3f52c367 fix: reset gateway event sequence on reconnect 2026-07-29 20:05:56 +01:00
Peter Steinberger ff72f287c3 fix(gateway): declare viewer presence explicitly instead of deriving it from subscriptions (#116001)
* fix(gateway): declare viewer presence explicitly instead of deriving it from subscriptions

* refactor(ui): isolate viewer presence lifecycle ownership

* chore(protocol): register viewer presence schema owner

* fix(ui): keep viewer presence cleared after detach

* chore: drop changelog edits from this PR

CHANGELOG.md is release-owned; release generation derives entries from merged
PRs. Release-note context stays in the PR body.
2026-07-29 13:56:54 -04:00
Jason (Json) cf927f7b1b fix(memory): keep rollbacks compatible after recall metadata upgrade (#116003)
* fix(memory): keep agent database rollbacks compatible

* fix(memory): satisfy rollback migration guards
2026-07-29 11:19:22 -06:00
Peter Steinberger 4229e96e0e feat(media): lazy playback transcode for exotic containers (#115987)
* feat(media): add lazy playback transcodes

* fix(media): harden playback transcodes

* fix(media): normalize raw AAC and WAV playback

* fix(media): finalize playback cache and codec policy

* fix(media): serialize playback cache enforcement

* fix(media): retain playback transcodes for seven days

* fix(media): keep playback internals private
2026-07-29 12:33:42 -04:00
Yiğit ERDOĞAN 6ec3dbd92d fix(ai): tool calls fail when an unsupported schema keyword is nested (#115741)
* 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>
2026-07-29 23:08:19 +08:00
Peter Steinberger fde4658bf6 fix(ui): recover sessions and dashboards after prolonged outages (#115654)
* fix(ui): recover long-running sessions and dashboards

* fix(ui): expose browser-safe gateway timers

* refactor(ui): keep browser timer surface minimal

* refactor(gateway): extract pending request state

* fix(ci): refresh browser runtime and format baseline

* fix(ci): exclude generated plugin outputs from targeted lint

* fix(ui): bound long-running connection and pane lifecycles

* refactor(ui): split long-running lifecycle regression coverage

* fix(ui): bound long-running media and lint ownership

* fix(security): preserve explicit workspace disable denylist

* fix(ci): preserve plugin manifest fallback lint
2026-07-29 10:09:51 -04:00
coder-master-0915 859fd0b11e fix(markdown): keep IR text slicing UTF-16 safe (#110643)
* fix(markdown): keep IR text slicing UTF-16 safe

* fix(markdown): preserve UTF-16 IR boundaries

* chore(markdown): reconcile original merge-base

* fix(markdown): preserve UTF-16 IR boundaries

* test(markdown): verify portable UTF-16 boundaries

* fix(markdown): normalize safe slice offsets once

* fix(markdown): preserve safe slice SDK contract

* fix(markdown): preserve native UTF-16 slice semantics

---------

Co-authored-by: lizeyu-xydt <li.zeyu@xydigit.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 09:24:15 -04:00
Colin Johnson 306c02af57 feat(ui): preview session workspace images (#95956)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 09:22:46 -04:00
Peter Steinberger adf3178ae6 feat(gateway): expose MCP tool identity in effective tools (#115870)
* feat(gateway): expose MCP tool identity in effective-tools catalog

* docs(agents): comment utility-tool pass gate invariant
2026-07-29 08:41:04 -04:00
Vincent Koc 38abf500ba fix(update): stabilize cross-version dev upgrades (#115651)
* fix(e2e): stabilize cross-version Parallels upgrades

* fix(e2e): avoid inline macOS guest probes

* fix(e2e): detach Windows dev updates

* fix(e2e): detach macOS guest updates with Node

* fix(e2e): initialize skipped upgrade config

* fix(update): use partial clone for dev checkout

* fix(update): keep Windows dev checkouts clean

* fix(e2e): pin Parallels dev update targets

* fix(e2e): own Parallels gateway restarts

* fix(e2e): verify pinned Parallels checkouts

* fix(e2e): forward Parallels update budgets

* fix(e2e): use canonical provider auth choices

* chore: leave changelog to release automation

* test(ui): stabilize route waits on loaded runners
2026-07-29 19:52:34 +08:00
tiffanychum 4b09214866 fix(ai): avoid websocket cache clobber on stale reused release (#105634)
* 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>
2026-07-29 07:52:04 -04:00
Peter Steinberger 8915f9c337 fix(gateway): prevent overlapping setup after wizard cancellation (#115856)
* fix(wizard): retain cancelled sessions until runner settles

* fix(wizard): purge cancelled sessions after settlement

* test(gateway): cover settled wizard replacement

* test(gateway): split wizard cancellation e2e

* test(gateway): fix wizard e2e env key types

* fix(gateway): forward daemon choice through wizard RPC

Co-authored-by: TheAngryPit <16145902+TheAngryPit@users.noreply.github.com>

* test(gateway): harden wizard cancellation cleanup

Co-authored-by: TheAngryPit <16145902+TheAngryPit@users.noreply.github.com>

* chore: drop changelog edit (release generation owns it)

---------

Co-authored-by: TheAngryPit <16145902+TheAngryPit@users.noreply.github.com>
2026-07-29 07:49:25 -04:00
Peter Steinberger 4c4aa2ed12 feat(gateway): manage audio and video attachments end to end (#115842)
* feat(gateway): manage audio and video attachments

* feat(gateway): preserve generated media metadata

* fix(gateway): align seeded managed media

* fix(gateway): scope pending media trust by URL

* fix(gateway): split managed media by trust

* fix(gateway): require terminal media trust unanimity

* fix(gateway): align managed media metadata types

* fix(gateway): refresh managed media contracts

* chore(ci): model managed media test seams

* test(sessions): expect canonical media kinds
2026-07-29 07:27:36 -04:00
Peter Steinberger 216f45af8e fix(memory): preserve Windows session ownership (#115851)
* fix(memory): preserve Windows session ownership

* test(memory): cover custom and nested Windows transcripts

* fix(memory): retain nested and custom Windows transcripts

* fix(memory): isolate agent-local Windows transcript stores

* style(memory): format Windows ownership regression coverage

* fix(memory): validate physical transcript ownership boundaries

* fix(memory): bind external session paths to configured agent stores

* fix(memory): reject unowned shared transcript store roots

* fix(memory): restrict transcript archives to agent-owned roots

* refactor(memory): preserve canonical transcript corpus contracts

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 07:11:24 -04:00
loong 7bdd1f646b fix(memory-host-sdk): resolve stable execPath for worker fork to survive Homebrew Node upgrades (#99318)
* fix(memory): survive Homebrew Node upgrades

Co-authored-by: 袁龙辉0668001277 <yuan.longhui@xydigit.com>

* test(whatsapp): isolate last-route coverage

* fix(deepinfra): preserve offline model compatibility

* test(memory): isolate migration cleanup lifecycle

* test: stabilize aggregate extension gates

* ci: retrigger pull request workflow

* test: preserve inherited Node options

* test(cli): tolerate cold hosted startup

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 06:49:02 -04:00