.'s avatar
. 1 month ago
I defintely want it as useful as possible 🙏🙏🙏

Replies (2)

This is what Fugu said about the unexpected error you saw. That error is a classic streaming vs. non-streaming mismatch, not a Routstr-vs-Fugu incompatibility. Here’s what’s happening in plain terms. ## What the error means The client received a streaming (SSE) response but tried to parse it as one JSON object. An OpenAI-compatible streaming response looks like this on the wire: data: {"id":"...","choices":[{"delta":{"content":"Hel"}}]} data: {"id":"...","choices":[{"delta":{"content":"lo"}}]} data: [DONE] If code then calls something like JSON.parse(body) or response.json(), it hits the literal text data: {"id"... and fails with exactly: Unexpected token 'd', "data: {"id"... is not valid JSON So the response is almost certainly fine — the client just isn’t reading it as a stream. ## The 3 likely causes (most to least common) 1. Client asked for a stream but parses it as JSON. The request included "stream": true, but the code does await response.json() instead of reading the SSE stream line-by-line. This is the #1 cause. 2. The request/tool defaults to streaming. Some UIs, SDKs, or curl copy-paste snippets set stream: true by default. The user may not realize it. 3. Upstream (Sakana Fugu) or Routstr is returning SSE even for a non-stream request. Less likely, but worth ruling out — if Fugu always streams, Routstr passes that through, and a client expecting a single JSON blob breaks. ## How to confirm quickly (no secrets in output) Two safe tests. Use placeholder values; never paste your real key. Test A — force non-streaming and expect one JSON object: curl -s https://<your-routstr-node>/v1/chat/completions \ -H "Authorization: Bearer <cashu-or-api-token>" \ -H "Content-Type: application/json" \ -d '{"model":"fugu","messages":[{"role":"user","content":"hi"}],"stream":false}' - If this returns a normal JSON object → your node works; the client just needs stream: false or proper stream handling. - If this still returns data: {...} lines → cause #3 (upstream/Routstr is forcing streaming), which needs a config/handling fix. Test B — explicitly stream and watch the SSE frames: curl -N https://<your-routstr-node>/v1/chat/completions \ -H "Authorization: Bearer <cashu-or-api-token>" \ -H "Content-Type: application/json" \ -d '{"model":"fugu","messages":[{"role":"user","content":"hi"}],"stream":true}' - You should see multiple data: {...} lines ending in data: [DONE]. That confirms streaming is working correctly and the client is the thing that must change. ## The fix (depends on what Test A shows) If Test A returns clean JSON (most likely): The client is the problem. Two options: - Easiest: send "stream": false and keep using response.json(). - Or handle the stream properly. Example (Node/JS): const res = await fetch(url, { method: "POST", headers, body }); const reader = res.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; while (true) { const { value, done } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); for (const line of buffer.split("\n")) { const s = line.trim(); if (!s.startsWith("data:")) continue; const payload = s.slice(5).trim(); if (payload === "[DONE]") break; const json = JSON.parse(payload); // parse each frame, not the whole body process.stdout.write(json.choices?.[0]?.delta?.content ?? ""); } } With the OpenAI SDK, just use the streaming iterator instead of awaiting a single response: const stream = await client.chat.completions.create({ model: "fugu", messages, stream: true }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ""); } If Test A still streams (cause #3): Then the node/upstream is forcing SSE. In that case I’d want to check how your Routstr node is configured and how Fugu is being called, because Routstr should honor the client’s stream flag rather than always streaming. ## Question so I can pin it down Can you tell me: 1. What is the client? (a website/chat UI, the OpenAI SDK, curl, LangChain, something else?) 2. Was stream: true set in the request (or is it a UI you don’t control)? 3. Can you run Test A above and tell me whether it returns clean JSON or data: {...} lines? That single Test A result tells us definitively whether this is a client-side parsing bug (easy) or a node/upstream streaming config issue (needs a look at your Routstr + Fugu setup).