@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 +51 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +52 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -60,9 +60,21 @@ interface AgentDoneEvent {
|
|
|
60
60
|
totalTurns: number;
|
|
61
61
|
totalUsage: Usage;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Terminal signal emitted when the loop stops because it exhausted its turn
|
|
65
|
+
* budget (`maxTurns`) mid-task — i.e. the model still wanted to run tools but
|
|
66
|
+
* ran out of turns. Distinguishes a hard cut-off from a clean completion so
|
|
67
|
+
* callers (e.g. the subagent spawner) can tell the parent the output may be
|
|
68
|
+
* incomplete. Yielded immediately before the final `agent_done`.
|
|
69
|
+
*/
|
|
70
|
+
interface AgentMaxTurnsEvent {
|
|
71
|
+
type: "max_turns";
|
|
72
|
+
totalTurns: number;
|
|
73
|
+
maxTurns: number;
|
|
74
|
+
}
|
|
63
75
|
interface AgentRetryEvent {
|
|
64
76
|
type: "retry";
|
|
65
|
-
reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact";
|
|
77
|
+
reason: "overloaded" | "rate_limit" | "provider_error" | "empty_response" | "stream_stall" | "overflow_compact" | "tool_argument_glitch";
|
|
66
78
|
attempt: number;
|
|
67
79
|
maxAttempts: number;
|
|
68
80
|
delayMs: number;
|
|
@@ -101,7 +113,7 @@ interface AgentFollowUpMessageEvent {
|
|
|
101
113
|
type: "follow_up_message";
|
|
102
114
|
content: Message["content"];
|
|
103
115
|
}
|
|
104
|
-
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentErrorEvent;
|
|
116
|
+
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentErrorEvent;
|
|
105
117
|
interface AgentOptions {
|
|
106
118
|
provider: StreamOptions["provider"];
|
|
107
119
|
model: string;
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { ZodError, prettifyError } from "zod";
|
|
|
6
6
|
import {
|
|
7
7
|
stream,
|
|
8
8
|
EventStream,
|
|
9
|
+
GGAIError,
|
|
9
10
|
isHardBillingMessage
|
|
10
11
|
} from "@kenkaiiii/gg-ai";
|
|
11
12
|
var DEFAULT_MAX_TURNS = 300;
|
|
@@ -188,6 +189,7 @@ async function* agentLoop(messages, options) {
|
|
|
188
189
|
const toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
189
190
|
const totalUsage = { inputTokens: 0, outputTokens: 0 };
|
|
190
191
|
let turn = 0;
|
|
192
|
+
let hitMaxTurns = false;
|
|
191
193
|
let firstTurn = true;
|
|
192
194
|
let consecutivePauses = 0;
|
|
193
195
|
let toolPairingRepaired = false;
|
|
@@ -198,6 +200,7 @@ async function* agentLoop(messages, options) {
|
|
|
198
200
|
let overflowCompactionAttempts = 0;
|
|
199
201
|
let toolResultTruncationAttempted = false;
|
|
200
202
|
const invalidToolArgumentCounts = /* @__PURE__ */ new Map();
|
|
203
|
+
let toolArgumentAutoContinueUsed = false;
|
|
201
204
|
let useNonStreamingFallback = false;
|
|
202
205
|
const MAX_OVERLOAD_RETRIES = 10;
|
|
203
206
|
const MAX_EMPTY_RESPONSE_RETRIES = 2;
|
|
@@ -764,8 +767,12 @@ async function* agentLoop(messages, options) {
|
|
|
764
767
|
}
|
|
765
768
|
}
|
|
766
769
|
let fatalToolArgumentError = null;
|
|
767
|
-
|
|
770
|
+
let fatalToolArgumentRecoverable = false;
|
|
771
|
+
let fatalToolArgumentToolName = "";
|
|
772
|
+
const markFatalToolArgumentError = (error, recoverable, toolName) => {
|
|
768
773
|
fatalToolArgumentError = error;
|
|
774
|
+
fatalToolArgumentRecoverable = recoverable;
|
|
775
|
+
fatalToolArgumentToolName = toolName;
|
|
769
776
|
};
|
|
770
777
|
const executionOptions = {
|
|
771
778
|
signal: options.signal,
|
|
@@ -781,8 +788,24 @@ async function* agentLoop(messages, options) {
|
|
|
781
788
|
messages.push({ role: "tool", content: executionResult.toolResults });
|
|
782
789
|
const toolsAborted = executionResult.aborted;
|
|
783
790
|
if (fatalToolArgumentError) {
|
|
784
|
-
|
|
785
|
-
|
|
791
|
+
if (fatalToolArgumentRecoverable && !toolArgumentAutoContinueUsed) {
|
|
792
|
+
toolArgumentAutoContinueUsed = true;
|
|
793
|
+
for (const key of invalidToolArgumentCounts.keys()) {
|
|
794
|
+
if (key.startsWith(`${fatalToolArgumentToolName}:`))
|
|
795
|
+
invalidToolArgumentCounts.delete(key);
|
|
796
|
+
}
|
|
797
|
+
yield {
|
|
798
|
+
type: "retry",
|
|
799
|
+
reason: "tool_argument_glitch",
|
|
800
|
+
attempt: 1,
|
|
801
|
+
maxAttempts: 1,
|
|
802
|
+
delayMs: 0,
|
|
803
|
+
silent: false
|
|
804
|
+
};
|
|
805
|
+
} else {
|
|
806
|
+
yield { type: "error", error: fatalToolArgumentError };
|
|
807
|
+
break;
|
|
808
|
+
}
|
|
786
809
|
}
|
|
787
810
|
if (toolsAborted) break;
|
|
788
811
|
if (options.getSteeringMessages) {
|
|
@@ -794,6 +817,9 @@ async function* agentLoop(messages, options) {
|
|
|
794
817
|
}
|
|
795
818
|
}
|
|
796
819
|
}
|
|
820
|
+
if (turn >= maxTurns) {
|
|
821
|
+
hitMaxTurns = true;
|
|
822
|
+
}
|
|
797
823
|
}
|
|
798
824
|
} finally {
|
|
799
825
|
sanitizeOrphanedServerTools(messages);
|
|
@@ -805,6 +831,19 @@ async function* agentLoop(messages, options) {
|
|
|
805
831
|
break;
|
|
806
832
|
}
|
|
807
833
|
}
|
|
834
|
+
if (hitMaxTurns) {
|
|
835
|
+
diag("max_turns_reached", {
|
|
836
|
+
turn,
|
|
837
|
+
maxTurns,
|
|
838
|
+
provider: options.provider,
|
|
839
|
+
model: options.model
|
|
840
|
+
});
|
|
841
|
+
yield {
|
|
842
|
+
type: "max_turns",
|
|
843
|
+
totalTurns: turn,
|
|
844
|
+
maxTurns
|
|
845
|
+
};
|
|
846
|
+
}
|
|
808
847
|
yield {
|
|
809
848
|
type: "agent_done",
|
|
810
849
|
totalTurns: turn,
|
|
@@ -867,10 +906,17 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
|
|
|
867
906
|
resultContent = `Invalid arguments for tool \`${toolCall.name}\`:
|
|
868
907
|
` + prettyError + "\nRe-issue the call with each field as the correct type.";
|
|
869
908
|
if (failureCount >= 3) {
|
|
909
|
+
const recoverable = Object.keys(toolCall.args ?? {}).length === 0;
|
|
870
910
|
options.markFatalToolArgumentError(
|
|
871
|
-
new
|
|
872
|
-
`The model repeatedly issued invalid arguments for tool \`${toolCall.name}\`. This is usually an upstream model/tool-calling bug
|
|
873
|
-
|
|
911
|
+
new GGAIError(
|
|
912
|
+
`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.`,
|
|
913
|
+
{
|
|
914
|
+
source: "provider",
|
|
915
|
+
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.")
|
|
916
|
+
}
|
|
917
|
+
),
|
|
918
|
+
recoverable,
|
|
919
|
+
toolCall.name
|
|
874
920
|
);
|
|
875
921
|
}
|
|
876
922
|
} else {
|