@tanstack/ai 0.10.0 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Core TanStack AI library - Open source AI SDK",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -32,7 +32,8 @@
32
32
  },
33
33
  "files": [
34
34
  "dist",
35
- "src"
35
+ "src",
36
+ "skills"
36
37
  ],
37
38
  "keywords": [
38
39
  "ai",
@@ -40,11 +41,12 @@
40
41
  "sdk",
41
42
  "llm",
42
43
  "chat",
43
- "embeddings"
44
+ "embeddings",
45
+ "tanstack-intent"
44
46
  ],
45
47
  "dependencies": {
46
48
  "partial-json": "^0.1.7",
47
- "@tanstack/ai-event-client": "0.2.0"
49
+ "@tanstack/ai-event-client": "0.2.1"
48
50
  },
49
51
  "devDependencies": {
50
52
  "@standard-schema/spec": "^1.1.0",
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: ai-core
3
+ description: >
4
+ Entry point for TanStack AI skills. Routes to chat-experience, tool-calling,
5
+ media-generation, structured-outputs, adapter-configuration, ag-ui-protocol,
6
+ middleware, and custom-backend-integration. Use chat() not streamText(),
7
+ openaiText() not createOpenAI(), toServerSentEventsResponse() not manual SSE,
8
+ middleware hooks not onEnd callbacks.
9
+ type: core
10
+ library: tanstack-ai
11
+ library_version: '0.10.0'
12
+ ---
13
+
14
+ # TanStack AI — Core Concepts
15
+
16
+ TanStack AI is a type-safe, provider-agnostic AI SDK. Server-side functions
17
+ live in `@tanstack/ai` and provider adapter packages. Client-side hooks live
18
+ in framework packages (`@tanstack/ai-react`, `@tanstack/ai-solid`, etc.).
19
+ Always import from the framework package on the client — never from
20
+ `@tanstack/ai-client` directly (unless vanilla JS).
21
+
22
+ ## Sub-Skills
23
+
24
+ | Need to... | Read |
25
+ | ------------------------------------------------- | ------------------------------------------- |
26
+ | Build a chat UI with streaming | ai-core/chat-experience/SKILL.md |
27
+ | Add tool calling (server, client, or both) | ai-core/tool-calling/SKILL.md |
28
+ | Generate images, video, speech, or transcriptions | ai-core/media-generation/SKILL.md |
29
+ | Get typed JSON responses from the LLM | ai-core/structured-outputs/SKILL.md |
30
+ | Choose and configure a provider adapter | ai-core/adapter-configuration/SKILL.md |
31
+ | Implement AG-UI streaming protocol server-side | ai-core/ag-ui-protocol/SKILL.md |
32
+ | Add analytics, logging, or lifecycle hooks | ai-core/middleware/SKILL.md |
33
+ | Connect to a non-TanStack-AI backend | ai-core/custom-backend-integration/SKILL.md |
34
+ | Set up Code Mode (LLM code execution) | See `@tanstack/ai-code-mode` package skills |
35
+
36
+ ## Quick Decision Tree
37
+
38
+ - Setting up a chatbot? → ai-core/chat-experience
39
+ - Adding function calling? → ai-core/tool-calling
40
+ - Generating media (images, audio, video)? → ai-core/media-generation
41
+ - Need structured JSON output? → ai-core/structured-outputs
42
+ - Choosing/configuring a provider? → ai-core/adapter-configuration
43
+ - Building a server-only AG-UI backend? → ai-core/ag-ui-protocol
44
+ - Adding analytics or post-stream events? → ai-core/middleware
45
+ - Connecting to a custom backend? → ai-core/custom-backend-integration
46
+ - Debugging mistakes? → Check Common Mistakes in the relevant sub-skill
47
+
48
+ ## Critical Rules
49
+
50
+ 1. **This is NOT the Vercel AI SDK.** Use `chat()` not `streamText()`. Use `openaiText()` not `createOpenAI()`. Import from `@tanstack/ai`, not `ai`.
51
+ 2. **Import from framework package on client.** Use `@tanstack/ai-react` (or solid/vue/svelte/preact), not `@tanstack/ai-client`.
52
+ 3. **Use `toServerSentEventsResponse()`** to convert streams to HTTP responses. Never implement SSE manually.
53
+ 4. **Use middleware for lifecycle events.** No `onEnd`/`onFinish` callbacks on `chat()` — use `middleware: [{ onFinish: ... }]`.
54
+ 5. **Ask the user which adapter and model** they want. Suggest the latest model. Also ask if they want Code Mode.
55
+ 6. **Tools must be passed to both server and client.** Server gets the tool in `chat({ tools })`, client gets the definition in `useChat({ clientTools })`.
56
+
57
+ ## Version
58
+
59
+ Targets TanStack AI v0.10.0.
@@ -0,0 +1,283 @@
1
+ ---
2
+ name: ai-core/adapter-configuration
3
+ description: >
4
+ Provider adapter selection and configuration: openaiText, anthropicText,
5
+ geminiText, ollamaText, grokText, groqText, openRouterText. Per-model
6
+ type safety with modelOptions, reasoning/thinking configuration,
7
+ runtime adapter switching, extendAdapter() for custom models, createModel().
8
+ API key env vars: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY/GEMINI_API_KEY,
9
+ XAI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY, OLLAMA_HOST.
10
+ type: sub-skill
11
+ library: tanstack-ai
12
+ library_version: '0.10.0'
13
+ sources:
14
+ - 'TanStack/ai:docs/adapters/openai.md'
15
+ - 'TanStack/ai:docs/adapters/anthropic.md'
16
+ - 'TanStack/ai:docs/adapters/gemini.md'
17
+ - 'TanStack/ai:docs/adapters/ollama.md'
18
+ - 'TanStack/ai:docs/advanced/per-model-type-safety.md'
19
+ - 'TanStack/ai:docs/advanced/runtime-adapter-switching.md'
20
+ - 'TanStack/ai:docs/advanced/extend-adapter.md'
21
+ ---
22
+
23
+ # Adapter Configuration
24
+
25
+ > **Dependency:** This skill builds on ai-core. Read it first for critical rules.
26
+
27
+ > **Before implementing:** Ask the user which provider and model they want.
28
+ > Then fetch the latest available models from the provider's source code
29
+ > (check the adapter's model metadata file, e.g. `packages/typescript/ai-openai/src/model-meta.ts`)
30
+ > or from the provider's API/docs to recommend the most current model.
31
+ > The model lists in this skill and its reference files may be outdated.
32
+ > Always verify against the source before recommending a specific model.
33
+
34
+ ## Setup
35
+
36
+ Create an adapter and use it with `chat()`:
37
+
38
+ ```typescript
39
+ import { chat, toServerSentEventsResponse } from '@tanstack/ai'
40
+ import { openaiText } from '@tanstack/ai-openai'
41
+
42
+ const stream = chat({
43
+ adapter: openaiText('gpt-5.2'),
44
+ messages,
45
+ temperature: 0.7,
46
+ maxTokens: 1000,
47
+ })
48
+
49
+ return toServerSentEventsResponse(stream)
50
+ ```
51
+
52
+ The adapter factory function takes the model name as a string literal and an
53
+ optional config object (API key, base URL, etc.). The model name is passed
54
+ into the factory, not into `chat()`.
55
+
56
+ ## Core Patterns
57
+
58
+ ### 1. Adapter Selection
59
+
60
+ Each provider has a dedicated package with tree-shakeable adapter factories.
61
+ The text adapter is the primary one for chat/completions:
62
+
63
+ | Provider | Package | Factory | Env Var |
64
+ | ---------- | ------------------------- | ---------------- | ------------------------------------------------- |
65
+ | OpenAI | `@tanstack/ai-openai` | `openaiText` | `OPENAI_API_KEY` |
66
+ | Anthropic | `@tanstack/ai-anthropic` | `anthropicText` | `ANTHROPIC_API_KEY` |
67
+ | Gemini | `@tanstack/ai-gemini` | `geminiText` | `GOOGLE_API_KEY` or `GEMINI_API_KEY` |
68
+ | Grok (xAI) | `@tanstack/ai-grok` | `grokText` | `XAI_API_KEY` |
69
+ | Groq | `@tanstack/ai-groq` | `groqText` | `GROQ_API_KEY` |
70
+ | OpenRouter | `@tanstack/ai-openrouter` | `openRouterText` | `OPENROUTER_API_KEY` |
71
+ | Ollama | `@tanstack/ai-ollama` | `ollamaText` | `OLLAMA_HOST` (default: `http://localhost:11434`) |
72
+
73
+ ```typescript
74
+ // Each factory takes model as first arg, optional config as second
75
+ import { openaiText } from '@tanstack/ai-openai'
76
+ import { anthropicText } from '@tanstack/ai-anthropic'
77
+ import { geminiText } from '@tanstack/ai-gemini'
78
+ import { grokText } from '@tanstack/ai-grok'
79
+ import { groqText } from '@tanstack/ai-groq'
80
+ import { openRouterText } from '@tanstack/ai-openrouter'
81
+ import { ollamaText } from '@tanstack/ai-ollama'
82
+
83
+ // Model string is passed to the factory, NOT to chat()
84
+ const adapter = openaiText('gpt-5.2')
85
+ const adapter2 = anthropicText('claude-sonnet-4-6')
86
+ const adapter3 = geminiText('gemini-2.5-pro')
87
+ const adapter4 = grokText('grok-4')
88
+ const adapter5 = groqText('llama-3.3-70b-versatile')
89
+ const adapter6 = openRouterText('anthropic/claude-sonnet-4')
90
+ const adapter7 = ollamaText('llama3.3')
91
+
92
+ // Optional: pass explicit API key
93
+ const adapterWithKey = openaiText('gpt-5.2', {
94
+ apiKey: 'sk-...',
95
+ })
96
+ ```
97
+
98
+ ### 2. Runtime Adapter Switching
99
+
100
+ Use an adapter factory map to switch providers dynamically based on user
101
+ input or configuration:
102
+
103
+ ```typescript
104
+ import { chat, toServerSentEventsResponse } from '@tanstack/ai'
105
+ import type { TextAdapter } from '@tanstack/ai/adapters'
106
+ import { openaiText } from '@tanstack/ai-openai'
107
+ import { anthropicText } from '@tanstack/ai-anthropic'
108
+ import { geminiText } from '@tanstack/ai-gemini'
109
+
110
+ // Define a map of provider+model to adapter factory calls
111
+ const adapters: Record<string, () => TextAdapter> = {
112
+ 'openai/gpt-5.2': () => openaiText('gpt-5.2'),
113
+ 'anthropic/claude-sonnet-4-6': () => anthropicText('claude-sonnet-4-6'),
114
+ 'gemini/gemini-2.5-pro': () => geminiText('gemini-2.5-pro'),
115
+ }
116
+
117
+ export function handleChat(providerModel: string, messages: Array<any>) {
118
+ const createAdapter = adapters[providerModel]
119
+ if (!createAdapter) {
120
+ throw new Error(`Unknown provider/model: ${providerModel}`)
121
+ }
122
+
123
+ const stream = chat({
124
+ adapter: createAdapter(),
125
+ messages,
126
+ })
127
+
128
+ return toServerSentEventsResponse(stream)
129
+ }
130
+ ```
131
+
132
+ ### 3. Configuring Reasoning / Thinking
133
+
134
+ Different providers expose reasoning/thinking through their `modelOptions`:
135
+
136
+ ```typescript
137
+ import { chat } from '@tanstack/ai'
138
+ import { openaiText } from '@tanstack/ai-openai'
139
+ import { anthropicText } from '@tanstack/ai-anthropic'
140
+ import { geminiText } from '@tanstack/ai-gemini'
141
+
142
+ // OpenAI: reasoning with effort and summary
143
+ const openaiStream = chat({
144
+ adapter: openaiText('gpt-5.2'),
145
+ messages,
146
+ modelOptions: {
147
+ reasoning: {
148
+ effort: 'high',
149
+ summary: 'auto',
150
+ },
151
+ },
152
+ })
153
+
154
+ // Anthropic: extended thinking with budget_tokens
155
+ const anthropicStream = chat({
156
+ adapter: anthropicText('claude-sonnet-4-6'),
157
+ messages,
158
+ maxTokens: 16000,
159
+ modelOptions: {
160
+ thinking: {
161
+ type: 'enabled',
162
+ budget_tokens: 8000, // must be >= 1024 and < maxTokens
163
+ },
164
+ },
165
+ })
166
+
167
+ // Anthropic: adaptive thinking (claude-sonnet-4-6 and newer)
168
+ const adaptiveStream = chat({
169
+ adapter: anthropicText('claude-sonnet-4-6'),
170
+ messages,
171
+ maxTokens: 16000,
172
+ modelOptions: {
173
+ thinking: {
174
+ type: 'adaptive',
175
+ },
176
+ effort: 'high', // 'max' | 'high' | 'medium' | 'low'
177
+ },
178
+ })
179
+
180
+ // Gemini: thinking config with budget or level
181
+ const geminiStream = chat({
182
+ adapter: geminiText('gemini-2.5-pro'),
183
+ messages,
184
+ modelOptions: {
185
+ thinkingConfig: {
186
+ includeThoughts: true,
187
+ thinkingBudget: 4096,
188
+ },
189
+ },
190
+ })
191
+ ```
192
+
193
+ ### 4. Extending Adapters with Custom Models
194
+
195
+ Use `extendAdapter()` and `createModel()` to add custom or fine-tuned models
196
+ while preserving type safety for the original models:
197
+
198
+ ```typescript
199
+ import { extendAdapter, createModel } from '@tanstack/ai'
200
+ import { openaiText } from '@tanstack/ai-openai'
201
+
202
+ // Define custom models
203
+ const customModels = [
204
+ createModel('ft:gpt-5.2:my-org:custom-model:abc123', ['text', 'image']),
205
+ createModel('my-local-proxy-model', ['text']),
206
+ ] as const
207
+
208
+ // Create extended factory - original models still fully typed
209
+ const myOpenai = extendAdapter(openaiText, customModels)
210
+
211
+ // Use original models - full type inference preserved
212
+ const gpt5 = myOpenai('gpt-5.2')
213
+
214
+ // Use custom models - accepted by the type system
215
+ const custom = myOpenai('ft:gpt-5.2:my-org:custom-model:abc123')
216
+
217
+ // Type error: 'nonexistent-model' is not a valid model
218
+ // myOpenai('nonexistent-model')
219
+ ```
220
+
221
+ At runtime, `extendAdapter` simply passes through to the original factory.
222
+ The `_customModels` parameter is only used for type inference.
223
+
224
+ ## Common Mistakes
225
+
226
+ ### a. HIGH: Confusing legacy monolithic with tree-shakeable adapter
227
+
228
+ The legacy `openai()` (and `anthropic()`, etc.) monolithic adapters are
229
+ deprecated. They take the model in `chat()`, not in the factory.
230
+
231
+ ```typescript
232
+ // WRONG: Legacy monolithic adapter pattern
233
+ import { openai } from '@tanstack/ai-openai'
234
+ chat({ adapter: openai(), model: 'gpt-5.2', messages })
235
+
236
+ // CORRECT: Tree-shakeable adapter, model in factory
237
+ import { openaiText } from '@tanstack/ai-openai'
238
+ chat({ adapter: openaiText('gpt-5.2'), messages })
239
+ ```
240
+
241
+ Source: docs/migration/migration.md
242
+
243
+ ### b. MEDIUM: Wrong API key environment variable name
244
+
245
+ Each provider uses a specific env var name. Using the wrong one causes a
246
+ runtime error:
247
+
248
+ | Provider | Correct Env Var | Common Mistake |
249
+ | ---------- | ------------------------------------ | ------------------------------------------------------------------------ |
250
+ | OpenAI | `OPENAI_API_KEY` | |
251
+ | Anthropic | `ANTHROPIC_API_KEY` | |
252
+ | Gemini | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | `GOOGLE_GENAI_API_KEY` (does not work) |
253
+ | Grok (xAI) | `XAI_API_KEY` | `GROK_API_KEY` (does not work) |
254
+ | Groq | `GROQ_API_KEY` | |
255
+ | OpenRouter | `OPENROUTER_API_KEY` | |
256
+ | Ollama | `OLLAMA_HOST` | No API key needed, just the host URL (default: `http://localhost:11434`) |
257
+
258
+ Source: adapter source code (`utils/client.ts` in each adapter package).
259
+
260
+ ## References
261
+
262
+ Detailed per-adapter reference files:
263
+
264
+ - [OpenAI Adapter](references/openai-adapter.md)
265
+ - [Anthropic Adapter](references/anthropic-adapter.md)
266
+ - [Gemini Adapter](references/gemini-adapter.md)
267
+ - [Ollama Adapter](references/ollama-adapter.md)
268
+ - [Grok Adapter](references/grok-adapter.md)
269
+ - [Groq Adapter](references/groq-adapter.md)
270
+ - [OpenRouter Adapter](references/openrouter-adapter.md)
271
+
272
+ ## Tension
273
+
274
+ **HIGH Tension: Type safety vs. quick prototyping** -- Per-model type safety
275
+ requires specific model string literals. Quick prototyping wants dynamic
276
+ selection with `string` variables. Agents optimizing for quick setup silently
277
+ lose type safety. If model names come from user input or config files, use
278
+ `extendAdapter()` to add custom names.
279
+
280
+ ## Cross-References
281
+
282
+ - See also: `ai-core/chat-experience/SKILL.md` -- Adapter choice affects chat setup
283
+ - See also: `ai-core/structured-outputs/SKILL.md` -- `outputSchema` handles provider differences transparently
@@ -0,0 +1,97 @@
1
+ # Anthropic Adapter Reference
2
+
3
+ ## Package
4
+
5
+ ```
6
+ @tanstack/ai-anthropic
7
+ ```
8
+
9
+ ## Adapter Factories
10
+
11
+ | Factory | Type | Description |
12
+ | -------------------- | --------- | ------------------ |
13
+ | `anthropicText` | Text/Chat | Chat completions |
14
+ | `anthropicSummarize` | Summarize | Text summarization |
15
+
16
+ ## Import
17
+
18
+ ```typescript
19
+ import { anthropicText } from '@tanstack/ai-anthropic'
20
+ ```
21
+
22
+ ## Key Chat Models
23
+
24
+ | Model | Context Window | Max Output | Notes |
25
+ | ------------------- | -------------- | ---------- | ------------------------------- |
26
+ | `claude-opus-4-6` | 200K | 128K | Most capable, adaptive thinking |
27
+ | `claude-sonnet-4-6` | 1M | 64K | Best balance, adaptive thinking |
28
+ | `claude-sonnet-4-5` | 200K | 64K | Previous gen balanced |
29
+ | `claude-opus-4-5` | 200K | 32K | Previous gen most capable |
30
+ | `claude-haiku-4-5` | 200K | 64K | Fast and affordable |
31
+ | `claude-sonnet-4` | 200K | 64K | Older balanced model |
32
+ | `claude-opus-4` | 200K | 32K | Older most capable |
33
+
34
+ Note: Model IDs use the format `claude-opus-4-6`, `claude-sonnet-4-6`, etc.
35
+
36
+ ## Provider-Specific modelOptions
37
+
38
+ ```typescript
39
+ chat({
40
+ adapter: anthropicText('claude-sonnet-4-6'),
41
+ messages,
42
+ maxTokens: 16000,
43
+ modelOptions: {
44
+ // Extended thinking (budget-based)
45
+ thinking: {
46
+ type: 'enabled',
47
+ budget_tokens: 8000, // must be >= 1024 and < maxTokens
48
+ },
49
+ // Adaptive thinking (claude-sonnet-4-6, claude-opus-4-6+)
50
+ thinking: {
51
+ type: 'adaptive',
52
+ },
53
+ effort: 'high', // 'max' | 'high' | 'medium' | 'low'
54
+ // Service tier
55
+ service_tier: 'auto', // 'auto' | 'standard_only'
56
+ // Stop sequences
57
+ stop_sequences: ['END'],
58
+ // Tool choice
59
+ tool_choice: { type: 'auto' },
60
+ // Context management
61
+ context_management: {
62
+ /* BetaContextManagementConfig */
63
+ },
64
+ // MCP servers (max 20)
65
+ mcp_servers: [
66
+ {
67
+ name: 'my-server',
68
+ url: 'https://mcp.example.com',
69
+ type: 'url',
70
+ tool_configuration: { enabled: true },
71
+ },
72
+ ],
73
+ // Container (skills)
74
+ container: {
75
+ id: 'container-id',
76
+ skills: [{ skill_id: 'analysis', type: 'anthropic' }],
77
+ },
78
+ // Sampling
79
+ top_k: 40,
80
+ },
81
+ })
82
+ ```
83
+
84
+ ## Environment Variable
85
+
86
+ ```
87
+ ANTHROPIC_API_KEY
88
+ ```
89
+
90
+ ## Gotchas
91
+
92
+ - `thinking.budget_tokens` must be >= 1024 AND less than `maxTokens`.
93
+ Failing either check throws a validation error.
94
+ - Cannot set both `top_p` and `temperature` at the same time (throws error).
95
+ - `claude-3-5-haiku` and `claude-3-haiku` do NOT support extended thinking.
96
+ - System prompts support prompt caching via `cache_control` on `TextBlockParam[]`.
97
+ - All Claude models accept `text`, `image`, and `document` (PDF) input.
@@ -0,0 +1,102 @@
1
+ # Gemini Adapter Reference
2
+
3
+ ## Package
4
+
5
+ ```
6
+ @tanstack/ai-gemini
7
+ ```
8
+
9
+ ## Adapter Factories
10
+
11
+ | Factory | Type | Description |
12
+ | ----------------- | --------- | ----------------------------- |
13
+ | `geminiText` | Text/Chat | Chat completions |
14
+ | `geminiImage` | Image | Image generation (Imagen) |
15
+ | `geminiSpeech` | TTS | Text-to-speech (experimental) |
16
+ | `geminiSummarize` | Summarize | Text summarization |
17
+
18
+ ## Import
19
+
20
+ ```typescript
21
+ import { geminiText } from '@tanstack/ai-gemini'
22
+ import { geminiImage } from '@tanstack/ai-gemini'
23
+ ```
24
+
25
+ ## Key Chat Models
26
+
27
+ | Model | Max Input | Max Output | Notes |
28
+ | ------------------------------- | --------- | ---------- | ---------------------------- |
29
+ | `gemini-3.1-pro-preview` | 1M | 65K | Latest flagship, thinking |
30
+ | `gemini-3-pro-preview` | 1M | 65K | Previous flagship |
31
+ | `gemini-3-flash-preview` | 1M | 65K | Fast, thinking, multimodal |
32
+ | `gemini-3.1-flash-lite-preview` | 1M | 65K | Budget, still capable |
33
+ | `gemini-2.5-pro` | 1M | 65K | Stable release, all features |
34
+ | `gemini-2.5-flash` | 1M | 65K | Fast stable release |
35
+
36
+ All Gemini text models accept `text`, `image`, `audio`, `video`, and `document` input.
37
+
38
+ ## Provider-Specific modelOptions
39
+
40
+ ```typescript
41
+ chat({
42
+ adapter: geminiText('gemini-2.5-pro'),
43
+ messages,
44
+ modelOptions: {
45
+ // Thinking (budget-based)
46
+ thinkingConfig: {
47
+ includeThoughts: true,
48
+ thinkingBudget: 4096,
49
+ },
50
+ // Thinking (level-based, advanced models)
51
+ thinkingConfig: {
52
+ thinkingLevel: 'THINKING_LEVEL_HIGH',
53
+ },
54
+ // Safety settings
55
+ safetySettings: [
56
+ {
57
+ category: 'HARM_CATEGORY_HATE_SPEECH',
58
+ threshold: 'BLOCK_MEDIUM_AND_ABOVE',
59
+ },
60
+ ],
61
+ // Tool config
62
+ toolConfig: {
63
+ /* ToolConfig */
64
+ },
65
+ // Structured output
66
+ responseMimeType: 'application/json',
67
+ responseSchema: {
68
+ /* Schema */
69
+ },
70
+ // Cached content
71
+ cachedContent: 'cachedContents/abc123',
72
+ // Response modalities
73
+ responseModalities: ['TEXT'],
74
+ // Sampling
75
+ topK: 40,
76
+ seed: 42,
77
+ presencePenalty: 0.5,
78
+ frequencyPenalty: 0.5,
79
+ candidateCount: 1,
80
+ stopSequences: ['END'],
81
+ },
82
+ })
83
+ ```
84
+
85
+ ## Environment Variable
86
+
87
+ ```
88
+ GOOGLE_API_KEY (preferred)
89
+ GEMINI_API_KEY (also accepted)
90
+ ```
91
+
92
+ The adapter checks `GOOGLE_API_KEY` first, then falls back to `GEMINI_API_KEY`.
93
+ Note: `GOOGLE_GENAI_API_KEY` does NOT work.
94
+
95
+ ## Gotchas
96
+
97
+ - All Gemini models are multimodal (text, image, audio, video, document input).
98
+ - Image generation models (`gemini-3-pro-image-preview`, etc.) have smaller
99
+ input limits (65K tokens) compared to text models (1M tokens).
100
+ - `thinkingConfig.thinkingLevel` (level-based) and `thinkingConfig.thinkingBudget`
101
+ (budget-based) serve different models. Check which your model supports.
102
+ - `cachedContent` must follow the format `cachedContents/{id}`.
@@ -0,0 +1,77 @@
1
+ # Grok (xAI) Adapter Reference
2
+
3
+ ## Package
4
+
5
+ ```
6
+ @tanstack/ai-grok
7
+ ```
8
+
9
+ ## Adapter Factories
10
+
11
+ | Factory | Type | Description |
12
+ | --------------- | --------- | ------------------ |
13
+ | `grokText` | Text/Chat | Chat completions |
14
+ | `grokImage` | Image | Image generation |
15
+ | `grokSummarize` | Summarize | Text summarization |
16
+
17
+ ## Import
18
+
19
+ ```typescript
20
+ import { grokText } from '@tanstack/ai-grok'
21
+ import { grokImage } from '@tanstack/ai-grok'
22
+ ```
23
+
24
+ ## Key Chat Models
25
+
26
+ | Model | Context Window | Notes |
27
+ | ----------------------------- | -------------- | ---------------------------- |
28
+ | `grok-4-1-fast-reasoning` | 2M | Latest, fast reasoning |
29
+ | `grok-4-1-fast-non-reasoning` | 2M | Latest, no reasoning |
30
+ | `grok-code-fast-1` | 256K | Code-specialized, reasoning |
31
+ | `grok-4` | 256K | Full reasoning, tool calling |
32
+ | `grok-4-fast-reasoning` | 2M | Fast reasoning variant |
33
+ | `grok-3` | 131K | Previous gen, no reasoning |
34
+ | `grok-3-mini` | 131K | Budget reasoning |
35
+ | `grok-2-vision-1212` | 32K | Vision input |
36
+
37
+ Image model: `grok-2-image-1212`
38
+
39
+ ## Provider-Specific modelOptions
40
+
41
+ Grok uses an OpenAI-compatible API. Options are straightforward:
42
+
43
+ ```typescript
44
+ chat({
45
+ adapter: grokText('grok-4'),
46
+ messages,
47
+ modelOptions: {
48
+ temperature: 0.7,
49
+ max_tokens: 4096,
50
+ top_p: 0.9,
51
+ frequency_penalty: 0.5,
52
+ presence_penalty: 0.5,
53
+ stop: ['\n\n'],
54
+ user: 'user-123',
55
+ },
56
+ })
57
+ ```
58
+
59
+ ## Environment Variable
60
+
61
+ ```
62
+ XAI_API_KEY
63
+ ```
64
+
65
+ **Important:** The env var is `XAI_API_KEY`, not `GROK_API_KEY`.
66
+ The adapter uses the OpenAI SDK with xAI's base URL (`https://api.x.ai/v1`).
67
+
68
+ ## Gotchas
69
+
70
+ - Uses the OpenAI SDK under the hood with a custom `baseURL`.
71
+ - `grok-4-1-fast-non-reasoning` and `grok-4-fast-non-reasoning` explicitly
72
+ do NOT support reasoning. Other grok-4+ models do.
73
+ - `grok-2-vision-1212` is the only model with image input support in the
74
+ older generation.
75
+ - The grok-4-1 fast models have a massive 2M context window.
76
+ - Provider options are simpler than OpenAI's (no Responses API features,
77
+ no structured outputs config, no metadata).