aira-sdk 0.2.2 → 0.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Aira TypeScript SDK
2
2
 
3
- **Legal infrastructure for AI agents.**
3
+ **AI compliance infrastructure for AI agents.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/aira-sdk.svg)](https://www.npmjs.com/package/aira-sdk)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
@@ -196,7 +196,7 @@ Supported event types: `action.notarized`, `action.authorized`, `agent.registere
196
196
 
197
197
  ## Core SDK Methods
198
198
 
199
- All 40 methods on `Aira`. Every write operation produces a cryptographic receipt.
199
+ All 56 methods on `Aira`. Every write operation produces a cryptographic receipt.
200
200
 
201
201
  | Category | Method | Description |
202
202
  |---|---|---|
@@ -217,6 +217,22 @@ All 40 methods on `Aira`. Every write operation produces a cryptographic receipt
217
217
  | | `decommissionAgent()` | Decommission agent |
218
218
  | | `transferAgent()` | Transfer ownership to another org |
219
219
  | | `getAgentActions()` | List actions by agent |
220
+ | **Trust Layer** | `getAgentDid()` | Retrieve agent's W3C DID (`did:web`) |
221
+ | | `rotateAgentKeys()` | Rotate agent's Ed25519 signing keys |
222
+ | | `getAgentCredential()` | Get agent's W3C Verifiable Credential |
223
+ | | `verifyCredential()` | Verify a Verifiable Credential |
224
+ | | `revokeCredential()` | Revoke agent's Verifiable Credential |
225
+ | | `requestMutualSign()` | Initiate mutual notarization with counterparty |
226
+ | | `completeMutualSign()` | Complete mutual notarization (counterparty signs) |
227
+ | | `getMutualSignStatus()` | Check status of a mutual sign request |
228
+ | | `getReputation()` | Get agent reputation score and tier |
229
+ | | `listReputationHistory()` | List reputation score history |
230
+ | | `setEndpointPolicy()` | Set endpoint verification policy |
231
+ | | `getEndpointPolicy()` | Get current endpoint policy |
232
+ | | `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 |
220
236
  | **Cases** | `runCase()` | Multi-model consensus adjudication |
221
237
  | | `getCase()` | Retrieve case result |
222
238
  | | `listCases()` | List cases |
@@ -245,6 +261,86 @@ All 40 methods on `Aira`. Every write operation produces a cryptographic receipt
245
261
 
246
262
  ---
247
263
 
264
+ ## Trust Layer
265
+
266
+ Standards-based identity and trust for agents: W3C DIDs, Verifiable Credentials, mutual notarization, and reputation scoring. Every agent gets a cryptographically verifiable identity that other agents (and humans) can check before interacting.
267
+
268
+ ### DID Identity
269
+
270
+ Every registered agent gets a W3C-compliant DID (`did:web`):
271
+
272
+ ```typescript
273
+ // Retrieve the agent's DID
274
+ const did = await aira.getAgentDid("my-agent");
275
+ console.log(did); // "did:web:airaproof.com:agents:my-agent"
276
+
277
+ // Rotate signing keys (old keys are revoked, new keys are published)
278
+ await aira.rotateAgentKeys("my-agent");
279
+ ```
280
+
281
+ ### Verifiable Credentials
282
+
283
+ ```typescript
284
+ // Get the agent's W3C Verifiable Credential
285
+ const vc = await aira.getAgentCredential("my-agent");
286
+
287
+ // Verify any VC (returns validity, issuer, expiry)
288
+ const result = await aira.verifyCredential(vc);
289
+ console.log(result.valid); // true
290
+
291
+ // Revoke a credential
292
+ await aira.revokeCredential("my-agent", { reason: "Agent deprecated" });
293
+ ```
294
+
295
+ ### Mutual Notarization
296
+
297
+ For high-stakes actions, both parties co-sign:
298
+
299
+ ```typescript
300
+ // Agent A initiates — sends a signing request to the counterparty
301
+ const request = await aira.requestMutualSign({
302
+ actionId: "act-uuid",
303
+ counterpartyDid: "did:web:partner.com:agents:their-agent",
304
+ });
305
+
306
+ // Agent B completes — signs the same payload
307
+ const receipt = await aira.completeMutualSign({
308
+ actionId: "act-uuid",
309
+ did: "did:web:partner.com:agents:their-agent",
310
+ signature: "z...",
311
+ signedPayloadHash: "sha256:...",
312
+ });
313
+ ```
314
+
315
+ ### Reputation
316
+
317
+ ```typescript
318
+ const rep = await aira.getReputation("my-agent");
319
+ console.log(rep.score); // 84
320
+ console.log(rep.tier); // "Verified"
321
+ ```
322
+
323
+ ### Trust Policy in Integrations
324
+
325
+ Pass a `trustPolicy` to any framework integration to run automated trust checks before agent interactions:
326
+
327
+ ```typescript
328
+ import { AiraCallbackHandler } from "aira-sdk/extras/langchain";
329
+
330
+ const handler = new AiraCallbackHandler(aira, "research-agent", {
331
+ modelId: "gpt-4o",
332
+ trustPolicy: {
333
+ verifyCounterparty: true, // resolve counterparty DID
334
+ minReputation: 60, // warn if reputation score below 60
335
+ requireValidVc: true, // check Verifiable Credential validity
336
+ blockRevokedVc: true, // block if counterparty VC is revoked
337
+ blockUnregistered: false, // don't block agents without Aira DIDs
338
+ },
339
+ });
340
+ ```
341
+
342
+ ---
343
+
248
344
  ## Error Handling
249
345
 
250
346
  ```typescript
@@ -286,7 +382,8 @@ const aira = new Aira({
286
382
 
287
383
  | Feature | Python | TypeScript |
288
384
  |---|---|---|
289
- | Core API (40 methods) | Yes | Yes |
385
+ | Core API (45+ methods) | Yes | Yes |
386
+ | Trust Layer (DID, VC, Reputation) | Yes | Yes |
290
387
  | LangChain | Yes | Yes |
291
388
  | CrewAI | Yes | -- (Python-only) |
292
389
  | Vercel AI | -- (JS-only) | Yes |
package/dist/client.d.ts CHANGED
@@ -129,6 +129,38 @@ export declare class Aira {
129
129
  tools_used: string[];
130
130
  model_id?: string;
131
131
  }>;
132
+ /** Get full DID info for an agent. */
133
+ getAgentDid(slug: string): Promise<Record<string, unknown>>;
134
+ /** Rotate an agent's DID keypair. */
135
+ rotateAgentKeys(slug: string): Promise<Record<string, unknown>>;
136
+ /** Resolve any did:web DID to its DID document. */
137
+ resolveDid(did: string): Promise<Record<string, unknown>>;
138
+ /** Get the current valid VC for an agent. */
139
+ getAgentCredential(slug: string): Promise<Record<string, unknown>>;
140
+ /** Get full credential history for an agent. */
141
+ getAgentCredentials(slug: string): Promise<Record<string, unknown>>;
142
+ /** Revoke the current credential for an agent. */
143
+ revokeCredential(slug: string, reason?: string): Promise<Record<string, unknown>>;
144
+ /** Verify a Verifiable Credential — checks signature, expiry, revocation. */
145
+ verifyCredential(credential: Record<string, unknown>): Promise<Record<string, unknown>>;
146
+ /** Initiate a mutual signing request for an action. */
147
+ requestMutualSign(actionId: string, counterpartyDid: string): Promise<Record<string, unknown>>;
148
+ /** Get the action payload awaiting counterparty signature. */
149
+ getPendingMutualSign(actionId: string): Promise<Record<string, unknown>>;
150
+ /** Submit counterparty signature to complete mutual signing. */
151
+ completeMutualSign(actionId: string, did: string, signature: string, signedPayloadHash: string): Promise<Record<string, unknown>>;
152
+ /** Get the co-signed receipt for a mutually signed action. */
153
+ getMutualSignReceipt(actionId: string): Promise<Record<string, unknown>>;
154
+ /** Reject a mutual signing request. */
155
+ rejectMutualSign(actionId: string, reason?: string): Promise<Record<string, unknown>>;
156
+ /** Get current reputation score for an agent. */
157
+ getReputation(slug: string): Promise<Record<string, unknown>>;
158
+ /** Get full reputation history for an agent. */
159
+ getReputationHistory(slug: string): Promise<Record<string, unknown>>;
160
+ /** Submit a signed attestation of a successful interaction. */
161
+ attestReputation(slug: string, counterpartyDid: string, actionId: string, attestation: string, signature: string): Promise<Record<string, unknown>>;
162
+ /** Verify a reputation score by returning inputs and score_hash. */
163
+ verifyReputation(slug: string): Promise<Record<string, unknown>>;
132
164
  /** Create a scoped session with pre-filled defaults. */
133
165
  session(agentId: string, defaults?: Record<string, unknown>): AiraSession;
134
166
  /** Number of queued offline requests. */
package/dist/client.js CHANGED
@@ -261,6 +261,76 @@ class Aira {
261
261
  async ask(message, params) {
262
262
  return this.post("/chat", buildBody({ message, history: params?.history, model: params?.model }));
263
263
  }
264
+ // ==================== DID ====================
265
+ /** Get full DID info for an agent. */
266
+ async getAgentDid(slug) {
267
+ return this.get(`/agents/${slug}/did`);
268
+ }
269
+ /** Rotate an agent's DID keypair. */
270
+ async rotateAgentKeys(slug) {
271
+ return this.post(`/agents/${slug}/did/rotate`, {});
272
+ }
273
+ /** Resolve any did:web DID to its DID document. */
274
+ async resolveDid(did) {
275
+ return this.post("/dids/resolve", { did });
276
+ }
277
+ // ==================== Verifiable Credentials ====================
278
+ /** Get the current valid VC for an agent. */
279
+ async getAgentCredential(slug) {
280
+ return this.get(`/agents/${slug}/credential`);
281
+ }
282
+ /** Get full credential history for an agent. */
283
+ async getAgentCredentials(slug) {
284
+ return this.get(`/agents/${slug}/credentials`);
285
+ }
286
+ /** Revoke the current credential for an agent. */
287
+ async revokeCredential(slug, reason = "") {
288
+ return this.post(`/agents/${slug}/credentials/revoke`, { reason });
289
+ }
290
+ /** Verify a Verifiable Credential — checks signature, expiry, revocation. */
291
+ async verifyCredential(credential) {
292
+ return this.post("/credentials/verify", { credential });
293
+ }
294
+ // ==================== Mutual Notarization ====================
295
+ /** Initiate a mutual signing request for an action. */
296
+ async requestMutualSign(actionId, counterpartyDid) {
297
+ return this.post(`/actions/${actionId}/mutual-sign/request`, { counterparty_did: counterpartyDid });
298
+ }
299
+ /** Get the action payload awaiting counterparty signature. */
300
+ async getPendingMutualSign(actionId) {
301
+ return this.get(`/actions/${actionId}/mutual-sign/pending`);
302
+ }
303
+ /** Submit counterparty signature to complete mutual signing. */
304
+ async completeMutualSign(actionId, did, signature, signedPayloadHash) {
305
+ return this.post(`/actions/${actionId}/mutual-sign/complete`, { did, signature, signed_payload_hash: signedPayloadHash });
306
+ }
307
+ /** Get the co-signed receipt for a mutually signed action. */
308
+ async getMutualSignReceipt(actionId) {
309
+ return this.get(`/actions/${actionId}/mutual-sign/receipt`);
310
+ }
311
+ /** Reject a mutual signing request. */
312
+ async rejectMutualSign(actionId, reason = "") {
313
+ return this.post(`/actions/${actionId}/mutual-sign/reject`, { reason });
314
+ }
315
+ // ==================== Reputation ====================
316
+ /** Get current reputation score for an agent. */
317
+ async getReputation(slug) {
318
+ return this.get(`/agents/${slug}/reputation`);
319
+ }
320
+ /** Get full reputation history for an agent. */
321
+ async getReputationHistory(slug) {
322
+ return this.get(`/agents/${slug}/reputation/history`);
323
+ }
324
+ /** Submit a signed attestation of a successful interaction. */
325
+ async attestReputation(slug, counterpartyDid, actionId, attestation, signature) {
326
+ return this.post(`/agents/${slug}/reputation/attest`, {
327
+ counterparty_did: counterpartyDid, action_id: actionId, attestation, signature,
328
+ });
329
+ }
330
+ /** Verify a reputation score by returning inputs and score_hash. */
331
+ async verifyReputation(slug) {
332
+ return this.get(`/agents/${slug}/reputation/verify`);
333
+ }
264
334
  // ==================== Session ====================
265
335
  /** Create a scoped session with pre-filled defaults. */
266
336
  session(agentId, defaults) {
@@ -17,3 +17,5 @@ export { createServer, getTools, handleToolCall } from "./mcp";
17
17
  export type { MCPTool, MCPTextContent } from "./mcp";
18
18
  export { verifySignature, parseEvent, WebhookEventType } from "./webhooks";
19
19
  export type { WebhookEvent, WebhookEventTypeName } from "./webhooks";
20
+ export { checkTrust } from "./trust";
21
+ export type { TrustPolicy, TrustContext } from "./trust";
@@ -12,7 +12,7 @@
12
12
  * import { verifySignature, parseEvent } from "aira-sdk/extras/webhooks";
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.WebhookEventType = exports.parseEvent = exports.verifySignature = exports.handleToolCall = exports.getTools = exports.createServer = exports.AiraGuardrail = exports.AiraVercelMiddleware = exports.AiraCallbackHandler = void 0;
15
+ exports.checkTrust = exports.WebhookEventType = exports.parseEvent = exports.verifySignature = exports.handleToolCall = exports.getTools = exports.createServer = exports.AiraGuardrail = exports.AiraVercelMiddleware = exports.AiraCallbackHandler = void 0;
16
16
  var langchain_1 = require("./langchain");
17
17
  Object.defineProperty(exports, "AiraCallbackHandler", { enumerable: true, get: function () { return langchain_1.AiraCallbackHandler; } });
18
18
  var vercel_ai_1 = require("./vercel-ai");
@@ -27,3 +27,5 @@ var webhooks_1 = require("./webhooks");
27
27
  Object.defineProperty(exports, "verifySignature", { enumerable: true, get: function () { return webhooks_1.verifySignature; } });
28
28
  Object.defineProperty(exports, "parseEvent", { enumerable: true, get: function () { return webhooks_1.parseEvent; } });
29
29
  Object.defineProperty(exports, "WebhookEventType", { enumerable: true, get: function () { return webhooks_1.WebhookEventType; } });
30
+ var trust_1 = require("./trust");
31
+ Object.defineProperty(exports, "checkTrust", { enumerable: true, get: function () { return trust_1.checkTrust; } });
@@ -9,15 +9,24 @@
9
9
  * const chain = someChain.withConfig({ callbacks: [handler] });
10
10
  */
11
11
  import type { Aira } from "../client";
12
+ import type { TrustPolicy, TrustContext } from "./trust";
13
+ export type { TrustPolicy, TrustContext } from "./trust";
12
14
  export declare class AiraCallbackHandler {
13
15
  private client;
14
16
  private agentId;
15
17
  private modelId?;
16
18
  private actionTypes;
19
+ private trustPolicy?;
17
20
  constructor(client: Aira, agentId: string, options?: {
18
21
  modelId?: string;
19
22
  actionTypes?: Record<string, string>;
23
+ trustPolicy?: TrustPolicy;
20
24
  });
25
+ /**
26
+ * Check trust for a counterparty agent before interacting.
27
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
28
+ */
29
+ checkTrust(counterpartyId: string): Promise<TrustContext>;
21
30
  private notarize;
22
31
  /** Called when a tool finishes. */
23
32
  handleToolEnd(output: string, name?: string): void;
@@ -11,16 +11,19 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.AiraCallbackHandler = void 0;
14
+ const trust_1 = require("./trust");
14
15
  const MAX_DETAILS = 5000;
15
16
  class AiraCallbackHandler {
16
17
  client;
17
18
  agentId;
18
19
  modelId;
19
20
  actionTypes;
21
+ trustPolicy;
20
22
  constructor(client, agentId, options) {
21
23
  this.client = client;
22
24
  this.agentId = agentId;
23
25
  this.modelId = options?.modelId;
26
+ this.trustPolicy = options?.trustPolicy;
24
27
  this.actionTypes = {
25
28
  tool_end: "tool_call",
26
29
  chain_end: "chain_completed",
@@ -28,6 +31,16 @@ class AiraCallbackHandler {
28
31
  ...(options?.actionTypes ?? {}),
29
32
  };
30
33
  }
34
+ /**
35
+ * Check trust for a counterparty agent before interacting.
36
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
37
+ */
38
+ async checkTrust(counterpartyId) {
39
+ if (!this.trustPolicy) {
40
+ return { counterpartyId, blocked: false, recommendation: "No trust policy configured" };
41
+ }
42
+ return (0, trust_1.checkTrust)(this.client, this.trustPolicy, counterpartyId);
43
+ }
31
44
  notarize(actionType, details) {
32
45
  try {
33
46
  const params = {
@@ -51,6 +51,51 @@ function getTools() {
51
51
  required: ["receipt_id"],
52
52
  },
53
53
  },
54
+ {
55
+ name: "resolve_did",
56
+ description: "Resolve a did:web DID to its DID document",
57
+ inputSchema: {
58
+ type: "object",
59
+ properties: {
60
+ did: { type: "string", description: "The DID to resolve (e.g. did:web:airaproof.com:agents:my-agent)" },
61
+ },
62
+ required: ["did"],
63
+ },
64
+ },
65
+ {
66
+ name: "verify_credential",
67
+ description: "Verify a Verifiable Credential — checks signature, expiry, and revocation status",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ agent_id: { type: "string", description: "Agent slug whose credential to verify" },
72
+ },
73
+ required: ["agent_id"],
74
+ },
75
+ },
76
+ {
77
+ name: "get_reputation",
78
+ description: "Get the current reputation score and tier for an agent",
79
+ inputSchema: {
80
+ type: "object",
81
+ properties: {
82
+ agent_id: { type: "string", description: "Agent slug" },
83
+ },
84
+ required: ["agent_id"],
85
+ },
86
+ },
87
+ {
88
+ name: "request_mutual_sign",
89
+ description: "Initiate a mutual signing request for an action with a counterparty",
90
+ inputSchema: {
91
+ type: "object",
92
+ properties: {
93
+ action_id: { type: "string", description: "Action UUID to co-sign" },
94
+ counterparty_did: { type: "string", description: "DID of the counterparty agent" },
95
+ },
96
+ required: ["action_id", "counterparty_did"],
97
+ },
98
+ },
54
99
  ];
55
100
  }
56
101
  /** Handle an MCP tool call and return text content. */
@@ -73,6 +118,23 @@ async function handleToolCall(client, name, args) {
73
118
  const result = await client.getReceipt(args.receipt_id);
74
119
  return [{ type: "text", text: JSON.stringify(result) }];
75
120
  }
121
+ if (name === "resolve_did") {
122
+ const result = await client.resolveDid(args.did);
123
+ return [{ type: "text", text: JSON.stringify(result) }];
124
+ }
125
+ if (name === "verify_credential") {
126
+ const cred = await client.getAgentCredential(args.agent_id);
127
+ const result = await client.verifyCredential(cred);
128
+ return [{ type: "text", text: JSON.stringify(result) }];
129
+ }
130
+ if (name === "get_reputation") {
131
+ const result = await client.getReputation(args.agent_id);
132
+ return [{ type: "text", text: JSON.stringify(result) }];
133
+ }
134
+ if (name === "request_mutual_sign") {
135
+ const result = await client.requestMutualSign(args.action_id, args.counterparty_did);
136
+ return [{ type: "text", text: JSON.stringify(result) }];
137
+ }
76
138
  return [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }) }];
77
139
  }
78
140
  catch (e) {
@@ -9,13 +9,22 @@
9
9
  * guardrail.onToolCall("search", { query: "test" });
10
10
  */
11
11
  import type { Aira } from "../client";
12
+ import type { TrustPolicy, TrustContext } from "./trust";
13
+ export type { TrustPolicy, TrustContext } from "./trust";
12
14
  export declare class AiraGuardrail {
13
15
  private client;
14
16
  private agentId;
15
17
  private modelId?;
18
+ private trustPolicy?;
16
19
  constructor(client: Aira, agentId: string, options?: {
17
20
  modelId?: string;
21
+ trustPolicy?: TrustPolicy;
18
22
  });
23
+ /**
24
+ * Check trust for a counterparty agent before interacting.
25
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
26
+ */
27
+ checkTrust(counterpartyId: string): Promise<TrustContext>;
19
28
  private notarize;
20
29
  /** Call after a tool execution to notarize it. */
21
30
  onToolCall(toolName: string, args?: Record<string, unknown>): void;
@@ -11,15 +11,28 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.AiraGuardrail = void 0;
14
+ const trust_1 = require("./trust");
14
15
  const MAX_DETAILS = 5000;
15
16
  class AiraGuardrail {
16
17
  client;
17
18
  agentId;
18
19
  modelId;
20
+ trustPolicy;
19
21
  constructor(client, agentId, options) {
20
22
  this.client = client;
21
23
  this.agentId = agentId;
22
24
  this.modelId = options?.modelId;
25
+ this.trustPolicy = options?.trustPolicy;
26
+ }
27
+ /**
28
+ * Check trust for a counterparty agent before interacting.
29
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
30
+ */
31
+ async checkTrust(counterpartyId) {
32
+ if (!this.trustPolicy) {
33
+ return { counterpartyId, blocked: false, recommendation: "No trust policy configured" };
34
+ }
35
+ return (0, trust_1.checkTrust)(this.client, this.trustPolicy, counterpartyId);
23
36
  }
24
37
  notarize(actionType, details) {
25
38
  try {
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Trust layer types and helpers shared across all framework integrations.
3
+ */
4
+ import type { Aira } from "../client";
5
+ /** Policy for automated trust checks before tool execution. */
6
+ export interface TrustPolicy {
7
+ verifyCounterparty?: boolean;
8
+ minReputation?: number;
9
+ requireValidVc?: boolean;
10
+ blockRevokedVc?: boolean;
11
+ blockUnregistered?: boolean;
12
+ }
13
+ /** Result of a trust check against a counterparty agent. */
14
+ export interface TrustContext {
15
+ counterpartyId?: string;
16
+ didResolved?: boolean;
17
+ did?: string;
18
+ vcValid?: boolean | null;
19
+ reputationScore?: number | null;
20
+ reputationTier?: string | null;
21
+ reputationWarning?: string;
22
+ blocked?: boolean;
23
+ blockReason?: string;
24
+ recommendation?: string;
25
+ }
26
+ /**
27
+ * Run a trust check against a counterparty agent.
28
+ *
29
+ * Advisory by default — populates TrustContext with warnings.
30
+ * Only blocks when `blockRevokedVc` is set and the VC is revoked,
31
+ * or when `blockUnregistered` is set and the DID cannot be resolved.
32
+ */
33
+ export declare function checkTrust(client: Aira, policy: TrustPolicy, counterpartyId: string): Promise<TrustContext>;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Trust layer types and helpers shared across all framework integrations.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.checkTrust = checkTrust;
7
+ /**
8
+ * Run a trust check against a counterparty agent.
9
+ *
10
+ * Advisory by default — populates TrustContext with warnings.
11
+ * Only blocks when `blockRevokedVc` is set and the VC is revoked,
12
+ * or when `blockUnregistered` is set and the DID cannot be resolved.
13
+ */
14
+ async function checkTrust(client, policy, counterpartyId) {
15
+ const ctx = {
16
+ counterpartyId,
17
+ blocked: false,
18
+ };
19
+ // Step 1: Resolve DID
20
+ if (policy.verifyCounterparty || policy.requireValidVc || policy.blockUnregistered) {
21
+ try {
22
+ const didResult = await client.resolveDid(`did:web:airaproof.com:agents:${counterpartyId}`);
23
+ ctx.didResolved = true;
24
+ ctx.did = didResult.did;
25
+ }
26
+ catch {
27
+ ctx.didResolved = false;
28
+ if (policy.blockUnregistered) {
29
+ ctx.blocked = true;
30
+ ctx.blockReason = `Agent '${counterpartyId}' DID could not be resolved`;
31
+ return ctx;
32
+ }
33
+ ctx.recommendation = `Could not resolve DID for '${counterpartyId}' — proceed with caution`;
34
+ return ctx;
35
+ }
36
+ }
37
+ // Step 2: Verify credential
38
+ if (policy.requireValidVc || policy.blockRevokedVc) {
39
+ try {
40
+ const cred = await client.getAgentCredential(counterpartyId);
41
+ const verification = await client.verifyCredential(cred);
42
+ const valid = verification.valid;
43
+ ctx.vcValid = valid;
44
+ if (!valid && policy.blockRevokedVc) {
45
+ ctx.blocked = true;
46
+ ctx.blockReason = `Agent '${counterpartyId}' has a revoked or invalid credential`;
47
+ return ctx;
48
+ }
49
+ if (!valid) {
50
+ ctx.recommendation = `Credential for '${counterpartyId}' is invalid — proceed with caution`;
51
+ }
52
+ }
53
+ catch {
54
+ ctx.vcValid = null;
55
+ if (policy.blockRevokedVc) {
56
+ ctx.recommendation = `Could not verify credential for '${counterpartyId}' — treating as unknown`;
57
+ }
58
+ }
59
+ }
60
+ // Step 3: Check reputation
61
+ if (policy.minReputation != null) {
62
+ try {
63
+ const rep = await client.getReputation(counterpartyId);
64
+ ctx.reputationScore = rep.score;
65
+ ctx.reputationTier = rep.tier;
66
+ if (ctx.reputationScore != null && ctx.reputationScore < policy.minReputation) {
67
+ ctx.reputationWarning = `Reputation ${ctx.reputationScore} is below minimum ${policy.minReputation}`;
68
+ ctx.recommendation = ctx.reputationWarning;
69
+ }
70
+ }
71
+ catch {
72
+ ctx.reputationScore = null;
73
+ ctx.reputationWarning = `Could not fetch reputation for '${counterpartyId}'`;
74
+ }
75
+ }
76
+ return ctx;
77
+ }
@@ -9,13 +9,22 @@
9
9
  * // Use as wrap around tool calls or stream callbacks
10
10
  */
11
11
  import type { Aira } from "../client";
12
+ import type { TrustPolicy, TrustContext } from "./trust";
13
+ export type { TrustPolicy, TrustContext } from "./trust";
12
14
  export declare class AiraVercelMiddleware {
13
15
  private client;
14
16
  private agentId;
15
17
  private modelId?;
18
+ private trustPolicy?;
16
19
  constructor(client: Aira, agentId: string, options?: {
17
20
  modelId?: string;
21
+ trustPolicy?: TrustPolicy;
18
22
  });
23
+ /**
24
+ * Check trust for a counterparty agent before interacting.
25
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
26
+ */
27
+ checkTrust(counterpartyId: string): Promise<TrustContext>;
19
28
  private notarize;
20
29
  /** Call after a tool execution to notarize it. */
21
30
  onToolCall(toolName: string, argKeys?: string[]): void;
@@ -11,15 +11,28 @@
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.AiraVercelMiddleware = void 0;
14
+ const trust_1 = require("./trust");
14
15
  const MAX_DETAILS = 5000;
15
16
  class AiraVercelMiddleware {
16
17
  client;
17
18
  agentId;
18
19
  modelId;
20
+ trustPolicy;
19
21
  constructor(client, agentId, options) {
20
22
  this.client = client;
21
23
  this.agentId = agentId;
22
24
  this.modelId = options?.modelId;
25
+ this.trustPolicy = options?.trustPolicy;
26
+ }
27
+ /**
28
+ * Check trust for a counterparty agent before interacting.
29
+ * Advisory by default — only blocks on revoked VC or unregistered agent if configured.
30
+ */
31
+ async checkTrust(counterpartyId) {
32
+ if (!this.trustPolicy) {
33
+ return { counterpartyId, blocked: false, recommendation: "No trust policy configured" };
34
+ }
35
+ return (0, trust_1.checkTrust)(this.client, this.trustPolicy, counterpartyId);
23
36
  }
24
37
  notarize(actionType, details) {
25
38
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aira-sdk",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "TypeScript SDK for Aira — legal infrastructure for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",