openclaw-navigator 5.7.7 → 5.7.8
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 +8 -56
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1613,63 +1613,15 @@ function handleRequest(req, res) {
|
|
|
1613
1613
|
return;
|
|
1614
1614
|
}
|
|
1615
1615
|
|
|
1616
|
-
// ── SSE
|
|
1617
|
-
//
|
|
1618
|
-
//
|
|
1619
|
-
//
|
|
1620
|
-
//
|
|
1616
|
+
// ── SSE for streaming endpoints (/api/chat) ──────────────────────
|
|
1617
|
+
// DO NOT transform SSE — pipe raw bytes through untouched.
|
|
1618
|
+
// The web UI works fine hitting port 4000 directly; any transformation
|
|
1619
|
+
// we add (SSE→JSON, SSE→NDJSON, setEncoding) breaks the frontend parser.
|
|
1620
|
+
// Raw binary pipe preserves the exact chunking the BFF sends.
|
|
1621
1621
|
if (isSSE && isStreamingEndpoint) {
|
|
1622
|
-
console.log(` ${DIM}SSE
|
|
1623
|
-
|
|
1624
|
-
|
|
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");
|
|
1637
|
-
proxyRes.on("data", (chunk) => {
|
|
1638
|
-
sseLineBuf += chunk;
|
|
1639
|
-
// Process complete lines
|
|
1640
|
-
const lines = sseLineBuf.split("\n");
|
|
1641
|
-
sseLineBuf = lines.pop() || ""; // keep incomplete line in buffer
|
|
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.
|
|
1653
|
-
}
|
|
1654
|
-
if (typeof res.flush === "function") res.flush();
|
|
1655
|
-
});
|
|
1656
|
-
|
|
1657
|
-
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
|
-
res.end();
|
|
1672
|
-
});
|
|
1622
|
+
console.log(` ${DIM}SSE raw pipe: ${path}${RESET}`);
|
|
1623
|
+
res.writeHead(proxyRes.statusCode ?? 200, headers);
|
|
1624
|
+
proxyRes.pipe(res, { end: true });
|
|
1673
1625
|
return;
|
|
1674
1626
|
}
|
|
1675
1627
|
|