@kenkaiiii/gg-agent 5.4.1 → 5.4.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.cjs CHANGED
@@ -217,6 +217,7 @@ async function* agentLoop(messages, options) {
217
217
  const toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
218
218
  const totalUsage = { inputTokens: 0, outputTokens: 0 };
219
219
  let turn = 0;
220
+ let hitMaxTurns = false;
220
221
  let firstTurn = true;
221
222
  let consecutivePauses = 0;
222
223
  let toolPairingRepaired = false;
@@ -227,6 +228,7 @@ async function* agentLoop(messages, options) {
227
228
  let overflowCompactionAttempts = 0;
228
229
  let toolResultTruncationAttempted = false;
229
230
  const invalidToolArgumentCounts = /* @__PURE__ */ new Map();
231
+ let toolArgumentAutoContinueUsed = false;
230
232
  let useNonStreamingFallback = false;
231
233
  const MAX_OVERLOAD_RETRIES = 10;
232
234
  const MAX_EMPTY_RESPONSE_RETRIES = 2;
@@ -793,8 +795,12 @@ async function* agentLoop(messages, options) {
793
795
  }
794
796
  }
795
797
  let fatalToolArgumentError = null;
796
- const markFatalToolArgumentError = (error) => {
798
+ let fatalToolArgumentRecoverable = false;
799
+ let fatalToolArgumentToolName = "";
800
+ const markFatalToolArgumentError = (error, recoverable, toolName) => {
797
801
  fatalToolArgumentError = error;
802
+ fatalToolArgumentRecoverable = recoverable;
803
+ fatalToolArgumentToolName = toolName;
798
804
  };
799
805
  const executionOptions = {
800
806
  signal: options.signal,
@@ -810,8 +816,24 @@ async function* agentLoop(messages, options) {
810
816
  messages.push({ role: "tool", content: executionResult.toolResults });
811
817
  const toolsAborted = executionResult.aborted;
812
818
  if (fatalToolArgumentError) {
813
- yield { type: "error", error: fatalToolArgumentError };
814
- break;
819
+ if (fatalToolArgumentRecoverable && !toolArgumentAutoContinueUsed) {
820
+ toolArgumentAutoContinueUsed = true;
821
+ for (const key of invalidToolArgumentCounts.keys()) {
822
+ if (key.startsWith(`${fatalToolArgumentToolName}:`))
823
+ invalidToolArgumentCounts.delete(key);
824
+ }
825
+ yield {
826
+ type: "retry",
827
+ reason: "tool_argument_glitch",
828
+ attempt: 1,
829
+ maxAttempts: 1,
830
+ delayMs: 0,
831
+ silent: false
832
+ };
833
+ } else {
834
+ yield { type: "error", error: fatalToolArgumentError };
835
+ break;
836
+ }
815
837
  }
816
838
  if (toolsAborted) break;
817
839
  if (options.getSteeringMessages) {
@@ -823,6 +845,9 @@ async function* agentLoop(messages, options) {
823
845
  }
824
846
  }
825
847
  }
848
+ if (turn >= maxTurns) {
849
+ hitMaxTurns = true;
850
+ }
826
851
  }
827
852
  } finally {
828
853
  sanitizeOrphanedServerTools(messages);
@@ -834,6 +859,19 @@ async function* agentLoop(messages, options) {
834
859
  break;
835
860
  }
836
861
  }
862
+ if (hitMaxTurns) {
863
+ diag("max_turns_reached", {
864
+ turn,
865
+ maxTurns,
866
+ provider: options.provider,
867
+ model: options.model
868
+ });
869
+ yield {
870
+ type: "max_turns",
871
+ totalTurns: turn,
872
+ maxTurns
873
+ };
874
+ }
837
875
  yield {
838
876
  type: "agent_done",
839
877
  totalTurns: turn,
@@ -896,10 +934,17 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
896
934
  resultContent = `Invalid arguments for tool \`${toolCall.name}\`:
897
935
  ` + prettyError + "\nRe-issue the call with each field as the correct type.";
898
936
  if (failureCount >= 3) {
937
+ const recoverable = Object.keys(toolCall.args ?? {}).length === 0;
899
938
  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
- )
939
+ new import_gg_ai.GGAIError(
940
+ `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.`,
941
+ {
942
+ source: "provider",
943
+ 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.")
944
+ }
945
+ ),
946
+ recoverable,
947
+ toolCall.name
903
948
  );
904
949
  }
905
950
  } else {