Migrate from the Google GenAI SDK
Moving from the official @google/genai 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, Anthropic, and xAI by changing one string.
Install
Section titled “Install”npm install @combycode/llm-sdkBasic completion
Section titled “Basic completion”Before:
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });const res = await ai.models.generateContent({ model: 'gemini-3.5-flash', contents: 'Hello',});console.log(res.text);After:
import { complete } from '@combycode/llm-sdk';
const { text } = await complete({ model: 'google/gemini-3.5-flash', apiKey: process.env.GEMINI_API_KEY, prompt: 'Hello',});console.log(text);The model id becomes google/<model>. The response is { text, parsed?, response }; token
counts are on response.usage (response.usage.inputTokens, response.usage.outputTokens)
instead of res.usageMetadata.
System prompt
Section titled “System prompt”Google takes the system text via config.systemInstruction; ORXA takes a top-level system:
Before:
const res = await ai.models.generateContent({ model: 'gemini-3.5-flash', contents: 'Hello', config: { systemInstruction: 'You are terse.' },});After:
const { text } = await complete({ model: 'google/gemini-3.5-flash', system: 'You are terse.', prompt: 'Hello',});Multi-turn
Section titled “Multi-turn”Before, you build a contents array of { role, parts }. In ORXA, pass a Message[]:
const { text } = await complete({ model: 'google/gemini-3.5-flash', prompt: [ { role: 'user', content: 'Hi' }, { role: 'assistant', content: 'Hello!' }, { role: 'user', content: 'What did I just say?' }, ],});Note ORXA uses assistant for the model turn (not Google’s model role) — it normalizes
roles for you. See Multi-turn.
Streaming
Section titled “Streaming”Before:
const stream = await ai.models.generateContentStream({ model: 'gemini-3.5-flash', contents: 'Count to 5.',});for await (const chunk of stream) { process.stdout.write(chunk.text ?? '');}After:
import { createLLM } from '@combycode/llm-sdk';
const llm = createLLM({ model: 'google/gemini-3.5-flash', apiKey: process.env.GEMINI_API_KEY });for await (const ev of llm.stream('Count to 5.')) { if (ev.type === 'text') process.stdout.write(ev.text);}See Streaming.
Function / tool calling
Section titled “Function / tool calling”Before — declare functionDeclarations, then read functionCalls, execute, append a
functionResponse, and call again:
const res = await ai.models.generateContent({ model: 'gemini-3.5-flash', contents: 'Weather in Paris?', config: { tools: [{ functionDeclarations: [{ name: 'get_weather', description: 'Get weather for a city', parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] }, }], }], },});// ...read res.functionCalls, run them, append functionResponse, loopAfter — 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: 'google/gemini-3.5-flash', prompt: 'Weather in Paris?', tools: [getWeather],});See Single tool call and Multi-step loop.
Structured / JSON output
Section titled “Structured / JSON output”Before, Google’s responseMimeType + responseSchema; in ORXA, the unified
structured.schema option:
const { parsed } = await complete({ model: 'google/gemini-3.5-flash', 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.
Built-in search
Section titled “Built-in search”Google’s grounding maps to a built-in tool:
const { text } = await complete({ model: 'google/gemini-3.5-flash', prompt: 'What launched this week?', tools: [{ type: 'web_search' }],});See Web search.
What changes, what stays the same
Section titled “What changes, what stays the same”| Official SDK | ORXA | |
|---|---|---|
| Model id | 'gemini-3.5-flash' | 'google/gemini-3.5-flash' |
| System text | config.systemInstruction | top-level system |
| Response text | res.text | result.text |
| Token usage | res.usageMetadata | response.usage.inputTokens |
| Model turn role | 'model' | 'assistant' (normalized) |
| Tool loop | manual | run by complete() |
| Switch provider | new SDK + new shapes | change the model string |
Next: Models & providers · Provider routing & fallback · Cost tracking.