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

@lazaruseth/agreement-guard

v0.1.1

Published

Agreement Guard SDK - Protect your AI agent's autonomy by capturing and validating agreements

Readme

@receipts/agreement-guard

Protect your AI agent's autonomy by capturing and validating every agreement before acceptance.

npm version TypeScript License: MIT

Why Agreement Guard?

When AI agents make purchases, book services, or sign up for accounts on behalf of users, they often accept terms of service without oversight. This creates risk:

  • Users don't know what their agent agreed to
  • Disputes become "he said, she said" without evidence
  • Agents can be blamed for anything without proof

Agreement Guard solves this by:

  1. Capturing every agreement with a timestamped receipt
  2. Analyzing terms for risky clauses (binding arbitration, no refunds, etc.)
  3. Validating against user-defined policies
  4. Building trust through a reputation system that unlocks more autonomy

Installation

npm install @receipts/agreement-guard
# or
yarn add @receipts/agreement-guard
# or
pnpm add @receipts/agreement-guard

Quick Start

import { AgreementGuard } from '@receipts/agreement-guard';

const guard = new AgreementGuard({
  agentId: 'my-agent-123',
  agentType: 'custom',
  apiKey: process.env.RECEIPTS_API_KEY, // Optional for demo mode
});

// Before accepting any terms of service
const result = await guard.capture({
  documentText: termsOfServiceText,
  sourceUrl: 'https://merchant.com/terms',
  merchantName: 'Acme Corp', // Optional, will be inferred
});

if (result.recommendation === 'proceed') {
  // Safe to accept - receipt captured
  console.log(`Captured: ${result.captureId}`);
  console.log(`Trust score: ${result.trustScore}/100`);
} else if (result.recommendation === 'require_approval') {
  // Ask user for explicit approval
  console.log('Human approval required:', result.agentMessage);
} else {
  // Blocked - do not accept
  console.log('Agreement blocked:', result.violations);
}

Framework Integrations

Claude/Anthropic

import Anthropic from '@anthropic-ai/sdk';
import { AgreementGuard } from '@receipts/agreement-guard';
import { ClaudeAdapter } from '@receipts/agreement-guard/adapters/claude';

const guard = new AgreementGuard({
  agentId: 'claude-shopping-agent',
  agentType: 'claude-code',
  apiKey: process.env.RECEIPTS_API_KEY,
});

const adapter = new ClaudeAdapter(guard);
const anthropic = new Anthropic();

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  system: adapter.getSystemPrompt(),
  tools: [adapter.getToolDefinition()],
  messages: [{ role: 'user', content: 'Book me a flight to NYC' }],
});

// Handle tool_use blocks
for (const block of response.content) {
  if (block.type === 'tool_use' && block.name === 'agreement_guard') {
    const result = await adapter.execute(block.input);
    // Use result.recommendation to decide next steps
  }
}

OpenAI Assistants

import OpenAI from 'openai';
import { AgreementGuard } from '@receipts/agreement-guard';
import { OpenAIAdapter } from '@receipts/agreement-guard/adapters/openai';

const guard = new AgreementGuard({
  agentId: 'openai-shopping-assistant',
  agentType: 'openai-assistants',
  apiKey: process.env.RECEIPTS_API_KEY,
});

const adapter = new OpenAIAdapter(guard);
const openai = new OpenAI();

// Create an assistant with the tool
const assistant = await openai.beta.assistants.create({
  name: 'Shopping Assistant',
  instructions: adapter.getSystemPrompt(),
  model: 'gpt-4-turbo',
  tools: [adapter.getAsToolDefinition()],
});

// Handle function calls in runs
async function handleToolCall(toolCall) {
  if (toolCall.function.name === 'capture_agreement') {
    const args = OpenAIAdapter.parseArguments(toolCall.function.arguments);
    const result = await adapter.execute(args);
    return adapter.formatFunctionResult(result);
  }
}

LangChain

import { ChatOpenAI } from '@langchain/openai';
import { AgentExecutor, createOpenAIToolsAgent } from 'langchain/agents';
import { AgreementGuard } from '@receipts/agreement-guard';
import { AgreementGuardTool } from '@receipts/agreement-guard/adapters/langchain';

const guard = new AgreementGuard({
  agentId: 'langchain-agent',
  agentType: 'langchain',
  apiKey: process.env.RECEIPTS_API_KEY,
});

const agreementTool = new AgreementGuardTool(guard);

const llm = new ChatOpenAI({ modelName: 'gpt-4-turbo' });

const agent = await createOpenAIToolsAgent({
  llm,
  tools: [agreementTool],
  prompt: yourPromptTemplate,
});

const executor = new AgentExecutor({
  agent,
  tools: [agreementTool],
});

API Reference

AgreementGuard

Main class for interacting with the RECEIPTS API.

Constructor

new AgreementGuard(config: AgreementGuardConfig)

| Option | Type | Required | Description | |--------|------|----------|-------------| | agentId | string | Yes | Unique identifier for your agent | | agentType | AgentType | Yes | Type of agent ('claude-code', 'openai-assistants', 'langchain', 'custom') | | apiKey | string | No | RECEIPTS API key (demo mode if not provided) | | baseUrl | string | No | API URL (defaults to production) | | userId | string | No | User ID for policy lookup | | debug | boolean | No | Enable verbose logging | | timeout | number | No | Request timeout in ms (default: 30000) |

Methods

capture(options: CaptureOptions): Promise<CaptureResult>

Capture and validate an agreement.

const result = await guard.capture({
  documentText: 'Full text of terms...',
  sourceUrl: 'https://example.com/terms',
  merchantName: 'Example Corp', // Optional
});
getReputation(): Promise<ReputationResult>

Get the agent's current trust score and capabilities.

const reputation = await guard.getReputation();
console.log(`Trust score: ${reputation.trustScore}/100`);
console.log(`Tier: ${reputation.tier.name}`);
console.log(`Max spend: $${reputation.capabilities.maxSpendPerTx}`);
anchor(captureId: string, termsHash: string): Promise<AnchorResult>

Anchor an agreement on Base L2 for immutable proof. Requires trust score >= 61.

const anchor = await guard.anchor(result.captureId, result.termsHash);
console.log(`Transaction: ${anchor.explorerUrl}`);
validate(pao: unknown): Promise<ValidateResult>

Validate a PAO against policy without capturing.

register(): Promise<RegistrationResult>

Register the agent with RECEIPTS (called automatically on first capture).

heartbeat(): Promise<{ ok: boolean; latencyMs: number }>

Health check for the API connection.

Types

CaptureResult

interface CaptureResult {
  success: boolean;
  captureId: string;
  documentHash: string;
  timestamp: string;
  recommendation: 'proceed' | 'require_approval' | 'block';
  termsHash?: string;
  riskFlags: string[];
  summary: string;
  violations: Array<{ rule: string; severity: 'block' | 'warn'; description: string }>;
  warnings: Array<{ type: string; description: string; recommendation: string }>;
  agentMessage: string;
  trustScore: number;
  capabilities: {
    maxSpendPerTx: number;
    allowedCategories: string[];
    requiresHumanApproval: string[];
    canAnchorOnchain: boolean;
  };
}

Trust Score System

Agents build trust through good behavior:

| Action | Points | |--------|--------| | Agreement captured | +1 | | Passes policy validation | +2 | | Dispute won with evidence | +5 | | Daily activity | +0.1 | | Risky agreement accepted without approval | -5 | | Dispute lost | -10 |

Trust Tiers

| Tier | Score | Max Spend/Tx | Capabilities | |------|-------|--------------|--------------| | New Agent | 0-20 | $10 | Manual approval required | | Emerging Agent | 21-40 | $50 | Some auto-approvals | | Active Transactor | 41-60 | $200 | Most categories auto-approved | | Verified Operator | 61-80 | $500 | On-chain anchoring unlocked | | Trusted Delegate | 81-100 | $1000 | Near-full autonomy |

Error Handling

The SDK provides typed errors for different failure scenarios:

import {
  AgreementGuardError,
  AuthenticationError,
  ValidationError,
  NetworkError,
  RateLimitError,
  TrustScoreError,
} from '@receipts/agreement-guard';

try {
  await guard.anchor(captureId, termsHash);
} catch (error) {
  if (error instanceof TrustScoreError) {
    console.log(`Need trust score ${error.requiredScore}, have ${error.currentScore}`);
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited, retry in ${error.retryAfterMs}ms`);
  } else if (error instanceof AuthenticationError) {
    console.log('Invalid API key');
  }
}

Static Utilities

// Detect if a page looks like terms of service
const isAgreement = AgreementGuard.detectAgreementPage(html, url);

// Extract text from HTML
const text = AgreementGuard.extractText(html);

System Prompt

Include this in your agent's system prompt for best results:

import { AGREEMENT_GUARD_SYSTEM_PROMPT } from '@receipts/agreement-guard';

const systemPrompt = `
You are a helpful shopping assistant.

${AGREEMENT_GUARD_SYSTEM_PROMPT}
`;

Demo Mode

Without an API key, the SDK runs in demo mode with mock responses. This is useful for development and testing.

License

MIT - see LICENSE

Links