Integrate Orbitrage (LLM router + full observability) into THIS codebase. Orbitrage is
OpenAI-API-compatible: existing OpenAI/Anthropic-style clients just point at
https://api.orbitrage.ai/v1 with an `orb_` key and every call is auto-routed + traced.
Make MINIMAL changes — only the integration, never the app logic. Docs: https://docs.orbitrage.ai
1) INSTALL the latest SDK (match the project language):
• Python: pip install -U orbitrage openai
• Node/TS: npm install orbitrage@latest openai
2) INITIALIZE ONCE at the program entrypoint, before any LLM client is constructed. Read the
key from env ORBITRAGE_API_KEY (never hardcode). Pass user_id = the end-user/customer id
(use the real per-request id where available, else a sensible constant):
• Python: import orbitrage; orbitrage.init(os.environ["ORBITRAGE_API_KEY"], user_id="<end_user_id>")
• Node: import { orbitrage } from "orbitrage";
await orbitrage.init({ apiKey: process.env.ORBITRAGE_API_KEY, userId: "<end_user_id>" });
3) MODELS: prefer a DIRECT model for predictable behavior — "claude-sonnet-4-6" (quality) or
"grok-4-fast" (fast/cheap). Use "auto" only to let Orbitrage pick the cheapest model, and
then keep max_tokens >= 512 (auto may pick a reasoning model that truncates short answers).
For Claude, do NOT use the Anthropic SDK — call model="claude-sonnet-4-6" via the OpenAI client.
4) WIRE every LLM client found in the repo:
• Raw OpenAI SDK (OpenAI() / new OpenAI()): after init(), do NOT set base_url — init points it
at the gateway and forces the orb_ key automatically (even if OPENAI_API_KEY is set). Only
change the model id.
• LangChain (Py): ChatOpenAI(model="grok-4-fast", base_url="https://api.orbitrage.ai/v1",
api_key=os.environ["ORBITRAGE_API_KEY"], default_headers={"x-orbitrage-end-user-id":"<id>"})
• LangChain.js: new ChatOpenAI({ model:"grok-4-fast", apiKey:process.env.ORBITRAGE_API_KEY,
configuration:{ baseURL:"https://api.orbitrage.ai/v1",
defaultHeaders:{"x-orbitrage-end-user-id":"<id>"} } })
• CrewAI: LLM(model="openai/gpt-4o-mini", base_url="https://api.orbitrage.ai/v1",
api_key=os.environ["ORBITRAGE_API_KEY"]) # LiteLLM validates names: use a recognized
OpenAI id, or litellm.register_model({...}) to allow grok/claude.
• Agno: OpenAIChat(id="grok-4-fast", api_key=os.environ["ORBITRAGE_API_KEY"],
base_url="https://api.orbitrage.ai/v1", default_headers={"x-orbitrage-end-user-id":"<id>"})
• LlamaIndex: from llama_index.llms.openai_like import OpenAILike
OpenAILike(model="grok-4-fast", api_base="https://api.orbitrage.ai/v1",
api_key=os.environ["ORBITRAGE_API_KEY"], is_chat_model=True) # stock OpenAI class
# rejects non-OpenAI model names — use OpenAILike for grok/claude/auto.
• Vercel AI SDK: createOpenAI({ baseURL:"https://api.orbitrage.ai/v1",
apiKey:process.env.ORBITRAGE_API_KEY, headers:{"x-orbitrage-end-user-id":"<id>"} });
then provider.chat("grok-4-fast")
5) MANAGED TOOLS (optional — no tool API keys to wire): add reserved names to the request
tools array and Orbitrage runs them server-side: tavily_orbitrage (web search),
serper_orbitrage, firecrawl_orbitrage, jina_orbitrage, weather_orbitrage,
calculator_orbitrage, datetime_orbitrage. Pin a model (not "auto") for tool calls.
6) PER-USER (multi-tenant server): switch per request with orbitrage.set_user(id) (Python) /
orbitrage.setUser(id) (Node), then construct a NEW client so it picks up the new id.
7) VERIFY: run the app; confirm calls succeed and show up at https://app.orbitrage.ai/workflows
attributed to the user_id. For anything unclear or any edge case, consult https://docs.orbitrage.ai.