OpenAI-compatible providers
Model, token counts, and tool names extracted automatically — no extra wiring.
If the value your wrapped function returns has the shape of an OpenAI chat completion, the SDK reads the fields it recognises straight off it. That covers OpenAI itself and every provider that speaks the same protocol:
- OpenAI
- Groq
- Cerebras
- Together
- vLLM, and anything else exposing an OpenAI-compatible route
Wrapping a completion call
Wrap the call itself and the trace fills in on its own — no model, no token counts to thread through by hand.
import OpenAI from 'openai'
import { watch } from '@agentwatch-beta/sdk'
const client = new OpenAI({
baseURL: 'https://api.groq.com/openai/v1',
apiKey: process.env.GROQ_API_KEY,
})
const chat = watch(
(messages) => client.chat.completions.create({
model: 'llama-3.3-70b-versatile',
messages,
}),
{ apiKey: 'aw_live_...', agentId: '<agent-uuid>' },
)What is read off the response
- Model — the model the provider reports having served, which is not always the one you asked for. Baselines are held per model, so a silent version bump surfaces as a change point instead of unexplained drift.
- Token counts — prompt, completion, and total, from the usage block.
- Tool names — the tools the completion called. A shift in which tools fire is a behavioural change even when the prose still reads fine.
Non-matching returns still trace
Wrapping the agent, not the call
Wrapping the completion traces one model call. Wrapping your agent function traces the whole run — retrieval, tool calls, retries, and all — which is the unit AgentWatch scores. Prefer the outer one when your agent does more than a single completion.
// traces one model call
const chat = watch((messages) => client.chat.completions.create({ ... }), opts)
// traces the whole run — usually what you want
const runAgent = watch(async (query: string) => {
const docs = await retrieve(query)
const answer = await client.chat.completions.create({ ... })
return answer.choices[0].message.content
}, opts)In the second form the return value is a string rather than a completion, so the model and token fields are not extracted. Return the completion object instead, or send them explicitly with aw.trace().