Symptom
When FastClaw talks to an OpenAI/Anthropic-compatible streaming endpoint through an LLM gateway (DeepSeek, GLM, self-hosted gateways, etc.), the model's reply is completely lost and the agent reports:
model returned an empty response
Non-gateway endpoints work fine, which makes this look random and very hard to debug.
Root cause
The SSE spec (MDN — event stream format) makes the single space after the data: field name optional:
If the value contains a leading space, it is ignored... the colon and space are both optional.
Many gateways emit data:{...} with no space. All four stream parsers match the literal prefix data: and skip every such line, so the assembled content ends up empty:
internal/provider/openai.go — ChatStream (~line 340) and parseSSE (~line 520)
internal/provider/anthropic.go — streaming loop (~line 515) and parseSSE (~line 650)
Verified with curl -N against the gateway: the body is well-formed SSE, just without the space.
Fix
Accept data: with or without the space and TrimSpace the payload — proposed in #112 (includes unit tests).
Symptom
When FastClaw talks to an OpenAI/Anthropic-compatible streaming endpoint through an LLM gateway (DeepSeek, GLM, self-hosted gateways, etc.), the model's reply is completely lost and the agent reports:
Non-gateway endpoints work fine, which makes this look random and very hard to debug.
Root cause
The SSE spec (MDN — event stream format) makes the single space after the
data:field name optional:Many gateways emit
data:{...}with no space. All four stream parsers match the literal prefixdata:and skip every such line, so the assembled content ends up empty:internal/provider/openai.go—ChatStream(~line 340) andparseSSE(~line 520)internal/provider/anthropic.go— streaming loop (~line 515) andparseSSE(~line 650)Verified with
curl -Nagainst the gateway: the body is well-formed SSE, just without the space.Fix
Accept
data:with or without the space andTrimSpacethe payload — proposed in #112 (includes unit tests).