@kenkaiiii/gg-agent 5.19.0 → 5.19.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 +50 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -5
- package/dist/index.d.ts +17 -5
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamOptions, Message, Tool, ToolResultContent, ServerToolDefinition,
|
|
1
|
+
import { StreamOptions, Message, Tool, ToolResultContent, ServerToolDefinition, Usage, StopReason, AssistantMessage } from '@kenkaiiii/gg-ai';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
interface StructuredToolResult {
|
|
@@ -136,6 +136,14 @@ interface AgentFollowUpMessageEvent {
|
|
|
136
136
|
content: Message["content"];
|
|
137
137
|
}
|
|
138
138
|
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentErrorEvent;
|
|
139
|
+
interface TransformContextOptions {
|
|
140
|
+
/** Force a transform after the provider reports context overflow. */
|
|
141
|
+
force?: boolean;
|
|
142
|
+
/** Latest successful provider usage, anchored at its assistant message. */
|
|
143
|
+
usage?: Usage;
|
|
144
|
+
/** Messages appended after that usage sample and not yet seen by the provider. */
|
|
145
|
+
pendingMessages: Message[];
|
|
146
|
+
}
|
|
139
147
|
interface AgentOptions {
|
|
140
148
|
provider: StreamOptions["provider"];
|
|
141
149
|
model: string;
|
|
@@ -180,6 +188,10 @@ interface AgentOptions {
|
|
|
180
188
|
clearToolUses?: boolean;
|
|
181
189
|
/** Max characters for a single tool result. Results exceeding this are truncated with a notice. */
|
|
182
190
|
maxToolResultChars?: number;
|
|
191
|
+
/** Aggregate budget for ALL tool results in one assistant turn. Protects
|
|
192
|
+
* against parallel fan-outs injecting huge uncached context in one turn;
|
|
193
|
+
* the largest results are trimmed (water-filling) with a re-run notice. */
|
|
194
|
+
maxTurnToolResultChars?: number;
|
|
183
195
|
/** Max consecutive pause_turn continuations before stopping (default: 5).
|
|
184
196
|
* Prevents infinite loops when server-side tools keep pausing. */
|
|
185
197
|
maxContinuations?: number;
|
|
@@ -188,12 +200,12 @@ interface AgentOptions {
|
|
|
188
200
|
* the messages array (e.g. compaction, truncation). Return the same array
|
|
189
201
|
* for no-op, or a new array to replace the conversation context.
|
|
190
202
|
*
|
|
203
|
+
* The latest provider usage is authoritative for the history through its
|
|
204
|
+
* assistant response. `pendingMessages` contains context appended afterward.
|
|
191
205
|
* When `options.force` is true, the caller should compact unconditionally
|
|
192
206
|
* (e.g. after a context overflow error from the API).
|
|
193
207
|
*/
|
|
194
|
-
transformContext?: (messages: Message[], options
|
|
195
|
-
force?: boolean;
|
|
196
|
-
}) => Message[] | Promise<Message[]>;
|
|
208
|
+
transformContext?: (messages: Message[], options: TransformContextOptions) => Message[] | Promise<Message[]>;
|
|
197
209
|
/**
|
|
198
210
|
* Polled after tool execution completes each turn. Returns user messages
|
|
199
211
|
* to inject into the conversation before the next LLM call (steering).
|
|
@@ -299,4 +311,4 @@ declare function isBillingError(err: unknown): boolean;
|
|
|
299
311
|
declare function isUsageLimitError(err: unknown): boolean;
|
|
300
312
|
declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
|
|
301
313
|
|
|
302
|
-
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
|
|
314
|
+
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamOptions, Message, Tool, ToolResultContent, ServerToolDefinition,
|
|
1
|
+
import { StreamOptions, Message, Tool, ToolResultContent, ServerToolDefinition, Usage, StopReason, AssistantMessage } from '@kenkaiiii/gg-ai';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
interface StructuredToolResult {
|
|
@@ -136,6 +136,14 @@ interface AgentFollowUpMessageEvent {
|
|
|
136
136
|
content: Message["content"];
|
|
137
137
|
}
|
|
138
138
|
type AgentEvent = AgentTextDeltaEvent | AgentThinkingDeltaEvent | AgentToolCallStartEvent | AgentToolCallUpdateEvent | AgentToolCallEndEvent | AgentToolCallDeltaEvent | AgentServerToolCallEvent | AgentServerToolResultEvent | AgentSteeringMessageEvent | AgentFollowUpMessageEvent | AgentRetryEvent | AgentTurnEndEvent | AgentDoneEvent | AgentMaxTurnsEvent | AgentErrorEvent;
|
|
139
|
+
interface TransformContextOptions {
|
|
140
|
+
/** Force a transform after the provider reports context overflow. */
|
|
141
|
+
force?: boolean;
|
|
142
|
+
/** Latest successful provider usage, anchored at its assistant message. */
|
|
143
|
+
usage?: Usage;
|
|
144
|
+
/** Messages appended after that usage sample and not yet seen by the provider. */
|
|
145
|
+
pendingMessages: Message[];
|
|
146
|
+
}
|
|
139
147
|
interface AgentOptions {
|
|
140
148
|
provider: StreamOptions["provider"];
|
|
141
149
|
model: string;
|
|
@@ -180,6 +188,10 @@ interface AgentOptions {
|
|
|
180
188
|
clearToolUses?: boolean;
|
|
181
189
|
/** Max characters for a single tool result. Results exceeding this are truncated with a notice. */
|
|
182
190
|
maxToolResultChars?: number;
|
|
191
|
+
/** Aggregate budget for ALL tool results in one assistant turn. Protects
|
|
192
|
+
* against parallel fan-outs injecting huge uncached context in one turn;
|
|
193
|
+
* the largest results are trimmed (water-filling) with a re-run notice. */
|
|
194
|
+
maxTurnToolResultChars?: number;
|
|
183
195
|
/** Max consecutive pause_turn continuations before stopping (default: 5).
|
|
184
196
|
* Prevents infinite loops when server-side tools keep pausing. */
|
|
185
197
|
maxContinuations?: number;
|
|
@@ -188,12 +200,12 @@ interface AgentOptions {
|
|
|
188
200
|
* the messages array (e.g. compaction, truncation). Return the same array
|
|
189
201
|
* for no-op, or a new array to replace the conversation context.
|
|
190
202
|
*
|
|
203
|
+
* The latest provider usage is authoritative for the history through its
|
|
204
|
+
* assistant response. `pendingMessages` contains context appended afterward.
|
|
191
205
|
* When `options.force` is true, the caller should compact unconditionally
|
|
192
206
|
* (e.g. after a context overflow error from the API).
|
|
193
207
|
*/
|
|
194
|
-
transformContext?: (messages: Message[], options
|
|
195
|
-
force?: boolean;
|
|
196
|
-
}) => Message[] | Promise<Message[]>;
|
|
208
|
+
transformContext?: (messages: Message[], options: TransformContextOptions) => Message[] | Promise<Message[]>;
|
|
197
209
|
/**
|
|
198
210
|
* Polled after tool execution completes each turn. Returns user messages
|
|
199
211
|
* to inject into the conversation before the next LLM call (steering).
|
|
@@ -299,4 +311,4 @@ declare function isBillingError(err: unknown): boolean;
|
|
|
299
311
|
declare function isUsageLimitError(err: unknown): boolean;
|
|
300
312
|
declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
|
|
301
313
|
|
|
302
|
-
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
|
|
314
|
+
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, isAbortError, isBillingError, isContextOverflow, isUsageLimitError, setStreamDiagnostic };
|
package/dist/index.js
CHANGED
|
@@ -189,6 +189,8 @@ async function* agentLoop(messages, options) {
|
|
|
189
189
|
const maxContinuations = options.maxContinuations ?? 5;
|
|
190
190
|
let toolMap = new Map((options.tools ?? []).map((t) => [t.name, t]));
|
|
191
191
|
const totalUsage = { inputTokens: 0, outputTokens: 0 };
|
|
192
|
+
let latestProviderUsage;
|
|
193
|
+
let usageAnchorIndex;
|
|
192
194
|
let turn = 0;
|
|
193
195
|
let hitMaxTurns = false;
|
|
194
196
|
let firstTurn = true;
|
|
@@ -265,7 +267,11 @@ async function* agentLoop(messages, options) {
|
|
|
265
267
|
firstTurn = false;
|
|
266
268
|
if (options.transformContext) {
|
|
267
269
|
diag("transform_start");
|
|
268
|
-
const
|
|
270
|
+
const pendingMessages = usageAnchorIndex === void 0 ? [] : messages.slice(usageAnchorIndex + 1);
|
|
271
|
+
const transformed = await options.transformContext(messages, {
|
|
272
|
+
usage: latestProviderUsage,
|
|
273
|
+
pendingMessages
|
|
274
|
+
});
|
|
269
275
|
if (transformed !== messages) {
|
|
270
276
|
diag("transform_compacted", {
|
|
271
277
|
before: messages.length,
|
|
@@ -273,6 +279,8 @@ async function* agentLoop(messages, options) {
|
|
|
273
279
|
});
|
|
274
280
|
messages.length = 0;
|
|
275
281
|
messages.push(...transformed);
|
|
282
|
+
latestProviderUsage = void 0;
|
|
283
|
+
usageAnchorIndex = void 0;
|
|
276
284
|
}
|
|
277
285
|
diag("transform_end");
|
|
278
286
|
}
|
|
@@ -527,10 +535,17 @@ async function* agentLoop(messages, options) {
|
|
|
527
535
|
...overflowDetails
|
|
528
536
|
});
|
|
529
537
|
try {
|
|
530
|
-
const
|
|
538
|
+
const pendingMessages = usageAnchorIndex === void 0 ? [] : messages.slice(usageAnchorIndex + 1);
|
|
539
|
+
const compacted = await options.transformContext(messages, {
|
|
540
|
+
force: true,
|
|
541
|
+
usage: latestProviderUsage,
|
|
542
|
+
pendingMessages
|
|
543
|
+
});
|
|
531
544
|
if (compacted !== messages && compacted.length < messages.length) {
|
|
532
545
|
messages.length = 0;
|
|
533
546
|
messages.push(...compacted);
|
|
547
|
+
latestProviderUsage = void 0;
|
|
548
|
+
usageAnchorIndex = void 0;
|
|
534
549
|
diag("overflow_compact_success", {
|
|
535
550
|
attempt: overflowCompactionAttempts,
|
|
536
551
|
messages: messages.length,
|
|
@@ -736,6 +751,8 @@ async function* agentLoop(messages, options) {
|
|
|
736
751
|
totalUsage.cacheWrite = (totalUsage.cacheWrite ?? 0) + response.usage.cacheWrite;
|
|
737
752
|
}
|
|
738
753
|
messages.push(response.message);
|
|
754
|
+
latestProviderUsage = response.usage;
|
|
755
|
+
usageAnchorIndex = messages.length - 1;
|
|
739
756
|
const completedAt = Date.now();
|
|
740
757
|
const outputTokensPerSecond = providerDurationMs > 0 && response.usage.outputTokens > 0 ? response.usage.outputTokens / (providerDurationMs / 1e3) : void 0;
|
|
741
758
|
const timing = {
|
|
@@ -823,6 +840,7 @@ async function* agentLoop(messages, options) {
|
|
|
823
840
|
const executionOptions = {
|
|
824
841
|
signal: options.signal,
|
|
825
842
|
maxToolResultChars: options.maxToolResultChars,
|
|
843
|
+
maxTurnToolResultChars: options.maxTurnToolResultChars,
|
|
826
844
|
toolMap,
|
|
827
845
|
invalidToolArgumentCounts,
|
|
828
846
|
markFatalToolArgumentError
|
|
@@ -1059,6 +1077,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1059
1077
|
}
|
|
1060
1078
|
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById);
|
|
1061
1079
|
capToolResults(toolResults, options.maxToolResultChars);
|
|
1080
|
+
capTurnToolResults(toolResults, options.maxTurnToolResultChars);
|
|
1062
1081
|
return { toolResults, aborted };
|
|
1063
1082
|
}
|
|
1064
1083
|
async function* executeToolCallsParallel(toolCalls, initialToolResults, options) {
|
|
@@ -1098,6 +1117,7 @@ async function* executeToolCallsParallel(toolCalls, initialToolResults, options)
|
|
|
1098
1117
|
}
|
|
1099
1118
|
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById);
|
|
1100
1119
|
capToolResults(toolResults, options.maxToolResultChars);
|
|
1120
|
+
capTurnToolResults(toolResults, options.maxTurnToolResultChars);
|
|
1101
1121
|
return { toolResults, aborted };
|
|
1102
1122
|
}
|
|
1103
1123
|
function buildToolResults(initialToolResults, toolCalls, resultsById) {
|
|
@@ -1140,6 +1160,34 @@ function capToolResults(toolResults, maxToolResultChars) {
|
|
|
1140
1160
|
` + tail;
|
|
1141
1161
|
}
|
|
1142
1162
|
}
|
|
1163
|
+
function capTurnToolResults(toolResults, maxTurnToolResultChars) {
|
|
1164
|
+
if (!maxTurnToolResultChars) return;
|
|
1165
|
+
const textResults = toolResults.filter(
|
|
1166
|
+
(toolResult) => typeof toolResult.content === "string"
|
|
1167
|
+
);
|
|
1168
|
+
const total = textResults.reduce((sum, toolResult) => sum + toolResult.content.length, 0);
|
|
1169
|
+
if (total <= maxTurnToolResultChars) return;
|
|
1170
|
+
const bySize = [...textResults].sort((a, b) => a.content.length - b.content.length);
|
|
1171
|
+
let remaining = maxTurnToolResultChars;
|
|
1172
|
+
let left = bySize.length;
|
|
1173
|
+
for (const toolResult of bySize) {
|
|
1174
|
+
const fairShare = Math.floor(remaining / left);
|
|
1175
|
+
left--;
|
|
1176
|
+
if (toolResult.content.length <= fairShare) {
|
|
1177
|
+
remaining -= toolResult.content.length;
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
remaining -= fairShare;
|
|
1181
|
+
const headChars = Math.floor(fairShare * 0.7);
|
|
1182
|
+
const tailChars = fairShare - headChars;
|
|
1183
|
+
const omitted = toolResult.content.length - fairShare;
|
|
1184
|
+
toolResult.content = toolResult.content.slice(0, headChars) + `
|
|
1185
|
+
|
|
1186
|
+
[... ${omitted} characters trimmed: this turn's combined tool results exceeded the per-turn budget. Re-run this call alone with narrower filters or offset/limit if you need the omitted content ...]
|
|
1187
|
+
|
|
1188
|
+
` + (tailChars > 0 ? toolResult.content.slice(-tailChars) : "");
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1143
1191
|
function normalizeToolResult(raw) {
|
|
1144
1192
|
return typeof raw === "string" ? { content: raw } : raw;
|
|
1145
1193
|
}
|