@kenkaiiii/gg-agent 5.8.0 → 5.8.2

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/dist/index.cjs CHANGED
@@ -214,7 +214,7 @@ function abortableSleep(ms, signal) {
214
214
  async function* agentLoop(messages, options) {
215
215
  const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
216
216
  const maxContinuations = options.maxContinuations ?? 5;
217
- const toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
217
+ let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
218
218
  const totalUsage = { inputTokens: 0, outputTokens: 0 };
219
219
  let turn = 0;
220
220
  let hitMaxTurns = false;
@@ -236,6 +236,8 @@ async function* agentLoop(messages, options) {
236
236
  const MAX_OVERFLOW_COMPACTIONS = 2;
237
237
  const STALL_RETRIES_BEFORE_NON_STREAMING = 2;
238
238
  const STALL_DELAY_MS = 1e3;
239
+ const MIN_PARTIAL_PRESERVE_CHARS = 200;
240
+ const PARTIAL_CONTINUATION_PROMPT = "[Your previous response was cut off by a connection failure. The text above is what was already delivered to the user. Continue exactly from where it stopped \u2014 do not repeat or restart it.]";
239
241
  const OVERLOAD_BASE_DELAY_MS = 2e3;
240
242
  const OVERLOAD_MAX_DELAY_MS = 3e4;
241
243
  const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
@@ -254,6 +256,7 @@ async function* agentLoop(messages, options) {
254
256
  while (turn < maxTurns) {
255
257
  options.signal?.throwIfAborted();
256
258
  turn++;
259
+ toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
257
260
  if (_diagFn) {
258
261
  let msgChars = 0;
259
262
  for (const m of messages) {
@@ -310,6 +313,7 @@ async function* agentLoop(messages, options) {
310
313
  let toolcallDeltaChars = 0;
311
314
  let toolcallDeltaCount = 0;
312
315
  let runawayDetected = null;
316
+ let attemptText = "";
313
317
  let lastYieldEndTime = Date.now();
314
318
  let maxConsumerLagMs = 0;
315
319
  const forwardAbort = () => streamController.abort();
@@ -430,6 +434,7 @@ async function* agentLoop(messages, options) {
430
434
  idleTimer = null;
431
435
  }
432
436
  if (event.type === "text_delta") {
437
+ attemptText += event.text;
433
438
  yield { type: "text_delta", text: event.text };
434
439
  } else if (event.type === "thinking_delta") {
435
440
  yield { type: "thinking_delta", text: event.text };
@@ -631,13 +636,23 @@ async function* agentLoop(messages, options) {
631
636
  });
632
637
  }
633
638
  const delayMs = Math.min(STALL_DELAY_MS * 2 ** (stallRetries - 1), 8e3);
639
+ let preservedChars = 0;
640
+ if (attemptText.length >= MIN_PARTIAL_PRESERVE_CHARS && toolcallDeltaCount === 0) {
641
+ messages.push({
642
+ role: "assistant",
643
+ content: [{ type: "text", text: attemptText }]
644
+ });
645
+ messages.push({ role: "user", content: PARTIAL_CONTINUATION_PROMPT });
646
+ preservedChars = attemptText.length;
647
+ }
634
648
  diag("retry", {
635
649
  reason: cause,
636
650
  attempt: stallRetries,
637
651
  maxAttempts: MAX_STALL_RETRIES,
638
652
  delayMs,
639
653
  events: streamEventCount,
640
- nonStreaming: useNonStreamingFallback
654
+ nonStreaming: useNonStreamingFallback,
655
+ preservedChars
641
656
  });
642
657
  yield {
643
658
  type: "retry",
@@ -645,7 +660,8 @@ async function* agentLoop(messages, options) {
645
660
  attempt: stallRetries,
646
661
  maxAttempts: MAX_STALL_RETRIES,
647
662
  delayMs,
648
- silent: stallRetries <= 2
663
+ silent: stallRetries <= 2,
664
+ ...preservedChars > 0 ? { preservedChars } : {}
649
665
  };
650
666
  await abortableSleep(delayMs, options.signal);
651
667
  turn--;