feat(provider): add OpenCode Zen provider with multi-backend routing and cost tracking#2594
Merged
tusharmath merged 13 commits intomainfrom Mar 19, 2026
Merged
feat(provider): add OpenCode Zen provider with multi-backend routing and cost tracking#2594tusharmath merged 13 commits intomainfrom
tusharmath merged 13 commits intomainfrom
Conversation
Comment on lines
+89
to
+91
| if is_complete_usage { | ||
| // Replace with the latest complete usage | ||
| usage = *current_usage; |
Contributor
There was a problem hiding this comment.
Critical Bug: Cost data loss when cost-only event precedes complete usage event
When replacing usage with complete usage, any previously accumulated cost is lost. This occurs when a cost-only ping event arrives before a complete usage chunk.
Scenario:
- Cost-only event arrives:
usage.cost = Some(0.005) - Complete usage event arrives:
usage = *current_usage(which hascost: None) - Result: The cost from step 1 is lost
if is_complete_usage {
// Replace with the latest complete usage, but preserve cost if already set
let existing_cost = usage.cost;
usage = *current_usage;
if usage.cost.is_none() && existing_cost.is_some() {
usage.cost = existing_cost;
}
}The existing test test_into_full_cost_only_event_adds_cost_to_usage only validates cost-only events AFTER complete usage, not before.
Suggested change
| if is_complete_usage { | |
| // Replace with the latest complete usage | |
| usage = *current_usage; | |
| if is_complete_usage { | |
| // Replace with the latest complete usage, but preserve cost if already set | |
| let existing_cost = usage.cost; | |
| usage = *current_usage; | |
| if usage.cost.is_none() && existing_cost.is_some() { | |
| usage.cost = existing_cost; | |
| } | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add OpenCode Zen provider with intelligent multi-backend routing and cost tracking via ping events.
Context
OpenCode Zen (opencode.ai) provides a unified API endpoint that aggregates multiple LLM providers (Anthropic, OpenAI, Google, and others). While it appears to be OpenAI-compatible, it requires specialized handling that cannot be achieved with a standard OpenAI-compatible provider for several critical reasons:
Why a New Provider Was Needed
1. Multi-Backend Routing by Model Prefix
OpenCode Zen routes requests to different backends based on the model name:
claude-*models → Anthropic Messages API (/v1/messages)gpt-5*models → OpenAI Responses API (/v1/responses)gemini-*models → Google API (/v1)/v1/chat/completions)Each backend has different endpoint URLs, request/response formats, and streaming behaviors. A simple OpenAI-compatible provider cannot handle this routing complexity.
2. Non-Standard SSE Content Types
The Anthropic backend returns Server-Sent Events with non-standard content types that fail
reqwest-eventsource's validation. The provider must detect this and fall back to raw byte streaming with manual SSE parsing.3. Cost-Bearing Ping Events
OpenCode Zen injects custom
pingevents into the stream that carry cost information:{"type":"ping","cost":"0.00675010"}These must be captured and forwarded as usage data. Standard OpenAI-compatible providers would fail on these unknown event types.
4. Response Type Variations
Different backends return different response structures:
content_block_deltaeventsChanges
New OpenCode Zen Provider (
opencode_zen.rs)OpenAI Responses Enhancements
pingevent handling for cost tracking from proxy serversUnknownevent variant to silently ignore unrecognized eventsStreamItemenum to handle both standard events and pre-resolved messagesAnthropic Provider Updates
should_use_raw_sse()detection for OpenCode Zenchat_raw_sse()for manual SSE parsing when content-type validation would faileventsource_streamcrate for raw byte SSE parsingContext Reasoning Fix
append_message()now accepts bothreasoning(flat string) andreasoning_details(structured)Provider Configuration
provider.jsonwith 20+ models across all backendsLinks