npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tuttiai/telemetry

v0.4.0

Published

Tutti telemetry — span-based tracing for agent runs, tool calls, and LLM completions

Readme

@tuttiai/telemetry

In-process span tracing, cost estimation, and OTLP/JSON export for Tutti.

Wired into @tuttiai/core automatically — every agent run, LLM call, tool call, guardrail, and checkpoint becomes a span. No application-code changes required.

Install

npm install @tuttiai/telemetry

@tuttiai/core already depends on this package, so most users never install it directly. Reach for it when you want to:

  • subscribe to live span events from your application code
  • write a custom exporter (Slack alerts, Postgres archive, …)
  • inspect or aggregate traces in tests

Quick start

The runtime auto-exports spans when you set one of these in your score:

import { defineScore } from "@tuttiai/core";

export default defineScore({
  // …agents, provider…
  telemetry: {
    enabled: false, // OTel SDK auto-instrumentation (separate)

    // Pick one — OTLP/HTTP collector:
    otlp: {
      endpoint: "http://localhost:4318/v1/traces",
      headers: { "x-honeycomb-team": process.env.HONEYCOMB_API_KEY ?? "" },
    },

    // …or newline-delimited JSON file (great for CI eval artefacts):
    jsonFile: "./traces.jsonl",
  },
});

Or via environment variable, no score change needed:

TUTTI_OTLP_ENDPOINT=http://localhost:4318/v1/traces npm run dev
TUTTI_TRACE_FILE=./traces.jsonl npm run dev

Env vars beat the score config so operators can override without editing source.

Inspect spans in code

Every run returns a trace_id you can use to retrieve the full span tree:

import { getTuttiTracer } from "@tuttiai/telemetry";

const result = await tutti.run("assistant", "Hi!");
const spans = getTuttiTracer().getTrace(result.trace_id!);
// → [agent.run, llm.completion, tool.call, ...]

Subscribe for live tailing:

const stop = getTuttiTracer().subscribe((span) => {
  console.log(`${span.name} ${span.status} ${span.duration_ms}ms`);
});
// stop() to detach

Cost estimation

Built-in price table for the major model families. cost_usd is recorded on every llm.completion span and aggregated onto result.usage.cost_usd:

import { estimateCost, getRunCost, registerModelPrice } from "@tuttiai/telemetry";

estimateCost("gpt-4o", 1000, 500);              // → 0.0125

registerModelPrice("our-fine-tune", 100, 200);  // USD per 1M tokens
estimateCost("our-fine-tune", 1000, 500);       // → 0.2

const cost = getRunCost(result.trace_id!);
// → { prompt_tokens, completion_tokens, total_tokens, cost_usd }

Built-in models (USD per 1M tokens):

| Model | Input | Output | |---|---|---| | gpt-4o | $5 | $15 | | gpt-4o-mini | $0.15 | $0.60 | | claude-opus-4 | $15 | $75 | | claude-sonnet-4 | $3 | $15 | | claude-haiku-3-5 | $0.80 | $4 | | gemini-2-0-flash | $0.10 | $0.40 |

Returns null for unregistered models so callers can detect missing pricing instead of silently zeroing out.

Exporters

import {
  configureExporter,
  JsonFileExporter,
  OTLPExporter,
} from "@tuttiai/telemetry";

const stop = configureExporter(
  new OTLPExporter({
    endpoint: "http://localhost:4318/v1/traces",
    headers: { "x-api-key": "…" },
  }),
);

// later, before exit:
await stop();
  • OTLPExporter — buffered (100 spans / 5 s), retries 3× with 1s/2s/4s backoff on network errors and 5xx; 4xx is permanent. Uses JsonTraceSerializer from @opentelemetry/otlp-transformer. Compatible with Jaeger, Datadog, Honeycomb, Grafana Tempo, and any OTLP/HTTP collector.
  • JsonFileExporter — appends one JSON object per closed span to a file. Lazy file-open on first write.
  • Custom — implement the SpanExporter interface (export / flush / shutdown).

Span schema

Every span carries:

interface TuttiSpan {
  span_id: string;
  trace_id: string;
  parent_span_id?: string;
  name: string;
  kind: "agent" | "tool" | "llm" | "guardrail" | "checkpoint";
  started_at: Date;
  ended_at?: Date;
  duration_ms?: number;
  status: "running" | "ok" | "error";
  attributes: TuttiSpanAttributes; // typed bag — see types.ts
  error?: { message: string; stack?: string };
}

The runtime emits these span names automatically:

| Name | Kind | Key attributes | |---|---|---| | agent.run | agent | agent_id, session_id, model | | llm.completion | llm | model, prompt_tokens, completion_tokens, total_tokens, cost_usd | | tool.call | tool | tool_name, tool_input, tool_output | | guardrail | guardrail | guardrail_name, guardrail_action (pass/redact/block) | | checkpoint | checkpoint | session_id |

CLI

The tutti-ai traces commands in @tuttiai/cli consume these spans through the @tuttiai/server REST + SSE endpoints:

tutti-ai traces list           # last 20 traces
tutti-ai traces show <id>      # full span tree
tutti-ai traces tail           # live SSE tail

Links

License

Apache 2.0