Summary
When using Cerebras provider (both provider_type = "cerebras" and provider_type = "openai") with streaming enabled, CCM fails to properly convert OpenAI SSE format to Anthropic SSE format, resulting in malformed Server-Sent Events that Claude Code cannot parse.
Environment
- CCM Version: 0.6.3
- Provider: Cerebras (via direct API and Cloudflare Gateway)
- Client: Claude Code v2.0.50
- OS: macOS (Darwin 25.1.0)
Bug Details
Expected Behavior
When streaming is enabled, CCM should convert Cerebras/OpenAI SSE chunks to Anthropic SSE format:
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}
data: {"type":"message_stop"}
Actual Behavior
CCM outputs malformed SSE with double data: prefixes and unconverted OpenAI format:
data: data: {"id":"chatcmpl-...","choices":[{"delta":{"reasoning":"Hello"},"index":0}],"created":1764019479,"model":"zai-glm-4.6","object":"chat.completion.chunk"}
data:
data:
data: data: {"id":"chatcmpl-...","choices":[{"delta":{"reasoning":" world"},"index":0}],"created":1764019479,"model":"zai-glm-4.6","object":"chat.completion.chunk"}
data:
data:
Issues:
- ❌ Double
data: prefix: data: data: {...} instead of data: {...}
- ❌ OpenAI format unchanged: Still using
{"choices":[{"delta":...}]} instead of Anthropic format
- ❌ Extra blank lines: Adds
data: \ndata: \n between chunks
- ✅ Non-streaming works: When
stream: false, responses work correctly
Impact
- Severity: Critical
- Affects: All Cerebras users with streaming enabled
- Workaround: Disable streaming (
stream: false), but this breaks real-time response experience in Claude Code
Reproduction Steps
Configuration
[[models]]
name = "zai-glm-4.6"
[[models.mappings]]
actual_model = "zai-glm-4.6"
priority = 1
provider = "cerebras"
[[providers]]
name = "cerebras"
provider_type = "cerebras" # Also fails with "openai"
api_key = "csk-..."
models = []
enabled = true
[router]
default = "zai-glm-4.6"
Test Command
curl -N -X POST "http://127.0.0.1:13456/v1/messages" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: test" \
-d '{
"model": "zai-glm-4.6",
"max_tokens": 100,
"stream": true,
"messages": [{"role": "user", "content": "say hello"}]
}'
Result
data: data: {"id":"chatcmpl-...","choices":[{"delta":{"reasoning":"..."},"index":0}],...}
data:
data:
(continues with malformed format)
Expected vs Actual Comparison
| Aspect |
Expected (Anthropic SSE) |
Actual (CCM Output) |
| SSE Prefix |
data: {...} |
data: data: {...} ❌ |
| Format |
{"type":"content_block_delta","delta":{"type":"text_delta","text":"..."}} |
{"choices":[{"delta":{"reasoning":"..."}}]} ❌ |
| Blank Lines |
Single \n\n between events |
data: \ndata: \n after each event ❌ |
| Completeness |
Full message with proper stop event |
Stream appears complete but unparseable ❌ |
Additional Context
What Works
- ✅ Non-streaming mode (
stream: false) - Returns complete, properly formatted Anthropic response
What Fails
- ❌ Cerebras with
provider_type = "cerebras" - Malformed SSE
- ❌ Cerebras with
provider_type = "openai" - Same malformed SSE
- ❌ Both direct Cerebras API and Cloudflare Gateway - Same issue
Root Cause Hypothesis
The streaming conversion logic for Cerebras provider appears to:
- Not properly strip/replace the OpenAI
data: prefix before adding Anthropic data: prefix
- Not convert OpenAI delta format (
{"choices":[{"delta":...}]}) to Anthropic format ({"type":"content_block_delta",...})
- Add extra
data: lines creating malformed SSE
Suggested Fix
The Cerebras streaming handler should:
- Parse incoming OpenAI SSE chunks (strip
data: prefix)
- Convert OpenAI delta format to Anthropic delta format
- Re-emit as proper Anthropic SSE (with single
data: prefix)
Similar to how other OpenAI-compatible providers work (which stream correctly).
Related
- Cerebras is listed as "OpenAI-compatible" in README
- README shows ✅ streaming support for Cerebras
- This appears to be a format conversion bug, not a Cerebras API issue
Logs
Debug logs available on request. Shows successful connection to Cerebras but malformed SSE output.
Summary
When using Cerebras provider (both
provider_type = "cerebras"andprovider_type = "openai") with streaming enabled, CCM fails to properly convert OpenAI SSE format to Anthropic SSE format, resulting in malformed Server-Sent Events that Claude Code cannot parse.Environment
Bug Details
Expected Behavior
When streaming is enabled, CCM should convert Cerebras/OpenAI SSE chunks to Anthropic SSE format:
Actual Behavior
CCM outputs malformed SSE with double
data:prefixes and unconverted OpenAI format:Issues:
data:prefix:data: data: {...}instead ofdata: {...}{"choices":[{"delta":...}]}instead of Anthropic formatdata: \ndata: \nbetween chunksstream: false, responses work correctlyImpact
stream: false), but this breaks real-time response experience in Claude CodeReproduction Steps
Configuration
Test Command
Result
Expected vs Actual Comparison
data: {...}data: data: {...}❌{"type":"content_block_delta","delta":{"type":"text_delta","text":"..."}}{"choices":[{"delta":{"reasoning":"..."}}]}❌\n\nbetween eventsdata: \ndata: \nafter each event ❌Additional Context
What Works
stream: false) - Returns complete, properly formatted Anthropic responseWhat Fails
provider_type = "cerebras"- Malformed SSEprovider_type = "openai"- Same malformed SSERoot Cause Hypothesis
The streaming conversion logic for Cerebras provider appears to:
data:prefix before adding Anthropicdata:prefix{"choices":[{"delta":...}]}) to Anthropic format ({"type":"content_block_delta",...})data:lines creating malformed SSESuggested Fix
The Cerebras streaming handler should:
data:prefix)data:prefix)Similar to how other OpenAI-compatible providers work (which stream correctly).
Related
Logs
Debug logs available on request. Shows successful connection to Cerebras but malformed SSE output.