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

@zanii/blackbox

v0.23.1

Published

The flight recorder for AI agents: sessions, a zero-loss spool, framework hooks, approvals, and offline verification of the gateway's hash-chained record.

Readme

@zanii/blackbox

The TypeScript SDK for Zanii Blackbox, the flight recorder for AI agents.

Blackbox records every model call and tool call your agent makes, for any industry and any organisation, from a gateway that runs outside the agent's process. The records are hash-chained, so an edit or a deletion shows, and anchored as receipts that anyone can verify offline. This SDK is optional. It adds what only the agent knows (steps, its own tools, its checks, the outcome) as a second, independent record, and it reads and verifies what the gateway recorded.

npm install @zanii/blackbox

Node.js 24 or later. ESM only.

Before you start

You need a running Blackbox gateway, self-hosted with Docker, Kubernetes or from source. A hosted UAE region is planned; write to [email protected] for early access. The gateway holds your provider keys. Your agent gets a session token instead, and its model calls go through the gateway:

export BLACKBOX_URL=https://blackbox.example.com
export BLACKBOX_ADMIN_KEY=...     # or a tenant key (bbxt_...)

Record a run

import Anthropic from "@anthropic-ai/sdk";
import { session } from "@zanii/blackbox";

const s = await session({
  url: process.env.BLACKBOX_URL!,
  adminKey: process.env.BLACKBOX_ADMIN_KEY!,
  label: "refund-agent",
  budgetUsd: "2.00",
  flightPlan: {
    objective: "Process today's refund queue",
    expected_tools: ["lookup_order", "issue_refund"],
  },
});

// Model calls go through the gateway with the session's token, never your provider key.
const anthropic = new Anthropic({ baseURL: `${process.env.BLACKBOX_URL}/anthropic`, apiKey: s.token });

s.step("load queue");
s.toolCall("lookup_order", { order: 8812 });
s.toolResult("lookup_order", { ok: true });
s.verify("amount-matches-invoice", true); // your own check, recorded as evidence

// A risky tool waits for a person, who sees the arguments in the cockpit.
const answer = await s.requestApproval("issue_refund", {
  args: { order: 8812, amount_aed: "1250.00" },
  reason: "Damaged on delivery",
});
if (answer === "approved") {
  // issue the refund
}

await s.close("success");

answer is only "approved" when a person approved it. "rejected", "timeout" and "error" all mean don't run the tool.

What the SDK guarantees

  • It never throws into your agent. If the gateway is down, the session keeps recording to disk and reports the problem in s.stats.lastError.
  • It loses nothing it accepted. Every event is written to a local spool before it is sent, numbered without gaps, and resent until the gateway confirms it. After a crash, blackbox drain sends what's left.
  • It stays out of the way. Recording is non-blocking with bounded memory. A recorded call costs about 0.3 ms (measured over 20,000 calls on a laptop); shipping happens in the background.
  • It has no other runtime dependencies besides the Zanii core libraries.

Hallucination controls

The gateway checks every record, with no model needed: an invented tool or ID, arguments a tool's schema refuses, "done" right after an error, and amounts, doses, dates and IDs in answers that nothing the agent was given holds. With your organisation's own reference packs (prices, fees, rules, limits) it also catches answers that contradict them, and your own grounding model and judge can plug in. A risky answer can be held for a person before your customer sees it.

From the SDK, pin what the agent read, then check an answer's signed credential anywhere:

import { verifyAnswerCredential, verifyCertificate } from "@zanii/blackbox";

s.retrieved([{ id: "returns-policy", version: "2026-10", content: policyText }]); // hashed here, never sent

// later, from GET /v1/sessions/:id/answers/:seq/credential and the session's record:
verifyCertificate(credential).ok;                       // signed by the gateway
verifyAnswerCredential(credential, lines, bodies, packs); // { ok, problems }: the record backs every claim

The same checks run offline as pure functions: toolHallucinations, groundingFindings, factsIn, loadReferencePacks, answerRisk, detectorAccuracy.

New in 0.15.0

  • M-of-N shares: splitSecret / combineShares, and blackbox key-split --m 3 --n 5 / blackbox key-combine, so no single custodian holds the gateway's key passphrase.
  • otlpFromProtobuf(bytes): OTLP/HTTP protobuf spans, read without a protobuf library (gateway v0.17 takes them on /v1/traces).
  • Works with gateway v0.17: the passphrase from Google Cloud KMS or Azure Key Vault, retention per tenant, closed-session summaries kept, the trace exported while a session runs.

New in 0.14.0

  • Price uplifts (uplifts in a price table): US-only inference, regional endpoints and fast modes priced above list, per deployment (upliftPercent).
  • Statements in any currency: the fx:<CUR>:<rate> unit, fxRate(currency) (the ECB's rate through Frankfurter), and blackbox statement --currency EUR with the rate, date and source in the statement.
  • Tax invoices for zero-rated and reverse-charge customers (vat_treatment).

New in 0.13.0

  • fromOtlp(body): OpenTelemetry spans (GenAI semconv or OpenInference) as session events, the mapping behind gateway v0.15's POST /v1/traces. Point any framework's OTLP exporter at the gateway with the session's token, and its spans join the record.

New in 0.12.0

  • Tax credit notes: taxCreditNote / renderTaxCreditNote, the document and printable copy behind gateway v0.14's POST /v1/invoices/:number/credit-notes.

New in 0.11.0

  • Facts against the record compare currencies and units: AED 500 in a tool result no longer grounds USD 500 in the answer, nor 500 g grounds 500 mg (currencyCodes, unitOf). Dates written with an English or Arabic month (3 March 2026, 3 مارس 2026) are facts too.
  • blackbox policy-hook: a Claude Code / Codex PreToolUse hook that asks the gateway's policy before a local tool runs, and fails closed.
  • Works with gateway v0.13 (POST /v1/sessions/:id/policy-check).

New in 0.10.0

  • setTenantPolicy / tenantPolicy / removeTenantPolicy: a tenant's own rules, hot on the gateway. setProviderKey / providerKeys / removeProviderKey: a tenant's own model keys, sealed. cancelRun(sessionId, runId): stop one run (calls carrying x-blackbox-run).
  • loadPolicy refuses an args_match that JavaScript and Python would read differently (portableRegexError).
  • blackbox sessions --outcome success|failure|abandoned.
  • Works with gateway v0.12: alert routing to PagerDuty, Teams, Alertmanager and Slack; the key passphrase from Vault or AWS KMS.

New in 0.9.0

  • client(...).createKey(tenantId, {scope: "approve", expires_in_days}): a key that only decides approvals (and labels findings), and keys that expire.
  • Works with gateway v0.11: Idempotency-Key kept in the database (shared by every instance), the admin audit log anchored on the ledger and naming the signed-in person, and BLACKBOX_APPROVALS_NEED_PERSON.

New in 0.8.0

  • blackbox drain --close (and drainSpools({close: true}) / drain_spools(close=True)): after shipping what a stopped agent left behind, each session is closed as abandoned.
  • Works with gateway v0.10: alerts signed as Standard Webhooks, tenant keys that expire, more identity-provider algorithms (PS256, ES384, EdDSA).

New in 0.7.0

  • Any number of serverless functions or workers can write one session at the same moment: a joined session sends its events unnumbered, each with an id, and a v0.9+ gateway numbers them in arrival order (a resend adds nothing).
  • The repeat-call detector counts within one turn: a chat assistant or support bot asked for the same lookup in separate messages isn't stopped as a loop. A real loop inside one task still is.

New in 0.6.0

  • Serverless: a session joined with its id and token in a fresh function (Vercel, Lambda, Cloud Run) numbers its events from the server's sdk_next, so none are lost. Join in each invocation and flush before returning.
  • Fewer false alarms: an ISO date-time (2026-10-03T09:30:00+04:00) in a tool's arguments is a date, not an invented number, and an MCP call carrying out the model's own tool call isn't flagged a second time for the same value.

New in 0.5.0

  • Held streams: open a session with holdStreams: true (or set BLACKBOX_HOLD_STREAMS=all on the gateway) and a risky streamed answer waits for a person, as a non-streamed one does. The client gets keep-alives, then the whole stream, or one error in the provider's own format.
  • session.checkAnswer(seq?): what in an answer would hold it ({seq, risks, hold}), for an app that streams by itself.

New in 0.4.0

  • Hallucination controls: the checks above, reference packs, answer credentials (answerClaims, answerCredential, verifyAnswerCredential), session.retrieved(), accuracy from people's labels (detectorAccuracy, Wilson bounds), the grounding and judge contracts, answerRisk for held answers.
  • Keyed redaction tokens (tokenFor, resolveTokens).
  • Evidence for payments, health and public services (payment, healthAccess, decision and their verifiers); provable agent memory (memoryChain); record badges, agent CVs, SLAs, ledger co-signing and the post-quantum binding.
  • Compliance reports in Arabic, and the hallucination-controls report (hallucinationFacts).

Frameworks

| Framework | Use | |---|---| | LangChain / LangGraph | blackboxCallbacks(s), blackboxAgentMiddleware(s), blackboxCheckpointer(saver, s), and blackboxHitl for human-in-the-loop | | OpenAI Agents SDK | attachBlackbox(runner, s) | | Claude Agent SDK | blackboxAgentHooks(s) | | Vercel AI SDK | blackboxMiddleware(s) | | Mastra | exporters: [blackboxMastraExporter(s)] in its observability config, and blackboxMiddleware(s, { toolCalls: false }) on the agent's model for the model-call ids | | Provider clients | wrapAnthropic, wrapOpenAI, wrapGemini, wrapBedrock link each call to the gateway's record |

Command line

The package installs a blackbox command:

blackbox sessions                     # the newest sessions, and whether each record verifies
blackbox tail ses_...                 # follow a session live
blackbox export ses_... --out run.json
blackbox verify run.json              # verify an audit bundle offline, anywhere
blackbox reconcile ...                # check an agent's own logs against the gateway's record
blackbox mcp-wrap --server files -- node server.js   # record a local stdio MCP server
blackbox drain                        # send spooled events left by a stopped agent

Verify a record offline

import { verifyBundle } from "@zanii/blackbox";

An audit bundle carries the events, the chain and the anchors. Checking it needs no account and no network, so an auditor or a regulator can check it independently.

Also in Python

zanii-blackbox has the same API in snake_case. Both SDKs must produce the same output on the same shared test vectors.

Support

Licensed under Apache-2.0.