Telemetry & cost
Log every call, price it, and get an admin dashboard for free.
Record calls
A TelemetryStore records each LLM and tool call. Wire it into the agent's monitor sink:
import { InMemoryTelemetryStore } from '@agentoria/telemetry';
const telemetry = new InMemoryTelemetryStore();
const agent = createAgent({
provider,
tools,
monitor: { operation: 'chat', provider: 'anthropic', model, sink: (m) => telemetry.recordLlmCall(m) },
});For production, @agentoria/telemetry/drizzle provides a DrizzleTelemetryStore over any Drizzle SQLite driver (Cloudflare D1, better-sqlite3, libSQL), with hand-authorable DDL in AGENTORIA_TELEMETRY_DDL.
Cost
@agentoria/usage prices any call from its token usage, cache-aware, across the full Claude and GPT lineups:
import { costOf, computeCost, resolvePricing } from '@agentoria/usage';
const usd = costOf(usage, 'claude-sonnet-4-6'); // by model name
const c = computeCost(usage, resolvePricing('gpt-4o')); // or an explicit pricing tableA createBudget helper enforces a spend ceiling across a run.
Stats
Pure aggregators turn records into dashboards — headline totals, success rate, latency distribution (p50/p95/p99), per-model / per-day / per-tool breakdowns, and fine-grained tool outcomes:
import { llmCallStats, toolCallStats, toolOutcomeCounts } from '@agentoria/telemetry';
const stats = llmCallStats(await store.listLlmCalls());
const tools = toolCallStats(await store.listToolCalls());
const outcomes = toolOutcomeCounts(await store.listToolCalls());At scale, llmCallStatsSql / toolCallStatsSql compute the same numbers with GROUP BY in the database (D1/libSQL) instead of loading rows — verified byte-identical against the in-memory aggregators.
The dashboard
Feed the stats straight into <MetricsDashboard/> (from @agentoria/ui) for the admin view — stat tiles, a cost + calls/errors trend, outcome pills, and per-model / per-tool tables:
import { MetricsDashboard, AgentoriaStyles } from '@agentoria/ui';
<>
<AgentoriaStyles />
<MetricsDashboard stats={stats} tools={tools} toolOutcomes={outcomes} />
</>For per-call debugging, <LlmCallLog/> renders an expandable log (metadata, tokens, TTFT, error) and <TraceTimeline/> shows a span waterfall of where a turn spent its time.