ai 7.0.113 → 7.0.116
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 +32 -0
- package/README.md +6 -6
- package/dist/index.js +1010 -1289
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +231 -257
- package/dist/internal/index.js.map +1 -1
- package/docs/02-foundations/02-providers-and-models.mdx +3 -0
- package/docs/02-foundations/03-prompts.mdx +1 -1
- package/docs/02-foundations/04-tools.mdx +2 -2
- package/docs/02-foundations/06-provider-options.mdx +11 -11
- package/docs/02-getting-started/00-choosing-a-provider.mdx +4 -4
- package/docs/02-getting-started/02-nextjs-app-router.mdx +3 -3
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +3 -3
- package/docs/02-getting-started/04-svelte.mdx +7 -7
- package/docs/02-getting-started/05-nuxt.mdx +7 -7
- package/docs/02-getting-started/06-nodejs.mdx +3 -3
- package/docs/02-getting-started/07-expo.mdx +3 -3
- package/docs/02-getting-started/08-tanstack-start.mdx +3 -3
- package/docs/02-getting-started/09-coding-agents.mdx +1 -1
- package/docs/03-agents/03-workflows.mdx +2 -2
- package/docs/03-agents/04-loop-control.mdx +1 -1
- package/docs/03-agents/05-configuring-call-options.mdx +4 -2
- package/docs/03-agents/06-memory.mdx +2 -2
- package/docs/03-agents/06-policy-tool-approvals.mdx +2 -2
- package/docs/03-agents/07-workflow-agent.mdx +11 -11
- package/docs/03-agents/08-terminal-ui.mdx +14 -10
- package/docs/03-ai-sdk-core/05-generating-text.mdx +2 -2
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +6 -1
- package/docs/03-ai-sdk-core/17-mcp-apps.mdx +1 -1
- package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +1 -1
- package/docs/03-ai-sdk-core/26-reasoning.mdx +13 -12
- package/docs/03-ai-sdk-core/31-reranking.mdx +12 -10
- package/docs/03-ai-sdk-core/32-evaluation.mdx +1 -1
- package/docs/03-ai-sdk-core/35-image-generation.mdx +2 -2
- package/docs/03-ai-sdk-core/37-speech.mdx +6 -6
- package/docs/03-ai-sdk-core/39-file-uploads.mdx +1 -1
- package/docs/03-ai-sdk-core/41-skill-uploads.mdx +1 -1
- package/docs/03-ai-sdk-core/42-batch.mdx +1 -1
- package/docs/03-ai-sdk-core/45-provider-management.mdx +21 -21
- package/docs/03-ai-sdk-core/60-telemetry.mdx +1 -1
- package/docs/03-ai-sdk-core/65-devtools.mdx +3 -3
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +1 -1
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +97 -107
- package/docs/03-ai-sdk-harnesses/03-tools.mdx +1 -22
- package/docs/03-ai-sdk-harnesses/04-skills.mdx +0 -4
- package/docs/03-ai-sdk-harnesses/06-workflow-utilities.mdx +43 -9
- package/docs/03-ai-sdk-harnesses/07-ui.mdx +33 -30
- package/docs/03-ai-sdk-harnesses/08-terminal-ui.mdx +8 -6
- package/docs/04-ai-sdk-ui/02-chatbot.mdx +3 -3
- package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +3 -3
- package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +1 -1
- package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +5 -5
- package/docs/05-ai-sdk-rsc/04-multistep-interfaces.mdx +1 -1
- package/docs/05-ai-sdk-rsc/06-loading-state.mdx +1 -1
- package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +3 -3
- package/docs/06-advanced/11-secure-url-fetching.mdx +39 -0
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +5 -3
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +5 -3
- package/docs/07-reference/01-ai-sdk-core/06-rerank.mdx +5 -5
- package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +2 -2
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +4 -2
- package/docs/07-reference/01-ai-sdk-core/20-start-batch.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +4 -4
- package/docs/07-reference/01-ai-sdk-core/60-wrap-language-model.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/61-wrap-image-model.mdx +1 -1
- package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +3 -3
- package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +1 -1
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +8 -8
- package/docs/07-reference/06-ai-sdk-tui/01-run-agent-tui.mdx +13 -9
- package/docs/09-troubleshooting/11-use-chat-custom-request-options.mdx +3 -3
- package/docs/09-troubleshooting/13-repeated-assistant-messages.mdx +2 -2
- package/docs/09-troubleshooting/17-use-chat-stale-body-data.mdx +1 -1
- package/docs/09-troubleshooting/70-high-memory-usage-with-images.mdx +2 -2
- package/package.json +12 -12
- package/src/evaluate/evaluate.ts +1 -10
- package/src/generate-text/restricted-telemetry-dispatcher.ts +6 -58
- package/src/prompt/file-part-data.ts +9 -3
- package/src/prompt/standardize-prompt.ts +2 -0
- package/src/telemetry/create-telemetry-dispatcher.ts +58 -6
- package/src/telemetry/filter-included-context.ts +57 -2
- package/src/util/download/download.ts +2 -2
|
@@ -82,53 +82,53 @@ Define the `HarnessAgent` on the server:
|
|
|
82
82
|
```ts filename='app/api/chat/agent.ts'
|
|
83
83
|
import { HarnessAgent } from '@ai-sdk/harness/agent';
|
|
84
84
|
import { claudeCode } from '@ai-sdk/harness-claude-code';
|
|
85
|
-
import { createVercelSandbox } from '@ai-sdk/sandbox-vercel';
|
|
86
85
|
|
|
87
86
|
export const agent = new HarnessAgent({
|
|
88
87
|
harness: claudeCode,
|
|
89
|
-
sandbox: createVercelSandbox({
|
|
90
|
-
runtime: 'node24',
|
|
91
|
-
ports: [4000],
|
|
92
|
-
}),
|
|
93
88
|
instructions: 'You are a helpful coding assistant.',
|
|
94
89
|
});
|
|
95
90
|
```
|
|
96
91
|
|
|
97
92
|
## Session Store
|
|
98
93
|
|
|
99
|
-
Persist
|
|
94
|
+
Persist the opaque resume state returned by `session.detach()`. If the
|
|
100
95
|
turn paused for approval or was otherwise interrupted, that resume state carries
|
|
101
96
|
the continuation state internally. The chat id can also be the harness
|
|
102
|
-
`sessionId
|
|
103
|
-
|
|
97
|
+
`sessionId`. Here we derive a stable `sandboxId` from that known chat id. If
|
|
98
|
+
you do not derive one, persist the returned `sandboxSession.id` separately.
|
|
104
99
|
|
|
105
100
|
```ts filename='app/api/chat/session-store.ts'
|
|
106
|
-
import type {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
import type { HarnessAgentResumeSessionState } from '@ai-sdk/harness/agent';
|
|
102
|
+
import {
|
|
103
|
+
createVercelNetworkSandboxSession,
|
|
104
|
+
resumeVercelNetworkSandboxSession,
|
|
105
|
+
} from '@ai-sdk/sandbox-vercel';
|
|
110
106
|
|
|
111
107
|
const states: Record<string, HarnessAgentResumeSessionState | undefined> = {};
|
|
112
108
|
|
|
113
|
-
type SessionFactory = {
|
|
114
|
-
createSession(options?: {
|
|
115
|
-
sessionId?: string;
|
|
116
|
-
resumeFrom?: HarnessAgentResumeSessionState;
|
|
117
|
-
}): Promise<HarnessAgentSession>;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
109
|
export async function resumeOrCreateSession({
|
|
121
110
|
agent,
|
|
122
111
|
chatId,
|
|
123
112
|
}: {
|
|
124
|
-
agent:
|
|
113
|
+
agent: typeof import('./agent').agent;
|
|
125
114
|
chatId: string;
|
|
126
115
|
}) {
|
|
127
116
|
const resumeFrom = states[chatId];
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
117
|
+
const sandboxId = `harness-${chatId}`;
|
|
118
|
+
const sandboxSession = resumeFrom
|
|
119
|
+
? await resumeVercelNetworkSandboxSession({ sandboxId })
|
|
120
|
+
: await createVercelNetworkSandboxSession({
|
|
121
|
+
sandboxId,
|
|
122
|
+
runtime: 'node24',
|
|
123
|
+
ports: [4000],
|
|
124
|
+
template: await agent.getSandboxTemplate(),
|
|
125
|
+
});
|
|
126
|
+
const session = await agent.createSession({
|
|
127
|
+
sessionId: chatId,
|
|
128
|
+
resumeFrom,
|
|
129
|
+
sandboxSession,
|
|
130
|
+
});
|
|
131
|
+
return { session, sandboxSession };
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
export async function detachAndPersist({
|
|
@@ -136,13 +136,15 @@ export async function detachAndPersist({
|
|
|
136
136
|
session,
|
|
137
137
|
}: {
|
|
138
138
|
chatId: string;
|
|
139
|
-
session:
|
|
139
|
+
session: Awaited<ReturnType<typeof resumeOrCreateSession>>['session'];
|
|
140
140
|
}) {
|
|
141
141
|
states[chatId] = await session.detach();
|
|
142
142
|
}
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
Use durable storage instead of an in-memory map in production.
|
|
145
|
+
Use durable storage instead of an in-memory map in production. The creator
|
|
146
|
+
always creates a new sandbox and fails on a conflicting `sandboxId`; only the
|
|
147
|
+
resume function reattaches an existing one.
|
|
146
148
|
|
|
147
149
|
## Route
|
|
148
150
|
|
|
@@ -177,7 +179,7 @@ export async function POST(request: Request) {
|
|
|
177
179
|
return createUIMessageStreamResponse({
|
|
178
180
|
stream: createUIMessageStream({
|
|
179
181
|
execute: async ({ writer }) => {
|
|
180
|
-
const session = await resumeOrCreateSession({ agent, chatId });
|
|
182
|
+
const { session } = await resumeOrCreateSession({ agent, chatId });
|
|
181
183
|
const result = await agent.stream({ session, messages });
|
|
182
184
|
|
|
183
185
|
writer.merge(
|
|
@@ -212,9 +214,10 @@ sandbox warm for the next request. Bridge-backed adapters can usually reattach
|
|
|
212
214
|
or replay efficiently. If the turn is unfinished, `detach()` includes the turn
|
|
213
215
|
continuation state in the returned resume state.
|
|
214
216
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
217
|
+
`session.stop()` saves resume state and stops the harness runtime, but does not
|
|
218
|
+
stop a supplied sandbox. The caller owns that network session and should call
|
|
219
|
+
its `destroy()` method when the chat ends, not while a later request needs to
|
|
220
|
+
reattach. Preserve the chosen `sandboxId` across processes.
|
|
218
221
|
|
|
219
222
|
## Rendering Harness Parts
|
|
220
223
|
|
|
@@ -19,15 +19,11 @@ session for the lifetime of the terminal UI.
|
|
|
19
19
|
```ts filename='tui.ts'
|
|
20
20
|
import { HarnessAgent, type HarnessAgentSession } from '@ai-sdk/harness/agent';
|
|
21
21
|
import { codex } from '@ai-sdk/harness-codex';
|
|
22
|
-
import {
|
|
22
|
+
import { createVercelNetworkSandboxSession } from '@ai-sdk/sandbox-vercel';
|
|
23
23
|
import { runAgentTUI, type AgentTUIAgent } from '@ai-sdk/tui';
|
|
24
24
|
|
|
25
25
|
const agent = new HarnessAgent({
|
|
26
26
|
harness: codex,
|
|
27
|
-
sandbox: createVercelSandbox({
|
|
28
|
-
runtime: 'node24',
|
|
29
|
-
ports: [4000],
|
|
30
|
-
}),
|
|
31
27
|
});
|
|
32
28
|
|
|
33
29
|
function createTUIAgent({
|
|
@@ -56,7 +52,12 @@ function createTUIAgent({
|
|
|
56
52
|
} as AgentTUIAgent;
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
const
|
|
55
|
+
const sandboxSession = await createVercelNetworkSandboxSession({
|
|
56
|
+
runtime: 'node24',
|
|
57
|
+
ports: [4000],
|
|
58
|
+
template: await agent.getSandboxTemplate(),
|
|
59
|
+
});
|
|
60
|
+
const session = await agent.createSession({ sandboxSession });
|
|
60
61
|
|
|
61
62
|
try {
|
|
62
63
|
await runAgentTUI({
|
|
@@ -67,6 +68,7 @@ try {
|
|
|
67
68
|
});
|
|
68
69
|
} finally {
|
|
69
70
|
await session.destroy();
|
|
71
|
+
await sandboxSession.destroy();
|
|
70
72
|
}
|
|
71
73
|
```
|
|
72
74
|
|
|
@@ -543,7 +543,7 @@ return createUIMessageStreamResponse({
|
|
|
543
543
|
if (part.type === 'start') {
|
|
544
544
|
return {
|
|
545
545
|
createdAt: Date.now(),
|
|
546
|
-
model: 'gpt-
|
|
546
|
+
model: 'gpt-6-astra',
|
|
547
547
|
};
|
|
548
548
|
}
|
|
549
549
|
|
|
@@ -947,7 +947,7 @@ Check out the [stream protocol guide](/docs/ai-sdk-ui/stream-protocol) for more
|
|
|
947
947
|
## Reasoning
|
|
948
948
|
|
|
949
949
|
Some models such as DeepSeek `deepseek-r1`
|
|
950
|
-
and Anthropic `claude-sonnet-
|
|
950
|
+
and Anthropic `claude-sonnet-5` support reasoning tokens.
|
|
951
951
|
These tokens are typically sent before the message content.
|
|
952
952
|
You can forward them to the client with the `sendReasoning` option:
|
|
953
953
|
|
|
@@ -1074,7 +1074,7 @@ messages.map(message => (
|
|
|
1074
1074
|
|
|
1075
1075
|
## Image Generation
|
|
1076
1076
|
|
|
1077
|
-
Some models such as Google `gemini-
|
|
1077
|
+
Some models such as Google `gemini-3.1-flash-image-preview` support image generation.
|
|
1078
1078
|
When images are generated, they are exposed as files to the client.
|
|
1079
1079
|
On the client side, you can access file parts of the message object
|
|
1080
1080
|
and render them as images.
|
|
@@ -179,7 +179,7 @@ export async function POST(req: Request) {
|
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
const result = streamText({
|
|
182
|
-
model: 'openai/gpt-
|
|
182
|
+
model: 'openai/gpt-6-luna',
|
|
183
183
|
messages: convertToModelMessages(validatedMessages),
|
|
184
184
|
tools,
|
|
185
185
|
});
|
|
@@ -344,7 +344,7 @@ export async function POST(req: Request) {
|
|
|
344
344
|
await req.json();
|
|
345
345
|
|
|
346
346
|
const result = streamText({
|
|
347
|
-
model: 'openai/gpt-
|
|
347
|
+
model: 'openai/gpt-6-luna',
|
|
348
348
|
messages: await convertToModelMessages(messages),
|
|
349
349
|
});
|
|
350
350
|
|
|
@@ -472,7 +472,7 @@ export async function POST(req: Request) {
|
|
|
472
472
|
});
|
|
473
473
|
|
|
474
474
|
const result = streamText({
|
|
475
|
-
model: 'openai/gpt-
|
|
475
|
+
model: 'openai/gpt-6-luna',
|
|
476
476
|
messages: await convertToModelMessages(messages),
|
|
477
477
|
});
|
|
478
478
|
|
|
@@ -128,7 +128,7 @@ export async function POST(req: Request) {
|
|
|
128
128
|
saveChat({ id, messages, activeStreamId: null });
|
|
129
129
|
|
|
130
130
|
const result = streamText({
|
|
131
|
-
model: 'openai/gpt-
|
|
131
|
+
model: 'openai/gpt-6-luna',
|
|
132
132
|
messages: await convertToModelMessages(messages),
|
|
133
133
|
});
|
|
134
134
|
|
|
@@ -38,14 +38,14 @@ At a high level, the `streamUI` works like other AI SDK Core functions: you can
|
|
|
38
38
|
|
|
39
39
|
```tsx
|
|
40
40
|
const result = await streamUI({
|
|
41
|
-
model: openai('gpt-
|
|
41
|
+
model: openai('gpt-6-astra'),
|
|
42
42
|
prompt: 'Get the weather for San Francisco',
|
|
43
43
|
text: ({ content }) => <div>{content}</div>,
|
|
44
44
|
tools: {},
|
|
45
45
|
});
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
This example calls the `streamUI` function using OpenAI's `gpt-
|
|
48
|
+
This example calls the `streamUI` function using OpenAI's `gpt-6-astra` model, passes a prompt, specifies how the model's plain text response (`content`) should be rendered, and then provides an empty object for tools. Even though this example does not define any tools, it will stream the model's response as a `div` rather than plain text.
|
|
49
49
|
|
|
50
50
|
### Adding A Tool
|
|
51
51
|
|
|
@@ -60,7 +60,7 @@ Let's expand the previous example to add a tool.
|
|
|
60
60
|
|
|
61
61
|
```tsx highlight="6-14"
|
|
62
62
|
const result = await streamUI({
|
|
63
|
-
model: openai('gpt-
|
|
63
|
+
model: openai('gpt-6-astra'),
|
|
64
64
|
prompt: 'Get the weather for San Francisco',
|
|
65
65
|
text: ({ content }) => <div>{content}</div>,
|
|
66
66
|
tools: {
|
|
@@ -138,7 +138,7 @@ const WeatherComponent = (props: WeatherProps) => (
|
|
|
138
138
|
|
|
139
139
|
export async function streamComponent() {
|
|
140
140
|
const result = await streamUI({
|
|
141
|
-
model: openai('gpt-
|
|
141
|
+
model: openai('gpt-6-astra'),
|
|
142
142
|
prompt: 'Get the weather for San Francisco',
|
|
143
143
|
text: ({ content }) => <div>{content}</div>,
|
|
144
144
|
tools: {
|
|
@@ -166,7 +166,7 @@ The `getWeather` tool should look familiar as it is identical to the example in
|
|
|
166
166
|
2. Next, define a `getWeather` function that will timeout for 2 seconds (to simulate fetching the weather externally) before returning the "weather" for a `location`. Note: you could run any asynchronous TypeScript code here.
|
|
167
167
|
3. Finally, define a `WeatherComponent` which takes in `location` and `weather` as props, which are then rendered within a `div`.
|
|
168
168
|
|
|
169
|
-
Your Server Action is an asynchronous function called `streamComponent` that takes no inputs, and returns a `ReactNode`. Within the action, you call the `streamUI` function, specifying the model (`gpt-
|
|
169
|
+
Your Server Action is an asynchronous function called `streamComponent` that takes no inputs, and returns a `ReactNode`. Within the action, you call the `streamUI` function, specifying the model (`gpt-6-astra`), the prompt, the component that should be rendered if the model chooses to return text, and finally, your `getWeather` tool. Last but not least, you return the resulting component generated by the model with `result.value`.
|
|
170
170
|
|
|
171
171
|
To call this Server Action and display the resulting React Component, you will need a page.
|
|
172
172
|
|
|
@@ -82,7 +82,7 @@ export async function submitUserMessage(input: string) {
|
|
|
82
82
|
'use server';
|
|
83
83
|
|
|
84
84
|
const ui = await streamUI({
|
|
85
|
-
model: openai('gpt-
|
|
85
|
+
model: openai('gpt-6-astra'),
|
|
86
86
|
instructions: 'you are a flight booking assistant',
|
|
87
87
|
prompt: input,
|
|
88
88
|
text: async ({ content }) => <div>{content}</div>,
|
|
@@ -214,7 +214,7 @@ import { streamUI } from '@ai-sdk/rsc';
|
|
|
214
214
|
|
|
215
215
|
export async function generateResponse(prompt: string) {
|
|
216
216
|
const result = await streamUI({
|
|
217
|
-
model: openai('gpt-
|
|
217
|
+
model: openai('gpt-6-astra'),
|
|
218
218
|
prompt,
|
|
219
219
|
text: async function* ({ content }) {
|
|
220
220
|
yield <div>loading...</div>;
|
|
@@ -47,7 +47,7 @@ export async function sendMessage(message: string) {
|
|
|
47
47
|
messages.update([...messages.get(), { role: 'user', content: message }]);
|
|
48
48
|
|
|
49
49
|
const { value: stream } = await streamUI({
|
|
50
|
-
model: openai('gpt-
|
|
50
|
+
model: openai('gpt-6-astra'),
|
|
51
51
|
instructions: 'you are a friendly assistant!',
|
|
52
52
|
messages: messages.get(),
|
|
53
53
|
text: async function* ({ content, done }) {
|
|
@@ -187,7 +187,7 @@ import { getWeather } from '@/utils/queries';
|
|
|
187
187
|
import { Weather } from '@/components/weather';
|
|
188
188
|
|
|
189
189
|
const { value: stream } = await streamUI({
|
|
190
|
-
model: openai('gpt-
|
|
190
|
+
model: openai('gpt-6-astra'),
|
|
191
191
|
instructions: 'you are a friendly assistant!',
|
|
192
192
|
messages,
|
|
193
193
|
text: async function* ({ content, done }) {
|
|
@@ -399,7 +399,7 @@ import { openai } from '@ai-sdk/openai';
|
|
|
399
399
|
import { streamUI } from '@ai-sdk/rsc';
|
|
400
400
|
|
|
401
401
|
const { value: stream } = await streamUI({
|
|
402
|
-
model: openai('gpt-
|
|
402
|
+
model: openai('gpt-6-astra'),
|
|
403
403
|
instructions: 'you are a friendly assistant!',
|
|
404
404
|
messages,
|
|
405
405
|
initial: <div>Loading...</div>,
|
|
@@ -45,6 +45,45 @@ When the SDK fetches a URL taken from a provider response, it:
|
|
|
45
45
|
|
|
46
46
|
A blocked URL surfaces as a `DownloadError`.
|
|
47
47
|
|
|
48
|
+
## Fetching untrusted URLs directly
|
|
49
|
+
|
|
50
|
+
For custom integrations using `@ai-sdk/provider-utils`, use `fetchUntrustedUrl`
|
|
51
|
+
when the URL comes from a response or other untrusted input. It validates URLs
|
|
52
|
+
and redirects and withholds credentials and unknown custom headers on the first
|
|
53
|
+
request unless the URL matches a configured origin:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { fetchUntrustedUrl } from '@ai-sdk/provider-utils';
|
|
57
|
+
|
|
58
|
+
const response = await fetchUntrustedUrl({
|
|
59
|
+
url: result.downloadUrl,
|
|
60
|
+
headers: {
|
|
61
|
+
authorization: `Bearer ${apiKey}`,
|
|
62
|
+
accept: 'image/*',
|
|
63
|
+
},
|
|
64
|
+
credentialedOrigin: providerBaseURL,
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Here, `Authorization` is sent only when the initial URL has the same origin as
|
|
69
|
+
`providerBaseURL`. Otherwise, only allowlisted metadata such as `Accept`,
|
|
70
|
+
`Range`, and `User-Agent` is sent. A cross-origin redirect drops all caller
|
|
71
|
+
headers except `User-Agent`, and credentials are never reattached on later hops.
|
|
72
|
+
|
|
73
|
+
`credentialedOrigin` must come from your configuration, never from the response
|
|
74
|
+
URL. It does not disable URL validation. For a configured private endpoint, pass
|
|
75
|
+
`trustedOrigin` as well; if `credentialedOrigin` is omitted, `fetchUntrustedUrl`
|
|
76
|
+
uses `trustedOrigin` as the origin allowed to receive credentials. Extra protocol
|
|
77
|
+
metadata can be allowed with `untrustedFirstHopHeaders: ['x-protocol-version']`.
|
|
78
|
+
Only list headers that are safe to disclose to any destination; use a configured
|
|
79
|
+
origin for credentials.
|
|
80
|
+
|
|
81
|
+
The existing `fetchWithValidatedRedirects` helper preserves its first-request
|
|
82
|
+
behavior: it sanitizes risky headers but still forwards authentication and
|
|
83
|
+
custom headers. Switch to `fetchUntrustedUrl` to opt into first-request
|
|
84
|
+
credential isolation. Existing calls to `getFromApi` also retain their behavior;
|
|
85
|
+
pass `credentialedOrigin` when fetching response-supplied URLs with credentials.
|
|
86
|
+
|
|
48
87
|
## Self-hosted and local endpoints
|
|
49
88
|
|
|
50
89
|
URLs that are same-origin with the provider endpoint **you configured** (e.g. a
|
|
@@ -40,7 +40,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
40
40
|
{
|
|
41
41
|
name: 'model',
|
|
42
42
|
type: 'LanguageModel',
|
|
43
|
-
description: "The language model to use. Example: openai('gpt-
|
|
43
|
+
description: "The language model to use. Example: openai('gpt-6-astra')",
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
name: 'instructions',
|
|
@@ -1117,7 +1117,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
1117
1117
|
{
|
|
1118
1118
|
name: 'modelId',
|
|
1119
1119
|
type: 'string',
|
|
1120
|
-
description:
|
|
1120
|
+
description:
|
|
1121
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
1121
1122
|
},
|
|
1122
1123
|
{
|
|
1123
1124
|
name: 'instructions',
|
|
@@ -1269,7 +1270,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
1269
1270
|
{
|
|
1270
1271
|
name: 'modelId',
|
|
1271
1272
|
type: 'string',
|
|
1272
|
-
description:
|
|
1273
|
+
description:
|
|
1274
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
1273
1275
|
},
|
|
1274
1276
|
{
|
|
1275
1277
|
name: 'instructions',
|
|
@@ -42,7 +42,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
42
42
|
{
|
|
43
43
|
name: 'model',
|
|
44
44
|
type: 'LanguageModel',
|
|
45
|
-
description: "The language model to use. Example: openai('gpt-
|
|
45
|
+
description: "The language model to use. Example: openai('gpt-6-astra')",
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
name: 'instructions',
|
|
@@ -2131,7 +2131,8 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
2131
2131
|
{
|
|
2132
2132
|
name: 'modelId',
|
|
2133
2133
|
type: 'string',
|
|
2134
|
-
description:
|
|
2134
|
+
description:
|
|
2135
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
2135
2136
|
},
|
|
2136
2137
|
{
|
|
2137
2138
|
name: 'instructions',
|
|
@@ -2283,7 +2284,8 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
2283
2284
|
{
|
|
2284
2285
|
name: 'modelId',
|
|
2285
2286
|
type: 'string',
|
|
2286
|
-
description:
|
|
2287
|
+
description:
|
|
2288
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
2287
2289
|
},
|
|
2288
2290
|
{
|
|
2289
2291
|
name: 'instructions',
|
|
@@ -14,7 +14,7 @@ import { cohere } from '@ai-sdk/cohere';
|
|
|
14
14
|
import { rerank } from 'ai';
|
|
15
15
|
|
|
16
16
|
const { ranking } = await rerank({
|
|
17
|
-
model: cohere.reranking('rerank-
|
|
17
|
+
model: cohere.reranking('rerank-v4.0-pro'),
|
|
18
18
|
documents: ['sunny day at the beach', 'rainy afternoon in the city'],
|
|
19
19
|
query: 'talk about rain',
|
|
20
20
|
});
|
|
@@ -34,7 +34,7 @@ const { ranking } = await rerank({
|
|
|
34
34
|
name: 'model',
|
|
35
35
|
type: 'RerankingModel',
|
|
36
36
|
description:
|
|
37
|
-
"The reranking model to use. Example: cohere.reranking('rerank-
|
|
37
|
+
"The reranking model to use. Example: cohere.reranking('rerank-v4.0-pro')",
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
name: 'documents',
|
|
@@ -262,7 +262,7 @@ import { cohere } from '@ai-sdk/cohere';
|
|
|
262
262
|
import { rerank } from 'ai';
|
|
263
263
|
|
|
264
264
|
const { ranking, rerankedDocuments } = await rerank({
|
|
265
|
-
model: cohere.reranking('rerank-
|
|
265
|
+
model: cohere.reranking('rerank-v4.0-pro'),
|
|
266
266
|
documents: [
|
|
267
267
|
'sunny day at the beach',
|
|
268
268
|
'rainy afternoon in the city',
|
|
@@ -302,7 +302,7 @@ const documents = [
|
|
|
302
302
|
];
|
|
303
303
|
|
|
304
304
|
const { ranking } = await rerank({
|
|
305
|
-
model: cohere.reranking('rerank-
|
|
305
|
+
model: cohere.reranking('rerank-v4.0-pro'),
|
|
306
306
|
documents,
|
|
307
307
|
query: 'Which pricing did we get from Oracle?',
|
|
308
308
|
topN: 1,
|
|
@@ -319,7 +319,7 @@ import { cohere } from '@ai-sdk/cohere';
|
|
|
319
319
|
import { rerank } from 'ai';
|
|
320
320
|
|
|
321
321
|
const { ranking } = await rerank({
|
|
322
|
-
model: cohere.reranking('rerank-
|
|
322
|
+
model: cohere.reranking('rerank-v4.0-pro'),
|
|
323
323
|
documents: ['sunny day at the beach', 'rainy afternoon in the city'],
|
|
324
324
|
query: 'talk about rain',
|
|
325
325
|
providerOptions: {
|
|
@@ -13,7 +13,7 @@ import { openai } from '@ai-sdk/openai';
|
|
|
13
13
|
import { readFile } from 'fs/promises';
|
|
14
14
|
|
|
15
15
|
const { text: transcript } = await transcribe({
|
|
16
|
-
model: openai.transcription('
|
|
16
|
+
model: openai.transcription('gpt-4o-transcribe'),
|
|
17
17
|
audio: await readFile('audio.mp3'),
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -12,7 +12,7 @@ import { generateSpeech } from 'ai';
|
|
|
12
12
|
import { openai } from '@ai-sdk/openai';
|
|
13
13
|
|
|
14
14
|
const { audio } = await generateSpeech({
|
|
15
|
-
model: openai.speech('tts
|
|
15
|
+
model: openai.speech('gpt-4o-mini-tts'),
|
|
16
16
|
text: 'Hello from the AI SDK!',
|
|
17
17
|
voice: 'alloy',
|
|
18
18
|
});
|
|
@@ -29,7 +29,7 @@ import { generateSpeech } from 'ai';
|
|
|
29
29
|
import { openai } from '@ai-sdk/openai';
|
|
30
30
|
|
|
31
31
|
const { audio } = await generateSpeech({
|
|
32
|
-
model: openai.speech('tts
|
|
32
|
+
model: openai.speech('gpt-4o-mini-tts'),
|
|
33
33
|
text: 'Hello from the AI SDK!',
|
|
34
34
|
voice: 'alloy',
|
|
35
35
|
});
|
|
@@ -172,7 +172,8 @@ To see `ToolLoopAgent` in action, check out [these examples](#examples).
|
|
|
172
172
|
{
|
|
173
173
|
name: 'modelId',
|
|
174
174
|
type: 'string',
|
|
175
|
-
description:
|
|
175
|
+
description:
|
|
176
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
176
177
|
},
|
|
177
178
|
{
|
|
178
179
|
name: 'instructions',
|
|
@@ -319,7 +320,8 @@ To see `ToolLoopAgent` in action, check out [these examples](#examples).
|
|
|
319
320
|
{
|
|
320
321
|
name: 'modelId',
|
|
321
322
|
type: 'string',
|
|
322
|
-
description:
|
|
323
|
+
description:
|
|
324
|
+
'The specific model identifier (e.g., "gpt-6-astra").',
|
|
323
325
|
},
|
|
324
326
|
{
|
|
325
327
|
name: 'instructions',
|
|
@@ -62,7 +62,7 @@ import { generateText } from 'ai';
|
|
|
62
62
|
import { registry } from './registry';
|
|
63
63
|
|
|
64
64
|
const { text } = await generateText({
|
|
65
|
-
model: registry.languageModel('openai:gpt-
|
|
65
|
+
model: registry.languageModel('openai:gpt-6-astra'),
|
|
66
66
|
prompt: 'Invent a new holiday and describe its traditions.',
|
|
67
67
|
});
|
|
68
68
|
```
|
|
@@ -24,8 +24,8 @@ import { customProvider } from 'ai';
|
|
|
24
24
|
export const myOpenAI = customProvider({
|
|
25
25
|
languageModels: {
|
|
26
26
|
// replacement model with custom settings:
|
|
27
|
-
'gpt-
|
|
28
|
-
model: openai('gpt-
|
|
27
|
+
'gpt-6-astra': wrapLanguageModel({
|
|
28
|
+
model: openai('gpt-6-astra'),
|
|
29
29
|
middleware: defaultSettingsMiddleware({
|
|
30
30
|
settings: {
|
|
31
31
|
providerOptions: {
|
|
@@ -37,8 +37,8 @@ export const myOpenAI = customProvider({
|
|
|
37
37
|
}),
|
|
38
38
|
}),
|
|
39
39
|
// alias model with custom settings:
|
|
40
|
-
'gpt-
|
|
41
|
-
model: openai('gpt-
|
|
40
|
+
'gpt-6-astra-reasoning-high': wrapLanguageModel({
|
|
41
|
+
model: openai('gpt-6-astra'),
|
|
42
42
|
middleware: defaultSettingsMiddleware({
|
|
43
43
|
settings: {
|
|
44
44
|
providerOptions: {
|
|
@@ -13,7 +13,7 @@ See [Language Model Middleware](/docs/ai-sdk-core/middleware) for more informati
|
|
|
13
13
|
import { wrapLanguageModel, gateway } from 'ai';
|
|
14
14
|
|
|
15
15
|
const wrappedLanguageModel = wrapLanguageModel({
|
|
16
|
-
model: gateway('openai/gpt-
|
|
16
|
+
model: gateway('openai/gpt-6-astra'),
|
|
17
17
|
middleware: yourLanguageModelMiddleware,
|
|
18
18
|
});
|
|
19
19
|
```
|
|
@@ -13,7 +13,7 @@ import { generateImage, wrapImageModel } from 'ai';
|
|
|
13
13
|
import { openai } from '@ai-sdk/openai';
|
|
14
14
|
|
|
15
15
|
const model = wrapImageModel({
|
|
16
|
-
model: openai.image('gpt-image-2'),
|
|
16
|
+
model: openai.image('gpt-image-2.5-sunburst'),
|
|
17
17
|
middleware: yourImageModelMiddleware,
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -202,7 +202,7 @@ import { DirectChatTransport, ToolLoopAgent } from 'ai';
|
|
|
202
202
|
import { openai } from '@ai-sdk/openai';
|
|
203
203
|
|
|
204
204
|
const agent = new ToolLoopAgent({
|
|
205
|
-
model: openai('gpt-
|
|
205
|
+
model: openai('gpt-6-astra'),
|
|
206
206
|
instructions: 'You are a helpful assistant.',
|
|
207
207
|
});
|
|
208
208
|
|
|
@@ -246,7 +246,7 @@ const weatherTool = tool({
|
|
|
246
246
|
});
|
|
247
247
|
|
|
248
248
|
const agent = new ToolLoopAgent({
|
|
249
|
-
model: openai('gpt-
|
|
249
|
+
model: openai('gpt-6-astra'),
|
|
250
250
|
instructions: 'You are a helpful assistant with access to weather data.',
|
|
251
251
|
tools: { weather: weatherTool },
|
|
252
252
|
});
|
|
@@ -268,7 +268,7 @@ import { DirectChatTransport, ToolLoopAgent } from 'ai';
|
|
|
268
268
|
import { openai } from '@ai-sdk/openai';
|
|
269
269
|
|
|
270
270
|
const agent = new ToolLoopAgent<{ userId: string }>({
|
|
271
|
-
model: openai('gpt-
|
|
271
|
+
model: openai('gpt-6-astra'),
|
|
272
272
|
prepareCall: ({ options, ...rest }) => ({
|
|
273
273
|
...rest,
|
|
274
274
|
providerOptions: {
|
|
@@ -26,7 +26,7 @@ To see `streamUI` in action, check out [these examples](#examples).
|
|
|
26
26
|
{
|
|
27
27
|
name: 'model',
|
|
28
28
|
type: 'LanguageModel',
|
|
29
|
-
description: 'The language model to use. Example: openai("gpt-
|
|
29
|
+
description: 'The language model to use. Example: openai("gpt-6-astra")',
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
name: 'initial',
|