@amjadiqbal/tanstack-ai-sdk-bridge 0.0.0-stage → 0.1.1

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 ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@amjadiqbal/tanstack-ai-sdk-bridge` are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.1.1] - 2026-10-23
9
+
10
+ ### Fixed
11
+
12
+ - `aiSdkSpeech`: the result's `format` and `contentType` now come from what the provider returned (its `content-type` header, else the audio bytes), then the requested format, else `unknown`. Before, it reported `mp3` whenever no format was requested.
13
+
14
+ ### Added
15
+
16
+ - `aiSdkImage`: `modelOptions.mask` is sent to AI SDK v3/v4 image models (it was never sent before).
17
+
18
+ ### Documentation
19
+
20
+ - README states exactly which activities can be aborted (not `embed()`), what `outputSchema` does in the bridge (one non-streaming call without tools, JSON parsing, error cases; `chat()` validates), how `dimensions` behaves on v2/v3 embedding models, which transcription options are not sent, how speech reports its format, the image options and defaults, why `@ai-sdk/provider` is a dependency, and the `@tanstack/ai/adapter-internals` import.
21
+ - Removed the untested `deepgram` keyword.
22
+
23
+ ## [0.1.0] - 2026-10-23
24
+
25
+ ### Added
26
+
27
+ - `aiSdkText()`: AI SDK language models as TanStack AI text adapters, with streaming text, tool calls, reasoning, structured output, token usage and abort.
28
+ - `aiSdkEmbedding()`, `aiSdkTranscription()`, `aiSdkSpeech()`, `aiSdkImage()` and `aiSdkRerank()` for the other AI SDK model kinds.
29
+ - Support for AI SDK provider spec v2, v3 and v4 (AI SDK 5, 6 and 7 providers).
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Amjad Iqbal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,269 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="art/banner-dark.png">
4
+ <img alt="AI SDK Bridge: any Vercel AI SDK provider as a TanStack AI adapter" src="art/banner-light.png" width="100%">
5
+ </picture>
6
+ </p>
2
7
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
8
+ # TanStack AI SDK Bridge: use Vercel AI SDK providers with TanStack AI
9
+
10
+ Use any Vercel AI SDK provider (`@ai-sdk/*` and community providers) as a [TanStack AI](https://tanstack.com/ai) adapter. The bridge reads the AI SDK provider spec (v2, v3 and v4), so a provider package works with `chat()`, `embed()`, `generateTranscription()`, `generateSpeech()`, `generateImage()` and `rerank()` without a dedicated TanStack adapter. It is also the shortest path for moving an AI SDK app to TanStack AI: keep your provider setup and change the rest step by step.
11
+
12
+ Tested with: `@ai-sdk/deepseek`, `@ai-sdk/anthropic`, `@ai-sdk/openai`, `@ai-sdk/togetherai`, `@ai-sdk/cerebras`, `@ai-sdk/fireworks`, `@ai-sdk/cohere` (rerank), `ollama-ai-provider-v2` and `@ai-sdk/openai-compatible` 1.x, 2.x and 3.x (AI SDK 5, 6 and 7). See [What is tested](#what-is-tested).
13
+
14
+ [![npm](https://img.shields.io/npm/v/@amjadiqbal/tanstack-ai-sdk-bridge?style=flat-square)](https://www.npmjs.com/package/@amjadiqbal/tanstack-ai-sdk-bridge)
15
+ [![TanStack AI](https://img.shields.io/badge/TanStack%20AI-1.x-8B5CF6?style=flat-square)](https://tanstack.com/ai)
16
+ [![License](https://img.shields.io/npm/l/@amjadiqbal/tanstack-ai-sdk-bridge?style=flat-square)](LICENSE.md)
17
+
18
+ ```ts
19
+ import { chat } from '@tanstack/ai'
20
+ import { aiSdkText } from '@amjadiqbal/tanstack-ai-sdk-bridge'
21
+ import { deepseek } from '@ai-sdk/deepseek'
22
+
23
+ const stream = chat({
24
+ adapter: aiSdkText(deepseek('deepseek-chat')),
25
+ messages: [{ role: 'user', content: 'Hello!' }],
26
+ threadId: 'thread-1',
27
+ })
28
+ ```
29
+
30
+ - **Text**: streaming chat, tool calls (TanStack's agent loop runs your tools), reasoning, structured output (`outputSchema`), token usage, abort (see [Abort](#abort)).
31
+ - **Embeddings, transcription, speech, image generation, rerank**: one adapter function each.
32
+ - **AI SDK 5, 6 and 7 providers**: provider spec v2, v3 and v4 are all read.
33
+ - **No AI SDK runtime code**: the built package imports only `@tanstack/ai`. `@ai-sdk/provider` is a dependency because the published type declarations use its model types; nothing from it runs. No `ai` package needed.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ npm i @amjadiqbal/tanstack-ai-sdk-bridge @tanstack/ai
39
+ ```
40
+
41
+ Then the AI SDK provider you want, for example `npm i @ai-sdk/deepseek`. Requires `@tanstack/ai` 1.x and Node 20+.
42
+
43
+ ## Usage
44
+
45
+ ### Chat with a TanStack Start (or any Fetch API) route
46
+
47
+ ```ts
48
+ // src/routes/api/chat.ts
49
+ import { createFileRoute } from '@tanstack/react-router'
50
+ import { chat, toServerSentEventsResponse } from '@tanstack/ai'
51
+ import { aiSdkText } from '@amjadiqbal/tanstack-ai-sdk-bridge'
52
+ import { createDeepSeek } from '@ai-sdk/deepseek'
53
+
54
+ const deepseek = createDeepSeek({ apiKey: process.env.DEEPSEEK_API_KEY })
55
+
56
+ export const Route = createFileRoute('/api/chat')({
57
+ server: {
58
+ handlers: {
59
+ POST: async ({ request }) => {
60
+ const { messages, threadId } = await request.json()
61
+ const stream = chat({
62
+ adapter: aiSdkText(deepseek('deepseek-chat')),
63
+ messages,
64
+ threadId,
65
+ systemPrompts: ['You are a helpful assistant.'],
66
+ modelOptions: { temperature: 0.3, maxOutputTokens: 1024 },
67
+ })
68
+ return toServerSentEventsResponse(stream)
69
+ },
70
+ },
71
+ },
72
+ })
73
+ ```
74
+
75
+ The client is plain TanStack AI; nothing from this package runs in the browser:
76
+
77
+ ```tsx
78
+ import { useChat, fetchServerSentEvents } from '@tanstack/ai-react'
79
+
80
+ const { messages, sendMessage, isLoading, stop } = useChat({
81
+ connection: fetchServerSentEvents('/api/chat'),
82
+ })
83
+ ```
84
+
85
+ ### Tools
86
+
87
+ Tools are TanStack AI tools. The bridge sends their JSON Schema to the AI SDK model and streams the calls back, and `chat()` runs them.
88
+
89
+ ```ts
90
+ import { chat, toolDefinition } from '@tanstack/ai'
91
+ import { z } from 'zod'
92
+
93
+ const getWeather = toolDefinition({
94
+ name: 'getWeather',
95
+ description: 'Get the weather for a city',
96
+ inputSchema: z.object({ city: z.string() }),
97
+ }).server(async ({ city }) => ({ city, tempC: 21 }))
98
+
99
+ chat({ adapter: aiSdkText(deepseek('deepseek-chat')), messages, threadId, tools: [getWeather] })
100
+ ```
101
+
102
+ ### Structured output
103
+
104
+ ```ts
105
+ const product = await chat({
106
+ adapter: aiSdkText(deepseek('deepseek-chat')),
107
+ messages: [{ role: 'user', content: 'Invent a product.' }],
108
+ threadId: 'product-1',
109
+ outputSchema: z.object({ name: z.string(), price: z.number() }),
110
+ stream: false,
111
+ })
112
+ // product: { name: string; price: number }
113
+ ```
114
+
115
+ What the bridge does for `outputSchema`, exactly:
116
+
117
+ - After the agent loop, TanStack AI calls the adapter's `structuredOutput()`. The bridge makes **one non-streaming** `doGenerate` call with the conversation, **without tools**, and `responseFormat: { type: 'json', schema }` (the JSON Schema TanStack AI made from your schema). Whether the provider enforces the schema depends on the provider.
118
+ - It joins the text parts of the answer and parses them as JSON. An answer wrapped in a Markdown code fence is accepted.
119
+ - It throws `Structured output generation failed: ...` (original error as `cause`) when the answer was cut off at the token limit, when the text is not JSON, or when the provider call fails.
120
+ - The bridge does not check the data against the schema; `chat()` does that with your schema after the bridge returns.
121
+ - `structuredOutputStream` and combined tools-plus-schema in one request are not implemented, so TanStack AI uses its non-streaming path.
122
+
123
+ ### Reasoning
124
+
125
+ `chat({ reasoning: 'high' })` sets the AI SDK `reasoning` call option on AI SDK 7 (spec v4) models, and reasoning deltas stream as TanStack reasoning events. `'off'` becomes `'none'`. For AI SDK 5 and 6 providers, set reasoning in `modelOptions.providerOptions` the way that provider documents it.
126
+
127
+ ### Model options
128
+
129
+ `modelOptions` takes the AI SDK call settings and passes them through:
130
+
131
+ | Option | AI SDK call option |
132
+ |---|---|
133
+ | `temperature`, `topP`, `topK`, `presencePenalty`, `frequencyPenalty`, `seed`, `stopSequences`, `maxOutputTokens` | same name |
134
+ | `providerOptions` | `providerOptions`, e.g. `{ deepseek: { ... } }` |
135
+ | `headers` | `headers` |
136
+
137
+ ### Embeddings
138
+
139
+ ```ts
140
+ import { embed } from '@tanstack/ai'
141
+ import { aiSdkEmbedding } from '@amjadiqbal/tanstack-ai-sdk-bridge'
142
+ import { openai } from '@ai-sdk/openai'
143
+
144
+ const { embeddings } = await embed({
145
+ adapter: aiSdkEmbedding(openai.embedding('text-embedding-3-small')),
146
+ input: ['red guitar', 'blue drum kit'],
147
+ })
148
+ ```
149
+
150
+ Large inputs are split by the model's `maxEmbeddingsPerCall`. `dimensions` is sent to AI SDK 7 (spec v4) embedding models. On spec v2/v3 models the bridge throws if `dimensions` is set, because their spec has no such field: leave it unset and pass the provider's own option instead, for example `modelOptions: { providerOptions: { openai: { dimensions: 512 } } }`.
151
+
152
+ ### Transcription, speech, image, rerank
153
+
154
+ ```ts
155
+ import { generateImage, generateSpeech, generateTranscription, rerank } from '@tanstack/ai'
156
+ import { aiSdkImage, aiSdkRerank, aiSdkSpeech, aiSdkTranscription } from '@amjadiqbal/tanstack-ai-sdk-bridge'
157
+
158
+ import { openai } from '@ai-sdk/openai'
159
+ import { cohere } from '@ai-sdk/cohere'
160
+
161
+ const threadId = 'media-1'
162
+ await generateTranscription({ threadId, adapter: aiSdkTranscription(openai.transcription('whisper-1')), audio: file })
163
+ await generateSpeech({ threadId, adapter: aiSdkSpeech(openai.speech('gpt-4o-mini-tts')), text: 'Hello', voice: 'alloy' })
164
+ await generateImage({ threadId, adapter: aiSdkImage(openai.image('gpt-image-1')), prompt: 'a lighthouse at dusk' })
165
+ await rerank({ adapter: aiSdkRerank(cohere.reranking('rerank-v3.5')), query: 'refund policy', documents })
166
+ ```
167
+
168
+ | TanStack AI | Bridge | AI SDK model | Spec versions |
169
+ |---|---|---|---|
170
+ | `chat()` | `aiSdkText(model)` | `LanguageModel` | v2, v3, v4 |
171
+ | `embed()` | `aiSdkEmbedding(model)` | `EmbeddingModel` | v2, v3, v4 |
172
+ | `generateTranscription()` | `aiSdkTranscription(model)` | `TranscriptionModel` | v2, v3, v4 |
173
+ | `generateSpeech()` | `aiSdkSpeech(model)` | `SpeechModel` | v2, v3, v4 |
174
+ | `generateImage()` | `aiSdkImage(model)` | `ImageModel` | v2, v3, v4 |
175
+ | `rerank()` | `aiSdkRerank(model)` | `RerankingModel` | v3, v4 |
176
+
177
+ Activity-specific `modelOptions`, on top of `providerOptions` and `headers`:
178
+
179
+ | Adapter | `modelOptions` | Notes |
180
+ |---|---|---|
181
+ | `aiSdkTranscription` | `mediaType` | Media type of the audio when it can't be read from a `Blob`/`File` type or a data URL. Default `audio/mpeg`. `language`, `prompt` and `responseFormat` are not sent (the AI SDK spec has no such fields); the result has `text`, plus `segments`, `language` and `duration` when the provider returns them. An `http(s)` URL as `audio` is downloaded with the global `fetch`, not the provider's `fetch`. |
182
+ | `aiSdkSpeech` | `instructions`, `language` | Sent as the AI SDK `instructions` and `language` call options. The result's `format` and `contentType` come from the provider's `content-type` header, else from the audio bytes (MP3, WAV, Ogg, FLAC, AAC), else the `format` you asked for, else `unknown`. |
183
+ | `aiSdkImage` | `aspectRatio`, `seed`, `mask` | Sent as the AI SDK call options. `mask` is an AI SDK image file (`{ type: 'file', mediaType, data }` or `{ type: 'url', url }`). Image parts in the prompt become input `files`. Input images and masks need a spec v3/v4 model; v2 models throw. When the model does not report `maxImagesPerCall`, one image is requested per call (the AI SDK's own default) until `numberOfImages` is reached. |
184
+
185
+ Every function takes an optional second argument `{ name }`, the adapter name TanStack AI shows in devtools and usage. It defaults to the provider id before the first dot (`deepseek.chat` becomes `deepseek`).
186
+
187
+ ### Abort
188
+
189
+ | Activity | How to cancel | Passed to the AI SDK model |
190
+ |---|---|---|
191
+ | `chat()` | `abortController` (or the `request` signal) | yes: `abortSignal`, and the stream is cancelled |
192
+ | `generateTranscription()`, `generateSpeech()`, `generateImage()`, `rerank()` | `abortSignal` | yes |
193
+ | `embed()` | none: TanStack AI's `embed()` takes no signal | no |
194
+
195
+ ## Migrating from the Vercel AI SDK
196
+
197
+ TanStack's own [migration guide](https://tanstack.com/ai/latest/docs/migration/migration-from-vercel-ai) swaps your provider packages for TanStack adapters. With the bridge you can skip that step, and keep providers that have no TanStack adapter:
198
+
199
+ | Vercel AI SDK | TanStack AI with the bridge |
200
+ |---|---|
201
+ | `streamText({ model: deepseek('deepseek-chat'), ... })` | `chat({ adapter: aiSdkText(deepseek('deepseek-chat')), ... })` |
202
+ | `generateText(...)` | `chat({ ..., stream: false })` |
203
+ | `generateObject({ schema })` | `chat({ ..., outputSchema })` |
204
+ | `embedMany({ model: openai.embedding(...) })` | `embed({ adapter: aiSdkEmbedding(openai.embedding(...)) })` |
205
+ | `transcribe`, `generateSpeech`, `generateImage`, `rerank` | `generateTranscription`, `generateSpeech`, `generateImage`, `rerank` with the matching `aiSdk*` adapter |
206
+ | `system: '...'` | `systemPrompts: ['...']` |
207
+ | `temperature`, `maxOutputTokens`, `providerOptions` | `modelOptions: { temperature, maxOutputTokens, providerOptions }` |
208
+ | `tool({ inputSchema, execute })` | `toolDefinition({ inputSchema }).server(execute)` |
209
+ | `useChat` from `@ai-sdk/react` | `useChat` from `@tanstack/ai-react` |
210
+ | `result.toUIMessageStreamResponse()` | `toServerSentEventsResponse(stream)` |
211
+
212
+ A practical order: move the server route and client first with the bridge, ship, then replace a bridged provider with a native TanStack adapter later if one exists and you need its typed per-model options.
213
+
214
+ ## What is tested
215
+
216
+ Everything below ran on 2026-10-23 with `@tanstack/ai` 1.0.0. **No live provider API was called and no API key was used**: the real provider packages talked HTTP to [aimock](https://github.com/CopilotKit/aimock) 1.46, a local server that speaks each provider's wire format. That covers the request and stream formats, not every model's behaviour.
217
+
218
+ | Provider package | Spec | Chat stream | Tool loop | Structured output | Other |
219
+ |---|---|---|---|---|---|
220
+ | `@ai-sdk/deepseek` 3.0 | v4 | ✓ | ✓ | ✓ | reasoning ✓ |
221
+ | `@ai-sdk/anthropic` 4.0 | v4 | ✓ | ✓ | ✓ | reasoning ✓ |
222
+ | `@ai-sdk/openai` 4.0 (Responses and Chat Completions) | v4 | ✓ | ✓ | ✓ | embeddings, image, speech, transcription ✓ |
223
+ | `@ai-sdk/togetherai` 3.0 | v4 | ✓ | ✓ | ✓ | |
224
+ | `@ai-sdk/cerebras` 3.0 | v4 | ✓ | ✓ | ✓ | |
225
+ | `@ai-sdk/fireworks` 3.0 | v4 | ✓ | ✓ | ✓ | |
226
+ | `ollama-ai-provider-v2` 4.1 | v4 | ✓ | ✓ | ✓ | |
227
+ | `@ai-sdk/cohere` 4.0 | v4 | | | | rerank ✓ |
228
+ | `@ai-sdk/openai-compatible` 3.x / 2.x / 1.x (AI SDK 7 / 6 / 5) | v4 / v3 / v2 | ✓ | ✓ | ✓ | |
229
+
230
+ - **Unit tests** run every adapter against AI SDK's own `MockLanguageModelV3/V4`, `MockEmbeddingModelV4`, `MockTranscriptionModelV4`, `MockSpeechModelV4`, `MockImageModelV4` and `MockRerankingModelV4` (from `ai/test`) and hand-written spec v2 models, through the real `chat()`, `embed()`, `generateTranscription()`, `generateSpeech()`, `generateImage()` and `rerank()`: streaming, tool calls with and without input deltas, `toolChoice`, reasoning levels, errors, abort, structured output, batching by `maxEmbeddingsPerCall` and `maxImagesPerCall`, and v2/v3/v4 file parts.
231
+ - **In a real browser**: a TanStack Start 1.169 app with `@tanstack/ai-react` `useChat`, a `/api/chat` server route as in the example above, and the packed npm tarball installed. Seen working: streamed replies through `@ai-sdk/deepseek` and `@ai-sdk/anthropic`, a server tool call and its result followed by the final answer, reasoning shown before the answer, a second turn on the same thread, the Stop button ending a stream mid-reply, structured output through both providers, and embeddings through `@ai-sdk/openai`.
232
+ - **Not tested**: live provider APIs, other AI SDK providers, Vue/Solid/Svelte clients (the bridge runs on the server, so the client framework should not matter), and Cohere chat/embeddings and Ollama embeddings (aimock's responses for those fail the providers' own validation).
233
+
234
+ ## Limits
235
+
236
+ - **Provider-executed tools** (an AI SDK provider's own web search, code execution and the like) are not forwarded; function tools are.
237
+ - **Reasoning signatures** are not sent back, so providers that need signed thinking blocks in later turns (Anthropic extended thinking with tools) receive the reasoning as plain text or drop it.
238
+ - `chat({ wrapFetch })` is not applied; pass a custom `fetch` to the provider factory (`createDeepSeek({ fetch })`).
239
+ - Provider file handles (`{ type: 'file' }` sources) are rejected; send images and documents as data or URLs.
240
+ - Transcription `language`, `prompt` and `responseFormat` are not sent; see the options table.
241
+ - Embeddings cannot be aborted (TanStack AI's `embed()` has no signal).
242
+ - **TanStack AI internals:** like TanStack's own adapters, the bridge imports helpers (`transformMessagesForReplay`, `tanstackMetadata`, `toRunErrorPayload`) from `@tanstack/ai/adapter-internals`, the subpath TanStack's [community adapter guide](https://tanstack.com/ai/latest/docs/community-adapters/guide) points adapters to. It is not covered by the same stability promise as the main entry. Tested with `@tanstack/ai` 1.0.0; the peer range is `^1.0.0`. If a 1.x release breaks it, please open an issue.
243
+ - AI SDK reranking models report no token usage, so `rerank()` usage is zero.
244
+ - Video, audio generation and realtime models are not bridged yet.
245
+
246
+ ## Support
247
+
248
+ - 🐛 **Bug or feature request**: [open an issue](https://github.com/amjadiqbal/tanstack-ai-sdk-bridge/issues)
249
+ - 🔒 **Security issue**: please report privately via GitHub's security tab
250
+
251
+ ## Need this built into your app, or something custom?
252
+
253
+ [Get in touch](https://amjad.com.pk/contact?utm_source=github&utm_medium=readme&utm_campaign=tanstack-ai-sdk-bridge).
254
+
255
+ [![Hire me on Upwork](https://img.shields.io/badge/Hire%20me-Upwork-6FDA44?style=flat-square&logo=upwork&logoColor=white)](https://www.upwork.com/freelancers/amjadkhatri)
256
+
257
+ ## More packages
258
+
259
+ Part of a family of open-source packages. See [all of them](https://github.com/amjadiqbal?tab=repositories).
260
+
261
+ | | |
262
+ |---|---|
263
+ | [query-key-kit](https://github.com/amjadiqbal/query-key-kit) | Typed query-key hierarchy and invalidation helpers for TanStack Query v5 |
264
+ | [start-seo-kit](https://github.com/amjadiqbal/start-seo-kit) | SEO for TanStack Start: meta tags, sitemaps, JSON-LD |
265
+ | [tanstack-table-url-state](https://github.com/amjadiqbal/tanstack-table-url-state) | URL state and CSV/XLSX export for TanStack Table |
266
+
267
+ ## License
268
+
269
+ MIT. See [LICENSE.md](LICENSE.md). Not affiliated with TanStack or Vercel; "AI SDK" and provider names are used only to say what this package works with.
@@ -0,0 +1,207 @@
1
+ import { AdapterYieldChunk, EmbeddingOptions, EmbeddingResult, ImageGenerationOptions, ImageGenerationResult, ReasoningLevel, RerankAdapterResult, RerankOptions, TTSOptions, TTSResult, TextOptions, TranscriptionOptions, TranscriptionResult } from "@tanstack/ai";
2
+ import { BaseEmbeddingAdapter, BaseImageAdapter, BaseRerankAdapter, BaseTTSAdapter, BaseTextAdapter, BaseTranscriptionAdapter, StructuredOutputOptions, StructuredOutputResult } from "@tanstack/ai/adapters";
3
+ import { EmbeddingModelV2, EmbeddingModelV3, EmbeddingModelV4, ImageModelV2, ImageModelV3, ImageModelV4, ImageModelV4File, LanguageModelV2, LanguageModelV3, LanguageModelV4, RerankingModelV3, RerankingModelV4, SpeechModelV2, SpeechModelV3, SpeechModelV4, TranscriptionModelV2, TranscriptionModelV3, TranscriptionModelV4 } from "@ai-sdk/provider";
4
+ /** AI SDK provider spec versions this package reads. */
5
+ type SpecVersion = 'v2' | 'v3' | 'v4';
6
+ /** Options every bridge adapter takes besides the model. */
7
+ interface AiSdkAdapterOptions {
8
+ /**
9
+ * Adapter name shown by TanStack AI (devtools, usage, history source).
10
+ * Defaults to the first segment of the AI SDK provider id, e.g. `deepseek` for `deepseek.chat`.
11
+ */
12
+ name?: string;
13
+ }
14
+ /** Per-call options shared by every activity. `providerOptions` goes to the AI SDK model unchanged. */
15
+ interface AiSdkCallOptions {
16
+ /** AI SDK `providerOptions`, keyed by provider, e.g. `{ openai: { user: 'u1' } }`. */
17
+ providerOptions?: Record<string, Record<string, unknown>>;
18
+ /** Extra HTTP headers for this call. */
19
+ headers?: Record<string, string | undefined>;
20
+ }
21
+ /** Any AI SDK embedding model: spec v2, v3 or v4. */
22
+ type AiSdkEmbeddingModel = EmbeddingModelV2<string> | EmbeddingModelV3 | EmbeddingModelV4;
23
+ /** `modelOptions` for `embed()` with a bridged model. */
24
+ interface AiSdkEmbeddingModelOptions extends AiSdkCallOptions {}
25
+ /** TanStack AI embedding adapter around an AI SDK embedding model. Splits large inputs by `maxEmbeddingsPerCall`. */
26
+ export declare class AiSdkEmbeddingAdapter<TModel extends string = string> extends BaseEmbeddingAdapter<TModel, AiSdkEmbeddingModelOptions> {
27
+ readonly name: string;
28
+ readonly embeddingModel: AiSdkEmbeddingModel;
29
+ readonly specificationVersion: SpecVersion;
30
+ constructor(model: AiSdkEmbeddingModel, options?: AiSdkAdapterOptions);
31
+ createEmbeddings(options: EmbeddingOptions<AiSdkEmbeddingModelOptions>): Promise<EmbeddingResult>;
32
+ }
33
+ /**
34
+ * Wraps an AI SDK embedding model as a TanStack AI embedding adapter.
35
+ *
36
+ * @example
37
+ * import { embed } from '@tanstack/ai'
38
+ * import { openai } from '@ai-sdk/openai'
39
+ * await embed({ adapter: aiSdkEmbedding(openai.embedding('text-embedding-3-small')), input: ['hello'] })
40
+ */
41
+ export declare function aiSdkEmbedding(model: AiSdkEmbeddingModel, options?: AiSdkAdapterOptions): AiSdkEmbeddingAdapter<string>;
42
+ /** Any AI SDK image model: spec v2, v3 or v4. */
43
+ type AiSdkImageModel = ImageModelV2 | ImageModelV3 | ImageModelV4;
44
+ /** `modelOptions` for `generateImage()` with a bridged model. */
45
+ interface AiSdkImageModelOptions extends AiSdkCallOptions {
46
+ /** Aspect ratio such as `16:9`, for models that take one instead of a size. */
47
+ aspectRatio?: `${number}:${number}`;
48
+ /** Seed, for models that take one. */
49
+ seed?: number;
50
+ /** Mask for inpainting (AI SDK v3/v4 image models that support masks), as an AI SDK image file. */
51
+ mask?: ImageModelV4File;
52
+ }
53
+ /**
54
+ * TanStack AI image adapter around an AI SDK image model.
55
+ * Text parts of the prompt become the prompt; image parts become input files (AI SDK v3/v4 models).
56
+ */
57
+ export declare class AiSdkImageAdapter<TModel extends string = string> extends BaseImageAdapter<TModel, AiSdkImageModelOptions> {
58
+ readonly name: string;
59
+ readonly imageModel: AiSdkImageModel;
60
+ readonly specificationVersion: SpecVersion;
61
+ constructor(model: AiSdkImageModel, options?: AiSdkAdapterOptions);
62
+ private promptOf;
63
+ generateImages(options: ImageGenerationOptions<AiSdkImageModelOptions>): Promise<ImageGenerationResult>;
64
+ }
65
+ /**
66
+ * Wraps an AI SDK image model as a TanStack AI image adapter.
67
+ *
68
+ * @example
69
+ * import { generateImage } from '@tanstack/ai'
70
+ * import { openai } from '@ai-sdk/openai'
71
+ * await generateImage({ threadId, adapter: aiSdkImage(openai.image('gpt-image-1')), prompt: 'a lighthouse' })
72
+ */
73
+ export declare function aiSdkImage(model: AiSdkImageModel, options?: AiSdkAdapterOptions): AiSdkImageAdapter<string>;
74
+ /** Any AI SDK reranking model: spec v3 or v4 (AI SDK 5 had no reranking models). */
75
+ type AiSdkRerankingModel = RerankingModelV3 | RerankingModelV4;
76
+ /** `modelOptions` for `rerank()` with a bridged model. */
77
+ interface AiSdkRerankModelOptions extends AiSdkCallOptions {}
78
+ /** TanStack AI rerank adapter around an AI SDK reranking model. AI SDK reports no token usage for reranking. */
79
+ export declare class AiSdkRerankAdapter<TModel extends string = string> extends BaseRerankAdapter<TModel, AiSdkRerankModelOptions> {
80
+ readonly name: string;
81
+ readonly rerankingModel: AiSdkRerankingModel;
82
+ readonly specificationVersion: SpecVersion;
83
+ constructor(model: AiSdkRerankingModel, options?: AiSdkAdapterOptions);
84
+ rerank(options: RerankOptions<AiSdkRerankModelOptions>): Promise<RerankAdapterResult>;
85
+ }
86
+ /**
87
+ * Wraps an AI SDK reranking model as a TanStack AI rerank adapter.
88
+ *
89
+ * @example
90
+ * import { rerank } from '@tanstack/ai'
91
+ * import { cohere } from '@ai-sdk/cohere'
92
+ * await rerank({ adapter: aiSdkRerank(cohere.reranking('rerank-v3.5')), query, documents })
93
+ */
94
+ export declare function aiSdkRerank(model: AiSdkRerankingModel, options?: AiSdkAdapterOptions): AiSdkRerankAdapter<string>;
95
+ /** Any AI SDK speech model: spec v2, v3 or v4. */
96
+ type AiSdkSpeechModel = SpeechModelV2 | SpeechModelV3 | SpeechModelV4;
97
+ /** `modelOptions` for `generateSpeech()` with a bridged model. */
98
+ interface AiSdkSpeechModelOptions extends AiSdkCallOptions {
99
+ /** Style instructions, for models that take them. */
100
+ instructions?: string;
101
+ /** Language of the text, e.g. `en`. */
102
+ language?: string;
103
+ }
104
+ /**
105
+ * TanStack AI text-to-speech adapter around an AI SDK speech model.
106
+ * `format` in the result is what the provider returned (content-type header or audio bytes),
107
+ * falling back to the requested format, else `unknown`.
108
+ */
109
+ export declare class AiSdkSpeechAdapter<TModel extends string = string> extends BaseTTSAdapter<TModel, AiSdkSpeechModelOptions> {
110
+ readonly name: string;
111
+ readonly speechModel: AiSdkSpeechModel;
112
+ readonly specificationVersion: SpecVersion;
113
+ constructor(model: AiSdkSpeechModel, options?: AiSdkAdapterOptions);
114
+ generateSpeech(options: TTSOptions<AiSdkSpeechModelOptions>): Promise<TTSResult>;
115
+ }
116
+ /**
117
+ * Wraps an AI SDK speech model as a TanStack AI text-to-speech adapter.
118
+ *
119
+ * @example
120
+ * import { generateSpeech } from '@tanstack/ai'
121
+ * import { openai } from '@ai-sdk/openai'
122
+ * await generateSpeech({ threadId, adapter: aiSdkSpeech(openai.speech('gpt-4o-mini-tts')), text: 'Hello', voice: 'alloy' })
123
+ */
124
+ export declare function aiSdkSpeech(model: AiSdkSpeechModel, options?: AiSdkAdapterOptions): AiSdkSpeechAdapter<string>;
125
+ /** Any AI SDK language model: spec v2 (AI SDK 5), v3 (AI SDK 6) or v4 (AI SDK 7). */
126
+ type AiSdkLanguageModel = LanguageModelV2 | LanguageModelV3 | LanguageModelV4;
127
+ /** `modelOptions` for `chat()` with a bridged model. Sampling settings go to the AI SDK call unchanged. */
128
+ interface AiSdkTextModelOptions extends AiSdkCallOptions {
129
+ maxOutputTokens?: number;
130
+ temperature?: number;
131
+ topP?: number;
132
+ topK?: number;
133
+ presencePenalty?: number;
134
+ frequencyPenalty?: number;
135
+ stopSequences?: string[];
136
+ seed?: number;
137
+ }
138
+ type Modalities = readonly ['text', 'image', 'audio', 'video', 'document'];
139
+ type MetadataByModality = {
140
+ text: unknown;
141
+ image: unknown;
142
+ audio: unknown;
143
+ video: unknown;
144
+ document: unknown;
145
+ };
146
+ /**
147
+ * TanStack AI text adapter around an AI SDK language model.
148
+ * Streams text, reasoning and tool calls as AG-UI events and maps usage and finish reasons.
149
+ */
150
+ export declare class AiSdkTextAdapter<TModel extends string = string> extends BaseTextAdapter<TModel, AiSdkTextModelOptions, Modalities, MetadataByModality, ReadonlyArray<string>, unknown, never, {
151
+ levels: ReasoningLevel;
152
+ budget: false;
153
+ }> {
154
+ readonly name: string;
155
+ readonly api = "ai-sdk";
156
+ readonly provider: string;
157
+ readonly inputModalities: Modalities;
158
+ /** The wrapped AI SDK model. */
159
+ readonly languageModel: AiSdkLanguageModel;
160
+ /** AI SDK spec version of the wrapped model. */
161
+ readonly specificationVersion: SpecVersion;
162
+ constructor(model: AiSdkLanguageModel, options?: AiSdkAdapterOptions);
163
+ private callOptions;
164
+ chatStream(options: TextOptions<AiSdkTextModelOptions>): AsyncIterable<AdapterYieldChunk>;
165
+ private runError;
166
+ private mapStream;
167
+ structuredOutput(options: StructuredOutputOptions<AiSdkTextModelOptions>): Promise<StructuredOutputResult<unknown>>;
168
+ }
169
+ /**
170
+ * Wraps an AI SDK language model as a TanStack AI text adapter.
171
+ *
172
+ * @example
173
+ * import { chat } from '@tanstack/ai'
174
+ * import { deepseek } from '@ai-sdk/deepseek'
175
+ * chat({ adapter: aiSdkText(deepseek('deepseek-chat')), messages, threadId })
176
+ */
177
+ export declare function aiSdkText(model: AiSdkLanguageModel, options?: AiSdkAdapterOptions): AiSdkTextAdapter<string>;
178
+ /** Any AI SDK transcription model: spec v2, v3 or v4. */
179
+ type AiSdkTranscriptionModel = TranscriptionModelV2 | TranscriptionModelV3 | TranscriptionModelV4;
180
+ /** `modelOptions` for `generateTranscription()` with a bridged model. */
181
+ interface AiSdkTranscriptionModelOptions extends AiSdkCallOptions {
182
+ /** Media type of the audio when it cannot be read from a `Blob`/`File` or data URL. Default `audio/mpeg`. */
183
+ mediaType?: string;
184
+ }
185
+ /**
186
+ * TanStack AI transcription adapter around an AI SDK transcription model.
187
+ * `language`, `prompt` and `responseFormat` have no AI SDK equivalent and are not sent: pass the provider's own
188
+ * options in `modelOptions.providerOptions`. The result always has `text`, plus `segments`, `language` and `duration`
189
+ * when the provider returns them. An `http(s)` URL as `audio` is downloaded with the global `fetch`, not the provider's.
190
+ */
191
+ export declare class AiSdkTranscriptionAdapter<TModel extends string = string> extends BaseTranscriptionAdapter<TModel, AiSdkTranscriptionModelOptions> {
192
+ readonly name: string;
193
+ readonly transcriptionModel: AiSdkTranscriptionModel;
194
+ readonly specificationVersion: SpecVersion;
195
+ constructor(model: AiSdkTranscriptionModel, options?: AiSdkAdapterOptions);
196
+ transcribe(options: TranscriptionOptions<AiSdkTranscriptionModelOptions>): Promise<TranscriptionResult>;
197
+ }
198
+ /**
199
+ * Wraps an AI SDK transcription model as a TanStack AI transcription adapter.
200
+ *
201
+ * @example
202
+ * import { generateTranscription } from '@tanstack/ai'
203
+ * import { openai } from '@ai-sdk/openai'
204
+ * await generateTranscription({ threadId, adapter: aiSdkTranscription(openai.transcription('whisper-1')), audio: file })
205
+ */
206
+ export declare function aiSdkTranscription(model: AiSdkTranscriptionModel, options?: AiSdkAdapterOptions): AiSdkTranscriptionAdapter<string>;
207
+ export type { AiSdkAdapterOptions, AiSdkCallOptions, AiSdkEmbeddingModel, AiSdkEmbeddingModelOptions, AiSdkImageModel, AiSdkImageModelOptions, AiSdkLanguageModel, AiSdkRerankModelOptions, AiSdkRerankingModel, AiSdkSpeechModel, AiSdkSpeechModelOptions, AiSdkTextModelOptions, AiSdkTranscriptionModel, AiSdkTranscriptionModelOptions, SpecVersion };