@tanstack/ai 0.52.3 → 0.54.0
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/README.md +14 -13
- package/dist/esm/activities/chat/index.js +5 -3
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/generateLiveVideo/adapter.d.ts +69 -0
- package/dist/esm/activities/generateLiveVideo/adapter.js +23 -0
- package/dist/esm/activities/generateLiveVideo/adapter.js.map +1 -0
- package/dist/esm/activities/generateLiveVideo/index.d.ts +99 -0
- package/dist/esm/activities/generateLiveVideo/index.js +162 -0
- package/dist/esm/activities/generateLiveVideo/index.js.map +1 -0
- package/dist/esm/activities/generateVideo/index.js +3 -1
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/generateWorld/adapter.d.ts +69 -0
- package/dist/esm/activities/generateWorld/adapter.js +23 -0
- package/dist/esm/activities/generateWorld/adapter.js.map +1 -0
- package/dist/esm/activities/generateWorld/index.d.ts +99 -0
- package/dist/esm/activities/generateWorld/index.js +162 -0
- package/dist/esm/activities/generateWorld/index.js.map +1 -0
- package/dist/esm/activities/index.d.ts +8 -2
- package/dist/esm/activities/index.js +11 -7
- package/dist/esm/activities/middleware/types.d.ts +1 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.js +2 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
- package/dist/esm/byok/define-provider.d.ts +6 -0
- package/dist/esm/byok/define-provider.js +2 -1
- package/dist/esm/byok/define-provider.js.map +1 -1
- package/dist/esm/byok/get-key.d.ts +7 -0
- package/dist/esm/byok/get-key.js +8 -1
- package/dist/esm/byok/get-key.js.map +1 -1
- package/dist/esm/byok/server.d.ts +1 -1
- package/dist/esm/byok/server.js +2 -2
- package/dist/esm/client.d.ts +4 -2
- package/dist/esm/client.js +3 -1
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +3 -1
- package/dist/esm/middlewares/otel.js +3 -1
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/types.d.ts +112 -0
- package/package.json +2 -2
- package/skills/ai-core/adapter-configuration/SKILL.md +103 -54
- package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +39 -21
- package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +5 -0
- package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +14 -6
- package/skills/ai-core/adapter-configuration/references/grok-adapter.md +33 -25
- package/skills/ai-core/adapter-configuration/references/groq-adapter.md +7 -2
- package/skills/ai-core/adapter-configuration/references/ollama-adapter.md +25 -12
- package/skills/ai-core/adapter-configuration/references/openai-adapter.md +19 -9
- package/skills/ai-core/adapter-configuration/references/openrouter-adapter.md +34 -21
- package/skills/ai-core/ag-ui-protocol/SKILL.md +16 -10
- package/skills/ai-core/chat-experience/SKILL.md +228 -108
- package/skills/ai-core/client-persistence/SKILL.md +21 -9
- package/skills/ai-core/custom-backend-integration/SKILL.md +86 -52
- package/skills/ai-core/debug-logging/SKILL.md +100 -18
- package/skills/ai-core/locks/SKILL.md +35 -7
- package/skills/ai-core/media-generation/SKILL.md +114 -49
- package/skills/ai-core/middleware/SKILL.md +174 -69
- package/skills/ai-core/structured-outputs/SKILL.md +99 -49
- package/skills/ai-core/tool-calling/SKILL.md +245 -158
- package/src/activities/chat/index.ts +6 -7
- package/src/activities/generateLiveVideo/adapter.ts +99 -0
- package/src/activities/generateLiveVideo/index.ts +339 -0
- package/src/activities/generateVideo/index.ts +3 -4
- package/src/activities/generateWorld/adapter.ts +96 -0
- package/src/activities/generateWorld/index.ts +339 -0
- package/src/activities/index.ts +44 -0
- package/src/activities/middleware/types.ts +2 -0
- package/src/activities/summarize/chat-stream-summarize.ts +2 -0
- package/src/byok/define-provider.ts +7 -0
- package/src/byok/get-key.ts +18 -0
- package/src/byok/server.ts +1 -1
- package/src/client.ts +8 -0
- package/src/index.ts +8 -0
- package/src/middlewares/otel.ts +2 -0
- package/src/types.ts +128 -0
|
@@ -23,34 +23,41 @@ import { grokImage } from '@tanstack/ai-grok'
|
|
|
23
23
|
|
|
24
24
|
## Key Chat Models
|
|
25
25
|
|
|
26
|
-
| Model
|
|
27
|
-
|
|
|
28
|
-
| `grok-4
|
|
29
|
-
| `grok-4
|
|
30
|
-
| `grok-
|
|
31
|
-
| `grok-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Image model: `grok-2-image-1212`
|
|
26
|
+
| Model | Context Window | Notes |
|
|
27
|
+
| ---------------- | -------------- | -------------------------------------------------------- |
|
|
28
|
+
| `grok-4.6` | 500K | Latest; reasoning, tools, structured output; document in |
|
|
29
|
+
| `grok-4.5` | 500K | Reasoning, tools, structured output; document in |
|
|
30
|
+
| `grok-4.3` | 1M | Reasoning, tools, structured output; text + image in |
|
|
31
|
+
| `grok-build-0.1` | 256K | Code-specialized; `reasoning` option is not accepted |
|
|
32
|
+
|
|
33
|
+
`GROK_CHAT_MODELS` is exactly these four ids. Image models
|
|
34
|
+
(`GROK_IMAGE_MODELS`): `grok-2-image-1212`, `grok-imagine-image`,
|
|
35
|
+
`grok-imagine-image-2.0`, `grok-imagine-image-quality`.
|
|
38
36
|
|
|
39
37
|
## Provider-Specific modelOptions
|
|
40
38
|
|
|
41
|
-
Grok
|
|
39
|
+
Grok speaks the OpenAI **Responses** API (the adapter uses the OpenAI SDK
|
|
40
|
+
against `https://api.x.ai/v1`), so option names follow that API:
|
|
42
41
|
|
|
43
42
|
```typescript
|
|
43
|
+
import { chat } from '@tanstack/ai'
|
|
44
|
+
import { grokText } from '@tanstack/ai-grok'
|
|
45
|
+
|
|
46
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
47
|
+
|
|
44
48
|
chat({
|
|
45
|
-
adapter: grokText('grok-4'),
|
|
49
|
+
adapter: grokText('grok-4.6'),
|
|
46
50
|
messages,
|
|
47
51
|
modelOptions: {
|
|
52
|
+
// Sampling (Responses API names)
|
|
48
53
|
temperature: 0.7,
|
|
49
|
-
max_tokens: 4096,
|
|
50
54
|
top_p: 0.9,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
max_output_tokens: 4096,
|
|
56
|
+
// Reasoning (reasoning-capable models)
|
|
57
|
+
reasoning: { effort: 'high' }, // 'none' | 'low' | 'medium' | 'high'
|
|
58
|
+
// Response storage (adapter default: false)
|
|
59
|
+
store: false,
|
|
60
|
+
// End-user id for abuse monitoring
|
|
54
61
|
user: 'user-123',
|
|
55
62
|
},
|
|
56
63
|
})
|
|
@@ -68,10 +75,11 @@ The adapter uses the OpenAI SDK with xAI's base URL (`https://api.x.ai/v1`).
|
|
|
68
75
|
## Gotchas
|
|
69
76
|
|
|
70
77
|
- Uses the OpenAI SDK under the hood with a custom `baseURL`.
|
|
71
|
-
- `grok-
|
|
72
|
-
|
|
73
|
-
- `grok-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
- All four chat models support reasoning; `grok-build-0.1` is the exception
|
|
79
|
+
in that it rejects the `reasoning` option (`GrokBuildProviderOptions`).
|
|
80
|
+
- `grok-4.5` / `grok-4.6` accept `text`, `image`, and `document` input;
|
|
81
|
+
`grok-4.3` / `grok-build-0.1` accept `text` and `image`.
|
|
82
|
+
- Provider options are a subset of OpenAI's Responses options:
|
|
83
|
+
`temperature`, `top_p`, `max_output_tokens`, `reasoning`, `store`,
|
|
84
|
+
`include`, `user`. There is no `max_tokens`, `frequency_penalty`,
|
|
85
|
+
`presence_penalty`, `stop`, or `metadata`.
|
|
@@ -38,6 +38,11 @@ Guard models: `meta-llama/llama-guard-4-12b`, `meta-llama/llama-prompt-guard-2-8
|
|
|
38
38
|
## Provider-Specific modelOptions
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
|
+
import { chat } from '@tanstack/ai'
|
|
42
|
+
import { groqText } from '@tanstack/ai-groq'
|
|
43
|
+
|
|
44
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
45
|
+
|
|
41
46
|
chat({
|
|
42
47
|
adapter: groqText('llama-3.3-70b-versatile'),
|
|
43
48
|
messages,
|
|
@@ -49,7 +54,7 @@ chat({
|
|
|
49
54
|
// Response format
|
|
50
55
|
response_format: {
|
|
51
56
|
type: 'json_schema',
|
|
52
|
-
json_schema: {/*
|
|
57
|
+
json_schema: { name: 'answer', schema: {/* JSON Schema */} },
|
|
53
58
|
},
|
|
54
59
|
// Sampling
|
|
55
60
|
temperature: 0.7,
|
|
@@ -67,7 +72,7 @@ chat({
|
|
|
67
72
|
// Citations
|
|
68
73
|
citation_options: 'enabled',
|
|
69
74
|
// Documents for context
|
|
70
|
-
documents: [{ text: '...' }],
|
|
75
|
+
documents: [{ source: { type: 'text', text: '...' } }],
|
|
71
76
|
// Search settings (for web search tool)
|
|
72
77
|
search_settings: {/* SearchSettings */},
|
|
73
78
|
// Service tier
|
|
@@ -24,15 +24,20 @@ import { ollamaText } from '@tanstack/ai-ollama'
|
|
|
24
24
|
Ollama runs models locally. The adapter supports a large catalog of models.
|
|
25
25
|
Key families include:
|
|
26
26
|
|
|
27
|
-
| Model Family | Example Names
|
|
28
|
-
| ------------ |
|
|
29
|
-
| Llama 4 | `llama4`, `llama4:
|
|
30
|
-
| Llama 3.3 | `llama3.3`, `llama3.3:70b`
|
|
31
|
-
| Qwen 3 | `qwen3`, `qwen3:32b`
|
|
32
|
-
| DeepSeek R1 | `deepseek-r1`, `deepseek-r1:70b`
|
|
33
|
-
| Gemma 3 | `gemma3`, `gemma3:27b`
|
|
34
|
-
| Phi 4 | `phi4`, `phi4:14b`
|
|
35
|
-
| Mistral | `mistral`, `mistral-large`
|
|
27
|
+
| Model Family | Example Names | Notes |
|
|
28
|
+
| ------------ | ---------------------------------------- | ----------------------- |
|
|
29
|
+
| Llama 4 | `llama4:latest`, `llama4:16x17b` | Latest Meta models |
|
|
30
|
+
| Llama 3.3 | `llama3.3:latest`, `llama3.3:70b` | Strong general purpose |
|
|
31
|
+
| Qwen 3 | `qwen3:latest`, `qwen3:32b` | Reasoning capable |
|
|
32
|
+
| DeepSeek R1 | `deepseek-r1:latest`, `deepseek-r1:70b` | Reasoning focused |
|
|
33
|
+
| Gemma 3 | `gemma3:latest`, `gemma3:27b` | Google's open model |
|
|
34
|
+
| Phi 4 | `phi4:latest`, `phi4:14b` | Microsoft's small model |
|
|
35
|
+
| Mistral | `mistral:latest`, `mistral-large:latest` | Mistral AI models |
|
|
36
|
+
|
|
37
|
+
Typed ids are always `family:tag` (`OLLAMA_TEXT_MODELS`). `ollamaText()`
|
|
38
|
+
accepts any string, but a bare `llama3.3` falls outside the typed catalog and
|
|
39
|
+
`modelOptions` degrades to the raw Ollama `ChatRequest` (which then demands a
|
|
40
|
+
`model` field). Use `llama3.3:latest`.
|
|
36
41
|
|
|
37
42
|
Models must be pulled first: `ollama pull llama3.3`
|
|
38
43
|
|
|
@@ -48,8 +53,10 @@ Ollama's own request shape) — `temperature`, `top_p`, and `num_predict`
|
|
|
48
53
|
import { chat } from '@tanstack/ai'
|
|
49
54
|
import { ollamaText } from '@tanstack/ai-ollama'
|
|
50
55
|
|
|
56
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
57
|
+
|
|
51
58
|
const stream = chat({
|
|
52
|
-
adapter: ollamaText('llama3.3'),
|
|
59
|
+
adapter: ollamaText('llama3.3:latest'),
|
|
53
60
|
messages,
|
|
54
61
|
modelOptions: {
|
|
55
62
|
options: {
|
|
@@ -64,9 +71,15 @@ const stream = chat({
|
|
|
64
71
|
|
|
65
72
|
## Configuration
|
|
66
73
|
|
|
74
|
+
`ollamaText(model)` takes no config — it reads `OLLAMA_HOST`. To point at
|
|
75
|
+
another server (or pass headers / `baseURL` for a gateway), use
|
|
76
|
+
`createOllamaChat(model, hostOrConfig)`:
|
|
77
|
+
|
|
67
78
|
```typescript
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
import { createOllamaChat } from '@tanstack/ai-ollama'
|
|
80
|
+
|
|
81
|
+
// With explicit host (ollamaText() reads OLLAMA_HOST instead)
|
|
82
|
+
const adapter = createOllamaChat('llama3.3:latest', {
|
|
70
83
|
host: 'http://my-server:11434',
|
|
71
84
|
})
|
|
72
85
|
```
|
|
@@ -28,20 +28,30 @@ import { openaiSpeech } from '@tanstack/ai-openai'
|
|
|
28
28
|
|
|
29
29
|
## Key Chat Models
|
|
30
30
|
|
|
31
|
-
| Model
|
|
32
|
-
|
|
|
33
|
-
| `gpt-
|
|
34
|
-
| `gpt-5.
|
|
35
|
-
| `gpt-5.
|
|
36
|
-
| `gpt-5.
|
|
37
|
-
| `gpt-5`
|
|
38
|
-
| `gpt-5
|
|
31
|
+
| Model | Context Window | Max Output | Notes |
|
|
32
|
+
| -------------- | -------------- | ---------- | ---------------------------------------------- |
|
|
33
|
+
| `gpt-6-astra` | 1M | 128K | Newest; reasoning, tools, image input |
|
|
34
|
+
| `gpt-5.6` | 1M | 128K | Reasoning, tools, image input |
|
|
35
|
+
| `gpt-5.5` | 1M | 128K | Flagship used in examples; text/image/document |
|
|
36
|
+
| `gpt-5.5-pro` | 1M | 128K | Higher reasoning tier |
|
|
37
|
+
| `gpt-5.4-mini` | 400K | 128K | Cost-efficient (no bare `gpt-5.4` chat id) |
|
|
38
|
+
| `gpt-5.2` | 400K | 128K | Previous flagship; text/image/document |
|
|
39
|
+
| `gpt-5-mini` | 400K | 128K | Budget |
|
|
40
|
+
|
|
41
|
+
`OPENAI_CHAT_MODELS` is the full list (also `gpt-6-astra-pro`, the
|
|
42
|
+
`gpt-5.6-luna/sol/terra` family, `gpt-5.4-nano`, `gpt-5.2-pro`,
|
|
43
|
+
`gpt-5.1`, `gpt-5`, the `o3`/`o4-mini` reasoning models, and `gpt-4.1`/`gpt-4o`).
|
|
39
44
|
|
|
40
45
|
## Provider-Specific modelOptions
|
|
41
46
|
|
|
42
47
|
```typescript
|
|
48
|
+
import { chat } from '@tanstack/ai'
|
|
49
|
+
import { openaiText } from '@tanstack/ai-openai'
|
|
50
|
+
|
|
51
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
52
|
+
|
|
43
53
|
chat({
|
|
44
|
-
adapter: openaiText('gpt-5.
|
|
54
|
+
adapter: openaiText('gpt-5.5'),
|
|
45
55
|
messages,
|
|
46
56
|
modelOptions: {
|
|
47
57
|
// Sampling
|
|
@@ -38,24 +38,29 @@ the format `provider/model-name`:
|
|
|
38
38
|
OpenRouter has unique routing and provider selection options:
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
|
+
import { chat } from '@tanstack/ai'
|
|
42
|
+
import { openRouterText } from '@tanstack/ai-openrouter'
|
|
43
|
+
|
|
44
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
45
|
+
|
|
46
|
+
// Options are narrowed per model from OpenRouter's published metadata —
|
|
47
|
+
// e.g. 'anthropic/claude-sonnet-4' only accepts temperature/topP/
|
|
48
|
+
// maxCompletionTokens/stop/toolChoice/reasoning. This model takes the full set.
|
|
41
49
|
chat({
|
|
42
|
-
adapter: openRouterText('
|
|
50
|
+
adapter: openRouterText('deepseek/deepseek-v4-pro'),
|
|
43
51
|
messages,
|
|
44
52
|
modelOptions: {
|
|
45
53
|
// Reasoning
|
|
46
54
|
reasoning: {
|
|
47
|
-
effort: 'high', // 'none' | 'minimal' | 'low' | 'medium' | 'high'
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
effort: 'high', // 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
|
|
56
|
+
summary: 'auto',
|
|
57
|
+
// enabled: false — explicit opt-out (normalized to effort: 'none')
|
|
50
58
|
},
|
|
51
59
|
// Sampling
|
|
52
60
|
temperature: 0.7,
|
|
53
61
|
topP: 0.9,
|
|
54
|
-
topK: 40,
|
|
55
62
|
frequencyPenalty: 0.5,
|
|
56
63
|
presencePenalty: 0.5,
|
|
57
|
-
repetitionPenalty: 1.1,
|
|
58
|
-
minP: 0.05,
|
|
59
64
|
seed: 42,
|
|
60
65
|
// Token limits
|
|
61
66
|
maxCompletionTokens: 8192,
|
|
@@ -66,12 +71,11 @@ chat({
|
|
|
66
71
|
parallelToolCalls: true,
|
|
67
72
|
// Response format
|
|
68
73
|
responseFormat: { type: 'json_object' },
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
},
|
|
73
|
-
//
|
|
74
|
-
verbosity: 'medium',
|
|
74
|
+
// Routing (available on every model)
|
|
75
|
+
variant: 'nitro', // 'free' | 'nitro' | 'online' | 'exacto' | 'extended' | 'thinking'
|
|
76
|
+
models: ['deepseek/deepseek-v4-flash'], // fallbacks, tried in order
|
|
77
|
+
provider: { order: ['DeepSeek'], allowFallbacks: true },
|
|
78
|
+
plugins: [{ id: 'web' }], // web search
|
|
75
79
|
// Logprobs
|
|
76
80
|
logprobs: true,
|
|
77
81
|
topLogprobs: 5,
|
|
@@ -89,11 +93,20 @@ OPENROUTER_API_KEY
|
|
|
89
93
|
|
|
90
94
|
- Model IDs are `provider/model-name` format (e.g., `openai/gpt-5.2`).
|
|
91
95
|
- OpenRouter has unique features not found in direct provider adapters:
|
|
92
|
-
- `variant` option: `'free'`, `'nitro'`, `'online'`, `'
|
|
93
|
-
|
|
94
|
-
- `
|
|
95
|
-
|
|
96
|
-
- `
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
-
|
|
96
|
+
- `variant` option: `'free'`, `'nitro'`, `'online'`, `'exacto'`,
|
|
97
|
+
`'extended'`, `'thinking'`
|
|
98
|
+
- `provider` routing preferences (`order`, `allowFallbacks`, data
|
|
99
|
+
collection policies — camelCase keys)
|
|
100
|
+
- `models` array of fallback ids, tried in order
|
|
101
|
+
- `plugins: [{ id: 'web' }]` for web search (also `file-parser`,
|
|
102
|
+
`response-healing`, `moderation`, `auto-router`)
|
|
103
|
+
- Uses `camelCase` for option names (e.g., `topP`, `frequencyPenalty`,
|
|
104
|
+
`maxCompletionTokens`), unlike OpenAI's `snake_case`.
|
|
105
|
+
- `reasoning` is `{ effort, summary, enabled }` — there is no
|
|
106
|
+
`max_tokens`/`exclude` inside it; `enabled: false` is normalized to
|
|
107
|
+
`effort: 'none'`.
|
|
108
|
+
- Per-model options are narrowed from OpenRouter's published metadata, so
|
|
109
|
+
keys like `frequencyPenalty`, `seed`, `logprobs`, or `responseFormat` are
|
|
110
|
+
only accepted on models that support them. `topK`, `minP`,
|
|
111
|
+
`repetitionPenalty`, `webSearchOptions`, `verbosity`, `transforms`, and
|
|
112
|
+
`route` are not exposed by the adapter.
|
|
@@ -29,7 +29,7 @@ import { openaiText } from '@tanstack/ai-openai'
|
|
|
29
29
|
export async function POST(request: Request) {
|
|
30
30
|
const { messages } = await request.json()
|
|
31
31
|
const stream = chat({
|
|
32
|
-
adapter: openaiText('gpt-5.
|
|
32
|
+
adapter: openaiText('gpt-5.6'),
|
|
33
33
|
messages,
|
|
34
34
|
})
|
|
35
35
|
return toServerSentEventsResponse(stream)
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
mergeAgentTools,
|
|
50
50
|
toServerSentEventsResponse,
|
|
51
51
|
} from '@tanstack/ai'
|
|
52
|
-
import { openaiText } from '@tanstack/ai-openai
|
|
52
|
+
import { openaiText } from '@tanstack/ai-openai'
|
|
53
53
|
import { serverTools } from './tools'
|
|
54
54
|
|
|
55
55
|
export async function POST(req: Request) {
|
|
@@ -64,7 +64,7 @@ export async function POST(req: Request) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
const stream = chat({
|
|
67
|
-
adapter: openaiText('gpt-
|
|
67
|
+
adapter: openaiText('gpt-5.6'),
|
|
68
68
|
messages: params.messages,
|
|
69
69
|
tools: mergeAgentTools(serverTools, params.tools),
|
|
70
70
|
})
|
|
@@ -87,7 +87,7 @@ export async function POST(req: Request) {
|
|
|
87
87
|
|
|
88
88
|
**Wire format:** Each event is `data: <JSON>\n\n`. Stream ends with `data: [DONE]\n\n`.
|
|
89
89
|
|
|
90
|
-
```typescript
|
|
90
|
+
```typescript group=sse-response
|
|
91
91
|
import {
|
|
92
92
|
chat,
|
|
93
93
|
toServerSentEventsStream,
|
|
@@ -95,10 +95,12 @@ import {
|
|
|
95
95
|
} from '@tanstack/ai'
|
|
96
96
|
import { openaiText } from '@tanstack/ai-openai'
|
|
97
97
|
|
|
98
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
99
|
+
|
|
98
100
|
// Option A: Get a ReadableStream (manual Response construction)
|
|
99
101
|
const abortController = new AbortController()
|
|
100
102
|
const stream = chat({
|
|
101
|
-
adapter: openaiText('gpt-5.
|
|
103
|
+
adapter: openaiText('gpt-5.6'),
|
|
102
104
|
messages,
|
|
103
105
|
abortController,
|
|
104
106
|
})
|
|
@@ -127,7 +129,7 @@ const response2 = toServerSentEventsResponse(stream, { abortController })
|
|
|
127
129
|
|
|
128
130
|
Custom headers merge on top (user headers override defaults):
|
|
129
131
|
|
|
130
|
-
```typescript
|
|
132
|
+
```typescript group=sse-response
|
|
131
133
|
toServerSentEventsResponse(stream, {
|
|
132
134
|
headers: {
|
|
133
135
|
'X-Accel-Buffering': 'no', // Disable nginx buffering
|
|
@@ -149,10 +151,12 @@ aborted, the error event is suppressed and the stream closes silently.
|
|
|
149
151
|
import { chat, toHttpStream, toHttpResponse } from '@tanstack/ai'
|
|
150
152
|
import { openaiText } from '@tanstack/ai-openai'
|
|
151
153
|
|
|
154
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
155
|
+
|
|
152
156
|
// Option A: Get a ReadableStream
|
|
153
157
|
const abortController = new AbortController()
|
|
154
158
|
const stream = chat({
|
|
155
|
-
adapter: openaiText('gpt-5.
|
|
159
|
+
adapter: openaiText('gpt-5.6'),
|
|
156
160
|
messages,
|
|
157
161
|
abortController,
|
|
158
162
|
})
|
|
@@ -199,7 +203,7 @@ All events extend `BaseAGUIEvent` which carries `type`, `timestamp`, optional
|
|
|
199
203
|
| `STATE_DELTA` | Incremental state update. Carries `delta: Record<string, unknown>`. |
|
|
200
204
|
| `CUSTOM` | Extension point. Carries `name` (string) and optional `value` (unknown). |
|
|
201
205
|
| `RUN_FINISHED` | Stream complete. Carries `runId` and `finishReason` (`'stop'` / `'length'` / `'content_filter'` / `'tool_calls'` / `null`). |
|
|
202
|
-
| `RUN_ERROR` | Error during stream. Carries optional `
|
|
206
|
+
| `RUN_ERROR` | Error during stream. Carries `message`, optional `code` and `runId`; a nested `error: { message, code? }` copy is kept too. |
|
|
203
207
|
|
|
204
208
|
**Typical event sequence for a text-only response:**
|
|
205
209
|
|
|
@@ -235,8 +239,10 @@ no helper, no cast:
|
|
|
235
239
|
import { chat } from '@tanstack/ai'
|
|
236
240
|
import { openaiText } from '@tanstack/ai-openai'
|
|
237
241
|
|
|
242
|
+
const messages = [{ role: 'user' as const, content: 'Hello' }]
|
|
243
|
+
|
|
238
244
|
const stream = chat({
|
|
239
|
-
adapter: openaiText('gpt-5.
|
|
245
|
+
adapter: openaiText('gpt-5.6'),
|
|
240
246
|
messages,
|
|
241
247
|
})
|
|
242
248
|
|
|
@@ -284,7 +290,7 @@ causing events to arrive in batches instead of streaming token-by-token.
|
|
|
284
290
|
|
|
285
291
|
Fix: Set proxy-bypass headers on the response.
|
|
286
292
|
|
|
287
|
-
```typescript
|
|
293
|
+
```typescript group=sse-response
|
|
288
294
|
toServerSentEventsResponse(stream, {
|
|
289
295
|
headers: {
|
|
290
296
|
'X-Accel-Buffering': 'no', // nginx
|