← Vetro Attest

Quickstart

Every LLM call, tool call, cost and policy decision of your agent in a hash-chained, ed25519-signed ledger. One line of change, zero runtime dependencies in the core, Apache-2.0.

See a sample ledger verifiedFree Art. 12/14 checker

1. Install

npm i https://attest.piratefly.com/dl/vetro-core-0.1.0.tgz https://attest.piratefly.com/dl/vetro-anthropic-0.1.0.tgz   # Claude (Anthropic SDK)
npm i https://attest.piratefly.com/dl/vetro-core-0.1.0.tgz https://attest.piratefly.com/dl/vetro-openai-0.1.0.tgz      # OpenAI SDK
pip install https://attest.piratefly.com/dl/vetro-0.1.0-py3-none-any.whl                              # Python, both providers
npm i https://attest.piratefly.com/dl/vetro-core-0.1.0.tgz https://attest.piratefly.com/dl/vetro-vercel-ai-0.1.0.tgz   # Vercel AI SDK middleware
npm i https://attest.piratefly.com/dl/vetro-core-0.1.0.tgz https://attest.piratefly.com/dl/vetro-openai-agents-0.1.0.tgz # OpenAI Agents SDK tracer
npm i -g https://attest.piratefly.com/dl/vetro-cli-0.1.0.tgz                                         # the `vetro` command: verify, ls, show, diff

Straight from this server, zero runtime dependencies, same code as the repo. All packages (OpenTelemetry, policy, replay, LangChain, Vercel AI SDK, OpenAI Agents SDK): /dl/.

2. Record your agent

Node, Anthropic

import Anthropic from '@anthropic-ai/sdk';
import { Vetro } from '@vetro/core';
import { wrapAnthropic } from '@vetro/anthropic';

const run = new Vetro().startRun({ name: 'my-agent' });
const client = wrapAnthropic(new Anthropic(), run);   // the only change
// ... use client exactly as before ...
run.end();

Node, OpenAI

import OpenAI from 'openai';
import { Vetro } from '@vetro/core';
import { wrapOpenAI } from '@vetro/openai';

const run = new Vetro().startRun({ name: 'my-agent' });
const client = wrapOpenAI(new OpenAI(), run);
run.end();

Python (sync or async clients, streaming included)

import anthropic
from vetro import Vetro, wrap_anthropic   # or wrap_openai

run = Vetro().start_run(name="my-agent")
claude = wrap_anthropic(anthropic.Anthropic(), run)
claude.messages.create(model="claude-haiku-4-5", max_tokens=256,
                       messages=[{"role": "user", "content": "hi"}])
run.end()

The ledger lands in .vetro/runs/<run-id>.vtl, signed with a key kept in .vetro/.

Already on OpenTelemetry?

No SDK change needed. Export your GenAI spans as OTLP/JSON and paste the file on the verify box, or convert it locally:

vetro otel import trace.json --out-dir .vetro/imported   # OTel GenAI trace -> ledger
vetro otel export .vetro/runs/run.vtl -o trace.json      # and back

3. Verify, free

vetro verify .vetro/runs/*.vtl

Or drop the .vtl file on the home page: the chain and signatures are checked, and you see which EU AI Act obligations the log covers. Nothing to sign up for.

4. Get it countersigned

When the ledger verifies, the page offers the EU AI Act record-keeping report: a third-party ed25519 countersignature over the digest, a PDF/Markdown report mapping the log to Art. 12, 14, 26 and 86, and a public link your auditor or customer can check in one click.

Verify a ledger and get the reportPricing

Pricing