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.
@@ -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
- ### UI Messages
12
+ ### System Messages in `prompt` or `messages`
13
13
 
14
- You are passing a `UIMessage[]` as messages into e.g. `streamText`.
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 { type UIMessage, generateText, convertToModelMessages } from 'ai';
20
-
21
- const messages: UIMessage[] = [
22
- /* ... */
23
- ];
18
+ import { generateText } from 'ai';
24
19
 
25
20
  const result = await generateText({
26
21
  // ...
27
- messages: await convertToModelMessages(messages),
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.154",
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.127",
45
+ "@ai-sdk/gateway": "4.0.128",
46
46
  "@ai-sdk/provider": "4.0.34",
47
- "@ai-sdk/provider-utils": "5.0.69"
47
+ "@ai-sdk/provider-utils": "5.0.70"
48
48
  },
49
49
  "devDependencies": {
50
- "@ai-sdk/amazon-bedrock": "5.0.125",
51
- "@ai-sdk/deepseek": "3.0.74",
52
- "@ai-sdk/google": "4.0.106",
53
- "@ai-sdk/groq": "4.0.71",
54
- "@ai-sdk/huggingface": "2.0.79",
55
- "@ai-sdk/moonshotai": "3.0.79",
56
- "@ai-sdk/openai": "4.0.103",
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.31",
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",
@@ -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
- function isJSON(value: unknown, ancestors = new Set<object>()): boolean {
21
- if (value === null || typeof value === 'string' || typeof value === 'boolean')
22
- return true;
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' || (!Array.isArray(value) && !isRecord(value)))
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
- Object.getOwnPropertySymbols(value).length === 0 &&
30
- (Array.isArray(value)
31
- ? Array.from(value).every(item => isJSON(item, ancestors))
32
- : Object.values(value).every(item => isJSON(item, ancestors)));
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
- const validState = Array.isArray(state)
60
- ? Array.from(state).every(part => {
61
- if (!isRecord(part)) return false;
62
- switch (part.type) {
63
- case 'text':
64
- return textPartSchema.safeParse(part).success;
65
- case 'file':
66
- return filePartSchema.safeParse(part).success;
67
- case 'json':
68
- return isJSON(part.value);
69
- default:
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
- 'must be a string, JSON object, or array of text, file, or json parts',
70
+ 'JSON content must not contain non-finite numbers, cycles, or array holes',
79
71
  );
80
72
  }
81
- if (!isRecord(questions) || Object.keys(questions).length === 0) {
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
- !isRecord(question) ||
89
- ((question.type === 'box' || question.instructions != null) &&
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 be a JSON-compatible string, object, or array',
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 (!isRecord(criteria) || Object.keys(criteria).length === 0) {
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 (!Array.isArray(criteria) || criteria.length === 0) {
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
- (!isRecord(criteria) ||
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
- !isRecord(criteria) ||
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
- default:
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
- if (enumValues == null) {
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
- if (
537
- typeof (text as Partial<Iterable<unknown>>)?.[Symbol.iterator] ===
538
- 'function'
539
- ) {
540
- const iterable = text as Iterable<string | SpeechTextPart>;
541
- return convertAsyncIteratorToReadableStream(
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 instanceof RegExp
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 (!Array.isArray(callers)) {
51
- throw new InvalidArgumentError({
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 validated model
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
- if (prompt == null && messages == null) {
42
- throw new InvalidPromptError({
43
- prompt,
44
- message: 'prompt or messages must be defined',
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
  }
@@ -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
- * No-op stubs for the file and spawn methods on `Experimental_SandboxSession`,
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 (): Promise<Experimental_SandboxProcess> => ({
27
- stdout: new ReadableStream<Uint8Array>({ start: c => c.close() }),
28
- stderr: new ReadableStream<Uint8Array>({ start: c => c.close() }),
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
  };