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