@acmecloud/core 1.0.10 → 1.0.11

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.
@@ -280,45 +280,39 @@ export async function* runAgent(provider, modelName, messages, systemPrompt, abo
280
280
  yield { type: "messages", messages: currentMessages };
281
281
  return [];
282
282
  }
283
- else {
284
- // Check if this is a content safety error (should not retry)
285
- const errorMessage = err.message?.toLowerCase() || "";
286
- const isContentSafetyError = errorMessage.includes("sensitive_words_detected") ||
287
- errorMessage.includes("content_policy") ||
288
- errorMessage.includes("safety") ||
289
- errorMessage.includes("content_filter");
290
- if (isContentSafetyError) {
291
- // Content safety errors should not be retried - they won't succeed by retrying
292
- yield {
293
- type: "text",
294
- text: `\n[Content Safety Error: ${err.message}]\n\nThis request triggered the content safety filter. Please modify your request to avoid sensitive topics and try again.\n`,
295
- };
296
- yield { type: "messages", messages: currentMessages };
297
- return [];
298
- }
283
+ // Check if this is a content safety error (should not retry)
284
+ const errorMessage = err.message?.toLowerCase() || "";
285
+ const isContentSafetyError = errorMessage.includes("sensitive_words_detected") ||
286
+ errorMessage.includes("content_policy") ||
287
+ errorMessage.includes("safety") ||
288
+ errorMessage.includes("content_filter");
289
+ if (isContentSafetyError) {
290
+ // Content safety errors should not be retried - they won't succeed by retrying
299
291
  yield {
300
292
  type: "text",
301
- text: `\n[Error: ${err.message}]\n[Auto-recovering from stream drop...]\n`,
293
+ text: `\n[Content Safety Error: ${err.message}]\n\nThis request triggered the content safety filter. Please modify your request to avoid sensitive topics and try again.\n`,
302
294
  };
303
- if (stepText.trim()) {
304
- currentMessages.push({ role: "assistant", content: stepText });
305
- }
306
- consecutiveErrors++;
307
- if (consecutiveErrors >= 3) {
308
- yield {
309
- type: "text",
310
- text: `\n[Fatal Error: Stream dropped ${consecutiveErrors} times consecutively. Halting agent to prevent infinite loops.]\n`,
311
- };
312
- yield { type: "messages", messages: currentMessages };
313
- return [];
314
- }
315
- currentMessages.push({
316
- role: "user",
317
- content: `[System Error: The network stream disconnected prematurely with error: ${err.message || err}. Please carefully analyze the incomplete text you just generated, and continue your thought or tool execution precisely from where it was cut off without repeating yourself.]`,
318
- });
319
- await new Promise((resolve) => setTimeout(resolve, 2000));
320
- continue;
295
+ yield { type: "messages", messages: currentMessages };
296
+ return [];
297
+ }
298
+ // For all other errors (network issues, timeout, server errors), auto-recover indefinitely
299
+ yield {
300
+ type: "text",
301
+ text: `\n[Error: ${err.message}]\n[Auto-recovering from stream drop...]\n`,
302
+ };
303
+ if (stepText.trim()) {
304
+ currentMessages.push({ role: "assistant", content: stepText });
321
305
  }
306
+ consecutiveErrors++;
307
+ // Add system message to prompt the model to continue
308
+ currentMessages.push({
309
+ role: "user",
310
+ content: `[System Error: The network stream disconnected prematurely with error: ${err.message || err}. Please carefully analyze the incomplete text you just generated, and continue your thought or tool execution precisely from where it was cut off without repeating yourself.]`,
311
+ });
312
+ // Exponential backoff: 2s, 4s, 8s, max 30s
313
+ const delay = Math.min(2000 * Math.pow(2, Math.min(consecutiveErrors - 1, 3)), 30000);
314
+ await new Promise((resolve) => setTimeout(resolve, delay));
315
+ continue;
322
316
  }
323
317
  if (collectedToolCalls.length === 0) {
324
318
  const parseText = stepText
@@ -427,6 +421,7 @@ export async function* runAgent(provider, modelName, messages, systemPrompt, abo
427
421
  }
428
422
  if (collectedToolCalls.length === 0) {
429
423
  if (!stepText.trim()) {
424
+ // Empty response - retry a few times
430
425
  consecutiveErrors++;
431
426
  if (consecutiveErrors < 3) {
432
427
  yield {
@@ -450,9 +445,17 @@ export async function* runAgent(provider, modelName, messages, systemPrompt, abo
450
445
  return [];
451
446
  }
452
447
  }
448
+ // Model returned text but no tool calls
449
+ // This is normal - the model might be providing explanation or asking for clarification
450
+ // Add the response to history and continue the loop to let model continue working
453
451
  currentMessages.push({ role: "assistant", content: stepText });
454
- yield { type: "messages", messages: currentMessages };
455
- return [];
452
+ // Add a system prompt to encourage the model to continue if task is not complete
453
+ currentMessages.push({
454
+ role: "user",
455
+ content: `[System] You provided some output but did not complete the task. Please continue working on the task or explain what you need from the user. If you need to use tools, please do so now.`,
456
+ });
457
+ // Continue the loop instead of returning
458
+ continue;
456
459
  }
457
460
  yield { type: "text", text: "\n" };
458
461
  const toolSummary = collectedToolResults
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acmecloud/core",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -362,52 +362,51 @@ export async function* runAgent(
362
362
  yield { type: "text", text: "\n[Aborted by user]\n" };
363
363
  yield { type: "messages", messages: currentMessages };
364
364
  return [];
365
- } else {
366
- // Check if this is a content safety error (should not retry)
367
- const errorMessage = err.message?.toLowerCase() || "";
368
- const isContentSafetyError =
369
- errorMessage.includes("sensitive_words_detected") ||
370
- errorMessage.includes("content_policy") ||
371
- errorMessage.includes("safety") ||
372
- errorMessage.includes("content_filter");
373
-
374
- if (isContentSafetyError) {
375
- // Content safety errors should not be retried - they won't succeed by retrying
376
- yield {
377
- type: "text",
378
- text: `\n[Content Safety Error: ${err.message}]\n\nThis request triggered the content safety filter. Please modify your request to avoid sensitive topics and try again.\n`,
379
- };
380
- yield { type: "messages", messages: currentMessages };
381
- return [];
382
- }
365
+ }
383
366
 
367
+ // Check if this is a content safety error (should not retry)
368
+ const errorMessage = err.message?.toLowerCase() || "";
369
+ const isContentSafetyError =
370
+ errorMessage.includes("sensitive_words_detected") ||
371
+ errorMessage.includes("content_policy") ||
372
+ errorMessage.includes("safety") ||
373
+ errorMessage.includes("content_filter");
374
+
375
+ if (isContentSafetyError) {
376
+ // Content safety errors should not be retried - they won't succeed by retrying
384
377
  yield {
385
378
  type: "text",
386
- text: `\n[Error: ${err.message}]\n[Auto-recovering from stream drop...]\n`,
379
+ text: `\n[Content Safety Error: ${err.message}]\n\nThis request triggered the content safety filter. Please modify your request to avoid sensitive topics and try again.\n`,
387
380
  };
381
+ yield { type: "messages", messages: currentMessages };
382
+ return [];
383
+ }
388
384
 
389
- if (stepText.trim()) {
390
- currentMessages.push({ role: "assistant", content: stepText });
391
- }
385
+ // For all other errors (network issues, timeout, server errors), auto-recover indefinitely
386
+ yield {
387
+ type: "text",
388
+ text: `\n[Error: ${err.message}]\n[Auto-recovering from stream drop...]\n`,
389
+ };
392
390
 
393
- consecutiveErrors++;
394
- if (consecutiveErrors >= 3) {
395
- yield {
396
- type: "text",
397
- text: `\n[Fatal Error: Stream dropped ${consecutiveErrors} times consecutively. Halting agent to prevent infinite loops.]\n`,
398
- };
399
- yield { type: "messages", messages: currentMessages };
400
- return [];
401
- }
391
+ if (stepText.trim()) {
392
+ currentMessages.push({ role: "assistant", content: stepText });
393
+ }
402
394
 
403
- currentMessages.push({
404
- role: "user",
405
- content: `[System Error: The network stream disconnected prematurely with error: ${err.message || err}. Please carefully analyze the incomplete text you just generated, and continue your thought or tool execution precisely from where it was cut off without repeating yourself.]`,
406
- });
395
+ consecutiveErrors++;
407
396
 
408
- await new Promise((resolve) => setTimeout(resolve, 2000));
409
- continue;
410
- }
397
+ // Add system message to prompt the model to continue
398
+ currentMessages.push({
399
+ role: "user",
400
+ content: `[System Error: The network stream disconnected prematurely with error: ${err.message || err}. Please carefully analyze the incomplete text you just generated, and continue your thought or tool execution precisely from where it was cut off without repeating yourself.]`,
401
+ });
402
+
403
+ // Exponential backoff: 2s, 4s, 8s, max 30s
404
+ const delay = Math.min(
405
+ 2000 * Math.pow(2, Math.min(consecutiveErrors - 1, 3)),
406
+ 30000,
407
+ );
408
+ await new Promise((resolve) => setTimeout(resolve, delay));
409
+ continue;
411
410
  }
412
411
 
413
412
  if (collectedToolCalls.length === 0) {
@@ -529,6 +528,7 @@ export async function* runAgent(
529
528
 
530
529
  if (collectedToolCalls.length === 0) {
531
530
  if (!stepText.trim()) {
531
+ // Empty response - retry a few times
532
532
  consecutiveErrors++;
533
533
  if (consecutiveErrors < 3) {
534
534
  yield {
@@ -552,9 +552,19 @@ export async function* runAgent(
552
552
  }
553
553
  }
554
554
 
555
+ // Model returned text but no tool calls
556
+ // This is normal - the model might be providing explanation or asking for clarification
557
+ // Add the response to history and continue the loop to let model continue working
555
558
  currentMessages.push({ role: "assistant", content: stepText });
556
- yield { type: "messages", messages: currentMessages };
557
- return [];
559
+
560
+ // Add a system prompt to encourage the model to continue if task is not complete
561
+ currentMessages.push({
562
+ role: "user",
563
+ content: `[System] You provided some output but did not complete the task. Please continue working on the task or explain what you need from the user. If you need to use tools, please do so now.`,
564
+ });
565
+
566
+ // Continue the loop instead of returning
567
+ continue;
558
568
  }
559
569
 
560
570
  yield { type: "text", text: "\n" };