@p697/clawket 0.6.0 → 0.6.1
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 +150 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1447,6 +1447,7 @@ var HermesLocalBridge = class {
|
|
|
1447
1447
|
hermesChild = null;
|
|
1448
1448
|
modelStateCache = null;
|
|
1449
1449
|
contextWindowCache = /* @__PURE__ */ new Map();
|
|
1450
|
+
bridgeRequestSeq = 0;
|
|
1450
1451
|
constructor(options = {}) {
|
|
1451
1452
|
this.options = options;
|
|
1452
1453
|
this.host = normalizeHost(options.host);
|
|
@@ -1491,6 +1492,12 @@ var HermesLocalBridge = class {
|
|
|
1491
1492
|
if (this.httpServer) {
|
|
1492
1493
|
return;
|
|
1493
1494
|
}
|
|
1495
|
+
this.logPerf("bridge_start_begin", {
|
|
1496
|
+
apiBaseUrl: this.apiBaseUrl,
|
|
1497
|
+
host: this.host,
|
|
1498
|
+
port: this.port
|
|
1499
|
+
});
|
|
1500
|
+
const startStartedAt = Date.now();
|
|
1494
1501
|
const hermesReady = await this.ensureHermesApiReady();
|
|
1495
1502
|
this.httpServer = createServer((req, res) => {
|
|
1496
1503
|
void this.handleHttpRequest(req, res);
|
|
@@ -1534,6 +1541,11 @@ var HermesLocalBridge = class {
|
|
|
1534
1541
|
prewarmComplete: true,
|
|
1535
1542
|
lastError: hermesReady ? null : this.snapshot.lastError
|
|
1536
1543
|
});
|
|
1544
|
+
this.logPerf("bridge_start_ready", {
|
|
1545
|
+
elapsedMs: Date.now() - startStartedAt,
|
|
1546
|
+
hermesReady,
|
|
1547
|
+
hermesApiReachable: this.snapshot.hermesApiReachable
|
|
1548
|
+
});
|
|
1537
1549
|
this.log(hermesReady ? `hermes bridge listening on ${this.snapshot.bridgeUrl}` : `hermes bridge listening on ${this.snapshot.bridgeUrl} (degraded: Hermes API not ready yet)`);
|
|
1538
1550
|
}
|
|
1539
1551
|
async stop() {
|
|
@@ -1575,21 +1587,39 @@ var HermesLocalBridge = class {
|
|
|
1575
1587
|
});
|
|
1576
1588
|
}
|
|
1577
1589
|
async ensureHermesApiReady() {
|
|
1590
|
+
const startedAt = Date.now();
|
|
1578
1591
|
if (await probeHermesApi(this.apiBaseUrl, this.apiKey)) {
|
|
1579
1592
|
this.updateSnapshot({ hermesApiReachable: true, lastError: null });
|
|
1593
|
+
this.logPerf("hermes_api_probe", {
|
|
1594
|
+
result: "warm",
|
|
1595
|
+
elapsedMs: Date.now() - startedAt
|
|
1596
|
+
});
|
|
1580
1597
|
this.log(`reusing Hermes API already running at ${this.apiBaseUrl}`);
|
|
1581
1598
|
return true;
|
|
1582
1599
|
}
|
|
1583
1600
|
if (this.options.startHermesIfNeeded === false) {
|
|
1584
1601
|
const error = `Hermes API is not reachable at ${this.apiBaseUrl}. Start Hermes gateway with API server enabled and retry.`;
|
|
1585
1602
|
this.updateSnapshot({ hermesApiReachable: false, lastError: error });
|
|
1603
|
+
this.logPerf("hermes_api_probe", {
|
|
1604
|
+
result: "unreachable_no_autostart",
|
|
1605
|
+
elapsedMs: Date.now() - startedAt
|
|
1606
|
+
});
|
|
1586
1607
|
this.log(error);
|
|
1587
1608
|
return false;
|
|
1588
1609
|
}
|
|
1610
|
+
this.logPerf("hermes_api_probe", {
|
|
1611
|
+
result: "cold_start_required",
|
|
1612
|
+
elapsedMs: Date.now() - startedAt
|
|
1613
|
+
});
|
|
1589
1614
|
return this.startHermesGatewayProcess();
|
|
1590
1615
|
}
|
|
1591
1616
|
async startHermesGatewayProcess() {
|
|
1592
1617
|
const command = this.options.hermesCommand?.trim() || "hermes";
|
|
1618
|
+
const startedAt = Date.now();
|
|
1619
|
+
this.logPerf("hermes_api_cold_start_begin", {
|
|
1620
|
+
command,
|
|
1621
|
+
apiBaseUrl: this.apiBaseUrl
|
|
1622
|
+
});
|
|
1593
1623
|
this.log(`starting hermes gateway via ${command}`);
|
|
1594
1624
|
const verboseHermesStdio = process.env.CLAWKET_HERMES_VERBOSE === "1";
|
|
1595
1625
|
const hermesChildEnv = {
|
|
@@ -1624,12 +1654,19 @@ var HermesLocalBridge = class {
|
|
|
1624
1654
|
while (Date.now() - startMs < HERMES_BOOT_TIMEOUT_MS) {
|
|
1625
1655
|
if (await probeHermesApi(this.apiBaseUrl, this.apiKey)) {
|
|
1626
1656
|
this.updateSnapshot({ hermesApiReachable: true, lastError: null });
|
|
1657
|
+
this.logPerf("hermes_api_cold_start_ready", {
|
|
1658
|
+
elapsedMs: Date.now() - startedAt
|
|
1659
|
+
});
|
|
1627
1660
|
return true;
|
|
1628
1661
|
}
|
|
1629
1662
|
await delay2(500);
|
|
1630
1663
|
}
|
|
1631
1664
|
const error = `Hermes API did not become ready within ${HERMES_BOOT_TIMEOUT_MS}ms at ${this.apiBaseUrl}.`;
|
|
1632
1665
|
this.updateSnapshot({ hermesApiReachable: false, lastError: error });
|
|
1666
|
+
this.logPerf("hermes_api_cold_start_timeout", {
|
|
1667
|
+
elapsedMs: Date.now() - startedAt,
|
|
1668
|
+
timeoutMs: HERMES_BOOT_TIMEOUT_MS
|
|
1669
|
+
});
|
|
1633
1670
|
this.log(error);
|
|
1634
1671
|
return false;
|
|
1635
1672
|
}
|
|
@@ -1647,6 +1684,8 @@ var HermesLocalBridge = class {
|
|
|
1647
1684
|
});
|
|
1648
1685
|
}
|
|
1649
1686
|
async prewarmBridgeState() {
|
|
1687
|
+
const startedAt = Date.now();
|
|
1688
|
+
this.logPerf("bridge_prewarm_begin");
|
|
1650
1689
|
const tasks = [
|
|
1651
1690
|
() => {
|
|
1652
1691
|
this.listHermesSessions(24);
|
|
@@ -1665,6 +1704,9 @@ var HermesLocalBridge = class {
|
|
|
1665
1704
|
this.log(`bridge prewarm skipped: ${formatError2(error)}`);
|
|
1666
1705
|
}
|
|
1667
1706
|
}));
|
|
1707
|
+
this.logPerf("bridge_prewarm_done", {
|
|
1708
|
+
elapsedMs: Date.now() - startedAt
|
|
1709
|
+
});
|
|
1668
1710
|
}
|
|
1669
1711
|
async handleHttpRequest(req, res) {
|
|
1670
1712
|
const pathname = readRequestPathname(req.url);
|
|
@@ -1739,23 +1781,34 @@ var HermesLocalBridge = class {
|
|
|
1739
1781
|
}
|
|
1740
1782
|
async dispatchRequest(method, params) {
|
|
1741
1783
|
const payload = isRecord(params) ? params : {};
|
|
1784
|
+
const shouldTracePerf = method === "health" || method === "last-heartbeat" || method === "sessions.list" || method === "chat.history" || method === "chat.send" || method === "models.list" || method === "model.current" || method === "model.get";
|
|
1785
|
+
const requestStartedAt = shouldTracePerf ? Date.now() : 0;
|
|
1786
|
+
const requestSeq = shouldTracePerf ? ++this.bridgeRequestSeq : 0;
|
|
1787
|
+
if (shouldTracePerf) {
|
|
1788
|
+
this.logPerf("bridge_request_begin", {
|
|
1789
|
+
requestSeq,
|
|
1790
|
+
method,
|
|
1791
|
+
sessionKey: readString(payload.sessionKey) || void 0,
|
|
1792
|
+
limit: readPositiveInt(payload.limit, 0) || void 0
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1742
1795
|
switch (method) {
|
|
1743
1796
|
case "health":
|
|
1744
1797
|
case "last-heartbeat":
|
|
1745
|
-
return {
|
|
1798
|
+
return this.traceBridgeRequest(method, requestStartedAt, requestSeq, {
|
|
1746
1799
|
status: this.snapshot.hermesApiReachable ? "ok" : "degraded",
|
|
1747
1800
|
ts: Date.now(),
|
|
1748
1801
|
hermesApiReachable: this.snapshot.hermesApiReachable
|
|
1749
|
-
};
|
|
1802
|
+
});
|
|
1750
1803
|
case "sessions.list":
|
|
1751
|
-
return {
|
|
1804
|
+
return this.traceBridgeRequest(method, requestStartedAt, requestSeq, {
|
|
1752
1805
|
defaults: this.getHermesSessionListDefaults(),
|
|
1753
1806
|
sessions: this.listHermesSessions(readPositiveInt(payload.limit, 100))
|
|
1754
|
-
};
|
|
1807
|
+
});
|
|
1755
1808
|
case "chat.history":
|
|
1756
|
-
return this.getHermesSessionHistory(readString(payload.sessionKey) || DEFAULT_SESSION_ID, readPositiveInt(payload.limit, 50));
|
|
1809
|
+
return this.traceBridgeRequest(method, requestStartedAt, requestSeq, this.getHermesSessionHistory(readString(payload.sessionKey) || DEFAULT_SESSION_ID, readPositiveInt(payload.limit, 50)));
|
|
1757
1810
|
case "chat.send":
|
|
1758
|
-
return this.handleChatSend(payload);
|
|
1811
|
+
return this.traceBridgeRequest(method, requestStartedAt, requestSeq, this.handleChatSend(payload));
|
|
1759
1812
|
case "sessions.reset":
|
|
1760
1813
|
this.cancelActiveRunsForSession(readString(payload.key) || DEFAULT_SESSION_ID);
|
|
1761
1814
|
this.sessionStore.resetSession(readString(payload.key) || DEFAULT_SESSION_ID);
|
|
@@ -1875,6 +1928,17 @@ var HermesLocalBridge = class {
|
|
|
1875
1928
|
throw new Error(`Unsupported Hermes bridge method: ${method}`);
|
|
1876
1929
|
}
|
|
1877
1930
|
}
|
|
1931
|
+
async traceBridgeRequest(method, startedAt, requestSeq, value) {
|
|
1932
|
+
const result = await value;
|
|
1933
|
+
if (startedAt > 0) {
|
|
1934
|
+
this.logPerf("bridge_request", {
|
|
1935
|
+
requestSeq,
|
|
1936
|
+
method,
|
|
1937
|
+
elapsedMs: Date.now() - startedAt
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
return result;
|
|
1941
|
+
}
|
|
1878
1942
|
async handleChatSend(payload) {
|
|
1879
1943
|
const sessionKey = readString(payload.sessionKey) || DEFAULT_SESSION_ID;
|
|
1880
1944
|
const text = readString(payload.message);
|
|
@@ -4659,6 +4723,10 @@ var HermesLocalBridge = class {
|
|
|
4659
4723
|
log(line) {
|
|
4660
4724
|
this.options.onLog?.(line);
|
|
4661
4725
|
}
|
|
4726
|
+
logPerf(event, fields) {
|
|
4727
|
+
const payload = fields ? Object.entries(fields).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${String(value)}`).join(" ") : "";
|
|
4728
|
+
this.log(`[perf] ${event}${payload ? ` ${payload}` : ""}`);
|
|
4729
|
+
}
|
|
4662
4730
|
async hydrateToolOutputsFromHermesState(params) {
|
|
4663
4731
|
const toolOutputs = this.readHermesToolOutputsFromLocalState(params.sessionId, params.runStartedAtMs);
|
|
4664
4732
|
if (toolOutputs.length === 0 || params.completedTools.length === 0) {
|
|
@@ -5943,10 +6011,29 @@ var HermesRelayRuntime = class {
|
|
|
5943
6011
|
if (text == null)
|
|
5944
6012
|
return;
|
|
5945
6013
|
if (text.startsWith(RELAY_CONTROL_PREFIX)) {
|
|
6014
|
+
this.handleRelayControl(text);
|
|
5946
6015
|
return;
|
|
5947
6016
|
}
|
|
5948
6017
|
this.forwardOrQueueBridgeMessage({ text });
|
|
5949
6018
|
}
|
|
6019
|
+
handleRelayControl(text) {
|
|
6020
|
+
try {
|
|
6021
|
+
const parsed = JSON.parse(text.slice(RELAY_CONTROL_PREFIX.length));
|
|
6022
|
+
if (parsed?.event !== "gateway_ping") {
|
|
6023
|
+
return;
|
|
6024
|
+
}
|
|
6025
|
+
const relay = this.relaySocket;
|
|
6026
|
+
if (!relay || relay.readyState !== WebSocket2.OPEN) {
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
relay.send(`${RELAY_CONTROL_PREFIX}${JSON.stringify({
|
|
6030
|
+
type: "control",
|
|
6031
|
+
event: "gateway_pong",
|
|
6032
|
+
ts: typeof parsed.ts === "number" ? parsed.ts : Date.now()
|
|
6033
|
+
})}`);
|
|
6034
|
+
} catch {
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
5950
6037
|
handleBridgeMessage(data, isBinary) {
|
|
5951
6038
|
const relay = this.relaySocket;
|
|
5952
6039
|
if (isBinary) {
|
|
@@ -9820,6 +9907,8 @@ async function performHermesLocalPairing(args) {
|
|
|
9820
9907
|
};
|
|
9821
9908
|
}
|
|
9822
9909
|
async function performHermesRelayPairing(args) {
|
|
9910
|
+
const pairingStartedAt = Date.now();
|
|
9911
|
+
logHermesPerf("pair_relay_begin");
|
|
9823
9912
|
const server = resolvePairServer(args, "hermes");
|
|
9824
9913
|
const name = readFlag(args, "--name") ?? readFlag(args, "-n") ?? "Hermes";
|
|
9825
9914
|
const qrFile = readFlag(args, "--qr-file");
|
|
@@ -9827,6 +9916,10 @@ async function performHermesRelayPairing(args) {
|
|
|
9827
9916
|
serverUrl: server,
|
|
9828
9917
|
displayName: name
|
|
9829
9918
|
});
|
|
9919
|
+
logHermesPerf("pair_relay_registered", {
|
|
9920
|
+
elapsedMs: Date.now() - pairingStartedAt,
|
|
9921
|
+
action: paired.action
|
|
9922
|
+
});
|
|
9830
9923
|
const qrImagePath = await writeRawQrPng(paired.qrPayload, "clawket-hermes-relay-pair", qrFile);
|
|
9831
9924
|
if (paired.action === "registered") {
|
|
9832
9925
|
const stalePids = listHermesRelayRuntimePids2();
|
|
@@ -9835,6 +9928,9 @@ async function performHermesRelayPairing(args) {
|
|
|
9835
9928
|
}
|
|
9836
9929
|
}
|
|
9837
9930
|
const runtimeMessage = await ensureHermesRelayBackgroundRuntime(args);
|
|
9931
|
+
logHermesPerf("pair_relay_ready", {
|
|
9932
|
+
elapsedMs: Date.now() - pairingStartedAt
|
|
9933
|
+
});
|
|
9838
9934
|
return {
|
|
9839
9935
|
backend: "hermes",
|
|
9840
9936
|
transport: "relay",
|
|
@@ -10265,6 +10361,8 @@ async function keepHermesRelayRuntimeAlive(runtime) {
|
|
|
10265
10361
|
});
|
|
10266
10362
|
}
|
|
10267
10363
|
async function ensureHermesRelayBackgroundRuntime(args) {
|
|
10364
|
+
const startedAt = Date.now();
|
|
10365
|
+
logHermesPerf("relay_runtime_ensure_begin");
|
|
10268
10366
|
const relayConfig = readHermesRelayConfig();
|
|
10269
10367
|
if (!relayConfig) {
|
|
10270
10368
|
throw new Error("Hermes relay is not paired.");
|
|
@@ -10272,6 +10370,10 @@ async function ensureHermesRelayBackgroundRuntime(args) {
|
|
|
10272
10370
|
const relayPids = listHermesRelayRuntimePids2();
|
|
10273
10371
|
if (relayPids.length === 1) {
|
|
10274
10372
|
await waitForHermesRelayCloudBridgeReady(relayConfig, 2e4);
|
|
10373
|
+
logHermesPerf("relay_runtime_ensure_reused", {
|
|
10374
|
+
elapsedMs: Date.now() - startedAt,
|
|
10375
|
+
pid: relayPids[0]
|
|
10376
|
+
});
|
|
10275
10377
|
return `Hermes relay runtime already running (pid ${relayPids[0]}) and confirmed by relay.`;
|
|
10276
10378
|
}
|
|
10277
10379
|
if (relayPids.length > 1) {
|
|
@@ -10290,8 +10392,15 @@ async function ensureHermesRelayBackgroundRuntime(args) {
|
|
|
10290
10392
|
await waitForHermesRelayCloudBridgeReady(relayConfig, 2e4);
|
|
10291
10393
|
const startedPids = listHermesRelayRuntimePids2();
|
|
10292
10394
|
if (startedPids.length === 0) {
|
|
10395
|
+
logHermesPerf("relay_runtime_ensure_requested_no_pid", {
|
|
10396
|
+
elapsedMs: Date.now() - startedAt
|
|
10397
|
+
});
|
|
10293
10398
|
return "Hermes relay runtime launch was requested. Run `clawket hermes relay run` manually if it did not stay up.";
|
|
10294
10399
|
}
|
|
10400
|
+
logHermesPerf("relay_runtime_ensure_started", {
|
|
10401
|
+
elapsedMs: Date.now() - startedAt,
|
|
10402
|
+
pid: startedPids[0]
|
|
10403
|
+
});
|
|
10295
10404
|
return `Auto-started Hermes relay runtime (pid ${startedPids[0]}) and confirmed cloud bridge attachment.`;
|
|
10296
10405
|
}
|
|
10297
10406
|
async function ensureHermesBridgeBackgroundRuntime(input) {
|
|
@@ -10506,6 +10615,8 @@ function resolveRequestedPairBackend(args) {
|
|
|
10506
10615
|
throw new Error(`Unsupported local pairing backend "${backend}". Use --backend openclaw or --backend hermes.`);
|
|
10507
10616
|
}
|
|
10508
10617
|
async function ensureHermesPairingRuntimeReady(args) {
|
|
10618
|
+
const startedAt = Date.now();
|
|
10619
|
+
logHermesPerf("pairing_runtime_ready_begin");
|
|
10509
10620
|
const saved = readHermesBridgeCliConfig();
|
|
10510
10621
|
const host = readFlag(args, "--host") ?? saved?.host ?? "0.0.0.0";
|
|
10511
10622
|
const port = Number(readFlag(args, "--port") ?? saved?.port ?? "4319");
|
|
@@ -10513,7 +10624,12 @@ async function ensureHermesPairingRuntimeReady(args) {
|
|
|
10513
10624
|
const token = readFlag(args, "--token") ?? process.env.CLAWKET_HERMES_BRIDGE_TOKEN ?? saved?.token ?? randomUUID5();
|
|
10514
10625
|
const existingBridgePids = listHermesBridgeRuntimePids2();
|
|
10515
10626
|
if (existingBridgePids.length > 0) {
|
|
10516
|
-
|
|
10627
|
+
const resolved = await resolveExistingHermesPairingRuntime(saved);
|
|
10628
|
+
logHermesPerf("pairing_runtime_ready_reused", {
|
|
10629
|
+
elapsedMs: Date.now() - startedAt,
|
|
10630
|
+
port: resolved.port
|
|
10631
|
+
});
|
|
10632
|
+
return resolved;
|
|
10517
10633
|
}
|
|
10518
10634
|
if (!existsSync7(resolveDefaultHermesSourcePath())) {
|
|
10519
10635
|
throw new Error(
|
|
@@ -10528,6 +10644,10 @@ async function ensureHermesPairingRuntimeReady(args) {
|
|
|
10528
10644
|
restartHermes: hasFlag(args, "--restart-hermes")
|
|
10529
10645
|
});
|
|
10530
10646
|
await waitForHermesBridgeHealth(port);
|
|
10647
|
+
logHermesPerf("pairing_runtime_ready_started", {
|
|
10648
|
+
elapsedMs: Date.now() - startedAt,
|
|
10649
|
+
port
|
|
10650
|
+
});
|
|
10531
10651
|
return { host, port, apiBaseUrl, token };
|
|
10532
10652
|
}
|
|
10533
10653
|
async function resolveExistingHermesPairingRuntime(saved) {
|
|
@@ -10602,17 +10722,27 @@ function startDetachedHermesRelayRuntime(input) {
|
|
|
10602
10722
|
child.unref();
|
|
10603
10723
|
}
|
|
10604
10724
|
async function waitForHermesBridgeHealth(port, timeoutMs = 15e3) {
|
|
10725
|
+
const startedAt = Date.now();
|
|
10605
10726
|
const deadline = Date.now() + timeoutMs;
|
|
10606
10727
|
while (Date.now() < deadline) {
|
|
10607
10728
|
try {
|
|
10608
10729
|
const health = await readHermesBridgeHealth2(port);
|
|
10609
10730
|
if (health.ok && health.running) {
|
|
10731
|
+
logHermesPerf("bridge_health_ready", {
|
|
10732
|
+
elapsedMs: Date.now() - startedAt,
|
|
10733
|
+
port
|
|
10734
|
+
});
|
|
10610
10735
|
return;
|
|
10611
10736
|
}
|
|
10612
10737
|
} catch {
|
|
10613
10738
|
}
|
|
10614
10739
|
await new Promise((resolve4) => setTimeout(resolve4, 250));
|
|
10615
10740
|
}
|
|
10741
|
+
logHermesPerf("bridge_health_timeout", {
|
|
10742
|
+
elapsedMs: Date.now() - startedAt,
|
|
10743
|
+
port,
|
|
10744
|
+
timeoutMs
|
|
10745
|
+
});
|
|
10616
10746
|
throw new Error(`Hermes bridge did not become ready at http://127.0.0.1:${port}/health within ${timeoutMs}ms.`);
|
|
10617
10747
|
}
|
|
10618
10748
|
async function readHermesBridgeHealth2(port) {
|
|
@@ -10664,6 +10794,7 @@ async function waitForHermesRelayRuntimeReady(startedAtMs, timeoutMs) {
|
|
|
10664
10794
|
}
|
|
10665
10795
|
}
|
|
10666
10796
|
async function waitForHermesRelayCloudBridgeReady(relayConfig, timeoutMs) {
|
|
10797
|
+
const startedAt = Date.now();
|
|
10667
10798
|
const statusUrl = buildHermesRelayBridgeStatusUrl2(relayConfig.relayUrl, relayConfig.bridgeId);
|
|
10668
10799
|
const deadline = Date.now() + timeoutMs;
|
|
10669
10800
|
let lastError = null;
|
|
@@ -10678,6 +10809,9 @@ async function waitForHermesRelayCloudBridgeReady(relayConfig, timeoutMs) {
|
|
|
10678
10809
|
if (response.ok) {
|
|
10679
10810
|
const payload = await response.json();
|
|
10680
10811
|
if (payload?.hasBridge) {
|
|
10812
|
+
logHermesPerf("relay_cloud_bridge_ready", {
|
|
10813
|
+
elapsedMs: Date.now() - startedAt
|
|
10814
|
+
});
|
|
10681
10815
|
return;
|
|
10682
10816
|
}
|
|
10683
10817
|
} else {
|
|
@@ -10688,6 +10822,10 @@ async function waitForHermesRelayCloudBridgeReady(relayConfig, timeoutMs) {
|
|
|
10688
10822
|
}
|
|
10689
10823
|
await sleep(500);
|
|
10690
10824
|
}
|
|
10825
|
+
logHermesPerf("relay_cloud_bridge_timeout", {
|
|
10826
|
+
elapsedMs: Date.now() - startedAt,
|
|
10827
|
+
timeoutMs
|
|
10828
|
+
});
|
|
10691
10829
|
throw new Error(
|
|
10692
10830
|
`Hermes relay did not observe the local bridge for ${relayConfig.bridgeId} within ${timeoutMs}ms` + (lastError ? ` (${lastError}).` : ".")
|
|
10693
10831
|
);
|
|
@@ -10768,6 +10906,11 @@ function formatLocalTime(iso) {
|
|
|
10768
10906
|
function formatError3(error) {
|
|
10769
10907
|
return error instanceof Error ? error.message : String(error);
|
|
10770
10908
|
}
|
|
10909
|
+
function logHermesPerf(event, fields) {
|
|
10910
|
+
const payload = fields ? Object.entries(fields).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${String(value)}`).join(" ") : "";
|
|
10911
|
+
void event;
|
|
10912
|
+
void payload;
|
|
10913
|
+
}
|
|
10771
10914
|
async function followCliLogs(input) {
|
|
10772
10915
|
const sources = getCliLogSourcePaths(input.includeErrorLog);
|
|
10773
10916
|
const state = /* @__PURE__ */ new Map();
|