@kenkaiiii/gg-agent 5.25.0 → 5.26.1
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 +50 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +50 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -87,6 +87,21 @@ interface AgentMaxTurnsEvent {
|
|
|
87
87
|
totalTurns: number;
|
|
88
88
|
maxTurns: number;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Emitted when the loop was about to stop on an exhausted turn budget but the
|
|
92
|
+
* host granted an extension instead. The effective budget is raised and the
|
|
93
|
+
* loop continues with a continuation prompt, so this is NOT terminal — unlike
|
|
94
|
+
* `max_turns`, which still fires if the extended budget is also spent.
|
|
95
|
+
*/
|
|
96
|
+
interface AgentTurnBudgetExtendedEvent {
|
|
97
|
+
type: "turn_budget_extended";
|
|
98
|
+
/** Turn number at which the budget was exhausted. */
|
|
99
|
+
turn: number;
|
|
100
|
+
/** New effective `maxTurns` after the extension. */
|
|
101
|
+
grantedTurns: number;
|
|
102
|
+
/** 1-based extension count for this run. */
|
|
103
|
+
extension: number;
|
|
104
|
+
}
|
|
90
105
|
/**
|
|
91
106
|
* Warning signal emitted when a turn ended on a non-clean stop reason —
|
|
92
107
|
* `max_tokens` (output clipped at the model's output-token limit), `refusal`,
|
|
@@ -148,7 +163,7 @@ interface AgentFollowUpMessageEvent {
|
|
|
148
163
|
type: "follow_up_message";
|
|
149
164
|
content: Message["content"];
|
|
150
165
|
}
|
|
151
|
-
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentTruncatedEvent | AgentErrorEvent;
|
|
166
|
+
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentTurnBudgetExtendedEvent | AgentTruncatedEvent | AgentErrorEvent;
|
|
152
167
|
interface TransformContextOptions {
|
|
153
168
|
/** Force a transform after the provider reports context overflow. */
|
|
154
169
|
force?: boolean;
|
|
@@ -168,6 +183,12 @@ interface AgentOptions {
|
|
|
168
183
|
/** Control whether tools may/must be called, or select a named tool when supported. */
|
|
169
184
|
toolChoice?: StreamOptions["toolChoice"];
|
|
170
185
|
maxTurns?: number;
|
|
186
|
+
/**
|
|
187
|
+
* How many times `onTurnBudgetExhausted` may grant extra turns in one run.
|
|
188
|
+
* Each grant raises the effective budget by the original `maxTurns`.
|
|
189
|
+
* Default: 2. Set 0 to disable extensions entirely.
|
|
190
|
+
*/
|
|
191
|
+
maxTurnExtensions?: number;
|
|
171
192
|
maxTokens?: number;
|
|
172
193
|
temperature?: number;
|
|
173
194
|
thinking?: StreamOptions["thinking"];
|
|
@@ -234,6 +255,18 @@ interface AgentOptions {
|
|
|
234
255
|
* on read.
|
|
235
256
|
*/
|
|
236
257
|
getFollowUpMessages?: () => Promise<Message[] | null> | Message[] | null;
|
|
258
|
+
/**
|
|
259
|
+
* Consulted when a tool-running turn exhausts the turn budget mid-task,
|
|
260
|
+
* before the loop emits the terminal `max_turns` event. Return true to grant
|
|
261
|
+
* another `maxTurns` worth of turns; false (the default when unset) keeps
|
|
262
|
+
* today's hard cut-off. Hosts should only grant on evidence of progress —
|
|
263
|
+
* extending a spinning agent just buys it more tokens to spin with.
|
|
264
|
+
*/
|
|
265
|
+
onTurnBudgetExhausted?: (ctx: {
|
|
266
|
+
turn: number;
|
|
267
|
+
maxTurns: number;
|
|
268
|
+
extension: number;
|
|
269
|
+
}) => Promise<boolean> | boolean;
|
|
237
270
|
}
|
|
238
271
|
interface AgentResult {
|
|
239
272
|
message: AssistantMessage;
|
package/dist/index.d.ts
CHANGED
|
@@ -87,6 +87,21 @@ interface AgentMaxTurnsEvent {
|
|
|
87
87
|
totalTurns: number;
|
|
88
88
|
maxTurns: number;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Emitted when the loop was about to stop on an exhausted turn budget but the
|
|
92
|
+
* host granted an extension instead. The effective budget is raised and the
|
|
93
|
+
* loop continues with a continuation prompt, so this is NOT terminal — unlike
|
|
94
|
+
* `max_turns`, which still fires if the extended budget is also spent.
|
|
95
|
+
*/
|
|
96
|
+
interface AgentTurnBudgetExtendedEvent {
|
|
97
|
+
type: "turn_budget_extended";
|
|
98
|
+
/** Turn number at which the budget was exhausted. */
|
|
99
|
+
turn: number;
|
|
100
|
+
/** New effective `maxTurns` after the extension. */
|
|
101
|
+
grantedTurns: number;
|
|
102
|
+
/** 1-based extension count for this run. */
|
|
103
|
+
extension: number;
|
|
104
|
+
}
|
|
90
105
|
/**
|
|
91
106
|
* Warning signal emitted when a turn ended on a non-clean stop reason —
|
|
92
107
|
* `max_tokens` (output clipped at the model's output-token limit), `refusal`,
|
|
@@ -148,7 +163,7 @@ interface AgentFollowUpMessageEvent {
|
|
|
148
163
|
type: "follow_up_message";
|
|
149
164
|
content: Message["content"];
|
|
150
165
|
}
|
|
151
|
-
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentTruncatedEvent | AgentErrorEvent;
|
|
166
|
+
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentTurnBudgetExtendedEvent | AgentTruncatedEvent | AgentErrorEvent;
|
|
152
167
|
interface TransformContextOptions {
|
|
153
168
|
/** Force a transform after the provider reports context overflow. */
|
|
154
169
|
force?: boolean;
|
|
@@ -168,6 +183,12 @@ interface AgentOptions {
|
|
|
168
183
|
/** Control whether tools may/must be called, or select a named tool when supported. */
|
|
169
184
|
toolChoice?: StreamOptions["toolChoice"];
|
|
170
185
|
maxTurns?: number;
|
|
186
|
+
/**
|
|
187
|
+
* How many times `onTurnBudgetExhausted` may grant extra turns in one run.
|
|
188
|
+
* Each grant raises the effective budget by the original `maxTurns`.
|
|
189
|
+
* Default: 2. Set 0 to disable extensions entirely.
|
|
190
|
+
*/
|
|
191
|
+
maxTurnExtensions?: number;
|
|
171
192
|
maxTokens?: number;
|
|
172
193
|
temperature?: number;
|
|
173
194
|
thinking?: StreamOptions["thinking"];
|
|
@@ -234,6 +255,18 @@ interface AgentOptions {
|
|
|
234
255
|
* on read.
|
|
235
256
|
*/
|
|
236
257
|
getFollowUpMessages?: () => Promise<Message[] | null> | Message[] | null;
|
|
258
|
+
/**
|
|
259
|
+
* Consulted when a tool-running turn exhausts the turn budget mid-task,
|
|
260
|
+
* before the loop emits the terminal `max_turns` event. Return true to grant
|
|
261
|
+
* another `maxTurns` worth of turns; false (the default when unset) keeps
|
|
262
|
+
* today's hard cut-off. Hosts should only grant on evidence of progress —
|
|
263
|
+
* extending a spinning agent just buys it more tokens to spin with.
|
|
264
|
+
*/
|
|
265
|
+
onTurnBudgetExhausted?: (ctx: {
|
|
266
|
+
turn: number;
|
|
267
|
+
maxTurns: number;
|
|
268
|
+
extension: number;
|
|
269
|
+
}) => Promise<boolean> | boolean;
|
|
237
270
|
}
|
|
238
271
|
interface AgentResult {
|
|
239
272
|
message: AssistantMessage;
|
package/dist/index.js
CHANGED
|
@@ -191,6 +191,9 @@ function isTransportFailure(err) {
|
|
|
191
191
|
}
|
|
192
192
|
return false;
|
|
193
193
|
}
|
|
194
|
+
function turnBudgetContinuationPrompt() {
|
|
195
|
+
return "[You reached the turn limit for this segment but the work is not finished, so you have been granted more turns. Before continuing, state in one or two sentences what is already done and what remains, then keep going from there \u2014 do not restart work that is already complete.]";
|
|
196
|
+
}
|
|
194
197
|
function abortableSleep(ms, signal) {
|
|
195
198
|
if (signal?.aborted) {
|
|
196
199
|
return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
@@ -210,6 +213,9 @@ function abortableSleep(ms, signal) {
|
|
|
210
213
|
}
|
|
211
214
|
async function* agentLoop(messages, options) {
|
|
212
215
|
const maxTurns = options.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
216
|
+
let effectiveMaxTurns = maxTurns;
|
|
217
|
+
const maxTurnExtensions = Math.max(0, options.maxTurnExtensions ?? 2);
|
|
218
|
+
let turnExtensions = 0;
|
|
213
219
|
const maxContinuations = options.maxContinuations ?? 5;
|
|
214
220
|
let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
215
221
|
const totalUsage = { inputTokens: 0, outputTokens: 0 };
|
|
@@ -262,7 +268,7 @@ async function* agentLoop(messages, options) {
|
|
|
262
268
|
let firstProviderEventAt;
|
|
263
269
|
let providerDurationMs = 0;
|
|
264
270
|
try {
|
|
265
|
-
while (turn <
|
|
271
|
+
while (turn < effectiveMaxTurns) {
|
|
266
272
|
options.signal?.throwIfAborted();
|
|
267
273
|
turn++;
|
|
268
274
|
if (logicalTurnStartedAt === 0) logicalTurnStartedAt = Date.now();
|
|
@@ -975,8 +981,46 @@ async function* agentLoop(messages, options) {
|
|
|
975
981
|
}
|
|
976
982
|
}
|
|
977
983
|
}
|
|
978
|
-
if (turn >=
|
|
979
|
-
|
|
984
|
+
if (turn >= effectiveMaxTurns) {
|
|
985
|
+
let extended = false;
|
|
986
|
+
if (options.onTurnBudgetExhausted && turnExtensions < maxTurnExtensions) {
|
|
987
|
+
const extension = turnExtensions + 1;
|
|
988
|
+
let granted = false;
|
|
989
|
+
try {
|
|
990
|
+
granted = await options.onTurnBudgetExhausted({
|
|
991
|
+
turn,
|
|
992
|
+
maxTurns: effectiveMaxTurns,
|
|
993
|
+
extension
|
|
994
|
+
});
|
|
995
|
+
} catch {
|
|
996
|
+
granted = false;
|
|
997
|
+
}
|
|
998
|
+
if (granted) {
|
|
999
|
+
turnExtensions = extension;
|
|
1000
|
+
effectiveMaxTurns += maxTurns;
|
|
1001
|
+
extended = true;
|
|
1002
|
+
diag("turn_budget_extended", {
|
|
1003
|
+
turn,
|
|
1004
|
+
grantedTurns: effectiveMaxTurns,
|
|
1005
|
+
extension,
|
|
1006
|
+
provider: options.provider,
|
|
1007
|
+
model: options.model
|
|
1008
|
+
});
|
|
1009
|
+
yield {
|
|
1010
|
+
type: "turn_budget_extended",
|
|
1011
|
+
turn,
|
|
1012
|
+
grantedTurns: effectiveMaxTurns,
|
|
1013
|
+
extension
|
|
1014
|
+
};
|
|
1015
|
+
messages.push({
|
|
1016
|
+
role: "user",
|
|
1017
|
+
content: turnBudgetContinuationPrompt()
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
if (!extended) {
|
|
1022
|
+
hitMaxTurns = true;
|
|
1023
|
+
}
|
|
980
1024
|
}
|
|
981
1025
|
}
|
|
982
1026
|
} finally {
|
|
@@ -992,14 +1036,15 @@ async function* agentLoop(messages, options) {
|
|
|
992
1036
|
if (hitMaxTurns) {
|
|
993
1037
|
diag("max_turns_reached", {
|
|
994
1038
|
turn,
|
|
995
|
-
maxTurns,
|
|
1039
|
+
maxTurns: effectiveMaxTurns,
|
|
1040
|
+
extensions: turnExtensions,
|
|
996
1041
|
provider: options.provider,
|
|
997
1042
|
model: options.model
|
|
998
1043
|
});
|
|
999
1044
|
yield {
|
|
1000
1045
|
type: "max_turns",
|
|
1001
1046
|
totalTurns: turn,
|
|
1002
|
-
maxTurns
|
|
1047
|
+
maxTurns: effectiveMaxTurns
|
|
1003
1048
|
};
|
|
1004
1049
|
}
|
|
1005
1050
|
yield {
|