aira-sdk 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +269 -167
- package/dist/client.d.ts +2 -0
- package/dist/client.js +3 -1
- package/dist/session.d.ts +2 -0
- package/dist/types.d.ts +38 -11
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
# Aira TypeScript SDK
|
|
2
2
|
|
|
3
|
-
**AI
|
|
3
|
+
**AI governance infrastructure.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/aira-sdk)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Policies evaluate every agent action. Humans approve high-stakes decisions. Cryptographic receipts prove it all. Rules, AI, and multi-model consensus govern what your agents can do — with Ed25519 signatures, RFC 3161 timestamps, and W3C DID identity. Built for EU AI Act, SR 11-7, and GDPR compliance.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Drop Aira into your existing agent framework with one import:
|
|
15
|
-
|
|
16
|
-
| Framework | Import | Integration |
|
|
17
|
-
|---|---|---|
|
|
18
|
-
| **LangChain.js** | `import { AiraCallbackHandler } from "aira-sdk/extras/langchain"` | Callback handler |
|
|
19
|
-
| **Vercel AI** | `import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai"` | Middleware |
|
|
20
|
-
| **OpenAI Agents** | `import { AiraGuardrail } from "aira-sdk/extras/openai-agents"` | Guardrail |
|
|
21
|
-
| **MCP** | `import { createServer } from "aira-sdk/extras/mcp"` | MCP Server |
|
|
22
|
-
| **Webhooks** | `import { verifySignature } from "aira-sdk/extras/webhooks"` | Verification |
|
|
10
|
+
```bash
|
|
11
|
+
npm install aira-sdk
|
|
12
|
+
```
|
|
23
13
|
|
|
24
|
-
|
|
14
|
+
Framework integrations use sub-imports — just make sure the peer dependency is installed:
|
|
25
15
|
|
|
26
16
|
```bash
|
|
27
|
-
npm install aira-sdk
|
|
17
|
+
npm install aira-sdk langchain # for LangChain.js
|
|
18
|
+
npm install aira-sdk ai # for Vercel AI
|
|
19
|
+
npm install aira-sdk @openai/agents # for OpenAI Agents
|
|
28
20
|
```
|
|
29
21
|
|
|
30
22
|
---
|
|
@@ -53,154 +45,13 @@ console.log(receipt.action_id); // uuid — publicly verifiable
|
|
|
53
45
|
|
|
54
46
|
---
|
|
55
47
|
|
|
56
|
-
## Framework Integrations
|
|
57
|
-
|
|
58
|
-
### LangChain.js
|
|
59
|
-
|
|
60
|
-
`AiraCallbackHandler` notarizes every tool call, chain completion, and LLM invocation with a cryptographic receipt. No changes to your chain logic.
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
import { Aira } from "aira-sdk";
|
|
64
|
-
import { AiraCallbackHandler } from "aira-sdk/extras/langchain";
|
|
65
|
-
|
|
66
|
-
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
67
|
-
const handler = new AiraCallbackHandler({ client: aira, agentId: "research-agent", modelId: "gpt-4o" });
|
|
68
|
-
|
|
69
|
-
// Every tool call and chain completion gets a signed receipt
|
|
70
|
-
const result = await chain.invoke({ input: "Analyze Q1 revenue" }, { callbacks: [handler] });
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Vercel AI
|
|
74
|
-
|
|
75
|
-
`AiraVercelMiddleware` wraps your Vercel AI `streamText` / `generateText` calls so every model invocation is notarized with a tamper-proof receipt.
|
|
76
|
-
|
|
77
|
-
```typescript
|
|
78
|
-
import { Aira } from "aira-sdk";
|
|
79
|
-
import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai";
|
|
80
|
-
|
|
81
|
-
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
82
|
-
const middleware = new AiraVercelMiddleware({ client: aira, agentId: "assistant-agent" });
|
|
83
|
-
|
|
84
|
-
// Wrap your Vercel AI calls — receipts at invocation and completion
|
|
85
|
-
const result = await middleware.wrapGenerateText({
|
|
86
|
-
model: openai("gpt-4o"),
|
|
87
|
-
prompt: "Summarize the contract terms",
|
|
88
|
-
});
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### OpenAI Agents SDK
|
|
92
|
-
|
|
93
|
-
`AiraGuardrail` wraps any tool function to automatically notarize both invocation and result with cryptographic proof.
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
import { Aira } from "aira-sdk";
|
|
97
|
-
import { AiraGuardrail } from "aira-sdk/extras/openai-agents";
|
|
98
|
-
|
|
99
|
-
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
100
|
-
const guardrail = new AiraGuardrail({ client: aira, agentId: "assistant-agent" });
|
|
101
|
-
|
|
102
|
-
// Wrap tools — every call and result gets a signed receipt
|
|
103
|
-
const search = guardrail.wrapTool(searchTool, { toolName: "web_search" });
|
|
104
|
-
const execute = guardrail.wrapTool(codeExecutor, { toolName: "code_exec" });
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## MCP Server
|
|
110
|
-
|
|
111
|
-
Expose Aira as an MCP tool server. Any MCP-compatible AI agent can notarize actions and verify receipts without SDK integration.
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
import { createServer } from "aira-sdk/extras/mcp";
|
|
115
|
-
|
|
116
|
-
const server = createServer({ apiKey: "aira_live_xxx" });
|
|
117
|
-
server.listen(); // stdio transport
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
The server exposes three tools: `notarize_action`, `verify_action`, and `get_receipt` -- each producing cryptographically signed results.
|
|
121
|
-
|
|
122
|
-
Add to your MCP client config:
|
|
123
|
-
|
|
124
|
-
```json
|
|
125
|
-
{
|
|
126
|
-
"mcpServers": {
|
|
127
|
-
"aira": {
|
|
128
|
-
"command": "npx",
|
|
129
|
-
"args": ["aira-sdk", "mcp"],
|
|
130
|
-
"env": { "AIRA_API_KEY": "aira_live_xxx" }
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Session
|
|
139
|
-
|
|
140
|
-
Pre-fill defaults for a block of related actions. Every `notarize()` call within the session inherits the agent identity, producing receipts that share a common provenance chain.
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
const sess = aira.session("onboarding-agent", { modelId: "claude-sonnet-4-6" });
|
|
144
|
-
|
|
145
|
-
await sess.notarize({ actionType: "identity_verified", details: "Verified customer ID #4521" });
|
|
146
|
-
await sess.notarize({ actionType: "account_created", details: "Created account for customer #4521" });
|
|
147
|
-
await sess.notarize({ actionType: "welcome_sent", details: "Sent welcome email to customer #4521" });
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## Offline Mode
|
|
153
|
-
|
|
154
|
-
Queue notarizations locally when connectivity is unavailable. Cryptographic receipts are generated server-side when you sync -- nothing is lost.
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
const aira = new Aira({ apiKey: "aira_live_xxx", offline: true });
|
|
158
|
-
|
|
159
|
-
// These queue locally — no network calls
|
|
160
|
-
await aira.notarize({ actionType: "scan_completed", details: "Scanned document batch #77" });
|
|
161
|
-
await aira.notarize({ actionType: "classification_done", details: "Classified 142 documents" });
|
|
162
|
-
|
|
163
|
-
console.log(aira.pendingCount); // 2
|
|
164
|
-
|
|
165
|
-
// Flush to API when back online — receipts are generated for each action
|
|
166
|
-
const results = await aira.sync();
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Webhook Verification
|
|
172
|
-
|
|
173
|
-
Verify that incoming webhooks are authentic Aira events, not forged requests. HMAC-SHA256 signature verification ensures tamper-proof delivery.
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import { verifySignature, parseEvent } from "aira-sdk/extras/webhooks";
|
|
177
|
-
|
|
178
|
-
// Verify the webhook signature (HMAC-SHA256)
|
|
179
|
-
const isValid = verifySignature({
|
|
180
|
-
payload: request.body,
|
|
181
|
-
signature: request.headers["x-aira-signature"],
|
|
182
|
-
secret: "whsec_xxx",
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
if (isValid) {
|
|
186
|
-
const event = parseEvent(request.body);
|
|
187
|
-
console.log(event.eventType); // "action.notarized"
|
|
188
|
-
console.log(event.data); // Action data with cryptographic receipt
|
|
189
|
-
console.log(event.deliveryId); // Unique delivery ID
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
Supported event types: `action.notarized`, `action.authorized`, `agent.registered`, `agent.decommissioned`, `evidence.sealed`, `escrow.deposited`, `escrow.released`, `escrow.disputed`, `compliance.snapshot_created`, `case.complete`, `case.requires_human_review`.
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
48
|
## Core SDK Methods
|
|
198
49
|
|
|
199
|
-
All
|
|
50
|
+
All 52 methods on `Aira`. Every write operation produces a cryptographic receipt.
|
|
200
51
|
|
|
201
52
|
| Category | Method | Description |
|
|
202
53
|
|---|---|---|
|
|
203
|
-
| **Actions** | `notarize()` | Notarize an action -- returns Ed25519-signed receipt |
|
|
54
|
+
| **Actions** | `notarize()` | Notarize an action -- returns Ed25519-signed receipt (supports `requireApproval`) |
|
|
204
55
|
| | `getAction()` | Retrieve action details + receipt |
|
|
205
56
|
| | `listActions()` | List actions with filters (type, agent, status) |
|
|
206
57
|
| | `authorizeAction()` | Human co-signature on high-stakes action |
|
|
@@ -224,15 +75,9 @@ All 56 methods on `Aira`. Every write operation produces a cryptographic receipt
|
|
|
224
75
|
| | `revokeCredential()` | Revoke agent's Verifiable Credential |
|
|
225
76
|
| | `requestMutualSign()` | Initiate mutual notarization with counterparty |
|
|
226
77
|
| | `completeMutualSign()` | Complete mutual notarization (counterparty signs) |
|
|
227
|
-
| | `getMutualSignStatus()` | Check status of a mutual sign request |
|
|
228
78
|
| | `getReputation()` | Get agent reputation score and tier |
|
|
229
79
|
| | `listReputationHistory()` | List reputation score history |
|
|
230
|
-
| | `setEndpointPolicy()` | Set endpoint verification policy |
|
|
231
|
-
| | `getEndpointPolicy()` | Get current endpoint policy |
|
|
232
80
|
| | `resolveDid()` | Resolve any DID to its DID Document |
|
|
233
|
-
| | `checkTrust()` | Run full trust check against a counterparty |
|
|
234
|
-
| | `listCredentials()` | List all credentials for an agent |
|
|
235
|
-
| | `getTrustBundle()` | Get DID + VC + reputation in one call |
|
|
236
81
|
| **Cases** | `runCase()` | Multi-model consensus adjudication |
|
|
237
82
|
| | `getCase()` | Retrieve case result |
|
|
238
83
|
| | `listCases()` | List cases |
|
|
@@ -320,6 +165,45 @@ console.log(rep.score); // 84
|
|
|
320
165
|
console.log(rep.tier); // "Verified"
|
|
321
166
|
```
|
|
322
167
|
|
|
168
|
+
### Endpoint Verification
|
|
169
|
+
|
|
170
|
+
Control which external APIs your agents can call. When `endpointUrl` is passed to `notarize()`, Aira checks it against your org's whitelist. Unrecognized endpoints are blocked in strict mode.
|
|
171
|
+
|
|
172
|
+
#### Notarize with endpointUrl
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const receipt = await aira.notarize({
|
|
176
|
+
actionType: "api_call",
|
|
177
|
+
details: "Charged customer $49.99 for subscription renewal",
|
|
178
|
+
agentId: "billing-agent",
|
|
179
|
+
modelId: "claude-sonnet-4-6",
|
|
180
|
+
endpointUrl: "https://api.stripe.com/v1/charges",
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Handle ENDPOINT_NOT_WHITELISTED
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import { Aira, AiraError } from "aira-sdk";
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const receipt = await aira.notarize({
|
|
191
|
+
actionType: "api_call",
|
|
192
|
+
details: "Send SMS via new provider",
|
|
193
|
+
agentId: "notifications-agent",
|
|
194
|
+
endpointUrl: "https://api.newprovider.com/v1/sms",
|
|
195
|
+
});
|
|
196
|
+
} catch (e) {
|
|
197
|
+
if (e instanceof AiraError && e.code === "ENDPOINT_NOT_WHITELISTED") {
|
|
198
|
+
console.log(`Blocked: ${e.message}`);
|
|
199
|
+
console.log(`Approval request: ${e.details.approval_id}`);
|
|
200
|
+
console.log(`Suggested pattern: ${e.details.url_pattern_suggested}`);
|
|
201
|
+
} else {
|
|
202
|
+
throw e;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
323
207
|
### Trust Policy in Integrations
|
|
324
208
|
|
|
325
209
|
Pass a `trustPolicy` to any framework integration to run automated trust checks before agent interactions:
|
|
@@ -328,7 +212,7 @@ Pass a `trustPolicy` to any framework integration to run automated trust checks
|
|
|
328
212
|
import { AiraCallbackHandler } from "aira-sdk/extras/langchain";
|
|
329
213
|
|
|
330
214
|
const handler = new AiraCallbackHandler(aira, "research-agent", {
|
|
331
|
-
modelId: "gpt-
|
|
215
|
+
modelId: "gpt-5.2",
|
|
332
216
|
trustPolicy: {
|
|
333
217
|
verifyCounterparty: true, // resolve counterparty DID
|
|
334
218
|
minReputation: 60, // warn if reputation score below 60
|
|
@@ -341,6 +225,224 @@ const handler = new AiraCallbackHandler(aira, "research-agent", {
|
|
|
341
225
|
|
|
342
226
|
---
|
|
343
227
|
|
|
228
|
+
## Session
|
|
229
|
+
|
|
230
|
+
Pre-fill defaults for a block of related actions. Every `notarize()` call within the session inherits the agent identity, producing receipts that share a common provenance chain.
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const sess = aira.session("onboarding-agent", { modelId: "claude-sonnet-4-6" });
|
|
234
|
+
|
|
235
|
+
await sess.notarize({ actionType: "identity_verified", details: "Verified customer ID #4521" });
|
|
236
|
+
await sess.notarize({ actionType: "account_created", details: "Created account for customer #4521" });
|
|
237
|
+
await sess.notarize({ actionType: "welcome_sent", details: "Sent welcome email to customer #4521" });
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Offline Mode
|
|
243
|
+
|
|
244
|
+
Queue notarizations locally when connectivity is unavailable. Cryptographic receipts are generated server-side when you sync -- nothing is lost.
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const aira = new Aira({ apiKey: "aira_live_xxx", offline: true });
|
|
248
|
+
|
|
249
|
+
// These queue locally — no network calls
|
|
250
|
+
await aira.notarize({ actionType: "scan_completed", details: "Scanned document batch #77" });
|
|
251
|
+
await aira.notarize({ actionType: "classification_done", details: "Classified 142 documents" });
|
|
252
|
+
|
|
253
|
+
console.log(aira.pendingCount); // 2
|
|
254
|
+
|
|
255
|
+
// Flush to API when back online — receipts are generated for each action
|
|
256
|
+
const results = await aira.sync();
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Human Approval
|
|
262
|
+
|
|
263
|
+
Hold high-stakes actions for human review before the cryptographic receipt is issued. Approvers receive an email with Approve/Deny buttons.
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
const receipt = await aira.notarize({
|
|
267
|
+
actionType: "loan_decision",
|
|
268
|
+
details: "Approved €15,000 loan for Maria Schmidt",
|
|
269
|
+
agentId: "lending-agent",
|
|
270
|
+
requireApproval: true,
|
|
271
|
+
approvers: ["compliance@acme.com", "risk@acme.com"],
|
|
272
|
+
});
|
|
273
|
+
console.log(receipt.status); // "pending_approval"
|
|
274
|
+
console.log(receipt.receipt_id); // undefined — no receipt until approved
|
|
275
|
+
|
|
276
|
+
// Falls back to org default approvers (Settings → Approvers)
|
|
277
|
+
const receipt2 = await aira.notarize({
|
|
278
|
+
actionType: "wire_transfer",
|
|
279
|
+
details: "Transfer $50,000 to vendor account",
|
|
280
|
+
agentId: "payments-agent",
|
|
281
|
+
requireApproval: true,
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The approver clicks "Approve" in the email → receipt is minted with Ed25519 signature + RFC 3161 timestamp → `action.approved` webhook fires.
|
|
286
|
+
|
|
287
|
+
Configure default approvers in the [dashboard](https://app.airaproof.com/dashboard/settings/approvers) or via the `/approvers` API.
|
|
288
|
+
|
|
289
|
+
### Automatic Policy Evaluation
|
|
290
|
+
|
|
291
|
+
Org admins configure policies in the dashboard — your code doesn't change. Every `notarize()` call is automatically evaluated against active policies before the receipt is issued.
|
|
292
|
+
|
|
293
|
+
Three evaluation modes:
|
|
294
|
+
|
|
295
|
+
- **Rules**: Deterministic conditions — instant, no LLM call
|
|
296
|
+
- **AI**: Single LLM evaluates action against a natural language policy (1-5s)
|
|
297
|
+
- **Consensus**: Multiple LLMs evaluate independently — disagreement triggers human review (3-10s)
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Your code stays the same — policies evaluate automatically
|
|
301
|
+
const receipt = await aira.notarize({
|
|
302
|
+
actionType: "wire_transfer",
|
|
303
|
+
details: "Transfer $50,000 to vendor account",
|
|
304
|
+
agentId: "billing-agent",
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// If a policy triggers "require_approval":
|
|
308
|
+
console.log(receipt.status); // "pending_approval"
|
|
309
|
+
console.log(receipt.policy_evaluation); // { policy_name: "Wire transfers need approval", decision: "require_approval", ... }
|
|
310
|
+
|
|
311
|
+
// If a policy triggers "deny":
|
|
312
|
+
import { AiraError } from "aira-sdk";
|
|
313
|
+
try {
|
|
314
|
+
await aira.notarize({ actionType: "data_deletion", details: "Delete customer records" });
|
|
315
|
+
} catch (e) {
|
|
316
|
+
if (e instanceof AiraError && e.code === "POLICY_DENIED") {
|
|
317
|
+
console.log(e.message); // "Action denied by policy 'Block deletions': ..."
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Every policy evaluation produces a cryptographic receipt — proof the policy was checked. The SDK `requireApproval: true` override still works and skips policy evaluation entirely.
|
|
323
|
+
|
|
324
|
+
Configure policies at [Settings → Policies](https://app.airaproof.com/dashboard/policies).
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Framework Integrations
|
|
329
|
+
|
|
330
|
+
Drop Aira into your existing agent framework with one import:
|
|
331
|
+
|
|
332
|
+
| Framework | Import | Integration |
|
|
333
|
+
|---|---|---|
|
|
334
|
+
| **LangChain.js** | `import { AiraCallbackHandler } from "aira-sdk/extras/langchain"` | Callback handler |
|
|
335
|
+
| **Vercel AI** | `import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai"` | Middleware |
|
|
336
|
+
| **OpenAI Agents** | `import { AiraGuardrail } from "aira-sdk/extras/openai-agents"` | Guardrail |
|
|
337
|
+
| **MCP** | `import { createServer } from "aira-sdk/extras/mcp"` | MCP Server |
|
|
338
|
+
| **Webhooks** | `import { verifySignature } from "aira-sdk/extras/webhooks"` | Verification |
|
|
339
|
+
|
|
340
|
+
### LangChain.js
|
|
341
|
+
|
|
342
|
+
`AiraCallbackHandler` notarizes every tool call, chain completion, and LLM invocation with a cryptographic receipt. No changes to your chain logic.
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { Aira } from "aira-sdk";
|
|
346
|
+
import { AiraCallbackHandler } from "aira-sdk/extras/langchain";
|
|
347
|
+
|
|
348
|
+
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
349
|
+
const handler = new AiraCallbackHandler({ client: aira, agentId: "research-agent", modelId: "gpt-5.2" });
|
|
350
|
+
|
|
351
|
+
// Every tool call and chain completion gets a signed receipt
|
|
352
|
+
const result = await chain.invoke({ input: "Analyze Q1 revenue" }, { callbacks: [handler] });
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Vercel AI
|
|
356
|
+
|
|
357
|
+
`AiraVercelMiddleware` wraps your Vercel AI `streamText` / `generateText` calls so every model invocation is notarized with a tamper-proof receipt.
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
import { Aira } from "aira-sdk";
|
|
361
|
+
import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai";
|
|
362
|
+
|
|
363
|
+
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
364
|
+
const middleware = new AiraVercelMiddleware({ client: aira, agentId: "assistant-agent" });
|
|
365
|
+
|
|
366
|
+
// Wrap your Vercel AI calls — receipts at invocation and completion
|
|
367
|
+
const result = await middleware.wrapGenerateText({
|
|
368
|
+
model: openai("gpt-5.2"),
|
|
369
|
+
prompt: "Summarize the contract terms",
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### OpenAI Agents SDK
|
|
374
|
+
|
|
375
|
+
`AiraGuardrail` wraps any tool function to automatically notarize both invocation and result with cryptographic proof.
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { Aira } from "aira-sdk";
|
|
379
|
+
import { AiraGuardrail } from "aira-sdk/extras/openai-agents";
|
|
380
|
+
|
|
381
|
+
const aira = new Aira({ apiKey: "aira_live_xxx" });
|
|
382
|
+
const guardrail = new AiraGuardrail({ client: aira, agentId: "assistant-agent" });
|
|
383
|
+
|
|
384
|
+
// Wrap tools — every call and result gets a signed receipt
|
|
385
|
+
const search = guardrail.wrapTool(searchTool, { toolName: "web_search" });
|
|
386
|
+
const execute = guardrail.wrapTool(codeExecutor, { toolName: "code_exec" });
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## MCP Server
|
|
392
|
+
|
|
393
|
+
Expose Aira as an MCP tool server. Any MCP-compatible AI agent can notarize actions and verify receipts without SDK integration.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { createServer } from "aira-sdk/extras/mcp";
|
|
397
|
+
|
|
398
|
+
const server = createServer({ apiKey: "aira_live_xxx" });
|
|
399
|
+
server.listen(); // stdio transport
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
The server exposes three tools: `notarize_action`, `verify_action`, and `get_receipt` -- each producing cryptographically signed results.
|
|
403
|
+
|
|
404
|
+
Add to your MCP client config:
|
|
405
|
+
|
|
406
|
+
```json
|
|
407
|
+
{
|
|
408
|
+
"mcpServers": {
|
|
409
|
+
"aira": {
|
|
410
|
+
"command": "npx",
|
|
411
|
+
"args": ["aira-sdk", "mcp"],
|
|
412
|
+
"env": { "AIRA_API_KEY": "aira_live_xxx" }
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Webhook Verification
|
|
421
|
+
|
|
422
|
+
Verify that incoming webhooks are authentic Aira events, not forged requests. HMAC-SHA256 signature verification ensures tamper-proof delivery.
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { verifySignature, parseEvent } from "aira-sdk/extras/webhooks";
|
|
426
|
+
|
|
427
|
+
// Verify the webhook signature (HMAC-SHA256)
|
|
428
|
+
const isValid = verifySignature({
|
|
429
|
+
payload: request.body,
|
|
430
|
+
signature: request.headers["x-aira-signature"],
|
|
431
|
+
secret: "whsec_xxx",
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
if (isValid) {
|
|
435
|
+
const event = parseEvent(request.body);
|
|
436
|
+
console.log(event.eventType); // "action.notarized"
|
|
437
|
+
console.log(event.data); // Action data with cryptographic receipt
|
|
438
|
+
console.log(event.deliveryId); // Unique delivery ID
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Supported event types: `action.notarized`, `action.authorized`, `agent.registered`, `agent.decommissioned`, `evidence.sealed`, `escrow.deposited`, `escrow.released`, `escrow.disputed`, `compliance.snapshot_created`, `case.complete`, `case.requires_human_review`.
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
344
446
|
## Error Handling
|
|
345
447
|
|
|
346
448
|
```typescript
|
package/dist/client.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export declare class Aira {
|
|
|
29
29
|
parentActionId?: string;
|
|
30
30
|
storeDetails?: boolean;
|
|
31
31
|
idempotencyKey?: string;
|
|
32
|
+
requireApproval?: boolean;
|
|
33
|
+
approvers?: string[];
|
|
32
34
|
}): Promise<ActionReceipt>;
|
|
33
35
|
getAction(actionId: string): Promise<ActionDetail>;
|
|
34
36
|
listActions(params?: {
|
package/dist/client.js
CHANGED
|
@@ -91,6 +91,8 @@ class Aira {
|
|
|
91
91
|
parent_action_id: params.parentActionId,
|
|
92
92
|
store_details: params.storeDetails || undefined,
|
|
93
93
|
idempotency_key: params.idempotencyKey,
|
|
94
|
+
require_approval: params.requireApproval || undefined,
|
|
95
|
+
approvers: params.approvers,
|
|
94
96
|
});
|
|
95
97
|
return this.post("/actions", body);
|
|
96
98
|
}
|
|
@@ -259,7 +261,7 @@ class Aira {
|
|
|
259
261
|
}
|
|
260
262
|
// ==================== Chat ====================
|
|
261
263
|
async ask(message, params) {
|
|
262
|
-
return this.post("/chat", buildBody({ message, history: params?.history,
|
|
264
|
+
return this.post("/chat", buildBody({ message, history: params?.history, model_id: params?.model }));
|
|
263
265
|
}
|
|
264
266
|
// ==================== DID ====================
|
|
265
267
|
/** Get full DID info for an agent. */
|
package/dist/session.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
/** Cryptographic receipt from notarizing an action. */
|
|
2
2
|
export interface ActionReceipt {
|
|
3
3
|
action_id: string;
|
|
4
|
+
receipt_id: string;
|
|
4
5
|
payload_hash: string;
|
|
5
6
|
signature: string;
|
|
6
|
-
|
|
7
|
-
action_type: string;
|
|
8
|
-
agent_id: string | null;
|
|
7
|
+
timestamp_token: string | null;
|
|
9
8
|
created_at: string;
|
|
9
|
+
request_id: string;
|
|
10
|
+
status?: string;
|
|
11
|
+
action_type?: string;
|
|
12
|
+
agent_id?: string | null;
|
|
13
|
+
warnings?: string[] | null;
|
|
14
|
+
policy_evaluation?: {
|
|
15
|
+
policy_id: string;
|
|
16
|
+
policy_name: string;
|
|
17
|
+
decision: string;
|
|
18
|
+
reasoning: string | null;
|
|
19
|
+
confidence: number | null;
|
|
20
|
+
} | null;
|
|
10
21
|
}
|
|
11
22
|
/** Full action details including receipt and authorizations. */
|
|
12
23
|
export interface ActionDetail {
|
|
@@ -66,46 +77,62 @@ export interface EvidencePackage {
|
|
|
66
77
|
id: string;
|
|
67
78
|
title: string;
|
|
68
79
|
description: string | null;
|
|
80
|
+
action_ids: string[];
|
|
69
81
|
package_hash: string;
|
|
70
82
|
signature: string;
|
|
71
|
-
|
|
83
|
+
status: string;
|
|
72
84
|
created_at: string;
|
|
85
|
+
request_id: string;
|
|
86
|
+
agent_slugs?: string[] | null;
|
|
73
87
|
}
|
|
74
88
|
/** Compliance snapshot. */
|
|
75
89
|
export interface ComplianceSnapshot {
|
|
76
90
|
id: string;
|
|
77
91
|
framework: string;
|
|
78
|
-
agent_slug: string | null;
|
|
79
|
-
findings: Record<string, string>;
|
|
80
92
|
status: string;
|
|
93
|
+
findings: Record<string, string>;
|
|
94
|
+
snapshot_hash: string;
|
|
95
|
+
signature: string;
|
|
96
|
+
snapshot_at: string;
|
|
81
97
|
created_at: string;
|
|
98
|
+
request_id: string;
|
|
99
|
+
agent_id?: string | null;
|
|
82
100
|
}
|
|
83
101
|
/** Escrow account. */
|
|
84
102
|
export interface EscrowAccount {
|
|
85
103
|
id: string;
|
|
86
|
-
status: string;
|
|
87
104
|
currency: string;
|
|
88
105
|
balance: string;
|
|
89
|
-
|
|
106
|
+
status: string;
|
|
90
107
|
created_at: string;
|
|
108
|
+
request_id: string;
|
|
109
|
+
agent_id?: string | null;
|
|
110
|
+
counterparty_org_id?: string | null;
|
|
111
|
+
purpose?: string | null;
|
|
112
|
+
transactions?: EscrowTransaction[];
|
|
91
113
|
}
|
|
92
114
|
/** Escrow transaction (deposit, release, dispute). */
|
|
93
115
|
export interface EscrowTransaction {
|
|
94
116
|
id: string;
|
|
95
117
|
transaction_type: string;
|
|
96
118
|
amount: string;
|
|
97
|
-
|
|
119
|
+
currency: string;
|
|
98
120
|
transaction_hash: string;
|
|
99
121
|
signature: string;
|
|
122
|
+
status: string;
|
|
100
123
|
created_at: string;
|
|
124
|
+
description?: string | null;
|
|
125
|
+
reference_action_id?: string | null;
|
|
101
126
|
}
|
|
102
127
|
/** Public verification result. */
|
|
103
128
|
export interface VerifyResult {
|
|
104
129
|
valid: boolean;
|
|
105
|
-
receipt_id: string | null;
|
|
106
|
-
verified_at: string;
|
|
107
130
|
public_key_id: string;
|
|
108
131
|
message: string;
|
|
132
|
+
verified_at: string;
|
|
133
|
+
request_id: string;
|
|
134
|
+
receipt_id?: string | null;
|
|
135
|
+
action_id?: string | null;
|
|
109
136
|
}
|
|
110
137
|
/** Paginated list response. */
|
|
111
138
|
export interface PaginatedList<T = Record<string, unknown>> {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aira-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "TypeScript SDK for Aira —
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "TypeScript SDK for Aira — AI governance infrastructure",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|