samai-sdk
Production

Providers

Every provider implements the same Provider interface, so nothing else in your code changes when you swap one in.

providers.ts
import { openai, anthropic, google, groq, mistral, ollama, azureOpenAI, bedrock } from "samai-sdk";

createClient({ provider: openai({ apiKey: "..." }) });
createClient({ provider: anthropic({ apiKey: "..." }) });
createClient({ provider: google({ apiKey: "..." }) });

// OpenAI-compatible endpoints — same shared implementation under the hood:
createClient({ provider: groq({ apiKey: "..." }) });       // fast inference (LPU hardware)
createClient({ provider: mistral({ apiKey: "..." }) });    // Mistral's "La Plateforme"
createClient({ provider: ollama() });                      // local models, no key, no cost —
                                                             // `ollama pull llama3.1`, use "llama3.1" as model

// Azure OpenAI — routes by deployment name, so `model` = your deployment name:
createClient({ provider: azureOpenAI({ endpoint: "https://my-resource.openai.azure.com" }) });

// AWS Bedrock — the unified Converse API, works the same across every model family:
createClient({ provider: bedrock({ region: "us-east-1" }) });
// model: "anthropic.claude-sonnet-4-6-20260101-v1:0", "meta.llama3-1-70b-instruct-v1:0", etc.

Peer dependencies & auth

ProviderPeer dependencyAPI key / auth
anthropic()@anthropic-ai/sdkANTHROPIC_API_KEY (pass explicitly)
openai()openaipass explicitly
google()@google/generative-aipass explicitly
groq()openaiGROQ_API_KEY
mistral()openaiMISTRAL_API_KEY
ollama()openainone — local, no auth
azureOpenAI()openaiAZURE_OPENAI_API_KEY
bedrock()@aws-sdk/client-bedrock-runtimestandard AWS credential chain

Why 4 providers share one dependency

groq(), mistral(), ollama(), and azureOpenAI() all reuse the openai package pointed at a different baseURL. All the actual generate/stream/tool-call/finish-reason logic for every OpenAI-compatible provider lives in one shared implementation, so there's nothing provider-specific to go wrong per integration.

Switching providers later

Because every provider satisfies the same interface, tools, guardrails, agent definitions, and handoffs are all provider-agnostic — changing providers is a one-line edit to createClient(), nothing else in your codebase moves.