@agent-link/server 0.1.167 → 0.1.168

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-link/server",
3
- "version": "0.1.167",
3
+ "version": "0.1.168",
4
4
  "description": "AgentLink relay server",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -56,6 +56,7 @@ export function createConnection(deps) {
56
56
  let reconnectAttempts = 0;
57
57
  let reconnectTimer = null;
58
58
  let pingTimer = null;
59
+ let idleCheckTimer = null;
59
60
  const toolMsgMap = new Map(); // toolId -> message (for fast tool_result lookup)
60
61
 
61
62
  // ── toolMsgMap save/restore for conversation switching ──
@@ -90,6 +91,22 @@ export function createConnection(deps) {
90
91
  latency.value = null;
91
92
  }
92
93
 
94
+ // Idle-check: if isProcessing stays true with no claude_output for 15s,
95
+ // poll the agent to reconcile stale state (guards against lost turn_completed).
96
+ const IDLE_CHECK_MS = 15000;
97
+ function resetIdleCheck() {
98
+ if (idleCheckTimer) { clearTimeout(idleCheckTimer); idleCheckTimer = null; }
99
+ if (isProcessing.value) {
100
+ idleCheckTimer = setTimeout(() => {
101
+ idleCheckTimer = null;
102
+ if (isProcessing.value) wsSend({ type: 'query_active_conversations' });
103
+ }, IDLE_CHECK_MS);
104
+ }
105
+ }
106
+ function clearIdleCheck() {
107
+ if (idleCheckTimer) { clearTimeout(idleCheckTimer); idleCheckTimer = null; }
108
+ }
109
+
93
110
  function getSessionId() {
94
111
  const match = window.location.pathname.match(/^\/s\/([^/]+)/);
95
112
  return match ? match[1] : null;
@@ -118,6 +135,7 @@ export function createConnection(deps) {
118
135
  // (e.g. after reconnect before active_conversations response), self-correct
119
136
  if (!isProcessing.value) {
120
137
  isProcessing.value = true;
138
+ resetIdleCheck();
121
139
  if (currentConversationId && currentConversationId.value) {
122
140
  processingConversations.value[currentConversationId.value] = true;
123
141
  }
@@ -387,6 +405,7 @@ export function createConnection(deps) {
387
405
  if (team && msg.activeTeam) {
388
406
  team.handleActiveTeamRestore(msg.activeTeam);
389
407
  }
408
+ resetIdleCheck();
390
409
  } else if (msg.type === 'error') {
391
410
  streaming.flushReveal();
392
411
  finalizeStreamingMsg(scheduleHighlight);
@@ -399,6 +418,7 @@ export function createConnection(deps) {
399
418
  isProcessing.value = false;
400
419
  isCompacting.value = false;
401
420
  loadingSessions.value = false;
421
+ clearIdleCheck();
402
422
  if (currentConversationId && currentConversationId.value) {
403
423
  processingConversations.value[currentConversationId.value] = false;
404
424
  }
@@ -409,6 +429,7 @@ export function createConnection(deps) {
409
429
  _dequeueNext();
410
430
  } else if (msg.type === 'claude_output') {
411
431
  handleClaudeOutput(msg, scheduleHighlight);
432
+ resetIdleCheck();
412
433
  } else if (msg.type === 'session_started') {
413
434
  // Claude session ID captured — update and refresh sidebar
414
435
  currentClaudeSessionId.value = msg.claudeSessionId;
@@ -446,6 +467,7 @@ export function createConnection(deps) {
446
467
  finalizeStreamingMsg(scheduleHighlight);
447
468
  isProcessing.value = false;
448
469
  isCompacting.value = false;
470
+ clearIdleCheck();
449
471
  toolMsgMap.clear();
450
472
  if (msg.usage) usageStats.value = msg.usage;
451
473
  if (currentConversationId && currentConversationId.value) {
@@ -607,6 +629,7 @@ export function createConnection(deps) {
607
629
  ws.onclose = () => {
608
630
  sessionKey = null;
609
631
  stopPing();
632
+ clearIdleCheck();
610
633
  const wasConnected = status.value === 'Connected' || status.value === 'Connecting...';
611
634
  isProcessing.value = false;
612
635
  isCompacting.value = false;