@cydm/pie 1.0.14 → 1.0.15
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/builtin/extensions/ask-user/index.js +3 -2
- package/dist/builtin/extensions/plan-mode/index.js +3 -2
- package/dist/builtin/extensions/subagent/index.js +4 -3
- package/dist/builtin/extensions/todo/index.js +3 -2
- package/dist/chunks/{chunk-EFG2MQFD.js → chunk-55RUSXEA.js} +2 -2
- package/dist/chunks/{chunk-D7NAXU7F.js → chunk-5DA2D3K2.js} +79 -1097
- package/dist/chunks/{chunk-LF5Q7BVU.js → chunk-R5LYKDKA.js} +56 -5
- package/dist/chunks/chunk-VE2HDCNB.js +1029 -0
- package/dist/chunks/{src-LZC56DRG.js → src-6WPNVGT2.js} +2 -1
- package/dist/chunks/test-stream-ZSKNLUEJ.js +94 -0
- package/dist/cli.js +207 -33
- package/package.json +1 -1
|
@@ -242,6 +242,83 @@ var require_dist = __commonJS({
|
|
|
242
242
|
}
|
|
243
243
|
});
|
|
244
244
|
|
|
245
|
+
// ../../packages/ai/src/utils/event-stream.ts
|
|
246
|
+
var EventStream = class {
|
|
247
|
+
constructor(isComplete, extractResult) {
|
|
248
|
+
this.isComplete = isComplete;
|
|
249
|
+
this.extractResult = extractResult;
|
|
250
|
+
this.finalResultPromise = new Promise((resolve) => {
|
|
251
|
+
this.resolveFinalResult = resolve;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
isComplete;
|
|
255
|
+
extractResult;
|
|
256
|
+
queue = [];
|
|
257
|
+
waiting = [];
|
|
258
|
+
done = false;
|
|
259
|
+
resultResolved = false;
|
|
260
|
+
finalResultPromise;
|
|
261
|
+
resolveFinalResult;
|
|
262
|
+
push(event) {
|
|
263
|
+
if (this.done) return;
|
|
264
|
+
if (this.isComplete(event)) {
|
|
265
|
+
this.done = true;
|
|
266
|
+
if (!this.resultResolved) {
|
|
267
|
+
this.resultResolved = true;
|
|
268
|
+
this.resolveFinalResult(this.extractResult(event));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const waiter = this.waiting.shift();
|
|
272
|
+
if (waiter) {
|
|
273
|
+
waiter({ value: event, done: false });
|
|
274
|
+
} else {
|
|
275
|
+
this.queue.push(event);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
end(result) {
|
|
279
|
+
this.done = true;
|
|
280
|
+
if (result !== void 0 && !this.resultResolved) {
|
|
281
|
+
this.resultResolved = true;
|
|
282
|
+
this.resolveFinalResult(result);
|
|
283
|
+
}
|
|
284
|
+
while (this.waiting.length > 0) {
|
|
285
|
+
const waiter = this.waiting.shift();
|
|
286
|
+
waiter({ value: void 0, done: true });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
async *[Symbol.asyncIterator]() {
|
|
290
|
+
while (true) {
|
|
291
|
+
if (this.queue.length > 0) {
|
|
292
|
+
yield this.queue.shift();
|
|
293
|
+
} else if (this.done) {
|
|
294
|
+
return;
|
|
295
|
+
} else {
|
|
296
|
+
const result = await new Promise((resolve) => this.waiting.push(resolve));
|
|
297
|
+
if (result.done) return;
|
|
298
|
+
yield result.value;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
result() {
|
|
303
|
+
return this.finalResultPromise;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
var AssistantMessageEventStream = class extends EventStream {
|
|
307
|
+
constructor() {
|
|
308
|
+
super(
|
|
309
|
+
(event) => event.type === "done" || event.type === "error",
|
|
310
|
+
(event) => {
|
|
311
|
+
if (event.type === "done") {
|
|
312
|
+
return event.message;
|
|
313
|
+
} else if (event.type === "error") {
|
|
314
|
+
return event.error;
|
|
315
|
+
}
|
|
316
|
+
throw new Error("Unexpected event type for final result");
|
|
317
|
+
}
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
245
322
|
// ../../node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
|
|
246
323
|
var value_exports = {};
|
|
247
324
|
__export(value_exports, {
|
|
@@ -3030,83 +3107,6 @@ function calculateCost(model, usage) {
|
|
|
3030
3107
|
};
|
|
3031
3108
|
}
|
|
3032
3109
|
|
|
3033
|
-
// ../../packages/ai/src/utils/event-stream.ts
|
|
3034
|
-
var EventStream = class {
|
|
3035
|
-
constructor(isComplete, extractResult) {
|
|
3036
|
-
this.isComplete = isComplete;
|
|
3037
|
-
this.extractResult = extractResult;
|
|
3038
|
-
this.finalResultPromise = new Promise((resolve) => {
|
|
3039
|
-
this.resolveFinalResult = resolve;
|
|
3040
|
-
});
|
|
3041
|
-
}
|
|
3042
|
-
isComplete;
|
|
3043
|
-
extractResult;
|
|
3044
|
-
queue = [];
|
|
3045
|
-
waiting = [];
|
|
3046
|
-
done = false;
|
|
3047
|
-
resultResolved = false;
|
|
3048
|
-
finalResultPromise;
|
|
3049
|
-
resolveFinalResult;
|
|
3050
|
-
push(event) {
|
|
3051
|
-
if (this.done) return;
|
|
3052
|
-
if (this.isComplete(event)) {
|
|
3053
|
-
this.done = true;
|
|
3054
|
-
if (!this.resultResolved) {
|
|
3055
|
-
this.resultResolved = true;
|
|
3056
|
-
this.resolveFinalResult(this.extractResult(event));
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3059
|
-
const waiter = this.waiting.shift();
|
|
3060
|
-
if (waiter) {
|
|
3061
|
-
waiter({ value: event, done: false });
|
|
3062
|
-
} else {
|
|
3063
|
-
this.queue.push(event);
|
|
3064
|
-
}
|
|
3065
|
-
}
|
|
3066
|
-
end(result) {
|
|
3067
|
-
this.done = true;
|
|
3068
|
-
if (result !== void 0 && !this.resultResolved) {
|
|
3069
|
-
this.resultResolved = true;
|
|
3070
|
-
this.resolveFinalResult(result);
|
|
3071
|
-
}
|
|
3072
|
-
while (this.waiting.length > 0) {
|
|
3073
|
-
const waiter = this.waiting.shift();
|
|
3074
|
-
waiter({ value: void 0, done: true });
|
|
3075
|
-
}
|
|
3076
|
-
}
|
|
3077
|
-
async *[Symbol.asyncIterator]() {
|
|
3078
|
-
while (true) {
|
|
3079
|
-
if (this.queue.length > 0) {
|
|
3080
|
-
yield this.queue.shift();
|
|
3081
|
-
} else if (this.done) {
|
|
3082
|
-
return;
|
|
3083
|
-
} else {
|
|
3084
|
-
const result = await new Promise((resolve) => this.waiting.push(resolve));
|
|
3085
|
-
if (result.done) return;
|
|
3086
|
-
yield result.value;
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
}
|
|
3090
|
-
result() {
|
|
3091
|
-
return this.finalResultPromise;
|
|
3092
|
-
}
|
|
3093
|
-
};
|
|
3094
|
-
var AssistantMessageEventStream = class extends EventStream {
|
|
3095
|
-
constructor() {
|
|
3096
|
-
super(
|
|
3097
|
-
(event) => event.type === "done" || event.type === "error",
|
|
3098
|
-
(event) => {
|
|
3099
|
-
if (event.type === "done") {
|
|
3100
|
-
return event.message;
|
|
3101
|
-
} else if (event.type === "error") {
|
|
3102
|
-
return event.error;
|
|
3103
|
-
}
|
|
3104
|
-
throw new Error("Unexpected event type for final result");
|
|
3105
|
-
}
|
|
3106
|
-
);
|
|
3107
|
-
}
|
|
3108
|
-
};
|
|
3109
|
-
|
|
3110
3110
|
// ../../packages/platform/src/detector.ts
|
|
3111
3111
|
function isPuerTS() {
|
|
3112
3112
|
try {
|
|
@@ -9120,1023 +9120,6 @@ registerApiProvider({
|
|
|
9120
9120
|
streamSimple: streamSimpleAnthropic
|
|
9121
9121
|
});
|
|
9122
9122
|
|
|
9123
|
-
// ../../packages/agent-core/src/agent-loop.ts
|
|
9124
|
-
function createLoopErrorMessage(error, config, signal) {
|
|
9125
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
9126
|
-
return {
|
|
9127
|
-
role: "assistant",
|
|
9128
|
-
content: [{ type: "text", text: "" }],
|
|
9129
|
-
api: config.model.api,
|
|
9130
|
-
provider: config.model.provider,
|
|
9131
|
-
model: config.model.id,
|
|
9132
|
-
usage: {
|
|
9133
|
-
input: 0,
|
|
9134
|
-
output: 0,
|
|
9135
|
-
cacheRead: 0,
|
|
9136
|
-
cacheWrite: 0,
|
|
9137
|
-
totalTokens: 0,
|
|
9138
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
9139
|
-
},
|
|
9140
|
-
stopReason: signal?.aborted ? "aborted" : "error",
|
|
9141
|
-
errorMessage: message,
|
|
9142
|
-
timestamp: Date.now()
|
|
9143
|
-
};
|
|
9144
|
-
}
|
|
9145
|
-
async function notifyOnError(config, error, phase) {
|
|
9146
|
-
try {
|
|
9147
|
-
await config.hooks?.onError?.(error instanceof Error ? error : new Error(String(error)), { phase });
|
|
9148
|
-
} catch (hookError) {
|
|
9149
|
-
console.warn(`[AgentLoop] onError hook failed during ${phase}:`, hookError);
|
|
9150
|
-
}
|
|
9151
|
-
}
|
|
9152
|
-
function endStreamWithError(stream, newMessages, config, signal, error) {
|
|
9153
|
-
const errorMessage = createLoopErrorMessage(error, config, signal);
|
|
9154
|
-
newMessages.push(errorMessage);
|
|
9155
|
-
stream.push({ type: "message_start", message: errorMessage });
|
|
9156
|
-
stream.push({ type: "message_end", message: errorMessage });
|
|
9157
|
-
stream.push({ type: "turn_end", message: errorMessage, toolResults: [] });
|
|
9158
|
-
stream.push({ type: "agent_end", messages: newMessages });
|
|
9159
|
-
stream.end(newMessages);
|
|
9160
|
-
}
|
|
9161
|
-
function agentLoop(prompts, context, config, signal, streamFn) {
|
|
9162
|
-
const stream = createAgentStream();
|
|
9163
|
-
(async () => {
|
|
9164
|
-
const newMessages = [...prompts];
|
|
9165
|
-
try {
|
|
9166
|
-
try {
|
|
9167
|
-
await config.hooks?.beforeAgentStart?.();
|
|
9168
|
-
} catch (e) {
|
|
9169
|
-
console.warn("[AgentLoop] beforeAgentStart hook failed:", e);
|
|
9170
|
-
}
|
|
9171
|
-
const currentContext = {
|
|
9172
|
-
...context,
|
|
9173
|
-
messages: [...context.messages, ...prompts]
|
|
9174
|
-
};
|
|
9175
|
-
stream.push({ type: "agent_start" });
|
|
9176
|
-
stream.push({ type: "turn_start" });
|
|
9177
|
-
for (const prompt of prompts) {
|
|
9178
|
-
stream.push({ type: "message_start", message: prompt });
|
|
9179
|
-
stream.push({ type: "message_end", message: prompt });
|
|
9180
|
-
}
|
|
9181
|
-
try {
|
|
9182
|
-
await runLoop(currentContext, newMessages, config, signal, stream, streamFn);
|
|
9183
|
-
} catch (error) {
|
|
9184
|
-
await notifyOnError(config, error, "runLoop");
|
|
9185
|
-
endStreamWithError(stream, newMessages, config, signal, error);
|
|
9186
|
-
return;
|
|
9187
|
-
}
|
|
9188
|
-
try {
|
|
9189
|
-
await config.hooks?.afterAgentEnd?.(newMessages);
|
|
9190
|
-
} catch (e) {
|
|
9191
|
-
console.warn("[AgentLoop] afterAgentEnd hook failed:", e);
|
|
9192
|
-
}
|
|
9193
|
-
} catch (error) {
|
|
9194
|
-
await notifyOnError(config, error, "agentLoop");
|
|
9195
|
-
endStreamWithError(stream, newMessages, config, signal, error);
|
|
9196
|
-
}
|
|
9197
|
-
})();
|
|
9198
|
-
return stream;
|
|
9199
|
-
}
|
|
9200
|
-
function agentLoopContinue(context, config, signal, streamFn) {
|
|
9201
|
-
if (context.messages.length === 0) {
|
|
9202
|
-
throw new Error("Cannot continue: no messages in context");
|
|
9203
|
-
}
|
|
9204
|
-
if (context.messages[context.messages.length - 1].role === "assistant") {
|
|
9205
|
-
throw new Error("Cannot continue from message role: assistant");
|
|
9206
|
-
}
|
|
9207
|
-
const stream = createAgentStream();
|
|
9208
|
-
(async () => {
|
|
9209
|
-
const newMessages = [];
|
|
9210
|
-
try {
|
|
9211
|
-
try {
|
|
9212
|
-
await config.hooks?.beforeAgentStart?.();
|
|
9213
|
-
} catch (e) {
|
|
9214
|
-
console.warn("[AgentLoop] beforeAgentStart hook failed:", e);
|
|
9215
|
-
}
|
|
9216
|
-
const currentContext = { ...context };
|
|
9217
|
-
stream.push({ type: "agent_start" });
|
|
9218
|
-
stream.push({ type: "turn_start" });
|
|
9219
|
-
try {
|
|
9220
|
-
await runLoop(currentContext, newMessages, config, signal, stream, streamFn);
|
|
9221
|
-
} catch (error) {
|
|
9222
|
-
await notifyOnError(config, error, "runLoop");
|
|
9223
|
-
endStreamWithError(stream, newMessages, config, signal, error);
|
|
9224
|
-
return;
|
|
9225
|
-
}
|
|
9226
|
-
try {
|
|
9227
|
-
await config.hooks?.afterAgentEnd?.(newMessages);
|
|
9228
|
-
} catch (e) {
|
|
9229
|
-
console.warn("[AgentLoop] afterAgentEnd hook failed:", e);
|
|
9230
|
-
}
|
|
9231
|
-
} catch (error) {
|
|
9232
|
-
await notifyOnError(config, error, "agentLoopContinue");
|
|
9233
|
-
endStreamWithError(stream, newMessages, config, signal, error);
|
|
9234
|
-
}
|
|
9235
|
-
})();
|
|
9236
|
-
return stream;
|
|
9237
|
-
}
|
|
9238
|
-
function createAgentStream() {
|
|
9239
|
-
return new EventStream(
|
|
9240
|
-
(event) => event.type === "agent_end",
|
|
9241
|
-
(event) => event.type === "agent_end" ? event.messages : []
|
|
9242
|
-
);
|
|
9243
|
-
}
|
|
9244
|
-
async function runLoop(currentContext, newMessages, config, signal, stream, streamFn) {
|
|
9245
|
-
let firstTurn = true;
|
|
9246
|
-
let pendingMessages = await config.getSteeringMessages?.() || [];
|
|
9247
|
-
while (true) {
|
|
9248
|
-
let hasMoreToolCalls = true;
|
|
9249
|
-
let steeringAfterTools = null;
|
|
9250
|
-
while (hasMoreToolCalls || pendingMessages.length > 0) {
|
|
9251
|
-
if (!firstTurn) {
|
|
9252
|
-
stream.push({ type: "turn_start" });
|
|
9253
|
-
} else {
|
|
9254
|
-
firstTurn = false;
|
|
9255
|
-
}
|
|
9256
|
-
if (pendingMessages.length > 0) {
|
|
9257
|
-
for (const message2 of pendingMessages) {
|
|
9258
|
-
stream.push({ type: "message_start", message: message2 });
|
|
9259
|
-
stream.push({ type: "message_end", message: message2 });
|
|
9260
|
-
currentContext.messages.push(message2);
|
|
9261
|
-
newMessages.push(message2);
|
|
9262
|
-
}
|
|
9263
|
-
pendingMessages = [];
|
|
9264
|
-
}
|
|
9265
|
-
let message;
|
|
9266
|
-
try {
|
|
9267
|
-
message = await streamAssistantResponse(currentContext, config, signal, stream, streamFn);
|
|
9268
|
-
} catch (error) {
|
|
9269
|
-
await notifyOnError(config, error, "streamAssistantResponse");
|
|
9270
|
-
throw error;
|
|
9271
|
-
}
|
|
9272
|
-
newMessages.push(message);
|
|
9273
|
-
if (message.stopReason === "error" || message.stopReason === "aborted") {
|
|
9274
|
-
stream.push({ type: "turn_end", message, toolResults: [] });
|
|
9275
|
-
stream.push({ type: "agent_end", messages: newMessages });
|
|
9276
|
-
stream.end(newMessages);
|
|
9277
|
-
return;
|
|
9278
|
-
}
|
|
9279
|
-
const toolCalls = message.content.filter((c) => c.type === "toolCall");
|
|
9280
|
-
hasMoreToolCalls = toolCalls.length > 0;
|
|
9281
|
-
const toolResults = [];
|
|
9282
|
-
if (hasMoreToolCalls) {
|
|
9283
|
-
const toolExecution = await executeToolCalls(
|
|
9284
|
-
currentContext.tools,
|
|
9285
|
-
message,
|
|
9286
|
-
signal,
|
|
9287
|
-
stream,
|
|
9288
|
-
config.getSteeringMessages,
|
|
9289
|
-
config.hooks
|
|
9290
|
-
);
|
|
9291
|
-
toolResults.push(...toolExecution.toolResults);
|
|
9292
|
-
steeringAfterTools = toolExecution.steeringMessages ?? null;
|
|
9293
|
-
for (const result of toolResults) {
|
|
9294
|
-
currentContext.messages.push(result);
|
|
9295
|
-
newMessages.push(result);
|
|
9296
|
-
}
|
|
9297
|
-
}
|
|
9298
|
-
stream.push({ type: "turn_end", message, toolResults });
|
|
9299
|
-
if (steeringAfterTools && steeringAfterTools.length > 0) {
|
|
9300
|
-
pendingMessages = steeringAfterTools;
|
|
9301
|
-
steeringAfterTools = null;
|
|
9302
|
-
} else {
|
|
9303
|
-
pendingMessages = await config.getSteeringMessages?.() || [];
|
|
9304
|
-
}
|
|
9305
|
-
}
|
|
9306
|
-
const followUpMessages = await config.getFollowUpMessages?.() || [];
|
|
9307
|
-
if (followUpMessages.length > 0) {
|
|
9308
|
-
pendingMessages = followUpMessages;
|
|
9309
|
-
continue;
|
|
9310
|
-
}
|
|
9311
|
-
break;
|
|
9312
|
-
}
|
|
9313
|
-
stream.push({ type: "agent_end", messages: newMessages });
|
|
9314
|
-
stream.end(newMessages);
|
|
9315
|
-
}
|
|
9316
|
-
async function streamAssistantResponse(context, config, signal, stream, streamFn) {
|
|
9317
|
-
let messages = context.messages;
|
|
9318
|
-
if (config.transformContext) {
|
|
9319
|
-
messages = await config.transformContext(messages, signal);
|
|
9320
|
-
}
|
|
9321
|
-
const llmMessages = await config.convertToLlm(messages);
|
|
9322
|
-
const llmContext = {
|
|
9323
|
-
systemPrompt: context.systemPrompt,
|
|
9324
|
-
messages: llmMessages,
|
|
9325
|
-
tools: context.tools
|
|
9326
|
-
};
|
|
9327
|
-
const streamFunction = streamFn || streamSimple;
|
|
9328
|
-
const resolvedApiKey = (config.getApiKey ? await config.getApiKey(config.model.provider) : void 0) || config.apiKey;
|
|
9329
|
-
const response = await streamFunction(config.model, llmContext, {
|
|
9330
|
-
...config,
|
|
9331
|
-
apiKey: resolvedApiKey,
|
|
9332
|
-
signal
|
|
9333
|
-
});
|
|
9334
|
-
let partialMessage = null;
|
|
9335
|
-
let addedPartial = false;
|
|
9336
|
-
for await (const event of response) {
|
|
9337
|
-
switch (event.type) {
|
|
9338
|
-
case "start":
|
|
9339
|
-
partialMessage = event.partial;
|
|
9340
|
-
context.messages.push(partialMessage);
|
|
9341
|
-
addedPartial = true;
|
|
9342
|
-
stream.push({ type: "message_start", message: { ...partialMessage } });
|
|
9343
|
-
break;
|
|
9344
|
-
case "text_start":
|
|
9345
|
-
case "text_delta":
|
|
9346
|
-
case "text_end":
|
|
9347
|
-
case "thinking_start":
|
|
9348
|
-
case "thinking_delta":
|
|
9349
|
-
case "thinking_end":
|
|
9350
|
-
case "toolcall_start":
|
|
9351
|
-
case "toolcall_delta":
|
|
9352
|
-
case "toolcall_end":
|
|
9353
|
-
if (partialMessage) {
|
|
9354
|
-
partialMessage = event.partial;
|
|
9355
|
-
context.messages[context.messages.length - 1] = partialMessage;
|
|
9356
|
-
stream.push({
|
|
9357
|
-
type: "message_update",
|
|
9358
|
-
assistantMessageEvent: event,
|
|
9359
|
-
message: { ...partialMessage }
|
|
9360
|
-
});
|
|
9361
|
-
}
|
|
9362
|
-
break;
|
|
9363
|
-
case "done":
|
|
9364
|
-
case "error": {
|
|
9365
|
-
const finalMessage = await response.result();
|
|
9366
|
-
if (addedPartial) {
|
|
9367
|
-
context.messages[context.messages.length - 1] = finalMessage;
|
|
9368
|
-
} else {
|
|
9369
|
-
context.messages.push(finalMessage);
|
|
9370
|
-
}
|
|
9371
|
-
if (!addedPartial) {
|
|
9372
|
-
stream.push({ type: "message_start", message: { ...finalMessage } });
|
|
9373
|
-
}
|
|
9374
|
-
stream.push({ type: "message_end", message: finalMessage });
|
|
9375
|
-
return finalMessage;
|
|
9376
|
-
}
|
|
9377
|
-
}
|
|
9378
|
-
}
|
|
9379
|
-
return await response.result();
|
|
9380
|
-
}
|
|
9381
|
-
async function executeToolCalls(tools, assistantMessage, signal, stream, getSteeringMessages, hooks) {
|
|
9382
|
-
const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
|
|
9383
|
-
const results = [];
|
|
9384
|
-
let steeringMessages;
|
|
9385
|
-
for (let index = 0; index < toolCalls.length; index++) {
|
|
9386
|
-
const toolCall = toolCalls[index];
|
|
9387
|
-
const tool = tools?.find((t) => t.name === toolCall.name);
|
|
9388
|
-
let blocked = false;
|
|
9389
|
-
let blockReason;
|
|
9390
|
-
try {
|
|
9391
|
-
const hookResult = await hooks?.beforeToolCall?.(toolCall.name, toolCall.arguments);
|
|
9392
|
-
if (hookResult && hookResult.block) {
|
|
9393
|
-
blocked = true;
|
|
9394
|
-
blockReason = hookResult.reason || "Blocked by hook";
|
|
9395
|
-
}
|
|
9396
|
-
} catch (e) {
|
|
9397
|
-
console.warn(`[AgentLoop] beforeToolCall hook failed for ${toolCall.name}:`, e);
|
|
9398
|
-
}
|
|
9399
|
-
let result;
|
|
9400
|
-
let isError = false;
|
|
9401
|
-
let executionArgs = toolCall.arguments;
|
|
9402
|
-
let started = false;
|
|
9403
|
-
const pushToolStart = () => {
|
|
9404
|
-
if (started) return;
|
|
9405
|
-
started = true;
|
|
9406
|
-
stream.push({
|
|
9407
|
-
type: "tool_execution_start",
|
|
9408
|
-
toolCallId: toolCall.id,
|
|
9409
|
-
toolName: toolCall.name,
|
|
9410
|
-
args: executionArgs
|
|
9411
|
-
});
|
|
9412
|
-
};
|
|
9413
|
-
if (blocked) {
|
|
9414
|
-
pushToolStart();
|
|
9415
|
-
result = {
|
|
9416
|
-
content: [{ type: "text", text: `Tool execution blocked: ${blockReason}` }],
|
|
9417
|
-
details: { blocked: true, reason: blockReason }
|
|
9418
|
-
};
|
|
9419
|
-
isError = true;
|
|
9420
|
-
} else {
|
|
9421
|
-
try {
|
|
9422
|
-
if (!tool) {
|
|
9423
|
-
throw new Error(`Tool ${toolCall.name} not found`);
|
|
9424
|
-
}
|
|
9425
|
-
const validatedArgs = validateToolArguments(tool, toolCall);
|
|
9426
|
-
executionArgs = validatedArgs;
|
|
9427
|
-
pushToolStart();
|
|
9428
|
-
result = await tool.execute(toolCall.id, validatedArgs, signal, (partialResult) => {
|
|
9429
|
-
stream.push({
|
|
9430
|
-
type: "tool_execution_update",
|
|
9431
|
-
toolCallId: toolCall.id,
|
|
9432
|
-
toolName: toolCall.name,
|
|
9433
|
-
args: executionArgs,
|
|
9434
|
-
partialResult
|
|
9435
|
-
});
|
|
9436
|
-
});
|
|
9437
|
-
isError = isError || !!result.isError;
|
|
9438
|
-
} catch (e) {
|
|
9439
|
-
pushToolStart();
|
|
9440
|
-
result = {
|
|
9441
|
-
content: [{ type: "text", text: e instanceof Error ? e.message : String(e) }],
|
|
9442
|
-
details: {}
|
|
9443
|
-
};
|
|
9444
|
-
isError = true;
|
|
9445
|
-
try {
|
|
9446
|
-
await hooks?.onError?.(e instanceof Error ? e : new Error(String(e)), {
|
|
9447
|
-
toolName: toolCall.name,
|
|
9448
|
-
phase: "toolExecution"
|
|
9449
|
-
});
|
|
9450
|
-
} catch (hookError) {
|
|
9451
|
-
console.warn(`[AgentLoop] onError hook failed during toolExecution for ${toolCall.name}:`, hookError);
|
|
9452
|
-
}
|
|
9453
|
-
}
|
|
9454
|
-
}
|
|
9455
|
-
try {
|
|
9456
|
-
await hooks?.afterToolCall?.(toolCall.name, toolCall.arguments, result, isError);
|
|
9457
|
-
} catch (e) {
|
|
9458
|
-
console.warn(`[AgentLoop] afterToolCall hook failed for ${toolCall.name}:`, e);
|
|
9459
|
-
}
|
|
9460
|
-
stream.push({
|
|
9461
|
-
type: "tool_execution_end",
|
|
9462
|
-
toolCallId: toolCall.id,
|
|
9463
|
-
toolName: toolCall.name,
|
|
9464
|
-
args: executionArgs,
|
|
9465
|
-
result,
|
|
9466
|
-
isError
|
|
9467
|
-
});
|
|
9468
|
-
const toolResultMessage = {
|
|
9469
|
-
role: "toolResult",
|
|
9470
|
-
toolCallId: toolCall.id,
|
|
9471
|
-
toolName: toolCall.name,
|
|
9472
|
-
content: result.content,
|
|
9473
|
-
details: result.details,
|
|
9474
|
-
isError,
|
|
9475
|
-
timestamp: Date.now()
|
|
9476
|
-
};
|
|
9477
|
-
results.push(toolResultMessage);
|
|
9478
|
-
stream.push({ type: "message_start", message: toolResultMessage });
|
|
9479
|
-
stream.push({ type: "message_end", message: toolResultMessage });
|
|
9480
|
-
if (getSteeringMessages) {
|
|
9481
|
-
const steering = await getSteeringMessages();
|
|
9482
|
-
if (steering.length > 0) {
|
|
9483
|
-
steeringMessages = steering;
|
|
9484
|
-
const remainingCalls = toolCalls.slice(index + 1);
|
|
9485
|
-
for (const skipped of remainingCalls) {
|
|
9486
|
-
results.push(skipToolCall(skipped, stream));
|
|
9487
|
-
}
|
|
9488
|
-
break;
|
|
9489
|
-
}
|
|
9490
|
-
}
|
|
9491
|
-
}
|
|
9492
|
-
return { toolResults: results, steeringMessages };
|
|
9493
|
-
}
|
|
9494
|
-
function skipToolCall(toolCall, stream) {
|
|
9495
|
-
const result = {
|
|
9496
|
-
content: [{ type: "text", text: "Skipped due to queued user message." }],
|
|
9497
|
-
details: {}
|
|
9498
|
-
};
|
|
9499
|
-
stream.push({
|
|
9500
|
-
type: "tool_execution_start",
|
|
9501
|
-
toolCallId: toolCall.id,
|
|
9502
|
-
toolName: toolCall.name,
|
|
9503
|
-
args: toolCall.arguments
|
|
9504
|
-
});
|
|
9505
|
-
stream.push({
|
|
9506
|
-
type: "tool_execution_end",
|
|
9507
|
-
toolCallId: toolCall.id,
|
|
9508
|
-
toolName: toolCall.name,
|
|
9509
|
-
args: toolCall.arguments,
|
|
9510
|
-
result,
|
|
9511
|
-
isError: true
|
|
9512
|
-
});
|
|
9513
|
-
const toolResultMessage = {
|
|
9514
|
-
role: "toolResult",
|
|
9515
|
-
toolCallId: toolCall.id,
|
|
9516
|
-
toolName: toolCall.name,
|
|
9517
|
-
content: result.content,
|
|
9518
|
-
details: {},
|
|
9519
|
-
isError: true,
|
|
9520
|
-
timestamp: Date.now()
|
|
9521
|
-
};
|
|
9522
|
-
stream.push({ type: "message_start", message: toolResultMessage });
|
|
9523
|
-
stream.push({ type: "message_end", message: toolResultMessage });
|
|
9524
|
-
return toolResultMessage;
|
|
9525
|
-
}
|
|
9526
|
-
|
|
9527
|
-
// ../../packages/agent-core/src/agent.ts
|
|
9528
|
-
function defaultConvertToLlm(messages) {
|
|
9529
|
-
return messages.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "toolResult");
|
|
9530
|
-
}
|
|
9531
|
-
function isAgentMessage(value) {
|
|
9532
|
-
return !!value && typeof value === "object" && "role" in value;
|
|
9533
|
-
}
|
|
9534
|
-
function isUserContentBlock(value) {
|
|
9535
|
-
if (!value || typeof value !== "object" || !("type" in value)) {
|
|
9536
|
-
return false;
|
|
9537
|
-
}
|
|
9538
|
-
const type = value.type;
|
|
9539
|
-
return type === "text" || type === "image" || type === "audio" || type === "video" || type === "fileRef";
|
|
9540
|
-
}
|
|
9541
|
-
var Agent = class {
|
|
9542
|
-
_state;
|
|
9543
|
-
listeners = /* @__PURE__ */ new Set();
|
|
9544
|
-
semanticListeners = /* @__PURE__ */ new Set();
|
|
9545
|
-
abortController;
|
|
9546
|
-
convertToLlm;
|
|
9547
|
-
transformContext;
|
|
9548
|
-
steeringQueue = [];
|
|
9549
|
-
followUpQueue = [];
|
|
9550
|
-
steeringMode;
|
|
9551
|
-
followUpMode;
|
|
9552
|
-
streamFn;
|
|
9553
|
-
_sessionId;
|
|
9554
|
-
_apiKey;
|
|
9555
|
-
getApiKey;
|
|
9556
|
-
runningPrompt;
|
|
9557
|
-
resolveRunningPrompt;
|
|
9558
|
-
_thinkingBudgets;
|
|
9559
|
-
_maxRetryDelayMs;
|
|
9560
|
-
hooks;
|
|
9561
|
-
statusSnapshot = {
|
|
9562
|
-
phase: "idle",
|
|
9563
|
-
turnState: "completed",
|
|
9564
|
-
hasPendingToolContinuation: false
|
|
9565
|
-
};
|
|
9566
|
-
constructor(opts = {}) {
|
|
9567
|
-
this._state = {
|
|
9568
|
-
systemPrompt: "",
|
|
9569
|
-
model: null,
|
|
9570
|
-
// Must be set before use
|
|
9571
|
-
thinkingLevel: "off",
|
|
9572
|
-
tools: [],
|
|
9573
|
-
messages: [],
|
|
9574
|
-
isStreaming: false,
|
|
9575
|
-
streamMessage: null,
|
|
9576
|
-
pendingToolCalls: /* @__PURE__ */ new Set(),
|
|
9577
|
-
error: void 0,
|
|
9578
|
-
...opts.initialState
|
|
9579
|
-
};
|
|
9580
|
-
this.convertToLlm = opts.convertToLlm || defaultConvertToLlm;
|
|
9581
|
-
this.transformContext = opts.transformContext;
|
|
9582
|
-
this.steeringMode = opts.steeringMode || "one-at-a-time";
|
|
9583
|
-
this.followUpMode = opts.followUpMode || "one-at-a-time";
|
|
9584
|
-
this.streamFn = opts.streamFn || streamSimple;
|
|
9585
|
-
this._sessionId = opts.sessionId;
|
|
9586
|
-
this._apiKey = opts.apiKey;
|
|
9587
|
-
this.getApiKey = opts.getApiKey;
|
|
9588
|
-
this._thinkingBudgets = opts.thinkingBudgets;
|
|
9589
|
-
this._maxRetryDelayMs = opts.maxRetryDelayMs;
|
|
9590
|
-
this.hooks = opts.initialState?.hooks;
|
|
9591
|
-
}
|
|
9592
|
-
get sessionId() {
|
|
9593
|
-
return this._sessionId;
|
|
9594
|
-
}
|
|
9595
|
-
set sessionId(value) {
|
|
9596
|
-
this._sessionId = value;
|
|
9597
|
-
}
|
|
9598
|
-
get apiKey() {
|
|
9599
|
-
return this._apiKey;
|
|
9600
|
-
}
|
|
9601
|
-
set apiKey(value) {
|
|
9602
|
-
this._apiKey = value;
|
|
9603
|
-
}
|
|
9604
|
-
get thinkingBudgets() {
|
|
9605
|
-
return this._thinkingBudgets;
|
|
9606
|
-
}
|
|
9607
|
-
set thinkingBudgets(value) {
|
|
9608
|
-
this._thinkingBudgets = value;
|
|
9609
|
-
}
|
|
9610
|
-
get maxRetryDelayMs() {
|
|
9611
|
-
return this._maxRetryDelayMs;
|
|
9612
|
-
}
|
|
9613
|
-
set maxRetryDelayMs(value) {
|
|
9614
|
-
this._maxRetryDelayMs = value;
|
|
9615
|
-
}
|
|
9616
|
-
get state() {
|
|
9617
|
-
return this._state;
|
|
9618
|
-
}
|
|
9619
|
-
subscribe(fn) {
|
|
9620
|
-
this.listeners.add(fn);
|
|
9621
|
-
return () => this.listeners.delete(fn);
|
|
9622
|
-
}
|
|
9623
|
-
subscribeSemantic(fn) {
|
|
9624
|
-
this.semanticListeners.add(fn);
|
|
9625
|
-
return () => this.semanticListeners.delete(fn);
|
|
9626
|
-
}
|
|
9627
|
-
getStatusSnapshot() {
|
|
9628
|
-
return { ...this.statusSnapshot };
|
|
9629
|
-
}
|
|
9630
|
-
setSystemPrompt(v) {
|
|
9631
|
-
this._state.systemPrompt = v;
|
|
9632
|
-
}
|
|
9633
|
-
setModel(m) {
|
|
9634
|
-
this._state.model = m;
|
|
9635
|
-
}
|
|
9636
|
-
setThinkingLevel(l) {
|
|
9637
|
-
this._state.thinkingLevel = l;
|
|
9638
|
-
}
|
|
9639
|
-
setTools(t) {
|
|
9640
|
-
this._state.tools = t;
|
|
9641
|
-
}
|
|
9642
|
-
setHooks(hooks) {
|
|
9643
|
-
this.hooks = hooks;
|
|
9644
|
-
}
|
|
9645
|
-
replaceMessages(ms) {
|
|
9646
|
-
this._state.messages = ms.slice();
|
|
9647
|
-
}
|
|
9648
|
-
appendMessage(m) {
|
|
9649
|
-
this._state.messages = [...this._state.messages, m];
|
|
9650
|
-
}
|
|
9651
|
-
clearMessages() {
|
|
9652
|
-
this._state.messages = [];
|
|
9653
|
-
}
|
|
9654
|
-
steer(m) {
|
|
9655
|
-
this.steeringQueue.push(m);
|
|
9656
|
-
}
|
|
9657
|
-
followUp(m) {
|
|
9658
|
-
this.followUpQueue.push(m);
|
|
9659
|
-
}
|
|
9660
|
-
clearSteeringQueue() {
|
|
9661
|
-
this.steeringQueue = [];
|
|
9662
|
-
}
|
|
9663
|
-
clearFollowUpQueue() {
|
|
9664
|
-
this.followUpQueue = [];
|
|
9665
|
-
}
|
|
9666
|
-
clearAllQueues() {
|
|
9667
|
-
this.steeringQueue = [];
|
|
9668
|
-
this.followUpQueue = [];
|
|
9669
|
-
}
|
|
9670
|
-
hasQueuedMessages() {
|
|
9671
|
-
return this.steeringQueue.length > 0 || this.followUpQueue.length > 0;
|
|
9672
|
-
}
|
|
9673
|
-
setSteeringMode(mode) {
|
|
9674
|
-
this.steeringMode = mode;
|
|
9675
|
-
}
|
|
9676
|
-
getSteeringMode() {
|
|
9677
|
-
return this.steeringMode;
|
|
9678
|
-
}
|
|
9679
|
-
setFollowUpMode(mode) {
|
|
9680
|
-
this.followUpMode = mode;
|
|
9681
|
-
}
|
|
9682
|
-
getFollowUpMode() {
|
|
9683
|
-
return this.followUpMode;
|
|
9684
|
-
}
|
|
9685
|
-
dequeueSteeringMessages() {
|
|
9686
|
-
if (this.steeringMode === "one-at-a-time") {
|
|
9687
|
-
if (this.steeringQueue.length > 0) {
|
|
9688
|
-
const first = this.steeringQueue[0];
|
|
9689
|
-
this.steeringQueue = this.steeringQueue.slice(1);
|
|
9690
|
-
return [first];
|
|
9691
|
-
}
|
|
9692
|
-
return [];
|
|
9693
|
-
}
|
|
9694
|
-
const steering = this.steeringQueue.slice();
|
|
9695
|
-
this.steeringQueue = [];
|
|
9696
|
-
return steering;
|
|
9697
|
-
}
|
|
9698
|
-
dequeueFollowUpMessages() {
|
|
9699
|
-
if (this.followUpMode === "one-at-a-time") {
|
|
9700
|
-
if (this.followUpQueue.length > 0) {
|
|
9701
|
-
const first = this.followUpQueue[0];
|
|
9702
|
-
this.followUpQueue = this.followUpQueue.slice(1);
|
|
9703
|
-
return [first];
|
|
9704
|
-
}
|
|
9705
|
-
return [];
|
|
9706
|
-
}
|
|
9707
|
-
const followUp = this.followUpQueue.slice();
|
|
9708
|
-
this.followUpQueue = [];
|
|
9709
|
-
return followUp;
|
|
9710
|
-
}
|
|
9711
|
-
abort() {
|
|
9712
|
-
this.abortController?.abort();
|
|
9713
|
-
}
|
|
9714
|
-
waitForIdle() {
|
|
9715
|
-
return this.runningPrompt ?? Promise.resolve();
|
|
9716
|
-
}
|
|
9717
|
-
reset() {
|
|
9718
|
-
this._state.messages = [];
|
|
9719
|
-
this._state.isStreaming = false;
|
|
9720
|
-
this._state.streamMessage = null;
|
|
9721
|
-
this._state.pendingToolCalls = /* @__PURE__ */ new Set();
|
|
9722
|
-
this._state.error = void 0;
|
|
9723
|
-
this.steeringQueue = [];
|
|
9724
|
-
this.followUpQueue = [];
|
|
9725
|
-
this.runningPrompt = void 0;
|
|
9726
|
-
this.resolveRunningPrompt = void 0;
|
|
9727
|
-
this.updateStatusSnapshot({
|
|
9728
|
-
phase: "idle",
|
|
9729
|
-
turnState: "completed",
|
|
9730
|
-
activeToolName: void 0,
|
|
9731
|
-
lastStopReason: void 0,
|
|
9732
|
-
hasPendingToolContinuation: false
|
|
9733
|
-
});
|
|
9734
|
-
}
|
|
9735
|
-
/**
|
|
9736
|
-
* Reset only the processing state without clearing messages.
|
|
9737
|
-
* Useful when resuming a session that was saved mid-processing.
|
|
9738
|
-
*/
|
|
9739
|
-
resetProcessingState() {
|
|
9740
|
-
this._state.isStreaming = false;
|
|
9741
|
-
this._state.streamMessage = null;
|
|
9742
|
-
this._state.pendingToolCalls = /* @__PURE__ */ new Set();
|
|
9743
|
-
this._state.error = void 0;
|
|
9744
|
-
this.steeringQueue = [];
|
|
9745
|
-
this.followUpQueue = [];
|
|
9746
|
-
this.runningPrompt = void 0;
|
|
9747
|
-
this.resolveRunningPrompt = void 0;
|
|
9748
|
-
this.abortController = void 0;
|
|
9749
|
-
this.updateStatusSnapshot({
|
|
9750
|
-
phase: "idle",
|
|
9751
|
-
turnState: "completed",
|
|
9752
|
-
activeToolName: void 0,
|
|
9753
|
-
lastStopReason: void 0,
|
|
9754
|
-
hasPendingToolContinuation: false
|
|
9755
|
-
});
|
|
9756
|
-
}
|
|
9757
|
-
async prompt(input, images) {
|
|
9758
|
-
if (this.runningPrompt) {
|
|
9759
|
-
throw new Error("Agent is already processing a prompt.");
|
|
9760
|
-
}
|
|
9761
|
-
if (this._state.isStreaming) {
|
|
9762
|
-
throw new Error("Agent is already processing a prompt.");
|
|
9763
|
-
}
|
|
9764
|
-
const promise = new Promise((resolve) => {
|
|
9765
|
-
this.resolveRunningPrompt = resolve;
|
|
9766
|
-
});
|
|
9767
|
-
this.runningPrompt = promise;
|
|
9768
|
-
try {
|
|
9769
|
-
const model = this._state.model;
|
|
9770
|
-
if (!model) throw new Error("No model configured");
|
|
9771
|
-
let msgs;
|
|
9772
|
-
if (Array.isArray(input)) {
|
|
9773
|
-
if (input.length > 0 && input.every((item) => isUserContentBlock(item))) {
|
|
9774
|
-
msgs = [{ role: "user", content: input, timestamp: Date.now() }];
|
|
9775
|
-
} else if (input.every((item) => isAgentMessage(item))) {
|
|
9776
|
-
msgs = input;
|
|
9777
|
-
} else {
|
|
9778
|
-
throw new Error("Invalid prompt array: expected user content blocks or agent messages.");
|
|
9779
|
-
}
|
|
9780
|
-
} else if (typeof input === "string") {
|
|
9781
|
-
const content = [{ type: "text", text: input }];
|
|
9782
|
-
if (images && images.length > 0) {
|
|
9783
|
-
content.push(...images);
|
|
9784
|
-
}
|
|
9785
|
-
msgs = [{ role: "user", content, timestamp: Date.now() }];
|
|
9786
|
-
} else {
|
|
9787
|
-
msgs = [input];
|
|
9788
|
-
}
|
|
9789
|
-
await this._runLoop(msgs);
|
|
9790
|
-
} finally {
|
|
9791
|
-
if (this.runningPrompt === promise) {
|
|
9792
|
-
this.resolveRunningPrompt?.();
|
|
9793
|
-
this.runningPrompt = void 0;
|
|
9794
|
-
this.resolveRunningPrompt = void 0;
|
|
9795
|
-
}
|
|
9796
|
-
}
|
|
9797
|
-
}
|
|
9798
|
-
async continue() {
|
|
9799
|
-
if (this.runningPrompt) {
|
|
9800
|
-
throw new Error("Agent is already processing.");
|
|
9801
|
-
}
|
|
9802
|
-
if (this._state.isStreaming) {
|
|
9803
|
-
throw new Error("Agent is already processing.");
|
|
9804
|
-
}
|
|
9805
|
-
const promise = new Promise((resolve) => {
|
|
9806
|
-
this.resolveRunningPrompt = resolve;
|
|
9807
|
-
});
|
|
9808
|
-
this.runningPrompt = promise;
|
|
9809
|
-
try {
|
|
9810
|
-
const messages = this._state.messages;
|
|
9811
|
-
if (messages.length === 0) {
|
|
9812
|
-
throw new Error("No messages to continue from");
|
|
9813
|
-
}
|
|
9814
|
-
if (messages[messages.length - 1].role === "assistant") {
|
|
9815
|
-
const queuedSteering = this.dequeueSteeringMessages();
|
|
9816
|
-
if (queuedSteering.length > 0) {
|
|
9817
|
-
await this._runLoop(queuedSteering, {
|
|
9818
|
-
skipInitialSteeringPoll: true,
|
|
9819
|
-
suppressSteeringPolls: true,
|
|
9820
|
-
suppressFollowUpPolls: true
|
|
9821
|
-
});
|
|
9822
|
-
return;
|
|
9823
|
-
}
|
|
9824
|
-
const queuedFollowUp = this.dequeueFollowUpMessages();
|
|
9825
|
-
if (queuedFollowUp.length > 0) {
|
|
9826
|
-
await this._runLoop(queuedFollowUp, {
|
|
9827
|
-
suppressSteeringPolls: true,
|
|
9828
|
-
suppressFollowUpPolls: true
|
|
9829
|
-
});
|
|
9830
|
-
return;
|
|
9831
|
-
}
|
|
9832
|
-
throw new Error("Cannot continue from message role: assistant");
|
|
9833
|
-
}
|
|
9834
|
-
await this._runLoop(void 0);
|
|
9835
|
-
} finally {
|
|
9836
|
-
if (this.runningPrompt === promise) {
|
|
9837
|
-
this.resolveRunningPrompt?.();
|
|
9838
|
-
this.runningPrompt = void 0;
|
|
9839
|
-
this.resolveRunningPrompt = void 0;
|
|
9840
|
-
}
|
|
9841
|
-
}
|
|
9842
|
-
}
|
|
9843
|
-
async _runLoop(messages, options) {
|
|
9844
|
-
const model = this._state.model;
|
|
9845
|
-
if (!model) throw new Error("No model configured");
|
|
9846
|
-
this.abortController = new AbortController();
|
|
9847
|
-
this._state.isStreaming = true;
|
|
9848
|
-
this._state.streamMessage = null;
|
|
9849
|
-
this._state.error = void 0;
|
|
9850
|
-
const reasoning = this._state.thinkingLevel === "off" ? void 0 : this._state.thinkingLevel;
|
|
9851
|
-
const context = {
|
|
9852
|
-
systemPrompt: this._state.systemPrompt,
|
|
9853
|
-
messages: this._state.messages.slice(),
|
|
9854
|
-
tools: this._state.tools
|
|
9855
|
-
};
|
|
9856
|
-
let skipInitialSteeringPoll = options?.skipInitialSteeringPoll === true;
|
|
9857
|
-
const config = {
|
|
9858
|
-
model,
|
|
9859
|
-
reasoning,
|
|
9860
|
-
apiKey: this._apiKey,
|
|
9861
|
-
sessionId: this._sessionId,
|
|
9862
|
-
thinkingBudgets: this._thinkingBudgets,
|
|
9863
|
-
maxRetryDelayMs: this._maxRetryDelayMs,
|
|
9864
|
-
convertToLlm: this.convertToLlm,
|
|
9865
|
-
transformContext: this.transformContext,
|
|
9866
|
-
getApiKey: this.getApiKey,
|
|
9867
|
-
hooks: this.hooks,
|
|
9868
|
-
getSteeringMessages: async () => {
|
|
9869
|
-
if (options?.suppressSteeringPolls) {
|
|
9870
|
-
return [];
|
|
9871
|
-
}
|
|
9872
|
-
if (skipInitialSteeringPoll) {
|
|
9873
|
-
skipInitialSteeringPoll = false;
|
|
9874
|
-
return [];
|
|
9875
|
-
}
|
|
9876
|
-
return this.dequeueSteeringMessages();
|
|
9877
|
-
},
|
|
9878
|
-
getFollowUpMessages: async () => {
|
|
9879
|
-
if (options?.suppressFollowUpPolls) {
|
|
9880
|
-
return [];
|
|
9881
|
-
}
|
|
9882
|
-
return this.dequeueFollowUpMessages();
|
|
9883
|
-
}
|
|
9884
|
-
};
|
|
9885
|
-
let partial = null;
|
|
9886
|
-
try {
|
|
9887
|
-
const stream = messages ? agentLoop(messages, context, config, this.abortController.signal, this.streamFn) : agentLoopContinue(context, config, this.abortController.signal, this.streamFn);
|
|
9888
|
-
for await (const event of stream) {
|
|
9889
|
-
switch (event.type) {
|
|
9890
|
-
case "message_start":
|
|
9891
|
-
partial = event.message;
|
|
9892
|
-
this._state.streamMessage = event.message;
|
|
9893
|
-
break;
|
|
9894
|
-
case "message_update":
|
|
9895
|
-
partial = event.message;
|
|
9896
|
-
this._state.streamMessage = event.message;
|
|
9897
|
-
break;
|
|
9898
|
-
case "message_end":
|
|
9899
|
-
partial = null;
|
|
9900
|
-
this._state.streamMessage = null;
|
|
9901
|
-
this.appendMessage(event.message);
|
|
9902
|
-
break;
|
|
9903
|
-
case "tool_execution_start": {
|
|
9904
|
-
const s = new Set(this._state.pendingToolCalls);
|
|
9905
|
-
s.add(event.toolCallId);
|
|
9906
|
-
this._state.pendingToolCalls = s;
|
|
9907
|
-
break;
|
|
9908
|
-
}
|
|
9909
|
-
case "tool_execution_end": {
|
|
9910
|
-
const s = new Set(this._state.pendingToolCalls);
|
|
9911
|
-
s.delete(event.toolCallId);
|
|
9912
|
-
this._state.pendingToolCalls = s;
|
|
9913
|
-
break;
|
|
9914
|
-
}
|
|
9915
|
-
case "turn_end":
|
|
9916
|
-
if (event.message.role === "assistant" && event.message.errorMessage) {
|
|
9917
|
-
this._state.error = event.message.errorMessage;
|
|
9918
|
-
}
|
|
9919
|
-
break;
|
|
9920
|
-
case "agent_end":
|
|
9921
|
-
this._state.isStreaming = false;
|
|
9922
|
-
this._state.streamMessage = null;
|
|
9923
|
-
break;
|
|
9924
|
-
}
|
|
9925
|
-
this.emit(event);
|
|
9926
|
-
}
|
|
9927
|
-
if (partial && partial.role === "assistant" && partial.content?.length > 0) {
|
|
9928
|
-
const onlyEmpty = !partial.content.some(
|
|
9929
|
-
(c) => c.type === "thinking" && c.thinking?.trim().length > 0 || c.type === "text" && c.text?.trim().length > 0 || c.type === "toolCall" && c.name?.trim().length > 0
|
|
9930
|
-
);
|
|
9931
|
-
if (!onlyEmpty) {
|
|
9932
|
-
this.appendMessage(partial);
|
|
9933
|
-
}
|
|
9934
|
-
}
|
|
9935
|
-
} catch (err) {
|
|
9936
|
-
const errorMsg = {
|
|
9937
|
-
role: "assistant",
|
|
9938
|
-
content: [{ type: "text", text: "" }],
|
|
9939
|
-
api: model.api,
|
|
9940
|
-
provider: model.provider,
|
|
9941
|
-
model: model.id,
|
|
9942
|
-
usage: {
|
|
9943
|
-
input: 0,
|
|
9944
|
-
output: 0,
|
|
9945
|
-
cacheRead: 0,
|
|
9946
|
-
cacheWrite: 0,
|
|
9947
|
-
totalTokens: 0,
|
|
9948
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
9949
|
-
},
|
|
9950
|
-
stopReason: this.abortController?.signal.aborted ? "aborted" : "error",
|
|
9951
|
-
errorMessage: err?.message || String(err),
|
|
9952
|
-
timestamp: Date.now()
|
|
9953
|
-
};
|
|
9954
|
-
this.appendMessage(errorMsg);
|
|
9955
|
-
this._state.error = err?.message || String(err);
|
|
9956
|
-
this.emit({ type: "agent_end", messages: [errorMsg] });
|
|
9957
|
-
} finally {
|
|
9958
|
-
this._state.isStreaming = false;
|
|
9959
|
-
this._state.streamMessage = null;
|
|
9960
|
-
this._state.pendingToolCalls = /* @__PURE__ */ new Set();
|
|
9961
|
-
this.abortController = void 0;
|
|
9962
|
-
}
|
|
9963
|
-
}
|
|
9964
|
-
reportObserverError(kind, eventType, error) {
|
|
9965
|
-
console.warn(`[Agent] ${kind} failed while handling ${eventType}:`, error);
|
|
9966
|
-
}
|
|
9967
|
-
emit(e) {
|
|
9968
|
-
for (const listener of this.listeners) {
|
|
9969
|
-
try {
|
|
9970
|
-
listener(e);
|
|
9971
|
-
} catch (error) {
|
|
9972
|
-
this.reportObserverError("agent event listener", e.type, error);
|
|
9973
|
-
}
|
|
9974
|
-
}
|
|
9975
|
-
try {
|
|
9976
|
-
this.emitDerivedSemanticEvents(e);
|
|
9977
|
-
} catch (error) {
|
|
9978
|
-
this.reportObserverError("derived semantic event", e.type, error);
|
|
9979
|
-
}
|
|
9980
|
-
}
|
|
9981
|
-
emitSemantic(e) {
|
|
9982
|
-
for (const listener of this.semanticListeners) {
|
|
9983
|
-
try {
|
|
9984
|
-
listener(e);
|
|
9985
|
-
} catch (error) {
|
|
9986
|
-
this.reportObserverError("semantic event listener", e.type, error);
|
|
9987
|
-
}
|
|
9988
|
-
}
|
|
9989
|
-
}
|
|
9990
|
-
updateStatusSnapshot(next) {
|
|
9991
|
-
const snapshot = {
|
|
9992
|
-
...this.statusSnapshot,
|
|
9993
|
-
...next
|
|
9994
|
-
};
|
|
9995
|
-
if (snapshot.phase === this.statusSnapshot.phase && snapshot.turnState === this.statusSnapshot.turnState && snapshot.activeToolName === this.statusSnapshot.activeToolName && snapshot.lastStopReason === this.statusSnapshot.lastStopReason && snapshot.hasPendingToolContinuation === this.statusSnapshot.hasPendingToolContinuation) {
|
|
9996
|
-
return;
|
|
9997
|
-
}
|
|
9998
|
-
this.statusSnapshot = snapshot;
|
|
9999
|
-
this.emitSemantic({ type: "status_snapshot_changed", snapshot: { ...snapshot } });
|
|
10000
|
-
}
|
|
10001
|
-
emitDerivedSemanticEvents(event) {
|
|
10002
|
-
switch (event.type) {
|
|
10003
|
-
case "message_start":
|
|
10004
|
-
if (event.message.role === "assistant") {
|
|
10005
|
-
this.updateStatusSnapshot({
|
|
10006
|
-
phase: "responding",
|
|
10007
|
-
turnState: "continuing",
|
|
10008
|
-
activeToolName: void 0,
|
|
10009
|
-
lastStopReason: void 0,
|
|
10010
|
-
hasPendingToolContinuation: false
|
|
10011
|
-
});
|
|
10012
|
-
this.emitSemantic({ type: "assistant_response_started", message: event.message });
|
|
10013
|
-
}
|
|
10014
|
-
break;
|
|
10015
|
-
case "message_update":
|
|
10016
|
-
if (event.message.role === "assistant" && event.assistantMessageEvent.type === "text_delta") {
|
|
10017
|
-
this.updateStatusSnapshot({ phase: "responding" });
|
|
10018
|
-
this.emitSemantic({
|
|
10019
|
-
type: "assistant_response_delta",
|
|
10020
|
-
message: event.message,
|
|
10021
|
-
delta: event.assistantMessageEvent.delta
|
|
10022
|
-
});
|
|
10023
|
-
}
|
|
10024
|
-
break;
|
|
10025
|
-
case "message_end":
|
|
10026
|
-
if (event.message.role === "assistant") {
|
|
10027
|
-
this.emitSemantic({ type: "assistant_response_finished", message: event.message });
|
|
10028
|
-
}
|
|
10029
|
-
break;
|
|
10030
|
-
case "tool_execution_start":
|
|
10031
|
-
this.updateStatusSnapshot({
|
|
10032
|
-
phase: "running_tool",
|
|
10033
|
-
turnState: "continuing",
|
|
10034
|
-
activeToolName: event.toolName,
|
|
10035
|
-
lastStopReason: void 0,
|
|
10036
|
-
hasPendingToolContinuation: false
|
|
10037
|
-
});
|
|
10038
|
-
this.emitSemantic({
|
|
10039
|
-
type: "tool_started",
|
|
10040
|
-
toolCallId: event.toolCallId,
|
|
10041
|
-
toolName: event.toolName,
|
|
10042
|
-
args: event.args
|
|
10043
|
-
});
|
|
10044
|
-
break;
|
|
10045
|
-
case "tool_execution_update":
|
|
10046
|
-
this.emitSemantic({
|
|
10047
|
-
type: "tool_progressed",
|
|
10048
|
-
toolCallId: event.toolCallId,
|
|
10049
|
-
toolName: event.toolName,
|
|
10050
|
-
args: event.args,
|
|
10051
|
-
partialResult: event.partialResult
|
|
10052
|
-
});
|
|
10053
|
-
break;
|
|
10054
|
-
case "tool_execution_end":
|
|
10055
|
-
this.updateStatusSnapshot({
|
|
10056
|
-
phase: this._state.isStreaming ? "responding" : "completed",
|
|
10057
|
-
activeToolName: void 0
|
|
10058
|
-
});
|
|
10059
|
-
this.emitSemantic({
|
|
10060
|
-
type: "tool_finished",
|
|
10061
|
-
toolCallId: event.toolCallId,
|
|
10062
|
-
toolName: event.toolName,
|
|
10063
|
-
args: event.args,
|
|
10064
|
-
result: event.result,
|
|
10065
|
-
isError: event.isError
|
|
10066
|
-
});
|
|
10067
|
-
break;
|
|
10068
|
-
case "turn_end": {
|
|
10069
|
-
const stopReason = event.message.role === "assistant" ? event.message.stopReason : void 0;
|
|
10070
|
-
const hasToolCalls = event.message.role === "assistant" && Array.isArray(event.message.content) && event.message.content.some((block) => block.type === "toolCall");
|
|
10071
|
-
if (stopReason === "error" || stopReason === "aborted") {
|
|
10072
|
-
this.updateStatusSnapshot({
|
|
10073
|
-
phase: "failed",
|
|
10074
|
-
turnState: "failed",
|
|
10075
|
-
lastStopReason: stopReason,
|
|
10076
|
-
hasPendingToolContinuation: false,
|
|
10077
|
-
activeToolName: void 0
|
|
10078
|
-
});
|
|
10079
|
-
this.emitSemantic({
|
|
10080
|
-
type: "turn_failed",
|
|
10081
|
-
message: event.message,
|
|
10082
|
-
toolResults: event.toolResults
|
|
10083
|
-
});
|
|
10084
|
-
} else if (hasToolCalls || stopReason === "toolUse") {
|
|
10085
|
-
this.updateStatusSnapshot({
|
|
10086
|
-
phase: "responding",
|
|
10087
|
-
turnState: "continuing",
|
|
10088
|
-
lastStopReason: stopReason,
|
|
10089
|
-
hasPendingToolContinuation: true,
|
|
10090
|
-
activeToolName: void 0
|
|
10091
|
-
});
|
|
10092
|
-
this.emitSemantic({
|
|
10093
|
-
type: "turn_continues",
|
|
10094
|
-
message: event.message,
|
|
10095
|
-
toolResults: event.toolResults
|
|
10096
|
-
});
|
|
10097
|
-
} else {
|
|
10098
|
-
this.updateStatusSnapshot({
|
|
10099
|
-
phase: "completed",
|
|
10100
|
-
turnState: "completed",
|
|
10101
|
-
lastStopReason: stopReason,
|
|
10102
|
-
hasPendingToolContinuation: false,
|
|
10103
|
-
activeToolName: void 0
|
|
10104
|
-
});
|
|
10105
|
-
this.emitSemantic({
|
|
10106
|
-
type: "turn_completed",
|
|
10107
|
-
message: event.message,
|
|
10108
|
-
toolResults: event.toolResults
|
|
10109
|
-
});
|
|
10110
|
-
}
|
|
10111
|
-
break;
|
|
10112
|
-
}
|
|
10113
|
-
case "agent_end": {
|
|
10114
|
-
const lastMessage = event.messages[event.messages.length - 1];
|
|
10115
|
-
if (lastMessage?.role === "assistant" && (lastMessage.stopReason === "error" || lastMessage.stopReason === "aborted")) {
|
|
10116
|
-
this.updateStatusSnapshot({
|
|
10117
|
-
phase: "failed",
|
|
10118
|
-
turnState: "failed",
|
|
10119
|
-
lastStopReason: lastMessage.stopReason,
|
|
10120
|
-
hasPendingToolContinuation: false,
|
|
10121
|
-
activeToolName: void 0
|
|
10122
|
-
});
|
|
10123
|
-
this.emitSemantic({
|
|
10124
|
-
type: "turn_failed",
|
|
10125
|
-
message: lastMessage,
|
|
10126
|
-
toolResults: []
|
|
10127
|
-
});
|
|
10128
|
-
}
|
|
10129
|
-
this.updateStatusSnapshot({
|
|
10130
|
-
phase: "idle",
|
|
10131
|
-
activeToolName: void 0,
|
|
10132
|
-
hasPendingToolContinuation: false
|
|
10133
|
-
});
|
|
10134
|
-
break;
|
|
10135
|
-
}
|
|
10136
|
-
}
|
|
10137
|
-
}
|
|
10138
|
-
};
|
|
10139
|
-
|
|
10140
9123
|
export {
|
|
10141
9124
|
detectPlatform,
|
|
10142
9125
|
createLogger,
|
|
@@ -10160,6 +9143,7 @@ export {
|
|
|
10160
9143
|
KeyOfPattern,
|
|
10161
9144
|
ExtendsUndefinedCheck,
|
|
10162
9145
|
Type,
|
|
9146
|
+
EventStream,
|
|
10163
9147
|
getModelCacheCapability,
|
|
10164
9148
|
streamSimple,
|
|
10165
9149
|
completeSimple,
|
|
@@ -10175,7 +9159,5 @@ export {
|
|
|
10175
9159
|
TransformEncodeCheckError,
|
|
10176
9160
|
TransformEncode,
|
|
10177
9161
|
HasTransform,
|
|
10178
|
-
|
|
10179
|
-
agentLoopContinue,
|
|
10180
|
-
Agent
|
|
9162
|
+
validateToolArguments
|
|
10181
9163
|
};
|