@sigil-telemetry/js-hook
v0.3.0
Published
Sigil telemetry hook for Node.js — auto-instruments LLM SDKs (OpenAI, Anthropic, Mistral, Bedrock, Google, Cohere)
Maintainers
Readme
@sigil-telemetry/js-hook
Sigil telemetry hook for Node.js — auto-instruments LLM SDKs to capture call telemetry and send it to your OTEL collector.
Installation
npm install @sigil-telemetry/js-hookQuick Start
Add two lines at the very top of your app's entry file — before any other imports:
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
// Your normal code below — telemetry is captured automatically
const OpenAI = require('openai');
const client = new OpenAI();
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello' }]
});TypeScript / ESM
import { init } from '@sigil-telemetry/js-hook';
init();
import OpenAI from 'openai';
// Telemetry is captured automaticallyEnvironment Variables
| Variable | Required | Description |
|---|---|---|
| SIGIL_AGENT_ID | Yes | Your agent's unique identifier |
| SIGIL_COLLECTOR_URL | Yes | Telemetry collector endpoint URL |
| SIGIL_ENVIRONMENT | No | production (default), staging, development |
| SIGIL_AGENT_VERSION | No | Your agent's version (default: 0.1.0) |
| SIGIL_USER_ID | No | Static user ID for worker agents with no HTTP context |
| SIGIL_DIVISION | No | Organizational division |
| SIGIL_RISK_CLASSIFICATION | No | Risk classification level |
| SIGIL_HOURS_SAVED | No | Estimated hours saved per use |
| SIGIL_CAPTURE_USER | No | Set to false to disable user identity capture |
| SIGIL_DEBUG | No | Set to true to log telemetry events to console |
Supported LLM SDKs
All auto-detected and patched — no configuration needed:
| SDK | Package | Methods Captured |
|---|---|---|
| OpenAI | openai (v4+) | chat.completions.create() |
| Anthropic | @anthropic-ai/sdk (v0.10+) | messages.create() |
| Mistral | @mistralai/mistralai (v1+) | chat.complete() |
| AWS Bedrock | @aws-sdk/client-bedrock-runtime (v3+) | send(ConverseCommand), send(InvokeModelCommand) |
| Google GenAI | @google/genai (v0.1+) | models.generateContent() |
| Google Vertex AI | @google-cloud/vertexai (v1+) | generateContent() |
| Cohere | cohere-ai (v7+) | chat(), generate() |
Vercel AI SDK
The Vercel AI SDK (ai package) uses ESM modules that can't be auto-patched. Use the wrapper instead:
const sigil = require('@sigil-telemetry/js-hook');
const { generateText } = require('ai');
sigil.init();
const generate = sigil.wrapGenerateText(generateText);
const result = await generate({ model: yourModel, prompt: 'Hello' });Azure OpenAI
Azure OpenAI users should use the openai package with Azure configuration — our OpenAI hook covers it automatically:
const OpenAI = require('openai');
const client = new OpenAI({
apiKey: process.env.AZURE_OPENAI_API_KEY,
baseURL: 'https://your-resource.openai.azure.com/openai/deployments/your-deployment',
});Web Framework Middleware
For web apps, add middleware to automatically extract user identity from Azure AD JWT tokens in the Authorization header.
Express / Connect
const express = require('express');
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
const app = express();
app.use(sigil.middleware());Fastify
const fastify = require('fastify')();
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
fastify.register(sigil.fastifyPlugin);Koa
const Koa = require('koa');
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
const app = new Koa();
app.use(sigil.koaMiddleware());Next.js API Routes
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
export default sigil.withSigil(async function handler(req, res) {
// your handler
});Hapi
const Hapi = require('@hapi/hapi');
const sigil = require('@sigil-telemetry/js-hook');
sigil.init();
const server = Hapi.server({ port: 3000 });
await server.register(sigil.hapiPlugin);NestJS
NestJS uses Express or Fastify under the hood — use the corresponding middleware above.
No Framework / CLI Agents
For non-HTTP agents, set the SIGIL_USER_ID environment variable or call sigil.setUser('[email protected]').
What It Captures
Every LLM call automatically captures:
- Provider — OpenAI, Anthropic, Mistral, AWS Bedrock, Google GenAI, Vertex AI, Cohere
- Model — gpt-4o, claude-sonnet-4-20250514, mistral-large-latest, etc.
- Token usage — input, output, total
- Latency — duration in milliseconds
- Status — success or error
- Finish reason — stop, length, tool_calls, etc.
- Tool calls — names and count
- Error details — type and message
- User identity — extracted from Azure AD JWT
- Agent metadata — ID, version, environment, division
How It Works
The hook monkey-patches LLM SDK methods before your code imports them. Every call is intercepted, timed, and telemetry is sent to the collector asynchronously. Your code sees zero difference — same request, same response, no added latency.
Each HTTP request gets its own isolated context via AsyncLocalStorage, so user identities never leak between concurrent requests.
If the collector is unavailable or the hook fails, your agent keeps working normally. Telemetry is fire-and-forget.
Data Pipeline
Telemetry events are sent to your OTEL collector and flow through your existing analytics pipeline automatically.
