Skip to main content
Use @squasher-ai/agent when you need structured telemetry for AI workflows rather than plain errors and logs. It is a good fit for:
  • agent backends
  • customer chat assistants
  • tool-calling workflows
  • OpenRouter / OpenAI-compatible inference pipelines
  • internal copilots and runbooks

Install

Vercel AI SDK

Use one setup across AI SDK v4, v5, v6, and v7. Squasher selects the compatible instrumentation path internally.

Set up once

src/ai.ts
ai keeps the original AI SDK module types and exports. Squasher instruments generateText and streamText; object generation, agent classes, and other exports pass through unchanged.

Scope each request

.with() returns another typed module and does not mutate the shared instance. Nested .with() scopes merge context, with inner values winning and attributes merged by key. Prefer .with() for portable request isolation. This call shape is the same on every supported AI SDK major:
  • AI SDK 6 and 7 use lifecycle integration hooks.
  • AI SDK 4 and 5 use model middleware.
  • Existing callbacks, telemetry settings, and telemetry integrations remain in place.
Automatically captured fields include model and provider identity, tokens, cost, latency, finish status, cache and reasoning token counts, model settings, tool trajectory, and streaming outcome.

Serverless and shutdown

Flush after a non-streaming serverless invocation:
For streams, keep a completion-and-flush task alive with the runtime’s request-lifetime mechanism, such as waitUntil. Flushing before the stream settles can miss terminal telemetry. Call ai.close() during process shutdown, not after every request.

Privacy defaults

Prompt and completion content is off by default. Enable it only for workflows with a deliberate retention policy:
captureReasoning controls Squasher’s dedicated reasoning field. On the AI SDK 6-7 lifecycle path, capturePayloads: true also retains the provider response, which can contain reasoning parts. Use privacyMode: true when reasoning must not be retained. Privacy mode always wins and suppresses prompt messages, output text, provider payloads, raw error text, reasoning, and tool input/output. Tokens, model/provider identifiers, statuses, tool names, timings, and custom attributes still flow. On the AI SDK 4-5 model-middleware path, streaming output deltas are not accumulated. The AI SDK 6-7 lifecycle path can retain streamed output when payload capture is enabled.

Advanced integrations

Most applications should use withSquasher. The lower-level APIs remain for framework authors and custom instrumentation.

Native AI SDK lifecycle integration

Use the native integration when you already own the call’s telemetry settings or need direct lifecycle events:
AI SDK 6 callers can use createAiSdkV6TelemetryIntegration with experimental_telemetry.integrations. Existing integration aliases remain supported.

Model-level middleware

Use middleware to instrument one model independently of the module wrapper:
Use experimental_wrapLanguageModel on AI SDK versions that expose only the experimental name.

Manual telemetry for custom runtimes

Use the underlying client when a runtime does not use Vercel AI SDK:
Always pass a spanId on manual tool calls and generations. Ingest only materializes an observation when it has a span name, trace id, and span id.

Quality scores

Cost and latency tell you a model is cheaper and faster. Only a score tells you whether it is as good — which is the question a rollout actually turns on. For editable ratings or thumbs feedback, use the purpose-built helper. It requires the stable feedback id and trace link that make later edits join the same generation instead of becoming orphan scores:
Use sentiment: "positive" | "negative" instead of rating for thumbs feedback. Human feedback is recorded with source: "annotation" automatically. The example below pins a trace-level score to the run it judges. To bind a score to a specific generation instead, also pass that generation’s observationId, as in the feedback example above:
Use a stable scoreId for editable user feedback or annotations. Sending the same id again replaces the prior value in score queries and summaries. Send deleted: true with that id to remove it from query results without a mutable ingest write. source separates a human judgement from an automated one, because they carry very different weight in a rollout decision: Pass value for numeric and boolean scores (1 / 0), or label for categorical ones like correct / refused. Scores also carry the OpenTelemetry gen_ai.evaluation.* attributes, so they are readable by anything that speaks the GenAI semantic conventions rather than only by Squasher.

Runtime support and guarantees

@squasher-ai/agent is an ESM, server-side package. AI SDK 7 additionally requires Node.js 22+. Telemetry does not change model results, consume a stream on your behalf, alter callback behavior, or replace the original model error. Capture failures remain isolated from the model call.

How it appears in Squasher

Agent telemetry is sent to Squasher’s remote observability pipeline and is stored with your project telemetry. Use local logs or development artifacts only as temporary debugging aids; Squasher remains the system of record for production AI observability, historical search, and AI triage context.

Good fit

  • Agent backends that need per-run traces.
  • Tool execution and generation visibility.
  • Session-level analytics tied back to a customer, workflow, or environment.

Agent handoff

Use this prompt when a coding agent is instrumenting an AI workflow:

Notes

  • @squasher-ai/agent is for server-side runtimes.
  • Flush before shutdown so queued telemetry is delivered.
  • Completed generations count toward your plan’s AI request quota.
  • Free plans drop additional AI requests after the monthly included quota is exhausted.
  • Paid plans continue ingesting above the included quota and meter overage usage.
  • For a full OpenRouter example, see /integrations/openrouter.
  • If you don’t want to install an SDK at all, send the same generations directly to the AI batch ingest endpoint — see Direct HTTP ingest on the OpenRouter page for the worked curl example.