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

@tenzro/ai

v0.4.15

Published

Tenzro AI SDK — discover and run inference across Tenzro Network's decentralized AI providers. Cutting-edge TypeScript developer experience with TDIP identity, TNZO payment, and verifiable responses (TEE attestation, Plonky3 STARK).

Readme

@tenzro/ai

Core SDK for inference on Tenzro Network's decentralized AI providers.

A thin, ergonomic facade over the node's multi-modal inference RPCs (chat, embeddings, vision, forecast, segmentation, detection, audio, video) with TDIP identity, TNZO payment, and verifiable responses (TEE attestation, Plonky3 STARK proofs).

npm install @tenzro/ai
# or
pnpm add @tenzro/ai

Quick start

import { generateText, tenzro } from '@tenzro/ai';

const { text } = await generateText({
  model: tenzro('llama-3.3-70b'),
  prompt: 'What is post-quantum cryptography?',
});

That's it — no API key, no identity setup. Calls without a signer run faucet-tier against https://rpc.tenzro.network.

Top-level functions

| Function | Modality | Returns | |---|---|---| | generateText | chat | { text, reasoning, usage, finishReason, toolCalls, receipts } | | streamText | chat | { stream, text, reasoning, usage, finishReason, toolCalls, receipts } | | generateObject<T> | chat (structured) | { object: T, usage, finishReason, receipts } | | streamObject<T> | chat (structured) | { partialObjectStream, object, usage, finishReason, receipts } | | embed | text-embedding | { data: { embeddings, dim }, vector, receipts } | | embedImage | vision | { data: { embedding, dim }, receipts } | | imageTextSimilarity | vision | { data: { similarity }, receipts } | | forecast | timeseries | { data: { forecast, quantiles? }, receipts } | | segment | segmentation | { data: { masks }, receipts } | | detect | detection | { data: { detections }, receipts } | | transcribe | audio (ASR) | { data: { text, segments }, receipts } | | embedVideo | video | { data: { embedding }, receipts } |

Every function accepts the same base options (model, signer, payment, routing, verify, abortSignal, requestTimeoutMs, maxRetries).

Streaming

import { streamText, tenzro } from '@tenzro/ai';

const { stream } = streamText({
  model: tenzro('llama-3.3-70b'),
  messages: [
    { role: 'user', parts: [{ type: 'text', text: 'Write a haiku.' }] },
  ],
});

for await (const part of stream) {
  if (part.type === 'text-delta') process.stdout.write(part.text);
}

stream is AsyncIterable<TenzroStreamPart>. Discriminated union covers text-delta, reasoning-delta, tool-call, tool-call-delta, tool-result, source, tenzro-attestation, tenzro-zk-proof, tenzro-payment-receipt, finish, error.

Identity + payment

Tenzro has no API keys. Identity is a TDIP DID with hybrid Ed25519 + ML-DSA-65 signing; payment is per-call.

import { generateText, tenzro, InMemorySigner } from '@tenzro/ai';
import { randomBytes } from 'node:crypto';

const signer = new InMemorySigner({
  did: 'did:tenzro:human:01HZA...',
  ed25519Seed: randomBytes(32),
  mlDsa65Seed: randomBytes(32),
});

const { text, receipts } = await generateText({
  model: tenzro('llama-3.3-70b', { strategy: 'reputation', requireTee: 'tdx' }),
  prompt: 'Summarize this contract.',
  signer,
  payment: { protocol: 'auto', maxPrice: { amount: 1_000n, currency: 'TNZO' } },
});

// receipts.payment is set when the call settled against a paid provider.
// receipts.attestation is set when the provider attached TEE attestation.

payment.protocol: 'auto' lets the SDK negotiate x402 / MPP / micropayment-channel based on the provider's HTTP 402 challenge. Apps that want to lock the protocol can pass 'x402', 'mpp', or 'channel' directly.

The SDK never holds funds. Wallet implementations (e.g. tenzro-wallet) provide a Signer that signs payment authorizations alongside the inference preimage.

Verification

Provider responses can carry TEE attestations and Plonky3 STARK proofs. They're opt-in:

import { generateText, tenzro, verifyAttestation, verifyZkProof } from '@tenzro/ai';

const result = await generateText({
  model: tenzro('llama-3.3-70b', { requireTee: 'tdx' }),
  prompt: 'Hello.',
  verify: 'tee', // 'off' | 'tee' | 'zk' | 'all'
});

if (result.receipts.attestation) {
  await verifyAttestation(result.receipts.attestation);
}
if (result.receipts.zkProof) {
  await verifyZkProof(result.receipts.zkProof);
}

verify: 'tee' makes attestation verification a hard precondition (the call throws AttestationFailedError if verification fails). verify: 'off' (the default) leaves the receipt on the result for the caller to verify out-of-band.

Multi-modal

import { embed, embedImage, forecast, transcribe, tenzro } from '@tenzro/ai';
import fs from 'node:fs/promises';

// Text embedding
const e = await embed({
  model: tenzro('qwen3-embedding-0.6b'),
  input: 'hello world',
});
console.log(e.vector); // number[]

// Image embedding
const png = await fs.readFile('./photo.png');
const ie = await embedImage({
  model: tenzro('siglip2-base'),
  image: png,
});

// Timeseries forecast
const f = await forecast({
  model: tenzro('chronos-bolt-base'),
  history: [/* historical points */],
  horizon: 24,
});

// Audio transcription
const wav = await fs.readFile('./speech.wav');
const t = await transcribe({
  model: tenzro('whisper-large-v3-turbo'),
  audio: wav,
});

All modalities share the same { data, receipts, raw } envelope and accept the same identity/payment/verify base options.

Agent loop

Agent runs an OpenAI-compatible tool-calling loop. Tool execution is caller-owned code; the only network calls per step are generateText.

import { Agent, tool, stepCountIs, tenzro } from '@tenzro/ai';
import { z } from 'zod';

const agent = new Agent({
  model: tenzro('llama-3.3-70b'),
  tools: {
    getWeather: tool({
      description: 'Get the current weather for a city.',
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => {
        const res = await fetch(`https://api.example.com/wx?city=${city}`);
        return res.json();
      },
    }),
  },
  stopWhen: [stepCountIs(5)],
});

const { text, steps, stopReason } = await agent.run({
  prompt: 'What is the weather in Tokyo and Berlin? Compare them.',
});

Tools that need approval gates expose a needsApproval(input) predicate; bind an approve callback on the agent (or on the run) to handle confirmation.

Direct provider access (advanced)

The default tenzro() flow does discovery + routing + failover. Apps that already know which provider to hit can skip discovery:

import { discoverProviders, generateText } from '@tenzro/ai';

const providers = await discoverProviders({ modality: 'chat' });
const ranked = providers.filter((p) => p.reputation > 700);

const { text } = await generateText({
  providers: ranked,
  prompt: 'Hello.',
});

Stable subpaths

import type { TenzroProvider, UIMessage } from '@tenzro/ai/types';
import { TenzroAIError, RateLimitError } from '@tenzro/ai/errors';

The root '@tenzro/ai' re-exports everything — these subpaths are for callers that want a smaller surface.

Status

Pre-alpha. APIs may change without notice until 1.0.

License

Apache-2.0