openclaw-navigator 5.7.5 → 5.7.6

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.
Files changed (2) hide show
  1. package/cli.mjs +22 -65
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -1216,7 +1216,8 @@ function handleRequest(req, res) {
1216
1216
  chatHistory.unshift({ role: "user", content: message });
1217
1217
  }
1218
1218
  const proxyBody = JSON.stringify({
1219
- messages: chatHistory,
1219
+ message: message, // BFF expects "message" (singular) — the current user text
1220
+ messages: chatHistory, // Also send full history for OpenAI-compatible endpoints
1220
1221
  stream: true,
1221
1222
  });
1222
1223
  // Build cookie header: prefer captured BFF cookies, fall back to browser's cookies
@@ -1612,77 +1613,33 @@ function handleRequest(req, res) {
1612
1613
  return;
1613
1614
  }
1614
1615
 
1615
- // ── SSE→JSON for streaming endpoints (/api/chat) ──────────────────
1616
- // The BFF returns SSE but the web UI's parser can't handle SSE through
1617
- // a reverse proxy (it does JSON.parse on raw chunks without stripping
1618
- // the "data: " prefix). So we collect the full SSE stream, extract the
1619
- // text, and return a single JSON response. Also store + broadcast via WS.
1616
+ // ── SSE passthrough for streaming endpoints (/api/chat) ────────────
1617
+ // Pass SSE through as-is the web UI frontend handles SSE natively.
1618
+ // Disable response buffering so each SSE event reaches the client immediately.
1620
1619
  if (isSSE && isStreamingEndpoint) {
1621
- console.log(` ${DIM}SSE→JSON collect: ${path}${RESET}`);
1620
+ console.log(` ${DIM}SSE passthrough: ${path}${RESET}`);
1622
1621
 
1623
- let fullText = "";
1624
- let sseData = "";
1622
+ // Ensure SSE headers are clean for the browser
1623
+ headers["cache-control"] = "no-cache";
1624
+ headers["connection"] = "keep-alive";
1625
+ // Keep content-type as text/event-stream
1626
+ delete headers["content-length"]; // SSE is chunked
1625
1627
 
1626
- proxyRes.setEncoding("utf-8");
1628
+ res.writeHead(proxyRes.statusCode ?? 200, headers);
1629
+
1630
+ // Disable buffering at every layer
1631
+ if (res.socket) res.socket.setNoDelay(true);
1632
+
1633
+ // Pipe SSE events directly — no transformation
1627
1634
  proxyRes.on("data", (chunk) => {
1628
- sseData += chunk;
1635
+ res.write(chunk);
1636
+ // Flush after each chunk to prevent TCP buffering
1637
+ if (typeof res.flush === "function") res.flush();
1629
1638
  });
1630
1639
 
1631
1640
  proxyRes.on("end", () => {
1632
- // Extract text from all SSE events
1633
- for (const line of sseData.split("\n")) {
1634
- if (line.startsWith("data: ")) {
1635
- const raw = line.slice(6).trim();
1636
- if (raw === "[DONE]" || !raw) continue;
1637
- try {
1638
- const evt = JSON.parse(raw);
1639
- const delta =
1640
- evt.choices?.[0]?.delta?.content ||
1641
- evt.delta?.text ||
1642
- evt.text ||
1643
- evt.content ||
1644
- "";
1645
- if (delta) fullText += delta;
1646
- } catch {
1647
- if (raw) fullText += raw;
1648
- }
1649
- }
1650
- }
1651
-
1652
- // Return as a single OpenAI-compatible JSON response
1653
- const result = {
1654
- id: "chatcmpl_bridge_" + Date.now(),
1655
- object: "chat.completion",
1656
- created: Math.floor(Date.now() / 1000),
1657
- choices: [{
1658
- index: 0,
1659
- message: { role: "assistant", content: fullText },
1660
- finish_reason: "stop",
1661
- }],
1662
- };
1663
-
1664
- headers["content-type"] = "application/json";
1665
- delete headers["content-length"];
1666
- delete headers["transfer-encoding"];
1667
- res.writeHead(200, headers);
1668
- res.end(JSON.stringify(result));
1669
-
1670
- // Broadcast via WebSocket for live updates (but DON'T store in
1671
- // bridge chat session — web UI manages its own conversation state
1672
- // separately from sidepane chat. Mixing them causes 400 errors from
1673
- // the BFF due to malformed message history.)
1674
- if (fullText) {
1675
- broadcastToWS({
1676
- type: "chat.webui",
1677
- text: fullText,
1678
- content: fullText,
1679
- role: "assistant",
1680
- timestamp: Date.now(),
1681
- });
1682
- console.log(` ${GREEN}✓${RESET} Chat response (${fullText.length} chars): ${fullText.substring(0, 80)}...`);
1683
- } else {
1684
- console.log(` ${DIM}SSE stream ended with no content${RESET}`);
1685
- }
1641
+ res.end();
1642
+ console.log(` ${GREEN}✓${RESET} SSE stream completed for ${path}`);
1686
1643
  });
1687
1644
 
1688
1645
  proxyRes.on("error", (err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-navigator",
3
- "version": "5.7.5",
3
+ "version": "5.7.6",
4
4
  "description": "One-command bridge + tunnel for the Navigator browser — works on any machine, any OS",
5
5
  "keywords": [
6
6
  "browser",