Package Exports
- @agentlair/telemetry
- @agentlair/telemetry/anthropic
- @agentlair/telemetry/mastra
- @agentlair/telemetry/query
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