Commit graph

834 commits

Author SHA1 Message Date
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
musi
a1862982ae
Merge pull request #1696 from Burlesque1/fix/large-json-body-and-extraheaders
fix(ui): truncate over-large JSON bodies in preview to avoid formatter worker crash
2026-08-19 17:58:27 +08:00
Burlesque1
cfb6aae248 fix(ui): truncate over-large JSON bodies in preview to avoid formatter worker crash
Large (>=256KB) JSON request bodies were fully JSON.parse'd and pretty-printed
in the body formatter Web Worker, which then crashed (memory/CPU) on huge object
graphs - surfacing "Body formatter worker failed." and sticking at
"Loading body...". Preview truncation only applied to non-JSON bodies.

Now, in preview mode, an over-length text body is truncated to a plain-text
preview (createLogBodyPreviewText) instead of being parsed/pretty-printed, so the
worker never chokes. Full formatting still runs in "full" mode.

The judge is the real body.text length, not sizeBytes (which may be inflated
metadata and should still render its JSON tree when lightweight).

Fixes #1694
2026-08-19 08:55:14 +00:00
musi
fcf3d85da1
Merge pull request #1681 from songkuan-zheng/fix/usage-cache-convention-by-source
Normalize usage token conventions per source
2026-08-17 19:52:24 +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
bb1db63c49 Merge branch 'dev/3.1'
Some checks failed
Docs / Build (push) Has been cancelled
Docs / Deploy (push) Has been cancelled
2026-08-14 23:20:59 +08:00
musistudio
c87d7c848c Add manual Docker release workflow 2026-08-14 19:11:16 +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
f2860e165a Release 3.0.21 2026-08-14 17:51:29 +08:00
musistudio
d33cab9242 Update ai-gateway dependency to 1.0.17 2026-08-14 17:31:50 +08:00
musistudio
0fd9ea8f8b Add provider model refresh control 2026-08-14 16:24:25 +08:00
musistudio
9607c5f0a3 Improve provider account card layouts and meter visibility 2026-08-14 14:19:33 +08:00
musistudio
e4072137d4 Increase route script source size limit to 5 MiB 2026-08-14 11:44:33 +08:00
musistudio
48956f98cd Ensure request log tests close stores and cover row limit 2026-08-14 11:28:48 +08:00
musistudio
0104474e95 Merge branch 'main' into dev/3.1
# Conflicts:
#	packages/core/test/integration/observability/request-log-store.test.mjs
2026-08-14 11:17:06 +08:00
musistudio
2c424588f1 Merge remote-tracking branch 'origin/dev/3.1' into dev/3.1 2026-08-14 11:14:17 +08:00
musi
34da9b6a70
Merge pull request #1657 from pacocartones/fix/request-log-store-test-teardown
test(core): close request log stores before temp cleanup
2026-08-14 09:20:44 +08:00
musi
958e3fc02e
Merge pull request #1665 from jesieleo/fix/account-balance-compact-overflow
fix(ui): 修复紧凑账户余额卡片裁切
2026-08-14 09:13:53 +08:00
musi
013965d95f Refactor codebase and remove obsolete implementation 2026-08-14 08:37:29 +08:00
jesieleo
16f0868f40 fix(ui): 修复紧凑账户余额卡片裁切 2026-08-13 19:32:03 +08:00
pacocartones
2eb05b0e47 test(core): close request log stores before cleanup 2026-08-11 18:56:38 +02:00
musistudio
2a7aa9286b Update router configuration and provider handling 2026-08-11 16:15:53 +08:00
musistudio
3cb188c064 Report bounded agent analysis and handle missing session details 2026-08-11 15:00:59 +08:00
musi
56d7b37c64 Support multiple WorkBuddy models and generic app paths 2026-08-11 12:36:44 +08:00
musistudio
8fb38278f5 Merge branch 'main' of github.com:musistudio/claude-code-router into dev/3.1 2026-08-11 10:56:16 +08:00
musistudio
e38f9bc2dd Refactor router configuration and request handling 2026-08-11 10:53:45 +08:00
musistudio
28f0a2f2b9 Merge remote-tracking branch 'origin/dev/3.1' into dev/3.1
# Conflicts:
#	packages/core/src/profiles/service.ts
#	packages/ui/src/pages/home/components/profiles.tsx
#	packages/ui/src/pages/home/shared/profiles.ts
2026-08-11 10:05:44 +08:00
musistudio
551fc0e8ef Reuse healthy external gateways and decode Claude App routes 2026-08-11 10:00:33 +08:00
musi
c8e5e2b53d Add WorkBuddy app integration 2026-08-11 09:25:53 +08:00
musistudio
e8db9406a7 Add automatic provider model refresh and dialog Escape handling 2026-08-10 15:40:48 +08:00
musi
186fa619d2
Merge pull request #1640 from pacocartones/fix/raw-trace-directory-fsync-eperm-windows
fix(observability): raw trace spool never persists a bundle on Windows
2026-08-10 13:36:19 +08:00
musistudio
d48fd17105 Attribute Claude App encoded models to routed upstream usage 2026-08-10 13:04:07 +08:00
musi
23344888f3
Merge pull request #1642 from jesieleo/feat/xiaomi-mimo-provider-presets
feat(providers): 增加小米 MiMo 及 Token Plan 预设
2026-08-10 13:03:52 +08:00
musistudio
6e34da7fca Enforce profile model allowlists across agent catalogs 2026-08-10 12:55:54 +08:00
musi
0d178f3732 Improve compact handoff fidelity and token limit sanitization 2026-08-10 08:34:21 +08:00
jesieleo
f39ab4d5c4 feat(providers): 增加小米 MiMo 及 Token Plan 预设 2026-08-08 19:08:47 +08:00
pacocartones
92eeec11a9 fix(observability): raw trace spool never persists a bundle on Windows
Windows implements fsync as FlushFileBuffers, which behaves differently
from POSIX in two ways the raw trace spool relied on.

Flushing a directory handle is rejected outright with EPERM. syncDirectory
only tolerated EINVAL, ENOTSUP and EISDIR, so the durability barrier that
follows every rename threw instead of being skipped.

Flushing a file handle requires that handle to carry write access, and both
file flush sites opened their target read-only, so they also failed with
EPERM.

Together these made every durable write fail on Windows: with
observability.requestLogs enabled the sync handler answered 503
spool_unavailable for every bundle and nothing was ever persisted.

Tolerate EPERM alongside the other directory-flush rejections, and reopen
files as "r+" so their flush stays a real barrier rather than a tolerated
error. The tolerated set is extracted into a predicate so a test can pin
down which codes are skipped and, just as importantly, which ones still
propagate.

Fixes #1635
2026-08-07 21:45:10 +02:00
musistudio
47b23298fb Implement requested changes 2026-08-07 22:49:28 +08:00
musistudio
47f3649431 ci: install workspace deps for docs build
Some checks failed
Docs / Build (push) Has been cancelled
Docs / Deploy (push) Has been cancelled
2026-08-07 16:08:26 +08:00
musistudio
065be3bf99 chore: release v3.0.20 2026-08-07 15:49:19 +08:00
musistudio
8cab2dbb7a Merge dev/3.1 into main for v3.0.20 2026-08-07 15:41:27 +08:00
musistudio
c8825cf5cd Rename browser usage mode to Browser request 2026-08-07 15:04:43 +08:00
musistudio
83a7979c0b Implement routing updates 2026-08-07 14:57:45 +08:00
musistudio
1f5cc499f1 Improve Claude Design asset discovery and product runtime support 2026-08-07 11:51:19 +08:00
musistudio
860f41b187 Add provider logos to account balance widgets 2026-08-06 17:51:51 +08:00
musistudio
4097bbe5e7 Improve router configuration and request handling 2026-08-06 17:41:41 +08:00
musi
70b51b08d4
Merge pull request #1634 from flaviomartil/fix/grok-peer-rotated-credential
fix(grok): adopt peer-rotated credential on refresh 401
2026-08-06 16:12:24 +08:00
musistudio
6e431de9b5 Update agent and provider configuration documentation 2026-08-06 14:56:10 +08:00
musistudio
240cd73c1c Merge branch 'dev/3.1' into dev/docs
# Conflicts:
#	docs/src/content/docs/en/configuration/profiles.md
#	docs/src/content/docs/zh/configuration/profiles.md
2026-08-06 14:16:12 +08:00
musi
3c71252de1 Add interactive docs demos 2026-08-06 14:10:32 +08:00