@kenkaiiii/gg-agent 5.4.1 → 5.4.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
@@ -227,6 +227,7 @@ async function* agentLoop(messages, options) {
227
227
  let overflowCompactionAttempts = 0;
228
228
  let toolResultTruncationAttempted = false;
229
229
  const invalidToolArgumentCounts = /* @__PURE__ */ new Map();
230
+ let toolArgumentAutoContinueUsed = false;
230
231
  let useNonStreamingFallback = false;
231
232
  const MAX_OVERLOAD_RETRIES = 10;
232
233
  const MAX_EMPTY_RESPONSE_RETRIES = 2;
@@ -793,8 +794,12 @@ async function* agentLoop(messages, options) {
793
794
  }
794
795
  }
795
796
  let fatalToolArgumentError = null;
796
- const markFatalToolArgumentError = (error) => {
797
+ let fatalToolArgumentRecoverable = false;
798
+ let fatalToolArgumentToolName = "";
799
+ const markFatalToolArgumentError = (error, recoverable, toolName) => {
797
800
  fatalToolArgumentError = error;
801
+ fatalToolArgumentRecoverable = recoverable;
802
+ fatalToolArgumentToolName = toolName;
798
803
  };
799
804
  const executionOptions = {
800
805
  signal: options.signal,
@@ -810,8 +815,24 @@ async function* agentLoop(messages, options) {
810
815
  messages.push({ role: "tool", content: executionResult.toolResults });
811
816
  const toolsAborted = executionResult.aborted;
812
817
  if (fatalToolArgumentError) {
813
- yield { type: "error", error: fatalToolArgumentError };
814
- break;
818
+ if (fatalToolArgumentRecoverable && !toolArgumentAutoContinueUsed) {
819
+ toolArgumentAutoContinueUsed = true;
820
+ for (const key of invalidToolArgumentCounts.keys()) {
821
+ if (key.startsWith(`${fatalToolArgumentToolName}:`))
822
+ invalidToolArgumentCounts.delete(key);
823
+ }
824
+ yield {
825
+ type: "retry",
826
+ reason: "tool_argument_glitch",
827
+ attempt: 1,
828
+ maxAttempts: 1,
829
+ delayMs: 0,
830
+ silent: false
831
+ };
832
+ } else {
833
+ yield { type: "error", error: fatalToolArgumentError };
834
+ break;
835
+ }
815
836
  }
816
837
  if (toolsAborted) break;
817
838
  if (options.getSteeringMessages) {
@@ -896,10 +917,17 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
896
917
  resultContent = `Invalid arguments for tool \`${toolCall.name}\`:
897
918
  ` + prettyError + "\nRe-issue the call with each field as the correct type.";
898
919
  if (failureCount >= 3) {
920
+ const recoverable = Object.keys(toolCall.args ?? {}).length === 0;
899
921
  options.markFatalToolArgumentError(
900
- new Error(
901
- `The model repeatedly issued invalid arguments for tool \`${toolCall.name}\`. This is usually an upstream model/tool-calling bug. Your conversation is preserved; send another message or switch models to continue.`
902
- )
922
+ new import_gg_ai.GGAIError(
923
+ `The model repeatedly issued invalid arguments for tool \`${toolCall.name}\`. This is usually an upstream model/tool-calling bug` + (recoverable ? " (the provider's stream returned empty tool-call arguments)" : "") + `. Your conversation is preserved; send another message or switch models to continue.`,
924
+ {
925
+ source: "provider",
926
+ hint: "This is the model/provider's fault, not a ggcoder bug. " + (recoverable ? "ggcoder already retried automatically once; if it recurs, send another message or switch models." : "Send another message or switch models to continue.")
927
+ }
928
+ ),
929
+ recoverable,
930
+ toolCall.name
903
931
  );
904
932
  }
905
933
  } else {