openclaw-navigator 5.7.4 → 5.7.5
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 +38 -12
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1193,10 +1193,28 @@ function handleRequest(req, res) {
|
|
|
1193
1193
|
|
|
1194
1194
|
// 3. Background: relay to BFF (port 4000) /api/chat for AI processing
|
|
1195
1195
|
// Format: OpenAI-compatible chat completions with message history
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1196
|
+
// Sanitize: BFF expects alternating user/assistant roles, starting with user.
|
|
1197
|
+
// Drop orphaned assistant messages at the start (from web UI SSE tap).
|
|
1198
|
+
let chatHistory = session.messages
|
|
1199
|
+
.map((m) => ({ role: m.role, content: m.content }))
|
|
1200
|
+
.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "system");
|
|
1201
|
+
// Ensure first non-system message is 'user' — drop leading assistant messages
|
|
1202
|
+
while (chatHistory.length > 0 && chatHistory[0].role === "assistant") {
|
|
1203
|
+
chatHistory.shift();
|
|
1204
|
+
}
|
|
1205
|
+
// Collapse consecutive same-role messages (merge them)
|
|
1206
|
+
chatHistory = chatHistory.reduce((acc, msg) => {
|
|
1207
|
+
if (acc.length > 0 && acc[acc.length - 1].role === msg.role) {
|
|
1208
|
+
acc[acc.length - 1].content += "\n" + msg.content;
|
|
1209
|
+
} else {
|
|
1210
|
+
acc.push({ ...msg });
|
|
1211
|
+
}
|
|
1212
|
+
return acc;
|
|
1213
|
+
}, []);
|
|
1214
|
+
// Must have at least one user message
|
|
1215
|
+
if (chatHistory.length === 0 || chatHistory[0].role !== "user") {
|
|
1216
|
+
chatHistory.unshift({ role: "user", content: message });
|
|
1217
|
+
}
|
|
1200
1218
|
const proxyBody = JSON.stringify({
|
|
1201
1219
|
messages: chatHistory,
|
|
1202
1220
|
stream: true,
|
|
@@ -1217,6 +1235,7 @@ function handleRequest(req, res) {
|
|
|
1217
1235
|
};
|
|
1218
1236
|
|
|
1219
1237
|
console.log(` ${DIM}→ Relaying to BFF /api/chat (port ${ocUIPort}) with ${chatHistory.length} messages${relayCookie ? " +cookie" : " NO-COOKIE"}${RESET}`);
|
|
1238
|
+
console.log(` ${DIM} Body: ${proxyBody.substring(0, 300)}${proxyBody.length > 300 ? "..." : ""}${RESET}`);
|
|
1220
1239
|
|
|
1221
1240
|
// Helper: send the relay request (with optional retry after login)
|
|
1222
1241
|
function sendBFFRelay(opts, body, retryCount = 0) {
|
|
@@ -1341,7 +1360,15 @@ function handleRequest(req, res) {
|
|
|
1341
1360
|
if (!isSSE && sseBuffer) {
|
|
1342
1361
|
try {
|
|
1343
1362
|
const jsonBody = JSON.parse(sseBuffer);
|
|
1344
|
-
|
|
1363
|
+
// Check for error response (BFF returns 400/500 with error details)
|
|
1364
|
+
if (proxyRes.statusCode >= 400) {
|
|
1365
|
+
const errMsg = jsonBody.error?.message || jsonBody.error || jsonBody.message || JSON.stringify(jsonBody);
|
|
1366
|
+
console.log(` ${RED}✗${RESET} BFF error ${proxyRes.statusCode}: ${String(errMsg).substring(0, 300)}`);
|
|
1367
|
+
// Send error to Navigator so user sees it
|
|
1368
|
+
fullText = `⚠️ Error from AI: ${String(errMsg).substring(0, 200)}`;
|
|
1369
|
+
} else {
|
|
1370
|
+
fullText = jsonBody.choices?.[0]?.message?.content || jsonBody.response || jsonBody.message || jsonBody.text || "";
|
|
1371
|
+
}
|
|
1345
1372
|
} catch {
|
|
1346
1373
|
console.log(` ${DIM}BFF returned non-JSON (${sseBuffer.length} bytes): ${sseBuffer.substring(0, 200)}${RESET}`);
|
|
1347
1374
|
}
|
|
@@ -1359,7 +1386,7 @@ function handleRequest(req, res) {
|
|
|
1359
1386
|
});
|
|
1360
1387
|
console.log(` ${GREEN}✓${RESET} AI response (${fullText.length} chars): ${fullText.substring(0, 80)}...`);
|
|
1361
1388
|
} else {
|
|
1362
|
-
console.log(` ${DIM}BFF returned no content${RESET}`);
|
|
1389
|
+
console.log(` ${DIM}BFF returned no content (status ${proxyRes.statusCode})${RESET}`);
|
|
1363
1390
|
}
|
|
1364
1391
|
});
|
|
1365
1392
|
|
|
@@ -1640,16 +1667,15 @@ function handleRequest(req, res) {
|
|
|
1640
1667
|
res.writeHead(200, headers);
|
|
1641
1668
|
res.end(JSON.stringify(result));
|
|
1642
1669
|
|
|
1643
|
-
//
|
|
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.)
|
|
1644
1674
|
if (fullText) {
|
|
1645
|
-
const session = getChatSession("main");
|
|
1646
|
-
session.messages.push({ role: "assistant", content: fullText, timestamp: Date.now() });
|
|
1647
|
-
|
|
1648
1675
|
broadcastToWS({
|
|
1649
|
-
type: "chat.
|
|
1676
|
+
type: "chat.webui",
|
|
1650
1677
|
text: fullText,
|
|
1651
1678
|
content: fullText,
|
|
1652
|
-
sessionKey: "main",
|
|
1653
1679
|
role: "assistant",
|
|
1654
1680
|
timestamp: Date.now(),
|
|
1655
1681
|
});
|