ai 6.0.237 → 6.0.238
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 +12 -0
- package/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +144 -117
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +144 -117
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/03-agents/02-building-agents.mdx +4 -0
- package/docs/03-agents/04-loop-control.mdx +40 -0
- package/docs/03-ai-sdk-core/60-telemetry.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +61 -3
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +57 -1
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +1 -1
- package/package.json +3 -3
- package/src/generate-text/generate-text-result.ts +3 -1
- package/src/generate-text/generate-text.ts +17 -9
- package/src/generate-text/prepare-step-call-settings.ts +30 -0
- package/src/generate-text/prepare-step.ts +20 -3
- package/src/generate-text/step-result.ts +2 -1
- package/src/generate-text/stream-text.ts +26 -10
package/dist/internal/index.js
CHANGED
|
@@ -164,7 +164,7 @@ function detectMediaType({
|
|
|
164
164
|
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
165
165
|
|
|
166
166
|
// src/version.ts
|
|
167
|
-
var VERSION = true ? "6.0.
|
|
167
|
+
var VERSION = true ? "6.0.238" : "0.0.0-test";
|
|
168
168
|
|
|
169
169
|
// src/util/download/download.ts
|
|
170
170
|
var download = async ({
|
package/dist/internal/index.mjs
CHANGED
|
@@ -117,6 +117,10 @@ const agent = new ToolLoopAgent({
|
|
|
117
117
|
|
|
118
118
|
Learn more about [loop control and stop conditions](/docs/agents/loop-control).
|
|
119
119
|
|
|
120
|
+
Model call settings returned from `prepareStep`, such as `temperature`, apply
|
|
121
|
+
only to the current step. Later steps use the agent's top-level setting unless
|
|
122
|
+
they return another override.
|
|
123
|
+
|
|
120
124
|
### Tool Choice
|
|
121
125
|
|
|
122
126
|
Control how the agent uses tools:
|
|
@@ -178,6 +178,46 @@ const result = await agent.generate({
|
|
|
178
178
|
});
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
+
### Model Call Settings
|
|
182
|
+
|
|
183
|
+
Override provider-agnostic model call settings for an individual step. This can
|
|
184
|
+
be useful when tool-calling steps need more deterministic sampling than the
|
|
185
|
+
final response:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { ToolLoopAgent } from 'ai';
|
|
189
|
+
__PROVIDER_IMPORT__;
|
|
190
|
+
|
|
191
|
+
const agent = new ToolLoopAgent({
|
|
192
|
+
model: __MODEL__,
|
|
193
|
+
temperature: 0.7,
|
|
194
|
+
tools: {
|
|
195
|
+
// your tools
|
|
196
|
+
},
|
|
197
|
+
prepareStep: async ({ stepNumber }) => {
|
|
198
|
+
if (stepNumber === 0) {
|
|
199
|
+
return {
|
|
200
|
+
temperature: 0,
|
|
201
|
+
maxOutputTokens: 300,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {};
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const result = await agent.generate({
|
|
210
|
+
prompt: '...',
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`prepareStep` can override `maxOutputTokens`, `temperature`, `topP`, `topK`,
|
|
215
|
+
`presencePenalty`, `frequencyPenalty`, `stopSequences`, and `seed`. These
|
|
216
|
+
overrides apply only to the current step. When a setting is omitted or
|
|
217
|
+
`undefined`, the top-level value is used for that step. Defined falsy values
|
|
218
|
+
such as `temperature: 0`, `seed: 0`, and an empty `stopSequences` array are
|
|
219
|
+
preserved.
|
|
220
|
+
|
|
181
221
|
### Context Management
|
|
182
222
|
|
|
183
223
|
Manage growing conversation history in long-running loops:
|
|
@@ -197,7 +197,7 @@ The event types for each method are the same as the corresponding [event callbac
|
|
|
197
197
|
|
|
198
198
|
`generateText` records 3 types of spans:
|
|
199
199
|
|
|
200
|
-
- `ai.generateText` (span): the full length of the generateText call. It
|
|
200
|
+
- `ai.generateText` (span): the full length of the generateText call. It is the direct parent of 1 or more `ai.generateText.doGenerate` spans and any `ai.toolCall` spans recorded for the call.
|
|
201
201
|
It contains the [basic LLM span information](#basic-llm-span-information) and the following attributes:
|
|
202
202
|
|
|
203
203
|
- `operation.name`: `ai.generateText` and the functionId that was set through `telemetry.functionId`
|
|
@@ -208,7 +208,7 @@ The event types for each method are the same as the corresponding [event callbac
|
|
|
208
208
|
- `ai.response.finishReason`: the reason why the generation finished
|
|
209
209
|
- `ai.settings.maxOutputTokens`: the maximum number of output tokens that were set
|
|
210
210
|
|
|
211
|
-
- `ai.generateText.doGenerate` (span): a provider doGenerate call.
|
|
211
|
+
- `ai.generateText.doGenerate` (span): a provider doGenerate call.
|
|
212
212
|
It contains the [call LLM span information](#call-llm-span-information) and the following attributes:
|
|
213
213
|
|
|
214
214
|
- `operation.name`: `ai.generateText.doGenerate` and the functionId that was set through `telemetry.functionId`
|
|
@@ -229,7 +229,7 @@ The event types for each method are the same as the corresponding [event callbac
|
|
|
229
229
|
|
|
230
230
|
`streamText` records 3 types of spans and 2 types of events:
|
|
231
231
|
|
|
232
|
-
- `ai.streamText` (span): the full length of the streamText call. It
|
|
232
|
+
- `ai.streamText` (span): the full length of the streamText call. It is the direct parent of 1 or more `ai.streamText.doStream` spans and any `ai.toolCall` spans recorded for the call.
|
|
233
233
|
It contains the [basic LLM span information](#basic-llm-span-information) and the following attributes:
|
|
234
234
|
|
|
235
235
|
- `operation.name`: `ai.streamText` and the functionId that was set through `telemetry.functionId`
|
|
@@ -241,7 +241,7 @@ The event types for each method are the same as the corresponding [event callbac
|
|
|
241
241
|
- `ai.settings.maxOutputTokens`: the maximum number of output tokens that were set
|
|
242
242
|
|
|
243
243
|
- `ai.streamText.doStream` (span): a provider doStream call.
|
|
244
|
-
This span
|
|
244
|
+
This span can contain `ai.stream.firstChunk` and `ai.stream.finish` events.
|
|
245
245
|
It contains the [call LLM span information](#call-llm-span-information) and the following attributes:
|
|
246
246
|
|
|
247
247
|
- `operation.name`: `ai.streamText.doStream` and the functionId that was set through `telemetry.functionId`
|
|
@@ -530,7 +530,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
530
530
|
type: '(options: PrepareStepOptions) => PrepareStepResult<TOOLS> | Promise<PrepareStepResult<TOOLS>>',
|
|
531
531
|
isOptional: true,
|
|
532
532
|
description:
|
|
533
|
-
'Optional function that you can use to provide different settings for a step. You can modify the model, tool choices, active tools, system prompt, and input messages for each step.',
|
|
533
|
+
'Optional function that you can use to provide different settings for a step. You can modify the model, model call settings, tool choices, active tools, system prompt, and input messages for each step.',
|
|
534
534
|
properties: [
|
|
535
535
|
{
|
|
536
536
|
type: 'PrepareStepFunction<TOOLS>',
|
|
@@ -590,6 +590,62 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
590
590
|
description:
|
|
591
591
|
'Optionally override which LanguageModel instance is used for this step.',
|
|
592
592
|
},
|
|
593
|
+
{
|
|
594
|
+
name: 'maxOutputTokens',
|
|
595
|
+
type: 'number',
|
|
596
|
+
isOptional: true,
|
|
597
|
+
description:
|
|
598
|
+
'Maximum number of tokens to generate for this step. Uses the top-level value when omitted or undefined.',
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
name: 'temperature',
|
|
602
|
+
type: 'number',
|
|
603
|
+
isOptional: true,
|
|
604
|
+
description:
|
|
605
|
+
'Temperature for this step. Uses the top-level value when omitted or undefined.',
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
name: 'topP',
|
|
609
|
+
type: 'number',
|
|
610
|
+
isOptional: true,
|
|
611
|
+
description:
|
|
612
|
+
'Nucleus sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
name: 'topK',
|
|
616
|
+
type: 'number',
|
|
617
|
+
isOptional: true,
|
|
618
|
+
description:
|
|
619
|
+
'Top-K sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
name: 'presencePenalty',
|
|
623
|
+
type: 'number',
|
|
624
|
+
isOptional: true,
|
|
625
|
+
description:
|
|
626
|
+
'Presence penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
name: 'frequencyPenalty',
|
|
630
|
+
type: 'number',
|
|
631
|
+
isOptional: true,
|
|
632
|
+
description:
|
|
633
|
+
'Frequency penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
name: 'stopSequences',
|
|
637
|
+
type: 'string[]',
|
|
638
|
+
isOptional: true,
|
|
639
|
+
description:
|
|
640
|
+
'Stop sequences for this step. Uses the top-level value when omitted or undefined.',
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
name: 'seed',
|
|
644
|
+
type: 'number',
|
|
645
|
+
isOptional: true,
|
|
646
|
+
description:
|
|
647
|
+
'Random sampling seed for this step. Uses the top-level value when omitted or undefined.',
|
|
648
|
+
},
|
|
593
649
|
{
|
|
594
650
|
name: 'toolChoice',
|
|
595
651
|
type: 'ToolChoice<TOOLS>',
|
|
@@ -1977,7 +2033,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
1977
2033
|
{
|
|
1978
2034
|
name: 'text',
|
|
1979
2035
|
type: 'string',
|
|
1980
|
-
description:
|
|
2036
|
+
description:
|
|
2037
|
+
'The concatenation of all text parts generated in the final step. It is an empty string if the final step contains no text parts. Inspect `content` for a text part to distinguish that case.',
|
|
1981
2038
|
},
|
|
1982
2039
|
{
|
|
1983
2040
|
name: 'reasoning',
|
|
@@ -2388,7 +2445,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
2388
2445
|
{
|
|
2389
2446
|
name: 'text',
|
|
2390
2447
|
type: 'string',
|
|
2391
|
-
description:
|
|
2448
|
+
description:
|
|
2449
|
+
'The concatenation of all text parts generated in this step. It is an empty string if the step contains no text parts.',
|
|
2392
2450
|
},
|
|
2393
2451
|
{
|
|
2394
2452
|
name: 'reasoning',
|
|
@@ -574,7 +574,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
574
574
|
type: '(options: PrepareStepOptions) => PrepareStepResult<TOOLS> | Promise<PrepareStepResult<TOOLS>>',
|
|
575
575
|
isOptional: true,
|
|
576
576
|
description:
|
|
577
|
-
'Optional function that you can use to provide different settings for a step. You can modify the model, tool choices, active tools, system prompt, and input messages for each step.',
|
|
577
|
+
'Optional function that you can use to provide different settings for a step. You can modify the model, model call settings, tool choices, active tools, system prompt, and input messages for each step.',
|
|
578
578
|
properties: [
|
|
579
579
|
{
|
|
580
580
|
type: 'PrepareStepFunction<TOOLS>',
|
|
@@ -634,6 +634,62 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
634
634
|
description:
|
|
635
635
|
'Optionally override which LanguageModel instance is used for this step.',
|
|
636
636
|
},
|
|
637
|
+
{
|
|
638
|
+
name: 'maxOutputTokens',
|
|
639
|
+
type: 'number',
|
|
640
|
+
isOptional: true,
|
|
641
|
+
description:
|
|
642
|
+
'Maximum number of tokens to generate for this step. Uses the top-level value when omitted or undefined.',
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
name: 'temperature',
|
|
646
|
+
type: 'number',
|
|
647
|
+
isOptional: true,
|
|
648
|
+
description:
|
|
649
|
+
'Temperature for this step. Uses the top-level value when omitted or undefined.',
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: 'topP',
|
|
653
|
+
type: 'number',
|
|
654
|
+
isOptional: true,
|
|
655
|
+
description:
|
|
656
|
+
'Nucleus sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: 'topK',
|
|
660
|
+
type: 'number',
|
|
661
|
+
isOptional: true,
|
|
662
|
+
description:
|
|
663
|
+
'Top-K sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: 'presencePenalty',
|
|
667
|
+
type: 'number',
|
|
668
|
+
isOptional: true,
|
|
669
|
+
description:
|
|
670
|
+
'Presence penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
name: 'frequencyPenalty',
|
|
674
|
+
type: 'number',
|
|
675
|
+
isOptional: true,
|
|
676
|
+
description:
|
|
677
|
+
'Frequency penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: 'stopSequences',
|
|
681
|
+
type: 'string[]',
|
|
682
|
+
isOptional: true,
|
|
683
|
+
description:
|
|
684
|
+
'Stop sequences for this step. Uses the top-level value when omitted or undefined.',
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
name: 'seed',
|
|
688
|
+
type: 'number',
|
|
689
|
+
isOptional: true,
|
|
690
|
+
description:
|
|
691
|
+
'Random sampling seed for this step. Uses the top-level value when omitted or undefined.',
|
|
692
|
+
},
|
|
637
693
|
{
|
|
638
694
|
name: 'toolChoice',
|
|
639
695
|
type: 'ToolChoice<TOOLS>',
|
|
@@ -102,7 +102,7 @@ To see `ToolLoopAgent` in action, check out [these examples](#examples).
|
|
|
102
102
|
type: 'PrepareStepFunction',
|
|
103
103
|
isOptional: true,
|
|
104
104
|
description:
|
|
105
|
-
'Optional function to mutate step settings or inject state for each agent step.',
|
|
105
|
+
'Optional function to mutate step settings or inject state for each agent step, including per-step model call settings such as temperature, maxOutputTokens, sampling controls, penalties, stop sequences, and seed. Model call setting overrides apply only to the current step.',
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
name: 'experimental_repairToolCall',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.238",
|
|
4
4
|
"description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@opentelemetry/api": "^1.9.0",
|
|
48
|
-
"@ai-sdk/gateway": "3.0.
|
|
48
|
+
"@ai-sdk/gateway": "3.0.160",
|
|
49
49
|
"@ai-sdk/provider": "3.0.14",
|
|
50
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
50
|
+
"@ai-sdk/provider-utils": "4.0.41"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -36,7 +36,9 @@ export interface GenerateTextResult<
|
|
|
36
36
|
readonly content: Array<ContentPart<TOOLS>>;
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* The text
|
|
39
|
+
* The concatenation of all text parts generated in the final step.
|
|
40
|
+
* It is an empty string if the final step contains no text parts.
|
|
41
|
+
* Inspect `content` for a text part to distinguish that case.
|
|
40
42
|
*/
|
|
41
43
|
readonly text: string;
|
|
42
44
|
|
|
@@ -77,6 +77,7 @@ import { text, type Output } from './output';
|
|
|
77
77
|
import type { InferCompleteOutput } from './output-utils';
|
|
78
78
|
import { parseToolCall } from './parse-tool-call';
|
|
79
79
|
import type { PrepareStepFunction } from './prepare-step';
|
|
80
|
+
import { prepareStepCallSettings } from './prepare-step-call-settings';
|
|
80
81
|
import type { ResponseMessage } from './response-message';
|
|
81
82
|
import { DefaultStepResult, type StepResult } from './step-result';
|
|
82
83
|
import {
|
|
@@ -752,6 +753,11 @@ export async function generateText<
|
|
|
752
753
|
prepareStepResult?.providerOptions,
|
|
753
754
|
);
|
|
754
755
|
|
|
756
|
+
const stepCallSettings = prepareStepCallSettings({
|
|
757
|
+
callSettings,
|
|
758
|
+
stepSettings: prepareStepResult,
|
|
759
|
+
});
|
|
760
|
+
|
|
755
761
|
await notify({
|
|
756
762
|
event: {
|
|
757
763
|
stepNumber: steps.length,
|
|
@@ -816,20 +822,22 @@ export async function generateText<
|
|
|
816
822
|
'gen_ai.system': stepModel.provider,
|
|
817
823
|
'gen_ai.request.model': stepModel.modelId,
|
|
818
824
|
'gen_ai.request.frequency_penalty':
|
|
819
|
-
|
|
820
|
-
'gen_ai.request.max_tokens':
|
|
821
|
-
|
|
822
|
-
'gen_ai.request.
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
'gen_ai.request.
|
|
825
|
+
stepCallSettings.frequencyPenalty,
|
|
826
|
+
'gen_ai.request.max_tokens':
|
|
827
|
+
stepCallSettings.maxOutputTokens,
|
|
828
|
+
'gen_ai.request.presence_penalty':
|
|
829
|
+
stepCallSettings.presencePenalty,
|
|
830
|
+
'gen_ai.request.stop_sequences':
|
|
831
|
+
stepCallSettings.stopSequences,
|
|
832
|
+
'gen_ai.request.temperature': stepCallSettings.temperature,
|
|
833
|
+
'gen_ai.request.top_k': stepCallSettings.topK,
|
|
834
|
+
'gen_ai.request.top_p': stepCallSettings.topP,
|
|
827
835
|
},
|
|
828
836
|
}),
|
|
829
837
|
tracer,
|
|
830
838
|
fn: async span => {
|
|
831
839
|
const result = await stepModel.doGenerate({
|
|
832
|
-
...
|
|
840
|
+
...stepCallSettings,
|
|
833
841
|
tools: stepTools,
|
|
834
842
|
toolChoice: stepToolChoice,
|
|
835
843
|
responseFormat: await output?.responseFormat,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { prepareCallSettings } from '../prompt/prepare-call-settings';
|
|
2
|
+
import type { PrepareStepCallSettings } from './prepare-step';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolves model call settings for a single step.
|
|
6
|
+
*
|
|
7
|
+
* Undefined step settings intentionally fall back to the outer call settings,
|
|
8
|
+
* while defined falsy values such as `temperature: 0` and `seed: 0` are kept.
|
|
9
|
+
*/
|
|
10
|
+
export function prepareStepCallSettings({
|
|
11
|
+
callSettings,
|
|
12
|
+
stepSettings,
|
|
13
|
+
}: {
|
|
14
|
+
callSettings: PrepareStepCallSettings;
|
|
15
|
+
stepSettings: PrepareStepCallSettings | undefined;
|
|
16
|
+
}): PrepareStepCallSettings {
|
|
17
|
+
return prepareCallSettings({
|
|
18
|
+
maxOutputTokens:
|
|
19
|
+
stepSettings?.maxOutputTokens ?? callSettings.maxOutputTokens,
|
|
20
|
+
temperature: stepSettings?.temperature ?? callSettings.temperature,
|
|
21
|
+
topP: stepSettings?.topP ?? callSettings.topP,
|
|
22
|
+
topK: stepSettings?.topK ?? callSettings.topK,
|
|
23
|
+
presencePenalty:
|
|
24
|
+
stepSettings?.presencePenalty ?? callSettings.presencePenalty,
|
|
25
|
+
frequencyPenalty:
|
|
26
|
+
stepSettings?.frequencyPenalty ?? callSettings.frequencyPenalty,
|
|
27
|
+
stopSequences: stepSettings?.stopSequences ?? callSettings.stopSequences,
|
|
28
|
+
seed: stepSettings?.seed ?? callSettings.seed,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -4,9 +4,22 @@ import type {
|
|
|
4
4
|
SystemModelMessage,
|
|
5
5
|
Tool,
|
|
6
6
|
} from '@ai-sdk/provider-utils';
|
|
7
|
+
import type { CallSettings } from '../prompt/call-settings';
|
|
7
8
|
import type { LanguageModel, ToolChoice } from '../types/language-model';
|
|
8
9
|
import type { StepResult } from './step-result';
|
|
9
10
|
|
|
11
|
+
export type PrepareStepCallSettings = Pick<
|
|
12
|
+
CallSettings,
|
|
13
|
+
| 'maxOutputTokens'
|
|
14
|
+
| 'temperature'
|
|
15
|
+
| 'topP'
|
|
16
|
+
| 'topK'
|
|
17
|
+
| 'presencePenalty'
|
|
18
|
+
| 'frequencyPenalty'
|
|
19
|
+
| 'stopSequences'
|
|
20
|
+
| 'seed'
|
|
21
|
+
>;
|
|
22
|
+
|
|
10
23
|
/**
|
|
11
24
|
* Function that you can use to provide different settings for a step.
|
|
12
25
|
*
|
|
@@ -51,12 +64,16 @@ export type PrepareStepFunction<
|
|
|
51
64
|
|
|
52
65
|
/**
|
|
53
66
|
* The result type returned by a {@link PrepareStepFunction},
|
|
54
|
-
* allowing per-step overrides of model, tools, or
|
|
67
|
+
* allowing per-step overrides of model call settings, model, tools, or
|
|
68
|
+
* messages.
|
|
69
|
+
*
|
|
70
|
+
* Model call setting overrides apply only to the current step. Undefined
|
|
71
|
+
* settings fall back to the outer call settings.
|
|
55
72
|
*/
|
|
56
73
|
export type PrepareStepResult<
|
|
57
74
|
TOOLS extends Record<string, Tool> = Record<string, Tool>,
|
|
58
75
|
> =
|
|
59
|
-
| {
|
|
76
|
+
| ({
|
|
60
77
|
/**
|
|
61
78
|
* Optionally override which LanguageModel instance is used for this step.
|
|
62
79
|
*/
|
|
@@ -99,5 +116,5 @@ export type PrepareStepResult<
|
|
|
99
116
|
* container IDs for Anthropic's code execution.
|
|
100
117
|
*/
|
|
101
118
|
providerOptions?: ProviderOptions;
|
|
102
|
-
}
|
|
119
|
+
} & PrepareStepCallSettings)
|
|
103
120
|
| undefined;
|
|
@@ -65,7 +65,8 @@ export type StepResult<TOOLS extends ToolSet> = {
|
|
|
65
65
|
readonly content: Array<ContentPart<TOOLS>>;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
* The generated
|
|
68
|
+
* The concatenation of all text parts generated in this step.
|
|
69
|
+
* It is an empty string if the step contains no text parts.
|
|
69
70
|
*/
|
|
70
71
|
readonly text: string;
|
|
71
72
|
|
|
@@ -103,6 +103,7 @@ import type {
|
|
|
103
103
|
InferPartialOutput,
|
|
104
104
|
} from './output-utils';
|
|
105
105
|
import type { PrepareStepFunction } from './prepare-step';
|
|
106
|
+
import { prepareStepCallSettings } from './prepare-step-call-settings';
|
|
106
107
|
import type { ResponseMessage } from './response-message';
|
|
107
108
|
import {
|
|
108
109
|
runToolsTransformation,
|
|
@@ -714,6 +715,11 @@ function createOutputTransformStream<
|
|
|
714
715
|
textChunk += chunk.text;
|
|
715
716
|
textProviderMetadata = chunk.providerMetadata ?? textProviderMetadata;
|
|
716
717
|
|
|
718
|
+
if (chunk.text.length === 0 && chunk.providerMetadata != null) {
|
|
719
|
+
controller.enqueue({ part: chunk, partialOutput: undefined });
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
|
|
717
723
|
// only publish if partial json can be parsed:
|
|
718
724
|
const result = await output.parsePartialOutput({ text });
|
|
719
725
|
|
|
@@ -1670,6 +1676,11 @@ class DefaultStreamTextResult<
|
|
|
1670
1676
|
prepareStepResult?.providerOptions,
|
|
1671
1677
|
);
|
|
1672
1678
|
|
|
1679
|
+
const stepCallSettings = prepareStepCallSettings({
|
|
1680
|
+
callSettings,
|
|
1681
|
+
stepSettings: prepareStepResult,
|
|
1682
|
+
});
|
|
1683
|
+
|
|
1673
1684
|
await notify({
|
|
1674
1685
|
event: {
|
|
1675
1686
|
stepNumber: recordedSteps.length,
|
|
@@ -1735,14 +1746,16 @@ class DefaultStreamTextResult<
|
|
|
1735
1746
|
'gen_ai.system': stepModel.provider,
|
|
1736
1747
|
'gen_ai.request.model': stepModel.modelId,
|
|
1737
1748
|
'gen_ai.request.frequency_penalty':
|
|
1738
|
-
|
|
1739
|
-
'gen_ai.request.max_tokens':
|
|
1749
|
+
stepCallSettings.frequencyPenalty,
|
|
1750
|
+
'gen_ai.request.max_tokens':
|
|
1751
|
+
stepCallSettings.maxOutputTokens,
|
|
1740
1752
|
'gen_ai.request.presence_penalty':
|
|
1741
|
-
|
|
1742
|
-
'gen_ai.request.stop_sequences':
|
|
1743
|
-
|
|
1744
|
-
'gen_ai.request.
|
|
1745
|
-
'gen_ai.request.
|
|
1753
|
+
stepCallSettings.presencePenalty,
|
|
1754
|
+
'gen_ai.request.stop_sequences':
|
|
1755
|
+
stepCallSettings.stopSequences,
|
|
1756
|
+
'gen_ai.request.temperature': stepCallSettings.temperature,
|
|
1757
|
+
'gen_ai.request.top_k': stepCallSettings.topK,
|
|
1758
|
+
'gen_ai.request.top_p': stepCallSettings.topP,
|
|
1746
1759
|
},
|
|
1747
1760
|
}),
|
|
1748
1761
|
tracer,
|
|
@@ -1751,7 +1764,7 @@ class DefaultStreamTextResult<
|
|
|
1751
1764
|
startTimestampMs: now(), // get before the call
|
|
1752
1765
|
doStreamSpan,
|
|
1753
1766
|
result: await stepModel.doStream({
|
|
1754
|
-
...
|
|
1767
|
+
...stepCallSettings,
|
|
1755
1768
|
tools: stepTools,
|
|
1756
1769
|
toolChoice: stepToolChoice,
|
|
1757
1770
|
responseFormat: await output?.responseFormat,
|
|
@@ -1878,15 +1891,18 @@ class DefaultStreamTextResult<
|
|
|
1878
1891
|
}
|
|
1879
1892
|
|
|
1880
1893
|
case 'text-delta': {
|
|
1881
|
-
if (
|
|
1894
|
+
if (
|
|
1895
|
+
chunk.delta.length > 0 ||
|
|
1896
|
+
chunk.providerMetadata != null
|
|
1897
|
+
) {
|
|
1882
1898
|
controller.enqueue({
|
|
1883
1899
|
type: 'text-delta',
|
|
1884
1900
|
id: chunk.id,
|
|
1885
1901
|
text: chunk.delta,
|
|
1886
1902
|
providerMetadata: chunk.providerMetadata,
|
|
1887
1903
|
});
|
|
1888
|
-
activeText += chunk.delta;
|
|
1889
1904
|
}
|
|
1905
|
+
activeText += chunk.delta;
|
|
1890
1906
|
break;
|
|
1891
1907
|
}
|
|
1892
1908
|
|