When pointing FX_GATEWAY_CHAT_URL at a custom loopback endpoint, the response streaming contract is partially documented but the FINISH event shape is not — and fx rejects every documented variant.
WHAT WORKS: we captured the request wire format (prompt array body, model in ai-language-model-id header, streaming declared in ai-language-model-streaming) and built a translating proxy that streams responses back. Rendering WORKS when we emit the AI SDK UI stream protocol (SSE with parts: start, start-step, text-start, text-delta, text-end, finish-step, finish) — the model reply visibly streams into the fx UI. A plain OpenAI-completions SSE stream (data: chunk lines + data: [DONE]) does NOT render — fx retries with StreamInterrupted — so the parts protocol appears to be the expected response shape.
WHAT FAILS: after rendering the complete streamed text, fx reports request failed: InvalidProviderFinishReason. We tried every finish-step variant we could derive from the AI SDK stream-protocol docs: bare {"type":"finish-step"}; with finishReason stop; with finishReason unknown; with providerMetadata; with usage; and the message-finish part with and without totalUsage. All rejected identically — the error name suggests fx validates the finish reason against a provider-specific enum the custom-endpoint docs never specify.
ASK: document the exact finish-step/finish event schema a custom FX_GATEWAY_CHAT_URL endpoint must emit (or relax the validation for loopback endpoints). Happy to share our proxy as a reference — it translates a standard OpenAI-compatible upstream into the request/response shapes fx expects, and everything except the terminal event already works.
CONTEXT: this is the same loopback surface as issue #439 (the zero-frame startup). The use case is routing fx inference through a self-hosted model gateway — ours translates to an internal Ollama-backed pool; the request direction works perfectly, streaming render works, only the finish handshake blocks a fully-green custom endpoint.
When pointing FX_GATEWAY_CHAT_URL at a custom loopback endpoint, the response streaming contract is partially documented but the FINISH event shape is not — and fx rejects every documented variant.
WHAT WORKS: we captured the request wire format (prompt array body, model in ai-language-model-id header, streaming declared in ai-language-model-streaming) and built a translating proxy that streams responses back. Rendering WORKS when we emit the AI SDK UI stream protocol (SSE with parts: start, start-step, text-start, text-delta, text-end, finish-step, finish) — the model reply visibly streams into the fx UI. A plain OpenAI-completions SSE stream (data: chunk lines + data: [DONE]) does NOT render — fx retries with StreamInterrupted — so the parts protocol appears to be the expected response shape.
WHAT FAILS: after rendering the complete streamed text, fx reports
request failed: InvalidProviderFinishReason. We tried every finish-step variant we could derive from the AI SDK stream-protocol docs: bare {"type":"finish-step"}; with finishReason stop; with finishReason unknown; with providerMetadata; with usage; and the message-finish part with and without totalUsage. All rejected identically — the error name suggests fx validates the finish reason against a provider-specific enum the custom-endpoint docs never specify.ASK: document the exact finish-step/finish event schema a custom FX_GATEWAY_CHAT_URL endpoint must emit (or relax the validation for loopback endpoints). Happy to share our proxy as a reference — it translates a standard OpenAI-compatible upstream into the request/response shapes fx expects, and everything except the terminal event already works.
CONTEXT: this is the same loopback surface as issue #439 (the zero-frame startup). The use case is routing fx inference through a self-hosted model gateway — ours translates to an internal Ollama-backed pool; the request direction works perfectly, streaming render works, only the finish handshake blocks a fully-green custom endpoint.