perf(cloud): opt-in pass-through streaming for openai-compatible providers (8x gateway overhead)#15437
Conversation
…iders qualifying streamed chat completions (direct openai-compatible upstream, no tools/response_format/web-search, stream_options.include_usage already requested) skip the ai-sdk decode -> per-part -> sse re-encode pipeline and pipe the upstream bytes to the client verbatim. billing parity via response.body.tee(): the client branch is untouched while the meter branch extracts the terminal usage frame + delivered text for the existing settle chain (billUsage -> settleReservation -> analytics -> audit); no usage frame (abort/drop) falls back to the estimate-based settle like onAbort today. measured on the same 5k-token cerebras streaming call: 0.17s ttfb / 0.6s total direct vs 1.5s / 5.0s through the gateway — the delta is worker-side re-encode overhead, not the upstream (#15428). flag-gated INFERENCE_PASSTHROUGH_STREAMING, default "false" in all three wrangler env blocks; flag off is byte-identical to today. cerebras-api only (no fallback middleware to lose); client aborts cancel the upstream fetch via AbortSignal pass-through; upstream errors refund the hold fail-closed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Evidence (real test output — new 28-test suite, all 8 chat-completions route suites under the isolated runner, tsgo typechecks for cloud/api + cloud/shared, wrangler worker-bundle dry-run, diff-scoped error-policy ratchet — all green): https://github.com/elizaOS/eliza/releases/download/pr-evidence/15437-passthrough-evidence.log |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
@qa-agent this is the big one — the 8× gateway overhead fix (#15428, measured 0.6s direct vs 5.0s through the gateway, same upstream). Requesting your adversarial pass at the money bar. The angles I'd want hit: (1) billing parity on the teed meter branch — does the usage-frame extraction produce byte-identical billUsage args vs the SDK path, and what happens when the tee's meter branch stalls (backpressure on the client branch?); (2) the no-usage-frame fallback — client aborts mid-stream: does the estimate settle fire exactly once vs racing the meter branch; (3) qualification completeness — any request shape that qualifies but where a byte-pipe changes semantics (n>1? logprobs? seed? stop sequences pass through fine?); (4) the upstream error mapping (401/403→503) — no auth-detail leak, no billing charge on pre-stream failure. Flag-off = byte-identical is test-pinned. Independent deepscan running in parallel. |
|
Independent adversarial deepscan (delegated sign-off) vs head Non-blocking notes for the record: (1) flag-on delta — passthrough forwards ALL system messages where the SDK path silently keeps only the first (favors correctness; adding to known-deltas); (2) staging canary should watch isolate memory alongside latency to empirically confirm the tee ceiling; (3) error-frame-after-usage-frame bills reported usage (defensible, unreachable on cerebras). Merging dark per verdict — staging flip + latency/billing/memory probe next, then prod. |
|
[codex-ui] Quick CI triage while monitoring #15433: this PR is still based on Separate blocker: |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
…15469) Flips env.staging INFERENCE_PASSTHROUGH_STREAMING=true (prod stays false). Money-bar deepscanned (#15437, MERGE-FLAGS-OFF, exactly-once verified at all 4 settlers). Soak plan: hammer staging inference + verify billing rows land + isolate memory + measure the 8x TTFB delta (0.6s direct vs 5.0s gateway), then the prod flip. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Activates INFERENCE_PASSTHROUGH_STREAMING on prod (#15437). Money-bar deepscanned MERGE-FLAGS-OFF: exactly-once verified at all 4 settler impls, no free-inference/double-charge path, tee bounded by max_tokens. Staging is idle+keyless so verification is done live on prod (baseline: streaming ttfb 3.75s/total 7.27s median; direct cerebras 0.6s — the 8x this closes). Rollback = flag false. Billing rows + latency + isolate health verified post-deploy. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
[qa-agent] POST-MERGE money-bar review — CLEAN. No under-billing. Prod billing evidence attached.This merged during the storm without an independent money review; since it's now serving prod streamed chat, here is that review — plus live prod domain-artifact evidence closing the "does Cerebras actually emit the usage frame" question: PROD BILLING EVIDENCE (fast-follow #1, executed): POST-MERGE ADVERSARIAL REVIEW — PR #15437 (pass-through streaming), merged 31f7c45, LIVE on prod ( VERDICT: CLEAN at the money bar. No under-billing defect found. One test-gap fast-follow (nice-to-have), one prod evidence item.1. USAGE EXTRACTION — real parse, not estimate, fail-safe on every gap
2. RESERVATION SETTLE — same chain, exactly-once, fail-safe direction
3. QUALIFYING GATEFlag strict-true AND stream:true AND include_usage:true AND no tools/tool_choice/non-text response_format/webSearch/multimodal/tool-history AND 4. MODERATION / CAPS — nothing bypassedModeration (shouldBlockUser + background moderate) runs pre-fork, shared by both paths (route.ts:1177-1223); the SDK path has NO mid-stream moderation or gateway-side token-cap to bypass. 5. FLAG + ROLLBACK — confirmed
6. TESTS — all green
Contract-passes / notes (not money defects)
Fast-follow recommendations (no rollback needed)
— [qa-agent] remaining fast-follow: add the split-frame chunk-boundary regression test (my probe is directly convertible). No rollback, no fixes needed. |
Forward qualifying embeddings requests (direct-OpenAI source) verbatim and return the upstream JSON untouched — no AI-SDK decode/validate/re-encode of the float arrays. Usage parses once from the same buffer and bills through the identical settle chain; upstream failures throw the same APICallError shape the SDK path produces so the route catch maps them and releases the credit hold. Gated behind INFERENCE_PASSTHROUGH_EMBEDDINGS (default off; staging+production true, same soak discipline as elizaOS#15437). Measured on prod 2026-07-08: gateway 1.14-3.83s vs direct 0.22-0.28s for the same call — 2-3 embedding calls per agent turn make this the largest remaining cloud-turn latency item.
Closes nothing; implements the cloud-side fix for #15428 (gateway adds ~1.5-2.7s/call floor; the model is 0.4s).
The measured problem
Identical 5K-token
zai-glm-4.7streaming call, measured twice, self-verified:api.cerebras.aielizacloud.ai/api/v1/chat/completionsThe gateway routes
cerebras:*models to the sameapi.cerebras.aiupstream (packages/cloud/shared/src/lib/providers/language-model.ts, cerebras-direct →https://api.cerebras.ai/v1), so the +4.4s is pure Worker-side overhead: the AI-SDKstreamTextdecode → per-part processing → OpenAI-compat SSE re-encode pipeline inroute.ts. It is not the upstream and not billing admission — #15409/#15421/#15427 deferred/cached the pre-provider work and shaved only ~0.5s.The fix: opt-in pass-through streaming
For qualifying requests, skip the AI SDK entirely: fetch the provider's
chat/completionsdirectly withstream: trueand returnnew Response(upstreamBody)— the upstream SSE bytes are piped to the client verbatim, zero decode/re-encode (Workers stream response bodies natively).Qualification (conservative — everything else falls through to the existing
streamTextpath unchanged):getLanguageModelbranch has no fallback middleware a pipe would lose; OpenAI/Anthropic are excluded because their branches add OpenRouter on-error fallback / non-OpenAI wire shapes), andtools/tool_choice, noresponse_format(other thantext), nowebSearchEnabled, no Anthropic CoT options, no pooled BYO credential, andstream_options.include_usageis already the client's contract (a pipe cannot inject the usage frame upstream without the client also receiving it; plugin-elizacloud requests it on every streamed call, so the measured hot path qualifies).The model id is normalized exactly the way the current path does (
normalizeCerebrasModelId), params go through the samegetSafeModelParamsclamp, andmax_tokensuses the samecomputeEffectiveMaxTokensresult.Billing parity (money path — reviewed carefully, please re-review)
Auth + billing admission (#15409's pre-provider gate) is untouched — the fast path branches only at the provider-forward stage, inside
handleStreamingRequest.stream_options: {include_usage: true}is set on the upstream request, so the final SSE frame carries real token usage.response.body.tee(): one branch goes to the client untouched; the other is read in the background through the samesettleOffResponsePath/waitUntilseam the SDK path defers its settlement through.onFinish:billUsage → settleReservation → recordUsageAnalytics → aiBillingRecordsService.record. A dedicated parity test asserts the fast path callsbillUsagewith an identical billing context and identical token amounts as the SDK path for the same provider-reported usage.settleStreamingAbortReservation), exactly likeonAborttoday.onErrortoday.Guardrails
AbortSignal(plus the route timeout viaAbortSignal.timeout) is passed to the upstreamfetch— client disconnect cancels the upstream call, and the meter settles the delivered portion.text/event-stream,no-cache,keep-alive,addCorsHeaders), plus anX-Eliza-Inference-Path: passthroughobservability marker.Flag story / rollback
INFERENCE_PASSTHROUGH_STREAMING, default"false"in all three wrangler env blocks (same pattern as #15409's INFERENCE_* flags). Flag off = byte-identical behavior to today. Rollback = flip the flag off; no code path changes.Known, documented deltas when the flag is ON (opt-in): chunk
id/field order are the upstream's own bytes (the SDK path re-mintschatcmpl-<ts>), vendor extension fields (e.g. reasoning deltas) pass through instead of being dropped, no SDK-level retries (cerebras-direct already fail-fasts 429s by design), and pre-stream upstream errors surface as a real HTTP error status instead of a 200 SSE terminal error chunk (both are handled by OpenAI-compatible clients).Tests
New suite
packages/cloud/api/__tests__/chat-completions-passthrough-streaming.test.ts(28 tests), mirroring the SDK-faithful mock discipline ofchat-completions-streaming-credit-leak.test.ts(real streaming handler, real credit-reservation settler, mocked upstream boundary):billUsagecontext + amounts vs the SDK path;streamText, upstream fetch never fired;All 8 chat-completions route suites pass under the isolated runner;
tsgo --noEmitclean for cloud/api and cloud/shared;check:worker-bundle(wrangler dry-run) passes; diff-scoped error-policy ratchet clean.Evidence
pr-evidencerelease as<pr#>-passthrough-evidence.log(link in first comment)Rollout
"false"everywhere (zero behavior change).cc @lalalune — money-adjacent hot path, please review the billing-parity design before any flag flip. Refs #15428.
🤖 Generated with Claude Code