agent-transport-system 0.7.55 → 0.7.57

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/ats.js CHANGED
@@ -27,7 +27,7 @@ import wrapAnsi from "wrap-ansi";
27
27
  import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
28
28
 
29
29
  //#region package.json
30
- var version = "0.7.55";
30
+ var version = "0.7.57";
31
31
  var package_default = {
32
32
  $schema: "https://www.schemastore.org/package.json",
33
33
  name: "agent-transport-system",
@@ -15223,6 +15223,7 @@ const PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS = 6e4;
15223
15223
  const RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS = 6e4;
15224
15224
  const DEFAULT_RECONNECT_DELAY_MS = 1e3;
15225
15225
  const MAX_RECONNECT_DELAY_MS = 1e4;
15226
+ const DAEMON_STREAM_CONNECT_TIMEOUT_MS = 15e3;
15226
15227
  const REGISTER_RESPONSE_TIMEOUT_MS = 1e4;
15227
15228
  const HEARTBEAT_RESPONSE_TIMEOUT_MS = 15e3;
15228
15229
  const HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE = 3;
@@ -19738,8 +19739,8 @@ function isPidAlive$4(pid) {
19738
19739
  }
19739
19740
  }
19740
19741
  function isRuntimeLeaseHeartbeatStale(runtimeLease) {
19741
- if (!runtimeLease.heartbeatAt) return false;
19742
- const heartbeatMs = Date.parse(runtimeLease.heartbeatAt);
19742
+ const freshnessTimestamp = runtimeLease.heartbeatAt ?? runtimeLease.updatedAt;
19743
+ const heartbeatMs = Date.parse(freshnessTimestamp);
19743
19744
  if (Number.isNaN(heartbeatMs)) return true;
19744
19745
  return Date.now() - heartbeatMs > DAEMON_HEARTBEAT_STALE_MS;
19745
19746
  }
@@ -39544,12 +39545,29 @@ function buildDaemonAgentOverviewPayload(command) {
39544
39545
  //#region src/transport/ws.ts
39545
39546
  async function connectWebSocket(url, input) {
39546
39547
  return await new Promise((resolve, reject) => {
39548
+ let settled = false;
39547
39549
  const ws = new WebSocket(url, { headers: input?.headers });
39550
+ const openTimeoutMs = normalizeOpenTimeoutMs(input?.openTimeoutMs);
39551
+ const openTimeout = openTimeoutMs === null ? null : setTimeout(() => {
39552
+ if (settled) return;
39553
+ settled = true;
39554
+ ws.terminate();
39555
+ reject(/* @__PURE__ */ new Error(`websocket open timeout after ${openTimeoutMs}ms`));
39556
+ }, openTimeoutMs);
39548
39557
  const closePromise = new Promise((r) => {
39549
39558
  ws.on("close", () => r());
39550
39559
  ws.on("error", () => r());
39551
39560
  });
39561
+ ws.on("close", (code, reason) => {
39562
+ if (settled) return;
39563
+ settled = true;
39564
+ if (openTimeout) clearTimeout(openTimeout);
39565
+ reject(/* @__PURE__ */ new Error(`websocket closed before open (code=${String(code)}, reason=${reason.toString("utf8")})`));
39566
+ });
39552
39567
  ws.on("open", () => {
39568
+ if (settled) return;
39569
+ settled = true;
39570
+ if (openTimeout) clearTimeout(openTimeout);
39553
39571
  resolve({
39554
39572
  send: (data) => ws.send(data),
39555
39573
  close: (code, reason) => ws.close(code, reason),
@@ -39569,10 +39587,19 @@ async function connectWebSocket(url, input) {
39569
39587
  });
39570
39588
  });
39571
39589
  ws.on("error", (err) => {
39590
+ if (settled) return;
39591
+ settled = true;
39592
+ if (openTimeout) clearTimeout(openTimeout);
39572
39593
  reject(err);
39573
39594
  });
39574
39595
  });
39575
39596
  }
39597
+ function normalizeOpenTimeoutMs(value) {
39598
+ if (value === void 0 || value === null) return null;
39599
+ if (typeof value !== "number" || !Number.isFinite(value)) return null;
39600
+ const normalized = Math.trunc(value);
39601
+ return normalized > 0 ? normalized : null;
39602
+ }
39576
39603
  function toUtf8(value) {
39577
39604
  if (typeof value === "string") return value;
39578
39605
  if (value instanceof Buffer) return value.toString("utf8");
@@ -40720,13 +40747,15 @@ function createDaemonRuntimeStateTracker(input) {
40720
40747
  let lastRuntimeStatePersistAtMs = Date.now();
40721
40748
  const touchRuntimeState = async (updates, options) => {
40722
40749
  const nowAt = nowIsoString();
40750
+ const previousHeartbeatAt = runtimeState.heartbeatAt;
40723
40751
  runtimeState = {
40724
40752
  ...runtimeState,
40725
40753
  ...updates,
40726
40754
  updatedAt: updates.updatedAt ?? nowAt
40727
40755
  };
40756
+ const receivedFirstHeartbeat = previousHeartbeatAt === null && typeof updates.heartbeatAt === "string" && updates.heartbeatAt.length > 0;
40728
40757
  if (!shouldPersistDaemonRuntimeState({
40729
- forcePersist: options?.forcePersist === true,
40758
+ forcePersist: options?.forcePersist === true || receivedFirstHeartbeat,
40730
40759
  nowMs: Date.now(),
40731
40760
  lastPersistedAtMs: lastRuntimeStatePersistAtMs,
40732
40761
  updates
@@ -46065,7 +46094,7 @@ async function runDaemonSocketSession(input) {
46065
46094
  text: `heartbeat failed (${String(consecutiveHeartbeatFailures)}/${String(HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE)}): ${toErrorMessage$29(error)}`
46066
46095
  });
46067
46096
  if (shouldCloseSocket) {
46068
- input.socket.close(1011, "heartbeat_failed");
46097
+ input.socket.terminate();
46069
46098
  return;
46070
46099
  }
46071
46100
  updateHeartbeatInterval({
@@ -46926,10 +46955,13 @@ const runDaemonServiceLoop = async (input) => {
46926
46955
  }
46927
46956
  while (!stopRequested) try {
46928
46957
  const wsUrl = toDaemonStreamUrl(baseUrl);
46929
- const ws = await connectWebSocket(wsUrl, { headers: selectedAtsProfile ? await buildAtsProfileRequestHeadersWithAuth({
46930
- atsProfile: selectedAtsProfile,
46931
- requestUrl: wsUrl
46932
- }) : await buildRequestAuthHeaders({ requestUrl: wsUrl }) });
46958
+ const ws = await connectWebSocket(wsUrl, {
46959
+ headers: selectedAtsProfile ? await buildAtsProfileRequestHeadersWithAuth({
46960
+ atsProfile: selectedAtsProfile,
46961
+ requestUrl: wsUrl
46962
+ }) : await buildRequestAuthHeaders({ requestUrl: wsUrl }),
46963
+ openTimeoutMs: DAEMON_STREAM_CONNECT_TIMEOUT_MS
46964
+ });
46933
46965
  activeSocket = ws;
46934
46966
  emitRunLine({
46935
46967
  presenter: input.presenter,