openclaw-navigator 5.7.7 → 5.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.mjs +13 -50
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1613,63 +1613,26 @@ function handleRequest(req, res) {
|
|
|
1613
1613
|
return;
|
|
1614
1614
|
}
|
|
1615
1615
|
|
|
1616
|
-
// ── SSE
|
|
1617
|
-
//
|
|
1618
|
-
//
|
|
1619
|
-
//
|
|
1620
|
-
// forward clean JSON lines (NDJSON), one per write, flushed immediately.
|
|
1616
|
+
// ── SSE for streaming endpoints (/api/chat) ──────────────────────
|
|
1617
|
+
// Log the first chunk to see what the BFF actually sends (once per request).
|
|
1618
|
+
// Then pipe raw. The frontend's JSON parse error on "data: ..." suggests it
|
|
1619
|
+
// doesn't handle SSE format — log what's actually happening.
|
|
1621
1620
|
if (isSSE && isStreamingEndpoint) {
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
// Send as NDJSON (application/x-ndjson) so the frontend gets
|
|
1625
|
-
// one clean JSON object per line, no SSE framing.
|
|
1626
|
-
headers["content-type"] = "application/x-ndjson";
|
|
1627
|
-
headers["cache-control"] = "no-cache";
|
|
1628
|
-
headers["connection"] = "keep-alive";
|
|
1629
|
-
delete headers["content-length"];
|
|
1630
|
-
delete headers["transfer-encoding"];
|
|
1631
|
-
|
|
1632
|
-
res.writeHead(200, headers);
|
|
1633
|
-
if (res.socket) res.socket.setNoDelay(true);
|
|
1634
|
-
|
|
1635
|
-
let sseLineBuf = "";
|
|
1636
|
-
proxyRes.setEncoding("utf-8");
|
|
1621
|
+
let logged = false;
|
|
1622
|
+
res.writeHead(proxyRes.statusCode ?? 200, headers);
|
|
1637
1623
|
proxyRes.on("data", (chunk) => {
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
for (const line of lines) {
|
|
1643
|
-
if (line.startsWith("data: ")) {
|
|
1644
|
-
const payload = line.slice(6).trim();
|
|
1645
|
-
if (payload === "[DONE]") {
|
|
1646
|
-
res.write("data: [DONE]\n\n");
|
|
1647
|
-
} else if (payload) {
|
|
1648
|
-
// Write clean JSON + newline — one object per write
|
|
1649
|
-
res.write(payload + "\n");
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
// Skip empty lines, "event:", "id:", "retry:" etc.
|
|
1624
|
+
if (!logged) {
|
|
1625
|
+
const preview = (typeof chunk === "string" ? chunk : chunk.toString("utf-8")).substring(0, 300);
|
|
1626
|
+
console.log(` ${DIM}SSE first chunk (${chunk.length} bytes): ${preview.replace(/\n/g, "\\n")}${RESET}`);
|
|
1627
|
+
logged = true;
|
|
1653
1628
|
}
|
|
1654
|
-
|
|
1629
|
+
res.write(chunk);
|
|
1655
1630
|
});
|
|
1656
|
-
|
|
1657
1631
|
proxyRes.on("end", () => {
|
|
1658
|
-
// Flush remaining buffer
|
|
1659
|
-
if (sseLineBuf.startsWith("data: ")) {
|
|
1660
|
-
const payload = sseLineBuf.slice(6).trim();
|
|
1661
|
-
if (payload && payload !== "[DONE]") {
|
|
1662
|
-
res.write(payload + "\n");
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
res.end();
|
|
1666
|
-
console.log(` ${GREEN}✓${RESET} SSE→NDJSON stream completed for ${path}`);
|
|
1667
|
-
});
|
|
1668
|
-
|
|
1669
|
-
proxyRes.on("error", (err) => {
|
|
1670
|
-
console.log(` ${DIM}SSE stream error: ${err.message}${RESET}`);
|
|
1671
1632
|
res.end();
|
|
1633
|
+
console.log(` ${GREEN}✓${RESET} SSE stream completed for ${path}`);
|
|
1672
1634
|
});
|
|
1635
|
+
proxyRes.on("error", () => res.end());
|
|
1673
1636
|
return;
|
|
1674
1637
|
}
|
|
1675
1638
|
|