157 Commits
Author SHA1 Message Date
musistudio cfe7d530d1 Update model catalog for 3.1.0 2026-09-10 14:11:51 +08:00
musistudio 39e4da3a03 fix(meta): enforce output token floor and verify tool IDs (#1781) 2026-09-09 20:33:56 +08:00
musistudio bc630ffc21 fix(claude-code): default to helper auth and honor provider limits (#1779) 2026-09-09 20:28:29 +08:00
musistudio c7e9a4cb4b fix(opencode): supply required session headers (#1780) 2026-09-09 20:25:09 +08:00
musistudio b1fd1e242f fix(gemini): honor selected protocols and API key auth (#1778) 2026-09-09 20:25:09 +08:00
musistudio 9f45399bc7 perf(app): avoid repeated eager executable discovery (#1776) 2026-09-09 20:12:07 +08:00
musistudio 687b84f242 perf(routing): reuse provider identity sets (#1777) 2026-09-09 20:09:07 +08:00
musistudio 09d41b0a21 perf(providers): cache bounded catalog lookups (#1775) 2026-09-09 20:07:50 +08:00
musistudio 82d2f52738 fix(claude-app): remove deprecated configuration keys (#1772) 2026-09-09 20:06:04 +08:00
musistudio 37ae4f51e4 fix(claude-app): preserve preferences on restore (#1768) 2026-09-09 20:04:49 +08:00
musistudio b0d59afe08 Refactor routing configuration and improve provider support 2026-09-09 19:43:16 +08:00
musistudio 2b57c6078f Merge branch 'feat/ai-gateway' into dev/3.1
# Conflicts:
#	packages/core/src/gateway/core-runtime/upstream-header-sanitizer.ts
2026-09-02 20:24:42 +08:00
musistudio 4bf550824d Disable streaming replies for Weixin iLink 2026-09-02 19:29:25 +08:00
musistudio 4afd350eef Implement comprehensive application updates 2026-09-02 18:37:11 +08:00
musi 474dccb0e0 Merge pull request #1736 from BetterAndBetterII/fix/preserve-cowork-egress-hosts
fix: preserve coworkEgressAllowedHosts when rewriting Claude App config
2026-09-01 22:35:15 +08:00
musi c3231f84d7 Merge pull request #1723 from gtapps/fix/1722-responses-tool-strictness
fix(gateway): opt OpenAI Responses tools out of implicit strict mode
2026-08-30 10:46:26 +08:00
musi 51ab4ecafa Merge pull request #1718 from diogomcd/feat/codex-explicit-context-window
feat: allow explicit context window overrides for local Codex providers
2026-08-30 10:45:50 +08:00
Gabriel Tavares 197a8a604f fix(gateway): stamp Responses tool strictness only for Anthropic conversions
Native /v1/responses clients omit strict as API semantics; forcing false opted them out of strict tool schemas.
2026-08-30 01:19:28 +01:00
Yuzhong Zhang dc82dc9e47 fix: preserve coworkEgressAllowedHosts when rewriting Claude App config
Merge existing configLibrary JSON before writing gateway fields so CCR
restarts no longer wipe sandbox egress allowlists.

Fixes #1735
2026-08-29 13:28:08 +00:00
Diogo Macedo d5638fb4f3 fix: honor pinned context windows in Claude App routes with a shared percent helper 2026-08-27 19:20:43 -03:00
Diogo Macedo 49a8b5bd78 fix: remove the hardcoded imported Codex context-window cap 2026-08-27 19:19:34 -03:00
musi 46e3232913 Merge pull request #1699 from krajcik/fix/gateway-preload-undici-major-mismatch
fix(gateway): pair dispatchers with bundled undici fetch on undici major mismatch (Node >= 25)
2026-08-27 22:35:35 +08:00
musi 44e3a52990 Merge pull request #1715 from diogomcd/fix/responses-unsupported-metadata
fix: skip session affinity body fields for Codex Responses upstreams
2026-08-27 22:25:18 +08:00
krajcik 98b30c2510 refactor(gateway): defer dispatcher pairing to ai-gateway 1.0.18 2026-08-26 15:35:41 +03:00
Gabriel Tavares 54f57a35d5 fix(gateway): opt OpenAI Responses tools out of implicit strict mode
Claude Code omits tool.strict, so Responses promotes optional fields to required and models emit both Monitor command and ws.
2026-08-25 23:30:35 +01:00
Diogo Macedo 7c1c0d49b4 feat: respeita Entry mode dos perfis no sync da config do app Claude 2026-08-25 16:17:27 -03:00
Diogo Macedo 92d771feb6 fix: honor pinned context windows through metadata merges and effective percent 2026-08-25 15:20:36 -03:00
Diogo Macedo 7a2b4c3a75 feat: respect explicit user context windows over imported Codex caps 2026-08-25 13:03:59 -03:00
musi 99f24806c6 update sponsor 2026-08-25 22:03:48 +08:00
Diogo Macedo c15b668910 fix: skip session affinity body fields for codex responses upstreams 2026-08-24 10:41:34 -03:00
musistudio f2360ac046 Merge branch 'main' into dev/3.1 2026-08-24 20:02:57 +08:00
musistudio 70e7fd1a80 Secure gateway preload file permissions 2026-08-24 19:29:15 +08:00
musistudio 9e7d4f782c Implement router enhancements 2026-08-24 19:02:41 +08:00
pacocartones 6c98ea2adf fix(media): release artifact response body on early download failures
GatewayMediaExecutor.download() left the fetch Response body un-read and un-cancelled on several early-exit paths: a terminal non-ok HTTP status, an oversized declared content-length (declaredLength > maxApiArtifactBytes), and a mid-stream writeSync failure in the download loop. In each case the underlying undici connection/socket is leaked, so repeated failed downloads accumulate open connections and exhaust the pool.

Cancel the response body before throwing on those paths, and cancel the reader in the write-error handler, matching the cancellation already done on the retry branch and the in-loop size-limit branch.
2026-08-24 04:28:06 +00:00
musi 1347c868b4 Merge pull request #1691 from dylanpulver/fix/responses-session-affinity
Forward session id as prompt_cache_key on openai_responses
2026-08-22 18:34:25 +08:00
musistudio ccd00632ac Update project files 2026-08-22 16:12:46 +08:00
musistudio d515556574 Fix profile-specific model routing and gateway shutdown 2026-08-22 10:18:18 +08:00
kskada acf75d1280 Add Claude Code regression test for local agent auth provider hook 2026-08-21 16:29:58 +03:00
musistudio 46daaad92e Resolve Claude Code routes with one-million-context model suffixes 2026-08-20 16:45:54 +08:00
musi 6e1a9617ff Merge pull request #1672 from pacocartones/fix/sse-utf8-chunk-boundary
fix(gateway): SSE transforms corrupt multi-byte characters split across chunks
2026-08-20 11:23:31 +08:00
krajcik 59420662bd fix(gateway): pair dispatchers with bundled undici fetch on major mismatch
Node >= 25 ships undici 8 as its built-in fetch while CCR bundles undici 7.
A dispatcher created by one undici major fails inside the other's fetch with
UND_ERR_INVALID_ARG ("invalid onError method"), so every gateway upstream
request fails with 502 "All target providers failed" (stage upstream_connect)
regardless of provider or proxy settings.

The generated gateway-proxy-preload.cjs already intercepts global fetch, but it
passed dispatcher-carrying calls straight to the runtime's built-in fetch and
injected bundled dispatchers into it. Route every call that carries or receives
a bundled dispatcher through the bundled undici's own fetch when the runtime
and bundled undici majors disagree; keep the previous behavior when they match.
2026-08-19 23:37:11 +03:00
musistudio b073ebef31 Add Fusion vision instructions and image capabilities 2026-08-19 16:06:21 +08:00
Dylan Pulver 51c0fe7d12 Forward session id as prompt_cache_key on openai_responses
Requests converted to the OpenAI Responses protocol left the outbound
body without any session-stable field: prompt_cache_key was never set
and the inbound Anthropic metadata.user_id was dropped. Multi-channel
Responses upstreams that pin sessions on body fields hashed each turn
onto a different channel, so channel-bound encrypted_content
continuations failed with 400 invalid_encrypted_content and prefix
cache hits were lost.

The gateway boundary plugin now fills prompt_cache_key on outbound
openai_responses JSON bodies from the first non-empty of
x-claude-code-session-id, x-claude-session-id, or the inbound
metadata.user_id, and carries metadata.user_id onto the outbound body
when no metadata was set. A caller-supplied non-empty prompt_cache_key
always wins, and other protocols pass through untouched.

Fixes #1688
2026-08-18 12:15:21 +03:00
musistudio 4344a2d6a7 Refactor routing configuration and improve provider support 2026-08-18 11:45:39 +08:00
songkuan-zheng 17fd745898 Normalize usage token conventions per source
normalizeUsageInputTokens decides whether input_tokens already includes the
cached prefix, and it asked the upstream provider protocol first. Both usage
call sites merge the billing headers and the response body into one snapshot
and then normalize that merge once — but on a translated response the two
sources use different conventions:

  - x-gateway-billing-* headers restate the upstream provider's own counters
    verbatim, so for an OpenAI-compatible upstream they are cache-inclusive.
  - The response body is whatever the gateway emitted. An Anthropic body is
    cache-exclusive regardless of what it was translated from.

So an Anthropic response served from an OpenAI-compatible upstream had the
body's already-excluded prefix subtracted a second time. Non-streaming
responses were unaffected by luck: the headers win the merge and are
inclusive, making the subtraction correct. Streaming responses carry no
billing headers at all, leaving the body alone to be over-subtracted and then
clamped by Math.max(0, ...) — on a long cached conversation input_tokens
reports 0 on nearly every turn, and the derived cache ratio is pinned at
100%.

Tag each source with a UsageConventionSource and normalize the two separately
before merging them. Reordering the precedence instead is not sufficient: it
moves the defect onto the non-streaming path, which depends on the headers
being reduced.

Raw-trace updates carry no provider protocol, so their billing headers keep
falling back to the request path; only the body side changes there.
2026-08-17 05:21:30 +00:00
musistudio 22b68fd907 Qualify target model selectors with routed provider 2026-08-15 23:47:32 +08:00
pacocartones 79f48c0070 fix(gateway): SSE transforms corrupt multi-byte characters split across chunks
Four SSE response transforms decode every upstream chunk in isolation with
chunk.toString(). A UTF-8 character whose bytes straddle a chunk boundary is
therefore decoded twice as two invalid fragments, and each fragment becomes
U+FFFD. The character is destroyed before the block is ever parsed, so no
downstream code can recover it: the JSON still parses, the event still
validates, and the replacement characters are forwarded to the client.

The pending buffer these transforms already keep does not help. It joins
partial SSE *blocks*, not partial *characters* — by the time the bytes reach
it they have already been decoded and lost.

Affected sites, all in the response chain built in gateway/request/pipeline.ts:

  codex-patch-bridge.ts               transformSseChunk
  codex-multi-agent-bridge.ts         transformSseChunk
  hosted-web-search/response-transform.ts
                                      hostedWebSearchProtocolSseStream
                                      anthropicHostedWebSearchProtocolSseStream

The correct pattern is already in this repository. anthropic-response-model.ts,
the last transform in that same chain, runs the identical block-splitting loop
over a node:string_decoder StringDecoder, which holds back an incomplete
trailing sequence until the next chunk supplies the rest.

Apply that pattern to the other four. Each transform now owns one decoder for
its lifetime, writes every chunk through it, and drains decoder.end() in flush
so a truncated stream still emits what the decoder was holding.

Any non-ASCII output is affected — CJK, Cyrillic, accented Latin, emoji — and
the apply_patch bridge carries file contents, so a corrupted character there is
written to disk.
2026-08-14 12:40:55 +02:00
musistudio e4072137d4 Increase route script source size limit to 5 MiB 2026-08-14 11:44:33 +08:00
musistudio 2a7aa9286b Update router configuration and provider handling 2026-08-11 16:15:53 +08:00
musi 56d7b37c64 Support multiple WorkBuddy models and generic app paths 2026-08-11 12:36:44 +08:00