Coming from OpenAI
Move an agent from the OpenAI Agents SDK, ChatKit or Agent Builder to Cencori: what maps to what, and what changes.
cencori/agents follows the same shape as the OpenAI Agents SDK for JavaScript: agents, tools, run(), handoffs, guardrails, approvals. Most code moves by changing imports. What you get in return: any model in the catalog, durable runs that can wait on a person, traces, budgets and PII rules on every call, and a chat UI that works with all of it.
At a glance
1. Install and set your key
npm uninstall @openai/agents
npm install cencori zod# .env
CENCORI_API_KEY=csk_...2. Change the imports
// Before
import { Agent, run, tool } from '@openai/agents';
// After
import { Agent, run, tool } from 'cencori/agents';Agents, tools and runs are written the same way:
const getWeather = tool({
name: 'get_weather',
description: 'Current weather for a city.',
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => fetchWeather(city),
});
const agent = new Agent({
name: 'Assistant',
instructions: 'Answer briefly.',
tools: [getWeather],
});
const result = await run(agent, "What's the weather in Lagos?");
console.log(result.finalOutput);3. Pick a model
Agents without model use GPT OSS 120B on Cerebras: fast and good at tools. To keep using an OpenAI model, name it; to try another, change the string:
new Agent({ name: 'Assistant', model: 'gpt-4o', ... });
new Agent({ name: 'Assistant', model: 'claude-sonnet-4-5', ... });What maps one to one
What's different
Saving a paused run. Both serialize the state. Restoring differs slightly:
// OpenAI
const state = await RunState.fromString(agent, saved);
// Cencori
const state = RunState.fromJSON(saved);Then approve or reject and call run(agent, state) as before. Cencori keeps the paused session for 24 hours; the request and decision land in your governance ledger.
Guardrail errors. One class, GuardrailTripwireTriggered, with kind: 'input' | 'output' instead of two classes.
Conversations. Each run is a Cencori session. To continue one, pass its id: run(agent, input, { sessionId: result.sessionId }). The session holds the history server-side.
Stream events. Instead of raw model events plus run items, you get one flat list: agent_updated, text_delta, tool_call, tool_output, handoff, widget, interruption.
ChatKit to Agent UI
// app/api/chat/route.ts
import { createAgentChatHandler } from 'cencori/agents';
import { agent } from '@/lib/agent';
export const POST = createAgentChatHandler(agent);// app/page.tsx
import { AgentChat } from 'cencori/react';
<AgentChat api="/api/chat" />Agent Builder to Cencori
If your agent was built in Agent Builder rather than in code:
- No code needed: build it under Business Agents in the console (instructions, knowledge, tools, website and WhatsApp), then put it in your app with
<AgentChat widgetKey="cwk_..." />. - Defined by API: create a stored agent and run it by id from the SDK (
Agent.fromCencori(id)) or straight from a browser (<AgentChat agent publishableKey />).
Not here yet
- OpenAI hosted tools (file search, code interpreter, computer use). Web search is available as a built-in tool on stored agents.
- Voice and realtime agents. Use the Voice API for now.
- Python. The Agents SDK is TypeScript today; from Python, use the Agents API over HTTP.
A complete example
The Agent UI starter is a Next.js app with tools, widgets and an approval, ready to copy.

