@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.js CHANGED
@@ -186,7 +186,7 @@ function abortableSleep(ms, signal) {
186
186
  async function* agentLoop(messages, options) {
187
187
  const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
188
188
  const maxContinuations = options.maxContinuations ?? 5;
189
- const toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
189
+ let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
190
190
  const totalUsage = { inputTokens: 0, outputTokens: 0 };
191
191
  let turn = 0;
192
192
  let hitMaxTurns = false;
@@ -208,6 +208,8 @@ async function* agentLoop(messages, options) {
208
208
  const MAX_OVERFLOW_COMPACTIONS = 2;
209
209
  const STALL_RETRIES_BEFORE_NON_STREAMING = 2;
210
210
  const STALL_DELAY_MS = 1e3;
211
+ const MIN_PARTIAL_PRESERVE_CHARS = 200;
212
+ 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.]";
211
213
  const OVERLOAD_BASE_DELAY_MS = 2e3;
212
214
  const OVERLOAD_MAX_DELAY_MS = 3e4;
213
215
  const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
@@ -226,6 +228,7 @@ async function* agentLoop(messages, options) {
226
228
  while (turn < maxTurns) {
227
229
  options.signal?.throwIfAborted();
228
230
  turn++;
231
+ toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
229
232
  if (_diagFn) {
230
233
  let msgChars = 0;
231
234
  for (const m of messages) {
@@ -282,6 +285,7 @@ async function* agentLoop(messages, options) {
282
285
  let toolcallDeltaChars = 0;
283
286
  let toolcallDeltaCount = 0;
284
287
  let runawayDetected = null;
288
+ let attemptText = "";
285
289
  let lastYieldEndTime = Date.now();
286
290
  let maxConsumerLagMs = 0;
287
291
  const forwardAbort = () => streamController.abort();
@@ -402,6 +406,7 @@ async function* agentLoop(messages, options) {
402
406
  idleTimer = null;
403
407
  }
404
408
  if (event.type === "text_delta") {
409
+ attemptText += event.text;
405
410
  yield { type: "text_delta", text: event.text };
406
411
  } else if (event.type === "thinking_delta") {
407
412
  yield { type: "thinking_delta", text: event.text };
@@ -603,13 +608,23 @@ async function* agentLoop(messages, options) {
603
608
  });
604
609
  }
605
610
  const delayMs = Math.min(STALL_DELAY_MS * 2 ** (stallRetries - 1), 8e3);
611
+ let preservedChars = 0;
612
+ if (attemptText.length >= MIN_PARTIAL_PRESERVE_CHARS && toolcallDeltaCount === 0) {
613
+ messages.push({
614
+ role: "assistant",
615
+ content: [{ type: "text", text: attemptText }]
616
+ });
617
+ messages.push({ role: "user", content: PARTIAL_CONTINUATION_PROMPT });
618
+ preservedChars = attemptText.length;
619
+ }
606
620
  diag("retry", {
607
621
  reason: cause,
608
622
  attempt: stallRetries,
609
623
  maxAttempts: MAX_STALL_RETRIES,
610
624
  delayMs,
611
625
  events: streamEventCount,
612
- nonStreaming: useNonStreamingFallback
626
+ nonStreaming: useNonStreamingFallback,
627
+ preservedChars
613
628
  });
614
629
  yield {
615
630
  type: "retry",
@@ -617,7 +632,8 @@ async function* agentLoop(messages, options) {
617
632
  attempt: stallRetries,
618
633
  maxAttempts: MAX_STALL_RETRIES,
619
634
  delayMs,
620
- silent: stallRetries <= 2
635
+ silent: stallRetries <= 2,
636
+ ...preservedChars > 0 ? { preservedChars } : {}
621
637
  };
622
638
  await abortableSleep(delayMs, options.signal);
623
639
  turn--;