Skip to content

docs(ai-transport): add OpenAI Responses codec pages - #3488

Open
zknill wants to merge 11 commits into
mainfrom
zak/ait-1077-openai-codec-docs
Open

docs(ai-transport): add OpenAI Responses codec pages#3488
zknill wants to merge 11 commits into
mainfrom
zak/ait-1077-openai-codec-docs

Conversation

@zknill

@zknill zknill commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Add documentation for the OpenAI Responses codec (ResponsesCodec from @ably/ai-transport/openai) and reconcile the surrounding pages so none of them frame the Vercel codec as the only bundled codec.

  • Getting started > By SDK > OpenAI (new): a Next.js walkthrough that streams the OpenAI Responses event stream over a durable session using the generic createAgentSession and the core React hooks, with a stop button for cancellation and a second tab for multi-device sync.
  • Frameworks > OpenAI (new): what the Responses API brings, what AI Transport adds, the run.pipe connection point (with a before/after that contrasts the hand-rolled SSE response against run.pipe(stream)), and the server-side tool loop.
  • Nav: add both pages to aitransport.ts. OpenAI sits first under "By SDK" and first under "Frameworks".
  • Codecs concept + Why overview: note that the SDK bundles a Vercel codec and a ResponsesCodec, add an OpenAI "Read next" link, and correct the codecs intro from "an OpenAI completion" to "an OpenAI Responses event".
  • Remove the now-stale getting-started/openai redirect from the Vercel AI SDK page, since that path now resolves to a real page.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4964900e-1caa-4ba3-888c-fb201e3f7856

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch zak/ait-1077-openai-codec-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zknill
zknill marked this pull request as ready for review July 24, 2026 08:27
@zknill
zknill force-pushed the zak/ait-1077-openai-codec-docs branch from 47e677d to 3fcb6c5 Compare July 24, 2026 08:27
@zknill
zknill requested a review from owenpearson July 24, 2026 08:27
zknill added 4 commits July 31, 2026 14:06
Add a getting-started walkthrough and a framework page for the
OpenAI Responses codec (ResponsesCodec) from @ably/ai-transport/openai.

- Getting started: build a Next.js chat app that streams the Responses
  event stream over a durable session using the generic
  createAgentSession and core React hooks, with cancellation and
  multi-device sync.
- Framework page: what the Responses API brings, what AI Transport
  adds, the run.pipe connection point, and the server-side tool loop.
- Add both pages to the AI Transport nav (OpenAI first under By SDK
  and first in Frameworks).
- Remove the getting-started/openai redirect from the Vercel AI SDK
  page now that it resolves to a real page.
The docs implied the Vercel codec was the only bundled codec. Now that the
OpenAI ResponsesCodec ships in the SDK, update the pages that are not
specific to one codec.

- codec architecture: the SDK bundles a Vercel codec and a ResponsesCodec,
  and any other framework's events can be implemented against the same
  Codec interface.
- OpenAI framework and getting-started pages: point the codec Read next
  link at the codec architecture page, which the codecs concept page was
  folded into.
The ResponsesCodec now supports the full client-side tool surface
(client-executed tools, tool failures, and human approvals), so the
docs no longer match the SDK.

- Add a "Run client-side tools and approvals" section to the OpenAI
  framework page covering the createToolResult, createToolResultError,
  and createToolApprovalResponse factories and the tool-approval-request
  output, and remove the stale run-outcome Aside.
- Rewrite "Scope and trade-offs" so only hosted tools remain listed as
  unsupported.
- Add an "OpenAI codec" section to the tool-calling feature page.
…d page

The concepts/invocations page was folded into the runs page, so point at
the invocations section there and lowercase the primitives to match the
rest of the section.
@zknill
zknill force-pushed the zak/ait-1077-openai-codec-docs branch from 3fcb6c5 to 4c765e2 Compare July 31, 2026 13:12
zknill added 5 commits July 31, 2026 15:18
SDK 0.7 splits the run's identity from its behaviour. createRun takes
(invocation, identity?, hooks?) where the old second argument carried both,
and adoptRun takes (invocation, identity, hooks?) with triggerEventId gone,
since the trigger now comes from the Invocation. The old createRun call fails
silently: identity validation only rejects an empty runId or invocationId, so
a stray { signal } is accepted and the abort signal is dropped, leaving every
sample claiming a request cancellation it no longer wires up.

- Move the signal and the hooks into createRun's third argument at all 21
  remaining call sites, and pass {} for identity on the one-request path.
- Give adoptRun the invocation, and drop triggerEventId from the RunIds and
  TurnIds shapes the Temporal and WDK pages thread through their workflows.
  cleanupRun now takes the invocation it needs to adopt, rather than a bare
  channel name.
- Replace the RunRuntime table on the AgentSession page with RunIdentity and
  RunHooks, rename onMessage to onAblyMessage there and on the codec page,
  and document pipe(source: PipeSource) accepting any AsyncIterable, which
  retires the PipeOptions table.
…ptions

A client answering a tool call now sets a new supersedes header to the suspended
run it forked away from, and the tree excludes that run from branch selection,
so a single response renders as one linear reply. SendOptions grew role and
supersedes to carry it.

- Add the supersedes header to the wire-protocol table, and record on the
  conversation-tree internals page that the tree drops superseded runs from
  sibling groups, visible nodes, and reply runs.
- Add role and supersedes to the SendOptions table.
- Note that useView re-renders on run lifecycle events, so a component reading
  a run's status sees a suspend or an end.
- Rename start-serial to step-start-serial, and correct the exported-constant
  table, which listed the step headers among the constants the package root
  exports. It exports 14, and the step headers are internal.
The client-side tool docs described a flow that does not work. Three rules the
SDK enforces were missing, and each one makes the provider reject the resumed
request or leaves the approval prompt stuck.

- The agent must publish tool-approval-request as the tail of the model turn's
  own pipe, so it lands on the same codec-message-id as the function_call it
  gates. On its own message the client's decision never amends it.
- The client must wait for the run to report suspended, must answer every open
  call before waking the agent (unansweredCalls), and must still POST the
  invocation, since publishing an input resumes nothing on its own.
- An approved call has no output yet, so the agent runs it server-side on
  resume via approvedUnexecutedCalls. Document that reader and resolvedCallIds,
  neither of which appeared anywhere in the docs.
- Note that the codec's event inventory is total, so a hosted tool's events
  throw at the encoder unless the agent filters them out.
- In the getting-started route, start the run before returning its id, since a
  continuation re-keys runId from the trigger's headers, and await session.end.
The OpenAI Responses codec, the run identity and hooks split, and the
supersedes header all ship in 0.7, so the language selector and the two pinned
installs should name it.

0.7.0 is not on npm yet, so the pinned install commands only resolve once the
release lands.
…e it

The 0.7 pass rewrote descriptions that were already accurate, which buried the
actual API changes in unrelated churn. Restore the original wording and keep
only what the new signatures forced: the RunRuntime table split, the
onAblyMessage rename, the invocation argument on adoptRun, and PipeSource.

Also drop the three uses of "stamps" the pass introduced, on the onAblyMessage,
role, and supersedes rows. The remaining uses are the existing wording, where
only the header name changed.

Restore the sentence saying a client publishes its input on the same runId and
a continuation resumes the run, which is how the OpenAI codec works: the fork
behaviour belongs to the Vercel chat transport.
@zknill
zknill force-pushed the zak/ait-1077-openai-codec-docs branch from 49bb8ae to eead238 Compare July 31, 2026 14:47
Use "generated" for id creation on the lines this branch touches: the identity
parameter row, the step send description, and the createRun step of the
transport-patterns sequence.

The rest of the section still says "minted" in around 33 places that predate
this branch, so the two words sit side by side until a wider pass.
@VeskeR VeskeR added the review-app Create a Heroku review app label Jul 31, 2026
@ably-ci
ably-ci temporarily deployed to ably-docs-zak-ait-1077--zoxx0g July 31, 2026 15:11 Inactive

@VeskeR VeskeR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, as discussed on the slack I'm happy for the comments below to be fixed in the follow-up PR.

I think the only major missing part is missing API reference page for the new OpenAI export:

Image

Do you think we should add it in this PR or fine next week?

| History and replay | Load the full conversation on reconnect, page refresh, or new device join. |
| Token compaction | Reconnecting clients receive accumulated responses, not a replay of every token. |

These are the same capability bullets used on the [Vercel AI SDK Core](/docs/ai-transport/frameworks/vercel-ai-sdk-core) page; the session surface is the same whichever model layer you integrate against.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't think we should mention vercel here, don't see the relevance

| Multi-device sync | Every device subscribed to the session sees the same conversation in realtime. |
| Bidirectional control | Cancel, steer, and interrupt the agent from any client. No separate control channel. |
| Active run tracking | `view.runs()` exposes which clients have Runs streaming and which Runs are in progress. |
| Conversation branching | Edit and regenerate create forks in the conversation tree, not destructive replacements. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also mention "Approval gates that reach the user anywhere" like on Vercel page


Server-executed tools do not suspend the Run. The agent runs an agentic loop: call the Responses API, and if the model emits function calls, run them, append the model's output items and the tool outputs to the input, and call it again. The loop continues until the model produces a reply with no tool calls. Each unit of work publishes under its own `run.pipe`, so a Run that calls one tool produces three messages: the turn that emitted the calls, the tool outputs, and the final text turn.

For reasoning models, the loop must re-append the whole turn's output items, including the reasoning items that preceded a function call, since reasoning models expect that reasoning to travel with the call on the next request. The [runnable demo](https://github.com/ably/ably-ai-transport-js) implements the full loop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add link to the specific openai demo


## Run client-side tools and approvals <a id="client-tools"/>

The codec also carries the client-driven half of tool calling: a client executes a tool in the browser and publishes the result, reports a tool failure, or answers a human approval prompt. The suspend and resume mechanics belong to the transport, so they work the same way they do for the Vercel codec. The agent calls `run.suspend()` to wait for a client, the client publishes its input on the same `runId`, and a continuation resumes the Run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so they work the same way they do for the Vercel codec

no need to refer to Vercel codec


## Run server-side tools <a id="tools"/>

A Responses stream never carries a function call's *output*. OpenAI surfaces tool output only as model input on the next turn, so the codec adds an event of its own, `function_call_output`, for the agent to publish after it runs a tool. It adds one other event the Responses API has no equivalent for, the [`tool-approval-request`](#client-tools) that gates a tool on a human decision.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool-approval-request is needed for approval gated calls, so maybe worth mention in "Run client-side tools and approvals" section below. Regular server-side tools should just work as is


### Wait for the run to suspend, then wake the agent <a id="resume"/>

The client must get three things right when it answers a call.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: too claude-y sentence IMO


Run `npm run dev` and open `http://localhost:3000`. Open a second tab to the same URL; both tabs share the same durable session.

## What is happening <a id="what-is-happening"/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## What is happening <a id="what-is-happening"/>
## What happens when you send a message <a id="what-is-happening"/>

to match other getting started


- Node.js 22 or later.
- An [Ably account](https://ably.com/sign-up) with an API key.
- An OpenAI API key set as `OPENAI_API_KEY`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- An OpenAI API key set as `OPENAI_API_KEY`.
- An OpenAI API key.


## Install dependencies <a id="install-dependencies"/>

Install the AI Transport SDK, the Ably client, the OpenAI SDK, and Next.js:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should clarify that Next.js is not a required dependency, this is just what the framework this demo is built on

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to clariffy that we now have OpenAI and Vercel AI SDK codecs

…feedback

Addresses the review on #3488. The reference section was the gap VeskeR called
the only major missing part: ResponsesCodec, toResponsesInput and the three
correlation readers appeared only in prose, with no entry under API reference.

- Add api/javascript/openai/codec.mdx for ResponsesCodec, covering its methods,
  the three tool payloads keyed by OpenAI's snake_case call_id, and the exported
  types. The page says three times over that ResponsesCodec is a codec value you
  pass rather than a factory you call, since the Vercel sibling documents a
  factory and ResponsesCodec() is a type error.
- Add api/javascript/openai/conversation-helpers.mdx for toResponsesInput and
  the correlation readers, including a table of what counts as an answered tool
  call, because resuming a run with any unanswered call gets the request
  rejected by the provider.
- Add an OpenAI group to the API reference nav between Core SDK and Vercel, and
  link both pages from the framework and getting-started pages.
- Name both bundled codecs on the core Codec page, which was the last page in
  this PR's set still reading as Vercel-only.
- Move the tool-approval-request event out of the server-side tools intro, where
  it does not apply, and into the client-side tools section.
- Add the "Approval gates" capability row the OpenAI table was missing against
  the Vercel AI SDK Core table, deep-link the demo directory rather than the
  repo root, and drop two comparisons to the Vercel codec.
- Getting started: match the sibling pages' "What happens when you send a
  message" heading while keeping the existing anchor, drop the env var from the
  prerequisite, and say Next.js is a choice this guide makes rather than a
  dependency of AI Transport.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-app Create a Heroku review app

Development

Successfully merging this pull request may close these issues.

3 participants