{"_id":"@agentactionverifier/sdk","name":"@agentactionverifier/sdk","dist-tags":{"beta":"0.1.0-beta.1","latest":"0.1.0-beta.1"},"versions":{"0.1.0-beta.1":{"name":"@agentactionverifier/sdk","version":"0.1.0-beta.1","description":"Official Node.js SDK for Agent Action Verifier protected tool execution","license":"MIT","repository":{"type":"git","url":"git+https://github.com/karmarrero/agent-auditor-saas.git","directory":"packages/sdk"},"homepage":"https://github.com/karmarrero/agent-auditor-saas/tree/main/packages/sdk#readme","bugs":{"url":"https://github.com/karmarrero/agent-auditor-saas/issues"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"publishConfig":{"access":"public","tag":"beta"},"sideEffects":false,"engines":{"node":">=18.0.0"},"keywords":["aav","ai-agents","authorization","policy","audit"],"scripts":{"build":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"pnpm build && node --test test/*.test.mjs"},"gitHead":"342d4f22c64e9140424521fd9ede2f92ac55c27f","_id":"@agentactionverifier/sdk@0.1.0-beta.1","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-Z2CzLNYfdfFCebpD5QICJeLPxR1Q0+mlgmipXt+Dj0JwRR96KYbVac2ZJkPCOpvWBLX93m7JtkA5WxXuhTgtMw==","shasum":"bfb15170eccf01309f1b6d9edab152e5746384f7","tarball":"https://registry.npmjs.org/@agentactionverifier/sdk/-/sdk-0.1.0-beta.1.tgz","fileCount":5,"unpackedSize":28648,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDDaLg/CuRzWSzHG+5TRnDAsANczztWTKAE2k1kt5zheQIhAPVluxYnkcY+jSsf6BflkltQOoZuez9H4mAVW/qy+9l4"}]},"_npmUser":{"name":"carlosmarreroaav","email":"carlos.marrero@agentactionverifier.com"},"directories":{},"maintainers":[{"name":"carlosmarreroaav","email":"carlos.marrero@agentactionverifier.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.0-beta.1_1787784115222_0.4415897249877583"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-26T22:41:54.994Z","0.1.0-beta.1":"2026-08-26T22:41:55.396Z","modified":"2026-08-26T22:41:55.648Z"},"maintainers":[{"name":"carlosmarreroaav","email":"carlos.marrero@agentactionverifier.com"}],"description":"Official Node.js SDK for Agent Action Verifier protected tool execution","homepage":"https://github.com/karmarrero/agent-auditor-saas/tree/main/packages/sdk#readme","keywords":["aav","ai-agents","authorization","policy","audit"],"repository":{"type":"git","url":"git+https://github.com/karmarrero/agent-auditor-saas.git","directory":"packages/sdk"},"bugs":{"url":"https://github.com/karmarrero/agent-auditor-saas/issues"},"license":"MIT","readme":"# Agent Action Verifier SDK\n\nServer-side Node.js client for executing tools through AAV policy, risk, approval, billing, credential-vault, gateway, run, and receipt controls.\n\nThis is the first beta release line of the official server-side Node.js SDK.\n\n## Installation\n\n```bash\nnpm install @agentactionverifier/sdk@beta\n```\n\nTo install this exact prerelease version instead:\n\n```bash\nnpm install @agentactionverifier/sdk@0.1.0-beta.1\n```\n\nNode.js 18 or newer is required. The package is ESM and includes TypeScript declarations.\n\n## Configure\n\n```dotenv\nAAV_API_KEY=your_agent_api_key\n```\n\nCreate the key in AAV for the intended Agent. The key is shown once. Keep it in a server-side secret store or environment variable.\n\n## Quick start\n\n```js\nimport { AAVClient } from \"@agentactionverifier/sdk\";\n\nconst aav = new AAVClient({\n  apiKey: process.env.AAV_API_KEY,\n});\n\nconst result = await aav.tools.execute({\n  toolKey: \"orders.cancel\",\n  input: { orderId: \"8472\" },\n  idempotencyKey: \"orders-cancel-8472-v1\",\n});\n\nconsole.log({ runId: result.runId, requestId: result.requestId, output: result.output });\n```\n\nUse an Agent API key created in AAV. Protected actions pass through AAV and can be allowed, denied, or held for human approval according to the configured policy and risk controls.\n\nThe default API URL is `https://api.agentactionverifier.com`. Override `baseUrl` with loopback only for explicit local development or tests:\n\n```js\nconst aav = new AAVClient({\n  apiKey: process.env.AAV_API_KEY,\n  baseUrl: \"http://127.0.0.1:3001\",\n  timeoutMs: 30_000,\n});\n```\n\nThe canonical MCP endpoint for MCP clients is `https://api.agentactionverifier.com/v1/mcp`. The SDK itself uses the REST API base above.\n\n## DENY\n\nA policy denial is a deliberate AAV decision, not a transport failure:\n\n```js\nimport { AAVClient, PolicyDeniedError } from \"@agentactionverifier/sdk\";\n\nconst aav = new AAVClient({ apiKey: process.env.AAV_API_KEY });\n\ntry {\n  await aav.tools.execute({ toolKey: \"refund.payment\", input: { amount: 1000 } });\n} catch (error) {\n  if (error instanceof PolicyDeniedError) {\n    console.log({ code: error.code, requestId: error.requestId });\n  } else {\n    throw error;\n  }\n}\n```\n\nFor `POLICY_DENIED`, AAV records the run and policy/risk decision and does not access the downstream credential or call the downstream service.\n\n## REQUIRE_APPROVAL\n\n```js\nimport { AAVClient, ApprovalRequiredError } from \"@agentactionverifier/sdk\";\n\nconst aav = new AAVClient({ apiKey: process.env.AAV_API_KEY });\n\ntry {\n  await aav.tools.execute({\n    toolKey: \"customer.update\",\n    input: { customerId: \"cus_123\", status: \"reviewed\" },\n    idempotencyKey: \"review-cus-123-v1\",\n  });\n} catch (error) {\n  if (!(error instanceof ApprovalRequiredError)) throw error;\n\n  // Persist these safe correlation identifiers in your job record.\n  console.log({ approvalRequestId: error.approvalRequestId, runId: error.runId });\n}\n```\n\nA human with AAV approval permission must approve or reject the request in AAV. Agents cannot approve their own requests. Check status from a scheduled job or user-driven refresh; do not poll aggressively:\n\n```js\nconst approval = await aav.approvals.get(approvalRequestId);\n\nif (approval.status === \"CONSUMED\") {\n  console.log({ runId: approval.runId, receipt: approval.run.receipt });\n}\n```\n\nApproval currently resumes execution inside the human approval request. The agent status endpoint exposes completion and the receipt, but does not persist or return the downstream response body after the fact. Design asynchronous workflows around completion state and your downstream system of record.\n\n## Safe dry run\n\n```js\nconst simulation = await aav.tools.dryRun({\n  toolKey: \"customer.update\",\n  input: { customerId: \"cus_123\", status: \"reviewed\" },\n});\n\nconsole.log(simulation.predictedDecision, simulation.risk.level);\n```\n\nDry run validates identity, tool, input, egress, policy, risk, and optional grant constraints. It does not access credentials, call downstream, consume a grant, create an approval, or create a real execution run. The API remains the decision source of truth.\n\nThe policy candidate simulator (`POST /v1/policies/simulate`) is intentionally not exposed by this Agent SDK because it belongs to the authenticated administrative control plane.\n\n## Execution Grants\n\nPass an existing grant issued through AAV administration:\n\n```js\nawait aav.tools.execute({\n  toolKey: \"customer.update\",\n  input: { customerId: \"cus_123\" },\n  executionGrantId: process.env.AAV_EXECUTION_GRANT_ID,\n  idempotencyKey: \"customer-update-cus-123-v1\",\n});\n```\n\nThe SDK only transports the grant identifier separately from tool input. AAV validates tenant, agent, tool, expiry, execution count, task constraints, and consumption. The SDK cannot create, widen, or locally validate a grant.\n\n## Idempotency and retries\n\nFor executions that may be submitted again, supply a unique application operation key:\n\n```js\nawait aav.tools.execute({\n  toolKey: \"invoice.create\",\n  input: { orderId: \"ord_123\" },\n  idempotencyKey: \"invoice-order-ord_123-v1\",\n});\n```\n\nThe same key is scoped to organization, Agent, and tool. Use a key tied to one durable business operation, such as `order-8472-email`, rather than a global value such as `request-1`. AAV canonicalizes the logical request: the same key and same request safely replay the stored result without another downstream call, while the same key with different input or a different execution grant returns HTTP 409 `IDEMPOTENCY_CONFLICT`.\n\n```js\nimport { IdempotencyConflictError } from \"@agentactionverifier/sdk\";\n\ntry {\n  await aav.tools.execute({\n    toolKey: \"send-email\",\n    idempotencyKey: \"order-8472-email\",\n    input: { orderId: \"8472\" },\n  });\n} catch (error) {\n  if (error instanceof IdempotencyConflictError) {\n    // Fix the operation mapping, or use a new key for a genuinely new operation.\n  } else throw error;\n}\n```\n\nA conflict is not retryable with the same key and changed request. While the original request is still executing, AAV returns `IDEMPOTENCY_IN_PROGRESS` rather than a fake result.\n\nThe SDK performs **no automatic retries**, including network failures and 5xx responses. This avoids repeating downstream mutations. `error.retryable` only indicates whether retry can be considered safe from the SDK request perspective (GET, or an execution carrying an idempotency key); your application still decides when to retry.\n\n## Abort and timeout\n\n```js\nconst controller = new AbortController();\n\nawait aav.tools.execute({\n  toolKey: \"customer.read\",\n  input: {},\n  signal: controller.signal,\n  timeoutMs: 10_000,\n});\n```\n\nThe default timeout is 30 seconds. `TIMEOUT` and `REQUEST_ABORTED` are typed `AAVError` codes.\n\n## Error handling\n\n```js\nimport {\n  AAVError,\n  ApprovalRequiredError,\n  BillingRestrictedError,\n  PolicyDeniedError,\n  RateLimitError,\n} from \"@agentactionverifier/sdk\";\n\ntry {\n  await aav.tools.execute({ toolKey: \"customer.read\", input: {} });\n} catch (error) {\n  if (error instanceof RateLimitError) {\n    console.log({ retryAfterSeconds: error.retryAfter, requestId: error.requestId });\n  } else if (error instanceof BillingRestrictedError) {\n    console.log({ code: error.code, requestId: error.requestId });\n  } else if (error instanceof AAVError) {\n    console.log({ code: error.code, status: error.status, requestId: error.requestId, retryable: error.retryable });\n  } else {\n    throw error;\n  }\n}\n```\n\nErrors expose only safe fields: `code`, `status`, `message`, `requestId`, `retryable`, optional `retryAfter`, and minimized `details`. Server stacks, raw upstream bodies, credentials, and API keys are not included.\n\n## Runs and receipts\n\n```js\nconst run = await aav.runs.get(result.runId);\nconst events = await aav.runs.events(result.runId);\n\nconsole.log({ requestId: result.requestId, runId: run.runId, receipt: run.receipt });\n```\n\nA receipt contains `runId`, `eventCount`, `finalChainHash`, and `issuedAt`. It is a compact integrity snapshot of AAV's hash-chained run events; it is not a digital signature and does not independently prove the truth of a downstream system's response. A verifier exists inside the AAV workspace and validates the receipt against the complete event sequence. It is not currently offered as a public npm dependency; its future public identity should be `@agentactionverifier/verifier` after a separate release review.\n\n## Security\n\n- Use Agent API keys only in backend/server code.\n- Never expose a key through `NEXT_PUBLIC_*`, browser bundles, mobile apps, logs, error telemetry, or source control.\n- Never commit `.env` files.\n- Rotate or revoke a key that may have been exposed.\n- Store downstream credentials in the AAV Credential Vault. Agents and the SDK must not receive tool credentials.\n- Send protected actions through AAV Gateway; do not copy official examples into direct downstream calls.\n- Correlate support incidents with `requestId` and `runId`, not sensitive payloads.\n\n## Public API\n\n- `new AAVClient(config)` (`AAV` and `AuditorClient` remain compatible aliases)\n- `aav.me()`\n- `aav.tools.list()`\n- `aav.tools.execute()`\n- `aav.tools.dryRun()`\n- `aav.approvals.get()`\n- `aav.runs.get()`\n- `aav.runs.events()`\n\nAll methods accept an `AbortSignal`; request methods also support a caller-provided `x-request-id` through `requestId`.\n","readmeFilename":"README.md","_rev":"1-4eed0c54c82ce6430711566dd9c32b9b"}