aira-sdk 2.4.0 → 3.1.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 +99 -2
- package/dist/client.js +150 -10
- 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/session.d.ts +1 -1
- package/dist/session.js +1 -1
- package/dist/types.d.ts +75 -19
- package/dist/types.js +1 -1
- 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, ComplianceReport, ComplianceReportListResponse, ComplianceReportVerification, ActionExplanation, ExplanationVerification, OutputPolicy, OutputPolicyUpdate } from "./types";
|
|
1
|
+
import { Authorization, ActionReceipt, ActionDetail, AgentDetail, AgentVersion, CosignResult, EvidencePackage, ComplianceSnapshot, EscrowAccount, EscrowTransaction, VerifyResult, PaginatedList, ComplianceReport, ComplianceReportListResponse, ComplianceReportVerification, ActionExplanation, ExplanationVerification, OutputPolicy, OutputPolicyUpdate, DoraIncident, IctThirdParty, DoraTest } from "./types";
|
|
2
2
|
import { AiraSession } from "./session";
|
|
3
3
|
export interface AiraOptions {
|
|
4
4
|
apiKey: string;
|
|
@@ -24,7 +24,7 @@ export declare class Aira {
|
|
|
24
24
|
*
|
|
25
25
|
* Returns an `Authorization` with a status:
|
|
26
26
|
* - "authorized" → safe to execute the action, then call `notarize()`
|
|
27
|
-
* - "pending_approval" → enqueue `
|
|
27
|
+
* - "pending_approval" → enqueue `action_uuid` and wait for human approval
|
|
28
28
|
*
|
|
29
29
|
* If a policy denies the action, this throws `AiraError` with code
|
|
30
30
|
* `POLICY_DENIED` (HTTP 403). Duplicate idempotent requests throw
|
|
@@ -326,6 +326,103 @@ export declare class Aira {
|
|
|
326
326
|
* required server-side.
|
|
327
327
|
*/
|
|
328
328
|
updateOutputPolicy(updates: OutputPolicyUpdate): Promise<OutputPolicy>;
|
|
329
|
+
/** Open a new DORA ICT incident (Article 17). */
|
|
330
|
+
createDoraIncident(params: {
|
|
331
|
+
title: string;
|
|
332
|
+
description: string;
|
|
333
|
+
detectedAt: string;
|
|
334
|
+
affectedServices?: string[];
|
|
335
|
+
clientsAffectedCount?: number;
|
|
336
|
+
geographicScope?: string[];
|
|
337
|
+
relatedActionUuids?: string[];
|
|
338
|
+
}): Promise<DoraIncident>;
|
|
339
|
+
/** List DORA incidents with optional filters. */
|
|
340
|
+
listDoraIncidents(params?: {
|
|
341
|
+
status?: string;
|
|
342
|
+
severity?: string;
|
|
343
|
+
isMajor?: boolean;
|
|
344
|
+
limit?: number;
|
|
345
|
+
offset?: number;
|
|
346
|
+
}): Promise<{
|
|
347
|
+
items: DoraIncident[];
|
|
348
|
+
total: number;
|
|
349
|
+
limit: number;
|
|
350
|
+
offset: number;
|
|
351
|
+
request_id: string;
|
|
352
|
+
}>;
|
|
353
|
+
/** Get one DORA incident. */
|
|
354
|
+
getDoraIncident(incidentUuid: string): Promise<DoraIncident>;
|
|
355
|
+
/** Classify a detected incident (Article 18). */
|
|
356
|
+
classifyDoraIncident(incidentUuid: string, params: {
|
|
357
|
+
severity: "critical" | "high" | "medium" | "low";
|
|
358
|
+
category: string;
|
|
359
|
+
isMajor?: boolean;
|
|
360
|
+
rootCauseSummary?: string;
|
|
361
|
+
rootCauseClassification?: string;
|
|
362
|
+
thirdPartyUuid?: string;
|
|
363
|
+
}): Promise<DoraIncident>;
|
|
364
|
+
/** Mark an incident resolved + record post-mortem fields. */
|
|
365
|
+
resolveDoraIncident(incidentUuid: string, params: {
|
|
366
|
+
resolutionSummary: string;
|
|
367
|
+
lessonsLearned?: string;
|
|
368
|
+
resolvedAt?: string;
|
|
369
|
+
}): Promise<DoraIncident>;
|
|
370
|
+
/** Generate (if needed) and download the major-incident PDF for ESA submission. */
|
|
371
|
+
downloadDoraIncidentReport(incidentUuid: string): Promise<Uint8Array>;
|
|
372
|
+
/** Add a vendor to the ICT third-party register (Article 28). */
|
|
373
|
+
createIctThirdParty(params: {
|
|
374
|
+
vendorName: string;
|
|
375
|
+
serviceDescription: string;
|
|
376
|
+
serviceType: string;
|
|
377
|
+
criticality: "critical" | "non_critical" | "supporting";
|
|
378
|
+
contractStartDate?: string;
|
|
379
|
+
contractEndDate?: string;
|
|
380
|
+
exitStrategySummary?: string;
|
|
381
|
+
subcontractors?: string[];
|
|
382
|
+
dataCategories?: string[];
|
|
383
|
+
jurisdiction?: string;
|
|
384
|
+
}): Promise<IctThirdParty>;
|
|
385
|
+
/** List ICT third-party register entries. */
|
|
386
|
+
listIctThirdParties(params?: {
|
|
387
|
+
criticality?: string;
|
|
388
|
+
isActive?: boolean;
|
|
389
|
+
limit?: number;
|
|
390
|
+
offset?: number;
|
|
391
|
+
}): Promise<{
|
|
392
|
+
items: IctThirdParty[];
|
|
393
|
+
total: number;
|
|
394
|
+
limit: number;
|
|
395
|
+
offset: number;
|
|
396
|
+
request_id: string;
|
|
397
|
+
}>;
|
|
398
|
+
getIctThirdParty(thirdPartyUuid: string): Promise<IctThirdParty>;
|
|
399
|
+
/** PATCH semantics — only supplied fields change. */
|
|
400
|
+
updateIctThirdParty(thirdPartyUuid: string, fields: Partial<IctThirdParty> & {
|
|
401
|
+
is_active?: boolean;
|
|
402
|
+
}): Promise<IctThirdParty>;
|
|
403
|
+
/** Log a DORA resilience test (Articles 24-27). */
|
|
404
|
+
createDoraTest(params: {
|
|
405
|
+
testType: string;
|
|
406
|
+
title: string;
|
|
407
|
+
scope: string;
|
|
408
|
+
conductedAt: string;
|
|
409
|
+
conductedBy: string;
|
|
410
|
+
status: "passed" | "failed" | "partial";
|
|
411
|
+
findingsSummary?: string;
|
|
412
|
+
remediationPlan?: string;
|
|
413
|
+
remediationDueAt?: string;
|
|
414
|
+
}): Promise<DoraTest>;
|
|
415
|
+
listDoraTests(params?: {
|
|
416
|
+
testType?: string;
|
|
417
|
+
limit?: number;
|
|
418
|
+
offset?: number;
|
|
419
|
+
}): Promise<{
|
|
420
|
+
items: DoraTest[];
|
|
421
|
+
total: number;
|
|
422
|
+
limit: number;
|
|
423
|
+
offset: number;
|
|
424
|
+
request_id: string;
|
|
425
|
+
}>;
|
|
329
426
|
/**
|
|
330
427
|
* Article 6 right-to-explanation for a single action.
|
|
331
428
|
*
|
package/dist/client.js
CHANGED
|
@@ -138,7 +138,7 @@ class Aira {
|
|
|
138
138
|
*
|
|
139
139
|
* Returns an `Authorization` with a status:
|
|
140
140
|
* - "authorized" → safe to execute the action, then call `notarize()`
|
|
141
|
-
* - "pending_approval" → enqueue `
|
|
141
|
+
* - "pending_approval" → enqueue `action_uuid` and wait for human approval
|
|
142
142
|
*
|
|
143
143
|
* If a policy denies the action, this throws `AiraError` with code
|
|
144
144
|
* `POLICY_DENIED` (HTTP 403). Duplicate idempotent requests throw
|
|
@@ -153,7 +153,7 @@ class Aira {
|
|
|
153
153
|
instruction_hash: params.instructionHash,
|
|
154
154
|
model_id: params.modelId,
|
|
155
155
|
model_version: params.modelVersion,
|
|
156
|
-
|
|
156
|
+
parent_action_uuid: params.parentActionId,
|
|
157
157
|
endpoint_url: params.endpointUrl,
|
|
158
158
|
store_details: params.storeDetails || undefined,
|
|
159
159
|
idempotency_key: params.idempotencyKey,
|
|
@@ -247,7 +247,7 @@ class Aira {
|
|
|
247
247
|
return this.post(`/agents/${slug}/decommission`, {});
|
|
248
248
|
}
|
|
249
249
|
async transferAgent(slug, toOrgId, reason) {
|
|
250
|
-
return this.post(`/agents/${slug}/transfer`, buildBody({
|
|
250
|
+
return this.post(`/agents/${slug}/transfer`, buildBody({ to_org_uuid: toOrgId, reason }));
|
|
251
251
|
}
|
|
252
252
|
async getAgentActions(slug, page = 1) {
|
|
253
253
|
const data = await this.get(`/agents/${slug}/actions`, { page });
|
|
@@ -277,7 +277,7 @@ class Aira {
|
|
|
277
277
|
// ==================== Evidence ====================
|
|
278
278
|
async createEvidencePackage(params) {
|
|
279
279
|
return this.post("/evidence/packages", buildBody({
|
|
280
|
-
title: params.title,
|
|
280
|
+
title: params.title, action_uuids: params.actionIds, description: params.description, agent_slugs: params.agentSlugs,
|
|
281
281
|
}));
|
|
282
282
|
}
|
|
283
283
|
async listEvidencePackages(page = 1) {
|
|
@@ -327,7 +327,7 @@ class Aira {
|
|
|
327
327
|
async createEscrowAccount(params) {
|
|
328
328
|
return this.post("/escrow/accounts", buildBody({
|
|
329
329
|
purpose: params?.purpose, currency: params?.currency ?? "EUR",
|
|
330
|
-
agent_id: params?.agentId,
|
|
330
|
+
agent_id: params?.agentId, counterparty_org_uuid: params?.counterpartyOrgId,
|
|
331
331
|
}));
|
|
332
332
|
}
|
|
333
333
|
async listEscrowAccounts(page = 1) {
|
|
@@ -339,17 +339,17 @@ class Aira {
|
|
|
339
339
|
}
|
|
340
340
|
async escrowDeposit(accountId, amount, description, referenceActionId) {
|
|
341
341
|
return this.post(`/escrow/accounts/${accountId}/deposit`, buildBody({
|
|
342
|
-
amount, description,
|
|
342
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
343
343
|
}));
|
|
344
344
|
}
|
|
345
345
|
async escrowRelease(accountId, amount, description, referenceActionId) {
|
|
346
346
|
return this.post(`/escrow/accounts/${accountId}/release`, buildBody({
|
|
347
|
-
amount, description,
|
|
347
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
348
348
|
}));
|
|
349
349
|
}
|
|
350
350
|
async escrowDispute(accountId, amount, description, referenceActionId) {
|
|
351
351
|
return this.post(`/escrow/accounts/${accountId}/dispute`, buildBody({
|
|
352
|
-
amount, description,
|
|
352
|
+
amount, description, reference_action_uuid: referenceActionId,
|
|
353
353
|
}));
|
|
354
354
|
}
|
|
355
355
|
// ==================== Chat ====================
|
|
@@ -419,7 +419,7 @@ class Aira {
|
|
|
419
419
|
/** Submit a signed attestation of a successful interaction. */
|
|
420
420
|
async attestReputation(slug, counterpartyDid, actionId, attestation, signature) {
|
|
421
421
|
return this.post(`/agents/${slug}/reputation/attest`, {
|
|
422
|
-
counterparty_did: counterpartyDid,
|
|
422
|
+
counterparty_did: counterpartyDid, action_uuid: actionId, attestation, signature,
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
425
|
/** Verify a reputation score by returning inputs and score_hash. */
|
|
@@ -549,7 +549,7 @@ class Aira {
|
|
|
549
549
|
framework: params.framework,
|
|
550
550
|
period_start: params.periodStart,
|
|
551
551
|
period_end: params.periodEnd,
|
|
552
|
-
|
|
552
|
+
action_uuid: params.actionId,
|
|
553
553
|
agent_filter: params.agentFilter,
|
|
554
554
|
});
|
|
555
555
|
return this.post("/compliance/reports", body);
|
|
@@ -624,6 +624,146 @@ class Aira {
|
|
|
624
624
|
}
|
|
625
625
|
return this.patch("/output-policies", body);
|
|
626
626
|
}
|
|
627
|
+
// ==================== DORA (EU 2022/2554) ====================
|
|
628
|
+
/** Open a new DORA ICT incident (Article 17). */
|
|
629
|
+
async createDoraIncident(params) {
|
|
630
|
+
const body = buildBody({
|
|
631
|
+
title: params.title,
|
|
632
|
+
description: params.description,
|
|
633
|
+
detected_at: params.detectedAt,
|
|
634
|
+
affected_services: params.affectedServices,
|
|
635
|
+
clients_affected_count: params.clientsAffectedCount,
|
|
636
|
+
geographic_scope: params.geographicScope,
|
|
637
|
+
related_action_uuids: params.relatedActionUuids,
|
|
638
|
+
});
|
|
639
|
+
return this.post("/dora/incidents", body);
|
|
640
|
+
}
|
|
641
|
+
/** List DORA incidents with optional filters. */
|
|
642
|
+
async listDoraIncidents(params) {
|
|
643
|
+
const qs = new URLSearchParams();
|
|
644
|
+
if (params?.status)
|
|
645
|
+
qs.append("status", params.status);
|
|
646
|
+
if (params?.severity)
|
|
647
|
+
qs.append("severity", params.severity);
|
|
648
|
+
if (params?.isMajor !== undefined)
|
|
649
|
+
qs.append("is_major", String(params.isMajor));
|
|
650
|
+
if (params?.limit !== undefined)
|
|
651
|
+
qs.append("limit", String(params.limit));
|
|
652
|
+
if (params?.offset !== undefined)
|
|
653
|
+
qs.append("offset", String(params.offset));
|
|
654
|
+
const path = qs.toString() ? `/dora/incidents?${qs}` : "/dora/incidents";
|
|
655
|
+
return this.get(path);
|
|
656
|
+
}
|
|
657
|
+
/** Get one DORA incident. */
|
|
658
|
+
async getDoraIncident(incidentUuid) {
|
|
659
|
+
return this.get(`/dora/incidents/${incidentUuid}`);
|
|
660
|
+
}
|
|
661
|
+
/** Classify a detected incident (Article 18). */
|
|
662
|
+
async classifyDoraIncident(incidentUuid, params) {
|
|
663
|
+
const body = buildBody({
|
|
664
|
+
severity: params.severity,
|
|
665
|
+
category: params.category,
|
|
666
|
+
is_major: params.isMajor,
|
|
667
|
+
root_cause_summary: params.rootCauseSummary,
|
|
668
|
+
root_cause_classification: params.rootCauseClassification,
|
|
669
|
+
third_party_uuid: params.thirdPartyUuid,
|
|
670
|
+
});
|
|
671
|
+
return this.put(`/dora/incidents/${incidentUuid}/classify`, body);
|
|
672
|
+
}
|
|
673
|
+
/** Mark an incident resolved + record post-mortem fields. */
|
|
674
|
+
async resolveDoraIncident(incidentUuid, params) {
|
|
675
|
+
const body = buildBody({
|
|
676
|
+
resolution_summary: params.resolutionSummary,
|
|
677
|
+
lessons_learned: params.lessonsLearned,
|
|
678
|
+
resolved_at: params.resolvedAt,
|
|
679
|
+
});
|
|
680
|
+
return this.put(`/dora/incidents/${incidentUuid}/resolve`, body);
|
|
681
|
+
}
|
|
682
|
+
/** Generate (if needed) and download the major-incident PDF for ESA submission. */
|
|
683
|
+
async downloadDoraIncidentReport(incidentUuid) {
|
|
684
|
+
if (this.queue) {
|
|
685
|
+
throw new types_1.AiraError(0, "OFFLINE", "Downloads not available offline");
|
|
686
|
+
}
|
|
687
|
+
const controller = new AbortController();
|
|
688
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
689
|
+
try {
|
|
690
|
+
const res = await fetchWithRetry(() => fetch(`${this.baseUrl}/dora/incidents/${incidentUuid}/report`, {
|
|
691
|
+
method: "GET",
|
|
692
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
693
|
+
signal: controller.signal,
|
|
694
|
+
}));
|
|
695
|
+
if (!res.ok) {
|
|
696
|
+
throw new types_1.AiraError(res.status, "DOWNLOAD_FAILED", res.statusText);
|
|
697
|
+
}
|
|
698
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
699
|
+
}
|
|
700
|
+
finally {
|
|
701
|
+
clearTimeout(timer);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
/** Add a vendor to the ICT third-party register (Article 28). */
|
|
705
|
+
async createIctThirdParty(params) {
|
|
706
|
+
const body = buildBody({
|
|
707
|
+
vendor_name: params.vendorName,
|
|
708
|
+
service_description: params.serviceDescription,
|
|
709
|
+
service_type: params.serviceType,
|
|
710
|
+
criticality: params.criticality,
|
|
711
|
+
contract_start_date: params.contractStartDate,
|
|
712
|
+
contract_end_date: params.contractEndDate,
|
|
713
|
+
exit_strategy_summary: params.exitStrategySummary,
|
|
714
|
+
subcontractors: params.subcontractors,
|
|
715
|
+
data_categories: params.dataCategories,
|
|
716
|
+
jurisdiction: params.jurisdiction,
|
|
717
|
+
});
|
|
718
|
+
return this.post("/dora/third-parties", body);
|
|
719
|
+
}
|
|
720
|
+
/** List ICT third-party register entries. */
|
|
721
|
+
async listIctThirdParties(params) {
|
|
722
|
+
const qs = new URLSearchParams();
|
|
723
|
+
if (params?.criticality)
|
|
724
|
+
qs.append("criticality", params.criticality);
|
|
725
|
+
if (params?.isActive !== undefined)
|
|
726
|
+
qs.append("is_active", String(params.isActive));
|
|
727
|
+
if (params?.limit !== undefined)
|
|
728
|
+
qs.append("limit", String(params.limit));
|
|
729
|
+
if (params?.offset !== undefined)
|
|
730
|
+
qs.append("offset", String(params.offset));
|
|
731
|
+
const path = qs.toString() ? `/dora/third-parties?${qs}` : "/dora/third-parties";
|
|
732
|
+
return this.get(path);
|
|
733
|
+
}
|
|
734
|
+
async getIctThirdParty(thirdPartyUuid) {
|
|
735
|
+
return this.get(`/dora/third-parties/${thirdPartyUuid}`);
|
|
736
|
+
}
|
|
737
|
+
/** PATCH semantics — only supplied fields change. */
|
|
738
|
+
async updateIctThirdParty(thirdPartyUuid, fields) {
|
|
739
|
+
return this.put(`/dora/third-parties/${thirdPartyUuid}`, fields);
|
|
740
|
+
}
|
|
741
|
+
/** Log a DORA resilience test (Articles 24-27). */
|
|
742
|
+
async createDoraTest(params) {
|
|
743
|
+
const body = buildBody({
|
|
744
|
+
test_type: params.testType,
|
|
745
|
+
title: params.title,
|
|
746
|
+
scope: params.scope,
|
|
747
|
+
conducted_at: params.conductedAt,
|
|
748
|
+
conducted_by: params.conductedBy,
|
|
749
|
+
status: params.status,
|
|
750
|
+
findings_summary: params.findingsSummary,
|
|
751
|
+
remediation_plan: params.remediationPlan,
|
|
752
|
+
remediation_due_at: params.remediationDueAt,
|
|
753
|
+
});
|
|
754
|
+
return this.post("/dora/tests", body);
|
|
755
|
+
}
|
|
756
|
+
async listDoraTests(params) {
|
|
757
|
+
const qs = new URLSearchParams();
|
|
758
|
+
if (params?.testType)
|
|
759
|
+
qs.append("test_type", params.testType);
|
|
760
|
+
if (params?.limit !== undefined)
|
|
761
|
+
qs.append("limit", String(params.limit));
|
|
762
|
+
if (params?.offset !== undefined)
|
|
763
|
+
qs.append("offset", String(params.offset));
|
|
764
|
+
const path = qs.toString() ? `/dora/tests?${qs}` : "/dora/tests";
|
|
765
|
+
return this.get(path);
|
|
766
|
+
}
|
|
627
767
|
/**
|
|
628
768
|
* Article 6 right-to-explanation for a single action.
|
|
629
769
|
*
|
|
@@ -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, 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";
|
|
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, type DoraIncident, type IctThirdParty, type DoraTest, } from "./types";
|
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
|
@@ -13,12 +13,12 @@ export declare const FRAMEWORK_ANNEX_IV: "eu_ai_act_annex_iv";
|
|
|
13
13
|
*
|
|
14
14
|
* Status tells you what to do next:
|
|
15
15
|
* - "authorized" → execute the action, then call `notarize()`
|
|
16
|
-
* - "pending_approval" → enqueue the
|
|
16
|
+
* - "pending_approval" → enqueue the action_uuid and wait for human approval
|
|
17
17
|
*
|
|
18
18
|
* POLICY_DENIED is raised as an `AiraError` — not returned as a status.
|
|
19
19
|
*/
|
|
20
20
|
export interface Authorization {
|
|
21
|
-
|
|
21
|
+
action_uuid: string;
|
|
22
22
|
status: "authorized" | "pending_approval";
|
|
23
23
|
created_at: string;
|
|
24
24
|
request_id: string;
|
|
@@ -31,11 +31,11 @@ export interface Authorization {
|
|
|
31
31
|
* the receipt fields stay null — only the audit trail is recorded.
|
|
32
32
|
*/
|
|
33
33
|
export interface ActionReceipt {
|
|
34
|
-
|
|
34
|
+
action_uuid: string;
|
|
35
35
|
status: "notarized" | "failed";
|
|
36
36
|
created_at: string;
|
|
37
37
|
request_id: string;
|
|
38
|
-
|
|
38
|
+
receipt_uuid: string | null;
|
|
39
39
|
payload_hash: string | null;
|
|
40
40
|
signature: string | null;
|
|
41
41
|
timestamp_token: string | null;
|
|
@@ -72,6 +72,62 @@ export interface OutputPolicy {
|
|
|
72
72
|
redact_severity_threshold: "info" | "warning" | "critical";
|
|
73
73
|
request_id: string;
|
|
74
74
|
}
|
|
75
|
+
export interface DoraIncident {
|
|
76
|
+
uuid: string;
|
|
77
|
+
title: string;
|
|
78
|
+
status: "detected" | "classified" | "resolved" | "reported";
|
|
79
|
+
severity: "critical" | "high" | "medium" | "low" | null;
|
|
80
|
+
category: string | null;
|
|
81
|
+
is_major: boolean;
|
|
82
|
+
detected_at: string;
|
|
83
|
+
classified_at: string | null;
|
|
84
|
+
resolved_at: string | null;
|
|
85
|
+
reported_at: string | null;
|
|
86
|
+
clients_affected_count: number;
|
|
87
|
+
has_report: boolean;
|
|
88
|
+
created_at: string;
|
|
89
|
+
org_uuid?: string | null;
|
|
90
|
+
description?: string | null;
|
|
91
|
+
affected_services?: string[] | null;
|
|
92
|
+
geographic_scope?: string[] | null;
|
|
93
|
+
root_cause_summary?: string | null;
|
|
94
|
+
root_cause_classification?: string | null;
|
|
95
|
+
third_party_uuid?: string | null;
|
|
96
|
+
resolution_summary?: string | null;
|
|
97
|
+
lessons_learned?: string | null;
|
|
98
|
+
related_action_uuids?: string[] | null;
|
|
99
|
+
report_content_hash?: string | null;
|
|
100
|
+
report_signature?: string | null;
|
|
101
|
+
report_signing_key_id?: string | null;
|
|
102
|
+
report_signed_at?: string | null;
|
|
103
|
+
report_pdf_size_bytes?: number | null;
|
|
104
|
+
request_id?: string;
|
|
105
|
+
}
|
|
106
|
+
export interface IctThirdParty {
|
|
107
|
+
uuid: string;
|
|
108
|
+
org_uuid: string;
|
|
109
|
+
vendor_name: string;
|
|
110
|
+
service_description: string;
|
|
111
|
+
service_type: string;
|
|
112
|
+
criticality: "critical" | "non_critical" | "supporting";
|
|
113
|
+
contract_start_date: string | null;
|
|
114
|
+
contract_end_date: string | null;
|
|
115
|
+
exit_strategy_summary: string | null;
|
|
116
|
+
subcontractors: string[] | null;
|
|
117
|
+
data_categories: string[] | null;
|
|
118
|
+
jurisdiction: string | null;
|
|
119
|
+
is_active: boolean;
|
|
120
|
+
created_at: string;
|
|
121
|
+
request_id?: string;
|
|
122
|
+
}
|
|
123
|
+
export interface DoraTest {
|
|
124
|
+
uuid: string;
|
|
125
|
+
test_type: string;
|
|
126
|
+
title: string;
|
|
127
|
+
conducted_at: string;
|
|
128
|
+
conducted_by: string;
|
|
129
|
+
status: "passed" | "failed" | "partial";
|
|
130
|
+
}
|
|
75
131
|
export interface OutputPolicyUpdate {
|
|
76
132
|
enabled?: boolean;
|
|
77
133
|
mode?: "flag" | "deny" | "redact";
|
|
@@ -81,19 +137,19 @@ export interface OutputPolicyUpdate {
|
|
|
81
137
|
}
|
|
82
138
|
/** Full action details including receipt and authorizations. */
|
|
83
139
|
export interface ActionDetail {
|
|
84
|
-
|
|
85
|
-
|
|
140
|
+
action_uuid: string;
|
|
141
|
+
org_uuid: string;
|
|
86
142
|
action_type: string;
|
|
87
143
|
action_details_hash: string;
|
|
88
144
|
agent_id: string | null;
|
|
89
145
|
model_id: string | null;
|
|
90
146
|
instruction_hash: string | null;
|
|
91
|
-
|
|
147
|
+
parent_action_uuid: string | null;
|
|
92
148
|
status: string;
|
|
93
149
|
legal_hold: boolean;
|
|
94
150
|
created_at: string;
|
|
95
151
|
receipt: {
|
|
96
|
-
|
|
152
|
+
receipt_uuid: string;
|
|
97
153
|
payload_hash: string;
|
|
98
154
|
signature: string;
|
|
99
155
|
public_key_id: string;
|
|
@@ -144,7 +200,7 @@ export interface EvidencePackage {
|
|
|
144
200
|
id: string;
|
|
145
201
|
title: string;
|
|
146
202
|
description: string | null;
|
|
147
|
-
|
|
203
|
+
action_uuids: string[];
|
|
148
204
|
package_hash: string;
|
|
149
205
|
signature: string;
|
|
150
206
|
status: string;
|
|
@@ -174,7 +230,7 @@ export interface EscrowAccount {
|
|
|
174
230
|
created_at: string;
|
|
175
231
|
request_id: string;
|
|
176
232
|
agent_id?: string | null;
|
|
177
|
-
|
|
233
|
+
counterparty_org_uuid?: string | null;
|
|
178
234
|
purpose?: string | null;
|
|
179
235
|
transactions?: EscrowTransaction[];
|
|
180
236
|
}
|
|
@@ -189,7 +245,7 @@ export interface EscrowTransaction {
|
|
|
189
245
|
status: string;
|
|
190
246
|
created_at: string;
|
|
191
247
|
description?: string | null;
|
|
192
|
-
|
|
248
|
+
reference_action_uuid?: string | null;
|
|
193
249
|
}
|
|
194
250
|
/**
|
|
195
251
|
* Result of a public action receipt verification.
|
|
@@ -209,8 +265,8 @@ export interface VerifyResult {
|
|
|
209
265
|
message: string;
|
|
210
266
|
verified_at: string;
|
|
211
267
|
request_id: string;
|
|
212
|
-
|
|
213
|
-
|
|
268
|
+
receipt_uuid?: string | null;
|
|
269
|
+
action_uuid?: string | null;
|
|
214
270
|
payload_hash?: string | null;
|
|
215
271
|
signature?: string | null;
|
|
216
272
|
public_key?: string | null;
|
|
@@ -239,8 +295,8 @@ export interface PaginatedList<T = Record<string, unknown>> {
|
|
|
239
295
|
* (and optionally already notarized).
|
|
240
296
|
*/
|
|
241
297
|
export interface CosignResult {
|
|
242
|
-
|
|
243
|
-
|
|
298
|
+
cosignature_uuid: string;
|
|
299
|
+
action_uuid: string;
|
|
244
300
|
cosigner_email: string;
|
|
245
301
|
cosigned_at: string;
|
|
246
302
|
request_id: string;
|
|
@@ -257,7 +313,7 @@ export declare class AiraError extends Error {
|
|
|
257
313
|
statusCode: number;
|
|
258
314
|
/** Error code string (e.g. "POLICY_DENIED", "INVALID_STATE"). */
|
|
259
315
|
code: string;
|
|
260
|
-
/** Optional backend-supplied context (
|
|
316
|
+
/** Optional backend-supplied context (policy_uuid, action_uuid, etc.). */
|
|
261
317
|
details: Record<string, unknown>;
|
|
262
318
|
constructor(statusCode: number, code: string, message: string, details?: Record<string, unknown>);
|
|
263
319
|
}
|
|
@@ -267,10 +323,10 @@ export interface ComplianceReport {
|
|
|
267
323
|
status: "pending" | "generating" | "ready" | "failed";
|
|
268
324
|
created_at: string;
|
|
269
325
|
request_id?: string;
|
|
270
|
-
|
|
326
|
+
org_uuid?: string;
|
|
271
327
|
period_start?: string | null;
|
|
272
328
|
period_end?: string | null;
|
|
273
|
-
|
|
329
|
+
action_uuid?: string | null;
|
|
274
330
|
agent_filter?: string[] | null;
|
|
275
331
|
receipt_count?: number | null;
|
|
276
332
|
pdf_size_bytes?: number | null;
|
|
@@ -291,7 +347,7 @@ export interface ComplianceReportListResponse {
|
|
|
291
347
|
request_id: string;
|
|
292
348
|
}
|
|
293
349
|
export interface ComplianceReportVerification {
|
|
294
|
-
|
|
350
|
+
report_uuid: string;
|
|
295
351
|
valid: boolean;
|
|
296
352
|
checks: Record<string, unknown>;
|
|
297
353
|
descriptor?: Record<string, unknown> | null;
|
package/dist/types.js
CHANGED
|
@@ -23,7 +23,7 @@ class AiraError extends Error {
|
|
|
23
23
|
statusCode;
|
|
24
24
|
/** Error code string (e.g. "POLICY_DENIED", "INVALID_STATE"). */
|
|
25
25
|
code;
|
|
26
|
-
/** Optional backend-supplied context (
|
|
26
|
+
/** Optional backend-supplied context (policy_uuid, action_uuid, etc.). */
|
|
27
27
|
details;
|
|
28
28
|
constructor(statusCode, code, message, details = {}) {
|
|
29
29
|
super(`[${code}] ${message}`);
|