{"_id":"@aegara/sdk","_rev":"8-8d0324a7a1938e6ac1340f510d794bfd","name":"@aegara/sdk","dist-tags":{"latest":"0.7.0"},"versions":{"0.2.0":{"name":"@aegara/sdk","version":"0.2.0","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"author":{"name":"Aegara AI"},"license":"MIT","_id":"@aegara/sdk@0.2.0","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"homepage":"https://aegara.ai","bugs":{"url":"https://github.com/mohitpatel094-ui/aegara-ai/issues"},"dist":{"shasum":"8f1df83aeb38c7f3ceb59ce555c456127591c912","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.2.0.tgz","fileCount":33,"integrity":"sha512-1rLUB1mLaHmhL0rBNZC1+rnsmZNQsCB6eo3boDrUShpcWXi8uwnvRzIBag85AIx9YPSKpJnx9vLhwvU85pwwAA==","signatures":[{"sig":"MEQCIGyX6Ax0/ypCpZi0itaKgpqW47OLXZPxPejcYHp6RzgNAiBelangljgvX+uUnatcCnh+2vGjxE5wlRiXcYcIBILnSQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100888},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"e00de243e46e447882d6593179132bce75f937c4","scripts":{"test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"repository":{"url":"git+https://github.com/mohitpatel094-ui/aegara-ai.git","type":"git","directory":"sdk"},"_npmVersion":"11.8.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"_nodeVersion":"24.13.1","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.0.18","typescript":"5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.2.0_1779853536959_0.24776320168220556","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aegara/sdk","version":"0.3.0","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"author":{"name":"Aegara AI"},"license":"MIT","_id":"@aegara/sdk@0.3.0","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"homepage":"https://aegara.ai","bugs":{"url":"https://github.com/mohitpatel094-ui/aegara-ai/issues"},"dist":{"shasum":"e5dbdfe5b4375793a074f946e07e939802814184","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.3.0.tgz","fileCount":47,"integrity":"sha512-O2xkChn5xPfjTbITe1FBHiPeybBPqRSh1en2B6YWCxSjzBTKONW6tORBl8mJEKqshWSYICxOiP+HNcOwGmJxMg==","signatures":[{"sig":"MEUCID9z6x4WczEvhrUj6vYlHAeRqK1mIRU4ZP6JkqxZ3hvoAiEAwMj1KS5D8GP5ozfo2/Pspz3CRexpSweKwyAhK93vUEQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":154969},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"49eba9aacb751fee01a7118a314d104a4ffff446","scripts":{"test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"repository":{"url":"git+https://github.com/mohitpatel094-ui/aegara-ai.git","type":"git","directory":"sdk"},"_npmVersion":"11.16.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","typescript":"5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.3.0_1788725388451_0.9813959757788049","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aegara/sdk","version":"0.4.0","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"author":{"name":"Aegara AI"},"license":"MIT","_id":"@aegara/sdk@0.4.0","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"homepage":"https://aegara.ai","bugs":{"url":"https://aegara.ai/contact"},"dist":{"shasum":"ec4387ba3625a003a9f31d21116755ffc25ac244","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.4.0.tgz","fileCount":47,"integrity":"sha512-s6dz4Y0bGZxf/dIdFPNuIOTb3xmQzbQV4vlB4UQuLTm1lwRANtxgztfqECOwj+w1da0JdNquyrKcSSC1PgvoYw==","signatures":[{"sig":"MEQCIDwOeYIFj7TYG9eg5sJQHmTYDShJwkfVqzriPIdLTppLAiBctqEeL9vW1lSfkerqlMnA9m+lS6PMWQOTE0Kjywdv0Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":164317},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"48f48d6366723e499cb626f2780fd1d9f2a4b8a8","scripts":{"test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"_npmVersion":"11.16.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","typescript":"5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.4.0_1789057649609_0.9145398451087854","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aegara/sdk","version":"0.5.0","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"author":{"name":"Aegara AI"},"license":"MIT","_id":"@aegara/sdk@0.5.0","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"homepage":"https://aegara.ai","bugs":{"url":"https://aegara.ai/contact"},"dist":{"shasum":"7c01fb37df0e85d77bb052ed95c9884fb69b1e79","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.5.0.tgz","fileCount":47,"integrity":"sha512-bU9wRJpRK8whW/UaZHm+EI+xlPERscpPa8GYqRyCiY6zayoPd7dIVNeR/FbusoZhFjLxDXVIbNrxK22MD/NAWw==","signatures":[{"sig":"MEYCIQCSE4xEvgFmkq0Pd13gJ9vB4A3Ww/8Z8GUQp8paUJpfBQIhALab6nNh8GhQyJG/5BcdXq5nKUmjZCwek2ObsB+euVFv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDM9lxonpq24uycSAy65x9zOlNiTMjy5L0ueOkQPgZ/LQIgUTrSu1icIucGsw0lK+OPblVO421ScA9avoVArNsLnEs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162968},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"bf4b616892c2a6652b470ba354e68880948cf691","scripts":{"test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"_npmVersion":"11.16.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","typescript":"5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.5.0_1789611246020_0.722517896691806","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@aegara/sdk","version":"0.6.0","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"author":{"name":"Aegara AI"},"license":"MIT","_id":"@aegara/sdk@0.6.0","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"homepage":"https://aegara.ai","bugs":{"url":"https://aegara.ai/contact"},"dist":{"shasum":"18c4faf30ca230af300f36f9f675517fa1f42255","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.6.0.tgz","fileCount":63,"integrity":"sha512-/DFoBRqlBuPfhzOFSUKvns9Pr73bz3eDHUHSqofBTSV+dESElrxRo8mlRvxTXQUoJxXF13v86IPkRm1j+ZJgZw==","signatures":[{"sig":"MEUCIDMXHBcndnbW1VhC4L+TLiiw6WiDPTLZZuiWm4ach7iaAiEAnrMTZfI21bA7vtJvE7b6lUc4sHRxD01vsRb3aLLPjDc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCICevEepvvGMnx3nZ1PYECSU7DCGnN54nRLnbvJQEZF/EAiEAjdLq2aIoqi9u4AKQQWNC6E2Oyh8KN6b6SJuJ2DQrA0U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":498986},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"7a1cd95388b1f0a772fc213e5acf371e61dcefed","scripts":{"test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"_npmVersion":"11.16.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","typescript":"5.9.3"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.6.0_1790043160499_0.8875374544486907","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"_id":"@aegara/sdk@0.7.0","bugs":{"url":"https://aegara.ai/contact"},"dist":{"shasum":"3fcefdcbb821726614c0f4e20ad3170c5e09b278","tarball":"https://registry.npmjs.org/@aegara/sdk/-/sdk-0.7.0.tgz","fileCount":65,"integrity":"sha512-nJoGpDkQHynHW5vKh8BDcGzMAE3Il+7GFY8tMWqaldEXRlZDZndnZpb5TRnU1r2FL6WpEgFGvgGlYBerN41vlw==","signatures":[{"sig":"MEUCIQCM1gApQ9kbuttYWTWGIymHD2HE5Cq0cxGVmAuoP1/OSAIgXpAQiGCwTpHq9405hsWh9yY5YvJ/NZw3AzDpYVqKuwU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHBGWLMuV0gky2pJQUeD9g4TA9nLO+vVwjjF4Bf1cqOiAiEAzgmMeC76OI/qR6UO0JB+b8ZL6xC3JvSeKrmI/Canttc="}],"unpackedSize":523350},"main":"dist/index.js","name":"@aegara/sdk","types":"dist/index.d.ts","author":{"name":"Aegara AI"},"engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"6de7e5531d9f1a629df36de40b7096202f5ec122","license":"MIT","scripts":{"keys":"vitest run test/edge/key-corpus.test.ts","test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"version":"0.7.0","_npmUser":{"name":"mohit.patel","email":"aegara.ai@gmail.com"},"homepage":"https://aegara.ai","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"_npmVersion":"11.16.0","description":"Official SDK for Aegara, the AI governance and observability platform","directories":{},"maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"_nodeVersion":"24.18.0","dependencies":{"ulid":"3.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","typescript":"5.9.3"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.7.0_1790716011522_0.08917605675221174"}}},"time":{"created":"2026-05-27T03:45:36.826Z","modified":"2026-09-29T21:06:52.116Z","0.1.0":"2026-03-13T04:47:45.353Z","0.2.0":"2026-05-27T03:45:37.114Z","0.3.0":"2026-09-06T20:09:48.587Z","0.4.0":"2026-09-10T16:27:29.756Z","0.5.0":"2026-09-17T02:14:06.093Z","0.6.0":"2026-09-22T02:12:40.636Z","0.7.0":"2026-09-29T21:06:51.738Z"},"bugs":{"url":"https://aegara.ai/contact"},"author":{"name":"Aegara AI"},"license":"MIT","homepage":"https://aegara.ai","keywords":["aegara","ai","observability","audit","governance","ai-safety","llm","openai","anthropic","langchain"],"description":"Official SDK for Aegara, the AI governance and observability platform","maintainers":[{"name":"mohit.patel","email":"aegara.ai@gmail.com"}],"readme":"# @aegara/sdk\n\nOfficial SDK for **Aegara Trace**, the AI observability platform by Aegara AI.\n\n## Install\n\n```bash\nnpm install @aegara/sdk\n```\n\n## Getting your credentials\n\nYour API key and `org_id` come from the Aegara portal at\n[aegara.ai/portal](https://aegara.ai/portal): your key is shown once at\nregistration and can be rotated any time under **API Keys**, and your\n`org_id` appears in your **Profile**. The examples below use\nplaceholders; substitute your real values.\n\n## Quick Start: Auto-Wrap (Recommended)\n\nWrap your AI client and every call is automatically observed. No manual tracking needed:\n\n```typescript\nimport { Aegara } from \"@aegara/sdk\";\nimport OpenAI from \"openai\";\n\nconst aegara = new Aegara({ apiKey: \"your-api-key\" });\n\nconst openai = aegara.wrap(new OpenAI({ apiKey: \"sk-...\" }), {\n  ai_system_id: \"my-chatbot\",\n  org_id: \"org-123\",\n});\n\n// This call is automatically tracked by Aegara\nconst response = await openai.chat.completions.create({\n  model: \"gpt-4o\",\n  messages: [{ role: \"user\", content: \"Summarize this document\" }],\n});\n```\n\nThe `wrap()` function uses a JavaScript Proxy to intercept AI provider calls. Events are sent asynchronously (fire-and-forget) so your AI calls are never slowed down.\n\n### What Gets Intercepted (OpenAI example)\n\n| Method | Primitive | When |\n|---|---|---|\n| `chat.completions.create` | `TRANSFORM` | Standard chat completions |\n| `chat.completions.create` (with tool calls) | `CALL` | When the model invokes tools |\n| `embeddings.create` | `TRANSFORM` | Embedding generation |\n\n---\n\n## Supported AI Providers\n\n`wrap()` auto-detects and instruments any of these AI clients. Same `aegara.wrap(client, config)` call works for all. Detection happens once at wrap time using duck typing on the client object.\n\n| Provider | Client (example) | Detection |\n|---|---|---|\n| OpenAI | `new OpenAI({ apiKey })` | `chat.completions.create` is a function |\n| Anthropic | `new Anthropic({ apiKey })` | `messages.create` is a function |\n| Google Gemini, current | `new GoogleGenAI({ apiKey })` | `models.generateContent` is a function |\n| Google Gemini, legacy | `new GoogleGenerativeAI(apiKey).getGenerativeModel({ model })` | `generateContent` is a function |\n| Cohere | `new CohereClient({ token })` | `chat` and `embed` are both functions |\n| Mistral | `new Mistral({ apiKey })` | `chat.complete` is a function |\n| AWS Bedrock | `new BedrockRuntimeClient({ region })` or `new BedrockRuntime({ region })` | `send` is a function + `config.serviceId` is `\"Bedrock Runtime\"` |\n\n```typescript\nimport Anthropic from \"@anthropic-ai/sdk\";\n\nconst aegara = new Aegara({ apiKey: \"your-aegara-key\" });\n\nconst anthropic = aegara.wrap(new Anthropic({ apiKey: \"your-anthropic-key\" }), {\n  ai_system_id: \"my-assistant\",\n  org_id: \"org-123\",\n});\n\nconst message = await anthropic.messages.create({\n  model: \"claude-3-5-sonnet-20241022\",\n  max_tokens: 1024,\n  messages: [{ role: \"user\", content: \"Hello\" }],\n});\n```\n\n**AWS Bedrock uses the command pattern** (`client.send(new InvokeModelCommand(...))`). The SDK handles this transparently: same `wrap()` call, modelId is extracted from the unwrapped command:\n\n```typescript\nimport { BedrockRuntimeClient, InvokeModelCommand } from \"@aws-sdk/client-bedrock-runtime\";\n\nconst bedrock = aegara.wrap(new BedrockRuntimeClient({ region: \"us-east-1\" }), {\n  ai_system_id: \"compliance-bot\",\n  org_id: \"org-123\",\n});\n\nawait bedrock.send(new InvokeModelCommand({\n  modelId: \"anthropic.claude-3-haiku-20240307-v1:0\",\n  body: JSON.stringify({ messages: [{ role: \"user\", content: \"hi\" }] }),\n}));\n```\n\nThe aggregated `BedrockRuntime` client works too, and its convenience methods\nrecord exactly what the same command through `send()` records:\n\n```typescript\nimport { BedrockRuntime } from \"@aws-sdk/client-bedrock-runtime\";\n\nconst bedrock = aegara.wrap(new BedrockRuntime({ region: \"us-east-1\" }), {\n  ai_system_id: \"compliance-bot\",\n  org_id: \"org-123\",\n});\n\nawait bedrock.converse({\n  modelId: \"anthropic.claude-3-haiku-20240307-v1:0\",\n  messages: [{ role: \"user\", content: [{ text: \"hi\" }] }],\n});\n```\n\nOne rule decides what becomes a record, and it is the same rule on both client\nclasses: a command whose input carries a `modelId` is recorded, and one\nwithout it is not. So `applyGuardrail`, `invokeGuardrailChecks`,\n`getAsyncInvoke` and `listAsyncInvokes` record only when the input you hand\nthem carries a `modelId`, and the `paginateListAsyncInvokes` paginator records\nnothing whatever its input carries.\n\nYour own method under one of those names is left alone. Aegara hands the\nwrapped client to a method only when that method, or the same name reached by\nwalking up the prototype chain, calls `this.send`, which is how the AWS SDK's\ngenerated methods reach the call Aegara records, and only when none of them\nreads private state, which a wrapped client cannot answer. A `#` field is\nrefused directly, and so is one a build compiled into a WeakMap keyed by the\nobject: the helpers TypeScript, Babel, esbuild and SWC write for a private\nread, a private write, a counter, a private method call and a brand check are\nrecognized by name, each compiler's whole family of them. A subclass whose\noverride calls `super.converse`, a method patched over the original, and a\nfacade carrying the real client's own method all record once, as long as it\npasses on the `this` it was called on; a method of your own that does\nsomething else, or that keeps private state of its own, is not recorded, and\ncalls through `send()` are recorded either way.\n\nThree shapes are still not recognized, because the method's own source does\nnot name them: a WeakMap you wrote yourself, any of those helpers once a\nminifier has renamed it, and a brand check (`#calls in other`), which names\nno private read of its own and which SWC and Babel compile to a plain WeakMap\nlookup. Under a wrapped client such a read\nfails and the call raises. Give such a method a name of its own, or wrap the\nAWS SDK client instead of your wrapper around it. The other direction costs a\nrecord rather than a call: a method of yours whose source happens to contain\none of those helper names, in a comment or a name of its own, is left alone\nand its calls are not recorded. Two more shapes pay that same cost though\nthey are safe: a private field declared `static` compiles to a read keyed by\nthe class rather than by the instance, and a method that declares a nested\nclass of its own carries that nested class's private-field helper in its own\nsource even though the field belongs to the nested class, not to yours. Both\nare left alone and their calls are not recorded.\n\nIf auto-detection fails (e.g. you have a custom client wrapper that looks unlike a known provider), force a specific adapter via the `provider` config option:\n\n```typescript\nconst wrapped = aegara.wrap(customClient, {\n  ai_system_id: \"my-assistant\",\n  org_id: \"org-123\",\n  provider: \"openai\",\n});\n```\n\n---\n\n## Edge Value Inspection\n\nSensitive values are classified inside your own environment and only\nthe verdicts are transmitted. Structured values only (tool call\narguments and tool results); free text is never scanned. Scanning runs\nafter your AI call has returned, so latency is unaffected, and no\nvalue, substring, or hash of a value ever leaves your process.\n\nThis runs on every integration path.\nWith `wrap()`:\n\n```typescript\nconst openai = aegara.wrap(new OpenAI({ apiKey: \"sk-...\" }), {\n  ai_system_id: \"my-chatbot\",\n  org_id: \"org-...\",\n});\n```\n\nWith the LangChain handler (v0.4.0+):\n\n```typescript\nconst handler = new AegaraCallbackHandler(aegara, {\n  ai_system_id: \"my-langchain-agent\",\n  org_id: \"org-...\",\n});\n```\n\nTracking events yourself (v0.4.0+): run the inspector on your own\nstructured values and attach the result.\n\n```typescript\nimport { inspectValues, validateEdgePayload } from \"@aegara/sdk\";\n\nconst edge = validateEdgePayload(\n  inspectValues({ tool_arguments: { update_customer: toolArgs } })\n);\nawait aegara.track({ ...event, edge });\n```\n\n`scanToolArguments` and `scanToolResults` default to true when enabled.\nRequires `@aegara/sdk` 0.3.0 or later for `wrap()`, 0.4.0 or later for\nthe handler and the standalone inspector; earlier versions do not have\nthese capabilities, and 0.3.0+ warns if it receives options it does not\nrecognize. Org admins can centrally disallow edge inspection; the SDK\nhonors that automatically. Details: the Edge Value Inspection guide in\nyour Aegara portal documentation.\n\n## LangChain Integration\n\nFor LangChain agents, use the `AegaraCallbackHandler` instead of `wrap()`. The handler records model calls, chain steps, tool runs and retriever queries, each with its start, its end and its error (`handleLLMStart` through `handleRetrieverError`). LangChain's agent hooks, its free-text hook and its custom-event hook are not read, so an agent's choice of action is visible through the tool run it produces rather than as a record of its own:\n\n```typescript\nimport { ChatOpenAI } from \"@langchain/openai\";\nimport { Aegara, AegaraCallbackHandler } from \"@aegara/sdk\";\n\nconst aegara = new Aegara({ apiKey: \"your-aegara-key\" });\n\nconst handler = new AegaraCallbackHandler(aegara, {\n  ai_system_id: \"my-langchain-agent\",\n  org_id: \"org-123\",\n});\n\nconst llm = new ChatOpenAI({\n  callbacks: [handler],\n});\n\nconst result = await llm.invoke(\"What's the weather?\");\n```\n\nThe handler shares a single trace_id across the whole agent run, so chain steps and tool invocations link to the parent LLM call.\n\nA tool built with the `tool()` factory, with `DynamicTool` or with\n`DynamicStructuredTool` records under the name you gave it. A tool written as\na `StructuredTool` or `Tool` subclass records under its class name instead,\nbecause `@langchain/core` sends the handler no name for those two, and in a\nminified bundle that class name is letters your bundler chose. Pass\n`runName` when you invoke such a tool, or build it with `tool()`. Full table\nin the SDK integrations guide.\n\n---\n\n## Custom Providers\n\nFor internal AI services or providers without a built-in adapter, register a custom one:\n\n```typescript\nimport { registerProvider, type ProviderAdapter } from \"@aegara/sdk\";\n\nregisterProvider({\n  name: \"my-internal-llm\",\n  detect: (client) => typeof (client as any).generate === \"function\",\n  interceptPoints: [{\n    path: \"generate\",\n    capability: \"generate\",\n    defaultModel: \"internal-v1\",\n    extractRequest: (params) => ({ model: (params as any).model || \"internal-v1\" }),\n    extractResponse: (response) => ({ model: (response as any).model || \"unknown\" }),\n    getPrimitive: () => \"TRANSFORM\",\n  }],\n});\n\n// Now wrap() auto-detects your internal client\nconst wrapped = aegara.wrap(myInternalClient, {\n  ai_system_id: \"internal\",\n  org_id: \"org-123\",\n});\n```\n\nUse `listProviders()` to see what adapters are currently registered, and `getProvider(name)` to retrieve a specific adapter for inspection.\n\n---\n\n## Error Handling\n\nBy default, `wrap()` swallows track errors silently, so your AI calls never crash because Aegara couldn't be reached. This is the right default for production.\n\nTo surface errors (logging, alerting, debugging), pass an `onError` handler in your wrap config:\n\n```typescript\nconst openai = aegara.wrap(new OpenAI({ apiKey: \"...\" }), {\n  ai_system_id: \"my-chatbot\",\n  org_id: \"org-123\",\n  onError: (err) => {\n    console.error(\"[my-app] Aegara track failed:\", err);\n    // Send to your error tracker, alert your oncall, etc.\n  },\n});\n```\n\n`onError` fires on three things: an event that failed to send (network error, 4xx, 5xx), an inspection result that failed validation and rode on no event, and a call whose record could not be built at all. The third costs that call its record, and before 0.6.0 it happened silently. A common cause when `onError` starts firing immediately after a deploy is a wrong `apiKey`, and the error message includes `\"Aegara API error (401)\"`.\n\nIf your `onError` handler itself throws, the throw is caught and discarded so your AI call still succeeds.\n\n---\n\n## Manual Tracking\n\nFor full control over event data, use `track()` directly:\n\n```typescript\nimport { Aegara } from \"@aegara/sdk\";\n\nconst aegara = new Aegara({\n  apiKey: \"your-api-key\",\n});\n\nawait aegara.track({\n  trace_id: \"trace-abc-123\",\n  ai_system_id: \"my-chatbot\",\n  ai_model_name: \"gpt-4o\",\n  capability_invoked: \"email.summarize\",\n  primitive_type: \"READ\",\n  actor: {\n    trigger_type: \"user\",\n    user_id: \"user-42\",\n    system_id: null,\n  },\n  resources_accessed: [\n    { resource_type: \"email.thread\", resource_id: \"thread-99\" },\n  ],\n  fields_accessed: [\"subject\", \"body\", \"sender\"],\n  fields_not_accessed: [\"attachments\"],\n  systems_contacted: [\n    { system_id: \"gmail_api\", direction: \"inbound\" },\n  ],\n  actions_taken: [\"read_emails\", \"generate_summary\"],\n  outputs_generated: [\n    { output_type: \"summary\", output_size_bytes: 480 },\n  ],\n  memory_activity: {\n    memory_written: false,\n    memory_read: false,\n    memory_keys: [],\n  },\n  explicit_negatives: [\"did not forward emails\", \"did not access contacts\"],\n  risk_signals: {\n    data_sensitivity: \"internal\",\n    sensitive_domains: [],\n    potential_external_exposure: false,\n  },\n  schema_version: \"1.0.0\",\n  org_id: \"your-org-id\",\n  environment: \"production\",\n});\n```\n\n## Buffering (Recommended for Production)\n\nBuffer events and send them in efficient batches:\n\n```typescript\nconst aegara = new Aegara({\n  apiKey: \"your-api-key\",\n  buffering: {\n    maxSize: 50,       // Flush when 50 events are queued\n    intervalMs: 5000,  // Or every 5 seconds, whichever comes first\n  },\n});\n\n// Events are queued automatically\nawait aegara.track({ ... });\nawait aegara.track({ ... });\n\n// Flush before your process exits\nawait aegara.shutdown();\n```\n\nBuffering works with both `track()` and `wrap()`.\n\n## API\n\n### `new Aegara(config)`\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `apiKey` | `string` | *required* | Your Aegara API key |\n| `endpoint` | `string` | `https://aegara.ai` | Server URL |\n| `buffering.maxSize` | `number` | `50` | Max events before auto-flush |\n| `buffering.intervalMs` | `number` | `5000` | Auto-flush interval (ms) |\n| `debug` | `boolean` | `false` | Log debug info to console |\n\n### `aegara.wrap(client, config)`\n\nWrap any supported AI client for automatic observation (see [Supported AI Providers](#supported-ai-providers) above). Returns a proxied version of the client that works identically but sends events to Aegara on every API call.\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `ai_system_id` | `string` | *required* | Your AI system identifier in Aegara |\n| `org_id` | `string` | *required* | Your organization ID |\n| `environment` | `string` | `\"production\"` | Environment tag (`\"production\"` / `\"staging\"` / `\"development\"`) |\n| `getUserId` | `() => string \\| null` | `() => null` | Resolver for the current user ID (called on each request) |\n| `getTraceId` | `() => string` | `() => ulid()` | Resolver for trace linking (called on each request) |\n| `provider` | `string` | *auto-detect* | Provider name to force a specific adapter: `\"openai\"` / `\"anthropic\"` / `\"google-genai\"` / `\"gemini\"` / `\"cohere\"` / `\"mistral\"` / `\"bedrock\"` |\n| `onError` | `(err: unknown) => void` | `() => {}` (swallow) | Called when an event fails to send (see [Error Handling](#error-handling)) |\n\n### `aegara.track(event)`\n\nSend a single event. Buffered if buffering is enabled, otherwise sent immediately.\n\n### `aegara.trackBatch(events)`\n\nSend an array of events immediately (bypasses buffer).\n\n### `aegara.flush()`\n\nFlush all buffered events now.\n\n### `aegara.shutdown()`\n\nFlush remaining events and stop the background timer. Call this before your process exits.\n\n## The Six Primitives\n\nEvery AI action maps to exactly one primitive:\n\n| Primitive | Description |\n|-----------|-------------|\n| `READ` | AI accesses or retrieves data |\n| `TRANSFORM` | AI processes or interprets data |\n| `WRITE` | AI generates or modifies output |\n| `CALL` | AI invokes an external system |\n| `STORE` | AI persists memory or artifacts |\n| `ROUTE` | AI sends output to another system |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}