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

risicare

v0.6.0

Published

AI agent observability and error diagnosis for Node.js — trace LLM calls, detect errors, get AI-generated fix suggestions

Readme

risicare

AI agent observability and error diagnosis for Node.js and TypeScript.

npm version npm downloads TypeScript License: MIT

Monitor your AI agents in production. Trace every LLM call, detect errors automatically, and get AI-generated fix suggestions — with 3 lines of setup.

Quickstart

npm install risicare
import { init, agent, shutdown } from 'risicare';
import { patchOpenAI } from 'risicare/openai';
import OpenAI from 'openai';

// 1. Initialize
init({
  apiKey: 'rsk-...',
  endpoint: 'https://app.risicare.ai',
});

// 2. Patch your LLM client
const openai = patchOpenAI(new OpenAI());

// 3. Wrap your agent — all LLM calls inside are traced automatically
const myAgent = agent({ name: 'research-agent' }, async (query: string) => {
  const response = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: [{ role: 'user', content: query }],
  });
  return response.choices[0].message.content;
});

// Run it — traces appear in your dashboard within seconds
const result = await myAgent('What is quantum computing?');
await shutdown();

That's it. Your agent's LLM calls, latency, token usage, and costs now appear in the Risicare dashboard.

Prompt content is NOT captured by default

Since 0.5.1, traceContent defaults to false. Your prompts and completions stay in your process. Everything else — model, token counts, latency, cost, message roles, errors, and any attributes you set — is captured as normal, so the dashboard, cost tracking and error diagnosis all work unchanged.

To send prompt and completion text as well, opt in:

init({ apiKey: 'rsk-...', traceContent: true });
// or set RISICARE_TRACE_CONTENT=true

Upgrading from 0.5.0 or earlier? This is a behaviour change: content that used to be sent is no longer sent unless you opt in. In those versions the flag also did not work for content you set by hand — traceContent: false did not stop a span.setAttribute('gen_ai.prompt.0.content', ...) from reaching us. Both are fixed together.

When capture is off, content-bearing attributes are replaced with <risicare:content-omitted> rather than removed, so "no prompt was sent" stays distinguishable from "capture is off".

If you want content captured but redacted first, use the mask hook — it is independent of this switch and runs on every content-bearing field before export:

init({ apiKey: 'rsk-...', traceContent: true, mask: (key, value) => value });

Features

  • 12 LLM providers — OpenAI, Anthropic, Google, Mistral, Groq, Cohere, Together, Ollama, HuggingFace, Cerebras, Bedrock, Vercel AI
  • 4 framework integrations — LangChain, LangGraph, Instructor, LlamaIndex
  • Error Diagnosis (beta) — LLM-powered root cause analysis with fix suggestions; auto-apply not yet wired (see "Error Diagnosis" section below)
  • Evaluation scores — Rate agent quality with score() and 13 built-in scorers
  • Streaming supporttracedStream() for async iterator tracing
  • Context propagation — Automatic across async/await, Promise, setTimeout, EventEmitter
  • Zero runtime dependencies — No bloat in your node_modules
  • Dual CJS/ESM — Works with require() and import
  • Full TypeScript — Strict types and IntelliSense out of the box
  • Non-blocking — Async batch export with circuit breaker and retry
  • Zero overhead when disabled — Frozen NOOP_SPAN singleton, no allocations

LLM Providers

import { patchOpenAI } from 'risicare/openai';
import { patchAnthropic } from 'risicare/anthropic';
import { patchGoogle } from 'risicare/google';
// ... and 9 more

const openai = patchOpenAI(new OpenAI());
// Every call is now traced — model, tokens, latency, cost

All 12 providers:

openai · anthropic · google · mistral · groq · cohere · together · ollama · huggingface · cerebras · bedrock · vercel-ai

Framework Integrations

// LangChain
import { RisicareCallbackHandler } from 'risicare/langchain';
const handler = new RisicareCallbackHandler();
await chain.invoke(input, { callbacks: [handler] });

// LangGraph
import { instrumentLangGraph } from 'risicare/langgraph';
const tracedGraph = instrumentLangGraph(compiledGraph);

// Instructor
import { patchInstructor } from 'risicare/instructor';
const client = patchInstructor(instructor);

// LlamaIndex
import { RisicareLlamaIndexHandler } from 'risicare/llamaindex';

Core API

import {
  init, shutdown,                         // Lifecycle
  agent, session,                         // Identity & grouping
  traceThink, traceDecide, traceAct,      // Decision phases
  reportError, score,                     // Diagnosis & evaluation
  tracedStream,                           // Streaming
} from 'risicare';

init({ apiKey, endpoint })                // Initialize SDK
agent({ name }, fn)                       // Wrap function with agent identity
session({ sessionId, userId }, fn)        // Group traces into user sessions
// These are WRAPPER FACTORIES: they return a function you then call.
await traceThink('analyze', async () => {...})()   // note the trailing ()
await traceDecide('choose', async () => {...})()
await traceAct('execute', async () => {...})()
reportError(error)                        // Report caught errors for diagnosis
score(traceId, 'quality', 0.92)           // Record evaluation score [0.0-1.0]
tracedStream(asyncIterable, 'stream')     // Trace async iterators
await shutdown()                          // Flush pending spans and close

Error Diagnosis

Beta status (2026-05): detect → diagnose → suggest is shipped and runs against Together.AI Llama-3.3-70B with a circuit-breaker / template-only fallback. Suggested fixes land in your dashboard as status=draft for human review. Automatic deployment, A/B rollout, and learning-from-outcomes (stages 4–6 in our docs) are in development and not yet wired in production. Treat this as AI-assisted error diagnosis today; auto-apply will follow.

When your agent fails, Risicare:

  1. Classifies the error (154 codes across TOOL, MEMORY, REASONING, OUTPUT, etc.)
  2. Diagnoses the root cause using AI analysis
  3. Generates a fix suggestion you can review in the dashboard and apply manually
try {
  await myAgent(input);
} catch (error) {
  reportError(error); // Triggers diagnosis pipeline; fix lands as draft for review
}

Decision Phases

Structure your traces to see how your agent thinks, decides, and acts:

// traceThink / traceDecide / traceAct RETURN A WRAPPED FUNCTION — they do not
// run your callback themselves. Call the result (the trailing `()` below).
// Omitting it is silent: you get a function back, your callback never runs,
// and no span is emitted.
const myAgent = agent({ name: 'planner', role: 'coordinator' }, async (input) => {
  const analysis = await traceThink('analyze', async () => {
    return await openai.chat.completions.create({ /* ... */ });
  })();

  const decision = await traceDecide('choose-action', async () => {
    return pickBestAction(analysis);
  })();

  return await traceAct('execute', async () => {
    return executeAction(decision);
  })();
});

Sessions

Group traces from the same user conversation:

const result = await session(
  { sessionId: 'sess-abc123', userId: 'user-456' },
  () => myAgent(userMessage)
);

Known limitation — span loss during a backend outage

The SDK does not currently survive a sustained outage of the Risicare backend, and the loss is silent to your application (it is warned about, but nothing throws and flush() will not fail your request path).

The HTTP exporter opens a circuit breaker after 5 consecutive failed export calls and holds it open for 60 seconds, returning failure immediately without touching the network. Queued spans get 3 re-queue attempts, which against an open breaker resolve in microseconds — so they are dropped — and for the remainder of the cooldown the SDK will not retry even after your backend is healthy again.

Measured, for a 1,000-span cohort emitted during the outage: 4 s → all delivered; 5 s → half; 6 s and beyond → none. The thresholds are counted in failed calls, not seconds — where the 5th consecutive failure falls in wall-clock time depends on your span rate and on how fast your endpoint fails.

Nothing is lost on a clean shutdown(), and short blips that stay under the 5-failure threshold are fully survivable. Tracked as F-SDKBLIP-001.

A note on running without an API key

If tracing is enabled but no API key is configured, the SDK emits a one-time console.warn and drops the spans. It deliberately does not print span payloads to your console: the SDK performs no redaction of its own, so printing would put prompts, completions and anything else in your attributes onto your stderr. If you want console output for local development, pass debug: true explicitly.

Requirements

  • Node.js 18+
  • TypeScript 5.0+ (optional, types included)

Documentation

Support

During the public beta, please file detailed reproduction steps for any SDK or platform issue — fast feedback shapes GA.

License

MIT