aira-sdk 2.1.0 → 2.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/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
  /**
@@ -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, {});
@@ -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_id: 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) {
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/types.d.ts CHANGED
@@ -1,3 +1,13 @@
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
  *
@@ -29,11 +39,50 @@ export interface ActionReceipt {
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_id: string;
85
+ org_id: string;
37
86
  action_type: string;
38
87
  action_details_hash: string;
39
88
  agent_id: string | null;
@@ -51,6 +100,7 @@ export interface ActionDetail {
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 {
@@ -163,6 +217,11 @@ export interface VerifyResult {
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>> {
@@ -202,3 +261,68 @@ export declare class AiraError extends Error {
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_id?: string;
271
+ period_start?: string | null;
272
+ period_end?: string | null;
273
+ action_id?: 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_id: 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
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aira-sdk",
3
- "version": "2.1.0",
3
+ "version": "2.4.0",
4
4
  "description": "The authorization and audit layer for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",