Skip to content

[AISAGE-756] fix(ai-gateway): force a truthy stream to true - #8554

Merged
chrarnoldus merged 2 commits into
mainfrom
fix/ai-gateway-non-boolean-stream
Oct 22, 2026
Merged

chrarnoldus merged 2 commits into
mainfrom
fix/ai-gateway-non-boolean-stream

Conversation

@chrarnoldus

@chrarnoldus chrarnoldus commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A request could set stream to a truthy value that is not a boolean, such as "true" or 1, and skip usage recording. The proxy added stream_options.include_usage for any truthy stream, so an upstream could stream the response. Usage accounting reads the response as SSE only when stream === true, so it parsed the SSE body as JSON. That parse threw, no usage row was written, and the request was served free.

handleLlmProxyRequest now sets any truthy stream to true right after parsing the body, for Chat Completions, Responses and Messages. The upstream request and usage accounting then agree that the response is streamed.

Verification

  • Unit tests: a truthy non-boolean stream on each API reaches the upstream as true and is accounted as streaming.
  • No manual test against an upstream; the change only normalizes the request body.

Visual Changes

N/A

@chrarnoldus chrarnoldus self-assigned this Oct 22, 2026
@chrarnoldus chrarnoldus changed the title [AISAGE-756] fix(ai-gateway): reject non-boolean stream, estimate lost usage [AISAGE-756] fix(ai-gateway): force a truthy stream to true Oct 22, 2026
@kilo-code-bot

kilo-code-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The two changed files were reviewed: handleLlmProxyRequest now coerces any truthy non-boolean stream to true before the upstream call and before usageContext.isStreaming is derived, so usage accounting and the upstream request agree on streaming. The new it.each case exercises Chat Completions, Responses and Messages and asserts both the forwarded body and isStreaming, and the intermediate commit's estimate/fallback code is fully reverted with no dangling references.

Assumptions: [INFERENCE] the fix relies on upstreams treating any truthy stream as streaming (e.g. a client sending stream: "false" now becomes streaming); if an upstream instead rejects or ignores it, usage handling behaves exactly as before. [INFERENCE] the residual failure mode — an upstream returning a non-SSE body to a request the proxy treats as streaming — still has no fallback in countAndStoreUsage and would silently lose usage, but that path is pre-existing and outside this diff.

Files Reviewed (2 files)
  • packages/web-shared/src/lib/ai-gateway/handlers/llm-proxy.ts
  • packages/web-shared/src/lib/ai-gateway/handlers/llm-proxy.test.ts

Reviewed by deepseek-flash-latest · Input: 123.3K · Output: 17.4K · Cached: 1M

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants