-
Fix a batch of routing, streaming, and deployment quick wins (#941)
发布于
2026-08-20 15:10:33 +00:00 Server:
- proxy: capture streaming
usagefrom choice-bearing frames too, and
emit it to the client exactly once (after the finish chunk). Providers
that bundle usage onto the last content frame no longer fall back to
the chars/4 estimate in accounting. - proxy: cap GitHub Models output tokens (new per-platform maxTokensCap)
and trim oversized histories before a github dispatch instead of
burning the hop on a guaranteed 400/413. Attempt-scoped: the next
candidate still sees the full history. - ratelimit: throttle the rate_limit_usage sweep to once a minute (it
ran an unindexed DELETE on every request), stop the in-memory windows
growing unbounded on a healthy DB (memory is now the degraded-mode
fallback only), cap 429 cooldown escalation at 10 minutes for routes
with no published daily limits, and sweep expired cooldown rows once
at startup. - router: re-rank legacy-priority chains to dense positions before
adding 429/fail penalties — spaced priorities (e.g. holes left by
disabled models) could exceed MAX_PENALTY and make demotion inert. - error-classify: walk err.cause (bounded, cycle-safe) so wrapped undici
transport errors (ECONNRESET, EPIPE, socket hang up, UND_ERR_*)
classify retryable and fail over instead of 502-ing; client/hedge
aborts stay non-retryable. - gemini-wire: translate JSON-Schema type unions ("type": ["number",
"null"]) to Gemini's type + nullable, and inline local $ref targets
from $defs instead of dropping the whole subschema. - db-backup: upload Hugging Face backups through the commit API as
base64 text — the old PUT to /resolve/ never persisted, so HF Spaces
restored nothing on cold start. Legacy raw blobs still restore. - providers: Zhipu keys issued on the global z.ai console now validate
and route via api.z.ai automatically; domestic keys are unaffected. - proxy lib: pass hostnames through to SOCKS5 proxies unresolved so
rule-based clients (Clash) can route by domain. - crypto: maskKey no longer echoes keys of 8 chars or fewer.
Docker:
- drop the VOLUME declaration; persistence comes from the compose named
volume or an explicit bind mount. The anonymous volume broke PaaS
builds (Railway, Coolify, Dokploy, CapRover) and shadowed same-path
bind mounts.
62 new/updated tests across 13 test files; full suite green.
Co-authored-by: Claude Fable 5 noreply@anthropic.com
下载附件
- proxy: capture streaming