totemlayer 0.1.94 → 0.1.96

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.
@@ -232,7 +232,8 @@ export async function readAgentRuntimeStatus(profile, { isAlive = alive, now = D
232
232
  const fresh = now() - Date.parse(record.updatedAt) <= 30_000;
233
233
  const receiving =
234
234
  record.listenerHealthRequired !== true ||
235
- (typeof record.listenerHeartbeatAt === "string" &&
235
+ (record.listenerHeartbeatReady !== false &&
236
+ typeof record.listenerHeartbeatAt === "string" &&
236
237
  Number.isFinite(Date.parse(record.listenerHeartbeatAt)) &&
237
238
  now() - Date.parse(record.listenerHeartbeatAt) >= -5000 &&
238
239
  now() - Date.parse(record.listenerHeartbeatAt) <= 30_000);
@@ -263,7 +264,9 @@ export async function readAgentRuntimeStatus(profile, { isAlive = alive, now = D
263
264
  ),
264
265
  phase: running
265
266
  ? fresh
266
- ? record.phase
267
+ ? record.ready && !receiving && !["blocked", "working", "starting"].includes(record.phase)
268
+ ? "reconnecting"
269
+ : record.phase
267
270
  : "unresponsive"
268
271
  : ["stopped", "failed"].includes(record.phase)
269
272
  ? record.phase
@@ -338,8 +341,15 @@ export async function stopStalledAgent(profile, runId, options = {}) {
338
341
 
339
342
  function eventState(event) {
340
343
  if (event?.type === "runtime_ready")
341
- return { ready: true, listenerHeartbeatAt: new Date().toISOString() };
342
- if (event?.type === "runtime_heartbeat") return { listenerHeartbeatAt: new Date().toISOString() };
344
+ return {
345
+ ready: true,
346
+ listenerHeartbeatReady: true,
347
+ listenerHeartbeatAt: new Date().toISOString(),
348
+ };
349
+ if (event?.type === "runtime_heartbeat")
350
+ return { listenerHeartbeatReady: true, listenerHeartbeatAt: new Date().toISOString() };
351
+ if (event?.type === "runtime_heartbeat_check")
352
+ return { listenerCheckAt: new Date().toISOString() };
343
353
  const candidate = event?.state ?? event?.status ?? event?.type;
344
354
  const phase =
345
355
  typeof candidate === "string" ? candidate.replace(/^mission_agent_|^agent_/, "") : "";
@@ -472,14 +482,19 @@ export async function runAgentSession(profile, options = {}) {
472
482
  throw new Error("Invalid listener watchdog deadline.");
473
483
  const poll = async () => {
474
484
  if (status.ready && Date.now() - Date.parse(status.listenerHeartbeatAt) > listenerWatchdogMs) {
475
- listenerExpired = true;
476
- status = {
477
- ...status,
478
- ready: false,
479
- phase: "reconnecting",
480
- errorCode: "LISTENER_HEARTBEAT_TIMEOUT",
481
- };
482
- controller.abort();
485
+ // Bounded network retries keep the verified chat, but never restore readiness.
486
+ const retrying = Date.now() - Date.parse(status.listenerCheckAt ?? "") <= listenerWatchdogMs;
487
+ status = { ...status, listenerHeartbeatReady: false };
488
+ if (!retrying) {
489
+ listenerExpired = true;
490
+ status = {
491
+ ...status,
492
+ phase: "reconnecting",
493
+ ready: false,
494
+ errorCode: "LISTENER_HEARTBEAT_TIMEOUT",
495
+ };
496
+ controller.abort();
497
+ }
483
498
  }
484
499
  try {
485
500
  const request = await readPrivateJson(join(directory, `${runId}.stop`));
@@ -77,7 +77,14 @@ export async function runConnectedAgentService(settings, dependencies = {}) {
77
77
  replyTimeoutMs: 90000,
78
78
  pollMs: settings.pollMs ?? DEFAULT_LISTENER_POLL_MS,
79
79
  emit(event) {
80
- if (["runtime_ready", "runtime_heartbeat", "receive_check"].includes(event.type))
80
+ if (
81
+ [
82
+ "runtime_ready",
83
+ "runtime_heartbeat",
84
+ "runtime_heartbeat_check",
85
+ "receive_check",
86
+ ].includes(event.type)
87
+ )
81
88
  emit(event);
82
89
  else if (event.type === "runtime_reconnecting")
83
90
  report("messages", { type: "reconnecting" });
Binary file
@@ -1 +1 @@
1
- {"sourceSha256":"e15dc6cfd6f828dbcb829fc6fa3f5f6ef51062f45462ec6532b8c52f532c7951","binarySha256":"f516045a8e5ecb13e997c44785abad1e340e77cc4d7782e6bdbc3972ec33ceb7","architectures":["arm64","x86_64"],"minimumMacOS":"13.0"}
1
+ {"sourceSha256":"e15dc6cfd6f828dbcb829fc6fa3f5f6ef51062f45462ec6532b8c52f532c7951","binarySha256":"39c3e7ba072d6fe97d7a5bdec0effce7ba0fa035c5c0376d1295557e1272c352","architectures":["arm64","x86_64"],"minimumMacOS":"13.0"}
@@ -840,6 +840,7 @@ export async function runRuntime(settings) {
840
840
  }
841
841
  }
842
842
  const beat = async () => {
843
+ emit({ type: "runtime_heartbeat_check" });
843
844
  const unavailable = ["blocked", "reconnecting"].includes(diagnostics.phase);
844
845
  const result = await client.runtime.heartbeat(
845
846
  {
@@ -1 +1 @@
1
- {"version":1,"packageVersion":"0.1.94","bytes":27189,"sha256":"c62a0116c76177d905051b40ddcbb0503e042b1fc8f5d024c1ebf41c7f173983"}
1
+ {"version":1,"packageVersion":"0.1.96","bytes":27189,"sha256":"c62a0116c76177d905051b40ddcbb0503e042b1fc8f5d024c1ebf41c7f173983"}
@@ -1 +1 @@
1
- {"version":1,"packageVersion":"0.1.94","bytes":36144,"sha256":"66535754c594ad559c91b68c93348ec5579f10a0d791c462cecf98cb618ea2ae"}
1
+ {"version":1,"packageVersion":"0.1.96","bytes":36144,"sha256":"66535754c594ad559c91b68c93348ec5579f10a0d791c462cecf98cb618ea2ae"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "totemlayer",
3
- "version": "0.1.94",
3
+ "version": "0.1.96",
4
4
  "description": "Connect AI agents to Totem Network for discovery, messaging, and shared work.",
5
5
  "type": "module",
6
6
  "bin": {