openclaw-navigator 5.6.1 → 5.6.2
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 +43 -71
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1136,12 +1136,12 @@ function handleRequest(req, res) {
|
|
|
1136
1136
|
return;
|
|
1137
1137
|
}
|
|
1138
1138
|
|
|
1139
|
-
// ── Chat send: store locally +
|
|
1140
|
-
//
|
|
1141
|
-
//
|
|
1142
|
-
//
|
|
1143
|
-
//
|
|
1144
|
-
//
|
|
1139
|
+
// ── Chat send: store locally + respond immediately ─────────────────────
|
|
1140
|
+
// 1. Store user message in bridge memory (for MCP tools to read)
|
|
1141
|
+
// 2. Respond to Navigator immediately (don't block on gateway)
|
|
1142
|
+
// 3. In background: try relaying to gateway for AI processing
|
|
1143
|
+
// - If gateway responds → store assistant message + broadcast via WS
|
|
1144
|
+
// - If gateway hangs/fails → agent will respond via MCP tools later
|
|
1145
1145
|
if (path === "/api/sessions/send" && req.method === "POST") {
|
|
1146
1146
|
readBody(req)
|
|
1147
1147
|
.then((bodyStr) => {
|
|
@@ -1167,25 +1167,22 @@ function handleRequest(req, res) {
|
|
|
1167
1167
|
content: message,
|
|
1168
1168
|
timestamp: Date.now(),
|
|
1169
1169
|
});
|
|
1170
|
-
broadcastToWS({
|
|
1171
|
-
type: "chat.user",
|
|
1172
|
-
text: message,
|
|
1173
|
-
content: message,
|
|
1174
|
-
sessionKey,
|
|
1175
|
-
role: "user",
|
|
1176
|
-
timestamp: Date.now(),
|
|
1177
|
-
});
|
|
1178
1170
|
console.log(` ${DIM}Chat send [${sessionKey}]: ${message.substring(0, 60)}...${RESET}`);
|
|
1179
1171
|
|
|
1180
|
-
// 2.
|
|
1172
|
+
// 2. Respond immediately — don't block Navigator
|
|
1173
|
+
sendJSON(res, 200, { ok: true, stored: true, messageCount: session.messages.length });
|
|
1174
|
+
|
|
1175
|
+
// 3. Background: relay to gateway for AI processing
|
|
1176
|
+
const proxyBody = JSON.stringify({ message, sessionKey });
|
|
1181
1177
|
const proxyOpts = {
|
|
1182
1178
|
hostname: "127.0.0.1",
|
|
1183
1179
|
port: ocGatewayPort,
|
|
1184
1180
|
path: `/api/sessions/send`,
|
|
1185
1181
|
method: "POST",
|
|
1182
|
+
timeout: 60000, // 60s — agent may take a while to respond
|
|
1186
1183
|
headers: {
|
|
1187
1184
|
"content-type": "application/json",
|
|
1188
|
-
"content-length": Buffer.byteLength(
|
|
1185
|
+
"content-length": Buffer.byteLength(proxyBody),
|
|
1189
1186
|
},
|
|
1190
1187
|
};
|
|
1191
1188
|
|
|
@@ -1194,10 +1191,9 @@ function handleRequest(req, res) {
|
|
|
1194
1191
|
const isSSE = contentType.includes("text/event-stream");
|
|
1195
1192
|
|
|
1196
1193
|
if (isSSE) {
|
|
1197
|
-
//
|
|
1194
|
+
// SSE response: collect stream, broadcast chunks via WebSocket
|
|
1198
1195
|
let fullText = "";
|
|
1199
1196
|
let buffer = "";
|
|
1200
|
-
|
|
1201
1197
|
proxyRes.setEncoding("utf-8");
|
|
1202
1198
|
proxyRes.on("data", (chunk) => {
|
|
1203
1199
|
buffer += chunk;
|
|
@@ -1227,7 +1223,6 @@ function handleRequest(req, res) {
|
|
|
1227
1223
|
}
|
|
1228
1224
|
}
|
|
1229
1225
|
});
|
|
1230
|
-
|
|
1231
1226
|
proxyRes.on("end", () => {
|
|
1232
1227
|
if (buffer.startsWith("data: ")) {
|
|
1233
1228
|
const raw = buffer.slice(6).trim();
|
|
@@ -1241,12 +1236,7 @@ function handleRequest(req, res) {
|
|
|
1241
1236
|
}
|
|
1242
1237
|
}
|
|
1243
1238
|
if (fullText) {
|
|
1244
|
-
|
|
1245
|
-
session.messages.push({
|
|
1246
|
-
role: "assistant",
|
|
1247
|
-
content: fullText,
|
|
1248
|
-
timestamp: Date.now(),
|
|
1249
|
-
});
|
|
1239
|
+
session.messages.push({ role: "assistant", content: fullText, timestamp: Date.now() });
|
|
1250
1240
|
broadcastToWS({
|
|
1251
1241
|
type: "chat.final",
|
|
1252
1242
|
text: fullText,
|
|
@@ -1255,69 +1245,51 @@ function handleRequest(req, res) {
|
|
|
1255
1245
|
role: "assistant",
|
|
1256
1246
|
timestamp: Date.now(),
|
|
1257
1247
|
});
|
|
1258
|
-
console.log(` ${
|
|
1248
|
+
console.log(` ${GREEN}✓${RESET} Gateway SSE response: ${fullText.substring(0, 80)}...`);
|
|
1259
1249
|
}
|
|
1260
|
-
sendJSON(res, 200, {
|
|
1261
|
-
ok: true,
|
|
1262
|
-
stored: true,
|
|
1263
|
-
response: fullText || null,
|
|
1264
|
-
source: "gateway-sse",
|
|
1265
|
-
});
|
|
1266
|
-
});
|
|
1267
|
-
|
|
1268
|
-
proxyRes.on("error", () => {
|
|
1269
|
-
sendJSON(res, 200, { ok: true, stored: true, response: null, source: "gateway-sse-error" });
|
|
1270
1250
|
});
|
|
1251
|
+
proxyRes.on("error", () => {});
|
|
1271
1252
|
} else {
|
|
1272
|
-
//
|
|
1253
|
+
// JSON response from gateway
|
|
1273
1254
|
const chunks = [];
|
|
1274
1255
|
proxyRes.on("data", (c) => chunks.push(c));
|
|
1275
1256
|
proxyRes.on("end", () => {
|
|
1276
1257
|
const body = Buffer.concat(chunks).toString("utf-8");
|
|
1277
|
-
let jsonBody;
|
|
1278
1258
|
try {
|
|
1279
|
-
jsonBody = JSON.parse(body);
|
|
1259
|
+
const jsonBody = JSON.parse(body);
|
|
1260
|
+
const inlineResponse =
|
|
1261
|
+
jsonBody.response || jsonBody.message || jsonBody.answer || jsonBody.text || "";
|
|
1262
|
+
if (inlineResponse) {
|
|
1263
|
+
session.messages.push({ role: "assistant", content: inlineResponse, timestamp: Date.now() });
|
|
1264
|
+
broadcastToWS({
|
|
1265
|
+
type: "chat.final",
|
|
1266
|
+
text: inlineResponse,
|
|
1267
|
+
content: inlineResponse,
|
|
1268
|
+
sessionKey,
|
|
1269
|
+
role: "assistant",
|
|
1270
|
+
timestamp: Date.now(),
|
|
1271
|
+
});
|
|
1272
|
+
console.log(` ${GREEN}✓${RESET} Gateway JSON response: ${inlineResponse.substring(0, 80)}...`);
|
|
1273
|
+
} else {
|
|
1274
|
+
console.log(` ${DIM}Gateway returned JSON with no response field — waiting for MCP${RESET}`);
|
|
1275
|
+
}
|
|
1280
1276
|
} catch {
|
|
1281
|
-
|
|
1282
|
-
sendJSON(res, 200, { ok: true, stored: true, response: null, source: "gateway-raw" });
|
|
1283
|
-
return;
|
|
1284
|
-
}
|
|
1285
|
-
// Check if gateway returned an inline AI response
|
|
1286
|
-
const inlineResponse =
|
|
1287
|
-
jsonBody.response || jsonBody.message || jsonBody.answer || jsonBody.text || "";
|
|
1288
|
-
if (inlineResponse) {
|
|
1289
|
-
session.messages.push({
|
|
1290
|
-
role: "assistant",
|
|
1291
|
-
content: inlineResponse,
|
|
1292
|
-
timestamp: Date.now(),
|
|
1293
|
-
});
|
|
1294
|
-
broadcastToWS({
|
|
1295
|
-
type: "chat.final",
|
|
1296
|
-
text: inlineResponse,
|
|
1297
|
-
content: inlineResponse,
|
|
1298
|
-
sessionKey,
|
|
1299
|
-
role: "assistant",
|
|
1300
|
-
timestamp: Date.now(),
|
|
1301
|
-
});
|
|
1302
|
-
console.log(` ${DIM}Gateway inline→WS: ${inlineResponse.substring(0, 80)}...${RESET}`);
|
|
1277
|
+
console.log(` ${DIM}Gateway returned non-JSON — waiting for MCP${RESET}`);
|
|
1303
1278
|
}
|
|
1304
|
-
sendJSON(res, 200, {
|
|
1305
|
-
ok: true,
|
|
1306
|
-
stored: true,
|
|
1307
|
-
response: inlineResponse || null,
|
|
1308
|
-
source: "gateway-json",
|
|
1309
|
-
});
|
|
1310
1279
|
});
|
|
1311
1280
|
}
|
|
1312
1281
|
});
|
|
1313
1282
|
|
|
1283
|
+
proxyReq.on("timeout", () => {
|
|
1284
|
+
proxyReq.destroy();
|
|
1285
|
+
console.log(` ${DIM}Gateway relay timed out — agent will respond via MCP${RESET}`);
|
|
1286
|
+
});
|
|
1287
|
+
|
|
1314
1288
|
proxyReq.on("error", (err) => {
|
|
1315
|
-
|
|
1316
|
-
console.log(` ${DIM}Gateway not reachable (${err.message}) — message stored for MCP polling${RESET}`);
|
|
1317
|
-
sendJSON(res, 200, { ok: true, stored: true, response: null, source: "local-only" });
|
|
1289
|
+
console.log(` ${DIM}Gateway relay failed (${err.message}) — agent will respond via MCP${RESET}`);
|
|
1318
1290
|
});
|
|
1319
1291
|
|
|
1320
|
-
proxyReq.write(
|
|
1292
|
+
proxyReq.write(proxyBody);
|
|
1321
1293
|
proxyReq.end();
|
|
1322
1294
|
})
|
|
1323
1295
|
.catch(() => sendJSON(res, 400, { ok: false, error: "Bad request body" }));
|