@p697/clawket 0.6.1 → 0.6.3
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/dist/index.js +97 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5839,6 +5839,15 @@ var RELAY_CONTROL_PREFIX = "__clawket_relay_control__:";
|
|
|
5839
5839
|
var BRIDGE_HEALTH_METHOD = "health";
|
|
5840
5840
|
var BRIDGE_HEALTH_PARAMS = {};
|
|
5841
5841
|
var DEFAULT_BRIDGE_HEALTH_PROBE_TIMEOUT_MS = 1e4;
|
|
5842
|
+
var TRACEABLE_RELAY_METHODS = /* @__PURE__ */ new Set([
|
|
5843
|
+
"sessions.list",
|
|
5844
|
+
"chat.history",
|
|
5845
|
+
"last-heartbeat",
|
|
5846
|
+
"model.current",
|
|
5847
|
+
"models.list",
|
|
5848
|
+
"agent.identity.get",
|
|
5849
|
+
"agents.list"
|
|
5850
|
+
]);
|
|
5842
5851
|
var HermesRelayRuntime = class {
|
|
5843
5852
|
options;
|
|
5844
5853
|
relaySocket = null;
|
|
@@ -5853,6 +5862,7 @@ var HermesRelayRuntime = class {
|
|
|
5853
5862
|
bridgeStatusProbeInFlight = false;
|
|
5854
5863
|
pendingBridgeMessages = [];
|
|
5855
5864
|
bridgeHealthProbeSeq = 0;
|
|
5865
|
+
relayMessageSeq = 0;
|
|
5856
5866
|
pendingBridgeHealthProbe = null;
|
|
5857
5867
|
snapshot;
|
|
5858
5868
|
constructor(options) {
|
|
@@ -6010,6 +6020,7 @@ var HermesRelayRuntime = class {
|
|
|
6010
6020
|
const text = normalizeText(data);
|
|
6011
6021
|
if (text == null)
|
|
6012
6022
|
return;
|
|
6023
|
+
this.traceRelayFrame("relay_in", text);
|
|
6013
6024
|
if (text.startsWith(RELAY_CONTROL_PREFIX)) {
|
|
6014
6025
|
this.handleRelayControl(text);
|
|
6015
6026
|
return;
|
|
@@ -6045,6 +6056,7 @@ var HermesRelayRuntime = class {
|
|
|
6045
6056
|
const text = normalizeText(data);
|
|
6046
6057
|
if (text == null)
|
|
6047
6058
|
return;
|
|
6059
|
+
this.traceRelayFrame("bridge_in", text);
|
|
6048
6060
|
if (this.handleBridgeHealthProbeResponse(text)) {
|
|
6049
6061
|
return;
|
|
6050
6062
|
}
|
|
@@ -6055,6 +6067,9 @@ var HermesRelayRuntime = class {
|
|
|
6055
6067
|
forwardOrQueueBridgeMessage(message) {
|
|
6056
6068
|
const bridge = this.bridgeSocket;
|
|
6057
6069
|
if (!bridge || bridge.readyState !== WebSocket2.OPEN) {
|
|
6070
|
+
if (message.text !== void 0) {
|
|
6071
|
+
this.traceRelayFrame("bridge_queue", message.text);
|
|
6072
|
+
}
|
|
6058
6073
|
if (this.pendingBridgeMessages.length < 256) {
|
|
6059
6074
|
this.pendingBridgeMessages.push(message);
|
|
6060
6075
|
}
|
|
@@ -6062,6 +6077,7 @@ var HermesRelayRuntime = class {
|
|
|
6062
6077
|
return;
|
|
6063
6078
|
}
|
|
6064
6079
|
if (message.text !== void 0) {
|
|
6080
|
+
this.traceRelayFrame("bridge_send", message.text);
|
|
6065
6081
|
bridge.send(message.text);
|
|
6066
6082
|
return;
|
|
6067
6083
|
}
|
|
@@ -6078,12 +6094,44 @@ var HermesRelayRuntime = class {
|
|
|
6078
6094
|
if (!next)
|
|
6079
6095
|
break;
|
|
6080
6096
|
if (next.text !== void 0) {
|
|
6097
|
+
this.traceRelayFrame("bridge_flush", next.text);
|
|
6081
6098
|
bridge.send(next.text);
|
|
6082
6099
|
} else if (next.data) {
|
|
6083
6100
|
bridge.send(next.data);
|
|
6084
6101
|
}
|
|
6085
6102
|
}
|
|
6086
6103
|
}
|
|
6104
|
+
traceRelayFrame(direction, text) {
|
|
6105
|
+
const details = this.describeRelayFrame(text);
|
|
6106
|
+
if (!details)
|
|
6107
|
+
return;
|
|
6108
|
+
this.log(`[trace] ${direction} seq=${++this.relayMessageSeq} ${details}`);
|
|
6109
|
+
}
|
|
6110
|
+
describeRelayFrame(text) {
|
|
6111
|
+
if (text.startsWith(RELAY_CONTROL_PREFIX)) {
|
|
6112
|
+
try {
|
|
6113
|
+
const parsed = JSON.parse(text.slice(RELAY_CONTROL_PREFIX.length));
|
|
6114
|
+
const event = typeof parsed?.event === "string" ? parsed.event : "unknown";
|
|
6115
|
+
return `controlEvent=${event}`;
|
|
6116
|
+
} catch {
|
|
6117
|
+
return "controlEvent=invalid";
|
|
6118
|
+
}
|
|
6119
|
+
}
|
|
6120
|
+
try {
|
|
6121
|
+
const parsed = JSON.parse(text);
|
|
6122
|
+
if (parsed?.type === "req" && typeof parsed.method === "string") {
|
|
6123
|
+
if (!TRACEABLE_RELAY_METHODS.has(parsed.method))
|
|
6124
|
+
return null;
|
|
6125
|
+
return `frame=req id=${String(parsed.id ?? "")} method=${parsed.method}`;
|
|
6126
|
+
}
|
|
6127
|
+
if (parsed?.type === "res" && typeof parsed.id === "string") {
|
|
6128
|
+
return `frame=res id=${parsed.id} ok=${parsed.ok === true ? "true" : "false"}`;
|
|
6129
|
+
}
|
|
6130
|
+
return null;
|
|
6131
|
+
} catch {
|
|
6132
|
+
return null;
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
6087
6135
|
scheduleRelayReconnect() {
|
|
6088
6136
|
if (this.stopped || this.reconnectTimer)
|
|
6089
6137
|
return;
|
|
@@ -6152,9 +6200,8 @@ var HermesRelayRuntime = class {
|
|
|
6152
6200
|
} else {
|
|
6153
6201
|
const payload = await response.json();
|
|
6154
6202
|
if (!payload?.hasBridge) {
|
|
6155
|
-
this.log("bridge status probe reported hasBridge=false;
|
|
6156
|
-
this.
|
|
6157
|
-
this.bridgeSocket?.close();
|
|
6203
|
+
this.log("bridge status probe reported hasBridge=false; recycling relay socket");
|
|
6204
|
+
this.recycleRelaySocket("bridge status probe reported hasBridge=false");
|
|
6158
6205
|
return;
|
|
6159
6206
|
}
|
|
6160
6207
|
}
|
|
@@ -6244,6 +6291,26 @@ var HermesRelayRuntime = class {
|
|
|
6244
6291
|
clearTimeout(this.pendingBridgeHealthProbe.timeout);
|
|
6245
6292
|
this.pendingBridgeHealthProbe = null;
|
|
6246
6293
|
}
|
|
6294
|
+
recycleRelaySocket(reason) {
|
|
6295
|
+
const relay = this.relaySocket;
|
|
6296
|
+
if (!relay)
|
|
6297
|
+
return;
|
|
6298
|
+
this.relaySocket = null;
|
|
6299
|
+
this.clearBridgeStatusProbe();
|
|
6300
|
+
this.clearPendingBridgeHealthProbe();
|
|
6301
|
+
this.updateSnapshot({
|
|
6302
|
+
relayConnected: false,
|
|
6303
|
+
bridgeConnected: this.bridgeSocket?.readyState === WebSocket2.OPEN,
|
|
6304
|
+
lastError: reason
|
|
6305
|
+
});
|
|
6306
|
+
try {
|
|
6307
|
+
relay.close();
|
|
6308
|
+
} catch {
|
|
6309
|
+
}
|
|
6310
|
+
if (!this.stopped) {
|
|
6311
|
+
this.scheduleRelayReconnect();
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6247
6314
|
isRelayOpen() {
|
|
6248
6315
|
return this.relaySocket?.readyState === WebSocket2.OPEN;
|
|
6249
6316
|
}
|
|
@@ -9249,6 +9316,7 @@ function decidePairServiceAction(paired, service) {
|
|
|
9249
9316
|
}
|
|
9250
9317
|
|
|
9251
9318
|
// apps/bridge-cli/src/index.ts
|
|
9319
|
+
var HERMES_SERVICE_WATCHDOG_INTERVAL_MS = 3e4;
|
|
9252
9320
|
async function main() {
|
|
9253
9321
|
const [, , command = "help", ...args] = process.argv;
|
|
9254
9322
|
const isServiceMode = hasFlag(args, "--service");
|
|
@@ -9426,6 +9494,9 @@ async function main() {
|
|
|
9426
9494
|
instanceId: config.instanceId,
|
|
9427
9495
|
serviceMode: isServiceMode
|
|
9428
9496
|
});
|
|
9497
|
+
const hermesServiceWatchdog = isServiceMode ? startHermesServiceWatchdog((line) => {
|
|
9498
|
+
emitRuntimeLine(`[hermes-service] ${line}`);
|
|
9499
|
+
}) : null;
|
|
9429
9500
|
if (isServiceMode) {
|
|
9430
9501
|
await restoreHermesServiceRuntime((line) => {
|
|
9431
9502
|
emitRuntimeLine(`[hermes-service] ${line}`);
|
|
@@ -9435,6 +9506,9 @@ async function main() {
|
|
|
9435
9506
|
process.off("SIGINT", shutdown);
|
|
9436
9507
|
process.off("SIGTERM", shutdown);
|
|
9437
9508
|
await runtime.stop();
|
|
9509
|
+
if (hermesServiceWatchdog) {
|
|
9510
|
+
clearInterval(hermesServiceWatchdog);
|
|
9511
|
+
}
|
|
9438
9512
|
unregisterRuntimeProcess(process.pid);
|
|
9439
9513
|
if (isServiceMode) {
|
|
9440
9514
|
clearServiceState(process.pid);
|
|
@@ -10288,6 +10362,16 @@ async function keepHermesBridgeAlive(bridge) {
|
|
|
10288
10362
|
});
|
|
10289
10363
|
}
|
|
10290
10364
|
async function restoreHermesServiceRuntime(log) {
|
|
10365
|
+
await restoreHermesServiceRuntimeInternal(log, { silentIfHealthy: false });
|
|
10366
|
+
}
|
|
10367
|
+
function startHermesServiceWatchdog(log) {
|
|
10368
|
+
const timer = setInterval(() => {
|
|
10369
|
+
void restoreHermesServiceRuntimeInternal(log, { silentIfHealthy: true });
|
|
10370
|
+
}, HERMES_SERVICE_WATCHDOG_INTERVAL_MS);
|
|
10371
|
+
timer.unref?.();
|
|
10372
|
+
return timer;
|
|
10373
|
+
}
|
|
10374
|
+
async function restoreHermesServiceRuntimeInternal(log, options) {
|
|
10291
10375
|
const bridgeConfig = readHermesBridgeCliConfig();
|
|
10292
10376
|
const relayConfig = readHermesRelayConfig();
|
|
10293
10377
|
if (!bridgeConfig && !relayConfig) {
|
|
@@ -10302,9 +10386,11 @@ async function restoreHermesServiceRuntime(log) {
|
|
|
10302
10386
|
config: bridgeConfig,
|
|
10303
10387
|
replaceExisting: false
|
|
10304
10388
|
});
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10389
|
+
if (bridgePid != null || !options.silentIfHealthy) {
|
|
10390
|
+
log(
|
|
10391
|
+
bridgePid == null ? "Hermes bridge runtime already running." : `Started Hermes bridge runtime (pid ${bridgePid}).`
|
|
10392
|
+
);
|
|
10393
|
+
}
|
|
10308
10394
|
} catch (error) {
|
|
10309
10395
|
log(`Hermes bridge restore failed: ${formatError3(error)}`);
|
|
10310
10396
|
return;
|
|
@@ -10318,9 +10404,11 @@ async function restoreHermesServiceRuntime(log) {
|
|
|
10318
10404
|
config: bridgeConfig,
|
|
10319
10405
|
replaceExisting: false
|
|
10320
10406
|
});
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10407
|
+
if (relayPid != null || !options.silentIfHealthy) {
|
|
10408
|
+
log(
|
|
10409
|
+
relayPid == null ? "Hermes relay runtime already running." : `Started Hermes relay runtime (pid ${relayPid}).`
|
|
10410
|
+
);
|
|
10411
|
+
}
|
|
10324
10412
|
} catch (error) {
|
|
10325
10413
|
log(`Hermes relay restore failed: ${formatError3(error)}`);
|
|
10326
10414
|
}
|