ai 7.0.154 → 7.0.155
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 +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +700 -825
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -3
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +4 -380
- package/dist/internal/index.js.map +1 -1
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +7 -0
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +7 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +25 -10
- package/package.json +11 -11
- package/src/batch/batch.ts +0 -8
- package/src/decide/validate-decision.ts +39 -64
- package/src/generate-object/validate-object-generation-input.ts +1 -39
- package/src/generate-speech/stream-speech.ts +6 -18
- package/src/generate-text/smooth-stream.ts +2 -14
- package/src/generate-text/steering.ts +0 -8
- package/src/generate-text/tool-caller-configuration.ts +2 -26
- package/src/prompt/prepare-language-model-call-options.ts +0 -50
- package/src/prompt/standardize-prompt.ts +9 -58
- package/src/test/mock-sandbox.ts +5 -11
|
@@ -31,6 +31,13 @@ with `server/discover` and automatically falls back to the legacy
|
|
|
31
31
|
`initialize` handshake for older servers. Custom transports can opt into this
|
|
32
32
|
negotiation with `supportsProtocolVersionDiscovery: true`.
|
|
33
33
|
|
|
34
|
+
Recognized modern protocol errors, including `-32022` (unsupported protocol
|
|
35
|
+
version), do not trigger automatic fallback to `initialize`. If you know an
|
|
36
|
+
endpoint requires legacy initialization, set `protocolVersionDiscovery: false`
|
|
37
|
+
on `createMCPClient` to skip discovery and start with the legacy handshake.
|
|
38
|
+
The server can then negotiate an older supported version in its `initialize`
|
|
39
|
+
response.
|
|
40
|
+
|
|
34
41
|
### HTTP Transport (Recommended)
|
|
35
42
|
|
|
36
43
|
For production deployments, we recommend using the HTTP transport. You can configure it directly on the client:
|
|
@@ -201,6 +201,13 @@ experimental webhook delivery, see the [MCP Events guide](/docs/ai-sdk-core/mcp-
|
|
|
201
201
|
},
|
|
202
202
|
],
|
|
203
203
|
},
|
|
204
|
+
{
|
|
205
|
+
name: 'protocolVersionDiscovery',
|
|
206
|
+
type: 'boolean',
|
|
207
|
+
isOptional: true,
|
|
208
|
+
description:
|
|
209
|
+
'Whether transports that support protocol discovery probe with server/discover before legacy initialization. Defaults to true. Set to false for a known legacy server to start with initialize. Recognized modern protocol errors do not trigger automatic legacy fallback.',
|
|
210
|
+
},
|
|
204
211
|
{
|
|
205
212
|
name: 'initializationOptions',
|
|
206
213
|
type: 'RequestOptions',
|
|
@@ -9,25 +9,40 @@ This error occurs when the prompt provided is invalid.
|
|
|
9
9
|
|
|
10
10
|
## Potential Causes
|
|
11
11
|
|
|
12
|
-
###
|
|
12
|
+
### System Messages in `prompt` or `messages`
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
You need to first convert them to a `ModelMessage[]` using `convertToModelMessages()`.
|
|
14
|
+
AI SDK functions reject system messages in the `prompt` or `messages` fields to reduce the risk of prompt injection.
|
|
15
|
+
Pass system instructions with the `instructions` option instead:
|
|
17
16
|
|
|
18
17
|
```typescript
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
const messages: UIMessage[] = [
|
|
22
|
-
/* ... */
|
|
23
|
-
];
|
|
18
|
+
import { generateText } from 'ai';
|
|
24
19
|
|
|
25
20
|
const result = await generateText({
|
|
26
21
|
// ...
|
|
27
|
-
|
|
22
|
+
instructions: 'You are a helpful assistant.',
|
|
23
|
+
messages,
|
|
28
24
|
});
|
|
29
25
|
```
|
|
30
26
|
|
|
27
|
+
If the system messages come from a trusted source, you can allow them with `allowSystemInMessages: true`.
|
|
28
|
+
|
|
29
|
+
### Empty Messages
|
|
30
|
+
|
|
31
|
+
The `messages` array (or a `prompt` given as an array) must contain at least one message.
|
|
32
|
+
|
|
33
|
+
### Provider-Specific Prompt Requirements
|
|
34
|
+
|
|
35
|
+
Some providers throw this error when a prompt can't be expressed for their API,
|
|
36
|
+
for example when an assistant prefix message isn't the final message, or when a part combines options the provider doesn't support.
|
|
37
|
+
The error message describes the provider requirement that wasn't met.
|
|
38
|
+
|
|
39
|
+
<Note>
|
|
40
|
+
AI SDK functions do not validate the shape of `ModelMessage` objects at
|
|
41
|
+
runtime. If your messages come from an untrusted source, validate them before
|
|
42
|
+
passing them to an AI SDK function. See
|
|
43
|
+
[`ModelMessage`](/docs/reference/ai-sdk-core/model-message).
|
|
44
|
+
</Note>
|
|
45
|
+
|
|
31
46
|
## Properties
|
|
32
47
|
|
|
33
48
|
- `prompt`: The invalid prompt value
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.155",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"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.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,20 +42,20 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ai-sdk/gateway": "4.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.128",
|
|
46
46
|
"@ai-sdk/provider": "4.0.34",
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.70"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@ai-sdk/amazon-bedrock": "5.0.
|
|
51
|
-
"@ai-sdk/deepseek": "3.0.
|
|
52
|
-
"@ai-sdk/google": "4.0.
|
|
53
|
-
"@ai-sdk/groq": "4.0.
|
|
54
|
-
"@ai-sdk/huggingface": "2.0.
|
|
55
|
-
"@ai-sdk/moonshotai": "3.0.
|
|
56
|
-
"@ai-sdk/openai": "4.0.
|
|
50
|
+
"@ai-sdk/amazon-bedrock": "5.0.126",
|
|
51
|
+
"@ai-sdk/deepseek": "3.0.75",
|
|
52
|
+
"@ai-sdk/google": "4.0.107",
|
|
53
|
+
"@ai-sdk/groq": "4.0.72",
|
|
54
|
+
"@ai-sdk/huggingface": "2.0.80",
|
|
55
|
+
"@ai-sdk/moonshotai": "3.0.80",
|
|
56
|
+
"@ai-sdk/openai": "4.0.104",
|
|
57
57
|
"@ai-sdk/test-server": "2.0.4",
|
|
58
|
-
"@ai-sdk/xai": "5.0.
|
|
58
|
+
"@ai-sdk/xai": "5.0.32",
|
|
59
59
|
"@edge-runtime/vm": "^5.0.0",
|
|
60
60
|
"@smithy/eventstream-codec": "^4.3.3",
|
|
61
61
|
"@smithy/util-utf8": "^4.3.3",
|
package/src/batch/batch.ts
CHANGED
|
@@ -491,14 +491,6 @@ function validateBatchReference({
|
|
|
491
491
|
batchApi: BatchV4;
|
|
492
492
|
batch: BatchReference;
|
|
493
493
|
}) {
|
|
494
|
-
if (batch.version !== 2) {
|
|
495
|
-
throw new InvalidArgumentError({
|
|
496
|
-
parameter: 'batch',
|
|
497
|
-
value: batch,
|
|
498
|
-
message: 'batch must be a supported batch reference',
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
|
|
502
494
|
if (batch.provider !== batchApi.provider) {
|
|
503
495
|
throw new InvalidArgumentError({
|
|
504
496
|
parameter: 'provider',
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type Experimental_DecisionModelV4Result as DecisionModelV4Result,
|
|
4
4
|
type Experimental_DecisionModelV4Question as DecisionQuestion,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
|
-
import { filePartSchema, textPartSchema } from '../prompt/content-part';
|
|
7
6
|
import type { DecisionState } from './decision-state';
|
|
8
7
|
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
9
8
|
|
|
@@ -17,30 +16,28 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
17
16
|
return prototype === Object.prototype || prototype === null;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Checks the JSON constraints that types cannot express: finite numbers, no
|
|
21
|
+
* cycles, and no array holes. These would otherwise be silently changed by
|
|
22
|
+
* `JSON.stringify` or make it throw.
|
|
23
|
+
*/
|
|
24
|
+
function isSerializableJSON(
|
|
25
|
+
value: unknown,
|
|
26
|
+
ancestors = new Set<object>(),
|
|
27
|
+
): boolean {
|
|
23
28
|
if (typeof value === 'number') return Number.isFinite(value);
|
|
24
|
-
if (typeof value !== 'object'
|
|
25
|
-
return false;
|
|
29
|
+
if (value == null || typeof value !== 'object') return true;
|
|
26
30
|
if (ancestors.has(value)) return false;
|
|
27
31
|
ancestors.add(value);
|
|
28
|
-
const valid =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const valid = Array.isArray(value)
|
|
33
|
+
? Array.from(value.keys()).every(
|
|
34
|
+
index => index in value && isSerializableJSON(value[index], ancestors),
|
|
35
|
+
)
|
|
36
|
+
: Object.values(value).every(item => isSerializableJSON(item, ancestors));
|
|
33
37
|
ancestors.delete(value);
|
|
34
38
|
return valid;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
function isInput(value: unknown): boolean {
|
|
38
|
-
return (
|
|
39
|
-
(typeof value === 'string' || Array.isArray(value) || isRecord(value)) &&
|
|
40
|
-
isJSON(value)
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
41
|
function invalidInput(
|
|
45
42
|
parameter: string,
|
|
46
43
|
value: unknown,
|
|
@@ -56,50 +53,43 @@ export function validateDecisionInput({
|
|
|
56
53
|
state: DecisionState;
|
|
57
54
|
questions: Readonly<Record<string, DecisionQuestion>>;
|
|
58
55
|
}) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
: (typeof state === 'string' || isRecord(state)) && isJSON(state);
|
|
74
|
-
if (!validState) {
|
|
56
|
+
if (
|
|
57
|
+
Array.isArray(state) &&
|
|
58
|
+
Array.from(state.keys()).some(index => !(index in state))
|
|
59
|
+
) {
|
|
60
|
+
invalidInput('state', state, 'state parts must not contain array holes');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const stateJSON = Array.isArray(state)
|
|
64
|
+
? state.flatMap(part => (part.type === 'json' ? [part.value] : []))
|
|
65
|
+
: state;
|
|
66
|
+
if (!isSerializableJSON(stateJSON)) {
|
|
75
67
|
invalidInput(
|
|
76
68
|
'state',
|
|
77
69
|
state,
|
|
78
|
-
'
|
|
70
|
+
'JSON content must not contain non-finite numbers, cycles, or array holes',
|
|
79
71
|
);
|
|
80
72
|
}
|
|
81
|
-
|
|
73
|
+
|
|
74
|
+
if (Object.keys(questions).length === 0) {
|
|
82
75
|
invalidInput('questions', questions, 'must be a nonempty question map');
|
|
83
76
|
}
|
|
84
77
|
|
|
85
78
|
for (const [id, question] of Object.entries(questions)) {
|
|
86
79
|
const parameter = `questions.${id}`;
|
|
87
80
|
if (
|
|
88
|
-
!
|
|
89
|
-
(
|
|
90
|
-
!isInput(question.instructions))
|
|
81
|
+
!isSerializableJSON(question.instructions) ||
|
|
82
|
+
('criteria' in question && !isSerializableJSON(question.criteria))
|
|
91
83
|
) {
|
|
92
84
|
invalidInput(
|
|
93
85
|
parameter,
|
|
94
86
|
question,
|
|
95
|
-
'instructions must
|
|
87
|
+
'instructions and criteria must not contain non-finite numbers, cycles, or array holes',
|
|
96
88
|
);
|
|
97
89
|
}
|
|
98
|
-
if (question.type === 'box') continue;
|
|
99
|
-
const criteria = question.criteria;
|
|
100
90
|
switch (question.type) {
|
|
101
91
|
case 'choice':
|
|
102
|
-
if (
|
|
92
|
+
if (Object.keys(question.criteria).length === 0) {
|
|
103
93
|
invalidInput(
|
|
104
94
|
parameter,
|
|
105
95
|
question,
|
|
@@ -108,7 +98,7 @@ export function validateDecisionInput({
|
|
|
108
98
|
}
|
|
109
99
|
break;
|
|
110
100
|
case 'score':
|
|
111
|
-
if (
|
|
101
|
+
if (question.criteria.length === 0) {
|
|
112
102
|
invalidInput(
|
|
113
103
|
parameter,
|
|
114
104
|
question,
|
|
@@ -116,10 +106,11 @@ export function validateDecisionInput({
|
|
|
116
106
|
);
|
|
117
107
|
}
|
|
118
108
|
break;
|
|
119
|
-
case 'boolean':
|
|
109
|
+
case 'boolean': {
|
|
110
|
+
const criteria = question.criteria;
|
|
120
111
|
if (
|
|
121
112
|
question.instructions == null &&
|
|
122
|
-
(
|
|
113
|
+
(criteria == null ||
|
|
123
114
|
!Object.values(criteria).some(value => value != null))
|
|
124
115
|
) {
|
|
125
116
|
invalidInput(
|
|
@@ -128,9 +119,8 @@ export function validateDecisionInput({
|
|
|
128
119
|
'boolean questions require instructions or at least one non-null criterion',
|
|
129
120
|
);
|
|
130
121
|
}
|
|
131
|
-
if (criteria === undefined) continue;
|
|
132
122
|
if (
|
|
133
|
-
|
|
123
|
+
criteria != null &&
|
|
134
124
|
Object.keys(criteria).some(key => key !== 'true' && key !== 'false')
|
|
135
125
|
) {
|
|
136
126
|
invalidInput(
|
|
@@ -140,22 +130,7 @@ export function validateDecisionInput({
|
|
|
140
130
|
);
|
|
141
131
|
}
|
|
142
132
|
break;
|
|
143
|
-
|
|
144
|
-
invalidInput(
|
|
145
|
-
parameter,
|
|
146
|
-
question,
|
|
147
|
-
'question type must be choice, score, boolean, or box',
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
if (
|
|
151
|
-
!isJSON(criteria) ||
|
|
152
|
-
Object.values(criteria).some(value => value !== null && !isInput(value))
|
|
153
|
-
) {
|
|
154
|
-
invalidInput(
|
|
155
|
-
parameter,
|
|
156
|
-
question,
|
|
157
|
-
'criteria descriptions must be JSON-compatible strings, objects, arrays, or null',
|
|
158
|
-
);
|
|
133
|
+
}
|
|
159
134
|
}
|
|
160
135
|
}
|
|
161
136
|
}
|
|
@@ -14,20 +14,6 @@ export function validateObjectGenerationInput({
|
|
|
14
14
|
schemaDescription?: string;
|
|
15
15
|
enumValues?: Array<unknown>;
|
|
16
16
|
}) {
|
|
17
|
-
if (
|
|
18
|
-
output != null &&
|
|
19
|
-
output !== 'object' &&
|
|
20
|
-
output !== 'array' &&
|
|
21
|
-
output !== 'enum' &&
|
|
22
|
-
output !== 'no-schema'
|
|
23
|
-
) {
|
|
24
|
-
throw new InvalidArgumentError({
|
|
25
|
-
parameter: 'output',
|
|
26
|
-
value: output,
|
|
27
|
-
message: 'Invalid output type.',
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
17
|
if (output === 'no-schema') {
|
|
32
18
|
if (schema != null) {
|
|
33
19
|
throw new InvalidArgumentError({
|
|
@@ -63,14 +49,6 @@ export function validateObjectGenerationInput({
|
|
|
63
49
|
}
|
|
64
50
|
|
|
65
51
|
if (output === 'object') {
|
|
66
|
-
if (schema == null) {
|
|
67
|
-
throw new InvalidArgumentError({
|
|
68
|
-
parameter: 'schema',
|
|
69
|
-
value: schema,
|
|
70
|
-
message: 'Schema is required for object output.',
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
52
|
if (enumValues != null) {
|
|
75
53
|
throw new InvalidArgumentError({
|
|
76
54
|
parameter: 'enumValues',
|
|
@@ -81,14 +59,6 @@ export function validateObjectGenerationInput({
|
|
|
81
59
|
}
|
|
82
60
|
|
|
83
61
|
if (output === 'array') {
|
|
84
|
-
if (schema == null) {
|
|
85
|
-
throw new InvalidArgumentError({
|
|
86
|
-
parameter: 'schema',
|
|
87
|
-
value: schema,
|
|
88
|
-
message: 'Element schema is required for array output.',
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
62
|
if (enumValues != null) {
|
|
93
63
|
throw new InvalidArgumentError({
|
|
94
64
|
parameter: 'enumValues',
|
|
@@ -123,15 +93,7 @@ export function validateObjectGenerationInput({
|
|
|
123
93
|
});
|
|
124
94
|
}
|
|
125
95
|
|
|
126
|
-
|
|
127
|
-
throw new InvalidArgumentError({
|
|
128
|
-
parameter: 'enumValues',
|
|
129
|
-
value: enumValues,
|
|
130
|
-
message: 'Enum values are required for enum output.',
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
for (const value of enumValues) {
|
|
96
|
+
for (const value of enumValues ?? []) {
|
|
135
97
|
if (typeof value !== 'string') {
|
|
136
98
|
throw new InvalidArgumentError({
|
|
137
99
|
parameter: 'enumValues',
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
withUserAgentSuffix,
|
|
13
13
|
type ProviderOptions,
|
|
14
14
|
} from '@ai-sdk/provider-utils';
|
|
15
|
-
import { InvalidArgumentError } from '../error/invalid-argument-error';
|
|
16
15
|
import { NoSpeechGeneratedError } from '../error/no-speech-generated-error';
|
|
17
16
|
import { StreamProviderError } from '../error/stream-provider-error';
|
|
18
17
|
import { logWarnings } from '../logger/log-warnings';
|
|
@@ -533,23 +532,12 @@ function toSourceStream(
|
|
|
533
532
|
iterable[Symbol.asyncIterator](),
|
|
534
533
|
);
|
|
535
534
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
(async function* () {
|
|
543
|
-
yield* iterable;
|
|
544
|
-
})(),
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
throw new InvalidArgumentError({
|
|
548
|
-
parameter: 'text',
|
|
549
|
-
value: text,
|
|
550
|
-
message:
|
|
551
|
-
'Expected a string, an iterable or async iterable, or a ReadableStream of strings or text parts.',
|
|
552
|
-
});
|
|
535
|
+
const iterable = text as Iterable<string | SpeechTextPart>;
|
|
536
|
+
return convertAsyncIteratorToReadableStream(
|
|
537
|
+
(async function* () {
|
|
538
|
+
yield* iterable;
|
|
539
|
+
})(),
|
|
540
|
+
);
|
|
553
541
|
}
|
|
554
542
|
|
|
555
543
|
function toTextPart(
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { delay as originalDelay, type ToolSet } from '@ai-sdk/provider-utils';
|
|
2
|
-
import {
|
|
3
|
-
InvalidArgumentError,
|
|
4
|
-
type SharedV4ProviderMetadata,
|
|
5
|
-
} from '@ai-sdk/provider';
|
|
2
|
+
import type { SharedV4ProviderMetadata } from '@ai-sdk/provider';
|
|
6
3
|
import type { TextStreamPart } from './stream-text-result';
|
|
7
4
|
|
|
8
5
|
const CHUNKING_REGEXPS = {
|
|
@@ -92,16 +89,7 @@ export function smoothStream<TOOLS extends ToolSet>({
|
|
|
92
89
|
const chunkingRegex =
|
|
93
90
|
typeof chunking === 'string'
|
|
94
91
|
? CHUNKING_REGEXPS[chunking]
|
|
95
|
-
: chunking
|
|
96
|
-
? chunking
|
|
97
|
-
: undefined;
|
|
98
|
-
|
|
99
|
-
if (chunkingRegex == null) {
|
|
100
|
-
throw new InvalidArgumentError({
|
|
101
|
-
argument: 'chunking',
|
|
102
|
-
message: `Chunking must be "word", "line", a RegExp, an Intl.Segmenter, or a ChunkDetector function. Received: ${chunking}`,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
92
|
+
: (chunking as RegExp);
|
|
105
93
|
|
|
106
94
|
detectChunk = buffer => {
|
|
107
95
|
const lastIndex = chunkingRegex.lastIndex;
|
|
@@ -135,14 +135,6 @@ class DefaultSteering implements Steering {
|
|
|
135
135
|
? { role: 'user', content: message }
|
|
136
136
|
: message;
|
|
137
137
|
|
|
138
|
-
if (userMessage.role !== 'user') {
|
|
139
|
-
throw new InvalidArgumentError({
|
|
140
|
-
parameter: 'message',
|
|
141
|
-
value: message,
|
|
142
|
-
message: 'Steering messages must be user messages.',
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
138
|
const outcome =
|
|
147
139
|
this.state === 'ended'
|
|
148
140
|
? Promise.resolve<SteeringOutcome>({
|
|
@@ -47,33 +47,9 @@ export function resolveToolCallerConfiguration<TOOLS extends ToolSet>({
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
parameter: 'experimental_toolCallers',
|
|
53
|
-
value: toolCallers,
|
|
54
|
-
message: `callers for tool "${toolName}" must be an array.`,
|
|
55
|
-
});
|
|
50
|
+
if (callers != null) {
|
|
51
|
+
resolved[toolName] = callers;
|
|
56
52
|
}
|
|
57
|
-
|
|
58
|
-
resolved[toolName] = callers.map(caller => {
|
|
59
|
-
if (caller === DIRECT_TOOL_CALL) {
|
|
60
|
-
return caller;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
typeof caller !== 'string' ||
|
|
65
|
-
!Object.prototype.hasOwnProperty.call(tools, caller) ||
|
|
66
|
-
experimental_getToolCaller(tools[caller]) == null
|
|
67
|
-
) {
|
|
68
|
-
throw new InvalidArgumentError({
|
|
69
|
-
parameter: 'experimental_toolCallers',
|
|
70
|
-
value: toolCallers,
|
|
71
|
-
message: `tool "${toolName}" contains an invalid caller.`,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return caller;
|
|
76
|
-
});
|
|
77
53
|
}
|
|
78
54
|
|
|
79
55
|
return resolved;
|
|
@@ -33,56 +33,6 @@ export function prepareLanguageModelCallOptions({
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
if (temperature != null) {
|
|
37
|
-
if (typeof temperature !== 'number') {
|
|
38
|
-
throw new InvalidArgumentError({
|
|
39
|
-
parameter: 'temperature',
|
|
40
|
-
value: temperature,
|
|
41
|
-
message: 'temperature must be a number',
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (topP != null) {
|
|
47
|
-
if (typeof topP !== 'number') {
|
|
48
|
-
throw new InvalidArgumentError({
|
|
49
|
-
parameter: 'topP',
|
|
50
|
-
value: topP,
|
|
51
|
-
message: 'topP must be a number',
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (topK != null) {
|
|
57
|
-
if (typeof topK !== 'number') {
|
|
58
|
-
throw new InvalidArgumentError({
|
|
59
|
-
parameter: 'topK',
|
|
60
|
-
value: topK,
|
|
61
|
-
message: 'topK must be a number',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (presencePenalty != null) {
|
|
67
|
-
if (typeof presencePenalty !== 'number') {
|
|
68
|
-
throw new InvalidArgumentError({
|
|
69
|
-
parameter: 'presencePenalty',
|
|
70
|
-
value: presencePenalty,
|
|
71
|
-
message: 'presencePenalty must be a number',
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (frequencyPenalty != null) {
|
|
77
|
-
if (typeof frequencyPenalty !== 'number') {
|
|
78
|
-
throw new InvalidArgumentError({
|
|
79
|
-
parameter: 'frequencyPenalty',
|
|
80
|
-
value: frequencyPenalty,
|
|
81
|
-
message: 'frequencyPenalty must be a number',
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
36
|
if (seed != null) {
|
|
87
37
|
if (!Number.isInteger(seed)) {
|
|
88
38
|
throw new InvalidArgumentError({
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { InvalidPromptError } from '@ai-sdk/provider';
|
|
2
|
-
import {
|
|
3
|
-
asArray,
|
|
4
|
-
safeValidateTypes,
|
|
5
|
-
type ModelMessage,
|
|
6
|
-
} from '@ai-sdk/provider-utils';
|
|
7
|
-
import { z } from '../util/zod';
|
|
8
|
-
import { modelMessageSchema } from './message';
|
|
2
|
+
import type { ModelMessage } from '@ai-sdk/provider-utils';
|
|
9
3
|
import type { Instructions, Prompt } from './prompt';
|
|
10
4
|
|
|
11
5
|
export type StandardizedPrompt = {
|
|
@@ -21,8 +15,7 @@ export type StandardizedPrompt = {
|
|
|
21
15
|
};
|
|
22
16
|
|
|
23
17
|
/**
|
|
24
|
-
* Converts a prompt input into a standardized prompt with
|
|
25
|
-
* messages.
|
|
18
|
+
* Converts a prompt input into a standardized prompt with model messages.
|
|
26
19
|
*
|
|
27
20
|
* @param prompt - The prompt definition to standardize.
|
|
28
21
|
* Set `allowSystemInMessages` to true to allow system messages in the
|
|
@@ -38,42 +31,13 @@ export async function standardizePrompt({
|
|
|
38
31
|
prompt,
|
|
39
32
|
messages,
|
|
40
33
|
}: Prompt): Promise<StandardizedPrompt> {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (prompt != null && messages != null) {
|
|
49
|
-
throw new InvalidPromptError({
|
|
50
|
-
prompt,
|
|
51
|
-
message: 'prompt and messages cannot be defined at the same time',
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// validate that instructions is a string or a SystemModelMessage
|
|
56
|
-
if (
|
|
57
|
-
typeof instructions !== 'string' &&
|
|
58
|
-
!asArray(instructions).every(message => message.role === 'system')
|
|
59
|
-
) {
|
|
60
|
-
throw new InvalidPromptError({
|
|
61
|
-
prompt,
|
|
62
|
-
message:
|
|
63
|
-
'instructions must be a string, SystemModelMessage, or array of SystemModelMessage',
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (prompt != null && typeof prompt === 'string') {
|
|
68
|
-
messages = [{ role: 'user', content: prompt }];
|
|
69
|
-
} else if (prompt != null && Array.isArray(prompt)) {
|
|
70
|
-
messages = prompt;
|
|
71
|
-
} else if (messages == null) {
|
|
72
|
-
throw new InvalidPromptError({
|
|
73
|
-
prompt,
|
|
74
|
-
message: 'prompt or messages must be defined',
|
|
75
|
-
});
|
|
76
|
-
}
|
|
34
|
+
// `Prompt` requires exactly one of `prompt` or `messages`:
|
|
35
|
+
messages =
|
|
36
|
+
prompt == null
|
|
37
|
+
? messages!
|
|
38
|
+
: typeof prompt === 'string'
|
|
39
|
+
? [{ role: 'user', content: prompt }]
|
|
40
|
+
: prompt;
|
|
77
41
|
|
|
78
42
|
if (messages.length === 0) {
|
|
79
43
|
throw new InvalidPromptError({
|
|
@@ -95,18 +59,5 @@ export async function standardizePrompt({
|
|
|
95
59
|
});
|
|
96
60
|
}
|
|
97
61
|
|
|
98
|
-
const validationResult = await safeValidateTypes({
|
|
99
|
-
value: messages,
|
|
100
|
-
schema: z.array(modelMessageSchema),
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
if (!validationResult.success) {
|
|
104
|
-
throw new InvalidPromptError({
|
|
105
|
-
prompt,
|
|
106
|
-
message: 'The messages do not match the ModelMessage[] schema.',
|
|
107
|
-
cause: validationResult.error,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
62
|
return { messages, instructions };
|
|
112
63
|
}
|
package/src/test/mock-sandbox.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Experimental_SandboxSession,
|
|
3
|
-
Experimental_SandboxProcess,
|
|
4
|
-
} from '@ai-sdk/provider-utils';
|
|
1
|
+
import type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
|
-
*
|
|
4
|
+
* File stubs and an unimplemented spawn method on `Experimental_SandboxSession`,
|
|
8
5
|
* intended to be spread into test fixtures that only care about `run`.
|
|
9
6
|
*/
|
|
10
7
|
export const mockSandboxSessionFileStubs: Pick<
|
|
@@ -23,10 +20,7 @@ export const mockSandboxSessionFileStubs: Pick<
|
|
|
23
20
|
writeFile: async () => {},
|
|
24
21
|
writeBinaryFile: async () => {},
|
|
25
22
|
writeTextFile: async () => {},
|
|
26
|
-
spawn: async ()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
wait: async () => ({ exitCode: 0 }),
|
|
30
|
-
kill: async () => {},
|
|
31
|
-
}),
|
|
23
|
+
spawn: async () => {
|
|
24
|
+
throw new Error('spawn is not implemented in this mock.');
|
|
25
|
+
},
|
|
32
26
|
};
|