Commit Graph

1162 Commits

Author SHA1 Message Date
Peter Steinberger
597699401a refactor(memory): use sqlite transcript identities (#117334) 2026-08-01 04:38:40 -07:00
Yiğit ERDOĞAN
afe024e8c7 fix(ai): assistant text blocks are run together on replay (#115743)
Chat Completions replay flattened every assistant text block with an empty
separator, so two distinct blocks came back as one word-joined sentence. The
same message shape survives distinctly on the Anthropic, Responses and Mistral
lanes, and the string-content flattener for strict OpenAI-compatible servers
already joins with a newline.

Two blocks arise routinely: streaming opens a new text block after a tool call,
and cross-model replay converts a thinking block into a text block.
2026-08-01 02:23:08 -07:00
Peter Steinberger
b721cffa44 fix(inference): simplify lifecycle and preserve Codex tool identity (#117298) 2026-08-01 02:05:45 -07:00
Vincent Koc
05b46b48a0 merge: refresh talk lifecycle on main
* origin/main: (41 commits)
  test(ci): update memory helper routing expectation (#117295)
  fix(canvas): emit successful control results in JSON mode (#117297)
  fix(imessage): settle native inbound reply delivery (#117282)
  fix(agents): reject invalid UTF-8 LSP responses (#117271)
  fix(line): centralize card and template message alt text (#117280)
  fix(release): validate candidates before Docker publication (#117252)
  fix(media): validate provider-owned generated media downloads (#117281)
  fix(feishu): restore custom HTTPS API domains (#117278)
  fix(models): reuse prepared plugin metadata (#117131)
  fix(agents): stop fallback after delivered-but-failed attempts (#114628)
  fix(memory): reuse targeted session corpus snapshot (#117247)
  fix(matrix): reconcile durable sends after response loss
  test(release): repair full validation regressions (#116931)
  fix(linux-canvas): report socket watcher fallback (#109502)
  fix(codex): preserve authoritative turn completion (#117185)
  fix(canvas): preserve widgets across derived-name collisions (#117132)
  fix(channels): config validation rejects documented channels.<id>.configWrites on 13 channels (#117206)
  fix(msteams): prevent duplicate final replies (#116398)
  fix(doctor): session SQLite restore installs an empty session index over the valid archive (#117221)
  fix(plugins): preserve workspace plugins across CLI and control UI (#117265)
  ...
2026-08-01 16:43:54 +08:00
Harjoth Khara
b97a214604 fix(canvas): preserve widgets across derived-name collisions (#117132)
Fixes #116945
2026-08-01 15:33:56 +08:00
Vincent Koc
8fdcdaba76 fix(talk): bound browser transcript ownership 2026-08-01 14:39:27 +08:00
Peter Steinberger
1f9ee89f25 fix(google): preserve canonical replay and provider error ownership (#117193)
* fix(google): preserve provider signatures and failure outcomes

* fix(google): satisfy SDK stream event and optional text types

* fix(google): preserve signed empty SDK response parts

---------

Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 22:52:45 -07:00
RileyJJY
c7917cca36 fix(google-vertex): ignore blank project env (#109515) 2026-07-31 22:03:40 -07:00
Peter Steinberger
618f3298c7 fix(memory): reject malformed direct and batch embedding vectors (#117200)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 21:38:31 -07:00
Peter Steinberger
cb16d739cf fix(inference): harden Codex streaming, cancellation, and live QA (#116012)
* fix(inference): harden Codex turns, streams, and live QA

* fix(inference): dispatch open CR-delimited response frames

* fix(inference): finish live goal and split streaming regressions

* fix(codex): wait for interrupted turn completion

* fix(codex): narrow terminal collector notification ownership

* fix(inference): harden completion authority and lifecycle

* fix(inference): use canonical source delivery contract

* test(inference): align lifecycle probes with current main

* style(inference): format source delivery verification

* fix(goals): prevent premature completion across staged work

* fix(qa): settle streamed goal turns before continuation

* fix(goals): require visible replies after goal completion

* test(qa): keep goal flow regressions within lint limits
2026-07-31 21:29:33 -07:00
Paco Cartones
cb3cd94756 fix(net-policy): redact sig and x-* auth params in URLs and bodies (#116957)
* fix(redact): redact sig and x-* auth params (redact-sensitive-url.ts)

* test(redact): redact sig and x-* auth params (redact-sensitive-url.test.ts)

* fix(redact): redact sig and x-* auth params (redact.ts)

* test(redact): redact sig and x-* auth params (redact.test.ts)

* fix(logging): unify URL credential redaction

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-01 10:04:13 +08:00
Yiğit ERDOĞAN
ec5fb470c2 fix(ai): Codex stream shows internal parser text on a malformed frame (#116966)
* fix(ai): Codex stream shows internal parser text on a malformed frame

The Codex SSE parse boundary rethrew JSON.parse failures with its own
message, so the three consumers that key off the shared malformed-fragment
marker by exact string equality could not recognise it and the internal
parser wording reached the operator verbatim.

Mirror the canonical transport contract instead: a SyntaxError becomes the
shared marker with the original error kept as cause, and anything else is
rethrown untouched. The WebSocket twin is left alone because two open PRs
own that block today.

* fix(ai): preserve consumer SSE errors

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-01 09:34:09 +08:00
Peter Steinberger
95e50d3a7f fix(terminal): measure unicode display width consistently (#117062)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 18:25:15 -07:00
Peter Steinberger
d8ba00f8a2 fix(openai): clear ChatGPT SSE fallback per session (#117123)
* fix(openai): clear ChatGPT SSE fallback per session

* test(openai): prove ChatGPT fallback cleanup

* docs(openai): clarify fallback cleanup ownership
2026-07-31 18:24:46 -07:00
Peter Steinberger
f8aa383698 fix(mistral): reject incomplete streamed tool terminals (#117137)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 18:22:35 -07:00
Peter Steinberger
a7e0ebe8e6 fix(ai): preserve structured chat content and refusals (#117136)
Co-authored-by: Peter Steinberger <steipete@macos.shared>
2026-07-31 18:20:23 -07:00
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