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

@zetesis/payload-agents-metrics

v0.1.5

Published

Payload CMS plugin for LLM usage observability — token tracking, cost calculation, session analytics, and dashboard components

Downloads

589

Readme

@zetesis/payload-agents-metrics

LLM usage observability plugin for Payload CMS: token tracking, cost calculation, session analytics, and a ready-to-use dashboard component. Designed to plug into @zetesis/payload-agents-core via its onRunCompleted hook.

Installation

pnpm add @zetesis/payload-agents-metrics

Usage

import { agentPlugin } from '@zetesis/payload-agents-core'
import { metricsPlugin } from '@zetesis/payload-agents-metrics'
import { buildConfig } from 'payload'

const metrics = metricsPlugin({
  // Set to `true` and provide `checkAccess` + `resolveTenantId` for multi-tenant setups.
  multiTenant: false
})

export default buildConfig({
  plugins: [
    agentPlugin({
      // ...existing options
      onRunCompleted: metrics.onRunCompleted
    }),
    metrics
  ]
})

Renders the dashboard anywhere in your Payload admin (or any React app):

'use client'
import { LlmUsageDashboard } from '@zetesis/payload-agents-metrics/client'

export default function Page() {
  return <LlmUsageDashboard basePath="/api/metrics" />
}

Entry Points

| Subpath | Description | |---------|-------------| | . | Plugin factory, hook factory, collection, endpoints, query/pricing helpers | | ./client | <LlmUsageDashboard /> React component and related types |

Exports

Main (@zetesis/payload-agents-metrics)

  • metricsPlugin — Plugin factory. Returns a Plugin with an extra onRunCompleted property ready to wire into agentPlugin.
  • createOnRunCompleted — Lower-level factory if you need to build the hook manually.
  • calculateLlmCost / normalizeProvider — Pricing utilities, extensible via extraPricing.
  • Types: MetricsPluginConfig, ResolvedMetricsConfig, AccessResult, AggregateFilters, BucketRow, SeriesRow, Totals, SessionFilters, SessionRow, SessionsResult, SessionTotals, GroupBy.

Client (@zetesis/payload-agents-metrics/client)

  • LlmUsageDashboard — Filter-aware dashboard with KPI cards, day series, top-by-cost chart, per-dimension bucket table, and a sessions side panel.
  • Types: LlmUsageDashboardProps, BucketRow, SeriesRow, SessionRow, GroupBy.

Architecture

What the plugin installs

  • Collection llm-usage-events: one row per completed run, indexed by completedAt, user, agent, model, provider, apiKeySource, conversationId. Read-only from the admin UI.
  • Endpoints under {basePath} (default /metrics):
    • GET /aggregate — totals, paginated buckets, top-by-cost, day series.
    • POST /ingest — authenticated batch ingest (1–100 events).
    • GET /sessions — conversation list with per-session totals.
    • GET /session — conversation detail, pulling the full transcript from agno.agno_sessions.

Data flow

Agent runs a model
    -> agent-runtime emits SSE
    -> @zetesis/payload-agents-core captures `RunCompleted`
    -> metrics `onRunCompleted` creates an llm-usage-events row
    -> /metrics/* endpoints read and aggregate
    -> <LlmUsageDashboard /> renders

Security model

  • The collection is read-only from the admin; writes happen only via the hook or /ingest with x-internal-secret.
  • In multi-tenant mode, reads are scoped to the tenants returned by checkAccess. The plugin uses the multi-tenant Payload plugin convention: the tenant relationship is injected externally by your multi-tenant plugin, not by this one.
  • conversationId → session detail is double-checked: a tenant-scoped user must own at least one event for the requested conversation before the plugin exposes the Agno transcript.

Configuration

Full shape lives in MetricsPluginConfig but the common options are:

| Option | Default | Purpose | |--------|---------|---------| | multiTenant | true | Whether to scope everything by tenant. When false, the collection has no tenant field and endpoints skip tenant filters. | | checkAccess | () => ({ allTenants: true }) | Decide what the current user can read. Required when multiTenant is true. | | resolveTenantId | () => null | Resolve the tenant id for a user when persisting an event. Required when multiTenant is true. | | basePath | '/metrics' | Endpoint prefix. | | ingestSecret | process.env.AGNO_INTERNAL_SECRET ?? 'dev' | Shared secret required by POST /ingest. | | collectionSlug | 'llm-usage-events' | Override the Payload collection slug. | | extraPricing | {} | Extend or override the built-in model price table. | | agnoSessionsTable | 'agno.agno_sessions' | Fully-qualified Agno sessions table used by session detail and first-message previews. |

Cost calculation

Model prices live in src/lib/cost-calculator.ts as USD per token. The plugin applies the table server-side on every event (unless the caller passes a pre-computed costUsd to /ingest). To price custom or fine-tuned models, pass an extraPricing map that is merged over the built-in table:

metricsPlugin({
  extraPricing: {
    'my-fine-tune': { input: 1 / 1_000_000, output: 3 / 1_000_000 }
  }
})

Unknown models log a warning and record costUsd: 0.

License

MIT