← Back to all products

OpenAI to Anthropic Migration Kit

$29

A concept map + tested neutral adapter for migrating between (or supporting both) the OpenAI and Anthropic APIs: system prompts, required max_tokens, tool calling, stop reasons, streaming.

📁 8 files🏷 v1.0.0 (updated 2026-08-02)
TypeScriptMarkdownJSONOpenAI

📄 Product Preview

Try the interactive reader and demo tools below, or get the full product with all content unlocked.

📖 Interactive Reader (Free Preview) 📦 Download Free Sample

📁 File Structure 8 files

openai-anthropic-migration-kit/ ├── README.md ├── package.json ├── src/ │ ├── anthropic_adapter.ts │ ├── openai_adapter.ts │ ├── provider.ts │ └── types.ts └── test/ └── adapters.test.ts

📖 Documentation Preview README excerpt

OpenAI ↔ Anthropic SDK Migration Kit

A concept map + a thin adapter for moving code between the OpenAI and

Anthropic APIs (or supporting both behind one interface). This is a task

agents get constantly ("switch us from GPT to Claude", "add a fallback provider")

and the two SDKs differ in enough places — message shape, system prompts, token

params, tool calling, streaming, stop reasons — to break a naive swap.

What actually differs (the map)

ConceptOpenAIAnthropic
System prompta role:"system" messagetop-level system param
Messagesmessages[] incl. systemmessages[] (user/assistant only)
Max tokensmax_tokens (optional)max_tokens (required)
Multi-turnroles in one arraystrict user/assistant alternation
Tool callingtools + tool_callstools + tool_use/tool_result blocks
Response textchoices[0].message.contentcontent[0].text (content blocks)
Stop reasonfinish_reasonstop_reason
StreamingSSE deltasSSE content_block_delta events

Full detail with examples in CONCEPT-MAP.md.

What's inside

  • CONCEPT-MAP.md — every difference, with request/response examples side by side.
  • src/types.ts — a neutral ChatRequest/ChatResponse interface.
  • src/openai_adapter.ts — map neutral ⇄ OpenAI shape.
  • src/anthropic_adapter.ts — map neutral ⇄ Anthropic shape (system extraction,

required max_tokens, content-block flattening, stop-reason normalization).

  • src/provider.ts — one chat(req) that routes to either provider + fallback.
  • test/adapters.test.ts — proves the mappings both ways (Vitest).

Use it two ways

1. One-time migration: translate your call sites to the neutral interface, then

flip the provider.

2. Multi-provider: keep the neutral interface permanently and switch providers

by config, with automatic fallback when one is down or rate-limited.

Requirements

Node 18+, TypeScript 5+. (Adapters are transport-shaping only; wire your own HTTP

or the official SDKs behind them.)

License

MIT.

📄 Code Sample .ts preview

src/anthropic_adapter.tsimport type { ChatRequest, ChatResponse } from './types.js'; /** Neutral -> Anthropic Messages request body. Key differences handled: * system is a top-level param, max_tokens is required, messages are user/assistant * only (no system role), content is a string here (single text block). */ export function toAnthropicRequest(req: ChatRequest): Record<string, unknown> { return { model: req.model, ...(req.system ? { system: req.system } : {}), messages: req.messages.map((m) => ({ role: m.role, content: m.content })), max_tokens: req.maxTokens, // REQUIRED by Anthropic ...(req.temperature != null ? { temperature: req.temperature } : {}), ...(req.stop ? { stop_sequences: req.stop } : {}), }; } const ANTHROPIC_STOP: Record<string, ChatResponse['stopReason']> = { end_turn: 'stop', stop_sequence: 'stop', max_tokens: 'length', tool_use: 'tool_use', }; /** Anthropic response -> neutral. Flattens content blocks to text. */ export function fromAnthropicResponse(body: any): ChatResponse { const blocks: any[] = body?.content ?? []; const text = blocks.filter((b) => b.type === 'text').map((b) => b.text).join(''); return { text, stopReason: ANTHROPIC_STOP[body?.stop_reason] ?? 'other', model: body?.model ?? 'anthropic', raw: body, }; }
Buy Now — $29 Back to Products