@ai-sdk/workflow 1.0.0-canary.39 → 1.0.0-canary.41
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 +24 -0
- package/dist/index.d.mts +131 -55
- package/dist/index.mjs +160 -84
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/do-stream-step.ts +5 -2
- package/src/stream-text-iterator.ts +46 -26
- package/src/test/agent-e2e-workflows.ts +80 -0
- package/src/workflow-agent.ts +478 -220
package/src/workflow-agent.ts
CHANGED
|
@@ -6,6 +6,12 @@ import type {
|
|
|
6
6
|
LanguageModelV4ToolResultPart,
|
|
7
7
|
SharedV4ProviderOptions,
|
|
8
8
|
} from '@ai-sdk/provider';
|
|
9
|
+
import {
|
|
10
|
+
validateTypes,
|
|
11
|
+
type Context,
|
|
12
|
+
type HasRequiredKey,
|
|
13
|
+
type InferToolSetContext,
|
|
14
|
+
} from '@ai-sdk/provider-utils';
|
|
9
15
|
import {
|
|
10
16
|
Output,
|
|
11
17
|
experimental_filterActiveTools as filterActiveTools,
|
|
@@ -44,13 +50,14 @@ export type { CompatibleLanguageModel } from './types.js';
|
|
|
44
50
|
*/
|
|
45
51
|
export type WorkflowAgentOnStepFinishCallback<
|
|
46
52
|
TTools extends ToolSet = ToolSet,
|
|
47
|
-
|
|
53
|
+
TRuntimeContext extends Context = Context,
|
|
54
|
+
> = GenerateTextOnStepFinishCallback<TTools, TRuntimeContext>;
|
|
48
55
|
|
|
49
56
|
/**
|
|
50
57
|
* Infer the type of the tools of a workflow agent.
|
|
51
58
|
*/
|
|
52
59
|
export type InferWorkflowAgentTools<WORKFLOW_AGENT> =
|
|
53
|
-
WORKFLOW_AGENT extends WorkflowAgent<infer TOOLS> ? TOOLS : never;
|
|
60
|
+
WORKFLOW_AGENT extends WorkflowAgent<infer TOOLS, any> ? TOOLS : never;
|
|
54
61
|
|
|
55
62
|
/**
|
|
56
63
|
* Infer the UI message type of a workflow agent.
|
|
@@ -91,6 +98,11 @@ export interface OutputSpecification<OUTPUT, PARTIAL> {
|
|
|
91
98
|
*/
|
|
92
99
|
export type ProviderOptions = SharedV4ProviderOptions;
|
|
93
100
|
|
|
101
|
+
type WorkflowAgentToolsContextParameter<TTools extends ToolSet> =
|
|
102
|
+
HasRequiredKey<InferToolSetContext<TTools>> extends true
|
|
103
|
+
? { toolsContext: InferToolSetContext<TTools> }
|
|
104
|
+
: { toolsContext?: never };
|
|
105
|
+
|
|
94
106
|
/**
|
|
95
107
|
* Telemetry settings for observability.
|
|
96
108
|
*/
|
|
@@ -255,7 +267,10 @@ export interface GenerationSettings {
|
|
|
255
267
|
/**
|
|
256
268
|
* Information passed to the prepareStep callback.
|
|
257
269
|
*/
|
|
258
|
-
export interface PrepareStepInfo<
|
|
270
|
+
export interface PrepareStepInfo<
|
|
271
|
+
TTools extends ToolSet = ToolSet,
|
|
272
|
+
TRuntimeContext extends Context = Context,
|
|
273
|
+
> {
|
|
259
274
|
/**
|
|
260
275
|
* The current model configuration (string or function).
|
|
261
276
|
* The function should return a LanguageModelV4 instance.
|
|
@@ -270,7 +285,7 @@ export interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {
|
|
|
270
285
|
/**
|
|
271
286
|
* All previous steps with their results.
|
|
272
287
|
*/
|
|
273
|
-
steps: StepResult<TTools,
|
|
288
|
+
steps: StepResult<TTools, TRuntimeContext>[];
|
|
274
289
|
|
|
275
290
|
/**
|
|
276
291
|
* The messages that will be sent to the model.
|
|
@@ -279,16 +294,29 @@ export interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {
|
|
|
279
294
|
messages: LanguageModelV4Prompt;
|
|
280
295
|
|
|
281
296
|
/**
|
|
282
|
-
* The context
|
|
297
|
+
* The runtime context that flows through the agent loop.
|
|
298
|
+
* Treat the value as immutable; return a new `runtimeContext` from
|
|
299
|
+
* `prepareStep` to update it for the current and subsequent steps.
|
|
283
300
|
*/
|
|
284
|
-
|
|
301
|
+
runtimeContext: TRuntimeContext;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Per-tool context, keyed by tool name. Each tool receives only its own
|
|
305
|
+
* validated entry as `context` during execution.
|
|
306
|
+
* Treat the value as immutable; return a new `toolsContext` from
|
|
307
|
+
* `prepareStep` to update it for the current and subsequent steps.
|
|
308
|
+
*/
|
|
309
|
+
toolsContext: InferToolSetContext<TTools>;
|
|
285
310
|
}
|
|
286
311
|
|
|
287
312
|
/**
|
|
288
313
|
* Return type from the prepareStep callback.
|
|
289
314
|
* All properties are optional - only return the ones you want to override.
|
|
290
315
|
*/
|
|
291
|
-
export interface PrepareStepResult
|
|
316
|
+
export interface PrepareStepResult<
|
|
317
|
+
TTools extends ToolSet = ToolSet,
|
|
318
|
+
TRuntimeContext extends Context = Context,
|
|
319
|
+
> extends Partial<GenerationSettings> {
|
|
292
320
|
/**
|
|
293
321
|
* Override the model for this step.
|
|
294
322
|
*/
|
|
@@ -317,25 +345,38 @@ export interface PrepareStepResult extends Partial<GenerationSettings> {
|
|
|
317
345
|
activeTools?: string[];
|
|
318
346
|
|
|
319
347
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
348
|
+
* Updated runtime context for the current and subsequent steps.
|
|
349
|
+
* Returning a value replaces the agent's runtime context.
|
|
350
|
+
*/
|
|
351
|
+
runtimeContext?: TRuntimeContext;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Updated per-tool context for the current and subsequent steps.
|
|
355
|
+
* Returning a value replaces the agent's tools context.
|
|
322
356
|
*/
|
|
323
|
-
|
|
357
|
+
toolsContext?: InferToolSetContext<TTools>;
|
|
324
358
|
}
|
|
325
359
|
|
|
326
360
|
/**
|
|
327
361
|
* Callback function called before each step in the agent loop.
|
|
328
362
|
* Use this to modify settings, manage context, or implement dynamic behavior.
|
|
329
363
|
*/
|
|
330
|
-
export type PrepareStepCallback<
|
|
331
|
-
|
|
332
|
-
|
|
364
|
+
export type PrepareStepCallback<
|
|
365
|
+
TTools extends ToolSet = ToolSet,
|
|
366
|
+
TRuntimeContext extends Context = Context,
|
|
367
|
+
> = (
|
|
368
|
+
info: PrepareStepInfo<TTools, TRuntimeContext>,
|
|
369
|
+
) =>
|
|
370
|
+
| PrepareStepResult<TTools, TRuntimeContext>
|
|
371
|
+
| undefined
|
|
372
|
+
| Promise<PrepareStepResult<TTools, TRuntimeContext> | undefined>;
|
|
333
373
|
|
|
334
374
|
/**
|
|
335
375
|
* Options passed to the prepareCall callback.
|
|
336
376
|
*/
|
|
337
377
|
export interface PrepareCallOptions<
|
|
338
378
|
TTools extends ToolSet = ToolSet,
|
|
379
|
+
TRuntimeContext extends Context = Context,
|
|
339
380
|
> extends Partial<GenerationSettings> {
|
|
340
381
|
model: LanguageModel;
|
|
341
382
|
tools: TTools;
|
|
@@ -346,7 +387,15 @@ export interface PrepareCallOptions<
|
|
|
346
387
|
* @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
|
|
347
388
|
*/
|
|
348
389
|
experimental_telemetry?: TelemetryOptions;
|
|
349
|
-
|
|
390
|
+
/**
|
|
391
|
+
* Runtime context that flows through the agent loop.
|
|
392
|
+
* Treat as immutable; return a new `runtimeContext` to update it for the call.
|
|
393
|
+
*/
|
|
394
|
+
runtimeContext?: TRuntimeContext;
|
|
395
|
+
/**
|
|
396
|
+
* Per-tool context, keyed by tool name.
|
|
397
|
+
*/
|
|
398
|
+
toolsContext?: InferToolSetContext<TTools>;
|
|
350
399
|
messages: ModelMessage[];
|
|
351
400
|
}
|
|
352
401
|
|
|
@@ -356,179 +405,200 @@ export interface PrepareCallOptions<
|
|
|
356
405
|
* Note: `tools` cannot be overridden via prepareCall because they are
|
|
357
406
|
* bound at construction time for type safety.
|
|
358
407
|
*/
|
|
359
|
-
export type PrepareCallResult<
|
|
360
|
-
|
|
361
|
-
|
|
408
|
+
export type PrepareCallResult<
|
|
409
|
+
TTools extends ToolSet = ToolSet,
|
|
410
|
+
TRuntimeContext extends Context = Context,
|
|
411
|
+
> = Partial<Omit<PrepareCallOptions<TTools, TRuntimeContext>, 'tools'>>;
|
|
362
412
|
|
|
363
413
|
/**
|
|
364
414
|
* Callback called once before the agent loop starts to transform call parameters.
|
|
365
415
|
*/
|
|
366
|
-
export type PrepareCallCallback<
|
|
367
|
-
|
|
368
|
-
|
|
416
|
+
export type PrepareCallCallback<
|
|
417
|
+
TTools extends ToolSet = ToolSet,
|
|
418
|
+
TRuntimeContext extends Context = Context,
|
|
419
|
+
> = (
|
|
420
|
+
options: PrepareCallOptions<TTools, TRuntimeContext>,
|
|
421
|
+
) =>
|
|
422
|
+
| PrepareCallResult<TTools, TRuntimeContext>
|
|
423
|
+
| Promise<PrepareCallResult<TTools, TRuntimeContext>>;
|
|
369
424
|
|
|
370
425
|
/**
|
|
371
426
|
* Configuration options for creating a {@link WorkflowAgent} instance.
|
|
372
427
|
*/
|
|
373
|
-
export
|
|
428
|
+
export type WorkflowAgentOptions<
|
|
374
429
|
TTools extends ToolSet = ToolSet,
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
430
|
+
TRuntimeContext extends Context = Context,
|
|
431
|
+
> = GenerationSettings &
|
|
432
|
+
WorkflowAgentToolsContextParameter<TTools> & {
|
|
433
|
+
/**
|
|
434
|
+
* The id of the agent.
|
|
435
|
+
*/
|
|
436
|
+
id?: string;
|
|
380
437
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
438
|
+
/**
|
|
439
|
+
* The model provider to use for the agent.
|
|
440
|
+
*
|
|
441
|
+
* This should be a string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-opus'),
|
|
442
|
+
* or a LanguageModelV4 instance from a provider.
|
|
443
|
+
*/
|
|
444
|
+
model: LanguageModel;
|
|
388
445
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
446
|
+
/**
|
|
447
|
+
* A set of tools available to the agent.
|
|
448
|
+
* Tools can be implemented as workflow steps for automatic retries and persistence,
|
|
449
|
+
* or as regular workflow-level logic using core library features like sleep() and Hooks.
|
|
450
|
+
*/
|
|
451
|
+
tools?: TTools;
|
|
395
452
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
453
|
+
/**
|
|
454
|
+
* Agent instructions. Can be a string, a SystemModelMessage, or an array of SystemModelMessages.
|
|
455
|
+
* Supports provider-specific options (e.g., caching) when using the SystemModelMessage form.
|
|
456
|
+
*/
|
|
457
|
+
instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
|
|
401
458
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
459
|
+
/**
|
|
460
|
+
* Optional system prompt to guide the agent's behavior.
|
|
461
|
+
* @deprecated Use `instructions` instead.
|
|
462
|
+
*/
|
|
463
|
+
system?: string;
|
|
407
464
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
465
|
+
/**
|
|
466
|
+
* The tool choice strategy. Default: 'auto'.
|
|
467
|
+
*/
|
|
468
|
+
toolChoice?: ToolChoice<TTools>;
|
|
412
469
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
470
|
+
/**
|
|
471
|
+
* Optional telemetry configuration.
|
|
472
|
+
*/
|
|
473
|
+
telemetry?: TelemetryOptions;
|
|
417
474
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
475
|
+
/**
|
|
476
|
+
* Optional telemetry configuration.
|
|
477
|
+
*
|
|
478
|
+
* @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
|
|
479
|
+
*/
|
|
480
|
+
experimental_telemetry?: TelemetryOptions;
|
|
424
481
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
482
|
+
/**
|
|
483
|
+
* Default runtime context for every stream call on this agent.
|
|
484
|
+
*
|
|
485
|
+
* The runtime context flows through `prepareStep`, lifecycle callbacks,
|
|
486
|
+
* and step results.
|
|
487
|
+
* Treat as immutable; return a new `runtimeContext` from `prepareStep`
|
|
488
|
+
* to update it between steps.
|
|
489
|
+
*
|
|
490
|
+
* In workflow context, keep values serializable so they can cross workflow
|
|
491
|
+
* and step boundaries.
|
|
492
|
+
*
|
|
493
|
+
* Per-stream `runtimeContext` values passed to `stream()` override this default.
|
|
494
|
+
*/
|
|
495
|
+
runtimeContext?: TRuntimeContext;
|
|
433
496
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
497
|
+
/**
|
|
498
|
+
* Default stop condition for the agent loop. When the condition is an array,
|
|
499
|
+
* any of the conditions can be met to stop the generation.
|
|
500
|
+
*
|
|
501
|
+
* Per-stream `stopWhen` values passed to `stream()` override this default.
|
|
502
|
+
*/
|
|
503
|
+
stopWhen?:
|
|
504
|
+
| StopCondition<NoInfer<ToolSet>, any>
|
|
505
|
+
| Array<StopCondition<NoInfer<ToolSet>, any>>;
|
|
443
506
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
507
|
+
/**
|
|
508
|
+
* Default set of active tools that limits which tools the model can call,
|
|
509
|
+
* without changing the tool call and result types in the result.
|
|
510
|
+
*
|
|
511
|
+
* Per-stream `activeTools` values passed to `stream()` override this default.
|
|
512
|
+
*/
|
|
513
|
+
activeTools?: ActiveTools<NoInfer<TTools>>;
|
|
451
514
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
515
|
+
/**
|
|
516
|
+
* Default output specification for structured outputs.
|
|
517
|
+
* Use `Output.object({ schema })` for structured output or `Output.text()` for text output.
|
|
518
|
+
*
|
|
519
|
+
* Per-stream `output` values passed to `stream()` override this default.
|
|
520
|
+
*/
|
|
521
|
+
output?: OutputSpecification<any, any>;
|
|
459
522
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
523
|
+
/**
|
|
524
|
+
* Default function that attempts to repair a tool call that failed to parse.
|
|
525
|
+
*
|
|
526
|
+
* Per-stream `experimental_repairToolCall` values passed to `stream()` override this default.
|
|
527
|
+
*/
|
|
528
|
+
experimental_repairToolCall?: ToolCallRepairFunction<TTools>;
|
|
466
529
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
530
|
+
/**
|
|
531
|
+
* Default custom download function to use for URLs.
|
|
532
|
+
*
|
|
533
|
+
* Per-stream `experimental_download` values passed to `stream()` override this default.
|
|
534
|
+
*/
|
|
535
|
+
experimental_download?: DownloadFunction;
|
|
473
536
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
537
|
+
/**
|
|
538
|
+
* Default callback function called before each step in the agent loop.
|
|
539
|
+
* Use this to modify settings, manage context, or inject messages dynamically
|
|
540
|
+
* for every stream call on this agent instance.
|
|
541
|
+
*
|
|
542
|
+
* Per-stream `prepareStep` values passed to `stream()` override this default.
|
|
543
|
+
*/
|
|
544
|
+
prepareStep?: PrepareStepCallback<TTools, TRuntimeContext>;
|
|
482
545
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
546
|
+
/**
|
|
547
|
+
* Callback function to be called after each step completes.
|
|
548
|
+
*/
|
|
549
|
+
onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools, TRuntimeContext>;
|
|
487
550
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
551
|
+
/**
|
|
552
|
+
* Callback that is called when the LLM response and all request tool executions are finished.
|
|
553
|
+
*/
|
|
554
|
+
onFinish?: WorkflowAgentOnFinishCallback<TTools, TRuntimeContext>;
|
|
492
555
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
556
|
+
/**
|
|
557
|
+
* Callback called when the agent starts streaming, before any LLM calls.
|
|
558
|
+
*/
|
|
559
|
+
experimental_onStart?: WorkflowAgentOnStartCallback<
|
|
560
|
+
TTools,
|
|
561
|
+
TRuntimeContext
|
|
562
|
+
>;
|
|
497
563
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
564
|
+
/**
|
|
565
|
+
* Callback called before each step (LLM call) begins.
|
|
566
|
+
*/
|
|
567
|
+
experimental_onStepStart?: WorkflowAgentOnStepStartCallback<
|
|
568
|
+
TTools,
|
|
569
|
+
TRuntimeContext
|
|
570
|
+
>;
|
|
502
571
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
572
|
+
/**
|
|
573
|
+
* Callback called before a tool's execute function runs.
|
|
574
|
+
*/
|
|
575
|
+
onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback<TTools>;
|
|
507
576
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
577
|
+
/**
|
|
578
|
+
* Callback called after a tool execution completes.
|
|
579
|
+
*/
|
|
580
|
+
onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback<TTools>;
|
|
512
581
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
582
|
+
/**
|
|
583
|
+
* Prepare the parameters for the stream call.
|
|
584
|
+
* Called once before the agent loop starts. Use this to transform
|
|
585
|
+
* model, tools, instructions, or other settings based on runtime context.
|
|
586
|
+
*/
|
|
587
|
+
prepareCall?: PrepareCallCallback<TTools, TRuntimeContext>;
|
|
588
|
+
};
|
|
520
589
|
|
|
521
590
|
/**
|
|
522
591
|
* Callback that is called when the LLM response and all request tool executions are finished.
|
|
523
592
|
*/
|
|
524
593
|
export type WorkflowAgentOnFinishCallback<
|
|
525
594
|
TTools extends ToolSet = ToolSet,
|
|
595
|
+
TRuntimeContext extends Context = Context,
|
|
526
596
|
OUTPUT = never,
|
|
527
597
|
> = (event: {
|
|
528
598
|
/**
|
|
529
599
|
* Details for all steps.
|
|
530
600
|
*/
|
|
531
|
-
readonly steps: StepResult<TTools,
|
|
601
|
+
readonly steps: StepResult<TTools, TRuntimeContext>[];
|
|
532
602
|
|
|
533
603
|
/**
|
|
534
604
|
* The final messages including all tool calls and results.
|
|
@@ -551,9 +621,14 @@ export type WorkflowAgentOnFinishCallback<
|
|
|
551
621
|
readonly totalUsage: LanguageModelUsage;
|
|
552
622
|
|
|
553
623
|
/**
|
|
554
|
-
*
|
|
624
|
+
* The runtime context at the end of the agent loop.
|
|
555
625
|
*/
|
|
556
|
-
readonly
|
|
626
|
+
readonly runtimeContext: TRuntimeContext;
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* The per-tool context at the end of the agent loop.
|
|
630
|
+
*/
|
|
631
|
+
readonly toolsContext: InferToolSetContext<TTools>;
|
|
557
632
|
|
|
558
633
|
/**
|
|
559
634
|
* The generated structured output. It uses the `output` specification.
|
|
@@ -583,36 +658,57 @@ export type WorkflowAgentOnAbortCallback<TTools extends ToolSet = ToolSet> =
|
|
|
583
658
|
/**
|
|
584
659
|
* Callback that is called when the agent starts streaming, before any LLM calls.
|
|
585
660
|
*/
|
|
586
|
-
export type WorkflowAgentOnStartCallback
|
|
661
|
+
export type WorkflowAgentOnStartCallback<
|
|
662
|
+
TTools extends ToolSet = ToolSet,
|
|
663
|
+
TRuntimeContext extends Context = Context,
|
|
664
|
+
> = (event: {
|
|
587
665
|
/** The model being used */
|
|
588
666
|
readonly model: LanguageModel;
|
|
589
667
|
/** The messages being sent */
|
|
590
668
|
readonly messages: ModelMessage[];
|
|
669
|
+
/** Shared runtime context for this agent loop */
|
|
670
|
+
readonly runtimeContext: TRuntimeContext;
|
|
671
|
+
/** Per-tool context map for this agent loop */
|
|
672
|
+
readonly toolsContext: InferToolSetContext<TTools>;
|
|
591
673
|
}) => PromiseLike<void> | void;
|
|
592
674
|
|
|
593
675
|
/**
|
|
594
676
|
* Callback that is called before each step (LLM call) begins.
|
|
595
677
|
*/
|
|
596
|
-
export type WorkflowAgentOnStepStartCallback<
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
678
|
+
export type WorkflowAgentOnStepStartCallback<
|
|
679
|
+
TTools extends ToolSet = ToolSet,
|
|
680
|
+
TRuntimeContext extends Context = Context,
|
|
681
|
+
> = (event: {
|
|
682
|
+
/** The current step number (0-based) */
|
|
683
|
+
readonly stepNumber: number;
|
|
684
|
+
/** The model being used for this step */
|
|
685
|
+
readonly model: LanguageModel;
|
|
686
|
+
/** The messages being sent for this step */
|
|
687
|
+
readonly messages: ModelMessage[];
|
|
688
|
+
/** Results from all previously finished steps */
|
|
689
|
+
readonly steps: ReadonlyArray<StepResult<TTools, TRuntimeContext>>;
|
|
690
|
+
/** Shared runtime context for this step */
|
|
691
|
+
readonly runtimeContext: TRuntimeContext;
|
|
692
|
+
/** Per-tool context map for this step */
|
|
693
|
+
readonly toolsContext: InferToolSetContext<TTools>;
|
|
694
|
+
}) => PromiseLike<void> | void;
|
|
607
695
|
|
|
608
696
|
/**
|
|
609
697
|
* Callback that is called before a tool's execute function runs.
|
|
610
698
|
*/
|
|
611
|
-
export type WorkflowAgentOnToolExecutionStartCallback
|
|
699
|
+
export type WorkflowAgentOnToolExecutionStartCallback<
|
|
700
|
+
TTools extends ToolSet = ToolSet,
|
|
701
|
+
> = (event: {
|
|
612
702
|
/** The tool call being executed */
|
|
613
703
|
readonly toolCall: ToolCall;
|
|
614
704
|
/** The current step number (0-based) */
|
|
615
705
|
readonly stepNumber: number;
|
|
706
|
+
/** Messages sent to the language model for the step that produced the call */
|
|
707
|
+
readonly messages: ModelMessage[];
|
|
708
|
+
/** Tool-specific context passed to the tool */
|
|
709
|
+
readonly toolContext:
|
|
710
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
711
|
+
| undefined;
|
|
616
712
|
}) => PromiseLike<void> | void;
|
|
617
713
|
|
|
618
714
|
/**
|
|
@@ -620,7 +716,9 @@ export type WorkflowAgentOnToolExecutionStartCallback = (event: {
|
|
|
620
716
|
* Uses a discriminated union pattern: check `success` to determine
|
|
621
717
|
* whether `output` or `error` is available.
|
|
622
718
|
*/
|
|
623
|
-
export type WorkflowAgentOnToolExecutionEndCallback
|
|
719
|
+
export type WorkflowAgentOnToolExecutionEndCallback<
|
|
720
|
+
TTools extends ToolSet = ToolSet,
|
|
721
|
+
> = (
|
|
624
722
|
event:
|
|
625
723
|
| {
|
|
626
724
|
/** The tool call that was executed */
|
|
@@ -629,6 +727,12 @@ export type WorkflowAgentOnToolExecutionEndCallback = (
|
|
|
629
727
|
readonly stepNumber: number;
|
|
630
728
|
/** Execution time in milliseconds */
|
|
631
729
|
readonly durationMs: number;
|
|
730
|
+
/** Messages sent to the language model for the step that produced the call */
|
|
731
|
+
readonly messages: ModelMessage[];
|
|
732
|
+
/** Tool-specific context passed to the tool */
|
|
733
|
+
readonly toolContext:
|
|
734
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
735
|
+
| undefined;
|
|
632
736
|
/** Whether the tool call succeeded */
|
|
633
737
|
readonly success: true;
|
|
634
738
|
/** The tool result */
|
|
@@ -642,6 +746,12 @@ export type WorkflowAgentOnToolExecutionEndCallback = (
|
|
|
642
746
|
readonly stepNumber: number;
|
|
643
747
|
/** Execution time in milliseconds */
|
|
644
748
|
readonly durationMs: number;
|
|
749
|
+
/** Messages sent to the language model for the step that produced the call */
|
|
750
|
+
readonly messages: ModelMessage[];
|
|
751
|
+
/** Tool-specific context passed to the tool */
|
|
752
|
+
readonly toolContext:
|
|
753
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
754
|
+
| undefined;
|
|
645
755
|
/** Whether the tool call succeeded */
|
|
646
756
|
readonly success: false;
|
|
647
757
|
/** The error that occurred */
|
|
@@ -655,6 +765,7 @@ export type WorkflowAgentOnToolExecutionEndCallback = (
|
|
|
655
765
|
*/
|
|
656
766
|
export type WorkflowAgentStreamOptions<
|
|
657
767
|
TTools extends ToolSet = ToolSet,
|
|
768
|
+
TRuntimeContext extends Context = Context,
|
|
658
769
|
OUTPUT = never,
|
|
659
770
|
PARTIAL_OUTPUT = never,
|
|
660
771
|
> = Partial<GenerationSettings> &
|
|
@@ -752,11 +863,29 @@ export type WorkflowAgentStreamOptions<
|
|
|
752
863
|
experimental_telemetry?: TelemetryOptions;
|
|
753
864
|
|
|
754
865
|
/**
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
866
|
+
* Runtime context that flows through the agent loop.
|
|
867
|
+
*
|
|
868
|
+
* Treat as immutable; return a new `runtimeContext` from `prepareStep`
|
|
869
|
+
* to update it between steps.
|
|
870
|
+
*
|
|
871
|
+
* In workflow context, keep values serializable so they can cross workflow
|
|
872
|
+
* and step boundaries.
|
|
873
|
+
*
|
|
874
|
+
* Overrides the constructor-level `runtimeContext` if provided.
|
|
875
|
+
*/
|
|
876
|
+
runtimeContext?: TRuntimeContext;
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Per-tool context, keyed by tool name. Each tool receives only its own
|
|
880
|
+
* validated entry as `context` during execution. Tools that declare a
|
|
881
|
+
* `contextSchema` validate their entry against the schema.
|
|
882
|
+
*
|
|
883
|
+
* In workflow context, keep values serializable so they can cross workflow
|
|
884
|
+
* and step boundaries.
|
|
885
|
+
*
|
|
886
|
+
* Overrides the constructor-level `toolsContext` if provided.
|
|
758
887
|
*/
|
|
759
|
-
|
|
888
|
+
toolsContext?: InferToolSetContext<TTools>;
|
|
760
889
|
|
|
761
890
|
/**
|
|
762
891
|
* Optional specification for parsing structured outputs from the LLM response.
|
|
@@ -814,7 +943,7 @@ export type WorkflowAgentStreamOptions<
|
|
|
814
943
|
/**
|
|
815
944
|
* Callback function to be called after each step completes.
|
|
816
945
|
*/
|
|
817
|
-
onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools>;
|
|
946
|
+
onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools, TRuntimeContext>;
|
|
818
947
|
|
|
819
948
|
/**
|
|
820
949
|
* Callback that is invoked when an error occurs during streaming.
|
|
@@ -826,7 +955,7 @@ export type WorkflowAgentStreamOptions<
|
|
|
826
955
|
* Callback that is called when the LLM response and all request tool executions
|
|
827
956
|
* (for tools that have an `execute` function) are finished.
|
|
828
957
|
*/
|
|
829
|
-
onFinish?: WorkflowAgentOnFinishCallback<TTools, OUTPUT>;
|
|
958
|
+
onFinish?: WorkflowAgentOnFinishCallback<TTools, TRuntimeContext, OUTPUT>;
|
|
830
959
|
|
|
831
960
|
/**
|
|
832
961
|
* Callback that is called when the operation is aborted.
|
|
@@ -836,22 +965,28 @@ export type WorkflowAgentStreamOptions<
|
|
|
836
965
|
/**
|
|
837
966
|
* Callback called when the agent starts streaming, before any LLM calls.
|
|
838
967
|
*/
|
|
839
|
-
experimental_onStart?: WorkflowAgentOnStartCallback
|
|
968
|
+
experimental_onStart?: WorkflowAgentOnStartCallback<
|
|
969
|
+
TTools,
|
|
970
|
+
TRuntimeContext
|
|
971
|
+
>;
|
|
840
972
|
|
|
841
973
|
/**
|
|
842
974
|
* Callback called before each step (LLM call) begins.
|
|
843
975
|
*/
|
|
844
|
-
experimental_onStepStart?: WorkflowAgentOnStepStartCallback
|
|
976
|
+
experimental_onStepStart?: WorkflowAgentOnStepStartCallback<
|
|
977
|
+
TTools,
|
|
978
|
+
TRuntimeContext
|
|
979
|
+
>;
|
|
845
980
|
|
|
846
981
|
/**
|
|
847
982
|
* Callback called before a tool's execute function runs.
|
|
848
983
|
*/
|
|
849
|
-
onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback
|
|
984
|
+
onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback<TTools>;
|
|
850
985
|
|
|
851
986
|
/**
|
|
852
987
|
* Callback called after a tool execution completes.
|
|
853
988
|
*/
|
|
854
|
-
onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback
|
|
989
|
+
onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback<TTools>;
|
|
855
990
|
|
|
856
991
|
/**
|
|
857
992
|
* Callback function called before each step in the agent loop.
|
|
@@ -871,7 +1006,7 @@ export type WorkflowAgentStreamOptions<
|
|
|
871
1006
|
* }
|
|
872
1007
|
* ```
|
|
873
1008
|
*/
|
|
874
|
-
prepareStep?: PrepareStepCallback<TTools>;
|
|
1009
|
+
prepareStep?: PrepareStepCallback<TTools, TRuntimeContext>;
|
|
875
1010
|
|
|
876
1011
|
/**
|
|
877
1012
|
* Timeout in milliseconds for the stream operation.
|
|
@@ -1001,7 +1136,10 @@ export interface WorkflowAgentStreamResult<
|
|
|
1001
1136
|
* });
|
|
1002
1137
|
* ```
|
|
1003
1138
|
*/
|
|
1004
|
-
export class WorkflowAgent<
|
|
1139
|
+
export class WorkflowAgent<
|
|
1140
|
+
TBaseTools extends ToolSet = ToolSet,
|
|
1141
|
+
TRuntimeContext extends Context = Context,
|
|
1142
|
+
> {
|
|
1005
1143
|
/**
|
|
1006
1144
|
* The id of the agent.
|
|
1007
1145
|
*/
|
|
@@ -1019,7 +1157,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1019
1157
|
private generationSettings: GenerationSettings;
|
|
1020
1158
|
private toolChoice?: ToolChoice<TBaseTools>;
|
|
1021
1159
|
private telemetry?: TelemetryOptions;
|
|
1022
|
-
private
|
|
1160
|
+
private runtimeContext?: TRuntimeContext;
|
|
1161
|
+
private toolsContext?: InferToolSetContext<TBaseTools>;
|
|
1023
1162
|
private stopWhen?:
|
|
1024
1163
|
| StopCondition<ToolSet, any>
|
|
1025
1164
|
| Array<StopCondition<ToolSet, any>>;
|
|
@@ -1027,16 +1166,28 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1027
1166
|
private output?: OutputSpecification<any, any>;
|
|
1028
1167
|
private experimentalRepairToolCall?: ToolCallRepairFunction<TBaseTools>;
|
|
1029
1168
|
private experimentalDownload?: DownloadFunction;
|
|
1030
|
-
private prepareStep?: PrepareStepCallback<TBaseTools>;
|
|
1031
|
-
private constructorOnStepFinish?: WorkflowAgentOnStepFinishCallback<
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
private
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1169
|
+
private prepareStep?: PrepareStepCallback<TBaseTools, TRuntimeContext>;
|
|
1170
|
+
private constructorOnStepFinish?: WorkflowAgentOnStepFinishCallback<
|
|
1171
|
+
TBaseTools,
|
|
1172
|
+
TRuntimeContext
|
|
1173
|
+
>;
|
|
1174
|
+
private constructorOnFinish?: WorkflowAgentOnFinishCallback<
|
|
1175
|
+
TBaseTools,
|
|
1176
|
+
TRuntimeContext
|
|
1177
|
+
>;
|
|
1178
|
+
private constructorOnStart?: WorkflowAgentOnStartCallback<
|
|
1179
|
+
TBaseTools,
|
|
1180
|
+
TRuntimeContext
|
|
1181
|
+
>;
|
|
1182
|
+
private constructorOnStepStart?: WorkflowAgentOnStepStartCallback<
|
|
1183
|
+
TBaseTools,
|
|
1184
|
+
TRuntimeContext
|
|
1185
|
+
>;
|
|
1186
|
+
private constructorOnToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback<TBaseTools>;
|
|
1187
|
+
private constructorOnToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback<TBaseTools>;
|
|
1188
|
+
private prepareCall?: PrepareCallCallback<TBaseTools, TRuntimeContext>;
|
|
1189
|
+
|
|
1190
|
+
constructor(options: WorkflowAgentOptions<TBaseTools, TRuntimeContext>) {
|
|
1040
1191
|
this.id = options.id;
|
|
1041
1192
|
this.model = options.model;
|
|
1042
1193
|
this.tools = (options.tools ?? {}) as TBaseTools;
|
|
@@ -1044,7 +1195,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1044
1195
|
this.instructions = options.instructions ?? options.system;
|
|
1045
1196
|
this.toolChoice = options.toolChoice;
|
|
1046
1197
|
this.telemetry = options.telemetry ?? options.experimental_telemetry;
|
|
1047
|
-
this.
|
|
1198
|
+
this.runtimeContext = options.runtimeContext;
|
|
1199
|
+
this.toolsContext = options.toolsContext;
|
|
1048
1200
|
this.stopWhen = options.stopWhen;
|
|
1049
1201
|
this.activeTools = options.activeTools;
|
|
1050
1202
|
this.output = options.output;
|
|
@@ -1085,7 +1237,12 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1085
1237
|
OUTPUT = never,
|
|
1086
1238
|
PARTIAL_OUTPUT = never,
|
|
1087
1239
|
>(
|
|
1088
|
-
options: WorkflowAgentStreamOptions<
|
|
1240
|
+
options: WorkflowAgentStreamOptions<
|
|
1241
|
+
TTools,
|
|
1242
|
+
TRuntimeContext,
|
|
1243
|
+
OUTPUT,
|
|
1244
|
+
PARTIAL_OUTPUT
|
|
1245
|
+
>,
|
|
1089
1246
|
): Promise<WorkflowAgentStreamResult<TTools, OUTPUT>> {
|
|
1090
1247
|
// Call prepareCall to transform parameters before the agent loop
|
|
1091
1248
|
let effectiveModel: LanguageModel = this.model;
|
|
@@ -1094,8 +1251,14 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1094
1251
|
options.prompt;
|
|
1095
1252
|
let effectiveMessages: Array<ModelMessage> | undefined = options.messages;
|
|
1096
1253
|
let effectiveGenerationSettings = { ...this.generationSettings };
|
|
1097
|
-
let
|
|
1098
|
-
|
|
1254
|
+
let effectiveRuntimeContext: TRuntimeContext = (options.runtimeContext ??
|
|
1255
|
+
this.runtimeContext ??
|
|
1256
|
+
{}) as TRuntimeContext;
|
|
1257
|
+
let effectiveToolsContext: Record<string, Context | undefined> =
|
|
1258
|
+
(options.toolsContext ?? this.toolsContext ?? {}) as unknown as Record<
|
|
1259
|
+
string,
|
|
1260
|
+
Context | undefined
|
|
1261
|
+
>;
|
|
1099
1262
|
let effectiveToolChoiceFromPrepare = options.toolChoice ?? this.toolChoice;
|
|
1100
1263
|
let effectiveTelemetryFromPrepare =
|
|
1101
1264
|
options.telemetry ?? options.experimental_telemetry ?? this.telemetry;
|
|
@@ -1116,10 +1279,11 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1116
1279
|
toolChoice: effectiveToolChoiceFromPrepare as ToolChoice<TBaseTools>,
|
|
1117
1280
|
telemetry: effectiveTelemetryFromPrepare,
|
|
1118
1281
|
experimental_telemetry: effectiveTelemetryFromPrepare,
|
|
1119
|
-
|
|
1282
|
+
runtimeContext: effectiveRuntimeContext,
|
|
1283
|
+
toolsContext: effectiveToolsContext as InferToolSetContext<TBaseTools>,
|
|
1120
1284
|
messages: resolvedMessagesForPrepareCall,
|
|
1121
1285
|
...effectiveGenerationSettings,
|
|
1122
|
-
} as PrepareCallOptions<TBaseTools>);
|
|
1286
|
+
} as PrepareCallOptions<TBaseTools, TRuntimeContext>);
|
|
1123
1287
|
|
|
1124
1288
|
if (prepared.model !== undefined) effectiveModel = prepared.model;
|
|
1125
1289
|
if (prepared.instructions !== undefined)
|
|
@@ -1128,8 +1292,13 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1128
1292
|
effectiveMessages = prepared.messages as Array<ModelMessage>;
|
|
1129
1293
|
effectivePrompt = undefined; // messages from prepareCall take precedence
|
|
1130
1294
|
}
|
|
1131
|
-
if (prepared.
|
|
1132
|
-
|
|
1295
|
+
if (prepared.runtimeContext !== undefined)
|
|
1296
|
+
effectiveRuntimeContext = prepared.runtimeContext;
|
|
1297
|
+
if (prepared.toolsContext !== undefined)
|
|
1298
|
+
effectiveToolsContext = prepared.toolsContext as Record<
|
|
1299
|
+
string,
|
|
1300
|
+
Context | undefined
|
|
1301
|
+
>;
|
|
1133
1302
|
if (prepared.toolChoice !== undefined)
|
|
1134
1303
|
effectiveToolChoiceFromPrepare =
|
|
1135
1304
|
prepared.toolChoice as ToolChoice<TBaseTools>;
|
|
@@ -1193,10 +1362,15 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1193
1362
|
if (tool && typeof tool.execute === 'function') {
|
|
1194
1363
|
try {
|
|
1195
1364
|
const { execute } = tool;
|
|
1365
|
+
const resolvedContext = await resolveToolContext({
|
|
1366
|
+
toolName: approval.toolName,
|
|
1367
|
+
tool,
|
|
1368
|
+
toolsContext: effectiveToolsContext,
|
|
1369
|
+
});
|
|
1196
1370
|
const toolResult = await execute(approval.input, {
|
|
1197
1371
|
toolCallId: approval.toolCallId,
|
|
1198
1372
|
messages: [],
|
|
1199
|
-
context:
|
|
1373
|
+
context: resolvedContext,
|
|
1200
1374
|
});
|
|
1201
1375
|
toolResultContent.push({
|
|
1202
1376
|
type: 'tool-result' as const,
|
|
@@ -1338,22 +1512,26 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1338
1512
|
// Merge constructor + stream callbacks (constructor first, then stream)
|
|
1339
1513
|
const mergedOnStepFinish = mergeCallbacks(
|
|
1340
1514
|
this.constructorOnStepFinish as
|
|
1341
|
-
| WorkflowAgentOnStepFinishCallback<TTools>
|
|
1515
|
+
| WorkflowAgentOnStepFinishCallback<TTools, TRuntimeContext>
|
|
1342
1516
|
| undefined,
|
|
1343
1517
|
options.onStepFinish,
|
|
1344
1518
|
);
|
|
1345
1519
|
const mergedOnFinish = mergeCallbacks(
|
|
1346
1520
|
this.constructorOnFinish as
|
|
1347
|
-
| WorkflowAgentOnFinishCallback<TTools, OUTPUT>
|
|
1521
|
+
| WorkflowAgentOnFinishCallback<TTools, TRuntimeContext, OUTPUT>
|
|
1348
1522
|
| undefined,
|
|
1349
1523
|
options.onFinish,
|
|
1350
1524
|
);
|
|
1351
1525
|
const mergedOnStart = mergeCallbacks(
|
|
1352
|
-
this.constructorOnStart
|
|
1526
|
+
this.constructorOnStart as
|
|
1527
|
+
| WorkflowAgentOnStartCallback<TTools, TRuntimeContext>
|
|
1528
|
+
| undefined,
|
|
1353
1529
|
options.experimental_onStart,
|
|
1354
1530
|
);
|
|
1355
1531
|
const mergedOnStepStart = mergeCallbacks(
|
|
1356
|
-
this.constructorOnStepStart
|
|
1532
|
+
this.constructorOnStepStart as
|
|
1533
|
+
| WorkflowAgentOnStepStartCallback<TTools, TRuntimeContext>
|
|
1534
|
+
| undefined,
|
|
1357
1535
|
options.experimental_onStepStart,
|
|
1358
1536
|
);
|
|
1359
1537
|
const mergedOnToolExecutionStart = mergeCallbacks(
|
|
@@ -1382,9 +1560,11 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1382
1560
|
: this.tools;
|
|
1383
1561
|
|
|
1384
1562
|
// Initialize context
|
|
1385
|
-
let
|
|
1563
|
+
let runtimeContext: TRuntimeContext = effectiveRuntimeContext;
|
|
1564
|
+
let toolsContext: Record<string, Context | undefined> =
|
|
1565
|
+
effectiveToolsContext;
|
|
1386
1566
|
|
|
1387
|
-
const steps: StepResult<TTools,
|
|
1567
|
+
const steps: StepResult<TTools, TRuntimeContext>[] = [];
|
|
1388
1568
|
|
|
1389
1569
|
// Track tool calls and results from the last step for the result
|
|
1390
1570
|
let lastStepToolCalls: ToolCall[] = [];
|
|
@@ -1395,6 +1575,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1395
1575
|
await mergedOnStart({
|
|
1396
1576
|
model: effectiveModel,
|
|
1397
1577
|
messages: prompt.messages,
|
|
1578
|
+
runtimeContext,
|
|
1579
|
+
toolsContext: toolsContext as unknown as InferToolSetContext<TTools>,
|
|
1398
1580
|
});
|
|
1399
1581
|
}
|
|
1400
1582
|
|
|
@@ -1403,7 +1585,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1403
1585
|
toolCall: { toolCallId: string; toolName: string; input: unknown },
|
|
1404
1586
|
tools: ToolSet,
|
|
1405
1587
|
messages: LanguageModelV4Prompt,
|
|
1406
|
-
|
|
1588
|
+
perToolContexts: Record<string, Context | undefined>,
|
|
1407
1589
|
currentStepNumber: number = 0,
|
|
1408
1590
|
): Promise<LanguageModelV4ToolResultPart> => {
|
|
1409
1591
|
const toolCallEvent: ToolCall = {
|
|
@@ -1413,17 +1595,31 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1413
1595
|
input: toolCall.input,
|
|
1414
1596
|
};
|
|
1415
1597
|
|
|
1598
|
+
const tool = tools[toolCall.toolName];
|
|
1599
|
+
const resolvedContext = tool
|
|
1600
|
+
? await resolveToolContext({
|
|
1601
|
+
toolName: toolCall.toolName,
|
|
1602
|
+
tool,
|
|
1603
|
+
toolsContext: perToolContexts,
|
|
1604
|
+
})
|
|
1605
|
+
: undefined;
|
|
1606
|
+
const modelMessages = getToolCallbackMessages(messages);
|
|
1607
|
+
|
|
1416
1608
|
if (mergedOnToolExecutionStart) {
|
|
1417
1609
|
await mergedOnToolExecutionStart({
|
|
1418
1610
|
toolCall: toolCallEvent,
|
|
1419
1611
|
stepNumber: currentStepNumber,
|
|
1612
|
+
messages: modelMessages,
|
|
1613
|
+
toolContext: resolvedContext as
|
|
1614
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
1615
|
+
| undefined,
|
|
1420
1616
|
});
|
|
1421
1617
|
}
|
|
1422
1618
|
|
|
1423
1619
|
const startTime = Date.now();
|
|
1424
1620
|
let result: LanguageModelV4ToolResultPart;
|
|
1425
1621
|
try {
|
|
1426
|
-
result = await executeTool(toolCall, tools, messages,
|
|
1622
|
+
result = await executeTool(toolCall, tools, messages, resolvedContext);
|
|
1427
1623
|
} catch (err) {
|
|
1428
1624
|
const durationMs = Date.now() - startTime;
|
|
1429
1625
|
if (mergedOnToolExecutionEnd) {
|
|
@@ -1431,6 +1627,10 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1431
1627
|
toolCall: toolCallEvent,
|
|
1432
1628
|
stepNumber: currentStepNumber,
|
|
1433
1629
|
durationMs,
|
|
1630
|
+
messages: modelMessages,
|
|
1631
|
+
toolContext: resolvedContext as
|
|
1632
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
1633
|
+
| undefined,
|
|
1434
1634
|
success: false,
|
|
1435
1635
|
error: err,
|
|
1436
1636
|
});
|
|
@@ -1450,6 +1650,10 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1450
1650
|
toolCall: toolCallEvent,
|
|
1451
1651
|
stepNumber: currentStepNumber,
|
|
1452
1652
|
durationMs,
|
|
1653
|
+
messages: modelMessages,
|
|
1654
|
+
toolContext: resolvedContext as
|
|
1655
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
1656
|
+
| undefined,
|
|
1453
1657
|
success: false,
|
|
1454
1658
|
error: 'value' in result.output ? result.output.value : undefined,
|
|
1455
1659
|
});
|
|
@@ -1458,6 +1662,10 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1458
1662
|
toolCall: toolCallEvent,
|
|
1459
1663
|
stepNumber: currentStepNumber,
|
|
1460
1664
|
durationMs,
|
|
1665
|
+
messages: modelMessages,
|
|
1666
|
+
toolContext: resolvedContext as
|
|
1667
|
+
| InferToolSetContext<TTools>[keyof InferToolSetContext<TTools>]
|
|
1668
|
+
| undefined,
|
|
1461
1669
|
success: true,
|
|
1462
1670
|
output:
|
|
1463
1671
|
result.output && 'value' in result.output
|
|
@@ -1490,15 +1698,17 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1490
1698
|
prompt: modelPrompt,
|
|
1491
1699
|
stopConditions: options.stopWhen ?? this.stopWhen,
|
|
1492
1700
|
|
|
1493
|
-
onStepFinish: mergedOnStepFinish,
|
|
1494
|
-
onStepStart: mergedOnStepStart,
|
|
1701
|
+
onStepFinish: mergedOnStepFinish as any,
|
|
1702
|
+
onStepStart: mergedOnStepStart as any,
|
|
1495
1703
|
onError: options.onError,
|
|
1496
|
-
prepareStep:
|
|
1497
|
-
|
|
1498
|
-
|
|
1704
|
+
prepareStep: (options.prepareStep ??
|
|
1705
|
+
(this.prepareStep as
|
|
1706
|
+
| PrepareStepCallback<ToolSet, TRuntimeContext>
|
|
1707
|
+
| undefined)) as any,
|
|
1499
1708
|
generationSettings: mergedGenerationSettings,
|
|
1500
1709
|
toolChoice: effectiveToolChoice as ToolChoice<ToolSet>,
|
|
1501
|
-
|
|
1710
|
+
runtimeContext,
|
|
1711
|
+
toolsContext,
|
|
1502
1712
|
telemetry: effectiveTelemetry,
|
|
1503
1713
|
includeRawChunks: options.includeRawChunks ?? false,
|
|
1504
1714
|
repairToolCall: (options.experimental_repairToolCall ??
|
|
@@ -1529,16 +1739,20 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1529
1739
|
toolCalls,
|
|
1530
1740
|
messages: iterMessages,
|
|
1531
1741
|
step,
|
|
1532
|
-
|
|
1742
|
+
runtimeContext: yieldedRuntimeContext,
|
|
1743
|
+
toolsContext: yieldedToolsContext,
|
|
1533
1744
|
providerExecutedToolResults,
|
|
1534
1745
|
} = result.value;
|
|
1535
1746
|
// Capture current step number before pushing (0-based)
|
|
1536
1747
|
const currentStepNumber = steps.length;
|
|
1537
1748
|
if (step) {
|
|
1538
|
-
steps.push(step as unknown as StepResult<TTools,
|
|
1749
|
+
steps.push(step as unknown as StepResult<TTools, TRuntimeContext>);
|
|
1750
|
+
}
|
|
1751
|
+
if (yieldedRuntimeContext !== undefined) {
|
|
1752
|
+
runtimeContext = yieldedRuntimeContext as TRuntimeContext;
|
|
1539
1753
|
}
|
|
1540
|
-
if (
|
|
1541
|
-
|
|
1754
|
+
if (yieldedToolsContext !== undefined) {
|
|
1755
|
+
toolsContext = yieldedToolsContext;
|
|
1542
1756
|
}
|
|
1543
1757
|
|
|
1544
1758
|
// Only execute tools if there are tool calls
|
|
@@ -1562,10 +1776,16 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1562
1776
|
if (tool.needsApproval == null) return false;
|
|
1563
1777
|
if (typeof tool.needsApproval === 'boolean')
|
|
1564
1778
|
return tool.needsApproval;
|
|
1779
|
+
const resolvedContext = await resolveToolContext({
|
|
1780
|
+
toolName: tc.toolName,
|
|
1781
|
+
tool,
|
|
1782
|
+
toolsContext:
|
|
1783
|
+
toolsContext as unknown as InferToolSetContext<TTools>,
|
|
1784
|
+
});
|
|
1565
1785
|
return tool.needsApproval(tc.input, {
|
|
1566
1786
|
toolCallId: tc.toolCallId,
|
|
1567
1787
|
messages: iterMessages as unknown as ModelMessage[],
|
|
1568
|
-
context:
|
|
1788
|
+
context: resolvedContext,
|
|
1569
1789
|
});
|
|
1570
1790
|
}),
|
|
1571
1791
|
);
|
|
@@ -1601,7 +1821,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1601
1821
|
toolCall,
|
|
1602
1822
|
effectiveTools as ToolSet,
|
|
1603
1823
|
iterMessages,
|
|
1604
|
-
|
|
1824
|
+
toolsContext,
|
|
1605
1825
|
currentStepNumber,
|
|
1606
1826
|
),
|
|
1607
1827
|
),
|
|
@@ -1659,7 +1879,9 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1659
1879
|
text: lastStep?.text ?? '',
|
|
1660
1880
|
finishReason: lastStep?.finishReason ?? 'other',
|
|
1661
1881
|
totalUsage: aggregateUsage(steps),
|
|
1662
|
-
|
|
1882
|
+
runtimeContext,
|
|
1883
|
+
toolsContext:
|
|
1884
|
+
toolsContext as unknown as InferToolSetContext<TTools>,
|
|
1663
1885
|
output: undefined as OUTPUT,
|
|
1664
1886
|
});
|
|
1665
1887
|
}
|
|
@@ -1710,7 +1932,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1710
1932
|
toolCall,
|
|
1711
1933
|
effectiveTools as ToolSet,
|
|
1712
1934
|
iterMessages,
|
|
1713
|
-
|
|
1935
|
+
toolsContext,
|
|
1714
1936
|
currentStepNumber,
|
|
1715
1937
|
),
|
|
1716
1938
|
),
|
|
@@ -1846,7 +2068,8 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
|
|
|
1846
2068
|
text: lastStep?.text ?? '',
|
|
1847
2069
|
finishReason: lastStep?.finishReason ?? 'other',
|
|
1848
2070
|
totalUsage: aggregateUsage(steps),
|
|
1849
|
-
|
|
2071
|
+
runtimeContext,
|
|
2072
|
+
toolsContext: toolsContext as unknown as InferToolSetContext<TTools>,
|
|
1850
2073
|
output: experimentalOutput,
|
|
1851
2074
|
});
|
|
1852
2075
|
}
|
|
@@ -2003,6 +2226,33 @@ async function writeApprovalToolResults(
|
|
|
2003
2226
|
}
|
|
2004
2227
|
}
|
|
2005
2228
|
|
|
2229
|
+
/**
|
|
2230
|
+
* Resolve the per-tool context that gets passed into a tool's `execute`
|
|
2231
|
+
* (and `needsApproval`) function. When the tool declares a `contextSchema`,
|
|
2232
|
+
* the entry is validated against it.
|
|
2233
|
+
*/
|
|
2234
|
+
async function resolveToolContext({
|
|
2235
|
+
toolName,
|
|
2236
|
+
tool,
|
|
2237
|
+
toolsContext,
|
|
2238
|
+
}: {
|
|
2239
|
+
toolName: string;
|
|
2240
|
+
tool: ToolSet[string];
|
|
2241
|
+
toolsContext: Record<string, Context | undefined> | undefined;
|
|
2242
|
+
}): Promise<unknown> {
|
|
2243
|
+
const contextSchema = (tool as { contextSchema?: unknown }).contextSchema;
|
|
2244
|
+
const entry = toolsContext?.[toolName];
|
|
2245
|
+
if (contextSchema == null) {
|
|
2246
|
+
return entry;
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
return await validateTypes({
|
|
2250
|
+
value: entry,
|
|
2251
|
+
schema: contextSchema as Parameters<typeof validateTypes>[0]['schema'],
|
|
2252
|
+
context: { field: 'tool context', entityName: toolName },
|
|
2253
|
+
});
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2006
2256
|
function aggregateUsage(steps: StepResult<any, any>[]): LanguageModelUsage {
|
|
2007
2257
|
let inputTokens = 0;
|
|
2008
2258
|
let outputTokens = 0;
|
|
@@ -2097,11 +2347,19 @@ function createInvalidToolResult(toolCall: {
|
|
|
2097
2347
|
};
|
|
2098
2348
|
}
|
|
2099
2349
|
|
|
2350
|
+
function getToolCallbackMessages(
|
|
2351
|
+
messages: LanguageModelV4Prompt,
|
|
2352
|
+
): ModelMessage[] {
|
|
2353
|
+
const withoutAssistantToolCall =
|
|
2354
|
+
messages.at(-1)?.role === 'assistant' ? messages.slice(0, -1) : messages;
|
|
2355
|
+
return withoutAssistantToolCall as unknown as ModelMessage[];
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2100
2358
|
async function executeTool(
|
|
2101
2359
|
toolCall: { toolCallId: string; toolName: string; input: unknown },
|
|
2102
2360
|
tools: ToolSet,
|
|
2103
2361
|
messages: LanguageModelV4Prompt,
|
|
2104
|
-
|
|
2362
|
+
context?: unknown,
|
|
2105
2363
|
): Promise<LanguageModelV4ToolResultPart> {
|
|
2106
2364
|
const tool = tools[toolCall.toolName];
|
|
2107
2365
|
if (!tool) throw new Error(`Tool "${toolCall.toolName}" not found`);
|
|
@@ -2125,8 +2383,8 @@ async function executeTool(
|
|
|
2125
2383
|
toolCallId: toolCall.toolCallId,
|
|
2126
2384
|
// Pass the conversation messages to the tool so it has context about the conversation
|
|
2127
2385
|
messages,
|
|
2128
|
-
// Pass context to the tool
|
|
2129
|
-
context
|
|
2386
|
+
// Pass per-tool context to the tool (resolved from `toolsContext`)
|
|
2387
|
+
context,
|
|
2130
2388
|
});
|
|
2131
2389
|
|
|
2132
2390
|
// Use the appropriate output type based on the result
|