{"_id":"@ai-agent-filter/sdk","name":"@ai-agent-filter/sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@ai-agent-filter/sdk","version":"0.1.0","description":"Node.js/TypeScript SDK for AI Agent Filter - validate AI agent actions against security policies before execution. Prevent prompt injection, enforce rate limits, and audit all agent actions.","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","import":"./dist/index.js"}},"scripts":{"build":"tsc","test":"vitest run","test:watch":"vitest","lint":"tsc --noEmit","prepublishOnly":"npm run build && npm run test"},"keywords":["ai","ai-agents","agents","security","firewall","safety","guardrails","llm","langchain","openai","anthropic","claude","gpt","validation","policy","rate-limiting","audit","compliance","prompt-injection","ai-safety"],"author":{"name":"AI Agent Filter Team","email":"hello@aiagentfilter.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/ai-agent-filter/ai-agent-filter.git","directory":"sdk/nodejs"},"bugs":{"url":"https://github.com/ai-agent-filter/ai-agent-filter/issues"},"homepage":"https://aiagentfilter.com","engines":{"node":">=18.0.0"},"devDependencies":{"@types/node":"^20.0.0","tsx":"^4.20.6","typescript":"^5.0.0","vitest":"^1.0.0"},"publishConfig":{"access":"public"},"_id":"@ai-agent-filter/sdk@0.1.0","gitHead":"1e2c68f1107790a54276fa7f24c4bf6135150e03","_nodeVersion":"22.14.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-tPp1jQXApdsOTpnVmejqAigLMVqUpKSdIuxHY7gbP9UMDLtqlqnVQfpf85hZHZDgGRvOwp4sNh3wbo/a5rddGg==","shasum":"0f9e830c9c661338b3f575e387de8cc4481eca89","tarball":"https://registry.npmjs.org/@ai-agent-filter/sdk/-/sdk-0.1.0.tgz","fileCount":20,"unpackedSize":85022,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEMCH05GeI74ESikLWK0gGbPrpTQq3Rv0ehNSdFAu5eVfT4CIGnlxh9XA0BISXTiEmC92Ofj1zGCfOX9YzHOcvRJfWNf"}]},"_npmUser":{"name":"tobbie","email":"tobiloba.a.salau@gmail.com"},"directories":{},"maintainers":[{"name":"tobbie","email":"tobiloba.a.salau@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.0_1765457889595_0.34463547559190477"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-11T12:58:09.523Z","0.1.0":"2025-12-11T12:58:09.784Z","modified":"2025-12-11T12:58:10.073Z"},"maintainers":[{"name":"tobbie","email":"tobiloba.a.salau@gmail.com"}],"description":"Node.js/TypeScript SDK for AI Agent Filter - validate AI agent actions against security policies before execution. Prevent prompt injection, enforce rate limits, and audit all agent actions.","homepage":"https://aiagentfilter.com","keywords":["ai","ai-agents","agents","security","firewall","safety","guardrails","llm","langchain","openai","anthropic","claude","gpt","validation","policy","rate-limiting","audit","compliance","prompt-injection","ai-safety"],"repository":{"type":"git","url":"git+https://github.com/ai-agent-filter/ai-agent-filter.git","directory":"sdk/nodejs"},"author":{"name":"AI Agent Filter Team","email":"hello@aiagentfilter.com"},"bugs":{"url":"https://github.com/ai-agent-filter/ai-agent-filter/issues"},"license":"MIT","readme":"# AI Agent Filter - Node.js SDK\n\n[![npm version](https://img.shields.io/npm/v/@anthropic-ai/ai-firewall.svg)](https://www.npmjs.com/package/@anthropic-ai/ai-firewall)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node.js Version](https://img.shields.io/node/v/@anthropic-ai/ai-firewall.svg)](https://nodejs.org)\n\nThe official Node.js/TypeScript SDK for [AI Agent Filter](https://aiagentfilter.com) - validate AI agent actions against security policies before execution.\n\n**AI Agent Filter** is an open-source guardrails system that sits between your AI agents and the actions they perform. It validates every action against configurable policies, enforces rate limits, and provides complete audit logging.\n\n## Why AI Agent Filter?\n\n- **80% of organizations** have encountered risky behaviors from AI agents\n- **23% of IT professionals** have witnessed agents deceived into revealing credentials\n- **OWASP ranks prompt injection** as the #1 security risk for LLM applications in 2025\n\nAI Agent Filter helps you:\n- **Prevent unauthorized actions** - Block agents from exceeding spending limits, accessing forbidden resources, or performing dangerous operations\n- **Enforce rate limits** - Prevent runaway agents from making unlimited API calls or transactions\n- **Audit everything** - Complete audit trail of every action for compliance and debugging\n- **Simulate policies** - Test policy changes without affecting production\n\n---\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Configuration](#configuration)\n- [Core Concepts](#core-concepts)\n- [API Reference](#api-reference)\n- [Error Handling](#error-handling)\n- [Framework Integrations](#framework-integrations)\n- [Advanced Usage](#advanced-usage)\n- [TypeScript Support](#typescript-support)\n- [Examples](#examples)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n\n---\n\n## Installation\n\n```bash\nnpm install @anthropic-ai/ai-firewall\n```\n\n**Requirements:**\n- Node.js 18+ (uses native `fetch`)\n- TypeScript 5.0+ (optional, for type definitions)\n\n---\n\n## Quick Start\n\n### 1. Start the AI Agent Filter Server\n\n```bash\n# Using Docker (recommended)\ndocker run -p 8000:8000 aiagentfilter/server:latest\n\n# Or with docker-compose\ndocker-compose up -d\n```\n\n### 2. Create a Project and Get an API Key\n\n```bash\ncurl -X POST http://localhost:8000/projects \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"my-project\", \"description\": \"My AI agent project\"}'\n```\n\n### 3. Validate Agent Actions\n\n```typescript\nimport { AIFirewall } from \"@anthropic-ai/ai-firewall\";\n\n// Initialize the client\nconst fw = new AIFirewall({\n  apiKey: \"af_your_api_key\",\n  projectId: \"my-project\",\n  baseUrl: \"http://localhost:8000\", // Your AI Agent Filter server\n});\n\n// Validate an action before executing\nconst result = await fw.execute(\"invoice_agent\", \"pay_invoice\", {\n  vendor: \"Acme Corp\",\n  amount: 5000,\n  currency: \"USD\",\n});\n\nif (result.allowed) {\n  console.log(`✅ Action allowed (ID: ${result.actionId})`);\n  // Proceed with the actual payment\n  await processPayment({ vendor: \"Acme Corp\", amount: 5000 });\n} else {\n  console.log(`❌ Action blocked: ${result.reason}`);\n  // Handle the blocked action (notify user, log, etc.)\n}\n```\n\n---\n\n## Configuration\n\n### Client Options\n\n```typescript\nconst fw = new AIFirewall({\n  // Required\n  apiKey: \"af_xxx\",              // Your project API key\n  projectId: \"my-project\",       // Your project identifier\n\n  // Optional - Server\n  baseUrl: \"http://localhost:8000\",  // API URL (default: http://localhost:8000)\n  timeout: 30000,                    // Request timeout in ms (default: 30000)\n\n  // Optional - Behavior\n  strict: false,                 // Throw ActionBlockedError when blocked (default: false)\n\n  // Optional - Retry Configuration\n  maxRetries: 3,                 // Max retry attempts (default: 3, set to 0 to disable)\n  retryBaseDelay: 1000,          // Base delay in ms for exponential backoff (default: 1000)\n  retryMaxDelay: 30000,          // Maximum delay cap in ms (default: 30000)\n  retryOnStatus: [429, 500, 502, 503, 504],  // HTTP codes to retry (default)\n  retryOnNetworkError: true,     // Retry on network failures (default: true)\n});\n```\n\n### Environment Variables\n\nYou can also configure the client using environment variables:\n\n```bash\nAI_FIREWALL_API_KEY=af_your_api_key\nAI_FIREWALL_PROJECT_ID=my-project\nAI_FIREWALL_BASE_URL=http://localhost:8000\n```\n\n```typescript\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: process.env.AI_FIREWALL_PROJECT_ID!,\n  baseUrl: process.env.AI_FIREWALL_BASE_URL,\n});\n```\n\n---\n\n## Core Concepts\n\n### Actions\n\nAn **action** is any operation your AI agent wants to perform. Actions have:\n- **Agent Name**: Identifier for the agent (e.g., `\"invoice_agent\"`, `\"support_bot\"`)\n- **Action Type**: The operation type (e.g., `\"pay_invoice\"`, `\"send_email\"`, `\"delete_file\"`)\n- **Parameters**: Key-value pairs with action details (e.g., `{ amount: 5000, currency: \"USD\" }`)\n\n### Policies\n\nA **policy** defines what actions are allowed. Policies contain rules that specify:\n- Which actions are allowed/blocked\n- Parameter constraints (min/max values, allowed values, regex patterns)\n- Rate limits (requests per time window)\n- Aggregate limits (total amounts over time)\n\nExample policy:\n```json\n{\n  \"name\": \"finance-policy\",\n  \"version\": \"1.0\",\n  \"default\": \"block\",\n  \"rules\": [\n    {\n      \"action_type\": \"pay_invoice\",\n      \"effect\": \"allow\",\n      \"constraints\": {\n        \"params.amount\": { \"max\": 10000 },\n        \"params.currency\": { \"in\": [\"USD\", \"EUR\", \"GBP\"] }\n      },\n      \"rate_limit\": {\n        \"max_requests\": 100,\n        \"window_seconds\": 3600\n      }\n    }\n  ]\n}\n```\n\n### Validation Flow\n\n```\n┌─────────────┐     ┌──────────────────┐     ┌─────────────┐\n│  AI Agent   │────▶│  AI Agent Filter │────▶│   Action    │\n│             │     │    (Validate)    │     │ (If allowed)│\n└─────────────┘     └──────────────────┘     └─────────────┘\n                            │\n                            ▼\n                    ┌──────────────────┐\n                    │   Audit Log      │\n                    └──────────────────┘\n```\n\n---\n\n## API Reference\n\n### `execute(agentName, actionType, params?, options?)`\n\nValidate an action before executing it.\n\n```typescript\nconst result = await fw.execute(\n  \"agent_name\",      // Agent identifier\n  \"action_type\",     // Action type\n  { key: \"value\" },  // Parameters (optional)\n  { simulate: false } // Options (optional)\n);\n```\n\n**Parameters:**\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `agentName` | `string` | Yes | Identifier for the agent |\n| `actionType` | `string` | Yes | Type of action being performed |\n| `params` | `Record<string, unknown>` | No | Action parameters (default: `{}`) |\n| `options.simulate` | `boolean` | No | If true, validate without logging (default: `false`) |\n\n**Returns:** `Promise<ValidationResult>`\n\n```typescript\ninterface ValidationResult {\n  allowed: boolean;           // Whether the action is allowed\n  actionId: string | null;    // Unique ID (null for simulations)\n  timestamp: Date;            // When validation occurred\n  reason?: string;            // Reason if blocked\n  executionTimeMs?: number;   // Validation time in ms\n  simulated: boolean;         // Whether this was a simulation\n}\n```\n\n**Example:**\n```typescript\n// Basic validation\nconst result = await fw.execute(\"bot\", \"send_email\", {\n  to: \"user@example.com\",\n  subject: \"Hello\",\n});\n\n// Simulation (what-if mode)\nconst simResult = await fw.execute(\"bot\", \"delete_account\", { userId: \"123\" }, { simulate: true });\nif (!simResult.allowed) {\n  console.log(`Would be blocked: ${simResult.reason}`);\n}\n```\n\n---\n\n### `getPolicy()`\n\nGet the active policy for your project.\n\n```typescript\nconst policy = await fw.getPolicy();\n```\n\n**Returns:** `Promise<Policy>`\n\n```typescript\ninterface Policy {\n  id: number;              // Policy database ID\n  projectId: string;       // Associated project\n  name: string;            // Policy name\n  version: string;         // Policy version\n  rules: Record<string, unknown>;  // Policy rules\n  isActive: boolean;       // Whether this policy is active\n  createdAt: Date;         // Creation timestamp\n  updatedAt: Date;         // Last update timestamp\n}\n```\n\n**Example:**\n```typescript\nconst policy = await fw.getPolicy();\nconsole.log(`Active policy: ${policy.name} v${policy.version}`);\nconsole.log(`Rules: ${JSON.stringify(policy.rules, null, 2)}`);\n```\n\n---\n\n### `updatePolicy(options)`\n\nUpdate the policy for your project.\n\n```typescript\nconst policy = await fw.updatePolicy({\n  rules: [...],\n  name: \"my-policy\",\n  version: \"2.0\",\n  default: \"block\",\n});\n```\n\n**Parameters:**\n\n```typescript\ninterface UpdatePolicyOptions {\n  rules: Array<Record<string, unknown>>;  // Policy rules (required)\n  name?: string;           // Policy name (default: \"default\")\n  version?: string;        // Version string (default: \"1.0\")\n  default?: \"allow\" | \"block\";  // Default behavior (default: \"allow\")\n}\n```\n\n**Returns:** `Promise<Policy>`\n\n**Example:**\n```typescript\nconst policy = await fw.updatePolicy({\n  name: \"production-policy\",\n  version: \"2.0\",\n  default: \"block\",\n  rules: [\n    {\n      action_type: \"pay_invoice\",\n      effect: \"allow\",\n      constraints: {\n        \"params.amount\": { max: 10000 },\n        \"params.currency\": { in: [\"USD\", \"EUR\"] },\n      },\n      rate_limit: {\n        max_requests: 50,\n        window_seconds: 3600,\n      },\n    },\n    {\n      action_type: \"send_email\",\n      effect: \"allow\",\n      constraints: {\n        \"params.to\": { pattern: \"^[\\\\w.-]+@company\\\\.com$\" },\n      },\n    },\n    {\n      action_type: \"*\",\n      effect: \"allow\",\n      rate_limit: {\n        max_requests: 1000,\n        window_seconds: 86400,\n      },\n    },\n  ],\n});\n```\n\n---\n\n### `getLogs(options?)`\n\nGet audit logs for your project.\n\n```typescript\nconst logs = await fw.getLogs({\n  page: 1,\n  pageSize: 50,\n  agentName: \"invoice_agent\",\n  allowed: false,\n});\n```\n\n**Parameters:**\n\n```typescript\ninterface GetLogsOptions {\n  page?: number;           // Page number, 1-indexed (default: 1)\n  pageSize?: number;       // Items per page (default: 50, max: 100)\n  agentName?: string;      // Filter by agent name\n  actionType?: string;     // Filter by action type\n  allowed?: boolean;       // Filter by allowed status\n}\n```\n\n**Returns:** `Promise<LogsPage>`\n\n```typescript\ninterface LogsPage {\n  items: AuditLogEntry[];  // Log entries\n  total: number;           // Total count\n  page: number;            // Current page\n  pageSize: number;        // Items per page\n  hasMore: boolean;        // More pages available\n}\n\ninterface AuditLogEntry {\n  actionId: string;\n  projectId: string;\n  agentName: string;\n  actionType: string;\n  params: Record<string, unknown>;\n  allowed: boolean;\n  reason?: string;\n  policyVersion?: string;\n  executionTimeMs?: number;\n  timestamp: Date;\n}\n```\n\n**Example:**\n```typescript\n// Get all blocked actions\nconst blockedLogs = await fw.getLogs({ allowed: false });\n\nfor (const entry of blockedLogs.items) {\n  console.log(`[${entry.timestamp.toISOString()}] ${entry.agentName}/${entry.actionType}: ${entry.reason}`);\n}\n\n// Paginate through all logs\nlet page = 1;\nlet hasMore = true;\nwhile (hasMore) {\n  const logs = await fw.getLogs({ page, pageSize: 100 });\n  processLogs(logs.items);\n  hasMore = logs.hasMore;\n  page++;\n}\n```\n\n---\n\n### `getStats()`\n\nGet validation statistics for your project.\n\n```typescript\nconst stats = await fw.getStats();\n```\n\n**Returns:** `Promise<Stats>`\n\n```typescript\ninterface Stats {\n  totalActions: number;    // Total validations\n  allowed: number;         // Allowed count\n  blocked: number;         // Blocked count\n  blockRate: number;       // Block percentage (0-100)\n  topActionTypes?: Array<{ actionType: string; count: number }>;\n  topAgents?: Array<{ agentName: string; count: number }>;\n}\n```\n\n**Example:**\n```typescript\nconst stats = await fw.getStats();\n\nconsole.log(`Total actions: ${stats.totalActions}`);\nconsole.log(`Allowed: ${stats.allowed} (${100 - stats.blockRate}%)`);\nconsole.log(`Blocked: ${stats.blocked} (${stats.blockRate}%)`);\n\nconsole.log(\"\\nTop action types:\");\nstats.topActionTypes?.forEach(({ actionType, count }) => {\n  console.log(`  ${actionType}: ${count}`);\n});\n```\n\n---\n\n### `close()`\n\nClose the client. This is a no-op for the fetch-based client but included for API parity with the Python SDK.\n\n```typescript\nfw.close();\n```\n\n---\n\n## Error Handling\n\n### Error Classes\n\nThe SDK provides specific error classes for different failure scenarios:\n\n```typescript\nimport {\n  AIFirewall,\n  AIFirewallError,        // Base error class\n  AuthenticationError,    // Invalid or missing API key (401/403)\n  ProjectNotFoundError,   // Project doesn't exist (404)\n  PolicyNotFoundError,    // No active policy (404)\n  ValidationError,        // Invalid request format (422)\n  RateLimitError,         // Rate limit exceeded (429)\n  NetworkError,           // Connection failed or timeout\n  ActionBlockedError,     // Action blocked (strict mode only)\n} from \"@anthropic-ai/ai-firewall\";\n```\n\n### Handling Errors\n\n```typescript\ntry {\n  const result = await fw.execute(\"agent\", \"action\", params);\n} catch (error) {\n  if (error instanceof AuthenticationError) {\n    console.error(\"Invalid API key - check your credentials\");\n  } else if (error instanceof PolicyNotFoundError) {\n    console.error(\"No policy configured - create one first\");\n  } else if (error instanceof RateLimitError) {\n    console.error(\"Rate limited - slow down requests\");\n  } else if (error instanceof NetworkError) {\n    console.error(\"Network error - check server connectivity\");\n  } else if (error instanceof ActionBlockedError) {\n    console.error(`Action blocked: ${error.reason} (ID: ${error.actionId})`);\n  } else if (error instanceof AIFirewallError) {\n    console.error(`API error: ${error.message}`);\n  } else {\n    throw error; // Unknown error\n  }\n}\n```\n\n### Strict Mode\n\nWhen `strict: true`, blocked actions throw `ActionBlockedError` instead of returning a result:\n\n```typescript\nconst fw = new AIFirewall({\n  apiKey: \"af_xxx\",\n  projectId: \"my-project\",\n  strict: true,\n});\n\ntry {\n  // This will throw if the action is blocked\n  const result = await fw.execute(\"agent\", \"dangerous_action\", { amount: 1000000 });\n  // Only reached if action is allowed\n  await performAction();\n} catch (error) {\n  if (error instanceof ActionBlockedError) {\n    console.log(`Blocked: ${error.reason}`);\n    console.log(`Action ID: ${error.actionId}`);\n  }\n}\n```\n\n**Note:** Simulations never throw `ActionBlockedError` even in strict mode.\n\n---\n\n## Framework Integrations\n\n### LangChain.js\n\n```typescript\nimport { AIFirewall, ActionBlockedError } from \"@anthropic-ai/ai-firewall\";\nimport { Tool } from \"@langchain/core/tools\";\n\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"langchain-agent\",\n});\n\n// Wrap any tool with validation\nfunction withFirewall<T extends Tool>(tool: T, agentName: string): T {\n  const originalCall = tool._call.bind(tool);\n\n  tool._call = async (input: string) => {\n    const result = await fw.execute(agentName, tool.name, { input });\n\n    if (!result.allowed) {\n      return `Action blocked by security policy: ${result.reason}`;\n    }\n\n    return originalCall(input);\n  };\n\n  return tool;\n}\n\n// Usage\nconst calculator = withFirewall(new CalculatorTool(), \"math-agent\");\n```\n\n### Vercel AI SDK\n\n```typescript\nimport { AIFirewall } from \"@anthropic-ai/ai-firewall\";\nimport { generateText, tool } from \"ai\";\nimport { z } from \"zod\";\n\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"vercel-ai-agent\",\n});\n\nconst sendEmail = tool({\n  description: \"Send an email\",\n  parameters: z.object({\n    to: z.string().email(),\n    subject: z.string(),\n    body: z.string(),\n  }),\n  execute: async ({ to, subject, body }) => {\n    // Validate before executing\n    const validation = await fw.execute(\"email-agent\", \"send_email\", {\n      to,\n      subject,\n      bodyLength: body.length,\n    });\n\n    if (!validation.allowed) {\n      throw new Error(`Blocked: ${validation.reason}`);\n    }\n\n    // Proceed with sending email\n    return await emailService.send({ to, subject, body });\n  },\n});\n```\n\n### Express.js Middleware\n\n```typescript\nimport express from \"express\";\nimport { AIFirewall, ActionBlockedError } from \"@anthropic-ai/ai-firewall\";\n\nconst app = express();\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"api-server\",\n  strict: true,\n});\n\n// Middleware to validate agent actions\nconst validateAction = (actionType: string) => {\n  return async (req: express.Request, res: express.Response, next: express.NextFunction) => {\n    try {\n      const agentName = req.headers[\"x-agent-name\"] as string || \"unknown\";\n\n      await fw.execute(agentName, actionType, {\n        ...req.body,\n        ip: req.ip,\n        userAgent: req.headers[\"user-agent\"],\n      });\n\n      next();\n    } catch (error) {\n      if (error instanceof ActionBlockedError) {\n        res.status(403).json({\n          error: \"Action blocked by policy\",\n          reason: error.reason,\n          actionId: error.actionId,\n        });\n      } else {\n        next(error);\n      }\n    }\n  };\n};\n\n// Protected routes\napp.post(\"/api/payments\", validateAction(\"create_payment\"), createPaymentHandler);\napp.delete(\"/api/users/:id\", validateAction(\"delete_user\"), deleteUserHandler);\n```\n\n### Next.js API Routes\n\n```typescript\n// app/api/agent/route.ts\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { AIFirewall } from \"@anthropic-ai/ai-firewall\";\n\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"nextjs-app\",\n});\n\nexport async function POST(request: NextRequest) {\n  const { agentName, action, params } = await request.json();\n\n  const validation = await fw.execute(agentName, action, params);\n\n  if (!validation.allowed) {\n    return NextResponse.json(\n      { error: \"Action blocked\", reason: validation.reason },\n      { status: 403 }\n    );\n  }\n\n  // Execute the action\n  const result = await executeAgentAction(action, params);\n\n  return NextResponse.json({ success: true, result, actionId: validation.actionId });\n}\n```\n\n---\n\n## Advanced Usage\n\n### Simulation Mode (What-If Testing)\n\nTest whether an action would be allowed without creating an audit log entry:\n\n```typescript\n// Test a potentially dangerous action\nconst simResult = await fw.execute(\n  \"test-agent\",\n  \"delete_all_data\",\n  { confirm: true },\n  { simulate: true }\n);\n\nif (simResult.allowed) {\n  console.log(\"Warning: This action would be allowed!\");\n} else {\n  console.log(`Good: This action would be blocked (${simResult.reason})`);\n}\n\n// simResult.actionId is null for simulations\n// simResult.simulated is true\n```\n\n### Retry Configuration\n\nThe SDK automatically retries on transient failures with exponential backoff:\n\n```typescript\nconst fw = new AIFirewall({\n  apiKey: \"af_xxx\",\n  projectId: \"my-project\",\n\n  // Retry configuration\n  maxRetries: 5,                    // Try up to 6 times total\n  retryBaseDelay: 500,              // Start with 500ms delay\n  retryMaxDelay: 60000,             // Max 60s between retries\n  retryOnStatus: [429, 500, 502, 503, 504],  // Retry these status codes\n  retryOnNetworkError: true,        // Retry on connection failures\n});\n\n// Disable retries for time-sensitive operations\nconst fwNoRetry = new AIFirewall({\n  apiKey: \"af_xxx\",\n  projectId: \"my-project\",\n  maxRetries: 0,  // Fail immediately\n});\n```\n\n### Bulk Validation\n\nFor validating multiple actions efficiently:\n\n```typescript\nasync function validateBatch(actions: Array<{ agent: string; type: string; params: any }>) {\n  const results = await Promise.all(\n    actions.map(({ agent, type, params }) =>\n      fw.execute(agent, type, params).catch(err => ({\n        allowed: false,\n        reason: err.message,\n        error: true\n      }))\n    )\n  );\n\n  const blocked = results.filter(r => !r.allowed);\n  if (blocked.length > 0) {\n    console.log(`${blocked.length}/${results.length} actions would be blocked`);\n  }\n\n  return results;\n}\n```\n\n### Monitoring and Metrics\n\n```typescript\nimport { AIFirewall } from \"@anthropic-ai/ai-firewall\";\n\nclass MonitoredFirewall {\n  private fw: AIFirewall;\n  private metrics = {\n    total: 0,\n    allowed: 0,\n    blocked: 0,\n    errors: 0,\n    totalLatencyMs: 0,\n  };\n\n  constructor(options: AIFirewallOptions) {\n    this.fw = new AIFirewall(options);\n  }\n\n  async execute(...args: Parameters<AIFirewall[\"execute\"]>) {\n    const start = Date.now();\n    this.metrics.total++;\n\n    try {\n      const result = await this.fw.execute(...args);\n      this.metrics.totalLatencyMs += Date.now() - start;\n\n      if (result.allowed) {\n        this.metrics.allowed++;\n      } else {\n        this.metrics.blocked++;\n      }\n\n      return result;\n    } catch (error) {\n      this.metrics.errors++;\n      this.metrics.totalLatencyMs += Date.now() - start;\n      throw error;\n    }\n  }\n\n  getMetrics() {\n    return {\n      ...this.metrics,\n      avgLatencyMs: this.metrics.total > 0\n        ? this.metrics.totalLatencyMs / this.metrics.total\n        : 0,\n      blockRate: this.metrics.total > 0\n        ? (this.metrics.blocked / this.metrics.total) * 100\n        : 0,\n    };\n  }\n}\n```\n\n---\n\n## TypeScript Support\n\nThe SDK is written in TypeScript and provides full type definitions:\n\n```typescript\nimport type {\n  AIFirewallOptions,\n  ValidationResult,\n  Policy,\n  AuditLogEntry,\n  LogsPage,\n  Stats,\n  UpdatePolicyOptions,\n  GetLogsOptions,\n  ExecuteOptions,\n} from \"@anthropic-ai/ai-firewall\";\n\n// All types are exported and available\nconst options: AIFirewallOptions = {\n  apiKey: \"af_xxx\",\n  projectId: \"my-project\",\n  strict: true,\n};\n\nconst handleResult = (result: ValidationResult) => {\n  if (result.allowed) {\n    console.log(`Allowed: ${result.actionId}`);\n  }\n};\n```\n\n---\n\n## Examples\n\n### Complete Example: Payment Agent\n\n```typescript\nimport { AIFirewall, ActionBlockedError } from \"@anthropic-ai/ai-firewall\";\n\n// Initialize client\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"payment-system\",\n  strict: true,\n});\n\n// Set up policy\nawait fw.updatePolicy({\n  name: \"payment-policy\",\n  version: \"1.0\",\n  default: \"block\",\n  rules: [\n    {\n      action_type: \"create_payment\",\n      effect: \"allow\",\n      constraints: {\n        \"params.amount\": { min: 1, max: 50000 },\n        \"params.currency\": { in: [\"USD\", \"EUR\", \"GBP\"] },\n      },\n      rate_limit: {\n        max_requests: 100,\n        window_seconds: 3600,\n      },\n      aggregate_limit: {\n        field: \"params.amount\",\n        max: 100000,\n        window_seconds: 86400,\n      },\n    },\n    {\n      action_type: \"refund_payment\",\n      effect: \"allow\",\n      constraints: {\n        \"params.amount\": { max: 10000 },\n      },\n    },\n  ],\n});\n\n// Payment processing function\nasync function processPayment(agent: string, amount: number, currency: string, recipient: string) {\n  try {\n    // Validate with AI Agent Filter\n    const validation = await fw.execute(agent, \"create_payment\", {\n      amount,\n      currency,\n      recipient,\n    });\n\n    console.log(`✅ Payment validated (ID: ${validation.actionId})`);\n\n    // Actually process the payment\n    const paymentResult = await paymentGateway.charge({\n      amount,\n      currency,\n      recipient,\n    });\n\n    return { success: true, paymentId: paymentResult.id, validationId: validation.actionId };\n\n  } catch (error) {\n    if (error instanceof ActionBlockedError) {\n      console.log(`❌ Payment blocked: ${error.reason}`);\n      return { success: false, error: error.reason, actionId: error.actionId };\n    }\n    throw error;\n  }\n}\n\n// Usage\nconst result = await processPayment(\"invoice-bot\", 5000, \"USD\", \"vendor@example.com\");\n```\n\n### Complete Example: Multi-Agent System\n\n```typescript\nimport { AIFirewall } from \"@anthropic-ai/ai-firewall\";\n\nconst fw = new AIFirewall({\n  apiKey: process.env.AI_FIREWALL_API_KEY!,\n  projectId: \"multi-agent-system\",\n});\n\n// Different agents with different permissions\nconst agents = {\n  reader: {\n    name: \"reader-agent\",\n    actions: [\"read_file\", \"list_directory\", \"search\"],\n  },\n  writer: {\n    name: \"writer-agent\",\n    actions: [\"read_file\", \"write_file\", \"create_file\"],\n  },\n  admin: {\n    name: \"admin-agent\",\n    actions: [\"*\"],\n  },\n};\n\n// Validate agent action\nasync function agentAction(\n  agentType: keyof typeof agents,\n  actionType: string,\n  params: Record<string, unknown>\n) {\n  const agent = agents[agentType];\n\n  const result = await fw.execute(agent.name, actionType, params);\n\n  if (!result.allowed) {\n    throw new Error(`Agent ${agent.name} is not allowed to ${actionType}: ${result.reason}`);\n  }\n\n  return result;\n}\n\n// Usage\nawait agentAction(\"reader\", \"read_file\", { path: \"/data/report.txt\" });  // ✅ Allowed\nawait agentAction(\"reader\", \"delete_file\", { path: \"/data/report.txt\" }); // ❌ Blocked\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n#### \"Connection refused\" error\nMake sure the AI Agent Filter server is running:\n```bash\ncurl http://localhost:8000/health\n```\n\n#### \"Invalid API key\" error\nCheck that your API key is correct and starts with `af_`:\n```typescript\nconsole.log(process.env.AI_FIREWALL_API_KEY); // Should start with 'af_'\n```\n\n#### \"No active policy\" error\nCreate a policy for your project:\n```typescript\nawait fw.updatePolicy({\n  rules: [{ action_type: \"*\", effect: \"allow\" }],\n});\n```\n\n#### Timeout errors\nIncrease the timeout or check network connectivity:\n```typescript\nconst fw = new AIFirewall({\n  ...options,\n  timeout: 60000, // 60 seconds\n});\n```\n\n### Debug Mode\n\nEnable debug logging by checking the request/response:\n\n```typescript\n// Check what's being sent\nconst result = await fw.execute(\"agent\", \"action\", { debug: true });\nconsole.log(JSON.stringify(result, null, 2));\n\n// Check audit logs\nconst logs = await fw.getLogs({ pageSize: 1 });\nconsole.log(logs.items[0]);\n```\n\n---\n\n## Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](https://github.com/ai-agent-filter/ai-agent-filter/blob/main/CONTRIBUTING.md).\n\n```bash\n# Clone the repo\ngit clone https://github.com/ai-agent-filter/ai-agent-filter.git\ncd ai-agent-filter/sdk/nodejs\n\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n```\n\n---\n\n## License\n\nMIT License - see [LICENSE](./LICENSE) for details.\n\n---\n\n## Links\n\n- [Documentation](https://docs.aiagentfilter.com)\n- [GitHub Repository](https://github.com/ai-agent-filter/ai-agent-filter)\n- [Python SDK](https://pypi.org/project/ai-firewall/)\n- [Discord Community](https://discord.gg/aiagentfilter)\n- [Twitter](https://twitter.com/aiagentfilter)\n\n---\n\n<p align=\"center\">\n  <strong>AI Agent Filter</strong> - Guardrails for AI Agents\n  <br>\n  <a href=\"https://aiagentfilter.com\">Website</a> •\n  <a href=\"https://github.com/ai-agent-filter/ai-agent-filter\">GitHub</a> •\n  <a href=\"https://docs.aiagentfilter.com\">Docs</a>\n</p>\n","readmeFilename":"README.md","_rev":"1-6b3a4978df25dd9dea9f95d8326cbd81"}