agentcert 0.2.7 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/cli.js +8 -0
- package/dist/command-help.js +2 -0
- package/dist/index.js +1 -0
- package/dist/sandbox.js +323 -0
- package/dist/vendor/onegent-runtime/mock-procurement.d.ts +6 -0
- package/dist/vendor/onegent-runtime/mock-procurement.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/mock-procurement.js +33 -0
- package/dist/vendor/onegent-runtime/policies.d.ts +6 -0
- package/dist/vendor/onegent-runtime/policies.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/policies.js +109 -0
- package/dist/vendor/onegent-runtime/risk.d.ts +3 -0
- package/dist/vendor/onegent-runtime/risk.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/risk.js +54 -0
- package/dist/vendor/onegent-runtime/sandbox-adapter-kit.d.ts +45 -0
- package/dist/vendor/onegent-runtime/sandbox-adapter-kit.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/sandbox-adapter-kit.js +148 -0
- package/dist/vendor/onegent-runtime/sandbox-harness.d.ts +167 -0
- package/dist/vendor/onegent-runtime/sandbox-harness.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/sandbox-harness.js +729 -0
- package/dist/vendor/onegent-runtime/sandbox-hosted.d.ts +77 -0
- package/dist/vendor/onegent-runtime/sandbox-hosted.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/sandbox-hosted.js +133 -0
- package/dist/vendor/onegent-runtime/sdk.d.ts +29 -0
- package/dist/vendor/onegent-runtime/sdk.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/sdk.js +140 -0
- package/dist/vendor/onegent-runtime/service.d.ts +27 -0
- package/dist/vendor/onegent-runtime/service.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/service.js +421 -0
- package/dist/vendor/onegent-runtime/store.d.ts +16 -0
- package/dist/vendor/onegent-runtime/store.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/store.js +29 -0
- package/dist/vendor/onegent-runtime/stripe-test-readonly.d.ts +79 -0
- package/dist/vendor/onegent-runtime/stripe-test-readonly.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/stripe-test-readonly.js +163 -0
- package/dist/vendor/onegent-runtime/types.d.ts +284 -0
- package/dist/vendor/onegent-runtime/types.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/types.js +1 -0
- package/dist/vendor/onegent-runtime/vendor-sandbox-egress.d.ts +49 -0
- package/dist/vendor/onegent-runtime/vendor-sandbox-egress.d.ts.map +1 -0
- package/dist/vendor/onegent-runtime/vendor-sandbox-egress.js +152 -0
- package/package.json +2 -2
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SandboxAdapterConformanceReport } from "./sandbox-adapter-kit.js";
|
|
2
|
+
import type { SandboxCertificationReport } from "./sandbox-harness.js";
|
|
3
|
+
import type { StripeSandboxReadOnlyReport } from "./stripe-test-readonly.js";
|
|
4
|
+
export declare const SANDBOX_EVIDENCE_BUNDLE_SCHEMA_VERSION: "agentcert.evidence.v0.1";
|
|
5
|
+
export type HostedSandboxReport = SandboxCertificationReport | SandboxAdapterConformanceReport | StripeSandboxReadOnlyReport;
|
|
6
|
+
export interface SandboxHostedUploadOptions {
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
projectId: string;
|
|
9
|
+
apiKey: string;
|
|
10
|
+
externalId?: string;
|
|
11
|
+
fetch?: typeof fetch;
|
|
12
|
+
}
|
|
13
|
+
export interface SandboxHostedUploadResult {
|
|
14
|
+
run: Record<string, unknown>;
|
|
15
|
+
evidence: Record<string, unknown>;
|
|
16
|
+
completion: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface SandboxCertificationEvidenceBundle {
|
|
19
|
+
schemaName: "agentcert.evidence_bundle";
|
|
20
|
+
schemaVersion: typeof SANDBOX_EVIDENCE_BUNDLE_SCHEMA_VERSION;
|
|
21
|
+
schemaSemver: "0.1.0";
|
|
22
|
+
kind: "agentcert.evidence_bundle";
|
|
23
|
+
runId: string;
|
|
24
|
+
generatedAt: string;
|
|
25
|
+
subject: {
|
|
26
|
+
name: string;
|
|
27
|
+
type: "application";
|
|
28
|
+
};
|
|
29
|
+
verdict: {
|
|
30
|
+
passed: boolean;
|
|
31
|
+
score: number;
|
|
32
|
+
level: string;
|
|
33
|
+
};
|
|
34
|
+
summary: {
|
|
35
|
+
products: ["onegent-runtime"];
|
|
36
|
+
criticalEvidence: number;
|
|
37
|
+
highEvidence: number;
|
|
38
|
+
totalEvidence: 1;
|
|
39
|
+
};
|
|
40
|
+
results: Array<{
|
|
41
|
+
schemaVersion: "1";
|
|
42
|
+
product: "onegent-runtime";
|
|
43
|
+
runId: string;
|
|
44
|
+
timestamp: string;
|
|
45
|
+
phase: "pre-release";
|
|
46
|
+
score: number;
|
|
47
|
+
passed: boolean;
|
|
48
|
+
summary: string;
|
|
49
|
+
artifacts: Record<string, string>;
|
|
50
|
+
evidence: Array<{
|
|
51
|
+
id: string;
|
|
52
|
+
kind: "sandbox_adapter_conformance" | "sandbox_certification" | "sandbox_vendor_egress";
|
|
53
|
+
severity: "info" | "high";
|
|
54
|
+
message: string;
|
|
55
|
+
source: "onegent-runtime";
|
|
56
|
+
metadata: {
|
|
57
|
+
report: HostedSandboxReport;
|
|
58
|
+
reportSchemaVersion: string;
|
|
59
|
+
};
|
|
60
|
+
}>;
|
|
61
|
+
}>;
|
|
62
|
+
evidence: SandboxCertificationEvidenceBundle["results"][number]["evidence"];
|
|
63
|
+
artifacts: Record<string, string>;
|
|
64
|
+
artifactManifest: {
|
|
65
|
+
schemaVersion: "agentcert.artifact_manifest.v0.1";
|
|
66
|
+
entries: [];
|
|
67
|
+
};
|
|
68
|
+
standards: Array<{
|
|
69
|
+
id: "agentcert-sandbox-contract";
|
|
70
|
+
name: "AgentCert Sandbox Adapter Contract";
|
|
71
|
+
status: "mapped";
|
|
72
|
+
note: string;
|
|
73
|
+
}>;
|
|
74
|
+
}
|
|
75
|
+
export declare function createSandboxCertificationEvidenceBundle(report: HostedSandboxReport): SandboxCertificationEvidenceBundle;
|
|
76
|
+
export declare function uploadSandboxCertificationReport(report: HostedSandboxReport, options: SandboxHostedUploadOptions): Promise<SandboxHostedUploadResult>;
|
|
77
|
+
//# sourceMappingURL=sandbox-hosted.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-hosted.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/sandbox-hosted.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAE7E,eAAO,MAAM,sCAAsC,EAAG,yBAAkC,CAAC;AAEzF,MAAM,MAAM,mBAAmB,GAAG,0BAA0B,GAAG,+BAA+B,GAAG,2BAA2B,CAAC;AAE7H,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,kCAAkC;IACjD,UAAU,EAAE,2BAA2B,CAAC;IACxC,aAAa,EAAE,OAAO,sCAAsC,CAAC;IAC7D,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,2BAA2B,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,aAAa,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACP,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE;QACP,QAAQ,EAAE,CAAC,iBAAiB,CAAC,CAAC;QAC9B,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,CAAC,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,KAAK,CAAC;QACb,aAAa,EAAE,GAAG,CAAC;QACnB,OAAO,EAAE,iBAAiB,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,aAAa,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,QAAQ,EAAE,KAAK,CAAC;YACd,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,6BAA6B,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;YACxF,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;YAC1B,OAAO,EAAE,MAAM,CAAC;YAChB,MAAM,EAAE,iBAAiB,CAAC;YAC1B,QAAQ,EAAE;gBAAE,MAAM,EAAE,mBAAmB,CAAC;gBAAC,mBAAmB,EAAE,MAAM,CAAA;aAAE,CAAC;SACxE,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,QAAQ,EAAE,kCAAkC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IAC5E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gBAAgB,EAAE;QAChB,aAAa,EAAE,kCAAkC,CAAC;QAClD,OAAO,EAAE,EAAE,CAAC;KACb,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,4BAA4B,CAAC;QACjC,IAAI,EAAE,oCAAoC,CAAC;QAC3C,MAAM,EAAE,QAAQ,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAED,wBAAgB,wCAAwC,CACtD,MAAM,EAAE,mBAAmB,GAC1B,kCAAkC,CAwDpC;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,CAAC,CAyDpC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export const SANDBOX_EVIDENCE_BUNDLE_SCHEMA_VERSION = "agentcert.evidence.v0.1";
|
|
3
|
+
export function createSandboxCertificationEvidenceBundle(report) {
|
|
4
|
+
const reportDigest = createHash("sha256").update(JSON.stringify(report)).digest("hex");
|
|
5
|
+
const runId = `sandbox-${reportDigest}`;
|
|
6
|
+
const evidence = [{
|
|
7
|
+
id: `${report.kind}:${reportDigest.slice(0, 16)}`,
|
|
8
|
+
kind: report.kind === "agentcert.sandbox_adapter_conformance"
|
|
9
|
+
? "sandbox_adapter_conformance"
|
|
10
|
+
: report.kind === "agentcert.sandbox_vendor_egress"
|
|
11
|
+
? "sandbox_vendor_egress"
|
|
12
|
+
: "sandbox_certification",
|
|
13
|
+
severity: report.verdict.passed ? "info" : "high",
|
|
14
|
+
message: `${report.kind} ${report.verdict.passed ? "passed" : "failed"} (${report.verdict.score}/100).`,
|
|
15
|
+
source: "onegent-runtime",
|
|
16
|
+
metadata: { report: structuredClone(report), reportSchemaVersion: report.schemaVersion },
|
|
17
|
+
}];
|
|
18
|
+
return {
|
|
19
|
+
schemaName: "agentcert.evidence_bundle",
|
|
20
|
+
schemaVersion: SANDBOX_EVIDENCE_BUNDLE_SCHEMA_VERSION,
|
|
21
|
+
schemaSemver: "0.1.0",
|
|
22
|
+
kind: "agentcert.evidence_bundle",
|
|
23
|
+
runId,
|
|
24
|
+
generatedAt: report.generatedAt,
|
|
25
|
+
subject: { name: report.implementation, type: "application" },
|
|
26
|
+
verdict: {
|
|
27
|
+
passed: report.verdict.passed,
|
|
28
|
+
score: report.verdict.score,
|
|
29
|
+
level: report.verdict.passed ? "Sandbox conformant" : "Not conformant",
|
|
30
|
+
},
|
|
31
|
+
summary: {
|
|
32
|
+
products: ["onegent-runtime"],
|
|
33
|
+
criticalEvidence: 0,
|
|
34
|
+
highEvidence: report.verdict.passed ? 0 : 1,
|
|
35
|
+
totalEvidence: 1,
|
|
36
|
+
},
|
|
37
|
+
results: [{
|
|
38
|
+
schemaVersion: "1",
|
|
39
|
+
product: "onegent-runtime",
|
|
40
|
+
runId,
|
|
41
|
+
timestamp: report.generatedAt,
|
|
42
|
+
phase: "pre-release",
|
|
43
|
+
score: report.verdict.score,
|
|
44
|
+
passed: report.verdict.passed,
|
|
45
|
+
summary: `${report.kind} ${report.verdict.passed ? "passed" : "failed"}.`,
|
|
46
|
+
artifacts: {},
|
|
47
|
+
evidence,
|
|
48
|
+
}],
|
|
49
|
+
evidence,
|
|
50
|
+
artifacts: {},
|
|
51
|
+
artifactManifest: { schemaVersion: "agentcert.artifact_manifest.v0.1", entries: [] },
|
|
52
|
+
standards: [{
|
|
53
|
+
id: "agentcert-sandbox-contract",
|
|
54
|
+
name: "AgentCert Sandbox Adapter Contract",
|
|
55
|
+
status: "mapped",
|
|
56
|
+
note: "Synthetic or vendor test-mode evidence only. This does not authorize production access or certify production-side controls.",
|
|
57
|
+
}],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export async function uploadSandboxCertificationReport(report, options) {
|
|
61
|
+
const baseUrl = required(options.baseUrl, "baseUrl").replace(/\/$/, "");
|
|
62
|
+
const projectId = required(options.projectId, "projectId");
|
|
63
|
+
const apiKey = required(options.apiKey, "apiKey");
|
|
64
|
+
const requestFetch = options.fetch ?? fetch;
|
|
65
|
+
const projectUrl = `${baseUrl}/v1/projects/${encodeURIComponent(projectId)}`;
|
|
66
|
+
const bundle = createSandboxCertificationEvidenceBundle(report);
|
|
67
|
+
const bytes = Buffer.from(`${JSON.stringify(bundle, null, 2)}\n`, "utf8");
|
|
68
|
+
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
69
|
+
const operationId = `sandbox-upload-${digest.slice(0, 32)}`;
|
|
70
|
+
const externalId = options.externalId?.trim() || `${report.kind}:${report.implementation}:${report.generatedAt}`;
|
|
71
|
+
const run = await jsonRequest(requestFetch, `${projectUrl}/runs`, apiKey, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { "idempotency-key": `${operationId}:run` },
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
externalId,
|
|
76
|
+
kind: "custom",
|
|
77
|
+
schemaVersion: report.schemaVersion,
|
|
78
|
+
startedAt: report.generatedAt,
|
|
79
|
+
metadata: {
|
|
80
|
+
productLine: "onegent-runtime",
|
|
81
|
+
evidenceType: report.kind,
|
|
82
|
+
implementation: report.implementation,
|
|
83
|
+
sandboxOnly: true,
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
if (typeof run.id !== "string" || !run.id)
|
|
88
|
+
throw new Error("AgentCert Control Plane returned a run without an id.");
|
|
89
|
+
const query = new URLSearchParams({
|
|
90
|
+
fileName: "sandbox-certification-evidence.json",
|
|
91
|
+
kind: "evidence_bundle",
|
|
92
|
+
schemaVersion: SANDBOX_EVIDENCE_BUNDLE_SCHEMA_VERSION,
|
|
93
|
+
runId: run.id,
|
|
94
|
+
});
|
|
95
|
+
const evidence = await jsonRequest(requestFetch, `${projectUrl}/evidence?${query}`, apiKey, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: { "content-type": "application/json" },
|
|
98
|
+
body: new Uint8Array(bytes).buffer,
|
|
99
|
+
});
|
|
100
|
+
const completion = await jsonRequest(requestFetch, `${projectUrl}/runs/${encodeURIComponent(run.id)}/complete`, apiKey, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "idempotency-key": `${operationId}:complete` },
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
status: report.verdict.passed ? "passed" : "failed",
|
|
105
|
+
score: report.verdict.score / 100,
|
|
106
|
+
summary: `${report.kind} ${report.verdict.passed ? "passed" : "failed"} (${report.verdict.score}/100).`,
|
|
107
|
+
metadata: {
|
|
108
|
+
evidenceId: evidence.id,
|
|
109
|
+
evidenceSha256: evidence.sha256,
|
|
110
|
+
sandboxReportSchemaVersion: report.schemaVersion,
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
return { run, evidence, completion };
|
|
115
|
+
}
|
|
116
|
+
async function jsonRequest(requestFetch, url, apiKey, init) {
|
|
117
|
+
const headers = new Headers(init.headers);
|
|
118
|
+
headers.set("authorization", `Bearer ${apiKey}`);
|
|
119
|
+
if (typeof init.body === "string")
|
|
120
|
+
headers.set("content-type", "application/json");
|
|
121
|
+
const response = await requestFetch(url, { ...init, headers, redirect: "error" });
|
|
122
|
+
const value = await response.json().catch(() => ({}));
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
throw new Error(typeof value.error === "string" ? value.error : `AgentCert Control Plane request failed (${response.status}).`);
|
|
125
|
+
}
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
function required(value, name) {
|
|
129
|
+
const normalized = value.trim();
|
|
130
|
+
if (!normalized)
|
|
131
|
+
throw new Error(`Sandbox hosted upload ${name} is required.`);
|
|
132
|
+
return normalized;
|
|
133
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ActionAuditPacket, ActionExecutionSummary, ActionExecutionReceipt, ActionIntent, ActionReview, ApprovalAdapter, ApprovalRequest, AuditStore, AuthorizationPolicy, CreateActionIntentInput, LocalActionAdapter, ExecutionStore, PolicyEngine, PolicyEvaluation, PolicyRule, RiskAssessment, VerificationResult } from "./types.js";
|
|
2
|
+
export interface OnegentRuntimeOptions {
|
|
3
|
+
policyRules?: PolicyRule[];
|
|
4
|
+
policyEngine?: PolicyEngine;
|
|
5
|
+
approvalAdapter?: ApprovalAdapter;
|
|
6
|
+
auditStore?: AuditStore;
|
|
7
|
+
authorizationPolicy?: AuthorizationPolicy;
|
|
8
|
+
executionStore?: ExecutionStore;
|
|
9
|
+
}
|
|
10
|
+
export interface OnegentRuntime {
|
|
11
|
+
captureAction(input: CreateActionIntentInput): ActionReview;
|
|
12
|
+
assessRisk(action: ActionIntent): RiskAssessment;
|
|
13
|
+
evaluatePolicy(action: ActionIntent, risk?: RiskAssessment): PolicyEvaluation;
|
|
14
|
+
requestApproval(action: ActionIntent | string, assignedTo?: string): Promise<ApprovalRequest>;
|
|
15
|
+
approveAction(action: ActionIntent | string, reviewerId?: string, reviewerComment?: string): ActionReview;
|
|
16
|
+
rejectAction(action: ActionIntent | string, reviewerId?: string, reviewerComment?: string): ActionReview;
|
|
17
|
+
executeAfterApproval(action: ActionIntent | string, adapter?: LocalActionAdapter): Promise<ActionExecutionSummary>;
|
|
18
|
+
rollbackAfterExecution(action: ActionIntent | string, adapter: LocalActionAdapter, reason: string): Promise<ActionExecutionReceipt>;
|
|
19
|
+
getExecutionReceipt(action: ActionIntent | string): Promise<ActionExecutionReceipt | undefined>;
|
|
20
|
+
verifyOutcome(action: ActionIntent | string, observedState?: ActionExecutionSummary | Record<string, unknown>): VerificationResult;
|
|
21
|
+
writeAuditPacket(action: ActionIntent | string): Promise<ActionAuditPacket>;
|
|
22
|
+
getActionReview(action: ActionIntent | string): ActionReview;
|
|
23
|
+
listActionReviews(): ActionReview[];
|
|
24
|
+
}
|
|
25
|
+
export declare function createOnegentRuntime(options?: OnegentRuntimeOptions): OnegentRuntime;
|
|
26
|
+
export declare function createInMemoryExecutionStore(name?: string): ExecutionStore & {
|
|
27
|
+
receipts: Map<string, ActionExecutionReceipt>;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/sdk.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,KAAK,EAAE,uBAAuB,GAAG,YAAY,CAAC;IAC5D,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc,CAAC;IACjD,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAC;IAC9E,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9F,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAC1G,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IACzG,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACnH,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACpI,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAAC;IAChG,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,aAAa,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAAC;IACnI,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;IAC7D,iBAAiB,IAAI,YAAY,EAAE,CAAC;CACrC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CA2GxF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,SAA8B,GAAG,cAAc,GAAG;IACjG,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAC/C,CAQA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { evaluatePolicy as evaluatePolicyRules } from "./policies.js";
|
|
2
|
+
import { assessRisk as assessActionRisk } from "./risk.js";
|
|
3
|
+
import { approveAction, captureActionIntent, executeAfterApproval as executeApprovedAction, executeAfterApprovalWithAdapter, generateAuditPacket, getActionReview, listActionReviews, rejectAction, recordRollback, requestApproval as requestActionApproval, verifyOutcome as verifyActionOutcome, } from "./service.js";
|
|
4
|
+
export function createOnegentRuntime(options = {}) {
|
|
5
|
+
const executionStore = options.executionStore ?? createInMemoryExecutionStore();
|
|
6
|
+
const inFlight = new Map();
|
|
7
|
+
const executeOnce = async (actionInput, adapter) => {
|
|
8
|
+
const review = getActionReview(actionId(actionInput));
|
|
9
|
+
const key = review.action.idempotencyKey;
|
|
10
|
+
const existing = await executionStore.get(key);
|
|
11
|
+
if (existing) {
|
|
12
|
+
if (existing.actionIntentId !== review.action.id)
|
|
13
|
+
throw new Error(`Idempotency key ${key} is already bound to another action.`);
|
|
14
|
+
if (existing.status !== "COMPLETED") {
|
|
15
|
+
throw new Error(`Action ${review.action.id} execution is ${existing.status} and cannot be replayed as completed.`);
|
|
16
|
+
}
|
|
17
|
+
return existing.execution;
|
|
18
|
+
}
|
|
19
|
+
const pending = inFlight.get(key);
|
|
20
|
+
if (pending)
|
|
21
|
+
return pending;
|
|
22
|
+
const operation = (async () => {
|
|
23
|
+
const execution = adapter
|
|
24
|
+
? await executeAfterApprovalWithAdapter(review.action.id, adapter, { idempotencyKey: key, attempt: 1 })
|
|
25
|
+
: executeApprovedAction(review.action.id);
|
|
26
|
+
await executionStore.put({
|
|
27
|
+
idempotencyKey: key,
|
|
28
|
+
actionIntentId: review.action.id,
|
|
29
|
+
adapterName: adapter?.name ?? "onegent-local-mock",
|
|
30
|
+
status: "COMPLETED",
|
|
31
|
+
execution,
|
|
32
|
+
rollbackToken: execution.rollbackToken,
|
|
33
|
+
executedAt: new Date().toISOString(),
|
|
34
|
+
});
|
|
35
|
+
return execution;
|
|
36
|
+
})();
|
|
37
|
+
inFlight.set(key, operation);
|
|
38
|
+
try {
|
|
39
|
+
return await operation;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
inFlight.delete(key);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
captureAction: (input) => captureActionIntent(input, {
|
|
47
|
+
policyRules: options.policyRules,
|
|
48
|
+
policyEngine: options.policyEngine,
|
|
49
|
+
authorizationPolicy: options.authorizationPolicy,
|
|
50
|
+
}),
|
|
51
|
+
assessRisk: (action) => assessActionRisk(action),
|
|
52
|
+
evaluatePolicy: (action, risk) => {
|
|
53
|
+
const assessment = risk ?? assessActionRisk(action);
|
|
54
|
+
return options.policyEngine?.evaluate(action, assessment, options.policyRules ?? []) ?? evaluatePolicyRules(action, assessment, options.policyRules);
|
|
55
|
+
},
|
|
56
|
+
requestApproval: async (action, assignedTo) => {
|
|
57
|
+
const id = actionId(action);
|
|
58
|
+
const approval = requestActionApproval(id, assignedTo);
|
|
59
|
+
if (!options.approvalAdapter)
|
|
60
|
+
return approval;
|
|
61
|
+
const review = getActionReview(id);
|
|
62
|
+
const policy = options.policyEngine?.evaluate(review.action, review.riskAssessment, options.policyRules ?? []) ??
|
|
63
|
+
evaluatePolicyRules(review.action, review.riskAssessment, options.policyRules);
|
|
64
|
+
const decision = await options.approvalAdapter.requestApproval({
|
|
65
|
+
action: review.action,
|
|
66
|
+
risk: review.riskAssessment,
|
|
67
|
+
policy,
|
|
68
|
+
approvalRequest: approval,
|
|
69
|
+
});
|
|
70
|
+
if (decision?.approved !== undefined && !decision.reviewerId?.trim()) {
|
|
71
|
+
throw new Error(`Approval adapter ${options.approvalAdapter.name} must identify the reviewer.`);
|
|
72
|
+
}
|
|
73
|
+
if (decision?.expiresAt && Date.parse(decision.expiresAt) <= Date.now()) {
|
|
74
|
+
throw new Error(`Approval decision ${decision.decisionId ?? "from adapter"} has expired.`);
|
|
75
|
+
}
|
|
76
|
+
if (decision?.approved === true) {
|
|
77
|
+
approveAction(id, decision.reviewerId, decision.reviewerComment, { autoExecute: false });
|
|
78
|
+
}
|
|
79
|
+
else if (decision?.approved === false) {
|
|
80
|
+
rejectAction(id, decision.reviewerId, decision.reviewerComment);
|
|
81
|
+
}
|
|
82
|
+
return getActionReview(id).approvalRequest ?? approval;
|
|
83
|
+
},
|
|
84
|
+
approveAction: (action, reviewerId, reviewerComment) => approveAction(actionId(action), reviewerId, reviewerComment, { autoExecute: false }),
|
|
85
|
+
rejectAction: (action, reviewerId, reviewerComment) => rejectAction(actionId(action), reviewerId, reviewerComment),
|
|
86
|
+
executeAfterApproval: executeOnce,
|
|
87
|
+
rollbackAfterExecution: async (actionInput, adapter, reason) => {
|
|
88
|
+
const review = getActionReview(actionId(actionInput));
|
|
89
|
+
const key = review.action.idempotencyKey;
|
|
90
|
+
const receipt = await executionStore.get(key);
|
|
91
|
+
if (!receipt || receipt.actionIntentId !== review.action.id)
|
|
92
|
+
throw new Error(`Action ${review.action.id} has no completed execution to roll back.`);
|
|
93
|
+
if (receipt.status === "ROLLED_BACK")
|
|
94
|
+
return receipt;
|
|
95
|
+
if (!adapter.rollback)
|
|
96
|
+
throw new Error(`Adapter ${adapter.name} does not implement the rollback contract.`);
|
|
97
|
+
const result = await adapter.rollback(review.action, receipt.execution, { idempotencyKey: key, reason, rollbackToken: receipt.rollbackToken });
|
|
98
|
+
recordRollback(review.action.id, adapter.name, reason, result);
|
|
99
|
+
const next = {
|
|
100
|
+
...receipt,
|
|
101
|
+
status: result.success ? "ROLLED_BACK" : "ROLLBACK_FAILED",
|
|
102
|
+
rollback: { ...result, attemptedAt: new Date().toISOString(), reason },
|
|
103
|
+
};
|
|
104
|
+
await executionStore.put(next);
|
|
105
|
+
return next;
|
|
106
|
+
},
|
|
107
|
+
getExecutionReceipt: async (actionInput) => executionStore.get(getActionReview(actionId(actionInput)).action.idempotencyKey),
|
|
108
|
+
verifyOutcome: (action, observedState) => verifyActionOutcome(actionId(action), observedStateForVerification(observedState)),
|
|
109
|
+
writeAuditPacket: async (action) => {
|
|
110
|
+
const packet = generateAuditPacket(actionId(action));
|
|
111
|
+
await options.auditStore?.writeAuditPacket(packet);
|
|
112
|
+
return packet;
|
|
113
|
+
},
|
|
114
|
+
getActionReview: (action) => getActionReview(actionId(action)),
|
|
115
|
+
listActionReviews: () => listActionReviews(),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function createInMemoryExecutionStore(name = "in-memory-execution-store") {
|
|
119
|
+
const receipts = new Map();
|
|
120
|
+
return {
|
|
121
|
+
name,
|
|
122
|
+
receipts,
|
|
123
|
+
get: (idempotencyKey) => receipts.get(idempotencyKey),
|
|
124
|
+
put: (receipt) => { receipts.set(receipt.idempotencyKey, receipt); },
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function actionId(action) {
|
|
128
|
+
return typeof action === "string" ? action : action.id;
|
|
129
|
+
}
|
|
130
|
+
function observedStateForVerification(input) {
|
|
131
|
+
if (!input)
|
|
132
|
+
return undefined;
|
|
133
|
+
if (isActionExecutionSummary(input)) {
|
|
134
|
+
return input.observedState;
|
|
135
|
+
}
|
|
136
|
+
return input;
|
|
137
|
+
}
|
|
138
|
+
function isActionExecutionSummary(input) {
|
|
139
|
+
return typeof input.method === "string" && typeof input.status === "string" && typeof input.targetSystem === "string";
|
|
140
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ActionAuditPacket, ActionExecutionSummary, ActionRollbackResult, ActionReview, AuthorizationPolicy, ApprovalRequest, CreateActionIntentInput, LocalActionAdapter, PolicyEngine, PolicyRule, VerificationResult } from "./types.js";
|
|
2
|
+
export interface ActionGatewayOptions {
|
|
3
|
+
policyRules?: PolicyRule[];
|
|
4
|
+
policyEngine?: PolicyEngine;
|
|
5
|
+
authorizationPolicy?: AuthorizationPolicy;
|
|
6
|
+
}
|
|
7
|
+
export interface ApprovalOptions {
|
|
8
|
+
autoExecute?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function captureActionIntent(input: CreateActionIntentInput, options?: ActionGatewayOptions): ActionReview;
|
|
11
|
+
export declare function approveAction(actionId: string, reviewerId?: string, reviewerComment?: string, options?: ApprovalOptions): ActionReview;
|
|
12
|
+
export declare function requestApproval(actionId: string, assignedTo?: string, requestedBy?: string): ApprovalRequest;
|
|
13
|
+
export declare function rejectAction(actionId: string, reviewerId?: string, reviewerComment?: string): ActionReview;
|
|
14
|
+
export declare function executeAfterApproval(actionId: string): ActionExecutionSummary;
|
|
15
|
+
export declare function executeAfterApprovalWithAdapter(actionId: string, adapter: LocalActionAdapter, context?: {
|
|
16
|
+
idempotencyKey: string;
|
|
17
|
+
attempt: number;
|
|
18
|
+
}): Promise<ActionExecutionSummary>;
|
|
19
|
+
export declare function recordRollback(actionId: string, adapterName: string, reason: string, result: ActionRollbackResult): ActionReview;
|
|
20
|
+
export declare function executeMockAction(actionId: string): ActionExecutionSummary;
|
|
21
|
+
export declare function verifyOutcome(actionId: string, observedState?: Record<string, unknown>): VerificationResult;
|
|
22
|
+
export declare function verifyAction(actionId: string, observedState?: Record<string, unknown>): VerificationResult;
|
|
23
|
+
export declare function getActionReview(actionId: string): ActionReview;
|
|
24
|
+
export declare function listActionReviews(): ActionReview[];
|
|
25
|
+
export declare function writeAuditPacket(actionId: string): ActionAuditPacket;
|
|
26
|
+
export declare function generateAuditPacket(actionId: string): ActionAuditPacket;
|
|
27
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EAEpB,YAAY,EAEZ,mBAAmB,EACnB,eAAe,EAGf,uBAAuB,EACvB,kBAAkB,EAClB,YAAY,EACZ,UAAU,EAEV,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,EAAE,OAAO,GAAE,oBAAyB,GAAG,YAAY,CAuGpH;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,SAAiC,EAC3C,eAAe,SAAuC,EACtD,OAAO,GAAE,eAAoB,GAC5B,YAAY,CAwBd;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,SAAiC,EAC3C,WAAW,SAAoB,GAC9B,eAAe,CA2BjB;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,UAAU,SAAiC,EAC3C,eAAe,SAAgC,GAC9C,YAAY,CAmBd;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAQ7E;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpD,OAAO,CAAC,sBAAsB,CAAC,CA6BjC;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,oBAAoB,GAC3B,YAAY,CAkBd;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAyC1E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAE3G;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAoC1G;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAuB9D;AAED,wBAAgB,iBAAiB,IAAI,YAAY,EAAE,CAElD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CA+BvE"}
|