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

@sentygent/sdk

v0.1.1

Published

Sentygent SDK for AI agent observability

Downloads

208

Readme

@sentygent/sdk

TypeScript SDK for Sentygent — AI Observability & Evaluation Platform.

Instrument your AI agents and pipelines to capture LLM calls, tool executions, RAG retrievals, and conversation lifecycle events. Works with any LLM provider.

Installation

npm install @sentygent/sdk

Peer Dependencies (optional)

Install only the SDKs you use for auto-instrumentation:

# For Anthropic auto-instrumentation
npm install @anthropic-ai/sdk

# For AWS Bedrock auto-instrumentation
npm install @aws-sdk/client-bedrock-runtime

Quick Start

import { SentygentClient } from '@sentygent/sdk';

const sentygent = new SentygentClient({
  apiKey: process.env.SENTYGENT_API_KEY!,
  agent: 'my-agent',
});

await sentygent.trace('conversation-123', async (span) => {
  span.captureLifecycle('conversation_start');
  // Your agent logic here...
  span.captureLifecycle('conversation_end');
});

Provider Support

Sentygent works with any LLM provider. The integration method depends on your provider:

| Provider | Method | What you get | |----------|--------|-------------| | Anthropic | instrumentAnthropic() — zero-code | Automatic capture of all messages.create and messages.stream calls | | AWS Bedrock | instrumentBedrock() — zero-code | Automatic capture of ConverseCommand, InvokeModelCommand + streaming variants | | OpenAI | span.captureLLM() — typed helper | You provide execute + extractUsage. SDK handles timing, errors, event structure | | Cohere, Mistral, Groq, Together, etc. | span.captureLLM() — typed helper | Same as OpenAI — works with any provider that returns token counts | | Ollama, vLLM, local models | span.captureLLM() — typed helper | extractUsage can return null if provider doesn't expose tokens. Timing still captured |

Auto-Instrumentation: Anthropic

Wrap the Anthropic client once. All LLM calls are captured automatically — model, tokens, cost, latency.

import Anthropic from '@anthropic-ai/sdk';
import { SentygentClient, instrumentAnthropic } from '@sentygent/sdk';

const sentygent = new SentygentClient({
  apiKey: process.env.SENTYGENT_API_KEY!,
  agent: 'my-agent',
});

const anthropic = instrumentAnthropic(new Anthropic(), sentygent);

// Use as normal — all calls are captured automatically
await sentygent.trace('conv-123', async () => {
  const message = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Hello!' }],
  });
});

Streaming is also supported:

await sentygent.trace('conv-123', async () => {
  const stream = anthropic.messages.stream({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    messages: [{ role: 'user', content: 'Tell me a story' }],
  });

  for await (const event of stream) {
    // Process stream events...
  }

  const message = await stream.finalMessage();
});

Auto-Instrumentation: AWS Bedrock

import { BedrockRuntimeClient, ConverseCommand } from '@aws-sdk/client-bedrock-runtime';
import { SentygentClient, instrumentBedrock } from '@sentygent/sdk';

const sentygent = new SentygentClient({
  apiKey: process.env.SENTYGENT_API_KEY!,
  agent: 'my-agent',
});

const bedrock = instrumentBedrock(
  new BedrockRuntimeClient({ region: 'eu-west-1' }),
  sentygent,
);

await sentygent.trace('conv-123', async () => {
  await bedrock.send(
    new ConverseCommand({
      modelId: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
      messages: [{ role: 'user', content: [{ text: 'Hello!' }] }],
    }),
  );
});

Typed Helper: Any Provider (OpenAI, Cohere, Mistral, Groq, etc.)

Use span.captureLLM() to capture calls to any LLM provider. You provide the execute function and a callback to extract token usage.

import OpenAI from 'openai';

const openai = new OpenAI();

await sentygent.trace('conv-123', async (span) => {
  span.captureLifecycle('conversation_start');

  const result = await span.captureLLM({
    provider: 'openai',
    model: 'gpt-4o',
    execute: () => openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: 'Hello!' }],
    }),
    extractUsage: (r) => ({
      promptTokens: r.usage?.prompt_tokens ?? 0,
      completionTokens: r.usage?.completion_tokens ?? 0,
    }),
    cost: 0.003, // Optional: pre-computed cost in euros (overrides pricing table)
  });

  span.captureLifecycle('conversation_end');
});

Provider values: 'anthropic', 'bedrock', 'openai', or 'other' for any unlisted provider.

If your provider doesn't expose token counts (e.g. some local models), return null from extractUsage:

await span.captureLLM({
  provider: 'other',
  model: 'llama-3-70b',
  execute: () => ollama.chat({ model: 'llama3', messages }),
  extractUsage: () => null, // Tokens unavailable — timing still captured
});

Capturing Tool Calls

await span.captureTool({
  name: 'web_search',
  input: { query: 'latest news' },
  execute: () => searchAPI.search('latest news'),
  tags: { step: 'search' }, // Optional dimensional tags
});

Capturing RAG / Retrieval

For RAG, vector search, or any retrieval step:

await span.captureRetrieval({
  provider: 'bedrock-kb',        // or 'pinecone', 'opensearch', etc.
  query: 'leadership styles',
  execute: () => knowledgeBase.retrieve(query),
  extractResults: (r) => ({
    resultsCount: r.chunks.length,
    relevantCount: r.chunks.filter(c => c.score >= 0.5).length,
    meanScore: avg(r.chunks.map(c => c.score)),
    topScore: Math.max(...r.chunks.map(c => c.score)),
  }),
  searchType: 'hybrid',           // Optional: 'semantic', 'keyword', 'hybrid'
  cost: 0.0001,                   // Optional: retrieval cost in euros
  tags: { courseId: 'lid-101' },   // Optional dimensional tags
});

Tags (Dimensional Metadata)

Tags let you segment metrics by any dimension: course, intent, pipeline step, model version, etc.

// Tags on individual events
await span.captureLLM({
  provider: 'anthropic',
  model: 'claude-sonnet-4-20250514',
  execute: () => anthropic.messages.create({ ... }),
  extractUsage: (r) => ({ ... }),
  tags: { step: 'classify', intent: 'chat' },
});

// Tags on spans (inherited by all events from that span)
const child = span.child('analysis', { tags: { step: 'analyze' } });
await child.captureLLM({ ... }); // inherits step=analyze

// Tags at trace level (inherited by all spans and events)
await sentygent.trace('conv-123', async (span) => { ... }, {
  tags: { courseId: 'liderazgo-101' },
});

Tags are visible in the dashboard trace view as pill badges on each event.


Request-Response Pipelines

For pipeline architectures where each HTTP request is a complete trace, use request() instead of trace(). It automatically emits conversation_start and conversation_end, which triggers quality scoring.

app.post('/api/chat', async (req, res) => {
  const answer = await sentygent.request(req.body.sessionId, async (span) => {
    // No need to manually emit conversation_start/end
    const intent = await span.captureLLM({ tags: { step: 'classify' }, ... });
    const chunks = await span.captureRetrieval({ ... });
    const response = await span.captureLLM({ tags: { step: 'generate' }, ... });
    return response;
  }, { tags: { courseId: req.body.courseId } });

  res.json(answer);
});

Multi-Agent Tracing

For systems where multiple agents collaborate in a single conversation:

const sentygent = new SentygentClient({ agent: 'orchestrator' });

await sentygent.trace('conv-123', async (span) => {
  span.captureLifecycle('conversation_start');

  // Sub-agent with different slug
  const searchSpan = span.child('search', { agent: 'search-agent' });
  await searchSpan.captureLLM({ ... });
  await searchSpan.captureTool({ ... });

  // Another sub-agent
  const analysisSpan = span.child('analysis', { agent: 'analysis-agent' });
  await analysisSpan.captureLLM({ ... });

  // Orchestrator composes final response
  await span.captureLLM({ ... });
  span.captureLifecycle('conversation_end');
});

The dashboard groups spans by agent with color-coded timeline and per-agent cost breakdown.


Child Spans

await sentygent.trace('conv-123', async (span) => {
  const child = span.child('planning-step');
  await child.captureLLM({ ... });

  const toolSpan = span.child('tool-execution');
  await toolSpan.captureTool({ ... });
});

Configuration

const sentygent = new SentygentClient({
  apiKey: 'snt_...',            // Required: your API key
  agent: 'my-agent',           // Required: registered agent slug
  environment: 'production',   // Default: 'production'
  endpoint: 'https://api.sentygent.com', // Default API endpoint
  flushInterval: 5000,         // Flush every 5s (default)
  maxBatchSize: 100,           // Events per batch (default)
  maxBufferSize: 10000,        // Max buffered events (default)
  retryAttempts: 3,            // Retry failed sends (default)
  debug: false,                // Enable debug logging
  disabled: false,             // Kill switch — disables all operations
});

Graceful Shutdown

The SDK registers beforeExit and SIGTERM handlers to flush remaining events. You can also call shutdown manually:

await sentygent.shutdown();

Error Handling

The SDK never throws from transport operations. If the API is unreachable after retries, a warning is logged and the SDK continues. Your application is never affected by SDK failures.

Troubleshooting

Events not appearing in dashboard:

  • Verify your API key is correct
  • Check that the agent slug matches a registered agent
  • Enable debug: true for detailed logging
  • Ensure shutdown() is called before process exit

High memory usage:

  • Reduce maxBufferSize if your agent generates many events
  • Reduce flushInterval to send events more frequently