aira-sdk 2.1.0 → 3.0.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/dist/client.d.ts +85 -2
- package/dist/client.js +204 -9
- package/dist/extras/langchain.d.ts +2 -2
- package/dist/extras/langchain.js +4 -4
- package/dist/extras/mcp.js +16 -16
- package/dist/extras/openai-agents.d.ts +1 -1
- package/dist/extras/openai-agents.js +3 -3
- package/dist/extras/vercel-ai.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/dist/types.d.ts +139 -15
- package/dist/types.js +12 -2
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Authorization, ActionReceipt, ActionDetail, AgentDetail, AgentVersion, CosignResult, EvidencePackage, ComplianceSnapshot, EscrowAccount, EscrowTransaction, VerifyResult, PaginatedList } from "./types";
|
|
1
|
+
import { Authorization, ActionReceipt, ActionDetail, AgentDetail, AgentVersion, CosignResult, EvidencePackage, ComplianceSnapshot, EscrowAccount, EscrowTransaction, VerifyResult, PaginatedList, ComplianceReport, ComplianceReportListResponse, ComplianceReportVerification, ActionExplanation, ExplanationVerification, OutputPolicy, OutputPolicyUpdate } from "./types";
|
|
2
2
|
import { AiraSession } from "./session";
|
|
3
3
|
export interface AiraOptions {
|
|
4
4
|
apiKey: string;
|
|
@@ -16,6 +16,7 @@ export declare class Aira {
|
|
|
16
16
|
private get;
|
|
17
17
|
private post;
|
|
18
18
|
private put;
|
|
19
|
+
private patch;
|
|
19
20
|
private del;
|
|
20
21
|
private paginated;
|
|
21
22
|
/**
|
|
@@ -23,7 +24,7 @@ export declare class Aira {
|
|
|
23
24
|
*
|
|
24
25
|
* Returns an `Authorization` with a status:
|
|
25
26
|
* - "authorized" → safe to execute the action, then call `notarize()`
|
|
26
|
-
* - "pending_approval" → enqueue `
|
|
27
|
+
* - "pending_approval" → enqueue `action_uuid` and wait for human approval
|
|
27
28
|
*
|
|
28
29
|
* If a policy denies the action, this throws `AiraError` with code
|
|
29
30
|
* `POLICY_DENIED` (HTTP 403). Duplicate idempotent requests throw
|
|
@@ -271,6 +272,88 @@ export declare class Aira {
|
|
|
271
272
|
getSettlement(settlementId: string): Promise<Record<string, unknown>>;
|
|
272
273
|
/** Get the Merkle inclusion proof for one receipt in its settlement. */
|
|
273
274
|
getSettlementInclusionProof(receiptId: string): Promise<Record<string, unknown>>;
|
|
275
|
+
/**
|
|
276
|
+
* Generate a regulatory PDF report.
|
|
277
|
+
*
|
|
278
|
+
* Frameworks:
|
|
279
|
+
* - `eu_ai_act_art12` — Annex VII technical file. Requires period.
|
|
280
|
+
* - `eu_ai_act_art9` — risk management register. Requires period.
|
|
281
|
+
* - `eu_ai_act_art6` — single-action explanation. Requires actionId.
|
|
282
|
+
* - `eu_ai_act_annex_iv` — full Annex IV technical documentation
|
|
283
|
+
* (§§1..9). Requires period. Typical use: annual file for the
|
|
284
|
+
* high-risk AI system provider obligations in Article 11.
|
|
285
|
+
*/
|
|
286
|
+
createComplianceReport(params: {
|
|
287
|
+
framework: string;
|
|
288
|
+
periodStart?: string;
|
|
289
|
+
periodEnd?: string;
|
|
290
|
+
actionId?: string;
|
|
291
|
+
agentFilter?: string[];
|
|
292
|
+
}): Promise<ComplianceReport>;
|
|
293
|
+
/** Get the metadata for a compliance report (no PDF bytes). */
|
|
294
|
+
getComplianceReport(reportId: string): Promise<ComplianceReport>;
|
|
295
|
+
/** List compliance reports with optional filters. */
|
|
296
|
+
listComplianceReports(params?: {
|
|
297
|
+
framework?: string;
|
|
298
|
+
status?: string;
|
|
299
|
+
limit?: number;
|
|
300
|
+
offset?: number;
|
|
301
|
+
}): Promise<ComplianceReportListResponse>;
|
|
302
|
+
/**
|
|
303
|
+
* Download the generated PDF as raw bytes (Uint8Array).
|
|
304
|
+
*
|
|
305
|
+
* Retries on transient 5xx and network errors (3 attempts,
|
|
306
|
+
* exponential backoff). 4xx responses surface immediately.
|
|
307
|
+
*/
|
|
308
|
+
downloadComplianceReport(reportId: string): Promise<Uint8Array>;
|
|
309
|
+
/** Verify a compliance report's signature and content hash. */
|
|
310
|
+
verifyComplianceReport(reportId: string): Promise<ComplianceReportVerification>;
|
|
311
|
+
/**
|
|
312
|
+
* Return the org's output content-scan policy.
|
|
313
|
+
*
|
|
314
|
+
* Scans apply to the `outcomeDetails` passed to `notarize()`. Mode
|
|
315
|
+
* controls behaviour:
|
|
316
|
+
* - `flag` — hits are recorded on the receipt, nothing blocked
|
|
317
|
+
* - `deny` — a hit at or above `deny_severity_threshold` makes
|
|
318
|
+
* notarize return 422 with code `OUTPUT_SCAN_VIOLATION`
|
|
319
|
+
* - `redact` — matched spans are replaced with `[REDACTED]` and
|
|
320
|
+
* the receipt signs over the cleaned bytes
|
|
321
|
+
*/
|
|
322
|
+
getOutputPolicy(): Promise<OutputPolicy>;
|
|
323
|
+
/**
|
|
324
|
+
* Merge the supplied fields into the org's output content-scan
|
|
325
|
+
* policy. Omitted fields stay at their current values. Admin role
|
|
326
|
+
* required server-side.
|
|
327
|
+
*/
|
|
328
|
+
updateOutputPolicy(updates: OutputPolicyUpdate): Promise<OutputPolicy>;
|
|
329
|
+
/**
|
|
330
|
+
* Article 6 right-to-explanation for a single action.
|
|
331
|
+
*
|
|
332
|
+
* The response includes a cryptographic ``_envelope`` — verify it
|
|
333
|
+
* later with {@link verifyActionExplanation} (the verify endpoint
|
|
334
|
+
* is public, so anyone holding the JSON can re-check it).
|
|
335
|
+
*/
|
|
336
|
+
getActionExplanation(actionId: string): Promise<ActionExplanation>;
|
|
337
|
+
/**
|
|
338
|
+
* Public verify — recompute an explanation envelope's signature.
|
|
339
|
+
*
|
|
340
|
+
* POSTs the full explanation JSON to the unauthenticated
|
|
341
|
+
* ``/verify/explanation`` endpoint. The server looks up the public
|
|
342
|
+
* key by ``_envelope.signing_key_id`` and re-derives the canonical
|
|
343
|
+
* content hash + Ed25519 signature.
|
|
344
|
+
*
|
|
345
|
+
* ``request_id`` is stripped before sending, so a saved JSON
|
|
346
|
+
* explanation verifies the same way regardless of whether the
|
|
347
|
+
* caller round-tripped it through their own logs.
|
|
348
|
+
*/
|
|
349
|
+
verifyActionExplanation(explanation: ActionExplanation | Record<string, unknown>): Promise<ExplanationVerification>;
|
|
350
|
+
/**
|
|
351
|
+
* Download the Article 6 explanation as a PDF.
|
|
352
|
+
*
|
|
353
|
+
* Retries on transient 5xx and network errors (3 attempts,
|
|
354
|
+
* exponential backoff). 4xx responses surface immediately.
|
|
355
|
+
*/
|
|
356
|
+
downloadActionExplanationPdf(actionId: string): Promise<Uint8Array>;
|
|
274
357
|
/** Create a scoped session with pre-filled defaults. */
|
|
275
358
|
session(agentId: string, defaults?: Record<string, unknown>): AiraSession;
|
|
276
359
|
/** Number of queued offline requests. */
|
package/dist/client.js
CHANGED
|
@@ -7,6 +7,44 @@ const session_1 = require("./session");
|
|
|
7
7
|
const DEFAULT_BASE_URL = "https://api.airaproof.com";
|
|
8
8
|
const DEFAULT_TIMEOUT = 30_000;
|
|
9
9
|
const MAX_DETAILS_LENGTH = 50_000;
|
|
10
|
+
// Binary download endpoints retry on transient 5xx (server hiccups,
|
|
11
|
+
// brief gateway issues). 3 attempts with exponential backoff
|
|
12
|
+
// (250ms -> 500ms -> 1000ms) keeps the worst case under 2s while
|
|
13
|
+
// absorbing the most common flakes. 4xx errors are NOT retried —
|
|
14
|
+
// those indicate a real problem the caller needs to see.
|
|
15
|
+
const DOWNLOAD_MAX_ATTEMPTS = 3;
|
|
16
|
+
const DOWNLOAD_BACKOFF_BASE_MS = 250;
|
|
17
|
+
function sleep(ms) {
|
|
18
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a fetch with retries on transient 5xx and network errors.
|
|
22
|
+
* Returns the final Response (which may itself be a 5xx after all
|
|
23
|
+
* attempts are exhausted — caller decides whether to throw).
|
|
24
|
+
*/
|
|
25
|
+
async function fetchWithRetry(doFetch) {
|
|
26
|
+
let lastErr;
|
|
27
|
+
for (let attempt = 0; attempt < DOWNLOAD_MAX_ATTEMPTS; attempt++) {
|
|
28
|
+
try {
|
|
29
|
+
const res = await doFetch();
|
|
30
|
+
if (res.status >= 500 && attempt < DOWNLOAD_MAX_ATTEMPTS - 1) {
|
|
31
|
+
await sleep(DOWNLOAD_BACKOFF_BASE_MS * 2 ** attempt);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
lastErr = err;
|
|
38
|
+
if (attempt < DOWNLOAD_MAX_ATTEMPTS - 1) {
|
|
39
|
+
await sleep(DOWNLOAD_BACKOFF_BASE_MS * 2 ** attempt);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Unreachable in practice — the loop either returns or throws.
|
|
46
|
+
throw lastErr ?? new Error("download retry loop exited without a response");
|
|
47
|
+
}
|
|
10
48
|
function buildBody(obj) {
|
|
11
49
|
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined && v !== null));
|
|
12
50
|
}
|
|
@@ -76,6 +114,13 @@ class Aira {
|
|
|
76
114
|
}
|
|
77
115
|
return this.request("PUT", path, body);
|
|
78
116
|
}
|
|
117
|
+
patch(path, body) {
|
|
118
|
+
if (this.queue) {
|
|
119
|
+
const qid = this.queue.enqueue("PATCH", path, body);
|
|
120
|
+
return Promise.resolve({ _offline: true, _queue_id: qid });
|
|
121
|
+
}
|
|
122
|
+
return this.request("PATCH", path, body);
|
|
123
|
+
}
|
|
79
124
|
del(path) {
|
|
80
125
|
if (this.queue) {
|
|
81
126
|
const qid = this.queue.enqueue("DELETE", path, {});
|
|
@@ -93,7 +138,7 @@ class Aira {
|
|
|
93
138
|
*
|
|
94
139
|
* Returns an `Authorization` with a status:
|
|
95
140
|
* - "authorized" → safe to execute the action, then call `notarize()`
|
|
96
|
-
* - "pending_approval" → enqueue `
|
|
141
|
+
* - "pending_approval" → enqueue `action_uuid` and wait for human approval
|
|
97
142
|
*
|
|
98
143
|
* If a policy denies the action, this throws `AiraError` with code
|
|
99
144
|
* `POLICY_DENIED` (HTTP 403). Duplicate idempotent requests throw
|
|
@@ -108,7 +153,7 @@ class Aira {
|
|
|
108
153
|
instruction_hash: params.instructionHash,
|
|
109
154
|
model_id: params.modelId,
|
|
110
155
|
model_version: params.modelVersion,
|
|
111
|
-
|
|
156
|
+
parent_action_uuid: params.parentActionId,
|
|
112
157
|
endpoint_url: params.endpointUrl,
|
|
113
158
|
store_details: params.storeDetails || undefined,
|
|
114
159
|
idempotency_key: params.idempotencyKey,
|
|
@@ -202,7 +247,7 @@ class Aira {
|
|
|
202
247
|
return this.post(`/agents/${slug}/decommission`, {});
|
|
203
248
|
}
|
|
204
249
|
async transferAgent(slug, toOrgId, reason) {
|
|
205
|
-
return this.post(`/agents/${slug}/transfer`, buildBody({
|
|
250
|
+
return this.post(`/agents/${slug}/transfer`, buildBody({ to_org_uuid: toOrgId, reason }));
|
|
206
251
|
}
|
|
207
252
|
async getAgentActions(slug, page = 1) {
|
|
208
253
|
const data = await this.get(`/agents/${slug}/actions`, { page });
|
|
@@ -232,7 +277,7 @@ class Aira {
|
|
|
232
277
|
// ==================== Evidence ====================
|
|
233
278
|
async createEvidencePackage(params) {
|
|
234
279
|
return this.post("/evidence/packages", buildBody({
|
|
235
|
-
title: params.title,
|
|
280
|
+
title: params.title, action_uuids: params.actionIds, description: params.description, agent_slugs: params.agentSlugs,
|
|
236
281
|
}));
|
|
237
282
|
}
|
|
238
283
|
async listEvidencePackages(page = 1) {
|
|
@@ -282,7 +327,7 @@ class Aira {
|
|
|
282
327
|
async createEscrowAccount(params) {
|
|
283
328
|
return this.post("/escrow/accounts", buildBody({
|
|
284
329
|
purpose: params?.purpose, currency: params?.currency ?? "EUR",
|
|
285
|
-
agent_id: params?.agentId,
|
|
330
|
+
agent_id: params?.agentId, counterparty_org_uuid: params?.counterpartyOrgId,
|
|
286
331
|
}));
|
|
287
332
|
}
|
|
288
333
|
async listEscrowAccounts(page = 1) {
|
|
@@ -294,17 +339,17 @@ class Aira {
|
|
|
294
339
|
}
|
|
295
340
|
async escrowDeposit(accountId, amount, description, referenceActionId) {
|
|
296
341
|
return this.post(`/escrow/accounts/${accountId}/deposit`, buildBody({
|
|
297
|
-
amount, description,
|
|
342
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
298
343
|
}));
|
|
299
344
|
}
|
|
300
345
|
async escrowRelease(accountId, amount, description, referenceActionId) {
|
|
301
346
|
return this.post(`/escrow/accounts/${accountId}/release`, buildBody({
|
|
302
|
-
amount, description,
|
|
347
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
303
348
|
}));
|
|
304
349
|
}
|
|
305
350
|
async escrowDispute(accountId, amount, description, referenceActionId) {
|
|
306
351
|
return this.post(`/escrow/accounts/${accountId}/dispute`, buildBody({
|
|
307
|
-
amount, description,
|
|
352
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
308
353
|
}));
|
|
309
354
|
}
|
|
310
355
|
// ==================== Chat ====================
|
|
@@ -374,7 +419,7 @@ class Aira {
|
|
|
374
419
|
/** Submit a signed attestation of a successful interaction. */
|
|
375
420
|
async attestReputation(slug, counterpartyDid, actionId, attestation, signature) {
|
|
376
421
|
return this.post(`/agents/${slug}/reputation/attest`, {
|
|
377
|
-
counterparty_did: counterpartyDid,
|
|
422
|
+
counterparty_did: counterpartyDid, action_uuid: actionId, attestation, signature,
|
|
378
423
|
});
|
|
379
424
|
}
|
|
380
425
|
/** Verify a reputation score by returning inputs and score_hash. */
|
|
@@ -487,6 +532,156 @@ class Aira {
|
|
|
487
532
|
async getSettlementInclusionProof(receiptId) {
|
|
488
533
|
return this.get(`/settlements/inclusion-proof/${receiptId}`);
|
|
489
534
|
}
|
|
535
|
+
// ==================== Compliance reports (Phase 1) ====================
|
|
536
|
+
/**
|
|
537
|
+
* Generate a regulatory PDF report.
|
|
538
|
+
*
|
|
539
|
+
* Frameworks:
|
|
540
|
+
* - `eu_ai_act_art12` — Annex VII technical file. Requires period.
|
|
541
|
+
* - `eu_ai_act_art9` — risk management register. Requires period.
|
|
542
|
+
* - `eu_ai_act_art6` — single-action explanation. Requires actionId.
|
|
543
|
+
* - `eu_ai_act_annex_iv` — full Annex IV technical documentation
|
|
544
|
+
* (§§1..9). Requires period. Typical use: annual file for the
|
|
545
|
+
* high-risk AI system provider obligations in Article 11.
|
|
546
|
+
*/
|
|
547
|
+
async createComplianceReport(params) {
|
|
548
|
+
const body = buildBody({
|
|
549
|
+
framework: params.framework,
|
|
550
|
+
period_start: params.periodStart,
|
|
551
|
+
period_end: params.periodEnd,
|
|
552
|
+
action_uuid: params.actionId,
|
|
553
|
+
agent_filter: params.agentFilter,
|
|
554
|
+
});
|
|
555
|
+
return this.post("/compliance/reports", body);
|
|
556
|
+
}
|
|
557
|
+
/** Get the metadata for a compliance report (no PDF bytes). */
|
|
558
|
+
async getComplianceReport(reportId) {
|
|
559
|
+
return this.get(`/compliance/reports/${reportId}`);
|
|
560
|
+
}
|
|
561
|
+
/** List compliance reports with optional filters. */
|
|
562
|
+
async listComplianceReports(params) {
|
|
563
|
+
return this.get("/compliance/reports", buildBody({ ...params }));
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Download the generated PDF as raw bytes (Uint8Array).
|
|
567
|
+
*
|
|
568
|
+
* Retries on transient 5xx and network errors (3 attempts,
|
|
569
|
+
* exponential backoff). 4xx responses surface immediately.
|
|
570
|
+
*/
|
|
571
|
+
async downloadComplianceReport(reportId) {
|
|
572
|
+
if (this.queue) {
|
|
573
|
+
throw new types_1.AiraError(0, "OFFLINE", "Downloads are not available in offline mode");
|
|
574
|
+
}
|
|
575
|
+
const controller = new AbortController();
|
|
576
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
577
|
+
try {
|
|
578
|
+
const res = await fetchWithRetry(() => fetch(`${this.baseUrl}/compliance/reports/${reportId}/download`, {
|
|
579
|
+
method: "GET",
|
|
580
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
581
|
+
signal: controller.signal,
|
|
582
|
+
}));
|
|
583
|
+
if (!res.ok) {
|
|
584
|
+
throw new types_1.AiraError(res.status, "DOWNLOAD_FAILED", res.statusText);
|
|
585
|
+
}
|
|
586
|
+
const buf = await res.arrayBuffer();
|
|
587
|
+
return new Uint8Array(buf);
|
|
588
|
+
}
|
|
589
|
+
finally {
|
|
590
|
+
clearTimeout(timer);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/** Verify a compliance report's signature and content hash. */
|
|
594
|
+
async verifyComplianceReport(reportId) {
|
|
595
|
+
return this.get(`/compliance/reports/${reportId}/verify`);
|
|
596
|
+
}
|
|
597
|
+
// ==================== Output content-scan policy ====================
|
|
598
|
+
/**
|
|
599
|
+
* Return the org's output content-scan policy.
|
|
600
|
+
*
|
|
601
|
+
* Scans apply to the `outcomeDetails` passed to `notarize()`. Mode
|
|
602
|
+
* controls behaviour:
|
|
603
|
+
* - `flag` — hits are recorded on the receipt, nothing blocked
|
|
604
|
+
* - `deny` — a hit at or above `deny_severity_threshold` makes
|
|
605
|
+
* notarize return 422 with code `OUTPUT_SCAN_VIOLATION`
|
|
606
|
+
* - `redact` — matched spans are replaced with `[REDACTED]` and
|
|
607
|
+
* the receipt signs over the cleaned bytes
|
|
608
|
+
*/
|
|
609
|
+
async getOutputPolicy() {
|
|
610
|
+
return this.get("/output-policies");
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Merge the supplied fields into the org's output content-scan
|
|
614
|
+
* policy. Omitted fields stay at their current values. Admin role
|
|
615
|
+
* required server-side.
|
|
616
|
+
*/
|
|
617
|
+
async updateOutputPolicy(updates) {
|
|
618
|
+
// Strip undefined so they don't travel as `null` and accidentally
|
|
619
|
+
// reset server-side values.
|
|
620
|
+
const body = {};
|
|
621
|
+
for (const [k, v] of Object.entries(updates)) {
|
|
622
|
+
if (v !== undefined)
|
|
623
|
+
body[k] = v;
|
|
624
|
+
}
|
|
625
|
+
return this.patch("/output-policies", body);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Article 6 right-to-explanation for a single action.
|
|
629
|
+
*
|
|
630
|
+
* The response includes a cryptographic ``_envelope`` — verify it
|
|
631
|
+
* later with {@link verifyActionExplanation} (the verify endpoint
|
|
632
|
+
* is public, so anyone holding the JSON can re-check it).
|
|
633
|
+
*/
|
|
634
|
+
async getActionExplanation(actionId) {
|
|
635
|
+
return this.get(`/actions/${actionId}/explanation`);
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Public verify — recompute an explanation envelope's signature.
|
|
639
|
+
*
|
|
640
|
+
* POSTs the full explanation JSON to the unauthenticated
|
|
641
|
+
* ``/verify/explanation`` endpoint. The server looks up the public
|
|
642
|
+
* key by ``_envelope.signing_key_id`` and re-derives the canonical
|
|
643
|
+
* content hash + Ed25519 signature.
|
|
644
|
+
*
|
|
645
|
+
* ``request_id`` is stripped before sending, so a saved JSON
|
|
646
|
+
* explanation verifies the same way regardless of whether the
|
|
647
|
+
* caller round-tripped it through their own logs.
|
|
648
|
+
*/
|
|
649
|
+
async verifyActionExplanation(explanation) {
|
|
650
|
+
const payload = {};
|
|
651
|
+
for (const [k, v] of Object.entries(explanation)) {
|
|
652
|
+
if (k === "request_id")
|
|
653
|
+
continue;
|
|
654
|
+
payload[k] = v;
|
|
655
|
+
}
|
|
656
|
+
return this.request("POST", "/verify/explanation", { explanation: payload }, false);
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Download the Article 6 explanation as a PDF.
|
|
660
|
+
*
|
|
661
|
+
* Retries on transient 5xx and network errors (3 attempts,
|
|
662
|
+
* exponential backoff). 4xx responses surface immediately.
|
|
663
|
+
*/
|
|
664
|
+
async downloadActionExplanationPdf(actionId) {
|
|
665
|
+
if (this.queue) {
|
|
666
|
+
throw new types_1.AiraError(0, "OFFLINE", "Downloads are not available in offline mode");
|
|
667
|
+
}
|
|
668
|
+
const controller = new AbortController();
|
|
669
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
670
|
+
try {
|
|
671
|
+
const res = await fetchWithRetry(() => fetch(`${this.baseUrl}/actions/${actionId}/explanation/pdf`, {
|
|
672
|
+
method: "GET",
|
|
673
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
674
|
+
signal: controller.signal,
|
|
675
|
+
}));
|
|
676
|
+
if (!res.ok) {
|
|
677
|
+
throw new types_1.AiraError(res.status, "DOWNLOAD_FAILED", res.statusText);
|
|
678
|
+
}
|
|
679
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
680
|
+
}
|
|
681
|
+
finally {
|
|
682
|
+
clearTimeout(timer);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
490
685
|
// ==================== Session ====================
|
|
491
686
|
/** Create a scoped session with pre-filled defaults. */
|
|
492
687
|
session(agentId, defaults) {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* This handler implements the two-step flow as follows:
|
|
17
17
|
*
|
|
18
18
|
* 1. handleToolStart → aira.authorize()
|
|
19
|
-
* - If the backend returns "authorized" we cache the
|
|
19
|
+
* - If the backend returns "authorized" we cache the action_uuid
|
|
20
20
|
* keyed by LangChain's `runId`, then return so the tool executes.
|
|
21
21
|
* - If the backend throws POLICY_DENIED we propagate the error,
|
|
22
22
|
* which prevents the tool from running at all (real gate).
|
|
@@ -51,7 +51,7 @@ export declare class AiraCallbackHandler {
|
|
|
51
51
|
private actionTypes;
|
|
52
52
|
private trustPolicy?;
|
|
53
53
|
private strict;
|
|
54
|
-
/** runId →
|
|
54
|
+
/** runId → action_uuid cache so handleEnd can notarize the right action. */
|
|
55
55
|
private inFlight;
|
|
56
56
|
constructor(client: Aira, agentId: string, options?: AiraCallbackHandlerOptions);
|
|
57
57
|
/**
|
package/dist/extras/langchain.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* This handler implements the two-step flow as follows:
|
|
18
18
|
*
|
|
19
19
|
* 1. handleToolStart → aira.authorize()
|
|
20
|
-
* - If the backend returns "authorized" we cache the
|
|
20
|
+
* - If the backend returns "authorized" we cache the action_uuid
|
|
21
21
|
* keyed by LangChain's `runId`, then return so the tool executes.
|
|
22
22
|
* - If the backend throws POLICY_DENIED we propagate the error,
|
|
23
23
|
* which prevents the tool from running at all (real gate).
|
|
@@ -46,7 +46,7 @@ class AiraCallbackHandler {
|
|
|
46
46
|
actionTypes;
|
|
47
47
|
trustPolicy;
|
|
48
48
|
strict;
|
|
49
|
-
/** runId →
|
|
49
|
+
/** runId → action_uuid cache so handleEnd can notarize the right action. */
|
|
50
50
|
inFlight = new Map();
|
|
51
51
|
constructor(client, agentId, options) {
|
|
52
52
|
this.client = client;
|
|
@@ -81,11 +81,11 @@ class AiraCallbackHandler {
|
|
|
81
81
|
});
|
|
82
82
|
if (auth.status === "pending_approval") {
|
|
83
83
|
// Real gate — block the tool from running until a human approves.
|
|
84
|
-
const err = new Error(`Aira: action '${actionType}' is pending human approval (
|
|
84
|
+
const err = new Error(`Aira: action '${actionType}' is pending human approval (action_uuid=${auth.action_uuid}). Tool execution blocked.`);
|
|
85
85
|
err.code = "PENDING_APPROVAL";
|
|
86
86
|
throw err;
|
|
87
87
|
}
|
|
88
|
-
this.inFlight.set(runId, auth.
|
|
88
|
+
this.inFlight.set(runId, auth.action_uuid);
|
|
89
89
|
}
|
|
90
90
|
catch (e) {
|
|
91
91
|
const err = e;
|
package/dist/extras/mcp.js
CHANGED
|
@@ -39,7 +39,7 @@ function getTools() {
|
|
|
39
39
|
return [
|
|
40
40
|
{
|
|
41
41
|
name: "authorize_action",
|
|
42
|
-
description: "Step 1 of the Aira two-step flow. Authorize an action BEFORE it executes. Returns an
|
|
42
|
+
description: "Step 1 of the Aira two-step flow. Authorize an action BEFORE it executes. Returns an action_uuid with status 'authorized' or 'pending_approval'. Throws POLICY_DENIED if a policy blocks the action.",
|
|
43
43
|
inputSchema: {
|
|
44
44
|
type: "object",
|
|
45
45
|
properties: {
|
|
@@ -59,11 +59,11 @@ function getTools() {
|
|
|
59
59
|
inputSchema: {
|
|
60
60
|
type: "object",
|
|
61
61
|
properties: {
|
|
62
|
-
|
|
62
|
+
action_uuid: { type: "string", description: "action_uuid returned from authorize_action" },
|
|
63
63
|
outcome: { type: "string", enum: ["completed", "failed"], description: "Did the action succeed?" },
|
|
64
64
|
outcome_details: { type: "string", description: "Optional description of the outcome" },
|
|
65
65
|
},
|
|
66
|
-
required: ["
|
|
66
|
+
required: ["action_uuid"],
|
|
67
67
|
},
|
|
68
68
|
},
|
|
69
69
|
{
|
|
@@ -72,9 +72,9 @@ function getTools() {
|
|
|
72
72
|
inputSchema: {
|
|
73
73
|
type: "object",
|
|
74
74
|
properties: {
|
|
75
|
-
|
|
75
|
+
action_uuid: { type: "string", description: "Action UUID" },
|
|
76
76
|
},
|
|
77
|
-
required: ["
|
|
77
|
+
required: ["action_uuid"],
|
|
78
78
|
},
|
|
79
79
|
},
|
|
80
80
|
{
|
|
@@ -83,9 +83,9 @@ function getTools() {
|
|
|
83
83
|
inputSchema: {
|
|
84
84
|
type: "object",
|
|
85
85
|
properties: {
|
|
86
|
-
|
|
86
|
+
action_uuid: { type: "string", description: "Action UUID" },
|
|
87
87
|
},
|
|
88
|
-
required: ["
|
|
88
|
+
required: ["action_uuid"],
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
91
|
{
|
|
@@ -94,9 +94,9 @@ function getTools() {
|
|
|
94
94
|
inputSchema: {
|
|
95
95
|
type: "object",
|
|
96
96
|
properties: {
|
|
97
|
-
|
|
97
|
+
receipt_uuid: { type: "string", description: "Receipt UUID" },
|
|
98
98
|
},
|
|
99
|
-
required: ["
|
|
99
|
+
required: ["receipt_uuid"],
|
|
100
100
|
},
|
|
101
101
|
},
|
|
102
102
|
{
|
|
@@ -138,10 +138,10 @@ function getTools() {
|
|
|
138
138
|
inputSchema: {
|
|
139
139
|
type: "object",
|
|
140
140
|
properties: {
|
|
141
|
-
|
|
141
|
+
action_uuid: { type: "string", description: "Action UUID to co-sign" },
|
|
142
142
|
counterparty_did: { type: "string", description: "DID of the counterparty agent" },
|
|
143
143
|
},
|
|
144
|
-
required: ["
|
|
144
|
+
required: ["action_uuid", "counterparty_did"],
|
|
145
145
|
},
|
|
146
146
|
},
|
|
147
147
|
];
|
|
@@ -162,22 +162,22 @@ async function handleToolCall(client, name, args) {
|
|
|
162
162
|
}
|
|
163
163
|
if (name === "notarize_action") {
|
|
164
164
|
const result = await client.notarize({
|
|
165
|
-
actionId: args.
|
|
165
|
+
actionId: args.action_uuid,
|
|
166
166
|
outcome: args.outcome ?? "completed",
|
|
167
167
|
outcomeDetails: args.outcome_details,
|
|
168
168
|
});
|
|
169
169
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
170
170
|
}
|
|
171
171
|
if (name === "get_action") {
|
|
172
|
-
const result = await client.getAction(args.
|
|
172
|
+
const result = await client.getAction(args.action_uuid);
|
|
173
173
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
174
174
|
}
|
|
175
175
|
if (name === "verify_action") {
|
|
176
|
-
const result = await client.verifyAction(args.
|
|
176
|
+
const result = await client.verifyAction(args.action_uuid);
|
|
177
177
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
178
178
|
}
|
|
179
179
|
if (name === "get_receipt") {
|
|
180
|
-
const result = await client.getReceipt(args.
|
|
180
|
+
const result = await client.getReceipt(args.receipt_uuid);
|
|
181
181
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
182
182
|
}
|
|
183
183
|
if (name === "resolve_did") {
|
|
@@ -194,7 +194,7 @@ async function handleToolCall(client, name, args) {
|
|
|
194
194
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
195
195
|
}
|
|
196
196
|
if (name === "request_mutual_sign") {
|
|
197
|
-
const result = await client.requestMutualSign(args.
|
|
197
|
+
const result = await client.requestMutualSign(args.action_uuid, args.counterparty_did);
|
|
198
198
|
return [{ type: "text", text: JSON.stringify(result) }];
|
|
199
199
|
}
|
|
200
200
|
return [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }) }];
|
|
@@ -49,7 +49,7 @@ export declare class AiraGuardrail {
|
|
|
49
49
|
/**
|
|
50
50
|
* REAL GATE: call `authorize()` for a tool invocation.
|
|
51
51
|
*
|
|
52
|
-
* Returns the
|
|
52
|
+
* Returns the action_uuid on success, throws on POLICY_DENIED or
|
|
53
53
|
* pending_approval. Arg keys are logged (not values) to avoid leaking
|
|
54
54
|
* sensitive user input into audit trails.
|
|
55
55
|
*/
|
|
@@ -56,7 +56,7 @@ class AiraGuardrail {
|
|
|
56
56
|
/**
|
|
57
57
|
* REAL GATE: call `authorize()` for a tool invocation.
|
|
58
58
|
*
|
|
59
|
-
* Returns the
|
|
59
|
+
* Returns the action_uuid on success, throws on POLICY_DENIED or
|
|
60
60
|
* pending_approval. Arg keys are logged (not values) to avoid leaking
|
|
61
61
|
* sensitive user input into audit trails.
|
|
62
62
|
*/
|
|
@@ -70,11 +70,11 @@ class AiraGuardrail {
|
|
|
70
70
|
modelId: this.modelId,
|
|
71
71
|
});
|
|
72
72
|
if (auth.status === "pending_approval") {
|
|
73
|
-
const err = new Error(`Aira: tool '${toolName}' is pending human approval (
|
|
73
|
+
const err = new Error(`Aira: tool '${toolName}' is pending human approval (action_uuid=${auth.action_uuid}). Tool execution blocked.`);
|
|
74
74
|
err.code = "PENDING_APPROVAL";
|
|
75
75
|
throw err;
|
|
76
76
|
}
|
|
77
|
-
return auth.
|
|
77
|
+
return auth.action_uuid;
|
|
78
78
|
}
|
|
79
79
|
catch (e) {
|
|
80
80
|
const err = e;
|
package/dist/extras/vercel-ai.js
CHANGED
|
@@ -69,7 +69,7 @@ class AiraVercelMiddleware {
|
|
|
69
69
|
modelId: this.modelId,
|
|
70
70
|
});
|
|
71
71
|
if (auth.status === "authorized") {
|
|
72
|
-
await this.client.notarize({ actionId: auth.
|
|
72
|
+
await this.client.notarize({ actionId: auth.action_uuid, outcome: "completed" });
|
|
73
73
|
}
|
|
74
74
|
// If pending_approval — just leave it; nothing to execute for audit-only.
|
|
75
75
|
}
|
|
@@ -134,11 +134,11 @@ class AiraVercelMiddleware {
|
|
|
134
134
|
modelId: self.modelId,
|
|
135
135
|
});
|
|
136
136
|
if (auth.status === "pending_approval") {
|
|
137
|
-
const err = new Error(`Aira: tool '${toolName}' is pending human approval (
|
|
137
|
+
const err = new Error(`Aira: tool '${toolName}' is pending human approval (action_uuid=${auth.action_uuid}). Tool execution blocked.`);
|
|
138
138
|
err.code = "PENDING_APPROVAL";
|
|
139
139
|
throw err;
|
|
140
140
|
}
|
|
141
|
-
actionId = auth.
|
|
141
|
+
actionId = auth.action_uuid;
|
|
142
142
|
}
|
|
143
143
|
catch (e) {
|
|
144
144
|
const err = e;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export type { AiraOptions } from "./client";
|
|
|
3
3
|
export { AiraSession } from "./session";
|
|
4
4
|
export { OfflineQueue } from "./offline";
|
|
5
5
|
export type { QueuedRequest } from "./offline";
|
|
6
|
-
export { AiraError, type Authorization, type ActionReceipt, type ActionDetail, type AgentDetail, type AgentVersion, type CosignResult, type EvidencePackage, type ComplianceSnapshot, type EscrowAccount, type EscrowTransaction, type VerifyResult, type PaginatedList, } from "./types";
|
|
6
|
+
export { AiraError, FRAMEWORK_ANNEX_IV, FRAMEWORK_ART12, FRAMEWORK_ART9, FRAMEWORK_ART6, type Authorization, type ActionReceipt, type ActionDetail, type AgentDetail, type AgentVersion, type CosignResult, type EvidencePackage, type ComplianceSnapshot, type EscrowAccount, type EscrowTransaction, type VerifyResult, type PaginatedList, type ComplianceReport, type ComplianceReportListResponse, type ComplianceReportVerification, type ActionExplanation, type ExplanationEnvelope, type ExplanationVerification, type OutputPolicy, type OutputPolicyUpdate, type OutputScanFlags, type OutputScanHit, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AiraError = exports.OfflineQueue = exports.AiraSession = exports.Aira = void 0;
|
|
3
|
+
exports.FRAMEWORK_ART6 = exports.FRAMEWORK_ART9 = exports.FRAMEWORK_ART12 = exports.FRAMEWORK_ANNEX_IV = exports.AiraError = exports.OfflineQueue = exports.AiraSession = exports.Aira = void 0;
|
|
4
4
|
var client_1 = require("./client");
|
|
5
5
|
Object.defineProperty(exports, "Aira", { enumerable: true, get: function () { return client_1.Aira; } });
|
|
6
6
|
var session_1 = require("./session");
|
|
@@ -9,3 +9,7 @@ var offline_1 = require("./offline");
|
|
|
9
9
|
Object.defineProperty(exports, "OfflineQueue", { enumerable: true, get: function () { return offline_1.OfflineQueue; } });
|
|
10
10
|
var types_1 = require("./types");
|
|
11
11
|
Object.defineProperty(exports, "AiraError", { enumerable: true, get: function () { return types_1.AiraError; } });
|
|
12
|
+
Object.defineProperty(exports, "FRAMEWORK_ANNEX_IV", { enumerable: true, get: function () { return types_1.FRAMEWORK_ANNEX_IV; } });
|
|
13
|
+
Object.defineProperty(exports, "FRAMEWORK_ART12", { enumerable: true, get: function () { return types_1.FRAMEWORK_ART12; } });
|
|
14
|
+
Object.defineProperty(exports, "FRAMEWORK_ART9", { enumerable: true, get: function () { return types_1.FRAMEWORK_ART9; } });
|
|
15
|
+
Object.defineProperty(exports, "FRAMEWORK_ART6", { enumerable: true, get: function () { return types_1.FRAMEWORK_ART6; } });
|
package/dist/session.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* AiraSession — scoped session with pre-filled defaults for `authorize()`.
|
|
3
3
|
*
|
|
4
4
|
* Under the two-step flow, only `authorize()` takes agent/model metadata;
|
|
5
|
-
* `notarize()` operates on an existing
|
|
5
|
+
* `notarize()` operates on an existing action_uuid. This session therefore
|
|
6
6
|
* merges defaults on `authorize()` only and provides a thin passthrough
|
|
7
7
|
* for `notarize()` so callers can use a single object end-to-end.
|
|
8
8
|
*/
|
package/dist/session.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* AiraSession — scoped session with pre-filled defaults for `authorize()`.
|
|
4
4
|
*
|
|
5
5
|
* Under the two-step flow, only `authorize()` takes agent/model metadata;
|
|
6
|
-
* `notarize()` operates on an existing
|
|
6
|
+
* `notarize()` operates on an existing action_uuid. This session therefore
|
|
7
7
|
* merges defaults on `authorize()` only and provides a thin passthrough
|
|
8
8
|
* for `notarize()` so callers can use a single object end-to-end.
|
|
9
9
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance framework identifiers — string values accepted by
|
|
3
|
+
* `Aira.createComplianceReport()` and returned on `ComplianceReport.framework`.
|
|
4
|
+
* Import these constants rather than hard-coding the wire strings so
|
|
5
|
+
* callers stay in lockstep with the backend if a name ever changes.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FRAMEWORK_ART12: "eu_ai_act_art12";
|
|
8
|
+
export declare const FRAMEWORK_ART9: "eu_ai_act_art9";
|
|
9
|
+
export declare const FRAMEWORK_ART6: "eu_ai_act_art6";
|
|
10
|
+
export declare const FRAMEWORK_ANNEX_IV: "eu_ai_act_annex_iv";
|
|
1
11
|
/**
|
|
2
12
|
* Authorization result from `authorize()` — Step 1 of the two-step flow.
|
|
3
13
|
*
|
|
4
14
|
* Status tells you what to do next:
|
|
5
15
|
* - "authorized" → execute the action, then call `notarize()`
|
|
6
|
-
* - "pending_approval" → enqueue the
|
|
16
|
+
* - "pending_approval" → enqueue the action_uuid and wait for human approval
|
|
7
17
|
*
|
|
8
18
|
* POLICY_DENIED is raised as an `AiraError` — not returned as a status.
|
|
9
19
|
*/
|
|
10
20
|
export interface Authorization {
|
|
11
|
-
|
|
21
|
+
action_uuid: string;
|
|
12
22
|
status: "authorized" | "pending_approval";
|
|
13
23
|
created_at: string;
|
|
14
24
|
request_id: string;
|
|
@@ -21,36 +31,76 @@ export interface Authorization {
|
|
|
21
31
|
* the receipt fields stay null — only the audit trail is recorded.
|
|
22
32
|
*/
|
|
23
33
|
export interface ActionReceipt {
|
|
24
|
-
|
|
34
|
+
action_uuid: string;
|
|
25
35
|
status: "notarized" | "failed";
|
|
26
36
|
created_at: string;
|
|
27
37
|
request_id: string;
|
|
28
|
-
|
|
38
|
+
receipt_uuid: string | null;
|
|
29
39
|
payload_hash: string | null;
|
|
30
40
|
signature: string | null;
|
|
31
41
|
timestamp_token: string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Output content-scan result attached at notarize time when the
|
|
44
|
+
* org has an output policy enabled. ``null`` when output filtering
|
|
45
|
+
* is off (global flag or per-org).
|
|
46
|
+
*/
|
|
47
|
+
output_scan_flags?: OutputScanFlags | null;
|
|
32
48
|
warnings: string[] | null;
|
|
33
49
|
}
|
|
50
|
+
export interface OutputScanHit {
|
|
51
|
+
name: string;
|
|
52
|
+
library: string;
|
|
53
|
+
severity: "info" | "warning" | "critical";
|
|
54
|
+
description: string;
|
|
55
|
+
matches: number;
|
|
56
|
+
/** Always `"[REDACTED]"` — the matched fragment never travels. */
|
|
57
|
+
sample: string;
|
|
58
|
+
}
|
|
59
|
+
export interface OutputScanFlags {
|
|
60
|
+
scanned_at: string;
|
|
61
|
+
libraries: string[];
|
|
62
|
+
mode: "flag" | "deny" | "redact";
|
|
63
|
+
decision: "allow" | "require_approval" | "deny";
|
|
64
|
+
worst_severity: "info" | "warning" | "critical" | null;
|
|
65
|
+
hits: OutputScanHit[];
|
|
66
|
+
}
|
|
67
|
+
export interface OutputPolicy {
|
|
68
|
+
enabled: boolean;
|
|
69
|
+
mode: "flag" | "deny" | "redact";
|
|
70
|
+
libraries: string[];
|
|
71
|
+
deny_severity_threshold: "info" | "warning" | "critical";
|
|
72
|
+
redact_severity_threshold: "info" | "warning" | "critical";
|
|
73
|
+
request_id: string;
|
|
74
|
+
}
|
|
75
|
+
export interface OutputPolicyUpdate {
|
|
76
|
+
enabled?: boolean;
|
|
77
|
+
mode?: "flag" | "deny" | "redact";
|
|
78
|
+
libraries?: string[];
|
|
79
|
+
deny_severity_threshold?: "info" | "warning" | "critical";
|
|
80
|
+
redact_severity_threshold?: "info" | "warning" | "critical";
|
|
81
|
+
}
|
|
34
82
|
/** Full action details including receipt and authorizations. */
|
|
35
83
|
export interface ActionDetail {
|
|
36
|
-
|
|
84
|
+
action_uuid: string;
|
|
85
|
+
org_uuid: string;
|
|
37
86
|
action_type: string;
|
|
38
87
|
action_details_hash: string;
|
|
39
88
|
agent_id: string | null;
|
|
40
89
|
model_id: string | null;
|
|
41
90
|
instruction_hash: string | null;
|
|
42
|
-
|
|
91
|
+
parent_action_uuid: string | null;
|
|
43
92
|
status: string;
|
|
44
93
|
legal_hold: boolean;
|
|
45
94
|
created_at: string;
|
|
46
95
|
receipt: {
|
|
47
|
-
|
|
96
|
+
receipt_uuid: string;
|
|
48
97
|
payload_hash: string;
|
|
49
98
|
signature: string;
|
|
50
99
|
public_key_id: string;
|
|
51
100
|
timestamp_token: string | null;
|
|
52
101
|
receipt_version: string;
|
|
53
102
|
verify_url: string;
|
|
103
|
+
created_at: string | null;
|
|
54
104
|
} | null;
|
|
55
105
|
authorizations: {
|
|
56
106
|
id: string;
|
|
@@ -58,6 +108,10 @@ export interface ActionDetail {
|
|
|
58
108
|
authorized_at: string | null;
|
|
59
109
|
}[];
|
|
60
110
|
request_id: string;
|
|
111
|
+
system_prompt_hash?: string | null;
|
|
112
|
+
tool_inputs_hash?: string | null;
|
|
113
|
+
model_params?: Record<string, unknown> | null;
|
|
114
|
+
execution_env?: Record<string, unknown> | null;
|
|
61
115
|
}
|
|
62
116
|
/** Registered agent identity. */
|
|
63
117
|
export interface AgentDetail {
|
|
@@ -90,7 +144,7 @@ export interface EvidencePackage {
|
|
|
90
144
|
id: string;
|
|
91
145
|
title: string;
|
|
92
146
|
description: string | null;
|
|
93
|
-
|
|
147
|
+
action_uuids: string[];
|
|
94
148
|
package_hash: string;
|
|
95
149
|
signature: string;
|
|
96
150
|
status: string;
|
|
@@ -120,7 +174,7 @@ export interface EscrowAccount {
|
|
|
120
174
|
created_at: string;
|
|
121
175
|
request_id: string;
|
|
122
176
|
agent_id?: string | null;
|
|
123
|
-
|
|
177
|
+
counterparty_org_uuid?: string | null;
|
|
124
178
|
purpose?: string | null;
|
|
125
179
|
transactions?: EscrowTransaction[];
|
|
126
180
|
}
|
|
@@ -135,7 +189,7 @@ export interface EscrowTransaction {
|
|
|
135
189
|
status: string;
|
|
136
190
|
created_at: string;
|
|
137
191
|
description?: string | null;
|
|
138
|
-
|
|
192
|
+
reference_action_uuid?: string | null;
|
|
139
193
|
}
|
|
140
194
|
/**
|
|
141
195
|
* Result of a public action receipt verification.
|
|
@@ -155,14 +209,19 @@ export interface VerifyResult {
|
|
|
155
209
|
message: string;
|
|
156
210
|
verified_at: string;
|
|
157
211
|
request_id: string;
|
|
158
|
-
|
|
159
|
-
|
|
212
|
+
receipt_uuid?: string | null;
|
|
213
|
+
action_uuid?: string | null;
|
|
160
214
|
payload_hash?: string | null;
|
|
161
215
|
signature?: string | null;
|
|
162
216
|
public_key?: string | null;
|
|
163
217
|
algorithm?: string | null;
|
|
164
218
|
timestamp_token?: string | null;
|
|
165
219
|
signed_payload?: Record<string, unknown> | null;
|
|
220
|
+
policy_evaluator_attestation?: {
|
|
221
|
+
evaluator_key_id: string;
|
|
222
|
+
signature: string;
|
|
223
|
+
payload_hash: string;
|
|
224
|
+
} | null;
|
|
166
225
|
}
|
|
167
226
|
/** Paginated list response. */
|
|
168
227
|
export interface PaginatedList<T = Record<string, unknown>> {
|
|
@@ -180,8 +239,8 @@ export interface PaginatedList<T = Record<string, unknown>> {
|
|
|
180
239
|
* (and optionally already notarized).
|
|
181
240
|
*/
|
|
182
241
|
export interface CosignResult {
|
|
183
|
-
|
|
184
|
-
|
|
242
|
+
cosignature_uuid: string;
|
|
243
|
+
action_uuid: string;
|
|
185
244
|
cosigner_email: string;
|
|
186
245
|
cosigned_at: string;
|
|
187
246
|
request_id: string;
|
|
@@ -198,7 +257,72 @@ export declare class AiraError extends Error {
|
|
|
198
257
|
statusCode: number;
|
|
199
258
|
/** Error code string (e.g. "POLICY_DENIED", "INVALID_STATE"). */
|
|
200
259
|
code: string;
|
|
201
|
-
/** Optional backend-supplied context (
|
|
260
|
+
/** Optional backend-supplied context (policy_uuid, action_uuid, etc.). */
|
|
202
261
|
details: Record<string, unknown>;
|
|
203
262
|
constructor(statusCode: number, code: string, message: string, details?: Record<string, unknown>);
|
|
204
263
|
}
|
|
264
|
+
export interface ComplianceReport {
|
|
265
|
+
id: string;
|
|
266
|
+
framework: string;
|
|
267
|
+
status: "pending" | "generating" | "ready" | "failed";
|
|
268
|
+
created_at: string;
|
|
269
|
+
request_id?: string;
|
|
270
|
+
org_uuid?: string;
|
|
271
|
+
period_start?: string | null;
|
|
272
|
+
period_end?: string | null;
|
|
273
|
+
action_uuid?: string | null;
|
|
274
|
+
agent_filter?: string[] | null;
|
|
275
|
+
receipt_count?: number | null;
|
|
276
|
+
pdf_size_bytes?: number | null;
|
|
277
|
+
content_hash?: string | null;
|
|
278
|
+
signature?: string | null;
|
|
279
|
+
signing_key_id?: string | null;
|
|
280
|
+
timestamp_token?: string | null;
|
|
281
|
+
timestamp_token_present?: boolean;
|
|
282
|
+
report_metadata?: Record<string, unknown> | null;
|
|
283
|
+
error_message?: string | null;
|
|
284
|
+
generated_at?: string | null;
|
|
285
|
+
}
|
|
286
|
+
export interface ComplianceReportListResponse {
|
|
287
|
+
items: ComplianceReport[];
|
|
288
|
+
total: number;
|
|
289
|
+
limit: number;
|
|
290
|
+
offset: number;
|
|
291
|
+
request_id: string;
|
|
292
|
+
}
|
|
293
|
+
export interface ComplianceReportVerification {
|
|
294
|
+
report_uuid: string;
|
|
295
|
+
valid: boolean;
|
|
296
|
+
checks: Record<string, unknown>;
|
|
297
|
+
descriptor?: Record<string, unknown> | null;
|
|
298
|
+
request_id: string;
|
|
299
|
+
}
|
|
300
|
+
export interface ExplanationEnvelope {
|
|
301
|
+
alg: string;
|
|
302
|
+
signing_key_id: string;
|
|
303
|
+
content_hash: string;
|
|
304
|
+
signature: string;
|
|
305
|
+
generated_at: string;
|
|
306
|
+
}
|
|
307
|
+
export interface ActionExplanation {
|
|
308
|
+
action: Record<string, unknown>;
|
|
309
|
+
policy_chain: Array<Record<string, unknown>>;
|
|
310
|
+
approval_chain: Array<Record<string, unknown>>;
|
|
311
|
+
receipt?: Record<string, unknown> | null;
|
|
312
|
+
regulation: Record<string, unknown>;
|
|
313
|
+
/**
|
|
314
|
+
* Ed25519 signature over the canonical JSON of every field above
|
|
315
|
+
* (except ``_envelope`` itself and ``request_id``). The on-wire key
|
|
316
|
+
* is ``_envelope`` — the SDK exposes it under the same name so a
|
|
317
|
+
* saved ``JSON.stringify(explanation)`` round-trips through
|
|
318
|
+
* :meth:`Aira.verifyActionExplanation` untouched.
|
|
319
|
+
*/
|
|
320
|
+
_envelope?: ExplanationEnvelope;
|
|
321
|
+
request_id: string;
|
|
322
|
+
}
|
|
323
|
+
export interface ExplanationVerification {
|
|
324
|
+
valid: boolean;
|
|
325
|
+
checks: Record<string, unknown>;
|
|
326
|
+
signing_key_id?: string | null;
|
|
327
|
+
request_id: string;
|
|
328
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AiraError = void 0;
|
|
3
|
+
exports.AiraError = exports.FRAMEWORK_ANNEX_IV = exports.FRAMEWORK_ART6 = exports.FRAMEWORK_ART9 = exports.FRAMEWORK_ART12 = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Compliance framework identifiers — string values accepted by
|
|
6
|
+
* `Aira.createComplianceReport()` and returned on `ComplianceReport.framework`.
|
|
7
|
+
* Import these constants rather than hard-coding the wire strings so
|
|
8
|
+
* callers stay in lockstep with the backend if a name ever changes.
|
|
9
|
+
*/
|
|
10
|
+
exports.FRAMEWORK_ART12 = "eu_ai_act_art12";
|
|
11
|
+
exports.FRAMEWORK_ART9 = "eu_ai_act_art9";
|
|
12
|
+
exports.FRAMEWORK_ART6 = "eu_ai_act_art6";
|
|
13
|
+
exports.FRAMEWORK_ANNEX_IV = "eu_ai_act_annex_iv";
|
|
4
14
|
/**
|
|
5
15
|
* Aira API error.
|
|
6
16
|
*
|
|
@@ -13,7 +23,7 @@ class AiraError extends Error {
|
|
|
13
23
|
statusCode;
|
|
14
24
|
/** Error code string (e.g. "POLICY_DENIED", "INVALID_STATE"). */
|
|
15
25
|
code;
|
|
16
|
-
/** Optional backend-supplied context (
|
|
26
|
+
/** Optional backend-supplied context (policy_uuid, action_uuid, etc.). */
|
|
17
27
|
details;
|
|
18
28
|
constructor(statusCode, code, message, details = {}) {
|
|
19
29
|
super(`[${code}] ${message}`);
|