@ai-sdk/workflow 1.0.0-beta.2 → 1.0.0-beta.21
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/CHANGELOG.md +139 -0
- package/dist/index.d.mts +128 -38
- package/dist/index.mjs +98 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/do-stream-step.ts +10 -25
- package/src/index.ts +5 -4
- package/src/providers/mock.ts +79 -92
- package/src/stream-text-iterator.ts +22 -47
- package/src/telemetry.ts +5 -5
- package/src/workflow-agent.ts +430 -317
package/src/workflow-agent.ts
CHANGED
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
type ToolChoice,
|
|
22
22
|
type ToolSet,
|
|
23
23
|
type UIMessage,
|
|
24
|
+
LanguageModel,
|
|
25
|
+
experimental_filterActiveTools as filterActiveTools,
|
|
24
26
|
} from 'ai';
|
|
25
27
|
import {
|
|
26
28
|
convertToLanguageModelPrompt,
|
|
@@ -34,6 +36,15 @@ import type { CompatibleLanguageModel } from './types.js';
|
|
|
34
36
|
// Re-export for consumers
|
|
35
37
|
export type { CompatibleLanguageModel } from './types.js';
|
|
36
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Callback function to be called after each step completes.
|
|
41
|
+
* Alias for the AI SDK's StreamTextOnStepFinishCallback, using
|
|
42
|
+
* WorkflowAgent-consistent naming.
|
|
43
|
+
*/
|
|
44
|
+
export type WorkflowAgentOnStepFinishCallback<
|
|
45
|
+
TTools extends ToolSet = ToolSet,
|
|
46
|
+
> = StreamTextOnStepFinishCallback<TTools, any>;
|
|
47
|
+
|
|
37
48
|
/**
|
|
38
49
|
* Infer the type of the tools of a workflow agent.
|
|
39
50
|
*/
|
|
@@ -82,7 +93,7 @@ export type ProviderOptions = SharedV4ProviderOptions;
|
|
|
82
93
|
/**
|
|
83
94
|
* Telemetry settings for observability.
|
|
84
95
|
*/
|
|
85
|
-
export interface
|
|
96
|
+
export interface TelemetryOptions {
|
|
86
97
|
/**
|
|
87
98
|
* Enable or disable telemetry. Defaults to true.
|
|
88
99
|
*/
|
|
@@ -248,10 +259,7 @@ export interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {
|
|
|
248
259
|
* The current model configuration (string or function).
|
|
249
260
|
* The function should return a LanguageModelV4 instance.
|
|
250
261
|
*/
|
|
251
|
-
model:
|
|
252
|
-
| string
|
|
253
|
-
| CompatibleLanguageModel
|
|
254
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
262
|
+
model: LanguageModel;
|
|
255
263
|
|
|
256
264
|
/**
|
|
257
265
|
* The current step number (0-indexed).
|
|
@@ -282,12 +290,8 @@ export interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {
|
|
|
282
290
|
export interface PrepareStepResult extends Partial<GenerationSettings> {
|
|
283
291
|
/**
|
|
284
292
|
* Override the model for this step.
|
|
285
|
-
* The function should return a LanguageModelV4 instance.
|
|
286
293
|
*/
|
|
287
|
-
model?:
|
|
288
|
-
| string
|
|
289
|
-
| CompatibleLanguageModel
|
|
290
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
294
|
+
model?: LanguageModel;
|
|
291
295
|
|
|
292
296
|
/**
|
|
293
297
|
* Override the system message for this step.
|
|
@@ -332,14 +336,11 @@ export type PrepareStepCallback<TTools extends ToolSet = ToolSet> = (
|
|
|
332
336
|
export interface PrepareCallOptions<
|
|
333
337
|
TTools extends ToolSet = ToolSet,
|
|
334
338
|
> extends Partial<GenerationSettings> {
|
|
335
|
-
model:
|
|
336
|
-
| string
|
|
337
|
-
| CompatibleLanguageModel
|
|
338
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
339
|
+
model: LanguageModel;
|
|
339
340
|
tools: TTools;
|
|
340
341
|
instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
|
|
341
342
|
toolChoice?: ToolChoice<TTools>;
|
|
342
|
-
experimental_telemetry?:
|
|
343
|
+
experimental_telemetry?: TelemetryOptions;
|
|
343
344
|
experimental_context?: unknown;
|
|
344
345
|
messages: ModelMessage[];
|
|
345
346
|
}
|
|
@@ -367,16 +368,18 @@ export type PrepareCallCallback<TTools extends ToolSet = ToolSet> = (
|
|
|
367
368
|
export interface WorkflowAgentOptions<
|
|
368
369
|
TTools extends ToolSet = ToolSet,
|
|
369
370
|
> extends GenerationSettings {
|
|
371
|
+
/**
|
|
372
|
+
* The id of the agent.
|
|
373
|
+
*/
|
|
374
|
+
id?: string;
|
|
375
|
+
|
|
370
376
|
/**
|
|
371
377
|
* The model provider to use for the agent.
|
|
372
378
|
*
|
|
373
379
|
* This should be a string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-opus'),
|
|
374
|
-
* or a
|
|
380
|
+
* or a LanguageModelV4 instance from a provider.
|
|
375
381
|
*/
|
|
376
|
-
model:
|
|
377
|
-
| string
|
|
378
|
-
| CompatibleLanguageModel
|
|
379
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
382
|
+
model: LanguageModel;
|
|
380
383
|
|
|
381
384
|
/**
|
|
382
385
|
* A set of tools available to the agent.
|
|
@@ -405,7 +408,7 @@ export interface WorkflowAgentOptions<
|
|
|
405
408
|
/**
|
|
406
409
|
* Optional telemetry configuration (experimental).
|
|
407
410
|
*/
|
|
408
|
-
experimental_telemetry?:
|
|
411
|
+
experimental_telemetry?: TelemetryOptions;
|
|
409
412
|
|
|
410
413
|
/**
|
|
411
414
|
* Default context that is passed into tool execution for every stream call on this agent.
|
|
@@ -416,6 +419,46 @@ export interface WorkflowAgentOptions<
|
|
|
416
419
|
*/
|
|
417
420
|
experimental_context?: unknown;
|
|
418
421
|
|
|
422
|
+
/**
|
|
423
|
+
* Default stop condition for the agent loop. When the condition is an array,
|
|
424
|
+
* any of the conditions can be met to stop the generation.
|
|
425
|
+
*
|
|
426
|
+
* Per-stream `stopWhen` values passed to `stream()` override this default.
|
|
427
|
+
*/
|
|
428
|
+
stopWhen?:
|
|
429
|
+
| StopCondition<NoInfer<ToolSet>, any>
|
|
430
|
+
| Array<StopCondition<NoInfer<ToolSet>, any>>;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Default set of active tools that limits which tools the model can call,
|
|
434
|
+
* without changing the tool call and result types in the result.
|
|
435
|
+
*
|
|
436
|
+
* Per-stream `activeTools` values passed to `stream()` override this default.
|
|
437
|
+
*/
|
|
438
|
+
activeTools?: Array<keyof NoInfer<TTools>>;
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Default output specification for structured outputs.
|
|
442
|
+
* Use `Output.object({ schema })` for structured output or `Output.text()` for text output.
|
|
443
|
+
*
|
|
444
|
+
* Per-stream `output` values passed to `stream()` override this default.
|
|
445
|
+
*/
|
|
446
|
+
output?: OutputSpecification<any, any>;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Default function that attempts to repair a tool call that failed to parse.
|
|
450
|
+
*
|
|
451
|
+
* Per-stream `experimental_repairToolCall` values passed to `stream()` override this default.
|
|
452
|
+
*/
|
|
453
|
+
experimental_repairToolCall?: ToolCallRepairFunction<TTools>;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Default custom download function to use for URLs.
|
|
457
|
+
*
|
|
458
|
+
* Per-stream `experimental_download` values passed to `stream()` override this default.
|
|
459
|
+
*/
|
|
460
|
+
experimental_download?: DownloadFunction;
|
|
461
|
+
|
|
419
462
|
/**
|
|
420
463
|
* Default callback function called before each step in the agent loop.
|
|
421
464
|
* Use this to modify settings, manage context, or inject messages dynamically
|
|
@@ -428,12 +471,12 @@ export interface WorkflowAgentOptions<
|
|
|
428
471
|
/**
|
|
429
472
|
* Callback function to be called after each step completes.
|
|
430
473
|
*/
|
|
431
|
-
onStepFinish?:
|
|
474
|
+
onStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;
|
|
432
475
|
|
|
433
476
|
/**
|
|
434
477
|
* Callback that is called when the LLM response and all request tool executions are finished.
|
|
435
478
|
*/
|
|
436
|
-
onFinish?:
|
|
479
|
+
onFinish?: WorkflowAgentOnFinishCallback<ToolSet>;
|
|
437
480
|
|
|
438
481
|
/**
|
|
439
482
|
* Callback called when the agent starts streaming, before any LLM calls.
|
|
@@ -466,7 +509,7 @@ export interface WorkflowAgentOptions<
|
|
|
466
509
|
/**
|
|
467
510
|
* Callback that is called when the LLM response and all request tool executions are finished.
|
|
468
511
|
*/
|
|
469
|
-
export type
|
|
512
|
+
export type WorkflowAgentOnFinishCallback<
|
|
470
513
|
TTools extends ToolSet = ToolSet,
|
|
471
514
|
OUTPUT = never,
|
|
472
515
|
> = (event: {
|
|
@@ -510,14 +553,14 @@ export type StreamTextOnFinishCallback<
|
|
|
510
553
|
/**
|
|
511
554
|
* Callback that is invoked when an error occurs during streaming.
|
|
512
555
|
*/
|
|
513
|
-
export type
|
|
556
|
+
export type WorkflowAgentOnErrorCallback = (event: {
|
|
514
557
|
error: unknown;
|
|
515
558
|
}) => PromiseLike<void> | void;
|
|
516
559
|
|
|
517
560
|
/**
|
|
518
561
|
* Callback that is set using the `onAbort` option.
|
|
519
562
|
*/
|
|
520
|
-
export type
|
|
563
|
+
export type WorkflowAgentOnAbortCallback<TTools extends ToolSet = ToolSet> =
|
|
521
564
|
(event: {
|
|
522
565
|
/**
|
|
523
566
|
* Details for all previously finished steps.
|
|
@@ -530,10 +573,7 @@ export type StreamTextOnAbortCallback<TTools extends ToolSet = ToolSet> =
|
|
|
530
573
|
*/
|
|
531
574
|
export type WorkflowAgentOnStartCallback = (event: {
|
|
532
575
|
/** The model being used */
|
|
533
|
-
readonly model:
|
|
534
|
-
| string
|
|
535
|
-
| CompatibleLanguageModel
|
|
536
|
-
| (() => Promise<CompatibleLanguageModel>);
|
|
576
|
+
readonly model: LanguageModel;
|
|
537
577
|
/** The messages being sent */
|
|
538
578
|
readonly messages: ModelMessage[];
|
|
539
579
|
}) => PromiseLike<void> | void;
|
|
@@ -541,17 +581,17 @@ export type WorkflowAgentOnStartCallback = (event: {
|
|
|
541
581
|
/**
|
|
542
582
|
* Callback that is called before each step (LLM call) begins.
|
|
543
583
|
*/
|
|
544
|
-
export type WorkflowAgentOnStepStartCallback =
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}) => PromiseLike<void> | void;
|
|
584
|
+
export type WorkflowAgentOnStepStartCallback<TTools extends ToolSet = ToolSet> =
|
|
585
|
+
(event: {
|
|
586
|
+
/** The current step number (0-based) */
|
|
587
|
+
readonly stepNumber: number;
|
|
588
|
+
/** The model being used for this step */
|
|
589
|
+
readonly model: LanguageModel;
|
|
590
|
+
/** The messages being sent for this step */
|
|
591
|
+
readonly messages: ModelMessage[];
|
|
592
|
+
/** Results from all previously finished steps */
|
|
593
|
+
readonly steps: ReadonlyArray<StepResult<TTools, any>>;
|
|
594
|
+
}) => PromiseLike<void> | void;
|
|
555
595
|
|
|
556
596
|
/**
|
|
557
597
|
* Callback that is called before a tool's execute function runs.
|
|
@@ -559,235 +599,280 @@ export type WorkflowAgentOnStepStartCallback = (event: {
|
|
|
559
599
|
export type WorkflowAgentOnToolCallStartCallback = (event: {
|
|
560
600
|
/** The tool call being executed */
|
|
561
601
|
readonly toolCall: ToolCall;
|
|
602
|
+
/** The current step number (0-based) */
|
|
603
|
+
readonly stepNumber: number;
|
|
562
604
|
}) => PromiseLike<void> | void;
|
|
563
605
|
|
|
564
606
|
/**
|
|
565
607
|
* Callback that is called after a tool execution completes.
|
|
608
|
+
* Uses a discriminated union pattern: check `success` to determine
|
|
609
|
+
* whether `output` or `error` is available.
|
|
566
610
|
*/
|
|
567
|
-
export type WorkflowAgentOnToolCallFinishCallback = (
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
611
|
+
export type WorkflowAgentOnToolCallFinishCallback = (
|
|
612
|
+
event:
|
|
613
|
+
| {
|
|
614
|
+
/** The tool call that was executed */
|
|
615
|
+
readonly toolCall: ToolCall;
|
|
616
|
+
/** The current step number (0-based) */
|
|
617
|
+
readonly stepNumber: number;
|
|
618
|
+
/** Execution time in milliseconds */
|
|
619
|
+
readonly durationMs: number;
|
|
620
|
+
/** Whether the tool call succeeded */
|
|
621
|
+
readonly success: true;
|
|
622
|
+
/** The tool result */
|
|
623
|
+
readonly output: unknown;
|
|
624
|
+
readonly error?: never;
|
|
625
|
+
}
|
|
626
|
+
| {
|
|
627
|
+
/** The tool call that was executed */
|
|
628
|
+
readonly toolCall: ToolCall;
|
|
629
|
+
/** The current step number (0-based) */
|
|
630
|
+
readonly stepNumber: number;
|
|
631
|
+
/** Execution time in milliseconds */
|
|
632
|
+
readonly durationMs: number;
|
|
633
|
+
/** Whether the tool call succeeded */
|
|
634
|
+
readonly success: false;
|
|
635
|
+
/** The error that occurred */
|
|
636
|
+
readonly error: unknown;
|
|
637
|
+
readonly output?: never;
|
|
638
|
+
},
|
|
639
|
+
) => PromiseLike<void> | void;
|
|
575
640
|
|
|
576
641
|
/**
|
|
577
642
|
* Options for the {@link WorkflowAgent.stream} method.
|
|
578
643
|
*/
|
|
579
|
-
export
|
|
644
|
+
export type WorkflowAgentStreamOptions<
|
|
580
645
|
TTools extends ToolSet = ToolSet,
|
|
581
646
|
OUTPUT = never,
|
|
582
647
|
PARTIAL_OUTPUT = never,
|
|
583
|
-
>
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
648
|
+
> = Partial<GenerationSettings> &
|
|
649
|
+
(
|
|
650
|
+
| {
|
|
651
|
+
/**
|
|
652
|
+
* A prompt. It can be either a text prompt or a list of messages.
|
|
653
|
+
*
|
|
654
|
+
* You can either use `prompt` or `messages` but not both.
|
|
655
|
+
*/
|
|
656
|
+
prompt: string | Array<ModelMessage>;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* A list of messages.
|
|
660
|
+
*
|
|
661
|
+
* You can either use `prompt` or `messages` but not both.
|
|
662
|
+
*/
|
|
663
|
+
messages?: never;
|
|
664
|
+
}
|
|
665
|
+
| {
|
|
666
|
+
/**
|
|
667
|
+
* The conversation messages to process. Should follow the AI SDK's ModelMessage format.
|
|
668
|
+
*
|
|
669
|
+
* You can either use `prompt` or `messages` but not both.
|
|
670
|
+
*/
|
|
671
|
+
messages: Array<ModelMessage>;
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* A prompt. It can be either a text prompt or a list of messages.
|
|
675
|
+
*
|
|
676
|
+
* You can either use `prompt` or `messages` but not both.
|
|
677
|
+
*/
|
|
678
|
+
prompt?: never;
|
|
679
|
+
}
|
|
680
|
+
) & {
|
|
681
|
+
/**
|
|
682
|
+
* Optional system prompt override. If provided, overrides the system prompt from the constructor.
|
|
683
|
+
*/
|
|
684
|
+
system?: string;
|
|
617
685
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
686
|
+
/**
|
|
687
|
+
* A WritableStream that receives raw LanguageModelV4StreamPart chunks in real-time
|
|
688
|
+
* as the model generates them. This enables streaming to the client without
|
|
689
|
+
* coupling WorkflowAgent to UIMessageChunk format.
|
|
690
|
+
*
|
|
691
|
+
* Convert to UIMessageChunks at the response boundary using
|
|
692
|
+
* `createUIMessageChunkTransform()` from `@ai-sdk/workflow`.
|
|
693
|
+
*
|
|
694
|
+
* @example
|
|
695
|
+
* ```typescript
|
|
696
|
+
* // In the workflow:
|
|
697
|
+
* await agent.stream({
|
|
698
|
+
* messages,
|
|
699
|
+
* writable: getWritable<ModelCallStreamPart>(),
|
|
700
|
+
* });
|
|
701
|
+
*
|
|
702
|
+
* // In the route handler:
|
|
703
|
+
* return createUIMessageStreamResponse({
|
|
704
|
+
* stream: run.readable.pipeThrough(createModelCallToUIChunkTransform()),
|
|
705
|
+
* });
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
writable?: WritableStream<ModelCallStreamPart<ToolSet>>;
|
|
625
709
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
710
|
+
/**
|
|
711
|
+
* Condition for stopping the generation when there are tool results in the last step.
|
|
712
|
+
* When the condition is an array, any of the conditions can be met to stop the generation.
|
|
713
|
+
*/
|
|
714
|
+
stopWhen?:
|
|
715
|
+
| StopCondition<NoInfer<ToolSet>, any>
|
|
716
|
+
| Array<StopCondition<NoInfer<ToolSet>, any>>;
|
|
632
717
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
718
|
+
/**
|
|
719
|
+
* The tool choice strategy. Default: 'auto'.
|
|
720
|
+
* Overrides the toolChoice from the constructor if provided.
|
|
721
|
+
*/
|
|
722
|
+
toolChoice?: ToolChoice<TTools>;
|
|
638
723
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
724
|
+
/**
|
|
725
|
+
* Limits the tools that are available for the model to call without
|
|
726
|
+
* changing the tool call and result types in the result.
|
|
727
|
+
*/
|
|
728
|
+
activeTools?: Array<keyof NoInfer<TTools>>;
|
|
644
729
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
730
|
+
/**
|
|
731
|
+
* Optional telemetry configuration (experimental).
|
|
732
|
+
*/
|
|
733
|
+
experimental_telemetry?: TelemetryOptions;
|
|
649
734
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
735
|
+
/**
|
|
736
|
+
* Context that is passed into tool execution.
|
|
737
|
+
* Experimental (can break in patch releases).
|
|
738
|
+
* @default undefined
|
|
739
|
+
*/
|
|
740
|
+
experimental_context?: unknown;
|
|
656
741
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
742
|
+
/**
|
|
743
|
+
* Optional specification for parsing structured outputs from the LLM response.
|
|
744
|
+
* Use `Output.object({ schema })` for structured output or `Output.text()` for text output.
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```typescript
|
|
748
|
+
* import { Output } from '@workflow/ai';
|
|
749
|
+
* import { z } from 'zod';
|
|
750
|
+
*
|
|
751
|
+
* const result = await agent.stream({
|
|
752
|
+
* messages: [...],
|
|
753
|
+
* writable: getWritable(),
|
|
754
|
+
* output: Output.object({
|
|
755
|
+
* schema: z.object({
|
|
756
|
+
* sentiment: z.enum(['positive', 'negative', 'neutral']),
|
|
757
|
+
* confidence: z.number(),
|
|
758
|
+
* }),
|
|
759
|
+
* }),
|
|
760
|
+
* });
|
|
761
|
+
*
|
|
762
|
+
* console.log(result.output); // { sentiment: 'positive', confidence: 0.95 }
|
|
763
|
+
* ```
|
|
764
|
+
*/
|
|
765
|
+
output?: OutputSpecification<OUTPUT, PARTIAL_OUTPUT>;
|
|
681
766
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
767
|
+
/**
|
|
768
|
+
* Whether to include raw chunks from the provider in the stream.
|
|
769
|
+
* When enabled, you will receive raw chunks with type 'raw' that contain the unprocessed data from the provider.
|
|
770
|
+
* This allows access to cutting-edge provider features not yet wrapped by the AI SDK.
|
|
771
|
+
* Defaults to false.
|
|
772
|
+
*/
|
|
773
|
+
includeRawChunks?: boolean;
|
|
689
774
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
775
|
+
/**
|
|
776
|
+
* A function that attempts to repair a tool call that failed to parse.
|
|
777
|
+
*/
|
|
778
|
+
experimental_repairToolCall?: ToolCallRepairFunction<TTools>;
|
|
694
779
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
780
|
+
/**
|
|
781
|
+
* Optional stream transformations.
|
|
782
|
+
* They are applied in the order they are provided.
|
|
783
|
+
* The stream transformations must maintain the stream structure for streamText to work correctly.
|
|
784
|
+
*/
|
|
785
|
+
experimental_transform?:
|
|
786
|
+
| StreamTextTransform<TTools>
|
|
787
|
+
| Array<StreamTextTransform<TTools>>;
|
|
703
788
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
789
|
+
/**
|
|
790
|
+
* Custom download function to use for URLs.
|
|
791
|
+
* By default, files are downloaded if the model does not support the URL for the given media type.
|
|
792
|
+
*/
|
|
793
|
+
experimental_download?: DownloadFunction;
|
|
709
794
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
795
|
+
/**
|
|
796
|
+
* Callback function to be called after each step completes.
|
|
797
|
+
*/
|
|
798
|
+
onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools>;
|
|
714
799
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
800
|
+
/**
|
|
801
|
+
* Callback that is invoked when an error occurs during streaming.
|
|
802
|
+
* You can use it to log errors.
|
|
803
|
+
*/
|
|
804
|
+
onError?: WorkflowAgentOnErrorCallback;
|
|
720
805
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
806
|
+
/**
|
|
807
|
+
* Callback that is called when the LLM response and all request tool executions
|
|
808
|
+
* (for tools that have an `execute` function) are finished.
|
|
809
|
+
*/
|
|
810
|
+
onFinish?: WorkflowAgentOnFinishCallback<TTools, OUTPUT>;
|
|
726
811
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
812
|
+
/**
|
|
813
|
+
* Callback that is called when the operation is aborted.
|
|
814
|
+
*/
|
|
815
|
+
onAbort?: WorkflowAgentOnAbortCallback<TTools>;
|
|
731
816
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
817
|
+
/**
|
|
818
|
+
* Callback called when the agent starts streaming, before any LLM calls.
|
|
819
|
+
*/
|
|
820
|
+
experimental_onStart?: WorkflowAgentOnStartCallback;
|
|
736
821
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
822
|
+
/**
|
|
823
|
+
* Callback called before each step (LLM call) begins.
|
|
824
|
+
*/
|
|
825
|
+
experimental_onStepStart?: WorkflowAgentOnStepStartCallback;
|
|
741
826
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
827
|
+
/**
|
|
828
|
+
* Callback called before a tool's execute function runs.
|
|
829
|
+
*/
|
|
830
|
+
experimental_onToolCallStart?: WorkflowAgentOnToolCallStartCallback;
|
|
746
831
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
832
|
+
/**
|
|
833
|
+
* Callback called after a tool execution completes.
|
|
834
|
+
*/
|
|
835
|
+
experimental_onToolCallFinish?: WorkflowAgentOnToolCallFinishCallback;
|
|
751
836
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
837
|
+
/**
|
|
838
|
+
* Callback function called before each step in the agent loop.
|
|
839
|
+
* Use this to modify settings, manage context, or inject messages dynamically.
|
|
840
|
+
*
|
|
841
|
+
* @example
|
|
842
|
+
* ```typescript
|
|
843
|
+
* prepareStep: async ({ messages, stepNumber }) => {
|
|
844
|
+
* // Inject messages from a queue
|
|
845
|
+
* const queuedMessages = await getQueuedMessages();
|
|
846
|
+
* if (queuedMessages.length > 0) {
|
|
847
|
+
* return {
|
|
848
|
+
* messages: [...messages, ...queuedMessages],
|
|
849
|
+
* };
|
|
850
|
+
* }
|
|
851
|
+
* return {};
|
|
852
|
+
* }
|
|
853
|
+
* ```
|
|
854
|
+
*/
|
|
855
|
+
prepareStep?: PrepareStepCallback<TTools>;
|
|
771
856
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
857
|
+
/**
|
|
858
|
+
* Timeout in milliseconds for the stream operation.
|
|
859
|
+
* When specified, creates an AbortSignal that will abort the operation after the given time.
|
|
860
|
+
* If both `timeout` and `abortSignal` are provided, whichever triggers first will abort.
|
|
861
|
+
*/
|
|
862
|
+
timeout?: number;
|
|
778
863
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
864
|
+
/**
|
|
865
|
+
* Whether to send a 'finish' chunk to the writable stream when streaming completes.
|
|
866
|
+
* @default true
|
|
867
|
+
*/
|
|
868
|
+
sendFinish?: boolean;
|
|
784
869
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
}
|
|
870
|
+
/**
|
|
871
|
+
* Whether to prevent the writable stream from being closed after streaming completes.
|
|
872
|
+
* @default false
|
|
873
|
+
*/
|
|
874
|
+
preventClose?: boolean;
|
|
875
|
+
};
|
|
791
876
|
|
|
792
877
|
/**
|
|
793
878
|
* A tool call made by the model. Matches the AI SDK's tool call shape.
|
|
@@ -898,10 +983,12 @@ export interface WorkflowAgentStreamResult<
|
|
|
898
983
|
* ```
|
|
899
984
|
*/
|
|
900
985
|
export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
986
|
+
/**
|
|
987
|
+
* The id of the agent.
|
|
988
|
+
*/
|
|
989
|
+
public readonly id: string | undefined;
|
|
990
|
+
|
|
991
|
+
private model: LanguageModel;
|
|
905
992
|
/**
|
|
906
993
|
* The tool set configured for this agent.
|
|
907
994
|
*/
|
|
@@ -912,14 +999,18 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
912
999
|
| Array<SystemModelMessage>;
|
|
913
1000
|
private generationSettings: GenerationSettings;
|
|
914
1001
|
private toolChoice?: ToolChoice<TBaseTools>;
|
|
915
|
-
private telemetry?:
|
|
1002
|
+
private telemetry?: TelemetryOptions;
|
|
916
1003
|
private experimentalContext: unknown;
|
|
1004
|
+
private stopWhen?:
|
|
1005
|
+
| StopCondition<ToolSet, any>
|
|
1006
|
+
| Array<StopCondition<ToolSet, any>>;
|
|
1007
|
+
private activeTools?: Array<keyof TBaseTools>;
|
|
1008
|
+
private output?: OutputSpecification<any, any>;
|
|
1009
|
+
private experimentalRepairToolCall?: ToolCallRepairFunction<TBaseTools>;
|
|
1010
|
+
private experimentalDownload?: DownloadFunction;
|
|
917
1011
|
private prepareStep?: PrepareStepCallback<TBaseTools>;
|
|
918
|
-
private constructorOnStepFinish?:
|
|
919
|
-
|
|
920
|
-
any
|
|
921
|
-
>;
|
|
922
|
-
private constructorOnFinish?: StreamTextOnFinishCallback<ToolSet>;
|
|
1012
|
+
private constructorOnStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;
|
|
1013
|
+
private constructorOnFinish?: WorkflowAgentOnFinishCallback<ToolSet>;
|
|
923
1014
|
private constructorOnStart?: WorkflowAgentOnStartCallback;
|
|
924
1015
|
private constructorOnStepStart?: WorkflowAgentOnStepStartCallback;
|
|
925
1016
|
private constructorOnToolCallStart?: WorkflowAgentOnToolCallStartCallback;
|
|
@@ -927,6 +1018,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
927
1018
|
private prepareCall?: PrepareCallCallback<TBaseTools>;
|
|
928
1019
|
|
|
929
1020
|
constructor(options: WorkflowAgentOptions<TBaseTools>) {
|
|
1021
|
+
this.id = options.id;
|
|
930
1022
|
this.model = options.model;
|
|
931
1023
|
this.tools = (options.tools ?? {}) as TBaseTools;
|
|
932
1024
|
// `instructions` takes precedence over deprecated `system`
|
|
@@ -934,6 +1026,11 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
934
1026
|
this.toolChoice = options.toolChoice;
|
|
935
1027
|
this.telemetry = options.experimental_telemetry;
|
|
936
1028
|
this.experimentalContext = options.experimental_context;
|
|
1029
|
+
this.stopWhen = options.stopWhen;
|
|
1030
|
+
this.activeTools = options.activeTools;
|
|
1031
|
+
this.output = options.output;
|
|
1032
|
+
this.experimentalRepairToolCall = options.experimental_repairToolCall;
|
|
1033
|
+
this.experimentalDownload = options.experimental_download;
|
|
937
1034
|
this.prepareStep = options.prepareStep;
|
|
938
1035
|
this.constructorOnStepFinish = options.onStepFinish;
|
|
939
1036
|
this.constructorOnFinish = options.onFinish;
|
|
@@ -972,12 +1069,11 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
972
1069
|
options: WorkflowAgentStreamOptions<TTools, OUTPUT, PARTIAL_OUTPUT>,
|
|
973
1070
|
): Promise<WorkflowAgentStreamResult<TTools, OUTPUT>> {
|
|
974
1071
|
// Call prepareCall to transform parameters before the agent loop
|
|
975
|
-
let effectiveModel:
|
|
976
|
-
| string
|
|
977
|
-
| CompatibleLanguageModel
|
|
978
|
-
| (() => Promise<CompatibleLanguageModel>) = this.model;
|
|
1072
|
+
let effectiveModel: LanguageModel = this.model;
|
|
979
1073
|
let effectiveInstructions = options.system ?? this.instructions;
|
|
980
|
-
let
|
|
1074
|
+
let effectivePrompt: string | Array<ModelMessage> | undefined =
|
|
1075
|
+
options.prompt;
|
|
1076
|
+
let effectiveMessages: Array<ModelMessage> | undefined = options.messages;
|
|
981
1077
|
let effectiveGenerationSettings = { ...this.generationSettings };
|
|
982
1078
|
let effectiveExperimentalContext =
|
|
983
1079
|
options.experimental_context ?? this.experimentalContext;
|
|
@@ -985,6 +1081,14 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
985
1081
|
let effectiveTelemetryFromPrepare =
|
|
986
1082
|
options.experimental_telemetry ?? this.telemetry;
|
|
987
1083
|
|
|
1084
|
+
// Resolve messages for prepareCall: use messages directly, or convert prompt
|
|
1085
|
+
const resolvedMessagesForPrepareCall: ModelMessage[] =
|
|
1086
|
+
effectiveMessages ??
|
|
1087
|
+
(typeof effectivePrompt === 'string'
|
|
1088
|
+
? [{ role: 'user' as const, content: effectivePrompt }]
|
|
1089
|
+
: (effectivePrompt as ModelMessage[])) ??
|
|
1090
|
+
[];
|
|
1091
|
+
|
|
988
1092
|
if (this.prepareCall) {
|
|
989
1093
|
const prepared = await this.prepareCall({
|
|
990
1094
|
model: effectiveModel,
|
|
@@ -993,16 +1097,17 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
993
1097
|
toolChoice: effectiveToolChoiceFromPrepare as ToolChoice<TBaseTools>,
|
|
994
1098
|
experimental_telemetry: effectiveTelemetryFromPrepare,
|
|
995
1099
|
experimental_context: effectiveExperimentalContext,
|
|
996
|
-
messages:
|
|
1100
|
+
messages: resolvedMessagesForPrepareCall,
|
|
997
1101
|
...effectiveGenerationSettings,
|
|
998
1102
|
} as PrepareCallOptions<TBaseTools>);
|
|
999
1103
|
|
|
1000
1104
|
if (prepared.model !== undefined) effectiveModel = prepared.model;
|
|
1001
1105
|
if (prepared.instructions !== undefined)
|
|
1002
1106
|
effectiveInstructions = prepared.instructions;
|
|
1003
|
-
if (prepared.messages !== undefined)
|
|
1004
|
-
effectiveMessages =
|
|
1005
|
-
|
|
1107
|
+
if (prepared.messages !== undefined) {
|
|
1108
|
+
effectiveMessages = prepared.messages as Array<ModelMessage>;
|
|
1109
|
+
effectivePrompt = undefined; // messages from prepareCall take precedence
|
|
1110
|
+
}
|
|
1006
1111
|
if (prepared.experimental_context !== undefined)
|
|
1007
1112
|
effectiveExperimentalContext = prepared.experimental_context;
|
|
1008
1113
|
if (prepared.toolChoice !== undefined)
|
|
@@ -1035,7 +1140,9 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1035
1140
|
|
|
1036
1141
|
const prompt = await standardizePrompt({
|
|
1037
1142
|
system: effectiveInstructions,
|
|
1038
|
-
|
|
1143
|
+
...(effectivePrompt != null
|
|
1144
|
+
? { prompt: effectivePrompt }
|
|
1145
|
+
: { messages: effectiveMessages! }),
|
|
1039
1146
|
});
|
|
1040
1147
|
|
|
1041
1148
|
// Process tool approval responses before starting the agent loop.
|
|
@@ -1164,7 +1271,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1164
1271
|
const modelPrompt = await convertToLanguageModelPrompt({
|
|
1165
1272
|
prompt,
|
|
1166
1273
|
supportedUrls: {},
|
|
1167
|
-
download: options.experimental_download,
|
|
1274
|
+
download: options.experimental_download ?? this.experimentalDownload,
|
|
1168
1275
|
});
|
|
1169
1276
|
|
|
1170
1277
|
const effectiveAbortSignal = mergeAbortSignals(
|
|
@@ -1210,13 +1317,13 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1210
1317
|
// Merge constructor + stream callbacks (constructor first, then stream)
|
|
1211
1318
|
const mergedOnStepFinish = mergeCallbacks(
|
|
1212
1319
|
this.constructorOnStepFinish as
|
|
1213
|
-
|
|
|
1320
|
+
| WorkflowAgentOnStepFinishCallback<TTools>
|
|
1214
1321
|
| undefined,
|
|
1215
1322
|
options.onStepFinish,
|
|
1216
1323
|
);
|
|
1217
1324
|
const mergedOnFinish = mergeCallbacks(
|
|
1218
1325
|
this.constructorOnFinish as
|
|
1219
|
-
|
|
|
1326
|
+
| WorkflowAgentOnFinishCallback<TTools, OUTPUT>
|
|
1220
1327
|
| undefined,
|
|
1221
1328
|
options.onFinish,
|
|
1222
1329
|
);
|
|
@@ -1243,10 +1350,14 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1243
1350
|
// Merge telemetry settings
|
|
1244
1351
|
const effectiveTelemetry = effectiveTelemetryFromPrepare;
|
|
1245
1352
|
|
|
1246
|
-
// Filter tools if activeTools is specified
|
|
1353
|
+
// Filter tools if activeTools is specified (stream-level overrides constructor default)
|
|
1354
|
+
const effectiveActiveTools = options.activeTools ?? this.activeTools;
|
|
1247
1355
|
const effectiveTools =
|
|
1248
|
-
|
|
1249
|
-
?
|
|
1356
|
+
effectiveActiveTools && effectiveActiveTools.length > 0
|
|
1357
|
+
? (filterActiveTools({
|
|
1358
|
+
tools: this.tools,
|
|
1359
|
+
activeTools: effectiveActiveTools as string[],
|
|
1360
|
+
}) ?? this.tools)
|
|
1250
1361
|
: this.tools;
|
|
1251
1362
|
|
|
1252
1363
|
// Initialize context
|
|
@@ -1262,7 +1373,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1262
1373
|
if (mergedOnStart) {
|
|
1263
1374
|
await mergedOnStart({
|
|
1264
1375
|
model: effectiveModel,
|
|
1265
|
-
messages:
|
|
1376
|
+
messages: prompt.messages,
|
|
1266
1377
|
});
|
|
1267
1378
|
}
|
|
1268
1379
|
|
|
@@ -1272,59 +1383,67 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1272
1383
|
tools: ToolSet,
|
|
1273
1384
|
messages: LanguageModelV4Prompt,
|
|
1274
1385
|
context?: unknown,
|
|
1386
|
+
currentStepNumber: number = 0,
|
|
1275
1387
|
): Promise<LanguageModelV4ToolResultPart> => {
|
|
1388
|
+
const toolCallEvent: ToolCall = {
|
|
1389
|
+
type: 'tool-call',
|
|
1390
|
+
toolCallId: toolCall.toolCallId,
|
|
1391
|
+
toolName: toolCall.toolName,
|
|
1392
|
+
input: toolCall.input,
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1276
1395
|
if (mergedOnToolCallStart) {
|
|
1277
1396
|
await mergedOnToolCallStart({
|
|
1278
|
-
toolCall:
|
|
1279
|
-
|
|
1280
|
-
toolCallId: toolCall.toolCallId,
|
|
1281
|
-
toolName: toolCall.toolName,
|
|
1282
|
-
input: toolCall.input,
|
|
1283
|
-
},
|
|
1397
|
+
toolCall: toolCallEvent,
|
|
1398
|
+
stepNumber: currentStepNumber,
|
|
1284
1399
|
});
|
|
1285
1400
|
}
|
|
1401
|
+
|
|
1402
|
+
const startTime = Date.now();
|
|
1286
1403
|
let result: LanguageModelV4ToolResultPart;
|
|
1287
1404
|
try {
|
|
1288
1405
|
result = await executeTool(toolCall, tools, messages, context);
|
|
1289
1406
|
} catch (err) {
|
|
1407
|
+
const durationMs = Date.now() - startTime;
|
|
1290
1408
|
if (mergedOnToolCallFinish) {
|
|
1291
1409
|
await mergedOnToolCallFinish({
|
|
1292
|
-
toolCall:
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
input: toolCall.input,
|
|
1297
|
-
},
|
|
1410
|
+
toolCall: toolCallEvent,
|
|
1411
|
+
stepNumber: currentStepNumber,
|
|
1412
|
+
durationMs,
|
|
1413
|
+
success: false,
|
|
1298
1414
|
error: err,
|
|
1299
1415
|
});
|
|
1300
1416
|
}
|
|
1301
1417
|
throw err;
|
|
1302
1418
|
}
|
|
1419
|
+
|
|
1420
|
+
const durationMs = Date.now() - startTime;
|
|
1303
1421
|
if (mergedOnToolCallFinish) {
|
|
1304
1422
|
const isError =
|
|
1305
1423
|
result.output &&
|
|
1306
1424
|
'type' in result.output &&
|
|
1307
1425
|
(result.output.type === 'error-text' ||
|
|
1308
1426
|
result.output.type === 'error-json');
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1427
|
+
if (isError) {
|
|
1428
|
+
await mergedOnToolCallFinish({
|
|
1429
|
+
toolCall: toolCallEvent,
|
|
1430
|
+
stepNumber: currentStepNumber,
|
|
1431
|
+
durationMs,
|
|
1432
|
+
success: false,
|
|
1433
|
+
error: 'value' in result.output ? result.output.value : undefined,
|
|
1434
|
+
});
|
|
1435
|
+
} else {
|
|
1436
|
+
await mergedOnToolCallFinish({
|
|
1437
|
+
toolCall: toolCallEvent,
|
|
1438
|
+
stepNumber: currentStepNumber,
|
|
1439
|
+
durationMs,
|
|
1440
|
+
success: true,
|
|
1441
|
+
output:
|
|
1442
|
+
result.output && 'value' in result.output
|
|
1443
|
+
? result.output.value
|
|
1444
|
+
: undefined,
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1328
1447
|
}
|
|
1329
1448
|
return result;
|
|
1330
1449
|
};
|
|
@@ -1335,7 +1454,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1335
1454
|
await options.onAbort({ steps });
|
|
1336
1455
|
}
|
|
1337
1456
|
return {
|
|
1338
|
-
messages:
|
|
1457
|
+
messages: prompt.messages,
|
|
1339
1458
|
steps,
|
|
1340
1459
|
toolCalls: [],
|
|
1341
1460
|
toolResults: [],
|
|
@@ -1348,8 +1467,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1348
1467
|
tools: effectiveTools as ToolSet,
|
|
1349
1468
|
writable: options.writable,
|
|
1350
1469
|
prompt: modelPrompt,
|
|
1351
|
-
stopConditions: options.stopWhen,
|
|
1352
|
-
|
|
1470
|
+
stopConditions: options.stopWhen ?? this.stopWhen,
|
|
1471
|
+
|
|
1353
1472
|
onStepFinish: mergedOnStepFinish,
|
|
1354
1473
|
onStepStart: mergedOnStepStart,
|
|
1355
1474
|
onError: options.onError,
|
|
@@ -1361,9 +1480,11 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1361
1480
|
experimental_context: experimentalContext,
|
|
1362
1481
|
experimental_telemetry: effectiveTelemetry,
|
|
1363
1482
|
includeRawChunks: options.includeRawChunks ?? false,
|
|
1364
|
-
repairToolCall:
|
|
1365
|
-
|
|
1366
|
-
|
|
1483
|
+
repairToolCall: (options.experimental_repairToolCall ??
|
|
1484
|
+
this.experimentalRepairToolCall) as
|
|
1485
|
+
| ToolCallRepairFunction<ToolSet>
|
|
1486
|
+
| undefined,
|
|
1487
|
+
responseFormat: await (options.output ?? this.output)?.responseFormat,
|
|
1367
1488
|
});
|
|
1368
1489
|
|
|
1369
1490
|
// Track the final conversation messages from the iterator
|
|
@@ -1390,6 +1511,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1390
1511
|
context,
|
|
1391
1512
|
providerExecutedToolResults,
|
|
1392
1513
|
} = result.value;
|
|
1514
|
+
// Capture current step number before pushing (0-based)
|
|
1515
|
+
const currentStepNumber = steps.length;
|
|
1393
1516
|
if (step) {
|
|
1394
1517
|
steps.push(step as unknown as StepResult<TTools, any>);
|
|
1395
1518
|
}
|
|
@@ -1453,6 +1576,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1453
1576
|
effectiveTools as ToolSet,
|
|
1454
1577
|
iterMessages,
|
|
1455
1578
|
experimentalContext,
|
|
1579
|
+
currentStepNumber,
|
|
1456
1580
|
),
|
|
1457
1581
|
),
|
|
1458
1582
|
);
|
|
@@ -1553,6 +1677,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1553
1677
|
effectiveTools as ToolSet,
|
|
1554
1678
|
iterMessages,
|
|
1555
1679
|
experimentalContext,
|
|
1680
|
+
currentStepNumber,
|
|
1556
1681
|
),
|
|
1557
1682
|
),
|
|
1558
1683
|
);
|
|
@@ -1641,18 +1766,19 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1641
1766
|
// Don't throw yet - we want to call onFinish first
|
|
1642
1767
|
}
|
|
1643
1768
|
|
|
1644
|
-
// Use the final messages from the iterator, or fall back to
|
|
1769
|
+
// Use the final messages from the iterator, or fall back to standardized messages
|
|
1645
1770
|
const messages = (finalMessages ??
|
|
1646
|
-
|
|
1771
|
+
prompt.messages) as unknown as ModelMessage[];
|
|
1647
1772
|
|
|
1648
|
-
// Parse structured output if output is specified
|
|
1773
|
+
// Parse structured output if output is specified (stream-level overrides constructor default)
|
|
1774
|
+
const effectiveOutput = options.output ?? this.output;
|
|
1649
1775
|
let experimentalOutput: OUTPUT = undefined as OUTPUT;
|
|
1650
|
-
if (
|
|
1776
|
+
if (effectiveOutput && steps.length > 0) {
|
|
1651
1777
|
const lastStep = steps[steps.length - 1];
|
|
1652
1778
|
const text = lastStep.text;
|
|
1653
1779
|
if (text) {
|
|
1654
1780
|
try {
|
|
1655
|
-
experimentalOutput = await
|
|
1781
|
+
experimentalOutput = await effectiveOutput.parseCompleteOutput(
|
|
1656
1782
|
{ text },
|
|
1657
1783
|
{
|
|
1658
1784
|
response: lastStep.response,
|
|
@@ -1850,19 +1976,6 @@ function aggregateUsage(steps: StepResult<any, any>[]): LanguageModelUsage {
|
|
|
1850
1976
|
} as LanguageModelUsage;
|
|
1851
1977
|
}
|
|
1852
1978
|
|
|
1853
|
-
function filterTools<TTools extends ToolSet>(
|
|
1854
|
-
tools: TTools,
|
|
1855
|
-
activeTools: string[],
|
|
1856
|
-
): ToolSet {
|
|
1857
|
-
const filtered: ToolSet = {};
|
|
1858
|
-
for (const toolName of activeTools) {
|
|
1859
|
-
if (toolName in tools) {
|
|
1860
|
-
filtered[toolName] = tools[toolName];
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
return filtered;
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
1979
|
// Matches AI SDK's getErrorMessage from @ai-sdk/provider-utils
|
|
1867
1980
|
function getErrorMessage(error: unknown): string {
|
|
1868
1981
|
if (error == null) {
|