Skip to content

agent: Share compatible Chat Completions infrastructure - #62652

Merged
anantdgoel merged 2 commits into
mainfrom
feat/openai-compatible-chat-completions
Aug 14, 2026
Merged

agent: Share compatible Chat Completions infrastructure#62652
anantdgoel merged 2 commits into
mainfrom
feat/openai-compatible-chat-completions

Conversation

@anantdgoel

@anantdgoel anantdgoel commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

OpenAI-compatible providers currently cannot reuse Zed's OpenAI Chat Completions transport unless they also adopt the exact OpenAI request and response types. OpenRouter therefore maintained its own copy of request construction, authentication, status handling, response reading, and server-sent event framing.

This change extracts that mechanical transport into two provider-neutral functions in open_ai: one for streaming requests and one for non-streaming requests. They accept any serializable request envelope, preserve custom headers and provider names, return untyped JSON for provider-specific decoding, and retain typed failures for serialization, request construction, HTTP transport, response reading, and deserialization. The existing OpenAI entry points remain as compatibility wrappers, so existing callers keep the same API and behavior.

The abstraction deliberately stops at the wire boundary. OpenRouter continues to own its request and response schemas, attribution headers, routing controls, cache placement, and API-specific error interpretation. It now adapts the shared framed stream into those OpenRouter types instead of implementing a second HTTP and server-sent event stack.

Moving OpenRouter onto the shared path also requires the ordinary Chat Completions schema and event mapper to preserve compatible metadata that OpenRouter already emits. This includes structured reasoning details needed for replay, fragmented reasoning accumulation, prompt-cache read and write usage, and thought signatures attached to tool calls. The stream exposes [DONE] explicitly rather than treating it as indistinguishable from an unexpected end of the response body. OpenRouter's routing session identifier is hashed before transmission so Zed's internal thread identifier is not exposed.

The diff is larger than the extracted transport alone because the shared API is additive, the compatibility metadata must be represented in the common wire types and event mapper, and the provider-specific adapter remains intentionally independent. Roughly four hundred added lines are focused transport, metadata, error-classification, attribution, caching, and privacy tests. The provider-level OpenRouter implementation becomes smaller while preserving its existing behavior.

Testing performed:

  • cargo test -p open_ai
  • cargo test -p open_router
  • cargo nextest run -p language_models open_router
  • cargo check -p edit_prediction -p edit_prediction_cli
  • cargo fmt --all -- --check
  • ./script/clippy -p open_ai -p open_router -p language_models -p edit_prediction_cli
  • cargo machete

Release Notes:

  • Improved OpenRouter reasoning continuity and request privacy.

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Aug 14, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label Aug 14, 2026
@anantdgoel
anantdgoel force-pushed the feat/openai-compatible-chat-completions branch from 0b5f4f3 to 154d673 Compare August 14, 2026 20:32
@anantdgoel anantdgoel changed the title open_ai: Share compatible Chat Completions infrastructure openai: Share compatible Chat Completions infrastructure Aug 14, 2026
@anantdgoel anantdgoel changed the title openai: Share compatible Chat Completions infrastructure agent: Share compatible Chat Completions infrastructure Aug 14, 2026
@anantdgoel
anantdgoel force-pushed the feat/openai-compatible-chat-completions branch from 154d673 to cde9ce1 Compare August 14, 2026 20:52

@eholk eholk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks good to me. I pushed a small follow-up to use an async closure for the stream state machine and move the shared transport tests into their own file.

@anantdgoel
anantdgoel added this pull request to the merge queue Aug 14, 2026
Merged via the queue into main with commit 9f164a0 Aug 14, 2026
36 checks passed
@anantdgoel
anantdgoel deleted the feat/openai-compatible-chat-completions branch August 14, 2026 22:46
playdohface pushed a commit to playdohface/zed that referenced this pull request Aug 29, 2026
…es#62652)

OpenAI-compatible providers currently cannot reuse Zed's OpenAI Chat
Completions transport unless they also adopt the exact OpenAI request
and response types. OpenRouter therefore maintained its own copy of
request construction, authentication, status handling, response reading,
and server-sent event framing.

This change extracts that mechanical transport into two provider-neutral
functions in `open_ai`: one for streaming requests and one for
non-streaming requests. They accept any serializable request envelope,
preserve custom headers and provider names, return untyped JSON for
provider-specific decoding, and retain typed failures for serialization,
request construction, HTTP transport, response reading, and
deserialization. The existing OpenAI entry points remain as
compatibility wrappers, so existing callers keep the same API and
behavior.

The abstraction deliberately stops at the wire boundary. OpenRouter
continues to own its request and response schemas, attribution headers,
routing controls, cache placement, and API-specific error
interpretation. It now adapts the shared framed stream into those
OpenRouter types instead of implementing a second HTTP and server-sent
event stack.

Moving OpenRouter onto the shared path also requires the ordinary Chat
Completions schema and event mapper to preserve compatible metadata that
OpenRouter already emits. This includes structured reasoning details
needed for replay, fragmented reasoning accumulation, prompt-cache read
and write usage, and thought signatures attached to tool calls. The
stream exposes `[DONE]` explicitly rather than treating it as
indistinguishable from an unexpected end of the response body.
OpenRouter's routing session identifier is hashed before transmission so
Zed's internal thread identifier is not exposed.

The diff is larger than the extracted transport alone because the shared
API is additive, the compatibility metadata must be represented in the
common wire types and event mapper, and the provider-specific adapter
remains intentionally independent. Roughly four hundred added lines are
focused transport, metadata, error-classification, attribution, caching,
and privacy tests. The provider-level OpenRouter implementation becomes
smaller while preserving its existing behavior.

Testing performed:

- `cargo test -p open_ai`
- `cargo test -p open_router`
- `cargo nextest run -p language_models open_router`
- `cargo check -p edit_prediction -p edit_prediction_cli`
- `cargo fmt --all -- --check`
- `./script/clippy -p open_ai -p open_router -p language_models -p
edit_prediction_cli`
- `cargo machete`

Release Notes:

- Improved OpenRouter reasoning continuity and request privacy.

---------

Co-authored-by: Eric Holk <eric@zed.dev>
azeemshaik025 pushed a commit to azeemshaik025/zed that referenced this pull request Sep 2, 2026
Closes zed-industries#63314
Closes zed-industries#42584

Follow-up to zed-industries#62652

Removes a lot of duplicated code in favor of throwing it
into`language_core` as well as removing duplicate struct definitions
that were only different because of entirely unused fields.

Furthermore, improves error-messages so that these untagged enum errors
are no longer a thing in an effort to make this more maintainable in the
future.

Lastly, includes a small but nice improvement changing a `Value` to a
`RawValue` so that we don't have to clone for deserialization in that
specific case.

Release Notes:

- Improved streaming for OpenAI-compatible providers.

---------

Co-authored-by: Anant Goel <anant@zed.dev>
whitecat1331 pushed a commit to whitecat1331/zed that referenced this pull request Sep 3, 2026
Closes zed-industries#63314
Closes zed-industries#42584

Follow-up to zed-industries#62652

Removes a lot of duplicated code in favor of throwing it
into`language_core` as well as removing duplicate struct definitions
that were only different because of entirely unused fields.

Furthermore, improves error-messages so that these untagged enum errors
are no longer a thing in an effort to make this more maintainable in the
future.

Lastly, includes a small but nice improvement changing a `Value` to a
`RawValue` so that we don't have to clone for deserialization in that
specific case.

Release Notes:

- Improved streaming for OpenAI-compatible providers.

---------

Co-authored-by: Anant Goel <anant@zed.dev>
mchappell42 pushed a commit to mchappell42/zed-multi-agent that referenced this pull request Sep 4, 2026
Closes zed-industries#63314
Closes zed-industries#42584

Follow-up to zed-industries#62652

Removes a lot of duplicated code in favor of throwing it
into`language_core` as well as removing duplicate struct definitions
that were only different because of entirely unused fields.

Furthermore, improves error-messages so that these untagged enum errors
are no longer a thing in an effort to make this more maintainable in the
future.

Lastly, includes a small but nice improvement changing a `Value` to a
`RawValue` so that we don't have to clone for deserialization in that
specific case.

Release Notes:

- Improved streaming for OpenAI-compatible providers.

---------

Co-authored-by: Anant Goel <anant@zed.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants