@pencil-agent/nano-pencil 1.14.2 → 1.14.4
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/build-meta.json +3 -3
- package/dist/builtin-extensions.d.ts +4 -0
- package/dist/builtin-extensions.js +16 -16
- package/dist/core/config/settings-manager.d.ts +8 -1
- package/dist/core/config/settings-manager.js +9 -0
- package/dist/core/extensions/runner.d.ts +70 -4
- package/dist/core/extensions/runner.js +188 -8
- package/dist/core/extensions/types.d.ts +8 -1
- package/dist/core/i18n/slash-commands.d.ts +12 -0
- package/dist/core/i18n/slash-commands.js +16 -4
- package/dist/core/i18n/slash-commands.zh.d.ts +12 -0
- package/dist/core/i18n/slash-commands.zh.js +16 -4
- package/dist/core/runtime/agent-session.d.ts +5 -0
- package/dist/core/runtime/agent-session.js +85 -27
- package/dist/core/runtime/extension-core-bindings.d.ts +3 -3
- package/dist/core/runtime/extension-core-bindings.js +73 -20
- package/dist/core/runtime/retry-coordinator.d.ts +10 -1
- package/dist/core/runtime/retry-coordinator.js +20 -4
- package/dist/core/runtime/sdk.js +2 -1
- package/dist/core/runtime/slash-command-catalog.d.ts +2 -1
- package/dist/core/runtime/slash-command-catalog.js +9 -1
- package/dist/core/slash-commands.d.ts +12 -1
- package/dist/core/slash-commands.js +81 -32
- package/dist/core/telemetry/batching-dispatcher.d.ts +41 -0
- package/dist/core/telemetry/batching-dispatcher.js +89 -0
- package/dist/core/telemetry/build-meta.d.ts +12 -0
- package/dist/core/telemetry/build-meta.js +57 -0
- package/dist/core/telemetry/caller-context.d.ts +32 -0
- package/dist/core/telemetry/caller-context.js +19 -0
- package/dist/core/telemetry/credentials.d.ts +27 -0
- package/dist/core/telemetry/credentials.js +87 -0
- package/dist/core/telemetry/ext-events.d.ts +89 -0
- package/dist/core/telemetry/ext-events.js +189 -0
- package/dist/core/telemetry/index.d.ts +13 -0
- package/dist/core/telemetry/index.js +6 -0
- package/dist/core/telemetry/insforge-base.d.ts +37 -0
- package/dist/core/telemetry/insforge-base.js +160 -0
- package/dist/core/telemetry/types.d.ts +33 -0
- package/dist/core/telemetry/types.js +7 -0
- package/dist/extensions/defaults/browser/index.js +14 -6
- package/dist/extensions/defaults/btw/index.js +2 -2
- package/dist/extensions/defaults/debug/index.js +38 -3
- package/dist/extensions/defaults/diagnostics/index.js +12 -0
- package/dist/extensions/defaults/grub/grub-parser.d.ts +15 -1
- package/dist/extensions/defaults/grub/grub-parser.js +31 -1
- package/dist/extensions/defaults/grub/index.d.ts +1 -1
- package/dist/extensions/defaults/grub/index.js +4 -3
- package/dist/extensions/defaults/interview/index.js +2 -2
- package/dist/extensions/defaults/link-world/index.js +14 -6
- package/dist/extensions/defaults/loop/cron/cron-scheduler.js +19 -0
- package/dist/extensions/defaults/loop/index.js +35 -0
- package/dist/extensions/defaults/mcp/index.js +18 -0
- package/dist/extensions/defaults/plan/index.js +29 -11
- package/dist/extensions/defaults/presence/index.d.ts +12 -2
- package/dist/extensions/defaults/presence/index.js +77 -23
- package/dist/extensions/defaults/presence/presence-memory.d.ts +2 -1
- package/dist/extensions/defaults/presence/presence-memory.js +37 -1
- package/dist/extensions/defaults/recap/index.js +12 -0
- package/dist/extensions/defaults/sal/eval/insforge-sink.d.ts +6 -17
- package/dist/extensions/defaults/sal/eval/insforge-sink.js +40 -183
- package/dist/extensions/defaults/sal/index.js +31 -8
- package/dist/extensions/defaults/sal/sal-config.d.ts +5 -0
- package/dist/extensions/defaults/sal/sal-config.js +15 -82
- package/dist/extensions/defaults/security-audit/index.js +141 -83
- package/dist/extensions/defaults/subagent/index.js +29 -5
- package/dist/extensions/defaults/team/index.js +10 -9
- package/dist/extensions/defaults/team/team-parser.d.ts +18 -0
- package/dist/extensions/defaults/team/team-parser.js +91 -3
- package/dist/extensions/defaults/team/team-ui.js +4 -14
- package/dist/extensions/defaults/token-save/index.js +14 -1
- package/dist/extensions/optional/export-html/index.js +19 -5
- package/dist/extensions/optional/simplify/index.js +11 -5
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.js +68 -19
- package/dist/modes/interactive/slash-command-arguments.d.ts +16 -0
- package/dist/modes/interactive/slash-command-arguments.js +97 -0
- package/dist/modes/rpc/rpc-mode.d.ts +3 -0
- package/dist/modes/rpc/rpc-mode.js +40 -31
- package/dist/modes/rpc/rpc-types.d.ts +3 -0
- package/dist/node_modules/@pencil-agent/agent-core/agent.d.ts +15 -1
- package/dist/node_modules/@pencil-agent/agent-core/agent.js +13 -1
- package/dist/node_modules/@pencil-agent/agent-core/index.d.ts +2 -1
- package/dist/node_modules/@pencil-agent/agent-core/index.js +2 -1
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-agent-loop.d.ts +1 -1
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-agent-loop.js +293 -20
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.d.ts +33 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.js +189 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-tool-orchestration.d.ts +9 -0
- package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-tool-orchestration.js +30 -5
- package/dist/node_modules/@pencil-agent/agent-core/types.d.ts +90 -3
- package/dist/node_modules/@pencil-agent/agent-core/types.js +1 -1
- package/dist/node_modules/@pencil-agent/ai/models.generated.d.ts +0 -17
- package/dist/node_modules/@pencil-agent/ai/models.generated.js +29 -46
- package/dist/node_modules/@pencil-agent/tui/autocomplete.d.ts +8 -1
- package/dist/node_modules/@pencil-agent/tui/autocomplete.js +18 -2
- package/dist/node_modules/@pencil-agent/tui/index.d.ts +1 -1
- package/dist/node_modules/@pencil-agent/tui/tui.d.ts +8 -3
- package/dist/node_modules/@pencil-agent/tui/tui.js +68 -33
- package/dist/packages/mem-core/extension.js +154 -83
- package/dist/packages/mem-core/full-insights-sections.d.ts +48 -0
- package/dist/packages/mem-core/full-insights-sections.js +231 -0
- package/dist/packages/mem-core/full-insights.d.ts +1 -1
- package/dist/packages/mem-core/full-insights.js +102 -42
- package/package.json +2 -2
|
@@ -5,17 +5,21 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
7
|
* [WHO]: structuredAdaptiveAgentLoop, structuredAdaptiveAgentLoopContinue
|
|
8
|
-
* [FROM]: Depends on @pencil-agent/ai, ./types, ./errors, ./structured-adaptive-tool-orchestration
|
|
8
|
+
* [FROM]: Depends on @pencil-agent/ai, ./types, ./errors, ./structured-adaptive-tool-orchestration, ./structured-adaptive-streaming-tool-executor
|
|
9
9
|
* [TO]: Consumed by packages/agent-core/src/agent.ts and index.ts
|
|
10
10
|
* [HERE]: packages/agent-core/src/structured-adaptive-agent-loop.ts - selectable structured-adaptive query loop framework
|
|
11
11
|
*/
|
|
12
12
|
import { EventStream, isContextOverflow, streamSimple, } from "@pencil-agent/ai";
|
|
13
|
-
import { runStructuredAdaptiveTools } from "./structured-adaptive-tool-orchestration.js";
|
|
13
|
+
import { resolveMaxToolConcurrency, runStructuredAdaptiveTools, } from "./structured-adaptive-tool-orchestration.js";
|
|
14
|
+
import { StructuredAdaptiveStreamingToolExecutor } from "./structured-adaptive-streaming-tool-executor.js";
|
|
14
15
|
import { ValidationError } from "./errors.js";
|
|
15
16
|
const DEFAULT_MAX_TURNS_PER_PROMPT = 64;
|
|
16
17
|
const DEFAULT_MAX_TOOL_CALLS_PER_PROMPT = 128;
|
|
17
18
|
const DEFAULT_MAX_OUTPUT_TOKEN_RECOVERY_ATTEMPTS = 1;
|
|
18
19
|
const DEFAULT_MAX_STOP_HOOK_CONTINUATIONS = 3;
|
|
20
|
+
const DEFAULT_MAX_MODEL_ERROR_RECOVERY_ATTEMPTS = 1;
|
|
21
|
+
const DEFAULT_OUTPUT_TOKEN_BUDGET_THRESHOLD_PCT = 0.9;
|
|
22
|
+
const DEFAULT_OUTPUT_TOKEN_BUDGET_CONTINUATIONS = 3;
|
|
19
23
|
export function structuredAdaptiveAgentLoop(prompts, context, config, signal, streamFn) {
|
|
20
24
|
const stream = createAgentStream();
|
|
21
25
|
(async () => {
|
|
@@ -69,14 +73,18 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
69
73
|
const maxToolCalls = config.maxToolCallsPerPrompt ?? DEFAULT_MAX_TOOL_CALLS_PER_PROMPT;
|
|
70
74
|
const maxOutputTokenRecoveryAttempts = config.maxOutputTokenRecoveryAttempts ?? DEFAULT_MAX_OUTPUT_TOKEN_RECOVERY_ATTEMPTS;
|
|
71
75
|
const maxStopHookContinuations = config.maxStopHookContinuations ?? DEFAULT_MAX_STOP_HOOK_CONTINUATIONS;
|
|
76
|
+
const maxModelErrorRecoveryAttempts = config.maxModelErrorRecoveryAttempts ?? DEFAULT_MAX_MODEL_ERROR_RECOVERY_ATTEMPTS;
|
|
72
77
|
const state = {
|
|
73
78
|
turnCount: 0,
|
|
74
79
|
toolCallCount: 0,
|
|
75
|
-
transition: "start",
|
|
80
|
+
transition: { reason: "start" },
|
|
76
81
|
pendingMessages: (await config.getSteeringMessages?.()) || [],
|
|
82
|
+
pendingToolUseSummaries: [],
|
|
77
83
|
stopHookActive: false,
|
|
78
84
|
stopHookContinuationCount: 0,
|
|
79
85
|
maxOutputTokensRecoveryCount: 0,
|
|
86
|
+
modelErrorRecoveryCount: 0,
|
|
87
|
+
tokenBudgetContinuationCount: 0,
|
|
80
88
|
hasAttemptedReactiveCompact: false,
|
|
81
89
|
startedAt: Date.now(),
|
|
82
90
|
usage: emptyUsage(),
|
|
@@ -90,6 +98,7 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
90
98
|
else {
|
|
91
99
|
firstTurn = false;
|
|
92
100
|
}
|
|
101
|
+
flushReadyToolUseSummaries(state, currentContext, newMessages, stream);
|
|
93
102
|
if (state.pendingMessages.length > 0) {
|
|
94
103
|
for (const message of state.pendingMessages) {
|
|
95
104
|
stream.push({ type: "message_start", message });
|
|
@@ -113,20 +122,61 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
113
122
|
finish(stream, newMessages, state);
|
|
114
123
|
return;
|
|
115
124
|
}
|
|
116
|
-
const
|
|
125
|
+
const streamingToolExecutor = new StructuredAdaptiveStreamingToolExecutor(currentContext.tools, signal, stream, resolveMaxToolConcurrency(config.maxToolConcurrency), config.canUseTool);
|
|
126
|
+
const message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn, state.maxOutputTokensOverride, streamingToolExecutor);
|
|
117
127
|
newMessages.push(message);
|
|
118
128
|
addUsage(state.usage, message.usage);
|
|
119
129
|
state.maxOutputTokensOverride = undefined;
|
|
120
130
|
if (message.stopReason === "error" || message.stopReason === "aborted") {
|
|
121
|
-
|
|
131
|
+
const errorSubtype = message.stopReason === "aborted"
|
|
132
|
+
? "aborted"
|
|
133
|
+
: isContextOverflow(message, config.model.contextWindow)
|
|
134
|
+
? "context_overflow"
|
|
135
|
+
: "model_error";
|
|
136
|
+
const failedToolExecution = streamingToolExecutor.size > 0
|
|
137
|
+
? await streamingToolExecutor.discardAndDrain(message.stopReason === "aborted" ? "assistant stream aborted" : "assistant stream error", message.stopReason === "aborted" ? "cancel" : "all")
|
|
138
|
+
: { toolResults: [], contextMessages: [], permissionDenials: [] };
|
|
139
|
+
const toolResults = enforceToolResultBatchSize(failedToolExecution.toolResults, config.maxToolResultBatchSizeChars);
|
|
140
|
+
state.permissionDenials.push(...failedToolExecution.permissionDenials);
|
|
141
|
+
for (const result of toolResults) {
|
|
142
|
+
currentContext.messages.push(result);
|
|
143
|
+
newMessages.push(result);
|
|
144
|
+
stream.push({ type: "message_start", message: result });
|
|
145
|
+
stream.push({ type: "message_end", message: result });
|
|
146
|
+
}
|
|
147
|
+
for (const contextMessage of failedToolExecution.contextMessages) {
|
|
148
|
+
currentContext.messages.push(contextMessage);
|
|
149
|
+
newMessages.push(contextMessage);
|
|
150
|
+
stream.push({ type: "message_start", message: contextMessage });
|
|
151
|
+
stream.push({ type: "message_end", message: contextMessage });
|
|
152
|
+
}
|
|
153
|
+
if (message.stopReason === "error" &&
|
|
154
|
+
config.recoverModelError &&
|
|
155
|
+
state.modelErrorRecoveryCount < maxModelErrorRecoveryAttempts) {
|
|
156
|
+
const attempt = state.modelErrorRecoveryCount + 1;
|
|
157
|
+
const recovery = await config.recoverModelError({
|
|
158
|
+
message,
|
|
159
|
+
messages: currentContext.messages,
|
|
160
|
+
errorSubtype,
|
|
161
|
+
attempt,
|
|
162
|
+
});
|
|
163
|
+
if (recovery.action === "retry") {
|
|
164
|
+
stream.push({ type: "turn_end", message, toolResults });
|
|
165
|
+
state.modelErrorRecoveryCount = attempt;
|
|
166
|
+
currentContext.messages = recovery.messages;
|
|
167
|
+
state.transition =
|
|
168
|
+
recovery.transition ?? {
|
|
169
|
+
reason: "model_error_recovery",
|
|
170
|
+
subtype: errorSubtype,
|
|
171
|
+
attempt,
|
|
172
|
+
};
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
stream.push({ type: "turn_end", message, toolResults });
|
|
122
177
|
state.finalStopReason = message.stopReason;
|
|
123
178
|
state.finalErrorMessage = message.errorMessage;
|
|
124
|
-
state.finalErrorSubtype =
|
|
125
|
-
message.stopReason === "aborted"
|
|
126
|
-
? "aborted"
|
|
127
|
-
: isContextOverflow(message, config.model.contextWindow)
|
|
128
|
-
? "context_overflow"
|
|
129
|
-
: "model_error";
|
|
179
|
+
state.finalErrorSubtype = errorSubtype;
|
|
130
180
|
finish(stream, newMessages, state);
|
|
131
181
|
return;
|
|
132
182
|
}
|
|
@@ -138,7 +188,10 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
138
188
|
state.maxOutputTokensRecoveryCount += 1;
|
|
139
189
|
state.maxOutputTokensOverride = computeRecoveryMaxTokens(config, message);
|
|
140
190
|
state.pendingMessages = [createOutputTokenRecoveryMessage(state.maxOutputTokensRecoveryCount)];
|
|
141
|
-
state.transition =
|
|
191
|
+
state.transition = {
|
|
192
|
+
reason: "max_output_tokens_recovery",
|
|
193
|
+
attempt: state.maxOutputTokensRecoveryCount,
|
|
194
|
+
};
|
|
142
195
|
continue;
|
|
143
196
|
}
|
|
144
197
|
if (config.runStopHooks && !state.stopHookActive) {
|
|
@@ -164,16 +217,31 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
164
217
|
}
|
|
165
218
|
state.stopHookContinuationCount += 1;
|
|
166
219
|
state.pendingMessages = stopHookResult.messages;
|
|
167
|
-
state.transition =
|
|
220
|
+
state.transition = {
|
|
221
|
+
reason: "stop_hook_blocking",
|
|
222
|
+
continuationCount: state.stopHookContinuationCount,
|
|
223
|
+
};
|
|
168
224
|
continue;
|
|
169
225
|
}
|
|
170
226
|
}
|
|
227
|
+
const tokenBudgetContinuation = maybeCreateTokenBudgetContinuation(config, state);
|
|
228
|
+
if (tokenBudgetContinuation) {
|
|
229
|
+
state.tokenBudgetContinuationCount += 1;
|
|
230
|
+
state.pendingMessages = [tokenBudgetContinuation.message];
|
|
231
|
+
state.transition = {
|
|
232
|
+
reason: "token_budget_continuation",
|
|
233
|
+
continuationCount: state.tokenBudgetContinuationCount,
|
|
234
|
+
outputTokens: tokenBudgetContinuation.outputTokens,
|
|
235
|
+
targetTokens: tokenBudgetContinuation.targetTokens,
|
|
236
|
+
};
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
171
239
|
const followUpMessages = (await config.getFollowUpMessages?.()) || [];
|
|
172
240
|
if (followUpMessages.length === 0) {
|
|
173
241
|
break;
|
|
174
242
|
}
|
|
175
243
|
state.pendingMessages = followUpMessages;
|
|
176
|
-
state.transition = "follow_up";
|
|
244
|
+
state.transition = { reason: "follow_up" };
|
|
177
245
|
continue;
|
|
178
246
|
}
|
|
179
247
|
if (state.toolCallCount + toolCalls.length > maxToolCalls) {
|
|
@@ -190,9 +258,10 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
190
258
|
return;
|
|
191
259
|
}
|
|
192
260
|
state.toolCallCount += toolCalls.length;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
261
|
+
const toolExecution = streamingToolExecutor.size > 0
|
|
262
|
+
? await streamingToolExecutor.drain()
|
|
263
|
+
: await runStructuredAdaptiveTools(toolCalls, currentContext.tools, signal, stream, config.getSteeringMessages, config.maxToolConcurrency, config.canUseTool);
|
|
264
|
+
const toolResults = enforceToolResultBatchSize(toolExecution.toolResults, config.maxToolResultBatchSizeChars);
|
|
196
265
|
state.permissionDenials.push(...toolExecution.permissionDenials);
|
|
197
266
|
for (const result of toolResults) {
|
|
198
267
|
currentContext.messages.push(result);
|
|
@@ -206,6 +275,15 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
206
275
|
stream.push({ type: "message_start", message: contextMessage });
|
|
207
276
|
stream.push({ type: "message_end", message: contextMessage });
|
|
208
277
|
}
|
|
278
|
+
const pendingSummary = startToolUseSummary(config, {
|
|
279
|
+
assistantMessage: message,
|
|
280
|
+
toolResults,
|
|
281
|
+
contextMessages: toolExecution.contextMessages,
|
|
282
|
+
messages: currentContext.messages,
|
|
283
|
+
});
|
|
284
|
+
if (pendingSummary) {
|
|
285
|
+
state.pendingToolUseSummaries.push(pendingSummary);
|
|
286
|
+
}
|
|
209
287
|
stream.push({ type: "turn_end", message, toolResults });
|
|
210
288
|
if (toolExecution.steeringMessages && toolExecution.steeringMessages.length > 0) {
|
|
211
289
|
state.pendingMessages = toolExecution.steeringMessages;
|
|
@@ -213,12 +291,160 @@ async function runStructuredAdaptiveQueryLoop(currentContext, newMessages, confi
|
|
|
213
291
|
else {
|
|
214
292
|
state.pendingMessages = (await config.getSteeringMessages?.()) || [];
|
|
215
293
|
}
|
|
216
|
-
state.transition = "tool_result";
|
|
294
|
+
state.transition = { reason: "tool_result", toolCallCount: toolCalls.length };
|
|
217
295
|
}
|
|
218
296
|
state.finalStopReason = state.finalStopReason ?? inferStopReason(newMessages);
|
|
219
297
|
finish(stream, newMessages, state);
|
|
220
298
|
}
|
|
221
|
-
|
|
299
|
+
function flushReadyToolUseSummaries(state, currentContext, newMessages, stream) {
|
|
300
|
+
if (state.pendingToolUseSummaries.length === 0) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const pending = [];
|
|
304
|
+
for (const summary of state.pendingToolUseSummaries) {
|
|
305
|
+
const result = summary.read();
|
|
306
|
+
if (!result.settled) {
|
|
307
|
+
pending.push(summary);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (!result.value) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
currentContext.messages.push(result.value);
|
|
314
|
+
newMessages.push(result.value);
|
|
315
|
+
stream.push({ type: "message_start", message: result.value });
|
|
316
|
+
stream.push({ type: "message_end", message: result.value });
|
|
317
|
+
}
|
|
318
|
+
state.pendingToolUseSummaries = pending;
|
|
319
|
+
}
|
|
320
|
+
function startToolUseSummary(config, event) {
|
|
321
|
+
if (!config.createToolUseSummary) {
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
const value = config.createToolUseSummary({
|
|
326
|
+
...event,
|
|
327
|
+
messages: [...event.messages],
|
|
328
|
+
});
|
|
329
|
+
return trackToolUseSummary(value);
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function trackToolUseSummary(value) {
|
|
336
|
+
if (!value) {
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
if (typeof value.then !== "function") {
|
|
340
|
+
return {
|
|
341
|
+
read: () => ({ settled: true, value: value }),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
let settled = false;
|
|
345
|
+
let settledValue;
|
|
346
|
+
value.then((summary) => {
|
|
347
|
+
settled = true;
|
|
348
|
+
settledValue = summary;
|
|
349
|
+
}, () => {
|
|
350
|
+
settled = true;
|
|
351
|
+
settledValue = undefined;
|
|
352
|
+
});
|
|
353
|
+
return {
|
|
354
|
+
read: () => ({ settled, value: settledValue }),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function enforceToolResultBatchSize(toolResults, maxChars) {
|
|
358
|
+
if (!maxChars || maxChars <= 0 || toolResults.length === 0) {
|
|
359
|
+
return toolResults;
|
|
360
|
+
}
|
|
361
|
+
const limit = Math.floor(maxChars);
|
|
362
|
+
let currentTotal = sumToolResultTextChars(toolResults);
|
|
363
|
+
if (currentTotal <= limit) {
|
|
364
|
+
return toolResults;
|
|
365
|
+
}
|
|
366
|
+
const next = [...toolResults];
|
|
367
|
+
const ranked = toolResults
|
|
368
|
+
.map((result, index) => ({
|
|
369
|
+
index,
|
|
370
|
+
size: sumTextContentChars(result.content),
|
|
371
|
+
isError: result.isError,
|
|
372
|
+
}))
|
|
373
|
+
.filter((candidate) => candidate.size > 0)
|
|
374
|
+
.sort((a, b) => {
|
|
375
|
+
if (a.isError !== b.isError)
|
|
376
|
+
return a.isError ? 1 : -1;
|
|
377
|
+
return b.size - a.size || a.index - b.index;
|
|
378
|
+
});
|
|
379
|
+
for (const candidate of ranked) {
|
|
380
|
+
if (currentTotal <= limit)
|
|
381
|
+
break;
|
|
382
|
+
const reductionNeeded = currentTotal - limit;
|
|
383
|
+
const targetSize = Math.max(0, candidate.size - reductionNeeded);
|
|
384
|
+
const truncated = truncateToolResultToTextChars(next[candidate.index], targetSize, limit);
|
|
385
|
+
next[candidate.index] = truncated.result;
|
|
386
|
+
currentTotal = currentTotal - candidate.size + truncated.textChars;
|
|
387
|
+
}
|
|
388
|
+
return next;
|
|
389
|
+
}
|
|
390
|
+
function truncateToolResultToTextChars(result, targetChars, maxToolResultBatchSizeChars) {
|
|
391
|
+
const originalTextChars = sumTextContentChars(result.content);
|
|
392
|
+
if (originalTextChars <= targetChars) {
|
|
393
|
+
return { result, textChars: originalTextChars };
|
|
394
|
+
}
|
|
395
|
+
const note = `[Tool result truncated by batch budget: original ${originalTextChars} chars.]`;
|
|
396
|
+
let nextText = "";
|
|
397
|
+
if (targetChars > 0) {
|
|
398
|
+
if (targetChars <= note.length) {
|
|
399
|
+
nextText = note.slice(0, targetChars);
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
const suffix = `\n\n${note}`;
|
|
403
|
+
const bodyBudget = Math.max(0, targetChars - suffix.length);
|
|
404
|
+
nextText = `${flattenTextContent(result.content).slice(0, bodyBudget)}${suffix}`;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
let hasWrittenText = false;
|
|
408
|
+
const content = result.content.map((part) => {
|
|
409
|
+
if (part.type !== "text")
|
|
410
|
+
return part;
|
|
411
|
+
if (hasWrittenText) {
|
|
412
|
+
return { ...part, text: "" };
|
|
413
|
+
}
|
|
414
|
+
hasWrittenText = true;
|
|
415
|
+
return { ...part, text: nextText };
|
|
416
|
+
});
|
|
417
|
+
if (!hasWrittenText) {
|
|
418
|
+
content.push({ type: "text", text: nextText });
|
|
419
|
+
}
|
|
420
|
+
return {
|
|
421
|
+
result: {
|
|
422
|
+
...result,
|
|
423
|
+
content,
|
|
424
|
+
details: {
|
|
425
|
+
...(typeof result.details === "object" && result.details !== null ? result.details : {}),
|
|
426
|
+
truncationReason: "tool_result_batch_budget",
|
|
427
|
+
originalTextChars,
|
|
428
|
+
retainedTextChars: nextText.length,
|
|
429
|
+
maxToolResultBatchSizeChars,
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
textChars: nextText.length,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function sumToolResultTextChars(toolResults) {
|
|
436
|
+
return toolResults.reduce((total, result) => total + sumTextContentChars(result.content), 0);
|
|
437
|
+
}
|
|
438
|
+
function sumTextContentChars(content) {
|
|
439
|
+
return content.reduce((total, part) => total + (part.type === "text" ? part.text.length : 0), 0);
|
|
440
|
+
}
|
|
441
|
+
function flattenTextContent(content) {
|
|
442
|
+
return content
|
|
443
|
+
.filter((part) => part.type === "text")
|
|
444
|
+
.map((part) => part.text)
|
|
445
|
+
.join("");
|
|
446
|
+
}
|
|
447
|
+
async function streamAssistantResponse(context, config, signal, stream, streamFn, maxTokensOverride, streamingToolExecutor) {
|
|
222
448
|
let messages = context.messages;
|
|
223
449
|
if (config.transformContext) {
|
|
224
450
|
messages = await config.transformContext(messages, signal);
|
|
@@ -263,6 +489,16 @@ async function streamAssistantResponse(context, config, signal, stream, streamFn
|
|
|
263
489
|
case "thinking_end":
|
|
264
490
|
case "toolcall_start":
|
|
265
491
|
case "toolcall_delta":
|
|
492
|
+
if (partialMessage) {
|
|
493
|
+
partialMessage = event.partial;
|
|
494
|
+
context.messages[context.messages.length - 1] = partialMessage;
|
|
495
|
+
stream.push({
|
|
496
|
+
type: "message_update",
|
|
497
|
+
assistantMessageEvent: event,
|
|
498
|
+
message: { ...partialMessage },
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
break;
|
|
266
502
|
case "toolcall_end":
|
|
267
503
|
if (partialMessage) {
|
|
268
504
|
partialMessage = event.partial;
|
|
@@ -272,6 +508,7 @@ async function streamAssistantResponse(context, config, signal, stream, streamFn
|
|
|
272
508
|
assistantMessageEvent: event,
|
|
273
509
|
message: { ...partialMessage },
|
|
274
510
|
});
|
|
511
|
+
streamingToolExecutor?.addTool(event.toolCall);
|
|
275
512
|
}
|
|
276
513
|
break;
|
|
277
514
|
case "done":
|
|
@@ -313,6 +550,38 @@ function createOutputTokenRecoveryMessage(attempt) {
|
|
|
313
550
|
timestamp: Date.now(),
|
|
314
551
|
};
|
|
315
552
|
}
|
|
553
|
+
function maybeCreateTokenBudgetContinuation(config, state) {
|
|
554
|
+
const budget = config.outputTokenBudget;
|
|
555
|
+
if (!budget)
|
|
556
|
+
return undefined;
|
|
557
|
+
const targetTokens = Math.max(1, Math.floor(budget.targetTokens));
|
|
558
|
+
const thresholdPct = clamp(budget.thresholdPct ?? DEFAULT_OUTPUT_TOKEN_BUDGET_THRESHOLD_PCT, 0, 1);
|
|
559
|
+
const maxContinuations = Math.max(0, Math.floor(budget.maxContinuations ?? DEFAULT_OUTPUT_TOKEN_BUDGET_CONTINUATIONS));
|
|
560
|
+
if (maxContinuations <= state.tokenBudgetContinuationCount)
|
|
561
|
+
return undefined;
|
|
562
|
+
const outputTokens = Math.max(0, Math.floor(state.usage.output));
|
|
563
|
+
const requiredTokens = Math.ceil(targetTokens * thresholdPct);
|
|
564
|
+
if (outputTokens >= requiredTokens)
|
|
565
|
+
return undefined;
|
|
566
|
+
const message = {
|
|
567
|
+
role: "user",
|
|
568
|
+
content: [
|
|
569
|
+
{
|
|
570
|
+
type: "text",
|
|
571
|
+
text: `Continue because the output token budget is underused ` +
|
|
572
|
+
`(${outputTokens}/${targetTokens} tokens). Add the missing useful detail directly; ` +
|
|
573
|
+
`do not recap or apologize.`,
|
|
574
|
+
},
|
|
575
|
+
],
|
|
576
|
+
timestamp: Date.now(),
|
|
577
|
+
};
|
|
578
|
+
return { message, outputTokens, targetTokens };
|
|
579
|
+
}
|
|
580
|
+
function clamp(value, min, max) {
|
|
581
|
+
if (!Number.isFinite(value))
|
|
582
|
+
return min;
|
|
583
|
+
return Math.min(max, Math.max(min, value));
|
|
584
|
+
}
|
|
316
585
|
function createLoopLimitMessage(config, errorMessage) {
|
|
317
586
|
return {
|
|
318
587
|
role: "assistant",
|
|
@@ -345,11 +614,14 @@ function endWithLoopError(stream, newMessages, config, error, signal) {
|
|
|
345
614
|
const state = {
|
|
346
615
|
turnCount: 0,
|
|
347
616
|
toolCallCount: 0,
|
|
348
|
-
transition: "start",
|
|
617
|
+
transition: { reason: "start" },
|
|
349
618
|
pendingMessages: [],
|
|
619
|
+
pendingToolUseSummaries: [],
|
|
350
620
|
stopHookActive: false,
|
|
351
621
|
stopHookContinuationCount: 0,
|
|
352
622
|
maxOutputTokensRecoveryCount: 0,
|
|
623
|
+
modelErrorRecoveryCount: 0,
|
|
624
|
+
tokenBudgetContinuationCount: 0,
|
|
353
625
|
hasAttemptedReactiveCompact: false,
|
|
354
626
|
startedAt: Date.now(),
|
|
355
627
|
usage: emptyUsage(),
|
|
@@ -370,6 +642,7 @@ function finish(stream, newMessages, state) {
|
|
|
370
642
|
usage: state.usage,
|
|
371
643
|
permissionDenialCount: state.permissionDenials.length,
|
|
372
644
|
permissionDenials: state.permissionDenials,
|
|
645
|
+
lastTransition: state.transition,
|
|
373
646
|
errorMessage: state.finalErrorMessage,
|
|
374
647
|
errorSubtype: state.finalErrorSubtype,
|
|
375
648
|
});
|
package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-adaptive streaming tool executor.
|
|
3
|
+
* Starts complete streamed tool calls before the assistant response finishes,
|
|
4
|
+
* while preserving ordered tool_result emission for the next model turn.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* [WHO]: StructuredAdaptiveStreamingToolExecutor
|
|
8
|
+
* [FROM]: Depends on @pencil-agent/ai, ./types, ./structured-adaptive-tool-orchestration
|
|
9
|
+
* [TO]: Consumed by ./structured-adaptive-agent-loop.ts
|
|
10
|
+
* [HERE]: packages/agent-core/src/structured-adaptive-streaming-tool-executor.ts - streaming tool scheduling for weak-model-compatible loop
|
|
11
|
+
*/
|
|
12
|
+
import { EventStream } from "@pencil-agent/ai";
|
|
13
|
+
import type { AgentEvent, AgentLoopConfig, AgentMessage, AgentTool } from "./types.js";
|
|
14
|
+
import { type StructuredAdaptiveToolCall, type StructuredAdaptiveToolRunResult } from "./structured-adaptive-tool-orchestration.js";
|
|
15
|
+
export declare class StructuredAdaptiveStreamingToolExecutor {
|
|
16
|
+
private readonly stream;
|
|
17
|
+
private readonly canUseTool?;
|
|
18
|
+
private readonly toolByName;
|
|
19
|
+
private readonly records;
|
|
20
|
+
private readonly maxConcurrency;
|
|
21
|
+
private discardedReason;
|
|
22
|
+
private parentAborted;
|
|
23
|
+
private parentAbortReason;
|
|
24
|
+
constructor(tools: AgentTool<any>[] | undefined, signal: AbortSignal | undefined, stream: EventStream<AgentEvent, AgentMessage[]>, maxConcurrency: number, canUseTool?: AgentLoopConfig["canUseTool"]);
|
|
25
|
+
get size(): number;
|
|
26
|
+
addTool(toolCall: StructuredAdaptiveToolCall): void;
|
|
27
|
+
drain(): Promise<StructuredAdaptiveToolRunResult>;
|
|
28
|
+
discardAndDrain(reason: string, abortMode?: "all" | "cancel"): Promise<StructuredAdaptiveToolRunResult>;
|
|
29
|
+
private processQueue;
|
|
30
|
+
private canStart;
|
|
31
|
+
private start;
|
|
32
|
+
private completeWithSyntheticError;
|
|
33
|
+
}
|
package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-streaming-tool-executor.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured-adaptive streaming tool executor.
|
|
3
|
+
* Starts complete streamed tool calls before the assistant response finishes,
|
|
4
|
+
* while preserving ordered tool_result emission for the next model turn.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* [WHO]: StructuredAdaptiveStreamingToolExecutor
|
|
8
|
+
* [FROM]: Depends on @pencil-agent/ai, ./types, ./structured-adaptive-tool-orchestration
|
|
9
|
+
* [TO]: Consumed by ./structured-adaptive-agent-loop.ts
|
|
10
|
+
* [HERE]: packages/agent-core/src/structured-adaptive-streaming-tool-executor.ts - streaming tool scheduling for weak-model-compatible loop
|
|
11
|
+
*/
|
|
12
|
+
import { buildToolMap, isStructuredAdaptiveToolCallConcurrencySafe, resolveStructuredAdaptiveToolInterruptBehavior, runStructuredAdaptiveToolUse, } from "./structured-adaptive-tool-orchestration.js";
|
|
13
|
+
export class StructuredAdaptiveStreamingToolExecutor {
|
|
14
|
+
stream;
|
|
15
|
+
canUseTool;
|
|
16
|
+
toolByName;
|
|
17
|
+
records = [];
|
|
18
|
+
maxConcurrency;
|
|
19
|
+
discardedReason;
|
|
20
|
+
parentAborted = false;
|
|
21
|
+
parentAbortReason;
|
|
22
|
+
constructor(tools, signal, stream, maxConcurrency, canUseTool) {
|
|
23
|
+
this.stream = stream;
|
|
24
|
+
this.canUseTool = canUseTool;
|
|
25
|
+
this.toolByName = buildToolMap(tools);
|
|
26
|
+
this.maxConcurrency = Math.max(1, Math.floor(maxConcurrency));
|
|
27
|
+
if (signal?.aborted) {
|
|
28
|
+
this.parentAborted = true;
|
|
29
|
+
this.parentAbortReason = signal.reason;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
signal?.addEventListener("abort", () => {
|
|
33
|
+
this.parentAborted = true;
|
|
34
|
+
this.parentAbortReason = signal.reason;
|
|
35
|
+
for (const record of this.records) {
|
|
36
|
+
if (record.interruptBehavior === "cancel" && !record.abortController.signal.aborted) {
|
|
37
|
+
record.abortController.abort(signal.reason);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, { once: true });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
get size() {
|
|
44
|
+
return this.records.length;
|
|
45
|
+
}
|
|
46
|
+
addTool(toolCall) {
|
|
47
|
+
if (this.records.some((record) => record.toolCall.id === toolCall.id))
|
|
48
|
+
return;
|
|
49
|
+
const tool = this.toolByName.get(toolCall.name);
|
|
50
|
+
const abortController = new AbortController();
|
|
51
|
+
const interruptBehavior = resolveStructuredAdaptiveToolInterruptBehavior(toolCall, tool);
|
|
52
|
+
if (this.parentAborted && interruptBehavior === "cancel") {
|
|
53
|
+
abortController.abort(this.parentAbortReason);
|
|
54
|
+
}
|
|
55
|
+
this.records.push({
|
|
56
|
+
toolCall,
|
|
57
|
+
tool,
|
|
58
|
+
isConcurrencySafe: isStructuredAdaptiveToolCallConcurrencySafe(toolCall, tool),
|
|
59
|
+
interruptBehavior,
|
|
60
|
+
status: "queued",
|
|
61
|
+
abortController,
|
|
62
|
+
contextMessages: [],
|
|
63
|
+
});
|
|
64
|
+
this.processQueue();
|
|
65
|
+
}
|
|
66
|
+
async drain() {
|
|
67
|
+
this.processQueue();
|
|
68
|
+
while (this.records.some((record) => record.status !== "completed")) {
|
|
69
|
+
const running = this.records
|
|
70
|
+
.filter((record) => record.status === "executing" && record.promise)
|
|
71
|
+
.map((record) => record.promise);
|
|
72
|
+
if (running.length === 0) {
|
|
73
|
+
this.processQueue();
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
await Promise.race(running);
|
|
77
|
+
this.processQueue();
|
|
78
|
+
}
|
|
79
|
+
const toolResults = this.records.map((record) => record.toolResult);
|
|
80
|
+
return {
|
|
81
|
+
toolResults,
|
|
82
|
+
contextMessages: this.records.flatMap((record) => record.contextMessages),
|
|
83
|
+
permissionDenials: extractPermissionDenials(toolResults),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
async discardAndDrain(reason, abortMode = "all") {
|
|
87
|
+
this.discardedReason = reason;
|
|
88
|
+
for (const record of this.records) {
|
|
89
|
+
if (record.status === "executing" &&
|
|
90
|
+
(abortMode === "all" || record.interruptBehavior === "cancel") &&
|
|
91
|
+
!record.abortController.signal.aborted) {
|
|
92
|
+
record.abortController.abort(reason);
|
|
93
|
+
}
|
|
94
|
+
if (record.status === "queued") {
|
|
95
|
+
this.completeWithSyntheticError(record, reason);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return this.drain();
|
|
99
|
+
}
|
|
100
|
+
processQueue() {
|
|
101
|
+
for (const record of this.records) {
|
|
102
|
+
if (record.status !== "queued")
|
|
103
|
+
continue;
|
|
104
|
+
if (this.discardedReason) {
|
|
105
|
+
this.completeWithSyntheticError(record, this.discardedReason);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (!this.canStart(record)) {
|
|
109
|
+
if (!record.isConcurrencySafe)
|
|
110
|
+
return;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
this.start(record);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
canStart(record) {
|
|
117
|
+
const executing = this.records.filter((candidate) => candidate.status === "executing");
|
|
118
|
+
if (record.isConcurrencySafe) {
|
|
119
|
+
return (executing.length < this.maxConcurrency &&
|
|
120
|
+
executing.every((candidate) => candidate.isConcurrencySafe));
|
|
121
|
+
}
|
|
122
|
+
return executing.length === 0;
|
|
123
|
+
}
|
|
124
|
+
start(record) {
|
|
125
|
+
record.status = "executing";
|
|
126
|
+
record.promise = runStructuredAdaptiveToolUse(record.toolCall, record.tool, record.abortController.signal, this.stream, this.canUseTool)
|
|
127
|
+
.then((result) => {
|
|
128
|
+
record.toolResult = result.toolResult;
|
|
129
|
+
record.contextMessages = result.contextMessages;
|
|
130
|
+
})
|
|
131
|
+
.finally(() => {
|
|
132
|
+
record.status = "completed";
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
completeWithSyntheticError(record, reason) {
|
|
136
|
+
const startedAt = Date.now();
|
|
137
|
+
const result = {
|
|
138
|
+
content: [{ type: "text", text: `Tool discarded because ${reason}.` }],
|
|
139
|
+
details: {
|
|
140
|
+
errorType: "streaming_tool_discarded",
|
|
141
|
+
reason,
|
|
142
|
+
toolName: record.tool?.name ?? record.toolCall.name,
|
|
143
|
+
toolCallId: record.toolCall.id,
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
this.stream.push({
|
|
147
|
+
type: "tool_execution_start",
|
|
148
|
+
toolCallId: record.toolCall.id,
|
|
149
|
+
toolName: record.toolCall.name,
|
|
150
|
+
args: record.toolCall.arguments,
|
|
151
|
+
});
|
|
152
|
+
this.stream.push({
|
|
153
|
+
type: "tool_execution_end",
|
|
154
|
+
toolCallId: record.toolCall.id,
|
|
155
|
+
toolName: record.toolCall.name,
|
|
156
|
+
result,
|
|
157
|
+
isError: true,
|
|
158
|
+
durationMs: Date.now() - startedAt,
|
|
159
|
+
});
|
|
160
|
+
record.toolResult = {
|
|
161
|
+
role: "toolResult",
|
|
162
|
+
toolCallId: record.toolCall.id,
|
|
163
|
+
toolName: record.toolCall.name,
|
|
164
|
+
content: result.content,
|
|
165
|
+
details: result.details,
|
|
166
|
+
isError: true,
|
|
167
|
+
timestamp: Date.now(),
|
|
168
|
+
};
|
|
169
|
+
record.contextMessages = [];
|
|
170
|
+
record.status = "completed";
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function extractPermissionDenials(toolResults) {
|
|
174
|
+
const denials = [];
|
|
175
|
+
for (const result of toolResults) {
|
|
176
|
+
const details = result.details;
|
|
177
|
+
if (!details || typeof details !== "object")
|
|
178
|
+
continue;
|
|
179
|
+
if (details.errorType !== "permission_denied")
|
|
180
|
+
continue;
|
|
181
|
+
const reason = details.reason;
|
|
182
|
+
denials.push({
|
|
183
|
+
toolCallId: result.toolCallId,
|
|
184
|
+
toolName: result.toolName,
|
|
185
|
+
reason: typeof reason === "string" && reason.length > 0 ? reason : undefined,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return denials;
|
|
189
|
+
}
|
package/dist/node_modules/@pencil-agent/agent-core/structured-adaptive-tool-orchestration.d.ts
CHANGED
|
@@ -20,6 +20,15 @@ export interface StructuredAdaptiveToolRunResult {
|
|
|
20
20
|
steeringMessages?: AgentMessage[];
|
|
21
21
|
permissionDenials: AgentToolPermissionDenial[];
|
|
22
22
|
}
|
|
23
|
+
interface StructuredAdaptiveToolUseResult {
|
|
24
|
+
toolResult: ToolResultMessage;
|
|
25
|
+
contextMessages: AgentMessage[];
|
|
26
|
+
}
|
|
23
27
|
export declare function runStructuredAdaptiveTools(toolCalls: StructuredAdaptiveToolCall[], tools: AgentTool<any>[] | undefined, signal: AbortSignal | undefined, stream: EventStream<AgentEvent, AgentMessage[]>, getSteeringMessages?: AgentLoopConfig["getSteeringMessages"], maxConcurrency?: number, canUseTool?: AgentLoopConfig["canUseTool"]): Promise<StructuredAdaptiveToolRunResult>;
|
|
28
|
+
export declare function resolveMaxToolConcurrency(maxConcurrency: number | undefined): number;
|
|
24
29
|
export declare function buildToolMap(tools: AgentTool<any>[] | undefined): Map<string, AgentTool<any>>;
|
|
25
30
|
export declare function partitionStructuredAdaptiveToolCalls(toolCalls: StructuredAdaptiveToolCall[], toolByName: Map<string, AgentTool<any>>): StructuredAdaptiveToolCall[][];
|
|
31
|
+
export declare function isStructuredAdaptiveToolCallConcurrencySafe(toolCall: StructuredAdaptiveToolCall, tool: AgentTool<any> | undefined): boolean;
|
|
32
|
+
export declare function resolveStructuredAdaptiveToolInterruptBehavior(toolCall: StructuredAdaptiveToolCall, tool: AgentTool<any> | undefined): "cancel" | "block";
|
|
33
|
+
export declare function runStructuredAdaptiveToolUse(toolCall: StructuredAdaptiveToolCall, tool: AgentTool<any> | undefined, signal: AbortSignal | undefined, stream: EventStream<AgentEvent, AgentMessage[]>, canUseTool?: AgentLoopConfig["canUseTool"]): Promise<StructuredAdaptiveToolUseResult>;
|
|
34
|
+
export {};
|