@agentlair/telemetry
v0.1.1
Published
Drop-in behavioral telemetry for AI agents. 3-line integration, local SQLite storage, framework-agnostic.
Maintainers
Readme
@agentlair/telemetry
Drop-in behavioral telemetry for AI agents. 3-line integration, local SQLite storage, framework-agnostic.
Not governance. Not blocking. Pure observability. This is the sensor layer that feeds AgentLair's trust scoring.
Quick Start
import { telemetry } from '@agentlair/telemetry';
await telemetry.start({ agent: 'my-agent' });
// That's it — HTTP calls are auto-instrumented, events stored in local SQLiteWhat It Captures
| Category | Examples |
|----------|----------|
| tool_call | Tool invocations with input/output/duration |
| llm_request / llm_response | Model calls, token usage, latency |
| http_request | All fetch() calls (auto-instrumented) |
| file_write / file_read | File system operations |
| error | Failures with stack context |
| agent_start / agent_stop | Session lifecycle |
Installation
npm install @agentlair/telemetry
# or
bun add @agentlair/telemetrySQLite storage works out of the box with Bun. For Node.js, install better-sqlite3:
npm install better-sqlite3Manual Instrumentation
import { telemetry } from '@agentlair/telemetry';
await telemetry.start({ agent: 'researcher' });
// Instrument any async operation
const results = await telemetry.instrument('tool_call', 'web_search', async () => {
return await searchWeb(query);
}, { input: query });
// Record custom events
await telemetry.record({
category: 'custom',
action: 'decision',
success: true,
metadata: { reason: 'switching strategy' },
});
// Query and analyze
const stats = await telemetry.stats();
console.log(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
console.log('Top tools:', stats.topActions);
// Cleanup
await telemetry.stop();Framework Adapters
Anthropic SDK
import Anthropic from '@anthropic-ai/sdk';
import { instrumentAnthropicClient } from '@agentlair/telemetry/anthropic';
const client = instrumentAnthropicClient(new Anthropic(), { agent: 'researcher' });
// Use normally — telemetry is automatic
const msg = await client.messages.create({
model: 'claude-opus-4-5',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
// Access telemetry data
const stats = await client.telemetry.stats();Mastra
import { Agent } from '@mastra/core';
import { withTelemetry } from '@agentlair/telemetry/mastra';
const agent = withTelemetry(
new Agent({ name: 'researcher', tools: { ... } }),
{ agent: 'researcher' },
);
// Or use middleware
import { telemetryMiddleware } from '@agentlair/telemetry/mastra';
const agent = new Agent({
middleware: [telemetryMiddleware({ agent: 'researcher' })],
});Generic (Any Framework)
import { TelemetryCollector } from '@agentlair/telemetry';
const collector = new TelemetryCollector({ agent: 'my-agent' });
await collector.start();
// Wrap your agent's tool execution
async function executeTool(name: string, input: unknown) {
return collector.instrument('tool_call', name, async () => {
return await tools[name].execute(input);
}, { input });
}Querying Telemetry
import { queryTelemetry, queryStats } from '@agentlair/telemetry/query';
// Find slow tool calls
const slow = await queryTelemetry({
category: 'tool_call',
minDurationMs: 5000,
});
// Get error stats for the last hour
const stats = await queryStats({
after: new Date(Date.now() - 3600_000).toISOString(),
});Storage Backends
SQLite (default)
import { SQLiteStorage } from '@agentlair/telemetry';
await telemetry.start({
agent: 'my-agent',
storage: new SQLiteStorage({ path: './my-telemetry.db', maxEvents: 50_000 }),
});In-Memory
import { MemoryStorage } from '@agentlair/telemetry';
await telemetry.start({
agent: 'my-agent',
storage: new MemoryStorage(),
});AgentLair Cloud Sync
Local-first with async cloud upload:
import { SQLiteStorage, AgentLairSync } from '@agentlair/telemetry';
await telemetry.start({
agent: 'my-agent',
storage: new AgentLairSync({
local: new SQLiteStorage(),
apiKey: process.env.AGENTLAIR_API_KEY!,
}),
});Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| agent | string | required | Agent name/identifier |
| sessionId | string | auto-generated | Session identifier |
| storage | StorageBackend | SQLite (or Memory) | Storage backend |
| apiKey | string | - | AgentLair API key for cloud sync |
| bufferSize | number | 100 | Events buffered before flush |
| flushIntervalMs | number | 5000 | Auto-flush interval |
| console | boolean | false | Print events to console |
| instrumentFetch | boolean | true | Auto-instrument global fetch |
| maxSummaryLength | number | 200 | Max chars for input/output |
Privacy
- Input/output values are truncated to
maxSummaryLength(default 200 chars) - No raw prompts or completions stored by default
- Local SQLite storage — your data stays on your machine
- Cloud sync is opt-in and uses your AgentLair API key
License
MIT
