@cydm/pie 1.0.13 → 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.
@@ -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
- agentLoop,
10179
- agentLoopContinue,
10180
- Agent
9162
+ validateToolArguments
10181
9163
  };