Skip to content

handle data:[DONE] without space properly #5580

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

zyxue
Copy link

@zyxue zyxue commented May 8, 2025

although https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#request-body says

stream boolean Whether to stream back partial progress. If set, tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message

but what I see is data:[DONE] (without space), e.g.

curl -q --location 'http://localhost:8080/openai/deployments/gpt-4o/chat/completions?api-version=2023-07-01-preview' \
--header 'Authorization: Bearer <token>' \
--header 'X-Forwarded-Client-Cert: secret' \
--header 'Content-Type: application/json' \
--data '{
    "stream": true,
    "messages": [
        {
            "role": "user",
            "content": "hello."
        }
    ]
}'
data:{"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}

data:{"choices":[{"content_filter_results":{},"delta":{"refusal":null,"role":"assistant"},"finish_reason":null,"index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}
...
data:{"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"},"finish_reason":null,"index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}

data:{"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}

data:[DONE]

Description

handle the last chunk of AzureOpenAI streaming chat completion response more robustly.

Checklist

  • I've read the contributing guide
  • The relevant docs, if any, have been updated or created
  • [] The relevant tests, if any, have been updated or created

Screenshots

[ For visual changes, include screenshots. Screen recordings are particularly helpful, and appreciated! ]

Testing instructions

[ For new or modified features, provide step-by-step testing instructions to validate the intended behavior of the change, including any relevant tests to run. ]


Summary by mrge

Fixed parsing of server-sent events to handle both "data:[DONE]" (no space) and "data: [DONE]" (with space) as valid stream end markers.

although https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#request-body says

>stream    boolean    Whether to stream back partial progress. If set, tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message

but what I see is `data:[DONE]` (without space), e.g.

```
curl -q --location 'http://localhost:8080/openai/deployments/gpt-4o/chat/completions?api-version=2023-07-01-preview' \
--header 'Authorization: Bearer <token>' \
--header 'X-Forwarded-Client-Cert: secret' \
--header 'Content-Type: application/json' \
--data '{
    "stream": true,
    "messages": [
        {
            "role": "user",
            "content": "hello."
        }
    ]
}'
data:{"choices":[],"created":0,"id":"","model":"","object":"","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}]}

data:{"choices":[{"content_filter_results":{},"delta":{"refusal":null,"role":"assistant"},"finish_reason":null,"index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}
...
data:{"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"delta":{"content":"?"},"finish_reason":null,"index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}

data:{"choices":[{"content_filter_results":{},"delta":{},"finish_reason":"stop","index":0}],"created":1746741184,"id":"chatcmpl-BV3SqfEtCuk3f8fW5x7azEkELkJZ0","model":"gpt-4o-2024-05-13","object":"chat.completion.chunk","system_fingerprint":"fp_ee1d74bde0"}

data:[DONE]
```
@zyxue zyxue requested a review from a team as a code owner May 8, 2025 22:13
@zyxue zyxue requested review from tomasz-stefaniak and removed request for a team May 8, 2025 22:13
@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label May 8, 2025
Copy link

netlify bot commented May 8, 2025

Deploy Preview for continuedev canceled.

Name Link
🔨 Latest commit 1ea2a10
🔍 Latest deploy log https://app.netlify.com/sites/continuedev/deploys/68221a9044f0f9000878da33

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label May 9, 2025
@Patrick-Erichsen
Copy link
Collaborator

Thanks for the fix here @zyxue ! I merged main to resolve the issue with failing e2e tests.

@Patrick-Erichsen
Copy link
Collaborator

Failing test was due to rate limiting, not an issue with the PR

Copy link
Contributor

@sestinj sestinj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zyxue Are you able to add a test or two to lock down this behavior? I think it should luckily be pretty quick to do by making core/llm/stream.test.ts and adding a few important cases with Jest

@github-project-automation github-project-automation bot moved this from Todo to In Progress in Issues and PRs May 10, 2025
@dosubot dosubot bot removed the lgtm This PR has been approved by a maintainer label May 10, 2025
@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels May 12, 2025
@zyxue
Copy link
Author

zyxue commented May 12, 2025

what's the relationship between the stream.ts in core and packages?

@zyxue
Copy link
Author

zyxue commented May 12, 2025

@zyxue Are you able to add a test or two to lock down this behavior? I think it should luckily be pretty quick to do by making core/llm/stream.test.ts and adding a few important cases with Jest

I'm not very fluent with typescript, does that require prefixing export to the parseSseLine function?

@Patrick-Erichsen
Copy link
Collaborator

@zyxue looks like tests are failing in CI due to a few syntax errors: https://github.com/continuedev/continue/actions/runs/14976915270/job/42071499598?pr=5580#step:8:9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:M This PR changes 30-99 lines, ignoring generated files.
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

3 participants