@cryptiklemur/lattice 5.13.2 → 5.13.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.
@@ -41,23 +41,27 @@ const sessionPermissionOverrides = new Map();
41
41
  export function getAvailableModels() {
42
42
  return getWarmupModels();
43
43
  }
44
- function createMessageQueue() {
44
+ function createMessageQueue(label) {
45
45
  const queue = [];
46
46
  let waiting = null;
47
47
  let ended = false;
48
+ let readCount = 0;
48
49
  return {
49
50
  push: function (msg) {
50
51
  if (waiting) {
52
+ log.chat("MQ[%s] push: SDK was waiting, delivering immediately (queued=%d)", label || "?", queue.length);
51
53
  const resolve = waiting;
52
54
  waiting = null;
53
55
  resolve({ value: msg, done: false });
54
56
  }
55
57
  else {
56
58
  queue.push(msg);
59
+ log.chat("MQ[%s] push: buffered (queued=%d)", label || "?", queue.length);
57
60
  }
58
61
  },
59
62
  end: function () {
60
63
  ended = true;
64
+ log.chat("MQ[%s] end called (queued=%d, waiting=%s)", label || "?", queue.length, String(!!waiting));
61
65
  if (waiting) {
62
66
  const resolve = waiting;
63
67
  waiting = null;
@@ -67,12 +71,16 @@ function createMessageQueue() {
67
71
  [Symbol.asyncIterator]: function () {
68
72
  return {
69
73
  next: function () {
74
+ readCount++;
70
75
  if (queue.length > 0) {
76
+ log.chat("MQ[%s] read #%d: from buffer (remaining=%d)", label || "?", readCount, queue.length - 1);
71
77
  return Promise.resolve({ value: queue.shift(), done: false });
72
78
  }
73
79
  if (ended) {
80
+ log.chat("MQ[%s] read #%d: ended", label || "?", readCount);
74
81
  return Promise.resolve({ value: undefined, done: true });
75
82
  }
83
+ log.chat("MQ[%s] read #%d: waiting for push", label || "?", readCount);
76
84
  return new Promise(function (resolve) {
77
85
  waiting = resolve;
78
86
  });
@@ -654,7 +662,7 @@ export function startChatStream(options) {
654
662
  text,
655
663
  uuid: crypto.randomUUID(),
656
664
  });
657
- const mq = createMessageQueue();
665
+ const mq = createMessageQueue(sessionId.slice(0, 8));
658
666
  const firstMsg = buildSDKUserMessage(prompt, attachments, sessionId);
659
667
  const stream = query({ prompt: mq, options: queryOptions });
660
668
  pendingStreams.delete(sessionId);
@@ -698,17 +706,37 @@ export function startChatStream(options) {
698
706
  log.chat("Session %s pushing first message to queue", sessionId);
699
707
  mq.push(firstMsg);
700
708
  let retrying = false;
709
+ const TURN_TIMEOUT_MS = 30000;
710
+ let turnTimer = null;
711
+ function resetTurnTimer() {
712
+ if (turnTimer)
713
+ clearTimeout(turnTimer);
714
+ turnTimer = setTimeout(function () {
715
+ if (!sessionStream.sawNewTurnContent && !sessionStream.ended) {
716
+ log.chat("Session %s turn timeout: no new content after %dms, aborting", sessionId, TURN_TIMEOUT_MS);
717
+ abortController.abort();
718
+ }
719
+ }, TURN_TIMEOUT_MS);
720
+ }
721
+ resetTurnTimer();
701
722
  try {
702
723
  log.chat("Session %s entering stream loop", sessionId);
703
724
  let msgCount = 0;
704
725
  for await (const msg of stream) {
705
726
  msgCount++;
706
727
  log.chat("Session %s msg #%d type=%s", sessionId, msgCount, msg.type);
728
+ if (msg.type === "stream_event" || (msg.type === "assistant" && msg.message?.model !== "<synthetic>")) {
729
+ resetTurnTimer();
730
+ }
707
731
  processMessage(sessionStream, msg);
708
732
  }
733
+ if (turnTimer)
734
+ clearTimeout(turnTimer);
709
735
  log.chat("Session %s stream ended normally after %d messages", sessionId, msgCount);
710
736
  }
711
737
  catch (err) {
738
+ if (turnTimer)
739
+ clearTimeout(turnTimer);
712
740
  const errMsg = err instanceof Error ? err.message : String(err);
713
741
  log.chat("Session %s stream error: %s", sessionId, errMsg);
714
742
  if (errMsg.includes("aborted") || errMsg.includes("AbortError")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cryptiklemur/lattice",
3
- "version": "5.13.2",
3
+ "version": "5.13.3",
4
4
  "description": "Multi-machine agentic dashboard for Claude Code. Monitor sessions, manage MCP servers and skills, orchestrate across mesh-networked nodes.",
5
5
  "license": "MIT",
6
6
  "author": "Aaron Scherer <me@aaronscherer.me>",