Skip to content

Migrate from the Anthropic SDK

Moving from the official @anthropic-ai/sdk package to ORXA: LLM-SDK is mechanical. You replace the client construction and the call site; your prompts, tools, and schemas stay the same — and the same code now also runs OpenAI, Google, and xAI by changing one string.

Terminal window
npm install @combycode/llm-sdk

Before:

import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const msg = await client.messages.create({
model: 'claude-sonnet-4.6',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
console.log(msg.content[0].type === 'text' ? msg.content[0].text : '');

After:

import { complete } from '@combycode/llm-sdk';
const { text } = await complete({
model: 'anthropic/claude-sonnet-4.6',
apiKey: process.env.ANTHROPIC_API_KEY,
prompt: 'Hello',
});
console.log(text);

The model id becomes anthropic/<model>. max_tokens is no longer required — ORXA defaults it (set maxTokens to override). The response is { text, parsed?, response }, so no more content[0].type === 'text' narrowing. Token counts are on response.usage (response.usage.inputTokens, response.usage.outputTokens).

Anthropic takes system as a top-level field; so does ORXA:

Before:

const msg = await client.messages.create({
model: 'claude-sonnet-4.6',
max_tokens: 1024,
system: 'You are terse.',
messages: [{ role: 'user', content: 'Hello' }],
});

After:

const { text } = await complete({
model: 'anthropic/claude-sonnet-4.6',
system: 'You are terse.',
prompt: 'Hello',
});

Pass a Message[] as the prompt:

const { text } = await complete({
model: 'anthropic/claude-sonnet-4.6',
prompt: [
{ role: 'user', content: 'Hi' },
{ role: 'assistant', content: 'Hello!' },
{ role: 'user', content: 'What did I just say?' },
],
});

For managed conversations and layered context, see Multi-turn and Layered context.

Before:

const stream = client.messages.stream({
model: 'claude-sonnet-4.6',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Count to 5.' }],
});
for await (const event of stream) {
if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
process.stdout.write(event.delta.text);
}
}

After — one event type, no nested narrowing:

import { createLLM } from '@combycode/llm-sdk';
const llm = createLLM({ model: 'anthropic/claude-sonnet-4.6', apiKey: process.env.ANTHROPIC_API_KEY });
for await (const ev of llm.stream('Count to 5.')) {
if (ev.type === 'text') process.stdout.write(ev.text);
}

See Streaming.

Before — define an input_schema, then read tool_use blocks, run them, append tool_result blocks, and call again:

const msg = await client.messages.create({
model: 'claude-sonnet-4.6',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Weather in Paris?' }],
tools: [{
name: 'get_weather',
description: 'Get weather for a city',
input_schema: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },
}],
});
// ...find tool_use blocks, execute, append tool_result, loop

After — defineTool carries the executor, complete() runs the loop:

import { complete, defineTool } from '@combycode/llm-sdk';
const getWeather = defineTool({
name: 'get_weather',
description: 'Get weather for a city',
params: { city: 'string' },
execute: async ({ city }) => `Sunny in ${city}`,
});
const { text } = await complete({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Weather in Paris?',
tools: [getWeather],
});

See Single tool call and Multi-step loop.

Anthropic has no native JSON-schema response mode — you typically prompt for JSON and parse by hand. ORXA gives you the same structured.schema option as every other provider:

const { parsed } = await complete({
model: 'anthropic/claude-sonnet-4.6',
prompt: 'Extract name and age: John is 30',
structured: {
schema: {
type: 'object',
properties: { name: { type: 'string' }, age: { type: 'number' } },
required: ['name', 'age'],
},
},
});
console.log(parsed); // { name: 'John', age: 30 }

If the model returns invalid JSON, complete() throws — wrap in try/catch to retry. See Structured output.

Before, Anthropic’s thinking block; in ORXA, a unified thinking option:

const llm = createLLM({ model: 'anthropic/claude-sonnet-4.6', apiKey: process.env.ANTHROPIC_API_KEY });
const res = await llm.complete('Solve this step by step...', {
thinking: { mode: 'auto', effort: 'high' },
});
console.log(res.thinking, res.text);

See Reasoning.

Official SDKORXA
Model id'claude-sonnet-4.6''anthropic/claude-sonnet-4.6'
max_tokensrequiredoptional (defaulted)
Response textcontent[0].text (after narrowing)result.text
Token usageusage.input_tokensresponse.usage.inputTokens
Tool loopmanualrun by complete()
JSON schema modenone (prompt + parse)structured.schema
Switch providernew SDK + new shapeschange the model string

Next: Models & providers · Provider routing & fallback · Cost tracking.