Commit 90ba3e9
authored
fix: add stream value in gcp anthropic body (envoyproxy#1370)
**Description**
This PR fixes a bug where streaming chat completion requests from an
OpenAI-compatible client to the GCP Anthropic backend were failing.
Although the API returned a 200 OK status, the response was a
non-streaming JSON object instead of a text/event-stream, causing the
client to receive an empty stream and to fail our integration test
assertions.
Our integration tests output was like
`> assert model_output, f"Received empty {model_output=}"
E AssertionError: Received empty model_output=''
E assert ''`
and after adding debugging logs, the response header and the output
message showed that the response in not streamed, even though the url is
set to stream. It seems you can send to the stream URL but if the param
isn't set, that takes precedence.
the header output
{
"time": "2025-10-14T16:02:11.407-04:00",
"level": "DEBUG",
"msg": "response headers processing",
"response_headers": "headers:{key:\":status\" raw_value:\"200\"}
headers:{key:\"content-type\" raw_value:\"application/json\"}
headers:{key:\"server\" raw_value:\"hypercorn-h11\"} ..."
}
This second log shows the entire response body arriving in a single
chunk with end_of_stream:true. This confirmed that instead of streaming
the response piece-by-piece, the server sent the complete final message
all at once.
{
"time": "2025-10-14T16:02:11.408-04:00",
"level": "DEBUG",
"msg": "response body processing",
"request":
"response_body:{body:\"{\\\"id\\\":\\\"msg_vrtx_019F694kiwv6Z5BQApos5MJy\\\",\\\"type\\\":\\\"message\\\",\\\"role\\\":\\\"assistant\\\",
... ,\\\"content\\\":[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"I'm
doing well, thank you for asking! I'm here and ready to help with
whatever you'd like to chat about or work on. How are you doing
today?\\\"}],\\\"stop_reason\\\":\\\"end_turn\\\", ... }\"
end_of_stream:true}"
}
The root cause was the missing "stream": true field in the JSON payload
sent to GCP's :streamRawPredict endpoint. This PR modifies the
OpenAIToGCPAnthropicTranslator to conditionally add this field to the
request body when the original client request is for a stream. For
context, it seems like this is how anthropic's go sdk handles it
https://github.com/anthropics/anthropic-sdk-go/blob/e8befdc7fdceba33c9000b0b50061b8a42cb6c04/message.go#L86
its not a field in the message param object.
The Fix:
The solution implemented in this PR is to ensure the translated request
body always has the field stream: true for streaming requests:
Modify RequestBody: The RequestBody function in openaittogcpanthropic.go
has been updated to check if the incoming openAIReq.Stream is true.
Inject Stream Field: If streaming is requested, we use the sjson library
to inject the "stream": true key-value pair into the final JSON payload
before it is sent to the GCP endpoint.
Add Unit Test: The existing unit test "Streaming Request Path" has been
renamed to "Streaming Request Path and Body" and an assertion has been
added to verify that the stream field is correctly set to true in the
marshaled body, preventing future regressions
---------
Signed-off-by: Alexa Griffith <[email protected]>
Signed-off-by: Sukumar Gaonkar <[email protected]>
Signed-off-by: Dan Sun <[email protected]>1 parent 220b90c commit 90ba3e9
File tree
3 files changed
+14
-4
lines changed- internal/extproc/translator
- tests/extproc
3 files changed
+14
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
548 | 548 | | |
549 | 549 | | |
550 | 550 | | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
551 | 555 | | |
552 | 556 | | |
553 | 557 | | |
| |||
558 | 562 | | |
559 | 563 | | |
560 | 564 | | |
561 | | - | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
562 | 569 | | |
563 | 570 | | |
564 | 571 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
194 | | - | |
| 194 | + | |
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
| 202 | + | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| |||
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
211 | 214 | | |
212 | 215 | | |
213 | 216 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
534 | 534 | | |
535 | 535 | | |
536 | 536 | | |
537 | | - | |
| 537 | + | |
538 | 538 | | |
539 | 539 | | |
540 | 540 | | |
| |||
0 commit comments