@kenkaiiii/gg-agent 5.22.2 → 5.22.3

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.d.cts CHANGED
@@ -102,7 +102,7 @@ interface AgentTruncatedEvent {
102
102
  }
103
103
  interface AgentRetryEvent {
104
104
  type: "retry";
105
- reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact" | "tool_argument_glitch";
105
+ reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact" | "tool_argument_glitch" | "runaway_toolcall";
106
106
  attempt: number;
107
107
  maxAttempts: number;
108
108
  delayMs: number;
package/dist/index.d.ts CHANGED
@@ -102,7 +102,7 @@ interface AgentTruncatedEvent {
102
102
  }
103
103
  interface AgentRetryEvent {
104
104
  type: "retry";
105
- reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact" | "tool_argument_glitch";
105
+ reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact" | "tool_argument_glitch" | "runaway_toolcall";
106
106
  attempt: number;
107
107
  maxAttempts: number;
108
108
  delayMs: number;
package/dist/index.js CHANGED
@@ -200,6 +200,7 @@ async function* agentLoop(messages, options) {
200
200
  let overloadRetries = 0;
201
201
  let emptyResponseRetries = 0;
202
202
  let stallRetries = 0;
203
+ let runawayToolcallRetries = 0;
203
204
  let overflowCompactionAttempts = 0;
204
205
  let toolResultTruncationAttempted = false;
205
206
  const invalidToolArgumentCounts = /* @__PURE__ */ new Map();
@@ -208,6 +209,8 @@ async function* agentLoop(messages, options) {
208
209
  const MAX_OVERLOAD_RETRIES = 10;
209
210
  const MAX_EMPTY_RESPONSE_RETRIES = 2;
210
211
  const MAX_STALL_RETRIES = 5;
212
+ const MAX_RUNAWAY_TOOLCALL_RETRIES = 2;
213
+ const RUNAWAY_TOOLCALL_RETRY_DELAY_MS = 1e3;
211
214
  const MAX_OVERFLOW_COMPACTIONS = 2;
212
215
  const STALL_RETRIES_BEFORE_NON_STREAMING = 2;
213
216
  const STALL_DELAY_MS = 1e3;
@@ -612,11 +615,33 @@ async function* agentLoop(messages, options) {
612
615
  provider: options.provider,
613
616
  model: options.model
614
617
  });
618
+ if (runawayToolcallRetries < MAX_RUNAWAY_TOOLCALL_RETRIES) {
619
+ runawayToolcallRetries++;
620
+ const delayMs = RUNAWAY_TOOLCALL_RETRY_DELAY_MS * runawayToolcallRetries;
621
+ diag("retry", {
622
+ reason: "runaway_toolcall",
623
+ attempt: runawayToolcallRetries,
624
+ maxAttempts: MAX_RUNAWAY_TOOLCALL_RETRIES,
625
+ delayMs,
626
+ ...runawayDetected
627
+ });
628
+ yield {
629
+ type: "retry",
630
+ reason: "runaway_toolcall",
631
+ attempt: runawayToolcallRetries,
632
+ maxAttempts: MAX_RUNAWAY_TOOLCALL_RETRIES,
633
+ delayMs,
634
+ silent: true
635
+ };
636
+ await abortableSleep(delayMs, options.signal);
637
+ turn--;
638
+ continue;
639
+ }
615
640
  const detail = runawayDetected.kind === "chars" ? `${(runawayDetected.chars / 1024).toFixed(0)} KB of tool-call arguments` : `${runawayDetected.events} tool-call delta events`;
616
641
  yield {
617
642
  type: "error",
618
643
  error: new Error(
619
- `The model glitched mid-tool-call and produced ${detail} without closing the call. This is usually an upstream model bug \u2014 try the same request again or switch models. Your conversation is preserved.`
644
+ `The model repeatedly failed to close a tool call after ${MAX_RUNAWAY_TOOLCALL_RETRIES} automatic retries (${detail}). Switch models and retry; your conversation is preserved.`
620
645
  )
621
646
  };
622
647
  break;
@@ -717,6 +742,7 @@ async function* agentLoop(messages, options) {
717
742
  }
718
743
  overloadRetries = 0;
719
744
  stallRetries = 0;
745
+ runawayToolcallRetries = 0;
720
746
  const contentArr = Array.isArray(response.message.content) ? response.message.content : null;
721
747
  const hasActionableContent = response.message.content !== "" && contentArr !== null && contentArr.some(
722
748
  (p) => p.type === "text" || p.type === "tool_call" || p.type === "server_tool_call"