Bobo db7d5ddd19 Skip [DONE] stream terminator in anthropic and google_ai SSE parsers (#61627)
## Problem

When `api_url` points to a proxy or gateway that appends `data: [DONE]`
to the SSE stream, every streaming completion fails with:

```
error deserializing Anthropic API response: expected value at line 1 column 2
```

In the UI this surfaces as **"error deserializing Anthropic API response
— Retrying (Attempt 3 of 3)"** followed by **"Connection Interrupted"**,
even though the proxy returned a well-formed stream and the model's full
response was already delivered before the terminator. The failure is
100% reproducible on multi-turn tool-use conversations (Zed reads the
stream to completion after each turn, so it always reaches the trailing
`[DONE]`) and intermittent on single-turn conversations (depending on
whether the connection closes before the line is read). The same class
of error appears in the `google_ai` crate as `Error parsing JSON: ...
"[DONE]"`.

Neither side is at fault here. Zed's current parser is a correct
implementation of the Anthropic and Gemini specs, which terminate
streams by connection close and never emit `[DONE]`; at the same time,
appending a `[DONE]` terminator is a common, legitimate convention among
SSE gateways. This PR is a compatibility improvement that makes Zed
robust to that widely-used stream shape, so streaming works whether or
not the upstream emits the terminator.

## Why Zed crashes but the Anthropic SDK does not

The Anthropic TypeScript and Python SDKs handle this correctly
**without** any explicit `[DONE]` check. Their SSE parser uses a
two-layer architecture:

1. **SSE framing layer** — parses `event:` / `data:` fields into
`{event, data}` objects without inspecting the data payload.
2. **Event dispatch layer** — only calls `JSON.parse` on events whose
`event` name is in a known whitelist (`message_start`,
`content_block_delta`, etc.). A bare `data:` line with no preceding
`event:` line yields `event: null`, which is not in the whitelist and is
silently ignored.

So when a proxy sends `data: [DONE]`, the SDK produces `{event: null,
data: "[DONE]"}`, the dispatch layer drops it, and `JSON.parse` is never
run on `[DONE]`. Claude Code and Cline both use the Anthropic SDK under
the hood, so they inherit this behavior and never crash on `[DONE]`.

Zed's `anthropic` and `google_ai` crates use a simpler single-layer
parser: strip the `data:` prefix, then unconditionally
`serde_json::from_str` the remainder. There is no event-name dispatch,
so `[DONE]` goes straight into the JSON parser — `[` looks like an array
start, `D` is not a valid value, serde reports `expected value at line 1
column 2`, and the stream dies.

## Fix

Add a one-line guard after prefix stripping: if the trimmed payload is
`[DONE]`, return `None` from the `filter_map` closure. This is a
lightweight equivalent of the SDK's whitelist-ignore behavior — same
result (silently skip the terminator), without restructuring the parser
into a full event-name dispatch architecture.

Two commits, one per crate:

1. `anthropic` — guard in `stream_completion_with_rate_limit_info`
2. `google_ai` — identical guard in `stream_generate_content`

## Scope

The other ten SSE-based providers in this repo (`open_ai`, `deepseek`,
`mistral`, `open_router`, `lmstudio`, `llama_cpp`, `copilot_chat`)
already handle `[DONE]` because their upstream specs (OpenAI-compatible)
define it as a required stream terminator. `ollama` (NDJSON) and
`bedrock` (AWS SDK event stream) do not use SSE. After this PR, every
SSE parser in Zed handles `[DONE]` without error.

## Safety

- Official Anthropic and Gemini APIs never send `[DONE]`; the guard is a
no-op on direct connections.
- `line.trim() == "[DONE]"` handles both `data: [DONE]` and
`data:[DONE]`.
- Returning `None` drops the line silently; the stream concludes on the
next EOF as usual.

Release Notes:

- Fixed streaming completions failing with "error deserializing
Anthropic API response" when the SSE endpoint appends a `[DONE]` stream
terminator (affects custom `api_url` proxies for Anthropic and Google
Gemini)
2026-07-27 12:07:31 +00:00
2026-01-22 23:57:26 +05:30
2026-07-27 05:59:53 +00:00
WIP
2023-12-14 09:25:14 -07:00
2026-04-29 10:27:47 +00:00
2025-02-04 09:02:59 -05:00
2025-10-27 13:27:59 -04:00
2026-06-27 15:06:29 +00:00
2025-10-17 18:58:14 +00:00
2026-03-17 16:34:35 +00:00
2026-04-29 10:27:47 +00:00

Zed

Zed CI

Welcome to Zed, a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.


Installation

On macOS, Linux, and Windows you can download Zed directly or install Zed via your local package manager (macOS/Linux/Windows).

Other platforms are not yet available:

Developing Zed

Contributing

See CONTRIBUTING.md for ways you can contribute to Zed.

Also... we're hiring! Check out our jobs page for open roles.

Licensing

Zed source code is licensed primarily under GPL-3.0-or-later, with Apache-2.0 components where marked.

License information for third party dependencies must be correctly provided for CI to pass.

We use cargo-about to automatically comply with open source licenses. If CI is failing, check the following:

  • Is it showing a no license specified error for a crate you've created? If so, add publish = false under [package] in your crate's Cargo.toml.
  • Is the error failed to satisfy license requirements for a dependency? If so, first determine what license the project has and whether this system is sufficient to comply with this license's requirements. If you're unsure, ask a lawyer. Once you've verified that this system is acceptable add the license's SPDX identifier to the accepted array in script/licenses/zed-licenses.toml.
  • Is cargo-about unable to find the license for a dependency? If so, add a clarification field at the end of script/licenses/zed-licenses.toml, as specified in the cargo-about book.

Sponsorship

Zed is developed by Zed Industries, Inc., a for-profit company.

If you’d like to financially support the project, you can do so via GitHub Sponsors. Sponsorships go directly to Zed Industries and are used as general company revenue. There are no perks or entitlements associated with sponsorship.

S
Description
No description provided
Readme
411 MiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 94.9%
JSON-with-Comments 2.7%
Python 0.8%
Inno Setup 0.3%
Tree-sitter Query 0.3%
Other 0.5%