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