Assistants API → Responses API migration pack
View on GitHubA free, public working pack for teams that built on the OpenAI Assistants API and need to move to the Responses API before the Assistants API shuts down. Made by apinae.
Hard sunset: August 26, 2026. A correct migration starts with facts from OpenAI's own docs (read 2026-08-11).
Unofficial. apinae is not affiliated with OpenAI, and OpenAI has not endorsed, reviewed, or participated in this pack. OpenAI ships an official pack for the Chat Completions → Responses migration — openai/completions-responses-migration-pack. They did not ship one for Assistants → Responses, the migration with the deadline. This is that. The harness here is adapted from theirs under MIT; see NOTICE.
scripts/migrate.sh edits your code. It drives a coding agent over your
repository using the change spec below, and — unlike the upstream pack, which
appends || true to every test command — it runs your test suite before and
after and fails if a green suite turns red. It plans by default and writes
only when you pass --write.
change-spec.json— a machine-readable spec mapping every Assistants concept (assistant, thread, run, run step, message, tool, vector store, streaming, polling) to its Responses equivalent, each classified into mechanical / judgment / no equivalent, each citing the OpenAI doc it was read from and the read date.test/conformance.test.js— a gate for the mechanical items. Fails against wrongly-migrated code, passes against correctly-migrated code. (The gate's teeth are asserted directly: it trips on the pre-migration Assistants app.)- A worked example — the same toy support-triage bot twice: once on the
Assistants API (
src/assistants/), once migrated to the Responses API (src/responses/). A single implementation-agnostic behaviour suite (test/app.test.js, 14 tests) runs against both, so a correct migration is exactly one that leaves the suite green. All tests run against a local mock (test/mock-server.js) — no API key, no network.
Headline finding (read this first)
At concept granularity the migration is about 50% mechanical — 10 of 20 concepts are a deterministic rewrite; 8 need a human decision; 2 have no equivalent at all.
That 10/20 is not the same as "half the work is mechanical", because the
judgment items cluster where the work is hardest — state management. What
Assistants did for you server-side (threads, truncation, the function loop,
re-prompting) the Responses API leaves to your application. If you adopt
conversations and keep the tool loop simple, the mechanical fraction is real
and the conformance test can hold it. If your app depended on the assistant
object, tool_resources, or server-side truncation, those concepts do not
carry over and the app has to change shape.
Coverage and limits: the spec covers 20 concepts across the full surface —
assistant, thread, messages, runs, run steps, function calling, file search,
code interpreter, vector stores, file upload, streaming, polling, structured
output, context/truncation, sampling, usage. It does not cover fine-grained
realtime behavior, the "Prompts" dashboard product, or every SDK convenience
helper. Classifications are the author's judgment at concept granularity and
are marked as such; uncertain mappings are flagged. Facts come from the URLs
in change-spec.json, all read 2026-08-11, and from the [email protected] SDK
type definitions (extracted mechanically into vendor/surface.json). Verify
anything load-bearing against the live docs before you ship — the API is under
active change.
Layout
| Path | What it is |
|---|---|
change-spec.json |
hand-authored, machine-readable change spec (20 concepts, classification, cited sources) |
test/conformance.test.js |
conformance gate for the mechanical items |
test/app.test.js |
implementation-agnostic behaviour suite (14 tests) |
test/mock-server.js |
deterministic local mock of both APIs |
src/assistants/ |
the app before migration (Assistants API) |
src/responses/ |
the app after migration (Responses API) |
scripts/surface-diff.mjs |
extractor that produced vendor/surface.json from the installed [email protected] sources |
vendor/surface.json |
mechanical endpoint surface of both APIs, from [email protected] |
scripts/migrate.sh |
the harness: drives an agent over your repo, gated on your test suite |
prompts/migrate-assistants-to-responses.md |
the instruction the agent receives |
NOTICE |
attribution for the harness adapted from OpenAI's pack |
demo/index.html |
self-contained, branded overview page (what you would publish) |
Migrate your repository
./scripts/migrate.sh --repo /path/to/your/app # plan only, writes nothing
./scripts/migrate.sh --repo /path/to/your/app --write # branch, edit, verify
Default agent is Codex CLI; --agent claude uses Claude Code, and AGENT_CMD
takes any invocation you like. What it does, in order:
- Refuses to run outside a git repository, or with a dirty working tree.
- Finds the Assistants call sites, and exits if there are none.
- Runs your test suite to establish a baseline. If it is already red it stops
— migrating on top of a failing suite means you cannot tell whose failures
are whose. Override with
--allow-red-baseline. - Creates a branch and drives the agent with
change-spec.jsonandprompts/migrate-assistants-to-responses.md. - Runs the suite again. If it was green and is now red, the migration is reported as failed and the command tells you how to discard the branch.
A green suite is necessary, not sufficient. It says nothing about the eight
concepts marked judgment or the two marked no_equivalent — those need a
human, which is the point of classifying them.
Tests
npm install # [email protected]
npm test # 14 behaviour tests, green on both implementations
npm run test:conformance # 8 conformance assertions on the mechanical items
npm run test:all # both
Regenerate the surface
vendor/surface.json is generated from the installed SDK sources:
npm install # pins [email protected]
node scripts/surface-diff.mjs # rewrites vendor/surface.json
Honesty note
The change spec is hand-authored. OpenAI has no involvement in this pack.
The conformance test is written by the pack author from the official docs and
the [email protected] SDK types, as a stand-in for the input a team would want from
its SDK vendor; OpenAI has published the official migration guide
(developers.openai.com/api/docs/assistants/migration/) and says it will not
provide an automated tool for migrating Threads to Conversations.
Sources
| Ref | URL | Read |
|---|---|---|
| S1 | https://developers.openai.com/api/docs/assistants/migration/ | 2026-08-11 |
| S2 | [email protected] SDK type definitions, extracted into vendor/surface.json |
2026-08-11 |
License
MIT. See LICENSE. Third-party content: the openai npm package is
MIT-licensed by OpenAI; the Space Grotesk font embedded in demo/index.html is
OFL-licensed (see demo/fonts/).