Commit Graph

781 Commits

Author SHA1 Message Date
Christian Gennari
e3bf94ee25 feat(antigravity): add weekly quota tracking and free-tier handling (#3892) 2026-09-09 09:57:13 +07:00
decolua
e7b5f09d50 fix(gemini): normalize contents and handle intermediate tool responses in Antigravity
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-09 09:45:18 +07:00
02f097880d fix(merge): restore ANTHROPIC_COMPATIBLE_PREFIX import + drop dead appendRequestLog call
Full-source eslint no-undef sweep over src/ + open-sse/ (config
listing node/web globals) found two remaining undeclared-variable
regressions of the same merge-loss family:

* api/providers/test-batch: branch commit f0adfb20 added a
  providerId.startsWith(ANTHROPIC_COMPATIBLE_PREFIX) check but never
  imported it; the master merge kept the buggy line. Every batch
  test / provider-group filter touching a non-openai-compatible
  provider threw ReferenceError (|| does not short-circuit).
* utils/stream.js finalizeStream: no-usage fallback called
  appendRequestLog(), a stub upstream had marked no-op and whose
  export chain was dropped by the merge. The call site only fires
  when a stream ends without valid usage and now threw
  ReferenceError inside the terminal callback. Removed the dead
  call (behaviour identical: the stub wrote nothing).

All other no-undef reports are browser globals absent from the
scan config, not source bugs. next build --webpack passes; smoke
server boots and auth-rejects unauthenticated /v1 + /api traffic
as expected; unit suite 1746 pass / 103 fail (was 1738/111).
2026-09-08 10:36:24 +07:00
38ff11ee16 fix(merge): restore chat.js imports, trust-vision floor, gitignore entries
Audit of every branch-owned line the -X theirs merge dropped from
the 32 pre-merge commits found three more real regressions:

* src/sse/handlers/chat.js: merge kept the capsOverride feature
  (bb8d67ba) but reverted the import block, so getCustomModels and
  capabilitiesFromServiceKind were undefined. The runtime error was
  swallowed by the feature's own fail-open try/catch — custom
  models silently lost their vision override. Restored both imports.
* open-sse/providers/capabilities.js: TRUST_UPSTREAM_VISION (the
  floor that keeps vision on for unknown models on upstream-validating
  gateways like openrouter) was left as dead code by the merge —
  upstream rewrote step 4 as refine() and dropped the check.
  Re-applied it on top of the new refine() so catalog/limits
  refinement still applies.
* tests/unit/chat-connection-pin.test.js: mock auth module lacked
  isModelAllowedForKey added by f0adfb20.
* .gitignore: re-add .pi-subagents/.
2026-09-08 09:38:03 +07:00
e3ba5d2207 fix(usage): restore commandcode quota + timeout guards lost in master merge
The -X theirs merge of origin/master (v0.5.69) silently reverted five
branch-only hunks because upstream had no conflict-region counterpart
and simply won the three-way pick:

* services/usage.js: re-register the commandcode USAGE handler +
  import. Without it the dashboard Quota Tracker fell through to
  'Usage API not implemented for commandcode'. The handler module
  (services/usage/commandcode.js) and registry usage block survived;
  only the dispatch entry was dropped.
* ProviderLimits/utils.js: restore parseQuotaData 'commandcode' case
  (currency-credit rows need unit "$" + remainingPercentage
  forwarding, else $0.05 balances render as 0%).
* profile + providers/[id] pages: restore Math.max(1000, ...) connect
  timeout floors so a stray '60' is never interpreted as 60ms.
* .gitignore: re-add .commandcode/ CLI local state.

Verified: tests/unit/commandcode-usage.test.js (6) and
usage-dispatch.test.js (2, asserts every provider routes to a real
handler) pass standalone; full unit run 1742 pass / 107 fail vs
1738/111 before this fix (remaining failures pre-existing, unrelated).
2026-09-08 09:28:59 +07:00
6f52d7020c fix(chatCore): add missing capsOverride + streamErrorPatterns to destructure
* handleChatCore() referenced capsOverride (line 162) and
  streamErrorPatterns (line 475) but the destructured param list
  did not include them. Callers that did not pass these (e.g.
  open-sse/handlers/responsesHandler.js, unit callers, older
  client builds) would trigger 'capsOverride is not defined' /
  'streamErrorPatterns is not defined' ReferenceError mid-request.
* Both defaulted to null. capsOverride is read by capability merge
  (line 162, already guarded by '|| {}'). streamErrorPatterns is
  read in the early-peek hook (line 484) which was null-safe
  only because the variable happened to be in scope when chat.js
  spread it in; responsesHandler never passed it and would crash.
* Unblocks all callers regardless of which fields they pass.
2026-09-07 15:23:48 +07:00
59f17b3725 feat(usage): raw request detail modal + raw stream capture
* Add /api/usage/request-details/raw endpoint serving a single
  stored request detail verbatim (raw payloads), with /raw doc
  clarifying it stays gated by the dashboard auth layer.
* Add RawDetailModal opened from a new 'Raw' button in
  RequestDetailsTab. Modal loads /raw, exposes per-section copy
  buttons and a 'Copy all (JSON)' that bundles every section.
* Capture the raw provider SSE text inside the streaming
  transform (cap 64KB) and forward it through
  onStreamComplete.rawProviderText so handler stores it as the
  providerResponse. response.content stays the extracted user
  text. Tool-call-only turns remain so the marker.
* Accumulate from translated client-facing chunks instead of
  raw provider shapes so Responses, Claude delta types, and
  Gemini/Antigravity parts all contribute.
* Drop redaction from the list endpoint; raw access is now via
  the dedicated /raw endpoint. Tests cover the new behavior.
2026-09-07 14:23:48 +07:00
a835771c97 Merge origin/master (v0.5.69) into gitea/new_feature 2026-09-07 14:10:11 +07:00
decolua
eb712ca821 # v0.5.69 (2026-09-05)
## Features
- **Codex**: add GPT 6.0 Astra (`gpt-6-astra`) with vision, thinking and search capabilities
- **Usage**: add Claude Fable quota tracker support with weekly window normalization (`weekly fable (7d)`)
- **Dashboard**: group Antigravity Gemini and Claude quotas in Quota Tracker, prune stale hidden keys
- **OpenCode Go**: add `muse-spark-1.3-contributor` model and support parallel tool calls on Responses path (#3819)
- **Providers & Models**: align CodeBuddy-CN catalog/capabilities with server config; add GPT-5.6 Sol, Terra, Luna image aliases on Codex (#3806); refresh Qoder catalog with capability mapping and image pass-through
- **CLI tools**: replace Copilot MITM with VS Code extension setup guide
- **Gemini**: persist and replay `thoughtSignature` scoped by session namespace

## Fixes
- **Claude**: normalize adaptive auto effort (`output_config.effort`) (#3792)
- **Antigravity**: prevent Google anti-abuse rate limits during multi-account refresh (#3813)
- **Anthropic-compatible**: forward Claude beta flags to nodes fronting Anthropic (#3797)
- **Dashboard**: dynamic mode label for local/remote detection (#3801)
- **Codex**: format reset credit API errors cleanly (#3778)
- **Security**: guard cowork MCP tools probe against SSRF (#3783)
- **OpenCode Go**: track OpenCode Go quota (#3791) and send stable session headers (#3800)
- **Logger**: suppress noisy background token refresh logs
- **CLI**: export packed `.tgz` directly into workspace root instead of parent directory
2026-09-05 22:57:00 +07:00
Sina Sadeghi
11222eff0f feat(opencode-go): muse-spark-1.2 and Responses tool fixes (#3820)
- Add muse-spark-1.2-contributor as responses-only model on OpenCode Go
- Normalize object tool schemas without properties in OpenCode Go executor
- Make fallback Responses call_ids unique across same-millisecond calls
- Make Responses output coercion fail-soft for circular and non-stringifiable values
2026-09-05 22:39:22 +07:00
decolua
e214fb1c30 feat(usage): add Claude Fable quota tracker support
- Recognize Fable weekly windows and normalize to weekly fable (7d)
- Fall back to 100% available weekly Fable window when Anthropic payload omits it
- Forward remaining percentages and enforce canonical Claude quota order in Quota Tracker

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-05 22:05:18 +07:00
Sina Sadeghi
e74db4d0a6 feat(opencode-go): add muse-spark-1.3-contributor and fix parallel tool calls on Responses paths (#3819)
- Add muse-spark-1.3-contributor as responses-only model on OpenCode Go with dedicated executor
- Key Responses→chat streaming tool calls by item_id to prevent parallel tool calls merging into index 0
- Standardize tool coercions and call_id clamping in Responses API translation
2026-09-05 21:49:53 +07:00
Sutarto Jordan Chrisfivo
77e6a227fe fix(claude): normalize adaptive auto effort (#3792)
Claude adaptive requests without an explicit effort are normalized to
output_config.effort: "high" instead of forwarding the unsupported
literal value "auto" which Anthropic rejects with HTTP 400.
2026-09-05 21:41:25 +07:00
Hifzi
1442cc73ce fix(antigravity): prevent Google anti-abuse rate limits on multi-account refresh (#3813) 2026-09-05 21:28:30 +07:00
Federico Liva
fb9fab0206 fix(anthropic-compatible): send Claude beta flags to nodes fronting Anthropic (#3797) 2026-09-05 21:26:16 +07:00
Raisal P Wardana
1a3d446831 fix(codex): format reset credit API errors (#3778) 2026-09-05 21:18:07 +07:00
JOJO
0da803eef4 fix(usage): track OpenCode Go quota (#3791)
OpenCode Go API-key connections now appear in the Quota Tracker and report rolling, weekly, and monthly subscription usage.
2026-09-05 21:10:10 +07:00
turingcat
81f4f93082 fix(opencode-go): send stable session header (#3800)
- add a dedicated OpenCode Go executor that always sends x-opencode-session
- preserve a valid caller-provided native OpenCode session header
- translate downstream Agent session IDs into opaque, stable, Agent-scoped IDs
- forward the original provider session seed and client tool on both initial and credential-refresh requests
2026-09-05 21:09:49 +07:00
zmf
cec672d9d9 feat(providers): align codebuddy-cn catalog/capabilities with server config
- Sync codebuddy-cn catalog and capabilities with copilot.tencent.com server payload
- Fix thinkingCanDisable semantics for glm-5.3 and deepseek-v4 models
- Add missing glm-5.2 thinking levels to thinkingLevels.js
- Add glm-5-turbo model to glm and glm-cn registries
2026-09-05 21:03:02 +07:00
An Nguyen
ed963931b4 feat(codex): add GPT-5.6 Sol, Terra, and Luna image aliases (#3806) 2026-09-05 21:01:52 +07:00
hangyu
2ab6a4c949 feat(qoder): refresh model catalog, add capability mapping and image pass-through
- Registry/constants: drop qmodel_preview/gm51model, add lite,
  qmodel_38max (Qwen3.8-Max), qfmodel (Qwen3.8-Flash), gmodel (GLM-5.3),
  gfmodel (GLM-5.3-Flash)
- capabilities: add PROVIDER_CAPABILITIES['qoder'] so opaque internal
  ids resolve to their real models' context windows and limits
- executor: preserve image blocks instead of flattening away, convert
  Claude-style image blocks, and hash images into chat_record_id
- tests: cover image preservation, data-URI and Claude-block conversion
- build(docker): use CN mirrors for apk and npm
2026-09-03 23:02:52 +07:00
decolua
c08efdbe2b feat(gemini): persist and replay thoughtSignature with session namespace
- Add open-sse/services/thoughtSignatureStore.js managing LRU Map (2k) + SQLite kv table
- Store thoughtSignature with sessionId namespace and toolCallId fallback
- Replay cached signature by sessionId:tool_call_id to prevent multi-process collisions
- Normalize Antigravity sessionId to numeric int64 format

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-03 18:20:04 +07:00
Sami Basra
e0ffc7e2a1 feat(fetch): add Ollama Cloud web fetch provider 2026-09-03 10:13:15 +07:00
Federico Liva
6ab9ca9eb1 fix(claude): never anchor cache breakpoint on defer_loading tools (#3567) 2026-09-03 10:05:35 +07:00
decolua
6efb97904b feat(providers): streamline tokenrouter models and add missing provider icons
- Prune tokenrouter seed models from 121 to 22 flagship/newest models
- Add z-ai/glm-5.3-free with 0 pricing
- Add missing 128x128 icons for alims-intl, alitp-intl, fish-audio, and selfhosted-* providers

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-03 09:59:30 +07:00
IEatCodeDaily
e7dd72a8d7 fix(usage): read Responses-shape cached_tokens in extractUsageFromResponse
Non-streaming codex traffic recorded cached_tokens: 0 even when upstream
prompt caching worked. The Claude-format branch (which OpenAI Responses
usage also matches) never read input_tokens_details, and the OpenAI
branch ignored a top-level flat cached_tokens. Read both in both
branches; Responses prompts are cache-inclusive so canonicalizeUsage
passes the value through without folding. 5 new regression tests.
2026-09-03 09:48:19 +07:00
zmf
e014cb537f feat(codebuddy-cn): refresh model catalog — add hy4-preview/hy3/glm-5.3/kimi-k3, drop EOL glm-5.0/glm-4.7
- Add hy3, hy3-x, hy4-preview, hy4-preview-x, glm-5.3, glm-5.3-flash, kimi-k3-1
- Remove dead models glm-5.0, glm-4.7 (API 11102)
- Register capabilities and context windows in PROVIDER_CAPABILITIES
- Configure supported effort sets in PATTERN_THINKING
2026-09-03 09:41:02 +07:00
anojndr
acb5c34cdc fix(opencode): route Muse Spark models to Responses API and declare vision
Route all Muse Spark models (not just 1.2) on OpenCode Free to
/zen/v1/responses via isMuseSparkModel(), fixing HTTP 500 on
muse-spark-1.3-contributor-free. Declare vision:true on Muse Spark
models so image input is no longer stripped; register 1.3 in the
registry and capabilities. Scoped to opencode only — other providers
keep Chat Completions routing.
2026-09-03 09:24:18 +07:00
openhands
b870b5d41b fix(security): close SSRF guard bypasses in ssrfGuard.js (#3714)
Closes four SSRF guard bypasses reported in #3714:
- Block alternate IPv6 encodings (hex format, NAT64, IPv4-compatible, IPv4-mapped) by parsing to 16-bit groups
- Normalize trailing dots on hostnames to prevent FQDN bypasses
- Add assertPublicUrlResolved() with DNS resolution to block wildcard DNS domains resolving to private/metadata IPs
- Add fetchPublic() to safely handle and validate HTTP redirects
2026-09-03 09:22:22 +07:00
Zafar
70f15aa50b feat(antigravity,gemini): add Gemini 3.8 Flash support and bump IDE fingerprint to 2.11.0
Co-authored-by: Schnee111 <daffamaarif.dev@gmail.com>
Co-authored-by: AhooraZen <ahoora935137@gmail.com>
Co-authored-by: anojndr <anojndr@gmail.com>
Co-authored-by: Emirhan <emirhan551952@gmail.com>
2026-09-03 09:13:45 +07:00
Lek Huda
1fe996db6a fix(translator): route Gemini thinking through reasoning_effort on OpenAI-compatible wire 2026-09-03 09:12:34 +07:00
decolua
1fc2a81d65 fix(kiro): remove redundant top-level systemPrompt field from payload
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-03 09:06:02 +07:00
decolua
f6c59d30b0 fix(gemini): convert prefixItems and ensure array items in schema sanitizer
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-03 09:05:57 +07:00
LucasOl1337
ac9120fde3 fix(claude): support Fable 5.1
- add claude-fable-5-1 to the Claude Code model catalog (1M context,
  permanent adaptive thinking)
- centralize the spoofed Claude Code version and update both request
  and billing identities to 2.1.257 (Fable 5.1 rejects < 2.1.251)
- send output_config.effort without the redundant thinking switch for
  permanently adaptive models
- add regression coverage for capabilities, headers, billing identity
  and adaptive-effort payload

# Conflicts:
#	open-sse/providers/registry/claude.js
#	open-sse/providers/shared.js
#	open-sse/utils/claudeCloaking.js
#	tests/__baseline__/providers-baseline.json
2026-09-02 20:42:53 +07:00
Federico Liva
ee7a961633 fix: strip the [1m] context marker Claude Code appends to the model name
With the 1M-context beta enabled, Claude Code sends model: "claude-opus-5[1m]".
The marker is a client-side annotation — it matches no combo name, no alias and
no provider/model pair — so the request dies at model resolution with
"Invalid model format" and the client reports "There's an issue with the
selected model". Every request from that session fails until the beta is
switched off.

New open-sse/utils/modelMarkers.js exporting stripModelContextMarker(modelStr)
-> { model, contextMarker }. handleChat strips the marker before resolution and
normalizes body.model so downstream logging and translation see the real name.
Only a trailing marker is stripped, so a model whose name genuinely contains
brackets is left alone.

The capability itself travels in anthropic-beta: context-1m-2025-08-07, which
the default executor already forwards untouched — only the routing key needed
cleaning.

Fixes #3690.

Tests: tests/unit/model-context-marker.test.js (6 cases).
2026-09-02 20:20:32 +07:00
Federico Liva
ed1bd0c528 fix(claude): drop server_tool_use blocks carrying a foreign id
Anthropic validates server_tool_use.id against ^srvtoolu_[a-zA-Z0-9_]+$
and 400s the whole request when one does not match. A combo that falls
back to a provider with its own built-in tools (z.ai/glm emits
OpenAI-style call_ ids for analyze_image) leaves such blocks in the
history, so every later Claude turn fails.

Extend normalizeClaudePassthrough to drop those blocks (reusing the
existing loop), drop the paired tool_result / web_search_tool_result
referencing a dropped id, and drop empty text blocks plus messages left
with no content. Well-formed srvtoolu_ blocks and regular tool_use ids
are untouched.
2026-09-02 20:07:16 +07:00
openhands
b9c92cb83c feat(quota): add usage tracking for Groq
First slice of #3701: quota tracking for Groq via x-ratelimit-* response
headers on the models endpoint (no dedicated quota endpoint exists, and
reading usage costs zero tokens).

- usage/groq.js: parse request+token limit/remaining headers; Go-style
  duration reset headers ("2m59.56s") resolve to future timestamps;
  missing key/401/403 -> message, 2xx without headers -> soft
  "not tracked yet" with quotas:{}
- registry/groq.js: transport.usage.url (reuses validateUrl) +
  features {usage, usageApikey}
- services/usage.js: groq entry in USAGE_HANDLERS
- ProviderLimits/utils.js: parseQuotaData case (absolute used/total,
  codex/kiro style)
- tests: groq-usage.test.js (registry flags, header parsing, soft
  not-tracked path, missing key/401, parseQuotaData)
2026-09-02 20:04:35 +07:00
decolua
009cac6326 fix(claude): bump CC fingerprint to 2.1.258 for new-model access
Anthropic gates newly released models (e.g. claude-fable-5-1) to Claude
Code >= 2.1.251; the spoofed 2.1.92 client got HTTP 400 on every request.
Bump User-Agent + billing-header version to 2.1.258 and refresh the
providers baseline snapshot.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-02 11:27:21 +07:00
decolua
2fd99eae5d fix(session): read Claude Code session id from its request header
Claude Code carries the session in metadata.user_id, which the Responses
API translation drops before the executor resolves a cache session. The
request then fell through to the assistant-text hash and the per-connection
fallback, so one conversation was split across several prompt_cache_key
values and the upstream prefix cache kept missing.

Fall back to the x-claude-code-session-id header, which survives every
translation. The body stays authoritative when both are present.
2026-08-28 18:17:55 +07:00
Ahoora5678
dff648496c fix(antigravity): sanitize competing-client branding in system prompts
Antigravity flags requests whose system prompt identifies another vendor's
client and answers 429 Quota Exhausted. Move the existing Zed/Claude prompt
rewrite into a config-driven rule table and add case-preserving opencode ->
antigravity mapping.

Applied in the executor so only Antigravity requests are rewritten - the
shared openai-to-gemini translator also serves gemini, gemini-cli, vertex
and zed, which must not be touched.
2026-08-28 17:01:18 +07:00
Paulo Schuller
88676b3037 fix(oauth): refresh Cline tokens with extension JSON contract 2026-08-28 16:58:27 +07:00
Óscar Fonseca
4a371d1d9f fix(usage): preserve nested cached_tokens in canonicalizeUsage
buildUsage() only emits cache reads under prompt_tokens_details, so the
top-level-only read dropped the count for every Responses-format provider
(codex, grok-cli, ...), persisting cached_tokens: 0 and billing cache hits
at the full input rate. Mirror the cache_creation fallback already used
just above.
2026-08-28 16:46:05 +07:00
snower
993c6eb469 feat(headroom): make the compression request timeout configurable
The 3000 ms timeout on /v1/compress was fixed, so busy or slow machines
timed out often and sent the LLM an inconsistently compressed body,
hurting prompt caching. Add a headroomTimeoutMs setting, thread it from
the chat handler down to compressWithHeadroom, expose it in the Token
Saver dashboard, and normalize invalid values back to the 3000 ms default.
2026-08-28 16:34:33 +07:00
turingcat
28d005772a fix(minimax): preserve images on matched OpenAI transport
Prefer the sourceFormat-matched runtime transport over a model's
declared targetFormat when both apply. MiniMax-M3 previously resolved
to a Claude-shaped body while being posted to the already-selected
OpenAI endpoint, silently dropping image_url blocks from OpenAI
clients. Fixes #3418.
2026-08-28 16:34:05 +07:00
fasilu
2a9213c5bd feat(antigravity): map image size to aspect-ratio model suffix
Resolve body.size through sizeToAspectRatio and append the ratio as a
-WxH suffix so the executor's parseImageConfig picks it up. Also fall
back to gemini-3.1-flash-image when a non-image model reaches the
image handler.
2026-08-28 16:33:23 +07:00
Amir Seify
e5a13c3ab7 feat(usage): show Zed plan quota on the dashboard
Add a Zed usage handler so connected Zed accounts appear on
/dashboard/quota. Reads GET /client/users/me for plan, edit
predictions, optional hosted model requests and billing-cycle reset.

Render unlimited rows as "N used · Unlimited" instead of 0 / ∞, and
surface overdue-invoice / token-billing messages.
2026-08-28 16:16:01 +07:00
Bertho Joris
67d9182e1a fix(executor): handle CommandCode in-stream errors for combo and account fallback
CommandCode returns errors as a type:"error" event inside an HTTP 200
NDJSON stream instead of a non-200 status, so the existing combo/account
fallback logic (keyed off response.status) never triggered and the error
text was streamed to the client as if it were content.

Peek the first NDJSON events before committing to a stream; on a
type:"error" event, abort and return a proper 4xx/5xx Response instead.
Normal streams are replayed losslessly (buffered prefix + rest of the
stream) through the existing translator, so the happy path is unchanged.
Add CommandCodeExecutor.parseError() so parseUpstreamError() can extract
a clean message/status from the synthesized error body.
2026-08-28 16:15:19 +07:00
decolua
9dbdca0e5e refactor(search): fold zai-search into the glm provider
The separate zai-search entry showed "No connections" on the web search
page because credentials live on the `glm` connection, not on it. Every
other provider that does both chat and search (antigravity, kimi, xai,
gemini) declares webSearch on the provider itself, so do the same here.

- glm gains serviceKinds ["llm", "webSearch"] and the MCP searchConfig
- the request builder / normalizer move from "zai-search" to "glm"
- drop the zai-search registry entry and its svg logo, which also
  removes the only need for svg logo support in getProviderIconSrc

ollama-search keeps its own entry and credentialFallback: its search
endpoint is unrelated to the ollama chat transport.
2026-08-28 16:12:04 +07:00
decolua
5a86f6a8d2 feat(search): add ollama-search and zai-search with credential fallback
Register two web search providers that reuse an existing chat provider's
API key instead of requiring their own connection:

- ollama-search (POST ollama.com/api/web_search) reuses the `ollama` key
- zai-search (POST api.z.ai MCP web_search_prime) reuses the `glm` key

A new `credentialFallback` registry field drives this: when a search
provider has no connection of its own, the search handler falls back to
the linked chat provider's credentials.

Also teach getProviderIconSrc to serve .svg logos for providers that
ship vector art.
2026-08-28 16:04:45 +07:00
huohua-dev
eb312bd470 fix(claude): decloak tool names in same-format streaming passthrough
translateResponse() short-circuited untouched on claude->claude streaming,
so OAuth-cloaked tool names (CLAUDE_TOOL_SUFFIX) leaked to the client and
every tool call was rejected as unknown. Add decloakStreamChunk(), the
streaming counterpart of decloakToolNames(), and call it on the same-format
path using the already-plumbed state.toolNameMap.
2026-08-28 15:40:40 +07:00