# @h33/agent

Cryptographic attestation for AI agents, tools, and autonomous systems.

Every action your agent takes -- tool calls, LLM inferences, memory checkpoints, delegations -- gets a post-quantum attested receipt that anyone can independently verify. Zero dependencies. Works with MCP, LangChain.js, Vercel AI SDK, or plain TypeScript.

## Install

```bash
npm install @h33/agent
```

## Quick Start

```typescript
import { H33AgentClient, H33Session } from '@h33/agent';

// 1. Initialize
const h33 = new H33AgentClient(); // reads H33_API_KEY from env

// 2. Register agent
const agent = await h33.register({
  display_name: 'My Agent',
  canonical_name: 'h33.agent.myorg.myagent.prod.001',
  agent_type: 'autonomous',
  capabilities: ['execute', 'use_tools'],
  tenant_id: 'my-org',
});

// 3. Start session
const receipt = await h33.startSession({
  agent_id: agent.agent_id,
  duration_secs: 3600,
});
const session = new H33Session(h33, receipt);

// 4. Attest actions
await session.attestAction('api_call', 'Called weather API', inputHash);

// 5. Anyone can verify (no API key needed)
console.log(receipt.verification_url);

// 6. End session
await session.end();
```

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `H33_API_KEY` | Yes | Your H33 API key |

You can also pass `apiKey` directly to the constructor:

```typescript
const h33 = new H33AgentClient({ apiKey: 'your-key' });
```

## API Reference

### H33AgentClient

The main client. All mutating methods return an `AgentReceipt`.

```typescript
const h33 = new H33AgentClient({
  apiKey: string,      // default: process.env.H33_API_KEY
  baseUrl: string,     // default: 'https://api.h33.ai'
  timeoutMs: number,   // default: 30000
});
```

**Agent Identity**

| Method | Description |
|--------|-------------|
| `register(req)` | Register a new agent identity |

**Sessions**

| Method | Description |
|--------|-------------|
| `startSession(req)` | Start an attested session |
| `endSession(sessionId, summary?)` | End a session |

**Actions**

| Method | Description |
|--------|-------------|
| `attestAction(req)` | Attest an arbitrary action |
| `attestTool(req)` | Attest a tool call |
| `checkpointMemory(req)` | Checkpoint memory state |

**Governance**

| Method | Description |
|--------|-------------|
| `evaluatePolicy(req)` | Evaluate policy before acting |
| `checkExposure(req)` | Check for data exposure |
| `requestApproval(req)` | Request human approval |
| `delegate(req)` | Delegate to sub-agent |

**Verification (public, no auth)**

| Method | Description |
|--------|-------------|
| `getProof(nodeId)` | Get cryptographic proof for any receipt |

**Replay**

| Method | Description |
|--------|-------------|
| `replay(req)` | Replay a session chain |
| `replayFork(req)` | Fork a session at a node |
| `queryLineage(req)` | Query the lineage DAG |

### H33Session

Convenience wrapper that auto-fills session ID and tracks action count.

```typescript
const session = new H33Session(h33, startSessionReceipt);

await session.attestAction(actionType, summary, inputHash);
await session.attestTool(toolName, requestHash);
await session.checkpointMemory(memoryHash, contextHash, sizeBytes);
await session.evaluatePolicy(actionType, target);
await session.checkExposure(dataClass, operation);
await session.end(summary?);

session.id;       // session ID
session.actions;  // action count
session.ended;    // boolean
```

### H33Verifier

Public verification client. No API key needed.

```typescript
const verifier = new H33Verifier();

const proof = await verifier.verify(nodeId);
console.log(proof.valid); // true

const chain = await verifier.verifyChain(sessionId);
console.log(chain.intact, chain.nodes);
```

### Tool Helpers

```typescript
import { attestedTool, hashToolRequest, hashToolResponse, toolName } from '@h33/agent';

// Hash payloads (SHA-256, never send raw content)
const reqHash = hashToolRequest({ query: 'open claims' });
const resHash = hashToolResponse({ results: [...] });

// Canonical tool name
const name = toolName('acme', 'search', 'v1');
// => 'h33.tool.acme.search.v1'

// Wrap any handler with automatic attestation
const attested = attestedTool(session, name, myHandler);
const { result, receipt } = await attested(input);
```

### Memory Helpers

```typescript
import { hashMemoryState, hashContextWindow } from '@h33/agent';

const memHash = hashMemoryState({ docs, scratchpad, timestamp });
const ctxHash = hashContextWindow([
  { role: 'system', content: '...' },
  { role: 'user', content: '...' },
]);
```

## MCP Integration

Wrap your MCP tool handlers with `attestedTool()` for automatic attestation:

```typescript
import { attestedTool, toolName } from '@h33/agent';

// Your existing handler
async function myTool(input: MyInput): Promise<MyOutput> {
  return doWork(input);
}

// Wrapped -- every call is now attested
const attested = attestedTool(session, toolName('myorg', 'mytool', 'v1'), myTool);

// Use it like normal
const { result, receipt } = await attested(input);
```

If a tool throws, the failure is attested before the error is re-thrown.

See `examples/mcp-server.ts` for a complete example.

## LangChain.js Integration

Use the hash helpers in your LangChain callback handlers:

```typescript
import { hashToolRequest, hashToolResponse, hashContextWindow } from '@h33/agent';

// In your CallbackHandler
async handleToolStart(tool, input) {
  const hash = hashToolRequest(input);
  // store hash for handleToolEnd
}

async handleToolEnd(tool, output) {
  await session.attestTool(toolName, requestHash, {
    response_hash: hashToolResponse(output),
    status: 'success',
  });
}
```

See `examples/langchain.ts` for a complete example.

## Verification

Every receipt includes a `verification_url` that anyone can check without an API key:

```typescript
// The agent produces receipts
const receipt = await session.attestAction(...);

// Share the verification URL with auditors, regulators, or counterparties
console.log(receipt.verification_url);

// Or use the SDK to verify programmatically
const verifier = new H33Verifier();
const proof = await verifier.verify(receipt.node_id);
```

## Examples

- `examples/quickstart.ts` -- 5-minute getting started
- `examples/mcp-server.ts` -- Attested MCP server with `attestedTool()`
- `examples/langchain.ts` -- LangChain.js integration

## Design Decisions

- **Zero dependencies.** Uses native `fetch()` (Node 18+) and `crypto.createHash()`.
- **Hash, never send.** All content is SHA-256 hashed client-side. The API never sees raw data.
- **Public verification.** Proof endpoints require no authentication. Verification is for everyone.
- **Post-quantum.** Receipts are signed with ML-DSA (Dilithium) and carry H33-74 compact attestations.

## License

MIT
