@yeaft/webchat-agent 0.1.436 → 0.1.437

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.
@@ -56,7 +56,9 @@ export function connect() {
56
56
 
57
57
  const msg = await parseMessage(data);
58
58
  if (msg) {
59
- handleMessage(msg);
59
+ handleMessage(msg).catch(err => {
60
+ console.error('[WS] handleMessage error:', err.message || err);
61
+ });
60
62
  }
61
63
  });
62
64
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.436",
3
+ "version": "0.1.437",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -23,6 +23,9 @@ let session = null;
23
23
  /** @type {AbortController | null} */
24
24
  let currentAbort = null;
25
25
 
26
+ /** Query timeout in ms — abort if LLM doesn't respond within this window */
27
+ const QUERY_TIMEOUT_MS = 120_000;
28
+
26
29
  /** Virtual conversationId for the Unify session */
27
30
  let unifyConversationId = null;
28
31
 
@@ -100,12 +103,29 @@ export async function handleUnifyChat(msg) {
100
103
 
101
104
  currentAbort = new AbortController();
102
105
 
106
+ // ─── Timeout guard: abort query if LLM hangs beyond threshold ──
107
+ // Resets on every event — fires only after prolonged silence.
108
+ let queryTimer = null;
109
+ const resetQueryTimer = () => {
110
+ if (queryTimer) clearTimeout(queryTimer);
111
+ queryTimer = setTimeout(() => {
112
+ if (currentAbort) {
113
+ console.error(`[Unify] query timeout after ${QUERY_TIMEOUT_MS / 1000}s of silence — aborting`);
114
+ currentAbort.abort();
115
+ }
116
+ }, QUERY_TIMEOUT_MS);
117
+ };
118
+ resetQueryTimer();
119
+
120
+ try {
103
121
  // ─── Stream Engine events → claude_output format ──
104
122
  for await (const event of session.engine.query({
105
123
  prompt,
106
124
  mode: currentMode,
107
125
  signal: currentAbort.signal,
108
126
  })) {
127
+ // Reset timeout on every event — activity means the query is alive
128
+ resetQueryTimer();
109
129
  switch (event.type) {
110
130
  // ── Text streaming ──
111
131
  case 'text_delta':
@@ -261,9 +281,29 @@ export async function handleUnifyChat(msg) {
261
281
  result_text: '',
262
282
  });
263
283
 
284
+ } finally {
285
+ // Always clear the timeout guard
286
+ if (queryTimer) clearTimeout(queryTimer);
287
+ }
288
+
264
289
  } catch (err) {
265
- // Don't report abort errors
266
- if (err.name === 'AbortError') return;
290
+ // Don't report abort errors — but still send result to unblock frontend
291
+ if (err.name === 'AbortError') {
292
+ sendUnifyOutput({
293
+ type: 'assistant',
294
+ message: {
295
+ content: [{
296
+ type: 'text',
297
+ text: '⚠️ Query timed out — no response from LLM. Please try again.',
298
+ }],
299
+ },
300
+ });
301
+ sendUnifyOutput({
302
+ type: 'result',
303
+ result_text: '',
304
+ });
305
+ return;
306
+ }
267
307
 
268
308
  console.error('[Unify] query error:', err.message);
269
309
  sendUnifyOutput({