Vercel AI SDK
The AI SDK exposes an onFinish callback on every generateText and streamText call. withAgentPing() returns a pre-built onFinish (and optional onStepFinish) you spread into your call options. One helper, every provider the AI SDK supports.
withAgentPing() auto-detects provider and model from the AI SDK's response.modelId (for example openai/gpt-4o-mini). Pass { provider, model } only to override. The run is resolved from the active runScopeAsync scope, or pass it explicitly as the first argument.
Install
npm install @agentping/sdk ai @ai-sdk/openai
Quickstart
import * as agentping from "@agentping/sdk";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
agentping.init({ apiKey: process.env.AGENTPING_API_KEY });
const run = agentping.run("doc-summary");
const { text } = await generateText({
model: openai("gpt-4o-mini"),
prompt: "summarise this report",
...agentping.withAgentPing(run),
});
await run.finish({ status: "success" });
withAgentPing(run) reads usage.inputTokens / outputTokens (AI SDK v5+) and falls back to promptTokens / completionTokens (AI SDK v4). Both shapes produce the same llm_call event.
For streamText, drain the stream to completion before run.finish(), the event fires inside onFinish, so the run must still be open when the stream ends:
const result = streamText({
model: openai("gpt-4o-mini"),
prompt: "explain in three sentences",
...agentping.withAgentPing(run),
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}
await run.finish({ status: "success" });
What's captured
| AI SDK callback | AgentPing event | When |
|---|---|---|
onFinish |
llm_call |
once per call (input/output/cached tokens, latency) |
onFinish |
finish_reason |
when finish reason is not stop (length, error, content-filter) |
onStepFinish |
llm_call + tool_call |
per step, when perStep: true |
For tool-using agents, pass perStep: true so onStepFinish fires per round-trip; each step emits an llm_call and one tool_call per tool invoked:
const { text } = await generateText({
model: openai("gpt-4o"),
tools: { search: searchTool, fetch: fetchTool },
prompt: "find the latest pricing",
...agentping.withAgentPing(run, { perStep: true }),
});
Advanced (optional)
In a Next.js route handler, use agentPingOnFinish() to compose AgentPing's callback with your own. It returns the same callback that withAgentPing(...).onFinish produces:
export async function POST(req: Request) {
const { prompt } = await req.json();
const run = agentping.run("chat-route");
const agentpingFinish = agentping.agentPingOnFinish(run);
const result = streamText({
model: openai("gpt-4o-mini"),
prompt,
onFinish: (event) => {
agentpingFinish(event);
run.finish({ status: "success" });
},
});
return result.toDataStreamResponse();
}
Switching providers needs no other change: the same helper auto-detects @ai-sdk/anthropic, @ai-sdk/google, @ai-sdk/mistral, and the rest from response.modelId.
Source
- TypeScript SDK:
withAgentPing+agentPingOnFinishin agentping-sdk-typescript