# OpenAI
The OpenAI codec carries the [OpenAI Responses API](https://ably.com/docs/ai-transport/frameworks/openai.md)'s stream events over an Ably channel, plus an `input` event for the input items a client sends. The agent pipes the Responses stream from the `openai` package directly into the adaptor, which encodes the stream into Ably messages, and clients decode the messages back into the same stream of LLM events.
Import `openaiAdaptor` and `openaiDecoder` from `@ably/ai-transport/openai`. The agent publishes with an [agent adaptor](https://ably.com/docs/ai-transport/api/javascript/agent-adaptor.md), and the client reads with a [decoder](https://ably.com/docs/ai-transport/api/javascript/decoder.md). The codec works with the `openai` package at version 6.
#### Javascript
```
import { openaiAdaptor, openaiDecoder } from '@ably/ai-transport/openai';
// Agent code. channel is a channel from your Ably Pub/Sub client.
const adaptor = openaiAdaptor(channel);
// Client code.
const decoder = openaiDecoder();
await channel.subscribe(decoder.receive);
```
The codec writes each event type in one of three ways:
- Streams: the first `*.delta` event of a stream creates a single message, and later deltas append to that same message, accumulating all the deltas into a single Ably message.
- `response.created`, `response.in_progress` and `response.queued` are not published, because they do not carry any output.
- Every other event is a plain publish with the whole event as the message's `data` field. The `input` event is a plain publish with its items as the message's `data` field.
The Responses API duplicates content in the `*.done` events: these events carry the full streamed data a second time. The codec drops the duplicated fields from the done events, preferring the streamed deltas that were already sent over the channel.
## Create an OpenAI adaptor
`openaiAdaptor(channel: ChannelWriter, options?: AgentAdaptorOptions): AgentAdaptor`
Create an [agent adaptor](https://ably.com/docs/ai-transport/api/javascript/agent-adaptor.md) that publishes OpenAI events on `channel`.
### Javascript
```
import { openaiAdaptor } from '@ably/ai-transport/openai';
const adaptor = openaiAdaptor(channel);
```
### Parameters
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| channel | required | The channel to publish on. A `RealtimeChannel` satisfies it. See [`createAgentAdaptor`](https://ably.com/docs/ai-transport/api/javascript/agent-adaptor.md#create-agent-adaptor-params). | `ChannelWriter` |
| options | optional | Default headers and a logger. See [`createAgentAdaptor`](https://ably.com/docs/ai-transport/api/javascript/agent-adaptor.md#create-agent-adaptor-params). | `AgentAdaptorOptions` |
### Returns
`AgentAdaptor`. The adaptor, for events of the following type:
| Event | Description | Type |
| --- | --- | --- |
| `ResponseStreamEvent` | Every stream event the Responses API produces, as the `openai` package declares it. | `ResponseStreamEvent` |
| `input` | The input items a client sends: a user message to start a turn, or a `function_call_output` that answers a function call. | |
## Create an OpenAI decoder
`openaiDecoder(options?: DecoderOptions): Decoder`
Create a [decoder](https://ably.com/docs/ai-transport/api/javascript/decoder.md) that decodes what an OpenAI adaptor publishes.
### Javascript
```
import { openaiDecoder } from '@ably/ai-transport/openai';
const decoder = openaiDecoder();
await channel.subscribe(decoder.receive);
```
### Parameters
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| options | optional | A logger. See [`createDecoder`](https://ably.com/docs/ai-transport/api/javascript/decoder.md#create-decoder-params). | `DecoderOptions` |
### Returns
`Decoder`. The decoder, for the [events](#openai-adaptor-returns) the adaptor publishes.
## Example
The client POSTs the user's message to the agent, which publishes it as an `input` event. The agent pipes the Responses stream, and the client appends each output text delta to the response in its UI.
### Javascript
```
// Client code.
decoder.onEvent(({ event }) => {
if (event?.type === 'response.output_text.delta') appendText(event.item_id, event.delta);
});
await channel.subscribe(decoder.receive);
const items = [{ role: 'user', content: 'What is the weather?' }];
await fetch('/api/chat', { method: 'POST', body: JSON.stringify({ channelName: 'conversations:42', items }) });
```
### Javascript
```
// Agent code.
import OpenAI from 'openai';
await adaptor.send({ type: 'input', items });
const client = new OpenAI();
const stream = await client.responses.create({ model: 'gpt-4o-mini', input: items, stream: true });
await adaptor.pipe(stream, { signal: req.signal });
```
## Related Topics
- [Agent adaptor](https://ably.com/docs/ai-transport/api/javascript/agent-adaptor.md): API reference for the AI Transport agent adaptor: createAgentAdaptor, send, pipe, and pipeEach, and the options, results, and errors of each.
- [Decoder](https://ably.com/docs/ai-transport/api/javascript/decoder.md): API reference for the AI Transport decoder: createDecoder, receive, decode, onEvent, and onError, and the Delivery each message becomes.
- [Codec](https://ably.com/docs/ai-transport/api/javascript/codec.md): API reference for the AI Transport Codec: the encode and decode contract an adaptor and a decoder use, EncodedMessage, and how defineCodec builds a codec from a table of event rows.
- [Vercel](https://ably.com/docs/ai-transport/api/javascript/vercel.md): API reference for the AI Transport codec for the Vercel AI SDK: vercelAdaptor, vercelDecoder, and the VercelEvent union of UIMessageChunk events and the user message.
- [AG-UI](https://ably.com/docs/ai-transport/api/javascript/ag-ui.md): API reference for the AI Transport codec for AG-UI: agUiAdaptor, agUiDecoder, and the AGUIEvent union of AG-UI events and the run-input a client sends.
## Documentation Index
To discover additional Ably documentation:
1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages.
2. Identify relevant URLs from that index.
3. Fetch target pages as needed.
Avoid using assumed or outdated documentation paths.