Model providers
Provider-by-provider notes — what works out of the box, what needs config.
plr.wrap() auto-detects provider clients and records cost, tokens, and latency per request. This page covers everything tested in CI and a fallback for custom providers.
Anthropic
import Anthropic from "@anthropic-ai/sdk";
const anthropic = plr.wrap(new Anthropic());Captured: model, system prompt, messages, response content, prompt_tokens, completion_tokens, cache_read/write tokens, stop_reason, cost (USD), latency. Streaming responses are captured too.
OpenAI
import OpenAI from "openai";
const openai = plr.wrap(new OpenAI());Captured: model, messages, response choices, prompt_tokens, completion_tokens, finish_reason, cost (USD), latency. Function calls and tool calls are captured as child spans.
OpenAI-compatible (Groq, xAI, Together, OpenRouter, Fireworks, DeepSeek, Ollama)
Use the OpenAI client with a custom baseURL:
const groq = plr.wrap(new OpenAI({
baseURL: "https://api.groq.com/openai/v1",
apiKey: process.env.GROQ_API_KEY,
}));
const xai = plr.wrap(new OpenAI({
baseURL: "https://api.x.ai/v1",
apiKey: process.env.XAI_API_KEY,
}));The wrapper reads the host from the client and labels the trace accordingly.
Mistral
import { Mistral } from "@mistralai/mistralai";
const mistral = plr.wrap(new Mistral({ apiKey: process.env.MISTRAL_API_KEY }));Or explicit: wrapMistral(client, { label: "critic" }).
Google GenAI / Vertex AI
import { GoogleGenerativeAI } from "@google/genai";
const genai = wrapGoogleGenAI(new GoogleGenerativeAI(apiKey), { keystone: plr });Works with both Gemini (consumer API) and Vertex AI.
AWS Bedrock
Bedrock has a wider surface than other providers; the cleanest path is OTel. Use the AWS SDK with an OTel instrumentation (e.g. @opentelemetry/instrumentation-aws-sdk) and point OTLP at Polarity. See OpenTelemetry.
HuggingFace
For HF Inference Endpoints, use the OpenAI client form (HF exposes OpenAI-compatible endpoints) or wrap your own HTTP layer with traced("hf_inference", ...).
Polarity built-in judge models
Polarity ships its own model tier for LLM-as-judge work — no provider key required, usage included in the flat Polarity contract:
| Model | Use for |
|---|---|
paragon-fast | Quick heuristic-style judges, regex-like checks, high-volume continuous scoring |
paragon-md | Default for most LLM-as-judge work |
paragon-max | High-stakes graders, side-by-side comparisons, hard alignment calls |
Backing models update over time; usage is included in the flat Polarity contract.
Custom HTTP providers
If your provider isn't in the list, wrap your HTTP call with traced():
import { traced } from "@polarityinc/polarity";
async function callMyProvider(prompt: string) {
return traced("my_provider.generate", async () => {
const res = await fetch("https://my-llm.example/v1/chat", {
method: "POST",
body: JSON.stringify({ prompt }),
});
return res.json();
}, {
metadata: { model: "my-model-v1", prompt_tokens: prompt.length / 4 },
});
}Or use recordLLMCall() to emit a properly-shaped llm_call span — see SDK reference.
Mixed providers in one agent
Use explicit per-provider wrappers with labels so multi-agent runs (planner / executor / critic) are easy to debug:
import { wrapAnthropic, wrapOpenAI } from "@polarityinc/polarity";
const planner = wrapAnthropic(new Anthropic(), { label: "planner" });
const executor = wrapOpenAI(new OpenAI(), { label: "executor" });
const critic = wrapAnthropic(new Anthropic(), { label: "critic" });Labels show up in the trace tree so you can filter spans by role.