TanStack AI — открытый фреймворк для добавления чата, генерации медиа, инструментов и агентов в веб-приложения без привязки к одному провайдеру или UI-библиотеке.
В октябре 2026 фреймворк вышел в версии 1.0. Ядро получило стабильный API, а экспериментальный Agent Harness вынес долгоживущих агентов в отдельный пакет. Разбираем, из чего состоит TanStack AI, когда он нужен и чем отличается от одного вызова chat().
Что это
TanStack AI — часть экосистемы TanStack (TanStack Query, Table, Router). Если предыдущие библиотеки закрывали работу с данными и интерфейсом, то TanStack AI закрывает работу с языковыми моделями внутри приложения.
Фреймворк начинался в декабре 2025 с одной функции chat() и четырёх провайдеров. К 1.0 это набор модулей для стриминга ответов, вызова инструментов, работы с медиа, подключения MCP-серверов, хранения истории и запуска агентов в песочницах. Команда проекта небольшая — три мейнтейнера, но к релизу вклад внесли более 140 человек.
Ключевой принцип — «ваш провайдер, ваш фреймворк, ваша песочница». Адаптер для OpenAI, Anthropic или локальной модели взаимозаменяем. Клиентская часть работает с React, Vue, Svelte, Solid, Preact, Angular и другими фреймворками. Протокол между клиентом и сервером — открытый AG-UI.
Важно отличать два слоя релиза. Стабильное ядро 1.0 — это чат, инструменты, медиа, MCP, хранение и песочницы. Экспериментальный Agent Harness — отдельный пакет @tanstack/ai-harness версии 0.x для долгоживущих сессий, который сознательно оставили нестабильным, чтобы собрать обратную связь до фиксации API.
Зачем нужно
- Добавить ИИ-фичу в существующее приложение без переписывания стека — чат поддержки, генерация изображений в редакторе, голосовой ввод. Один адаптер меняется на другой без правок бизнес-логики.
- Собрать продукт поверх ИИ — от простого стримингового чата до медиа-студии. Компоненты для стриминга, инструментов, файлов и кэширования поставляются вместе и типизированы.
- Запустить кодинг-агента или помощника, который работает дольше одного запроса. Субагенты, Agent Harness с durable-сессиями и фоновыми задачами закрывают сценарии, где chat() уже недостаточен.
- Подключить внешние инструменты единообразно. Свои функции можно отдать как MCP-сервер для Claude Desktop или Cursor, а внешние MCP-инструменты — вызвать из чата через тот же интерфейс.
Как устроено
| Слой | Что делает | Ключевые возможности |
|---|---|---|
Чат и генерация | Клиент-серверный стриминг текста, изображений, аудио и видео | useChat и ChatClient, generateImage/generateSpeech, threadId на каждый диалог, стриминговый вывод и прерывания |
Инструменты и агенты | Модель вызывает код приложения и делегирует задачи | Типизированные tools, tool-approval через interrupts, субагенты в чате, decide() для выбора и оценки |
MCP и интеграции | Обмен инструментами с внешним миром | createMCPServer, фильтры и аппрувы, task-инструменты, WebMCP в обе стороны — браузер зовёт tools клиента и наоборот |
Модели и файлы | Единый доступ к провайдерам и их файловым API | 23 адаптера + openaiCompatible, единый reasoning-параметр, авткэширование промптов, Files API поверх всех провайдеров, retry и смена модели на лету |
Ключи и доступ | Кто и как платит за вызовы | BYOK через defineByok и keyed-адаптеры, вход через ChatGPT, GitHub Copilot, OpenRouter или Claude OAuth |
Песочницы и harness | Изоляция и долгоживущие сессии | 11 провайдеров песочниц, in-memory и durable persistence, сессии с логом, фоновые воркеры, плагины |
Разработка и тесты | Отладка и проверка без сети | DevTools для React/Svelte, fakeText() для тестов без ключа, типизированные headless-фабрики UI, Agent Skills для код-ассистентов |
Связь клиента и сервера идёт по AG-UI — открытому протоколу для стриминга событий агента. Благодаря этому тот же хук useChat работает и против простого chat(), и против harness-сессии. События TEXT_MESSAGE_CONTENT, RUN_FINISHED и прерывания одинаково доходят до интерфейса, независимо от провайдера модели.
Хранение вынесено в persistence-плагины. Стартовый вариант — memoryPersistence для разработки. Для продакшена подключается durable-хранилище, и тогда сессия переживает рестарт или деплой: лог треда восстанавливается, а ожидания аппрувов и долгих инструментов продолжают ждать ответа.
Типичная ошибка — путать MCP-сервер фреймворка с обычным tool-вызовом. Tool живёт внутри одного чата и отвечает синхронно. MCP-сервер, созданный через createMCPServer, публикует те же tools наружу и делает их доступными для Claude Desktop, Cursor и других MCP-хостов. Наоборот, внешний MCP-клиент позволяет чату пользоваться инструментами страницы через WebMCP.
Когда использовать
| Ситуация | Подходит / не подходит | Почему |
|---|---|---|
Нужен чат или генерация медиа в React/Vue/Svelte-приложении | Подходит | Готовые хуки, адаптеры и AG-UI-стриминг. Смена провайдера — замена одного пакета. |
Нужны инструменты, файлы и кэш на любом провайдере | Подходит | Единый reasoning-параметр, Files API и автокэширование работают одинаково на всех адаптерах. |
Нужен агент, который живёт дольше одного запроса | Подходит, через harness | Durable-сессии, steer/follow-up сообщения, фоновые задачи и субагенты — именно для этого сделан @tanstack/ai-harness. |
Нужен быстрый прототип без бэкенда | Не подходит | Фреймворк требует клиент + сервер с threadId и persistence. Для разового скрипта проще прямой вызов API провайдера. |
Проект уже на Vercel AI SDK | Оценить миграцию | TanStack AI даёт больше для агентских сценариев и песочниц, но переезд требует смены threadId/conversationId и модели аппрувов — смотри гайд по апгрейду с 0.x. |
Пример
Минимальный чат на React с OpenAI — установка и стриминг:
pnpm add @tanstack/ai @tanstack/ai-react @tanstack/ai-openai
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { useChat } from '@tanstack/ai-react'
// Сервер
const stream = chat({
adapter: openaiText('gpt-6.1-sol'),
messages: params.messages,
threadId: params.threadId,
})
// Клиент — threadId обязателен, его даёт ваш роут или база
function Chat({ chatId }: { chatId: string }) {
const { messages, send, interrupts } = useChat({
connection: '/api/chat',
threadId: chatId,
})
// interrupts содержит tool-approval и другие ожидания
// approval.resolveInterrupt(true) — подтвердить вызов инструмента
}
Долгоживущий помощник через harness — одна декларация работает в терминале, по HTTP, как ACP-агент и как MCP-сервер:
import { defineHarness, createHarnessHost } from '@tanstack/ai-harness'
import { openaiText } from '@tanstack/ai-openai'
import { memoryPersistence } from '@tanstack/ai-persistence'
const assistant = defineHarness({
name: 'acme/assistant',
adapter: openaiText('gpt-6.1-sol'),
systemPrompts: ['You are a helpful travel agent.'],
})
const host = createHarnessHost({ persistence: memoryPersistence() })
const session = await host.open(assistant, { threadId: 'trip-1' })
const plan = session.send('Plan a three-day trip to Lisbon.')
plan.onEvent('TEXT_MESSAGE_CONTENT', ({ event }) => process.stdout.write(event.delta))
// Сообщение во время работы — steer вклинивается до следующего вызова модели
await session.send('Keep it under 500 euros.', { mode: 'steer' })
await plan
// Запуск: терминал / CI / HTTP / ACP / MCP
// npx tsx coder.ts
// npx tsx coder.ts -p "Fix the failing test"
// npx tsx coder.ts --serve
// npx tsx coder.ts --acp
// npx tsx coder.ts --mcp
TanStack AI закрывает путь от простого чата до автономного агента без смены фреймворка: начинаете с chat() и хуков, а когда одного запроса становится мало — переносите ту же конфигурацию в harness и получаете durable-сессии, субагентов и фоновую работу поверх того же AG-UI.
Ссылки
- Документация: TanStack AI — Quick Start
- Сайт: TanStack AI 1.0 — Still Your AI, Still Your Way
- GitHub: TanStack/ai


