ai-capability-framework 1.0.0-rc.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -103
- package/CODE_OF_CONDUCT.md +11 -13
- package/CONTRIBUTING.md +40 -43
- package/GOVERNANCE.md +34 -35
- package/README.md +99 -63
- package/ROADMAP.md +12 -12
- package/SECURITY.md +15 -15
- package/dist/audit/ledger.d.ts.map +1 -1
- package/dist/audit/ledger.js +2 -1
- package/dist/audit/records.d.ts.map +1 -1
- package/dist/audit/records.js +2 -1
- package/dist/audit/types.d.ts +4 -1
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/aws/dynamodb-stores.d.ts +2 -7
- package/dist/aws/dynamodb-stores.d.ts.map +1 -1
- package/dist/aws/dynamodb-stores.js +56 -5
- package/dist/aws/testing.d.ts.map +1 -1
- package/dist/aws/testing.js +9 -0
- package/dist/cli.d.ts +6 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +77 -7
- package/dist/evals-live/index.d.ts +2 -2
- package/dist/evals-live/index.d.ts.map +1 -1
- package/dist/evals-live/index.js +1 -1
- package/dist/evals-live/live-eval-runner.d.ts +49 -1
- package/dist/evals-live/live-eval-runner.d.ts.map +1 -1
- package/dist/evals-live/live-eval-runner.js +246 -4
- package/dist/evals-live/types.d.ts +62 -9
- package/dist/evals-live/types.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/runtime/actions.d.ts +2 -0
- package/dist/runtime/actions.d.ts.map +1 -1
- package/dist/runtime/actions.js +200 -55
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/stores.d.ts +2 -7
- package/dist/runtime/stores.d.ts.map +1 -1
- package/dist/runtime/stores.js +12 -0
- package/dist/runtime/types.d.ts +25 -6
- package/dist/runtime/types.d.ts.map +1 -1
- package/docs/action-lifecycle.md +38 -32
- package/docs/adapter-roadmap.md +51 -49
- package/docs/adapters.md +14 -15
- package/docs/ai-sdk-runtime.md +36 -39
- package/docs/anthropic-runtime.md +29 -32
- package/docs/api/public-api-policy.md +59 -0
- package/docs/api.md +354 -371
- package/docs/architecture/current-state.md +28 -31
- package/docs/audit/index.md +29 -29
- package/docs/aws/cloudwatch-telemetry.md +5 -7
- package/docs/aws/dynamodb-single-table.md +8 -9
- package/docs/aws/kms-redaction.md +5 -6
- package/docs/aws/overview.md +5 -5
- package/docs/aws/production-reference.md +13 -14
- package/docs/aws/step-functions-approval.md +7 -9
- package/docs/aws-runtime.md +24 -25
- package/docs/capability-manifests.md +17 -21
- package/docs/control-plane/overview.md +2 -2
- package/docs/control-plane.md +24 -27
- package/docs/controls/index.md +19 -22
- package/docs/core/capability-manifests.md +4 -5
- package/docs/core/entity-manifests.md +5 -5
- package/docs/eval-runner.md +29 -31
- package/docs/evalops.md +13 -14
- package/docs/evals/golden-tests.md +4 -5
- package/docs/evals/overview.md +3 -3
- package/docs/evals/replay-and-trace-to-golden.md +19 -20
- package/docs/evals.md +19 -20
- package/docs/evidence.md +22 -23
- package/docs/gemini-runtime.md +31 -33
- package/docs/getting-started/anthropic-quickstart.md +61 -0
- package/docs/getting-started/concepts.md +9 -10
- package/docs/getting-started/gemini-quickstart.md +62 -0
- package/docs/getting-started/installation.md +3 -3
- package/docs/getting-started/openai-quickstart.md +61 -0
- package/docs/getting-started/provider-neutral-quickstart.md +106 -0
- package/docs/getting-started/quickstart.md +2 -2
- package/docs/getting-started.md +23 -20
- package/docs/glossary.md +31 -48
- package/docs/governance/gate.md +28 -30
- package/docs/governance/impact-and-compatibility.md +2 -3
- package/docs/governance/index.md +53 -54
- package/docs/governance/lifecycle.md +4 -5
- package/docs/governance/overview.md +2 -3
- package/docs/governance/risk-compiler.md +4 -5
- package/docs/host-responsibilities.md +6 -8
- package/docs/implementation-notes/baseline-gaps.md +15 -18
- package/docs/index.md +21 -6
- package/docs/interoperability.md +9 -9
- package/docs/langchain-runtime.md +27 -31
- package/docs/live-evals.md +68 -32
- package/docs/mcp-server-runtime.md +36 -40
- package/docs/memory.md +35 -36
- package/docs/migration-0.1-to-1.0.md +14 -9
- package/docs/observability/overview.md +2 -3
- package/docs/observability-runtime.md +35 -39
- package/docs/openai-responses.md +36 -37
- package/docs/openai-runtime.md +41 -46
- package/docs/openai-walkthrough.md +24 -28
- package/docs/policy-broker.md +9 -10
- package/docs/provenance.md +30 -29
- package/docs/providers/anthropic.md +5 -5
- package/docs/providers/choose-a-runtime.md +37 -0
- package/docs/providers/conformance.md +14 -15
- package/docs/providers/gemini.md +5 -5
- package/docs/providers/mcp.md +2 -3
- package/docs/providers/openai.md +2 -2
- package/docs/providers/semantic-kernel.md +2 -2
- package/docs/providers.md +43 -38
- package/docs/public/license-exceptions.md +187 -0
- package/docs/public/npm-release-preflight.md +112 -0
- package/docs/public-framework/compatibility-policy.md +12 -13
- package/docs/public-framework/deprecation-policy.md +8 -8
- package/docs/public-framework/final-certification-matrix.md +104 -0
- package/docs/public-framework/license-decision.md +20 -0
- package/docs/public-framework/release-process.md +46 -16
- package/docs/public-framework/security-disclosure.md +4 -5
- package/docs/public-framework/v1-certification.md +102 -15
- package/docs/release.md +200 -122
- package/docs/runtime/action-lifecycle.md +3 -3
- package/docs/runtime/policy-broker.md +4 -4
- package/docs/runtime/runtime-overview.md +4 -5
- package/docs/runtime/tool-result-envelope.md +7 -7
- package/docs/runtime.md +90 -93
- package/docs/security/overview.md +4 -4
- package/docs/security/security-packs.md +24 -26
- package/docs/security/trust-taint-redaction.md +42 -47
- package/docs/semantic-kernel-runtime.md +35 -37
- package/docs/spec.md +95 -101
- package/docs/start-here.md +18 -20
- package/examples/01-basic-read-capability/README.md +3 -4
- package/examples/02-prepare-approve-commit/README.md +6 -6
- package/examples/03-multi-provider-tools/README.md +2 -2
- package/examples/04-mcp-server/README.md +4 -5
- package/examples/05-langchain-langgraph-bridge/README.md +4 -5
- package/examples/06-vercel-ai-sdk-bridge/README.md +5 -7
- package/examples/07-policy-broker-custom-auth/README.md +4 -4
- package/examples/08-aws-step-functions-approval/README.md +4 -5
- package/examples/09-security-packs-promptfoo/README.md +4 -4
- package/examples/10-trace-to-golden/README.md +2 -2
- package/examples/11-control-plane/README.md +4 -5
- package/examples/aws/README.md +5 -8
- package/examples/control-plane/README.md +8 -9
- package/examples/control-plane/fixtures/control-plane.seed.json +8 -32
- package/examples/control-plane/public/app.js +57 -18
- package/examples/control-plane/public/index.html +15 -6
- package/examples/control-plane/server.mjs +15 -3
- package/examples/eval-results/public.results.passing.json +6 -21
- package/examples/providers/ai-sdk-next/README.md +11 -8
- package/examples/providers/anthropic-claude/README.md +5 -6
- package/examples/providers/gemini/README.md +6 -6
- package/examples/providers/langchain-agent/README.md +3 -4
- package/examples/providers/langgraph-tool-node/README.md +7 -7
- package/examples/providers/mcp/README.md +8 -8
- package/examples/providers/provider-conformance/README.md +3 -3
- package/examples/providers/semantic-kernel-mcp/README.md +6 -6
- package/examples/providers/semantic-kernel-openapi/README.md +6 -7
- package/examples/runtime-support-billing/README.md +8 -9
- package/examples/runtime-support-billing/support-billing-runtime.mjs +8 -4
- package/examples/scheduling/capabilities/scheduling.availability.get.yaml +2 -2
- package/examples/scheduling/capabilities/scheduling.invite.prepare.yaml +2 -2
- package/examples/scheduling/capabilities/scheduling.invite.send.yaml +2 -2
- package/examples/scheduling/entities/AvailabilitySlot.yaml +2 -2
- package/examples/scheduling/entities/MeetingInvite.yaml +2 -2
- package/examples/scheduling/evals/scheduling.invite.prepare.valid.yaml +3 -1
- package/examples/semantic-kernel-mcp/README.md +11 -12
- package/examples/semantic-kernel-openapi/README.md +8 -8
- package/examples/support/capabilities/support.refund.commit_case.yaml +3 -3
- package/examples/support/capabilities/support.refund.prepare_case.yaml +2 -2
- package/examples/support/capabilities/support.ticket.get.yaml +2 -2
- package/examples/support/entities/Ticket.yaml +0 -1
- package/examples/support/eval-results/support.results.passing.json +3 -12
- package/examples/support/evals/support.refund.prepare_case.approval_required.yaml +3 -1
- package/examples/support/evals/support.refund.prepare_case.valid.yaml +3 -2
- package/examples/support/memory/support.agent.preferences.json +2 -6
- package/examples/support/openai/context.support_agent.json +1 -4
- package/examples/support/provenance/support.refund.summary.provenance.json +2 -6
- package/examples/support/replay/support.refund.approval_required.trace.json +4 -14
- package/package.json +22 -5
- package/schemas/audit/action-record.schema.json +4 -1
- package/schemas/aws/approval-task.schema.json +8 -1
- package/schemas/conformance/conformance-case.schema.json +18 -2
- package/schemas/conformance/conformance-report.schema.json +17 -2
- package/schemas/conformance/provider-target-matrix.schema.json +35 -4
- package/schemas/controls/control-decision.schema.json +7 -1
- package/schemas/eval-case.schema.json +8 -1
- package/schemas/eval-result.schema.json +8 -1
- package/schemas/evidence/evidence-pack.schema.json +34 -5
- package/schemas/governance/compatibility-diff.schema.json +8 -1
- package/schemas/governance/lifecycle-transition.schema.json +10 -1
- package/schemas/governance/risk-compilation-result.schema.json +9 -1
- package/schemas/provenance/generated-content-provenance.schema.json +3 -1
- package/schemas/replay/replay-result.schema.json +16 -2
- package/schemas/replay/replay-trace.schema.json +11 -2
- package/schemas/security/context-segment.schema.json +21 -12
- package/schemas/security/redaction-policy.schema.json +4 -1
- package/schemas/security-packs/coverage-report.schema.json +17 -2
- package/schemas/security-packs/security-case-suite.schema.json +11 -1
- package/schemas/tool-result-envelope.schema.json +9 -1
- package/security-packs/approval_bypass.yaml +12 -2
- package/security-packs/capability_spoofing.yaml +17 -3
- package/security-packs/cost_amplification.yaml +21 -4
- package/security-packs/cross_tenant_access.yaml +16 -3
- package/security-packs/insecure_output_rendering.yaml +15 -4
- package/security-packs/mcp_tool_abuse.yaml +17 -3
- package/security-packs/memory_scope_violation.yaml +19 -4
- package/security-packs/prompt_injection_direct.yaml +19 -4
- package/security-packs/prompt_injection_indirect.yaml +18 -3
- package/security-packs/provider_payload_exposure.yaml +26 -4
- package/security-packs/retrieval_poisoning.yaml +5 -2
- package/security-packs/schema_confusion.yaml +17 -3
- package/security-packs/sensitive_data_disclosure.yaml +22 -5
- package/security-packs/tool_exfiltration.yaml +20 -4
- package/security-packs/tool_result_poisoning.yaml +19 -4
- package/security-packs/unsafe_commit_attempt.yaml +6 -3
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# AICF Control Plane Example
|
|
2
2
|
|
|
3
|
-
This is a public-safe local reference app for the optional AICF control-plane
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
without credentials.
|
|
3
|
+
This is a public-safe local reference app for the optional AICF control-plane subpath.
|
|
4
|
+
It shows capability review, governance status, eval/security coverage, policy decisions,
|
|
5
|
+
approvals, controls, replay metadata, and evidence export without credentials.
|
|
7
6
|
|
|
8
7
|
The example uses:
|
|
9
8
|
|
|
@@ -12,9 +11,9 @@ The example uses:
|
|
|
12
11
|
- mutable local state in `.aicf/control-plane-state.json`;
|
|
13
12
|
- a fake local development user.
|
|
14
13
|
|
|
15
|
-
Production deployments must enforce real authentication, tenant/account
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
Production deployments must enforce real authentication, tenant/account authorization,
|
|
15
|
+
approval identity, durable storage, audit retention, and side effects outside this
|
|
16
|
+
example.
|
|
18
17
|
|
|
19
18
|
## Run
|
|
20
19
|
|
|
@@ -41,5 +40,5 @@ PORT=4300 node examples/control-plane/server.mjs
|
|
|
41
40
|
- redacted replay index;
|
|
42
41
|
- evidence export with refs, hashes, and summaries only.
|
|
43
42
|
|
|
44
|
-
The app never displays raw prompts, provider payloads, transcripts, secrets,
|
|
45
|
-
|
|
43
|
+
The app never displays raw prompts, provider payloads, transcripts, secrets, stack
|
|
44
|
+
traces, tenant IDs, account IDs, or sensitive tool outputs.
|
|
@@ -28,11 +28,7 @@
|
|
|
28
28
|
"refHash": "sha256:example-tenant"
|
|
29
29
|
},
|
|
30
30
|
"redaction": {
|
|
31
|
-
"fieldsRedacted": [
|
|
32
|
-
"account",
|
|
33
|
-
"subject",
|
|
34
|
-
"tenant"
|
|
35
|
-
],
|
|
31
|
+
"fieldsRedacted": ["account", "subject", "tenant"],
|
|
36
32
|
"hashAlgorithm": "sha256",
|
|
37
33
|
"mode": "redacted"
|
|
38
34
|
},
|
|
@@ -72,11 +68,7 @@
|
|
|
72
68
|
"refHash": "sha256:example-tenant"
|
|
73
69
|
},
|
|
74
70
|
"redaction": {
|
|
75
|
-
"fieldsRedacted": [
|
|
76
|
-
"account",
|
|
77
|
-
"subject",
|
|
78
|
-
"tenant"
|
|
79
|
-
],
|
|
71
|
+
"fieldsRedacted": ["account", "subject", "tenant"],
|
|
80
72
|
"hashAlgorithm": "sha256",
|
|
81
73
|
"mode": "redacted"
|
|
82
74
|
},
|
|
@@ -107,9 +99,7 @@
|
|
|
107
99
|
"capabilityId": "support.refund.prepare_case",
|
|
108
100
|
"preparedActionId": "prepared_refund_example_1",
|
|
109
101
|
"status": "pending",
|
|
110
|
-
"requiredReasonCodes": [
|
|
111
|
-
"approval_required"
|
|
112
|
-
],
|
|
102
|
+
"requiredReasonCodes": ["approval_required"],
|
|
113
103
|
"requestedBy": {
|
|
114
104
|
"actorType": "user",
|
|
115
105
|
"refHash": "sha256:example-subject"
|
|
@@ -167,13 +157,8 @@
|
|
|
167
157
|
"model": "mock-responses"
|
|
168
158
|
},
|
|
169
159
|
"capabilitySlice": {
|
|
170
|
-
"capabilityIds": [
|
|
171
|
-
|
|
172
|
-
"support.refund.prepare_case"
|
|
173
|
-
],
|
|
174
|
-
"excludedCapabilityIds": [
|
|
175
|
-
"support.refund.commit_case"
|
|
176
|
-
],
|
|
160
|
+
"capabilityIds": ["support.ticket.get", "support.refund.prepare_case"],
|
|
161
|
+
"excludedCapabilityIds": ["support.refund.commit_case"],
|
|
177
162
|
"hash": "sha256:example-support-slice"
|
|
178
163
|
},
|
|
179
164
|
"capabilityVersions": {
|
|
@@ -184,10 +169,7 @@
|
|
|
184
169
|
"contextHash": "sha256:example-support-context",
|
|
185
170
|
"userInputSummary": "Synthetic user asks to prepare a refund case.",
|
|
186
171
|
"decisionContext": {
|
|
187
|
-
"permissions": [
|
|
188
|
-
"ticket.read",
|
|
189
|
-
"refund.case.create"
|
|
190
|
-
],
|
|
172
|
+
"permissions": ["ticket.read", "refund.case.create"],
|
|
191
173
|
"autonomyTier": "A2",
|
|
192
174
|
"riskCeiling": "medium"
|
|
193
175
|
}
|
|
@@ -225,17 +207,11 @@
|
|
|
225
207
|
"preparedActionId": "prepared_refund_example_1",
|
|
226
208
|
"capabilityId": "support.refund.prepare_case",
|
|
227
209
|
"status": "pending",
|
|
228
|
-
"requiredReasonCodes": [
|
|
229
|
-
"approval_required"
|
|
230
|
-
]
|
|
210
|
+
"requiredReasonCodes": ["approval_required"]
|
|
231
211
|
}
|
|
232
212
|
],
|
|
233
213
|
"redaction": {
|
|
234
|
-
"fieldsRedacted": [
|
|
235
|
-
"account",
|
|
236
|
-
"subject",
|
|
237
|
-
"tenant"
|
|
238
|
-
],
|
|
214
|
+
"fieldsRedacted": ["account", "subject", "tenant"],
|
|
239
215
|
"hashAlgorithm": "sha256",
|
|
240
216
|
"mode": "redacted"
|
|
241
217
|
}
|
|
@@ -14,9 +14,13 @@ navButtons.forEach((button) => {
|
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
document
|
|
17
|
+
document
|
|
18
|
+
.querySelector("#capabilityFilter")
|
|
19
|
+
.addEventListener("input", () => renderCatalogue());
|
|
18
20
|
document.querySelector("#exportEvidence").addEventListener("click", exportEvidence);
|
|
19
|
-
document
|
|
21
|
+
document
|
|
22
|
+
.querySelector("#createGlobalKillSwitch")
|
|
23
|
+
.addEventListener("click", createGlobalKillSwitch);
|
|
20
24
|
|
|
21
25
|
await refresh();
|
|
22
26
|
|
|
@@ -44,7 +48,9 @@ function renderCatalogue() {
|
|
|
44
48
|
const filter = document.querySelector("#capabilityFilter").value.toLowerCase();
|
|
45
49
|
const rows = document.querySelector("#capabilityRows");
|
|
46
50
|
rows.innerHTML = "";
|
|
47
|
-
for (const capability of snapshot.capabilities.filter((entry) =>
|
|
51
|
+
for (const capability of snapshot.capabilities.filter((entry) =>
|
|
52
|
+
entry.id.toLowerCase().includes(filter)
|
|
53
|
+
)) {
|
|
48
54
|
const row = document.createElement("tr");
|
|
49
55
|
row.dataset.capabilityId = capability.id;
|
|
50
56
|
row.innerHTML = `
|
|
@@ -68,11 +74,16 @@ async function renderCapabilityDetail() {
|
|
|
68
74
|
detailPanel.textContent = "No capability selected.";
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
|
-
const detail = await api(
|
|
77
|
+
const detail = await api(
|
|
78
|
+
`/api/aicf/capabilities/${encodeURIComponent(selectedCapabilityId)}`
|
|
79
|
+
);
|
|
72
80
|
detailPanel.innerHTML = `
|
|
73
81
|
<h3>${escapeHtml(detail.id)}</h3>
|
|
74
82
|
<p>${escapeHtml(detail.description)}</p>
|
|
75
|
-
<p><strong>Lifecycle:</strong> ${Object.entries(detail.lifecycle)
|
|
83
|
+
<p><strong>Lifecycle:</strong> ${Object.entries(detail.lifecycle)
|
|
84
|
+
.filter(([, value]) => value === true || typeof value === "string")
|
|
85
|
+
.map(([key, value]) => `${escapeHtml(key)}=${escapeHtml(String(value))}`)
|
|
86
|
+
.join(", ")}</p>
|
|
76
87
|
<p><strong>Risk:</strong> declared ${escapeHtml(detail.risk.declaredRiskTier)}, inferred ${escapeHtml(detail.risk.inferredMinimumRiskTier)}</p>
|
|
77
88
|
<p><strong>Input fields:</strong> ${detail.inputProperties.map((name) => `<span class="pill">${escapeHtml(name)}</span>`).join("") || "none"}</p>
|
|
78
89
|
<p><strong>Related evals:</strong> ${detail.relatedEvalIds.map((id) => `<span class="pill">${escapeHtml(id)}</span>`).join("") || "none"}</p>
|
|
@@ -92,7 +103,9 @@ function renderStatus() {
|
|
|
92
103
|
<p>${escapeHtml(snapshot.conformance.status)}</p>
|
|
93
104
|
<p>${snapshot.conformance.summary.passed} passed, ${snapshot.conformance.summary.failed} failed across ${snapshot.conformance.summary.providers} provider target(s).</p>
|
|
94
105
|
`;
|
|
95
|
-
const highRisk = snapshot.capabilities.filter((capability) =>
|
|
106
|
+
const highRisk = snapshot.capabilities.filter((capability) =>
|
|
107
|
+
["high", "critical"].includes(capability.riskTier)
|
|
108
|
+
);
|
|
96
109
|
document.querySelector("#riskStatus").innerHTML = `
|
|
97
110
|
<h3>Risk Posture</h3>
|
|
98
111
|
<p>${highRisk.length} high or critical capability(ies).</p>
|
|
@@ -116,27 +129,41 @@ function renderLedger() {
|
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
function renderApprovals() {
|
|
119
|
-
document.querySelector("#actionsList").innerHTML =
|
|
132
|
+
document.querySelector("#actionsList").innerHTML =
|
|
133
|
+
snapshot.actions
|
|
134
|
+
.map(
|
|
135
|
+
(action) => `
|
|
120
136
|
<div class="queue-item">
|
|
121
137
|
<strong>${escapeHtml(action.actionId)}</strong><br>
|
|
122
138
|
${escapeHtml(action.capabilityId)} · <span class="status-${escapeHtml(action.actionState)}">${escapeHtml(action.actionState)}</span>
|
|
123
139
|
</div>
|
|
124
|
-
`
|
|
140
|
+
`
|
|
141
|
+
)
|
|
142
|
+
.join("") || "No actions.";
|
|
125
143
|
|
|
126
|
-
document.querySelector("#approvalsList").innerHTML =
|
|
144
|
+
document.querySelector("#approvalsList").innerHTML =
|
|
145
|
+
snapshot.approvals
|
|
146
|
+
.map(
|
|
147
|
+
(approval) => `
|
|
127
148
|
<div class="queue-item">
|
|
128
149
|
<strong>${escapeHtml(approval.approvalRecordId)}</strong><br>
|
|
129
150
|
${escapeHtml(approval.capabilityId)} · <span class="status-${escapeHtml(approval.status)}">${escapeHtml(approval.status)}</span><br>
|
|
130
151
|
<button data-approve="${escapeHtml(approval.approvalRecordId)}" type="button">Approve</button>
|
|
131
152
|
<button data-reject="${escapeHtml(approval.approvalRecordId)}" type="button">Reject</button>
|
|
132
153
|
</div>
|
|
133
|
-
`
|
|
154
|
+
`
|
|
155
|
+
)
|
|
156
|
+
.join("") || "No approvals.";
|
|
134
157
|
|
|
135
158
|
document.querySelectorAll("[data-approve]").forEach((button) => {
|
|
136
|
-
button.addEventListener("click", () =>
|
|
159
|
+
button.addEventListener("click", () =>
|
|
160
|
+
mutateApproval(button.dataset.approve, "approve")
|
|
161
|
+
);
|
|
137
162
|
});
|
|
138
163
|
document.querySelectorAll("[data-reject]").forEach((button) => {
|
|
139
|
-
button.addEventListener("click", () =>
|
|
164
|
+
button.addEventListener("click", () =>
|
|
165
|
+
mutateApproval(button.dataset.reject, "reject")
|
|
166
|
+
);
|
|
140
167
|
});
|
|
141
168
|
}
|
|
142
169
|
|
|
@@ -156,12 +183,17 @@ function renderControls() {
|
|
|
156
183
|
}
|
|
157
184
|
|
|
158
185
|
function renderReplay() {
|
|
159
|
-
document.querySelector("#replayList").innerHTML =
|
|
186
|
+
document.querySelector("#replayList").innerHTML =
|
|
187
|
+
(snapshot.replays ?? [])
|
|
188
|
+
.map(
|
|
189
|
+
(trace) => `
|
|
160
190
|
<div>
|
|
161
191
|
<strong>${escapeHtml(trace.traceId)}</strong><br>
|
|
162
192
|
${escapeHtml(trace.provider ?? "unknown provider")} · ${escapeHtml(trace.redactionMode)} · ${trace.capabilityIds.map((id) => `<span class="pill">${escapeHtml(id)}</span>`).join("")}
|
|
163
193
|
</div>
|
|
164
|
-
`
|
|
194
|
+
`
|
|
195
|
+
)
|
|
196
|
+
.join("") || "No replay metadata.";
|
|
165
197
|
}
|
|
166
198
|
|
|
167
199
|
async function mutateApproval(id, action) {
|
|
@@ -189,16 +221,23 @@ async function exportEvidence() {
|
|
|
189
221
|
includeConformance: true,
|
|
190
222
|
includeReplayIndex: true
|
|
191
223
|
});
|
|
192
|
-
document.querySelector("#evidenceOutput").textContent = JSON.stringify(
|
|
224
|
+
document.querySelector("#evidenceOutput").textContent = JSON.stringify(
|
|
225
|
+
evidence,
|
|
226
|
+
null,
|
|
227
|
+
2
|
|
228
|
+
);
|
|
193
229
|
document.querySelector('[data-view="evidence"]').click();
|
|
194
230
|
}
|
|
195
231
|
|
|
196
232
|
async function api(path, body) {
|
|
197
233
|
const response = await fetch(path, {
|
|
198
234
|
body: body === undefined ? undefined : JSON.stringify(body),
|
|
199
|
-
headers:
|
|
200
|
-
|
|
201
|
-
|
|
235
|
+
headers:
|
|
236
|
+
body === undefined
|
|
237
|
+
? undefined
|
|
238
|
+
: {
|
|
239
|
+
"content-type": "application/json"
|
|
240
|
+
},
|
|
202
241
|
method: body === undefined ? "GET" : "POST"
|
|
203
242
|
});
|
|
204
243
|
const json = await response.json();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<meta charset="utf-8"
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1"
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>AICF Control Plane</title>
|
|
7
|
-
<link rel="stylesheet" href="/styles.css"
|
|
7
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<header class="topbar">
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
<main class="layout">
|
|
19
19
|
<aside class="sidebar" aria-label="Control plane sections">
|
|
20
|
-
<button class="nav active" data-view="catalogue" type="button">
|
|
20
|
+
<button class="nav active" data-view="catalogue" type="button">
|
|
21
|
+
Catalogue
|
|
22
|
+
</button>
|
|
21
23
|
<button class="nav" data-view="status" type="button">Status</button>
|
|
22
24
|
<button class="nav" data-view="ledger" type="button">Ledger</button>
|
|
23
25
|
<button class="nav" data-view="approvals" type="button">Approvals</button>
|
|
@@ -32,7 +34,12 @@
|
|
|
32
34
|
<section id="catalogue" class="view active">
|
|
33
35
|
<div class="section-header">
|
|
34
36
|
<h2>Capability Catalogue</h2>
|
|
35
|
-
<input
|
|
37
|
+
<input
|
|
38
|
+
id="capabilityFilter"
|
|
39
|
+
type="search"
|
|
40
|
+
placeholder="Filter capabilities"
|
|
41
|
+
aria-label="Filter capabilities"
|
|
42
|
+
/>
|
|
36
43
|
</div>
|
|
37
44
|
<div class="grid two">
|
|
38
45
|
<div>
|
|
@@ -99,7 +106,9 @@
|
|
|
99
106
|
<section id="controls" class="view">
|
|
100
107
|
<div class="section-header">
|
|
101
108
|
<h2>Kill Switches, Budgets, Circuit Breakers</h2>
|
|
102
|
-
<button id="createGlobalKillSwitch" type="button">
|
|
109
|
+
<button id="createGlobalKillSwitch" type="button">
|
|
110
|
+
Create Global Read-Only
|
|
111
|
+
</button>
|
|
103
112
|
</div>
|
|
104
113
|
<div class="grid three">
|
|
105
114
|
<article class="panel" id="killSwitches"></article>
|
|
@@ -46,12 +46,20 @@ const service = createControlPlaneService({
|
|
|
46
46
|
|
|
47
47
|
const server = createServer(async (request, response) => {
|
|
48
48
|
try {
|
|
49
|
-
const url = new URL(
|
|
49
|
+
const url = new URL(
|
|
50
|
+
request.url ?? "/",
|
|
51
|
+
`http://${request.headers.host ?? "localhost"}`
|
|
52
|
+
);
|
|
50
53
|
if (url.pathname.startsWith("/api/aicf/")) {
|
|
51
54
|
const routed = await routeControlPlaneRequest({
|
|
52
55
|
request: {
|
|
53
56
|
body: await readJsonBody(request),
|
|
54
|
-
headers: Object.fromEntries(
|
|
57
|
+
headers: Object.fromEntries(
|
|
58
|
+
Object.entries(request.headers).map(([key, value]) => [
|
|
59
|
+
key,
|
|
60
|
+
Array.isArray(value) ? value.join(",") : value
|
|
61
|
+
])
|
|
62
|
+
),
|
|
55
63
|
method: request.method ?? "GET",
|
|
56
64
|
path: url.pathname,
|
|
57
65
|
user: {
|
|
@@ -68,7 +76,11 @@ const server = createServer(async (request, response) => {
|
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
const staticPath = url.pathname === "/" ? "/index.html" : url.pathname;
|
|
71
|
-
const filePath = path.join(
|
|
79
|
+
const filePath = path.join(
|
|
80
|
+
here,
|
|
81
|
+
"public",
|
|
82
|
+
path.normalize(staticPath).replace(/^(\.\.[/\\])+/, "")
|
|
83
|
+
);
|
|
72
84
|
const content = await readFile(filePath);
|
|
73
85
|
response.writeHead(200, {
|
|
74
86
|
"content-type": contentType(filePath)
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
"results": [
|
|
4
4
|
{
|
|
5
5
|
"eval_id": "support.refund.prepare_case.approval_required",
|
|
6
|
-
"selected_capabilities": [
|
|
7
|
-
"support.ticket.get",
|
|
8
|
-
"support.refund.prepare_case"
|
|
9
|
-
],
|
|
6
|
+
"selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
|
|
10
7
|
"tool_calls": [
|
|
11
8
|
{
|
|
12
9
|
"capability_id": "support.refund.prepare_case",
|
|
@@ -27,10 +24,7 @@
|
|
|
27
24
|
},
|
|
28
25
|
{
|
|
29
26
|
"eval_id": "support.refund.commit_case.requires_approval",
|
|
30
|
-
"selected_capabilities": [
|
|
31
|
-
"support.ticket.get",
|
|
32
|
-
"support.refund.prepare_case"
|
|
33
|
-
],
|
|
27
|
+
"selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
|
|
34
28
|
"tool_calls": [],
|
|
35
29
|
"action_state": "refused",
|
|
36
30
|
"committed_capabilities": [],
|
|
@@ -44,10 +38,7 @@
|
|
|
44
38
|
},
|
|
45
39
|
{
|
|
46
40
|
"eval_id": "support.refund.prepare_case.valid",
|
|
47
|
-
"selected_capabilities": [
|
|
48
|
-
"support.ticket.get",
|
|
49
|
-
"support.refund.prepare_case"
|
|
50
|
-
],
|
|
41
|
+
"selected_capabilities": ["support.ticket.get", "support.refund.prepare_case"],
|
|
51
42
|
"tool_calls": [
|
|
52
43
|
{
|
|
53
44
|
"capability_id": "support.refund.prepare_case",
|
|
@@ -66,9 +57,7 @@
|
|
|
66
57
|
},
|
|
67
58
|
{
|
|
68
59
|
"eval_id": "scheduling.availability.get.valid",
|
|
69
|
-
"selected_capabilities": [
|
|
70
|
-
"scheduling.availability.get"
|
|
71
|
-
],
|
|
60
|
+
"selected_capabilities": ["scheduling.availability.get"],
|
|
72
61
|
"tool_calls": [
|
|
73
62
|
{
|
|
74
63
|
"capability_id": "scheduling.availability.get",
|
|
@@ -86,9 +75,7 @@
|
|
|
86
75
|
},
|
|
87
76
|
{
|
|
88
77
|
"eval_id": "scheduling.invite.prepare.valid",
|
|
89
|
-
"selected_capabilities": [
|
|
90
|
-
"scheduling.invite.prepare"
|
|
91
|
-
],
|
|
78
|
+
"selected_capabilities": ["scheduling.invite.prepare"],
|
|
92
79
|
"tool_calls": [
|
|
93
80
|
{
|
|
94
81
|
"capability_id": "scheduling.invite.prepare",
|
|
@@ -110,9 +97,7 @@
|
|
|
110
97
|
},
|
|
111
98
|
{
|
|
112
99
|
"eval_id": "scheduling.invite.send.requires_approval",
|
|
113
|
-
"selected_capabilities": [
|
|
114
|
-
"scheduling.invite.prepare"
|
|
115
|
-
],
|
|
100
|
+
"selected_capabilities": ["scheduling.invite.prepare"],
|
|
116
101
|
"tool_calls": [],
|
|
117
102
|
"action_state": "refused",
|
|
118
103
|
"committed_capabilities": [],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Vercel AI SDK Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for using AICF with Vercel AI SDK
|
|
4
|
-
|
|
3
|
+
This example shows the public-safe shape for using AICF with Vercel AI SDK Core. The
|
|
4
|
+
host application selects and configures the model provider.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework ai
|
|
@@ -10,12 +10,15 @@ npm run test:ai-sdk:mock
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
buildAiSdkTools,
|
|
15
|
+
runAiSdkGenerateText
|
|
16
|
+
} from "ai-capability-framework/providers/ai-sdk";
|
|
14
17
|
```
|
|
15
18
|
|
|
16
|
-
AICF builds executor-backed AI SDK tools from a routed capability slice. Tool
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
AICF builds executor-backed AI SDK tools from a routed capability slice. Tool `execute`
|
|
20
|
+
callbacks delegate to AICF validation, policy, lifecycle, and runtime envelope handling.
|
|
21
|
+
Commit capabilities are not exposed.
|
|
19
22
|
|
|
20
23
|
Live tests are opt-in only and depend on host-supplied model setup:
|
|
21
24
|
|
|
@@ -23,5 +26,5 @@ Live tests are opt-in only and depend on host-supplied model setup:
|
|
|
23
26
|
RUN_LIVE_AI_SDK=1 npm run test:ai-sdk:live
|
|
24
27
|
```
|
|
25
28
|
|
|
26
|
-
Do not include provider-specific raw stream chunks, payloads, or transcripts in
|
|
27
|
-
|
|
29
|
+
Do not include provider-specific raw stream chunks, payloads, or transcripts in public
|
|
30
|
+
examples.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Anthropic Claude Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for using AICF with Claude Messages
|
|
4
|
-
tool use.
|
|
3
|
+
This example shows the public-safe shape for using AICF with Claude Messages tool use.
|
|
5
4
|
|
|
6
5
|
```bash
|
|
7
6
|
npm install ai-capability-framework @anthropic-ai/sdk
|
|
@@ -13,10 +12,10 @@ npm run test:anthropic:mock
|
|
|
13
12
|
import { runAnthropicMessages } from "ai-capability-framework/providers/anthropic";
|
|
14
13
|
```
|
|
15
14
|
|
|
16
|
-
Host applications provide the Anthropic-compatible client, runtime context,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
Host applications provide the Anthropic-compatible client, runtime context, handler
|
|
16
|
+
registry, executor, and model messages. AICF routes only read and prepare capabilities,
|
|
17
|
+
validates tool input against AICF schemas, returns model-safe envelopes, and never
|
|
18
|
+
exposes commit tools to Claude.
|
|
20
19
|
|
|
21
20
|
Live tests are opt-in only:
|
|
22
21
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Google Gemini Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for using AICF with Gemini
|
|
4
|
-
|
|
3
|
+
This example shows the public-safe shape for using AICF with Gemini GenerateContent
|
|
4
|
+
function calling.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework @google/genai
|
|
@@ -13,10 +13,10 @@ npm run test:gemini:mock
|
|
|
13
13
|
import { runGeminiGenerateContent } from "ai-capability-framework/providers/gemini";
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Host applications provide the Gemini-compatible client, runtime context,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Host applications provide the Gemini-compatible client, runtime context, handler
|
|
17
|
+
registry, executor, and contents. AICF exports only routed read and prepare function
|
|
18
|
+
declarations, validates function arguments against canonical AICF schemas, and returns
|
|
19
|
+
model-safe function response envelopes.
|
|
20
20
|
|
|
21
21
|
Live tests are opt-in only:
|
|
22
22
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# LangChain Agent Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for exposing AICF capabilities as
|
|
4
|
-
|
|
3
|
+
This example shows the public-safe shape for exposing AICF capabilities as LangChain.js
|
|
4
|
+
tools.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework @langchain/core langchain zod
|
|
@@ -23,5 +23,4 @@ Live tests are opt-in only:
|
|
|
23
23
|
RUN_LIVE_LANGCHAIN=1 npm run test:langchain:live
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Do not commit raw LangChain traces, prompts, tool payloads, or provider
|
|
27
|
-
transcripts.
|
|
26
|
+
Do not commit raw LangChain traces, prompts, tool payloads, or provider transcripts.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# LangGraph ToolNode Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for wrapping AICF-backed LangChain
|
|
4
|
-
|
|
3
|
+
This example shows the public-safe shape for wrapping AICF-backed LangChain tools in a
|
|
4
|
+
host-supplied LangGraph `ToolNode`.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework @langchain/core langchain zod
|
|
@@ -13,9 +13,9 @@ npm run test:langchain:mock
|
|
|
13
13
|
import { buildLangGraphToolNode } from "ai-capability-framework/providers/langchain";
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
AICF does not import LangGraph by default. The host passes a compatible
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
AICF does not import LangGraph by default. The host passes a compatible `ToolNode`
|
|
17
|
+
constructor, and AICF supplies routed read/prepare tools that enforce AICF validation,
|
|
18
|
+
policy, lifecycle, and envelope boundaries.
|
|
19
19
|
|
|
20
|
-
Commit tools are not generated for LangGraph agent loops. Host applications own
|
|
21
|
-
|
|
20
|
+
Commit tools are not generated for LangGraph agent loops. Host applications own approval
|
|
21
|
+
collection and lifecycle commit after a stored prepared action.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# MCP Provider Example
|
|
2
2
|
|
|
3
|
-
This example shows the public-safe shape for exposing routed AICF capabilities
|
|
4
|
-
|
|
3
|
+
This example shows the public-safe shape for exposing routed AICF capabilities through
|
|
4
|
+
Model Context Protocol descriptors and server calls.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework @modelcontextprotocol/sdk
|
|
@@ -15,10 +15,10 @@ import { buildMcpProviderToolDescriptors } from "ai-capability-framework/provide
|
|
|
15
15
|
import { AicfMcpServer } from "ai-capability-framework/mcp-server";
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The descriptor subpath creates MCP tool metadata from a routed slice. The server
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
The descriptor subpath creates MCP tool metadata from a routed slice. The server subpath
|
|
19
|
+
executes only read and prepare calls through `AicfToolExecutor`. MCP client identity is
|
|
20
|
+
never trusted; the host `runtimeContextFactory` must resolve authenticated user, tenant,
|
|
21
|
+
account, and permission context.
|
|
22
22
|
|
|
23
|
-
Do not add standalone transport servers, raw MCP payload fixtures, or commit
|
|
24
|
-
|
|
23
|
+
Do not add standalone transport servers, raw MCP payload fixtures, or commit tools to
|
|
24
|
+
public examples.
|
|
@@ -22,6 +22,6 @@ Export Semantic Kernel OpenAPI compatibility metadata:
|
|
|
22
22
|
node dist/cli.js providers export-semantic-kernel-openapi examples --context examples/support/openai/context.support_agent.json --server-url https://aicf.example.com
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The conformance harness is descriptor/mock-only. It does not call live models,
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
The conformance harness is descriptor/mock-only. It does not call live models, use
|
|
26
|
+
credentials, execute provider SDK loops, persist raw payloads, or expose commit
|
|
27
|
+
capabilities.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Semantic Kernel MCP Compatibility Example
|
|
2
2
|
|
|
3
|
-
This example shows the recommended Semantic Kernel path: import a host-owned
|
|
4
|
-
|
|
3
|
+
This example shows the recommended Semantic Kernel path: import a host-owned AICF MCP
|
|
4
|
+
server as a Semantic Kernel MCP plugin.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework @modelcontextprotocol/sdk
|
|
@@ -15,7 +15,7 @@ import { AicfMcpServer } from "ai-capability-framework/mcp-server";
|
|
|
15
15
|
import { getSemanticKernelMcpIntegrationGuide } from "ai-capability-framework/providers/semantic-kernel";
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
AICF does not provide a native Semantic Kernel runtime. The host owns MCP
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
AICF does not provide a native Semantic Kernel runtime. The host owns MCP transport,
|
|
19
|
+
Semantic Kernel setup, auth, tenant/account context, approvals, idempotency, audit, and
|
|
20
|
+
side effects. AICF remains the capability, validation, policy, lifecycle, and envelope
|
|
21
|
+
authority.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Semantic Kernel OpenAPI Compatibility Example
|
|
2
2
|
|
|
3
|
-
This example shows the fallback Semantic Kernel path: generate OpenAPI 3.1
|
|
4
|
-
|
|
3
|
+
This example shows the fallback Semantic Kernel path: generate OpenAPI 3.1 metadata for
|
|
4
|
+
a host-owned AICF executor route.
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
npm install ai-capability-framework
|
|
@@ -14,9 +14,8 @@ import { exportSemanticKernelOpenApiPlugin } from "ai-capability-framework/provi
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
The generated OpenAPI document is descriptor-only. The host must implement
|
|
17
|
-
`POST /aicf/capabilities/{providerToolName}/execute`, resolve
|
|
18
|
-
|
|
19
|
-
persist audit events if needed.
|
|
17
|
+
`POST /aicf/capabilities/{providerToolName}/execute`, resolve `runtime_context_ref`,
|
|
18
|
+
enforce auth and approvals, run AICF execution, and persist audit events if needed.
|
|
20
19
|
|
|
21
|
-
The OpenAPI export must not include secret auth details, tenant internals, raw
|
|
22
|
-
|
|
20
|
+
The OpenAPI export must not include secret auth details, tenant internals, raw provider
|
|
21
|
+
payloads, or commit tools.
|