本页还没有译文
本页 52 段还没译成한국어,下面显示的是英文原文。Transport
还没翻译译自英文(ai-sdk.dev)本页 52 段都还没译
The useChat transport system provides fine-grained control over how messages are sent to your API endpoints and how responses are processed. This is particularly useful for alternative communication protocols like WebSockets, custom authentication patterns, or specialized backend integrations.
Default Transport
By default, useChat uses HTTP POST requests to send messages to /api/chat:
import { useChat } from '@ai-sdk/react';
// Uses default HTTP transport
const { messages, sendMessage } = useChat();This is equivalent to:
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
}),
});Custom Transport Configuration
Configure the default transport with custom options:
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/custom-chat',
headers: {
Authorization: 'Bearer your-token',
'X-API-Version': '2024-01',
},
credentials: 'include',
}),
});Dynamic Configuration
You can also provide functions that return configuration values. This is useful for authentication tokens that need to be refreshed, or for configuration that depends on runtime conditions:
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
headers: () => ({
Authorization: `Bearer ${getAuthToken()}`,
'X-User-ID': getCurrentUserId(),
}),
body: () => ({
sessionId: getCurrentSessionId(),
preferences: getUserPreferences(),
}),
credentials: () => 'include',
}),
});Request Transformation
Transform requests before sending to your API:
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
prepareSendMessagesRequest: ({ id, messages, trigger, messageId }) => {
return {
headers: {
'X-Session-ID': id,
},
body: {
messages: messages.slice(-10), // Only send last 10 messages
trigger,
messageId,
},
};
},
}),
});WebSocket Transport
Use WebSocketChatTransport when you want chat turns to share a persistent
WebSocket connection instead of opening an HTTP request for every turn. This is
useful for chats with frequent client-side tool results or other multi-step
interactions.
import { useChat } from '@ai-sdk/react';
import { WebSocketChatTransport } from 'ai';
import { useMemo } from 'react';
export default function Chat() {
const transport = useMemo(
() =>
new WebSocketChatTransport({
url: '/api/chat',
params: () => ({ token: getShortLivedToken() }),
}),
[],
);
const { messages, sendMessage } = useChat({ transport });
// ... render the chat
}The transport multiplexes requests by requestId, validates incoming
UIMessageChunk values, forwards aborts to the server, and reuses the open
socket for later turns. HTTP and HTTPS URLs are automatically converted to WS
and WSS URLs.
The code that creates a transport owns its lifecycle. React and Vue chat hooks
do not close caller-supplied transports when options change or components are
disposed, because the same transport can be shared by multiple chats. Call
transport.close() after its last consumer is gone. If a directly managed
Chat instance exclusively owns the transport, call chat.dispose(); for a
shared transport, stop individual chats and close the transport only after all
consumers are finished.
Your WebSocket server must implement the
WebSocketChatTransport protocol.
The exported WebSocketChatTransportRequest and
WebSocketChatTransportResponse types can be used to type server frames. Use
safeValidateWebSocketChatTransportRequest before handling an untrusted client
frame.
Note
Browser WebSocket APIs cannot set arbitrary handshake headers. The headers
option is included inside each application-level request frame. Authenticate
the handshake with secure cookies, a short-lived query parameter, or a
subprotocol, and validate the connection origin and every frame on the server.
sendAutomaticallyWhen still starts a new chat turn after the preceding UI
message stream finishes. WebSocketChatTransport avoids opening another HTTP
connection for that turn, but it does not send tool results into an active
model generation.
If the socket closes during a response, the active stream errors. A later send
opens a new connection. The transport does not automatically replay requests,
because replaying a generation can duplicate model output or tool effects.
reconnectToStream requests a complete replay of the retained response from
sequence zero. Chat rebuilds the message with a fresh parser, so the replay must
include all earlier chunks and the original start chunk's messageId. That
stable message ID lets Chat replace the partial assistant message. Duplicate
sequence numbers are ignored within each response stream.
For complete options, protocol details, cancellation behavior, and a server
example, see the
WebSocketChatTransport reference.
Direct Agent Transport
For scenarios where you want to communicate directly with an Agent without going through HTTP, you can use DirectChatTransport. This transport invokes the agent's stream() method directly in-process.
This is useful for:
- Server-side rendering: Run the agent on the server without an API endpoint
- Testing: Test chat functionality without network requests
- Single-process applications: Desktop or CLI apps where client and agent run together
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent } from 'ai';
const agent = new ToolLoopAgent({
model: 'anthropic/claude-sonnet-5.5',
instructions: 'You are a helpful assistant.',
tools: {
weather: weatherTool,
},
});
const { messages, sendMessage } = useChat({
transport: new DirectChatTransport({ agent }),
});How It Works
Unlike DefaultChatTransport which sends HTTP requests:
DirectChatTransportvalidates incoming UI messages- Converts them to model messages using
convertToModelMessages - Calls the agent's
stream()method directly - Returns the result as a UI message stream via
toUIMessageStream()
Configuration Options
You can pass additional options to customize the stream output:
const transport = new DirectChatTransport({
agent,
// Pass options to the agent
options: { customOption: 'value' },
// Configure what's sent to the client
sendReasoning: true,
sendSources: true,
});Note
DirectChatTransport does not support stream reconnection since there is no
persistent server-side stream. The reconnectToStream() method always returns
null.
For complete API details, see the DirectChatTransport reference.
Workflow Transport
For chat apps built on the Workflow SDK, WorkflowChatTransport from @ai-sdk/workflow provides automatic stream reconnection. It handles the common scenario where a workflow function times out mid-stream — the transport detects the missing finish event and reconnects to resume from where it left off.
import { useChat } from '@ai-sdk/react';
import { WorkflowChatTransport } from '@ai-sdk/workflow/client';
import { useMemo } from 'react';
export default function Chat() {
const transport = useMemo(
() =>
new WorkflowChatTransport({
api: '/api/chat',
maxConsecutiveErrors: 5,
onChatEnd: ({ chatId, chunkIndex }) => {
console.log(`Chat complete: ${chunkIndex} chunks`);
},
}),
[],
);
const { messages, sendMessage } = useChat({ transport });
// ... render chat UI
}Key features:
- Automatic reconnection: Detects interrupted streams (no
finishevent) and reconnects via GET to{api}/{runId}/stream - Page refresh recovery:
initialStartIndexcontrols where the initial reconnection begins - Configurable retries:
maxConsecutiveErrorscontrols how many consecutive reconnection failures to tolerate - Lifecycle callbacks:
onChatSendMessageandonChatEndfor tracking chat state
Negative initialStartIndex values can fetch only the tail when the durable
server stream already stores UIMessageChunk objects. For raw WorkflowAgent
streams, use a non-negative cursor and follow the server-side conversion in the
WorkflowAgent guide.
For the full API reference, see WorkflowChatTransport. For server-side endpoint setup, see the WorkflowAgent guide.
Chat SDK Web Adapter
The Chat SDK Web adapter (@chat-adapter/web) serves a useChat endpoint from a Chat SDK bot. It speaks the UI message stream protocol, so the default transport works without changes. Use it when the same bot also runs on Slack, Microsoft Teams, Discord, or other chat platforms, and you want one set of handlers for all of them.
pnpm add ai @ai-sdk/react chat @chat-adapter/web @chat-adapter/state-redisnpm install ai @ai-sdk/react chat @chat-adapter/web @chat-adapter/state-redisyarn add ai @ai-sdk/react chat @chat-adapter/web @chat-adapter/state-redisbun add ai @ai-sdk/react chat @chat-adapter/web @chat-adapter/state-redisOn the server, register the Web adapter and handle messages with onDirectMessage. Each browser conversation is a direct message thread:
import { Chat } from 'chat';
import { toAiMessages } from 'chat/ai';
import { createWebAdapter } from '@chat-adapter/web';
import { createRedisState } from '@chat-adapter/state-redis';
import { ToolLoopAgent } from 'ai';
import { getSession } from './session'; // your app's auth
const agent = new ToolLoopAgent({
model: 'anthropic/claude-sonnet-5.5',
instructions: 'You are a helpful assistant.',
});
export const bot = new Chat({
userName: 'mybot',
adapters: {
web: createWebAdapter({
userName: 'mybot',
// Identify the caller from your app's session. Returning null responds with 401.
getUser: async () => {
const session = await getSession();
return session ? { id: session.userId } : null;
},
}),
},
state: createRedisState(),
});
bot.onDirectMessage(async thread => {
const { messages } = await bot.history.thread.list(thread.id, {
limit: 20,
});
const result = await agent.stream({
messages: await toAiMessages(messages),
abortSignal: thread.signal,
});
await thread.post(result.fullStream);
});import { after } from 'next/server';
import { bot } from '@/lib/bot';
export async function POST(request: Request): Promise<Response> {
return bot.webhooks.web(request, {
waitUntil: task => after(() => task),
});
}On the client, point the default transport at the route:
'use client';
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
export default function Chat() {
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({ api: '/api/chat' }),
});
// ... render chat UI
}Things to know:
- Authentication: browser requests have no platform signature, so
getUseris the security boundary. Resolve the user from your app's session and returnnullto reject the request. - Conversation history: the adapter ignores the message history in the request body. It stores each conversation's messages in the state adapter, and
bot.history.thread.list()reads them back. The chatidfromuseChatidentifies the conversation. - Stopping: the adapter honors the request's abort signal, so calling
stop()inuseChatstops the handler's stream.
For all options, including the ag-ui protocol and useChat wrappers for React, Vue, and Svelte, see the Web adapter docs.
Building Custom Transports
To understand how to build your own transport, refer to the source code of the default implementation:
- DefaultChatTransport - The complete default HTTP transport implementation
- HttpChatTransport - Base HTTP transport with request handling
- ChatTransport Interface - The transport interface you need to implement
These implementations show you exactly how to:
- Handle the
sendMessagesmethod - Process UI message streams
- Transform requests and responses
- Handle errors and connection management
The transport system gives you complete control over how your chat application communicates, enabling integration with any backend protocol or service.