@tanstack/ai-client 0.11.5 → 0.11.7
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 +250 -79
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js.map +1 -1
- package/package.json +13 -7
- package/src/types.ts +1 -0
package/README.md
CHANGED
|
@@ -1,93 +1,253 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="
|
|
2
|
+
<img src="https://raw.githubusercontent.com/TanStack/ai/main/media/header_ai.png" alt="TanStack AI" />
|
|
3
3
|
</div>
|
|
4
4
|
|
|
5
5
|
<br />
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
8
|
-
<a href="https://npmjs.com/package/@tanstack/ai" target="
|
|
9
|
-
|
|
10
|
-
</a>
|
|
11
|
-
<a href="https://github.com/TanStack/ai" target="
|
|
12
|
-
|
|
13
|
-
</a>
|
|
14
|
-
<a href="https://
|
|
15
|
-
|
|
16
|
-
</a>
|
|
8
|
+
<a href="https://npmjs.com/package/@tanstack/ai" target="_parent">
|
|
9
|
+
<img alt="NPM downloads" src="https://img.shields.io/npm/dm/@tanstack/ai.svg" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/TanStack/ai" target="_parent">
|
|
12
|
+
<img alt="GitHub stars" src="https://img.shields.io/github/stars/TanStack/ai.svg?style=social&label=Star" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://github.com/TanStack/ai/releases" target="_parent">
|
|
15
|
+
<img alt="Release" src="https://img.shields.io/github/v/release/tanstack/ai" />
|
|
16
|
+
</a>
|
|
17
|
+
<a href="https://bundlephobia.com/result?p=@tanstack/ai@latest" target="_parent">
|
|
18
|
+
<img alt="Bundle size" src="https://badgen.net/bundlephobia/minzip/@tanstack/ai@latest" />
|
|
19
|
+
</a>
|
|
20
|
+
<a href="https://twitter.com/tan_stack">
|
|
21
|
+
<img alt="Follow @TanStack" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" />
|
|
22
|
+
</a>
|
|
17
23
|
</div>
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
<a href="#badge">
|
|
21
|
-
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
|
22
|
-
</a>
|
|
23
|
-
<a href="#badge">
|
|
24
|
-
<img src="https://img.shields.io/github/v/release/tanstack/ai" alt="Release"/>
|
|
25
|
-
</a>
|
|
26
|
-
<a href="https://twitter.com/tan_stack">
|
|
27
|
-
<img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/>
|
|
28
|
-
</a>
|
|
29
|
-
</div>
|
|
25
|
+
# TanStack AI
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
</div>
|
|
27
|
+
Type-safe, provider-agnostic TypeScript SDK for building streaming chat,
|
|
28
|
+
tool-calling agents, structured outputs, realtime voice, media generation, and
|
|
29
|
+
framework-native AI apps.
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
TanStack AI is built from composable activities and provider adapters. Use one
|
|
32
|
+
provider or switch between many. Import only chat, or add image, audio, video,
|
|
33
|
+
speech, transcription, summarization, realtime, Code Mode, devtools, and
|
|
34
|
+
framework bindings as your app needs them.
|
|
35
|
+
|
|
36
|
+
## <a href="https://tanstack.com/ai">Read the docs -></a>
|
|
37
|
+
|
|
38
|
+
## Start Here
|
|
39
|
+
|
|
40
|
+
- [Overview](https://tanstack.com/ai/latest/docs/getting-started/overview) -
|
|
41
|
+
what TanStack AI is and how the packages fit together.
|
|
42
|
+
- [Quick Start: React](https://tanstack.com/ai/latest/docs/getting-started/quick-start) -
|
|
43
|
+
add streaming chat to a React app.
|
|
44
|
+
- [Quick Start: Vue](https://tanstack.com/ai/latest/docs/getting-started/quick-start-vue) -
|
|
45
|
+
build with Vue composables.
|
|
46
|
+
- [Quick Start: Svelte](https://tanstack.com/ai/latest/docs/getting-started/quick-start-svelte) -
|
|
47
|
+
build with Svelte 5 runes.
|
|
48
|
+
- [Quick Start: Server Only](https://tanstack.com/ai/latest/docs/getting-started/quick-start-server) -
|
|
49
|
+
use TanStack AI from a server endpoint, script, or backend service.
|
|
50
|
+
- [TanStack AI vs Vercel AI SDK](https://tanstack.com/ai/latest/docs/comparison/vercel-ai-sdk) -
|
|
51
|
+
compare architecture, feature coverage, and tradeoffs.
|
|
52
|
+
|
|
53
|
+
## What You Can Build
|
|
54
|
+
|
|
55
|
+
- Streaming chat experiences with typed messages, tool calls, reasoning parts,
|
|
56
|
+
and configurable connection adapters.
|
|
57
|
+
- Type-safe tools that can run on the server or client from one shared
|
|
58
|
+
`toolDefinition()` contract.
|
|
59
|
+
- Structured output flows backed by JSON Schema, Zod, ArkType, Valibot, or
|
|
60
|
+
plain JSON Schema.
|
|
61
|
+
- Multimodal prompts and responses that include text, images, audio, video, and
|
|
62
|
+
documents.
|
|
63
|
+
- Image, audio, video, speech, transcription, and summarization workflows using
|
|
64
|
+
a shared generation client pattern.
|
|
65
|
+
- Realtime voice chat with provider adapters for realtime sessions and token
|
|
66
|
+
minting.
|
|
67
|
+
- Code Mode agents that let an LLM write and execute TypeScript in an isolated
|
|
68
|
+
sandbox to orchestrate tools with loops, branches, and parallel calls.
|
|
69
|
+
- Devtools and observability pipelines for inspecting messages, tool calls,
|
|
70
|
+
stream chunks, errors, usage, and OpenTelemetry traces.
|
|
71
|
+
- Framework-native clients for React, Solid, Vue, Svelte, and Preact, plus a
|
|
72
|
+
headless client for custom runtimes.
|
|
73
|
+
|
|
74
|
+
## Install
|
|
37
75
|
|
|
38
|
-
|
|
76
|
+
Install the core package and the provider/framework packages your app uses:
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
78
|
+
```bash
|
|
79
|
+
pnpm add @tanstack/ai @tanstack/ai-openai
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
For a React chat UI:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pnpm add @tanstack/ai @tanstack/ai-client @tanstack/ai-react @tanstack/ai-openai
|
|
86
|
+
```
|
|
49
87
|
|
|
50
|
-
|
|
88
|
+
OpenRouter is also a good starting point if you want access to many providers
|
|
89
|
+
through one API key:
|
|
51
90
|
|
|
52
|
-
|
|
91
|
+
```bash
|
|
92
|
+
pnpm add @tanstack/ai @tanstack/ai-openrouter
|
|
93
|
+
```
|
|
53
94
|
|
|
54
|
-
|
|
95
|
+
## Streaming Chat
|
|
55
96
|
|
|
56
97
|
```typescript
|
|
57
|
-
|
|
58
|
-
import { openaiText } from '@tanstack/ai-openai
|
|
59
|
-
import { generate } from '@tanstack/ai'
|
|
98
|
+
import { chat, toServerSentEventsResponse } from '@tanstack/ai'
|
|
99
|
+
import { openaiText } from '@tanstack/ai-openai'
|
|
60
100
|
|
|
61
|
-
|
|
101
|
+
export async function POST(request: Request) {
|
|
102
|
+
const body = await request.json()
|
|
62
103
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
104
|
+
const stream = chat({
|
|
105
|
+
adapter: openaiText('gpt-5.2'),
|
|
106
|
+
messages: body.messages,
|
|
107
|
+
})
|
|
68
108
|
|
|
69
|
-
|
|
70
|
-
console.log(chunk)
|
|
109
|
+
return toServerSentEventsResponse(stream)
|
|
71
110
|
}
|
|
72
111
|
```
|
|
73
112
|
|
|
74
|
-
|
|
113
|
+
Learn more in the
|
|
114
|
+
[Chat & Streaming docs](https://tanstack.com/ai/latest/docs/chat/streaming) and
|
|
115
|
+
[Connection Adapters docs](https://tanstack.com/ai/latest/docs/chat/connection-adapters).
|
|
116
|
+
|
|
117
|
+
## Type-Safe Tools
|
|
118
|
+
|
|
119
|
+
Define a tool once, then attach a server or client implementation with the same
|
|
120
|
+
input and output types:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { toolDefinition } from '@tanstack/ai'
|
|
124
|
+
import { z } from 'zod'
|
|
125
|
+
|
|
126
|
+
const getProducts = toolDefinition({
|
|
127
|
+
name: 'getProducts',
|
|
128
|
+
description: 'Search the product catalog',
|
|
129
|
+
inputSchema: z.object({ query: z.string() }),
|
|
130
|
+
outputSchema: z.array(
|
|
131
|
+
z.object({
|
|
132
|
+
id: z.string(),
|
|
133
|
+
name: z.string(),
|
|
134
|
+
}),
|
|
135
|
+
),
|
|
136
|
+
}).server(async ({ query }) => {
|
|
137
|
+
return db.products.search(query)
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Learn more in the
|
|
142
|
+
[Tools docs](https://tanstack.com/ai/latest/docs/tools/tools),
|
|
143
|
+
[Tool Approval Flow docs](https://tanstack.com/ai/latest/docs/tools/tool-approval),
|
|
144
|
+
and
|
|
145
|
+
[Lazy Tool Discovery docs](https://tanstack.com/ai/latest/docs/tools/lazy-tool-discovery).
|
|
146
|
+
|
|
147
|
+
## Structured Outputs
|
|
148
|
+
|
|
149
|
+
Use `outputSchema` when you need typed objects instead of freeform text:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { chat } from '@tanstack/ai'
|
|
153
|
+
import { openaiText } from '@tanstack/ai-openai'
|
|
154
|
+
import { z } from 'zod'
|
|
155
|
+
|
|
156
|
+
const Person = z.object({
|
|
157
|
+
name: z.string(),
|
|
158
|
+
age: z.number(),
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
const person = await chat({
|
|
162
|
+
adapter: openaiText('gpt-5.2'),
|
|
163
|
+
messages: [{ role: 'user', content: 'Ada Lovelace, 36' }],
|
|
164
|
+
outputSchema: Person,
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Learn more in the
|
|
169
|
+
[Structured Outputs docs](https://tanstack.com/ai/latest/docs/structured-outputs/overview).
|
|
170
|
+
|
|
171
|
+
## Media, Realtime, and Code Mode
|
|
172
|
+
|
|
173
|
+
- [Generations](https://tanstack.com/ai/latest/docs/media/generations) - one
|
|
174
|
+
pattern for image generation, text-to-speech, transcription, summarization,
|
|
175
|
+
audio generation, and video generation.
|
|
176
|
+
- [Realtime Voice Chat](https://tanstack.com/ai/latest/docs/media/realtime-chat) -
|
|
177
|
+
build low-latency realtime voice experiences.
|
|
178
|
+
- [Code Mode](https://tanstack.com/ai/latest/docs/code-mode/code-mode) - let
|
|
179
|
+
models write and execute TypeScript inside a secure isolate.
|
|
180
|
+
- [Code Mode with Skills](https://tanstack.com/ai/latest/docs/code-mode/code-mode-with-skills) -
|
|
181
|
+
give Code Mode reusable runtime capabilities.
|
|
182
|
+
|
|
183
|
+
## Providers
|
|
184
|
+
|
|
185
|
+
Official adapters include:
|
|
186
|
+
|
|
187
|
+
| Package | Use it for |
|
|
188
|
+
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
|
|
189
|
+
| [`@tanstack/ai-openrouter`](https://tanstack.com/ai/latest/docs/adapters/openrouter) | 300+ models through one OpenRouter API |
|
|
190
|
+
| [`@tanstack/ai-openai`](https://tanstack.com/ai/latest/docs/adapters/openai) | OpenAI chat, image, video, speech, transcription, realtime, and provider tools |
|
|
191
|
+
| [`@tanstack/ai-anthropic`](https://tanstack.com/ai/latest/docs/adapters/anthropic) | Anthropic Claude chat, thinking, tools, and structured outputs |
|
|
192
|
+
| [`@tanstack/ai-gemini`](https://tanstack.com/ai/latest/docs/adapters/gemini) | Google Gemini chat, image, speech, and audio generation |
|
|
193
|
+
| [`@tanstack/ai-ollama`](https://tanstack.com/ai/latest/docs/adapters/ollama) | Local Ollama models |
|
|
194
|
+
| [`@tanstack/ai-grok`](https://tanstack.com/ai/latest/docs/adapters/grok) | xAI Grok chat, images, and realtime |
|
|
195
|
+
| [`@tanstack/ai-groq`](https://tanstack.com/ai/latest/docs/adapters/groq) | Groq low-latency inference |
|
|
196
|
+
| [`@tanstack/ai-elevenlabs`](https://tanstack.com/ai/latest/docs/adapters/elevenlabs) | ElevenLabs realtime voice, speech, transcription, music, and sound effects |
|
|
197
|
+
| [`@tanstack/ai-fal`](https://tanstack.com/ai/latest/docs/adapters/fal) | fal.ai image, video, audio, speech, and transcription models |
|
|
198
|
+
|
|
199
|
+
The adapter system is tree-shakeable by activity. Import `openaiText` for chat,
|
|
200
|
+
`openaiImage` for images, `falVideo` for video, `geminiSpeech` for TTS, and so
|
|
201
|
+
on.
|
|
202
|
+
|
|
203
|
+
## Framework Packages
|
|
204
|
+
|
|
205
|
+
| Package | What it provides |
|
|
206
|
+
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
207
|
+
| [`@tanstack/ai-client`](https://tanstack.com/ai/latest/docs/api/ai-client) | Headless chat, realtime, and generation clients |
|
|
208
|
+
| [`@tanstack/ai-react`](https://tanstack.com/ai/latest/docs/api/ai-react) | React hooks including `useChat`, `useRealtimeChat`, and generation hooks |
|
|
209
|
+
| [`@tanstack/ai-solid`](https://tanstack.com/ai/latest/docs/api/ai-solid) | Solid hooks for chat and generations |
|
|
210
|
+
| [`@tanstack/ai-vue`](https://tanstack.com/ai/latest/docs/api/ai-vue) | Vue composables for chat and generations |
|
|
211
|
+
| [`@tanstack/ai-svelte`](https://tanstack.com/ai/latest/docs/api/ai-svelte) | Svelte 5 factories for chat and generations |
|
|
212
|
+
| [`@tanstack/ai-preact`](https://tanstack.com/ai/latest/docs/api/ai-preact) | Preact hooks for chat |
|
|
213
|
+
| `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, `@tanstack/ai-vue-ui` | Headless UI components for chat interfaces |
|
|
214
|
+
|
|
215
|
+
## Advanced Docs
|
|
216
|
+
|
|
217
|
+
- [Middleware](https://tanstack.com/ai/latest/docs/advanced/middleware) - hook
|
|
218
|
+
into chat configuration, chunks, tool calls, usage, errors, and structured
|
|
219
|
+
outputs.
|
|
220
|
+
- [OpenTelemetry](https://tanstack.com/ai/latest/docs/advanced/otel) - emit
|
|
221
|
+
vendor-neutral GenAI traces and metrics.
|
|
222
|
+
- [Observability](https://tanstack.com/ai/latest/docs/advanced/observability) -
|
|
223
|
+
subscribe to typed TanStack AI events.
|
|
224
|
+
- [Per-Model Type Safety](https://tanstack.com/ai/latest/docs/advanced/per-model-type-safety) -
|
|
225
|
+
narrow model options and content modalities to the selected model.
|
|
226
|
+
- [Runtime Adapter Switching](https://tanstack.com/ai/latest/docs/advanced/runtime-adapter-switching) -
|
|
227
|
+
switch providers at runtime.
|
|
228
|
+
- [Tree-Shaking](https://tanstack.com/ai/latest/docs/advanced/tree-shaking) -
|
|
229
|
+
ship only the activities and adapters you use.
|
|
230
|
+
- [Agent Skills](https://tanstack.com/ai/latest/docs/getting-started/agent-skills) -
|
|
231
|
+
install TanStack AI skills into Claude Code, Cursor, GitHub Copilot, Codex,
|
|
232
|
+
and other coding agents with TanStack Intent.
|
|
75
233
|
|
|
76
234
|
## Get Involved
|
|
77
235
|
|
|
78
|
-
-
|
|
79
|
-
- Participate in [GitHub discussions](https://github.com/TanStack/ai/discussions)
|
|
80
|
-
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
|
|
81
|
-
- See [CONTRIBUTING.md](
|
|
236
|
+
- Read the [docs](https://tanstack.com/ai).
|
|
237
|
+
- Participate in [GitHub discussions](https://github.com/TanStack/ai/discussions).
|
|
238
|
+
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ).
|
|
239
|
+
- See [CONTRIBUTING.md](https://github.com/TanStack/ai/blob/main/CONTRIBUTING.md)
|
|
240
|
+
for setup instructions.
|
|
241
|
+
- [Become a sponsor](https://github.com/sponsors/tannerlinsley/).
|
|
82
242
|
|
|
83
243
|
## Partners
|
|
84
244
|
|
|
85
245
|
<table align="center">
|
|
86
246
|
<tr>
|
|
87
247
|
<td>
|
|
88
|
-
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS"
|
|
248
|
+
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS">
|
|
89
249
|
<picture>
|
|
90
|
-
|
|
250
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-D643Zkrv.svg" />
|
|
91
251
|
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-CIzGLYU_.svg" />
|
|
92
252
|
<img src="https://tanstack.com/assets/coderabbit-light-CIzGLYU_.svg" height="40" alt="CodeRabbit" />
|
|
93
253
|
</picture>
|
|
@@ -96,7 +256,7 @@ Available adapters: `openaiText`, `openaiEmbed`, `openaiSummarize`, `anthropicTe
|
|
|
96
256
|
<td>
|
|
97
257
|
<a href="https://www.cloudflare.com?utm_source=tanstack">
|
|
98
258
|
<picture>
|
|
99
|
-
|
|
259
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-Co-Tyjbl.svg" />
|
|
100
260
|
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-6Ojsn8yh.svg" />
|
|
101
261
|
<img src="https://tanstack.com/assets/cloudflare-white-Co-Tyjbl.svg" height="60" alt="Cloudflare" />
|
|
102
262
|
</picture>
|
|
@@ -106,28 +266,39 @@ Available adapters: `openaiText`, `openaiEmbed`, `openaiSummarize`, `anthropicTe
|
|
|
106
266
|
</table>
|
|
107
267
|
|
|
108
268
|
<div align="center">
|
|
109
|
-
<img src="
|
|
110
|
-
<p>
|
|
111
|
-
We're looking for TanStack AI
|
|
112
|
-
|
|
113
|
-
|
|
269
|
+
<img src="https://raw.githubusercontent.com/TanStack/ai/main/media/partner_logo.svg" alt="AI and you?" height="65" />
|
|
270
|
+
<p>
|
|
271
|
+
We're looking for TanStack AI partners to join our mission. Partner with us
|
|
272
|
+
to push the boundaries of TanStack AI and build amazing things together.
|
|
273
|
+
</p>
|
|
274
|
+
<a href="mailto:partners@tanstack.com?subject=TanStack AI Partnership"><b>LET'S CHAT</b></a>
|
|
114
275
|
</div>
|
|
115
276
|
|
|
116
277
|
## Explore the TanStack Ecosystem
|
|
117
278
|
|
|
118
|
-
- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a>
|
|
119
|
-
|
|
120
|
-
- <a href="https://github.com/tanstack/
|
|
121
|
-
|
|
122
|
-
- <a href="https://github.com/tanstack/
|
|
123
|
-
|
|
124
|
-
- <a href="https://github.com/tanstack/
|
|
125
|
-
-
|
|
126
|
-
- <a href="https://github.com/tanstack/
|
|
127
|
-
|
|
128
|
-
- <a href="https://github.com/tanstack/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
279
|
+
- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> -
|
|
280
|
+
tooling for JS/TS packages
|
|
281
|
+
- <a href="https://github.com/tanstack/db"><b>TanStack DB</b></a> - reactive
|
|
282
|
+
sync client store
|
|
283
|
+
- <a href="https://github.com/tanstack/devtools"><b>TanStack Devtools</b></a> -
|
|
284
|
+
unified devtools panel
|
|
285
|
+
- <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> -
|
|
286
|
+
type-safe form state
|
|
287
|
+
- <a href="https://github.com/tanstack/pacer"><b>TanStack Pacer</b></a> -
|
|
288
|
+
debouncing, throttling, batching
|
|
289
|
+
- <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> -
|
|
290
|
+
async state and caching
|
|
291
|
+
- <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> -
|
|
292
|
+
range and slider primitives
|
|
293
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> -
|
|
294
|
+
type-safe routing, caching, and URL state
|
|
295
|
+
- <a href="https://github.com/tanstack/start"><b>TanStack Start</b></a> -
|
|
296
|
+
full-stack SSR and streaming
|
|
297
|
+
- <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> -
|
|
298
|
+
reactive data store
|
|
299
|
+
- <a href="https://github.com/tanstack/table"><b>TanStack Table</b></a> -
|
|
300
|
+
headless datagrids
|
|
301
|
+
- <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> -
|
|
302
|
+
virtualized rendering
|
|
303
|
+
|
|
304
|
+
...and more at <a href="https://tanstack.com"><b>TanStack.com</b></a>.
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { StructuredOutputPart } from '@tanstack/ai';
|
|
|
4
4
|
/**
|
|
5
5
|
* Tool call states - track the lifecycle of a tool call
|
|
6
6
|
*/
|
|
7
|
-
export type ToolCallState = 'awaiting-input' | 'input-streaming' | 'input-complete' | 'approval-requested' | 'approval-responded';
|
|
7
|
+
export type ToolCallState = 'awaiting-input' | 'input-streaming' | 'input-complete' | 'approval-requested' | 'approval-responded' | 'complete';
|
|
8
8
|
/**
|
|
9
9
|
* Tool result states - track the lifecycle of a tool result
|
|
10
10
|
*/
|
package/dist/esm/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../src/types.ts"],"sourcesContent":["import type {\n AnyClientTool,\n AudioPart,\n ChunkStrategy,\n ContentPart,\n DocumentPart,\n ImagePart,\n InferToolInput,\n InferToolOutput,\n ModelMessage,\n StreamChunk,\n StructuredOutputPart,\n VideoPart,\n} from '@tanstack/ai'\nimport type { ConnectionAdapter } from './connection-adapters'\n\nexport type { StructuredOutputPart } from '@tanstack/ai'\n\n/**\n * Tool call states - track the lifecycle of a tool call\n */\nexport type ToolCallState =\n | 'awaiting-input' // Received start but no arguments yet\n | 'input-streaming' // Partial arguments received\n | 'input-complete' // All arguments received\n | 'approval-requested' // Waiting for user approval\n | 'approval-responded' // User has approved/denied\n\n/**\n * Tool result states - track the lifecycle of a tool result\n */\nexport type ToolResultState =\n | 'streaming' // Placeholder for future streamed output\n | 'complete' // Result is complete\n | 'error' // Error occurred\n\n/**\n * ChatClient state - track the lifecycle of a chat\n */\nexport type ChatClientState = 'ready' | 'submitted' | 'streaming' | 'error'\n\n/**\n * Connection lifecycle state for the subscription loop.\n */\nexport type ConnectionStatus =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'error'\n\n/**\n * Multimodal content input for sending messages with rich media.\n * Allows sending text, images, audio, video, and documents to the LLM.\n *\n * @example\n * ```ts\n * // Send an image with a question\n * client.sendMessage({\n * content: [\n * { type: 'text', content: 'What is in this image?' },\n * { type: 'image', source: { type: 'url', value: 'https://example.com/photo.jpg' } }\n * ],\n * id: 'custom-message-id' // optional\n * })\n * ```\n */\nexport interface MultimodalContent {\n /**\n * The content of the message.\n * Can be a simple string or an array of content parts for multimodal messages.\n */\n content: string | Array<ContentPart>\n /**\n * Optional custom ID for the message.\n * If not provided, a unique ID will be generated.\n */\n id?: string\n}\n\n/**\n * Message parts - building blocks of UIMessage\n */\nexport interface TextPart {\n type: 'text'\n content: string\n}\n\n/**\n * Helper type that creates a tool-call part for a specific tool.\n * This is a conditional type to enable proper distribution over union types,\n * creating a discriminated union where `name` is the discriminant.\n */\ntype ToolCallPartForTool<T> = T extends AnyClientTool\n ? {\n type: 'tool-call'\n id: string\n name: T['name']\n arguments: string // JSON string (may be incomplete)\n /** Parsed tool input (typed from inputSchema) */\n input?: InferToolInput<T>\n state: ToolCallState\n /** Approval metadata if tool requires user approval */\n approval?: {\n id: string // Unique approval ID\n needsApproval: boolean // Always true if present\n approved?: boolean // User's decision (undefined until responded)\n }\n /** Tool execution output (for client tools or after approval) */\n output?: InferToolOutput<T>\n }\n : never\n\n/**\n * Fallback tool-call part type when tools are not typed\n */\ntype UntypedToolCallPart = {\n type: 'tool-call'\n id: string\n name: string\n arguments: string\n input?: any\n state: ToolCallState\n approval?: {\n id: string\n needsApproval: boolean\n approved?: boolean\n }\n output?: any\n}\n\n/**\n * Tool call part that creates a proper discriminated union.\n * When TTools is typed, checking `part.name === 'toolName'` will narrow\n * `part.output` to the correct type for that tool.\n *\n * The discriminant is `name`, so code like:\n * ```ts\n * if (part.name === 'recommendGuitar') {\n * // part.output is now typed to the recommendGuitar tool's output\n * }\n * ```\n */\nexport type ToolCallPart<TTools extends ReadonlyArray<AnyClientTool> = any> =\n // Check if we have a concrete tools array (not 'any' or 'never')\n [TTools] extends [never]\n ? UntypedToolCallPart\n : unknown extends TTools\n ? UntypedToolCallPart\n : TTools extends ReadonlyArray<infer Tool>\n ? Tool extends AnyClientTool\n ? ToolCallPartForTool<Tool>\n : UntypedToolCallPart\n : UntypedToolCallPart\n\nexport interface ToolResultPart {\n type: 'tool-result'\n toolCallId: string\n content: string\n state: ToolResultState\n error?: string // Error message if state is \"error\"\n}\n\nexport interface ThinkingPart {\n type: 'thinking'\n content: string\n}\n\nexport type MessagePart<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TData = unknown,\n> =\n | TextPart\n | ImagePart\n | AudioPart\n | VideoPart\n | DocumentPart\n | ToolCallPart<TTools>\n | ToolResultPart\n | ThinkingPart\n | StructuredOutputPart<TData>\n\n/**\n * UIMessage - Domain-specific message format optimized for building chat UIs\n * Contains parts that can be text, tool calls, or tool results.\n *\n * `TTools` narrows the tool-call/result part types based on the registered\n * tools. `TData` is the schema-inferred type for any `structured-output` part\n * on the message — defaulted to `unknown` so untyped consumers (the core\n * stream processor, the wire converter) don't need to thread a schema generic\n * everywhere; the hook layer (`useChat({ outputSchema })`) substitutes it on\n * the public return so `m.parts.find(p => p.type === 'structured-output').data`\n * is typed without manual casts.\n */\nexport interface UIMessage<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TData = unknown,\n> {\n id: string\n role: 'system' | 'user' | 'assistant'\n parts: Array<MessagePart<TTools, TData>>\n createdAt?: Date\n}\n\nexport interface ChatClientOptions<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n> {\n /**\n * Connection adapter for streaming.\n * Supports mutually exclusive modes: request-response via `connect()`, or\n * subscribe/send mode via `subscribe()` + `send()`.\n */\n connection: ConnectionAdapter\n\n /**\n * Initial messages to populate the chat\n */\n initialMessages?: Array<UIMessage<TTools>>\n\n /**\n * Unique identifier for this chat instance\n * Used for managing multiple chats\n */\n id?: string\n\n /**\n * Thread ID to use for this chat session. Persists across sends within\n * the session. If omitted, a unique thread ID is generated.\n */\n threadId?: string\n\n /**\n * Arbitrary client-controlled JSON forwarded to the server in the\n * AG-UI `RunAgentInput.forwardedProps` field. Use this for per-session\n * options like provider/model selection or feature flags that the\n * server endpoint should read.\n *\n * Replaces the legacy `body` option. If both are provided,\n * `forwardedProps` wins on key collision.\n */\n forwardedProps?: Record<string, any>\n\n /**\n * @deprecated Use `forwardedProps` instead. `body` continues to work\n * unchanged — its values are merged into the AG-UI\n * `RunAgentInput.forwardedProps` field on the wire and are also\n * mirrored under the legacy `data` field for servers that have not\n * migrated yet. Will be removed in a future major release.\n */\n body?: Record<string, any>\n\n /**\n * Callback when a response is received\n */\n onResponse?: (response?: Response) => void | Promise<void>\n\n /**\n * Callback when a stream chunk is received\n */\n onChunk?: (chunk: StreamChunk) => void\n\n /**\n * Callback when the response is finished\n */\n onFinish?: (message: UIMessage<TTools>) => void\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void\n\n /**\n * Callback when messages change\n */\n onMessagesChange?: (messages: Array<UIMessage<TTools>>) => void\n\n /**\n * Callback when loading state changes\n */\n onLoadingChange?: (isLoading: boolean) => void\n\n /**\n * Callback when error state changes\n */\n onErrorChange?: (error: Error | undefined) => void\n\n /**\n * Callback when chat status changes\n */\n onStatusChange?: (status: ChatClientState) => void\n\n /**\n * Callback when subscription lifecycle changes.\n * This is independent from request lifecycle (`isLoading`, `status`).\n */\n onSubscriptionChange?: (isSubscribed: boolean) => void\n\n /**\n * Callback when connection lifecycle changes.\n */\n onConnectionStatusChange?: (status: ConnectionStatus) => void\n\n /**\n * Callback when session generation activity changes.\n * Derived from stream run events (RUN_STARTED / RUN_FINISHED / RUN_ERROR).\n * Unlike `onLoadingChange` (request-local), this reflects shared generation\n * activity visible to all subscribers (e.g. across tabs/devices).\n */\n onSessionGeneratingChange?: (isGenerating: boolean) => void\n\n /**\n * Callback when a custom event is received from a server-side tool.\n * Custom events are emitted by tools using `context.emitCustomEvent()` during execution.\n *\n * @param eventType - The name of the custom event\n * @param data - The event payload data\n * @param context - Additional context including the toolCallId that emitted the event\n */\n onCustomEvent?: (\n eventType: string,\n data: unknown,\n context: { toolCallId?: string },\n ) => void\n\n /**\n * Client-side tools with execution logic\n * When provided, tools with execute functions will be called automatically\n */\n tools?: TTools\n\n /**\n * Stream processing options (optional)\n * Configure chunking strategy\n */\n streamProcessor?: {\n /**\n * Strategy for when to emit text updates\n * Defaults to ImmediateStrategy (every chunk)\n */\n chunkStrategy?: ChunkStrategy\n }\n}\n\nexport interface ChatRequestBody {\n messages: Array<ModelMessage>\n data?: Record<string, any>\n}\n\n/**\n * Create a typed array of client tools with proper type inference.\n * This eliminates the need for `as const` when defining tool arrays.\n *\n * @example\n * ```ts\n * const tools = clientTools(\n * myTool1.client(() => result1),\n * myTool2.client(() => result2),\n * )\n *\n * // tools is now properly typed as a tuple with literal tool names\n * // This enables type narrowing when checking part.name === 'toolName'\n * ```\n */\nexport function clientTools<const T extends Array<AnyClientTool>>(\n ...tools: T\n): T {\n return tools\n}\n\n/**\n * Helper to create typed chat client options\n * Use this to get proper type inference for messages\n *\n * @example\n * ```ts\n * const tools = clientTools(myTool1, myTool2)\n *\n * const chatOptions = createChatClientOptions({\n * connection: fetchServerSentEvents('/api/chat'),\n * tools,\n * })\n *\n * type MyMessages = InferChatMessages<typeof chatOptions>\n * ```\n */\nexport function createChatClientOptions<\n const TTools extends ReadonlyArray<AnyClientTool>,\n>(options: ChatClientOptions<TTools>): ChatClientOptions<TTools> {\n return options\n}\n\n/**\n * Extract the message type from chat options\n *\n * @example\n * ```ts\n * const chatOptions = createChatClientOptions({\n * connection: fetchServerSentEvents('/api/chat'),\n * tools: [myTool1, myTool2],\n * })\n *\n * type MyMessages = InferChatMessages<typeof chatOptions>\n * // MyMessages is now Array<UIMessage<[typeof myTool1, typeof myTool2]>>\n * ```\n */\nexport type InferChatMessages<T> =\n T extends ChatClientOptions<infer TTools> ? Array<UIMessage<TTools>> : never\n"],"names":[],"mappings":"AA0WO,SAAS,eACX,OACA;AACH,SAAO;AACT;AAkBO,SAAS,wBAEd,SAA+D;AAC/D,SAAO;AACT;"}
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../src/types.ts"],"sourcesContent":["import type {\n AnyClientTool,\n AudioPart,\n ChunkStrategy,\n ContentPart,\n DocumentPart,\n ImagePart,\n InferToolInput,\n InferToolOutput,\n ModelMessage,\n StreamChunk,\n StructuredOutputPart,\n VideoPart,\n} from '@tanstack/ai'\nimport type { ConnectionAdapter } from './connection-adapters'\n\nexport type { StructuredOutputPart } from '@tanstack/ai'\n\n/**\n * Tool call states - track the lifecycle of a tool call\n */\nexport type ToolCallState =\n | 'awaiting-input' // Received start but no arguments yet\n | 'input-streaming' // Partial arguments received\n | 'input-complete' // All arguments received\n | 'approval-requested' // Waiting for user approval\n | 'approval-responded' // User has approved/denied\n | 'complete' // Result is complete\n\n/**\n * Tool result states - track the lifecycle of a tool result\n */\nexport type ToolResultState =\n | 'streaming' // Placeholder for future streamed output\n | 'complete' // Result is complete\n | 'error' // Error occurred\n\n/**\n * ChatClient state - track the lifecycle of a chat\n */\nexport type ChatClientState = 'ready' | 'submitted' | 'streaming' | 'error'\n\n/**\n * Connection lifecycle state for the subscription loop.\n */\nexport type ConnectionStatus =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'error'\n\n/**\n * Multimodal content input for sending messages with rich media.\n * Allows sending text, images, audio, video, and documents to the LLM.\n *\n * @example\n * ```ts\n * // Send an image with a question\n * client.sendMessage({\n * content: [\n * { type: 'text', content: 'What is in this image?' },\n * { type: 'image', source: { type: 'url', value: 'https://example.com/photo.jpg' } }\n * ],\n * id: 'custom-message-id' // optional\n * })\n * ```\n */\nexport interface MultimodalContent {\n /**\n * The content of the message.\n * Can be a simple string or an array of content parts for multimodal messages.\n */\n content: string | Array<ContentPart>\n /**\n * Optional custom ID for the message.\n * If not provided, a unique ID will be generated.\n */\n id?: string\n}\n\n/**\n * Message parts - building blocks of UIMessage\n */\nexport interface TextPart {\n type: 'text'\n content: string\n}\n\n/**\n * Helper type that creates a tool-call part for a specific tool.\n * This is a conditional type to enable proper distribution over union types,\n * creating a discriminated union where `name` is the discriminant.\n */\ntype ToolCallPartForTool<T> = T extends AnyClientTool\n ? {\n type: 'tool-call'\n id: string\n name: T['name']\n arguments: string // JSON string (may be incomplete)\n /** Parsed tool input (typed from inputSchema) */\n input?: InferToolInput<T>\n state: ToolCallState\n /** Approval metadata if tool requires user approval */\n approval?: {\n id: string // Unique approval ID\n needsApproval: boolean // Always true if present\n approved?: boolean // User's decision (undefined until responded)\n }\n /** Tool execution output (for client tools or after approval) */\n output?: InferToolOutput<T>\n }\n : never\n\n/**\n * Fallback tool-call part type when tools are not typed\n */\ntype UntypedToolCallPart = {\n type: 'tool-call'\n id: string\n name: string\n arguments: string\n input?: any\n state: ToolCallState\n approval?: {\n id: string\n needsApproval: boolean\n approved?: boolean\n }\n output?: any\n}\n\n/**\n * Tool call part that creates a proper discriminated union.\n * When TTools is typed, checking `part.name === 'toolName'` will narrow\n * `part.output` to the correct type for that tool.\n *\n * The discriminant is `name`, so code like:\n * ```ts\n * if (part.name === 'recommendGuitar') {\n * // part.output is now typed to the recommendGuitar tool's output\n * }\n * ```\n */\nexport type ToolCallPart<TTools extends ReadonlyArray<AnyClientTool> = any> =\n // Check if we have a concrete tools array (not 'any' or 'never')\n [TTools] extends [never]\n ? UntypedToolCallPart\n : unknown extends TTools\n ? UntypedToolCallPart\n : TTools extends ReadonlyArray<infer Tool>\n ? Tool extends AnyClientTool\n ? ToolCallPartForTool<Tool>\n : UntypedToolCallPart\n : UntypedToolCallPart\n\nexport interface ToolResultPart {\n type: 'tool-result'\n toolCallId: string\n content: string\n state: ToolResultState\n error?: string // Error message if state is \"error\"\n}\n\nexport interface ThinkingPart {\n type: 'thinking'\n content: string\n}\n\nexport type MessagePart<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TData = unknown,\n> =\n | TextPart\n | ImagePart\n | AudioPart\n | VideoPart\n | DocumentPart\n | ToolCallPart<TTools>\n | ToolResultPart\n | ThinkingPart\n | StructuredOutputPart<TData>\n\n/**\n * UIMessage - Domain-specific message format optimized for building chat UIs\n * Contains parts that can be text, tool calls, or tool results.\n *\n * `TTools` narrows the tool-call/result part types based on the registered\n * tools. `TData` is the schema-inferred type for any `structured-output` part\n * on the message — defaulted to `unknown` so untyped consumers (the core\n * stream processor, the wire converter) don't need to thread a schema generic\n * everywhere; the hook layer (`useChat({ outputSchema })`) substitutes it on\n * the public return so `m.parts.find(p => p.type === 'structured-output').data`\n * is typed without manual casts.\n */\nexport interface UIMessage<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n TData = unknown,\n> {\n id: string\n role: 'system' | 'user' | 'assistant'\n parts: Array<MessagePart<TTools, TData>>\n createdAt?: Date\n}\n\nexport interface ChatClientOptions<\n TTools extends ReadonlyArray<AnyClientTool> = any,\n> {\n /**\n * Connection adapter for streaming.\n * Supports mutually exclusive modes: request-response via `connect()`, or\n * subscribe/send mode via `subscribe()` + `send()`.\n */\n connection: ConnectionAdapter\n\n /**\n * Initial messages to populate the chat\n */\n initialMessages?: Array<UIMessage<TTools>>\n\n /**\n * Unique identifier for this chat instance\n * Used for managing multiple chats\n */\n id?: string\n\n /**\n * Thread ID to use for this chat session. Persists across sends within\n * the session. If omitted, a unique thread ID is generated.\n */\n threadId?: string\n\n /**\n * Arbitrary client-controlled JSON forwarded to the server in the\n * AG-UI `RunAgentInput.forwardedProps` field. Use this for per-session\n * options like provider/model selection or feature flags that the\n * server endpoint should read.\n *\n * Replaces the legacy `body` option. If both are provided,\n * `forwardedProps` wins on key collision.\n */\n forwardedProps?: Record<string, any>\n\n /**\n * @deprecated Use `forwardedProps` instead. `body` continues to work\n * unchanged — its values are merged into the AG-UI\n * `RunAgentInput.forwardedProps` field on the wire and are also\n * mirrored under the legacy `data` field for servers that have not\n * migrated yet. Will be removed in a future major release.\n */\n body?: Record<string, any>\n\n /**\n * Callback when a response is received\n */\n onResponse?: (response?: Response) => void | Promise<void>\n\n /**\n * Callback when a stream chunk is received\n */\n onChunk?: (chunk: StreamChunk) => void\n\n /**\n * Callback when the response is finished\n */\n onFinish?: (message: UIMessage<TTools>) => void\n\n /**\n * Callback when an error occurs\n */\n onError?: (error: Error) => void\n\n /**\n * Callback when messages change\n */\n onMessagesChange?: (messages: Array<UIMessage<TTools>>) => void\n\n /**\n * Callback when loading state changes\n */\n onLoadingChange?: (isLoading: boolean) => void\n\n /**\n * Callback when error state changes\n */\n onErrorChange?: (error: Error | undefined) => void\n\n /**\n * Callback when chat status changes\n */\n onStatusChange?: (status: ChatClientState) => void\n\n /**\n * Callback when subscription lifecycle changes.\n * This is independent from request lifecycle (`isLoading`, `status`).\n */\n onSubscriptionChange?: (isSubscribed: boolean) => void\n\n /**\n * Callback when connection lifecycle changes.\n */\n onConnectionStatusChange?: (status: ConnectionStatus) => void\n\n /**\n * Callback when session generation activity changes.\n * Derived from stream run events (RUN_STARTED / RUN_FINISHED / RUN_ERROR).\n * Unlike `onLoadingChange` (request-local), this reflects shared generation\n * activity visible to all subscribers (e.g. across tabs/devices).\n */\n onSessionGeneratingChange?: (isGenerating: boolean) => void\n\n /**\n * Callback when a custom event is received from a server-side tool.\n * Custom events are emitted by tools using `context.emitCustomEvent()` during execution.\n *\n * @param eventType - The name of the custom event\n * @param data - The event payload data\n * @param context - Additional context including the toolCallId that emitted the event\n */\n onCustomEvent?: (\n eventType: string,\n data: unknown,\n context: { toolCallId?: string },\n ) => void\n\n /**\n * Client-side tools with execution logic\n * When provided, tools with execute functions will be called automatically\n */\n tools?: TTools\n\n /**\n * Stream processing options (optional)\n * Configure chunking strategy\n */\n streamProcessor?: {\n /**\n * Strategy for when to emit text updates\n * Defaults to ImmediateStrategy (every chunk)\n */\n chunkStrategy?: ChunkStrategy\n }\n}\n\nexport interface ChatRequestBody {\n messages: Array<ModelMessage>\n data?: Record<string, any>\n}\n\n/**\n * Create a typed array of client tools with proper type inference.\n * This eliminates the need for `as const` when defining tool arrays.\n *\n * @example\n * ```ts\n * const tools = clientTools(\n * myTool1.client(() => result1),\n * myTool2.client(() => result2),\n * )\n *\n * // tools is now properly typed as a tuple with literal tool names\n * // This enables type narrowing when checking part.name === 'toolName'\n * ```\n */\nexport function clientTools<const T extends Array<AnyClientTool>>(\n ...tools: T\n): T {\n return tools\n}\n\n/**\n * Helper to create typed chat client options\n * Use this to get proper type inference for messages\n *\n * @example\n * ```ts\n * const tools = clientTools(myTool1, myTool2)\n *\n * const chatOptions = createChatClientOptions({\n * connection: fetchServerSentEvents('/api/chat'),\n * tools,\n * })\n *\n * type MyMessages = InferChatMessages<typeof chatOptions>\n * ```\n */\nexport function createChatClientOptions<\n const TTools extends ReadonlyArray<AnyClientTool>,\n>(options: ChatClientOptions<TTools>): ChatClientOptions<TTools> {\n return options\n}\n\n/**\n * Extract the message type from chat options\n *\n * @example\n * ```ts\n * const chatOptions = createChatClientOptions({\n * connection: fetchServerSentEvents('/api/chat'),\n * tools: [myTool1, myTool2],\n * })\n *\n * type MyMessages = InferChatMessages<typeof chatOptions>\n * // MyMessages is now Array<UIMessage<[typeof myTool1, typeof myTool2]>>\n * ```\n */\nexport type InferChatMessages<T> =\n T extends ChatClientOptions<infer TTools> ? Array<UIMessage<TTools>> : never\n"],"names":[],"mappings":"AA2WO,SAAS,eACX,OACA;AACH,SAAO;AACT;AAkBO,SAAS,wBAEd,SAA+D;AAC/D,SAAO;AACT;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-client",
|
|
3
|
-
"version": "0.11.
|
|
4
|
-
"description": "Framework-agnostic headless client for TanStack AI",
|
|
3
|
+
"version": "0.11.7",
|
|
4
|
+
"description": "Framework-agnostic headless client for TanStack AI chat, realtime sessions, streaming transports, and media generations.",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -11,11 +11,17 @@
|
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"ai",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
14
|
+
"ai-sdk",
|
|
15
|
+
"typescript",
|
|
16
16
|
"tanstack",
|
|
17
|
+
"headless",
|
|
18
|
+
"client",
|
|
17
19
|
"chat",
|
|
18
|
-
"streaming"
|
|
20
|
+
"streaming",
|
|
21
|
+
"realtime",
|
|
22
|
+
"generative-ai",
|
|
23
|
+
"tool-calling",
|
|
24
|
+
"structured-outputs"
|
|
19
25
|
],
|
|
20
26
|
"type": "module",
|
|
21
27
|
"module": "./dist/esm/index.js",
|
|
@@ -31,8 +37,8 @@
|
|
|
31
37
|
"src"
|
|
32
38
|
],
|
|
33
39
|
"dependencies": {
|
|
34
|
-
"@tanstack/ai": "0.21.
|
|
35
|
-
"@tanstack/ai-event-client": "0.3.
|
|
40
|
+
"@tanstack/ai": "0.21.3",
|
|
41
|
+
"@tanstack/ai-event-client": "0.3.10"
|
|
36
42
|
},
|
|
37
43
|
"devDependencies": {
|
|
38
44
|
"@standard-schema/spec": "^1.1.0",
|
package/src/types.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type ToolCallState =
|
|
|
25
25
|
| 'input-complete' // All arguments received
|
|
26
26
|
| 'approval-requested' // Waiting for user approval
|
|
27
27
|
| 'approval-responded' // User has approved/denied
|
|
28
|
+
| 'complete' // Result is complete
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Tool result states - track the lifecycle of a tool result
|