@attested-intelligence/aga-mcp-server 2.1.0 → 2.2.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 +197 -124
- package/SECURITY.md +59 -0
- package/dist/core/bundle.d.ts +9 -2
- package/dist/core/bundle.d.ts.map +1 -1
- package/dist/core/bundle.js +16 -2
- package/dist/core/bundle.js.map +1 -1
- package/dist/core/identity.d.ts +19 -10
- package/dist/core/identity.d.ts.map +1 -1
- package/dist/core/identity.js +45 -11
- package/dist/core/identity.js.map +1 -1
- package/dist/core/portal.d.ts +10 -1
- package/dist/core/portal.d.ts.map +1 -1
- package/dist/core/portal.js +16 -12
- package/dist/core/portal.js.map +1 -1
- package/dist/core/types.d.ts +29 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/crypto/index.d.ts +5 -6
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js +5 -6
- package/dist/crypto/index.js.map +1 -1
- package/dist/crypto/sign.d.ts +2 -0
- package/dist/crypto/sign.d.ts.map +1 -1
- package/dist/crypto/sign.js +6 -0
- package/dist/crypto/sign.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/governance.d.ts +7 -1
- package/dist/middleware/governance.d.ts.map +1 -1
- package/dist/middleware/governance.js +18 -11
- package/dist/middleware/governance.js.map +1 -1
- package/dist/server.d.ts +7 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +342 -214
- package/dist/server.js.map +1 -1
- package/dist/storage/sqlite.js +6 -6
- package/independent-verifier/README.md +31 -0
- package/independent-verifier/package.json +18 -0
- package/independent-verifier/verify.ts +211 -0
- package/package.json +97 -76
- package/src/adapters/openclaw.ts +125 -0
- package/src/core/artifact.ts +45 -0
- package/src/core/attestation.ts +33 -0
- package/src/core/behavioral.ts +132 -0
- package/src/core/bundle.ts +45 -0
- package/src/core/chain.ts +72 -0
- package/src/core/checkpoint.ts +22 -0
- package/src/core/delegation.ts +146 -0
- package/src/core/disclosure.ts +32 -0
- package/src/core/identity.ts +62 -0
- package/src/core/index.ts +14 -0
- package/src/core/portal.ts +117 -0
- package/src/core/quarantine.ts +16 -0
- package/src/core/receipt.ts +33 -0
- package/src/core/subject.ts +11 -0
- package/src/core/types.ts +285 -0
- package/src/crypto/hash.ts +33 -0
- package/src/crypto/index.ts +5 -0
- package/src/crypto/merkle.ts +43 -0
- package/src/crypto/salt.ts +18 -0
- package/src/crypto/sign.ts +42 -0
- package/src/crypto/types.ts +19 -0
- package/src/index.ts +12 -0
- package/src/middleware/governance.ts +95 -0
- package/src/middleware/index.ts +1 -0
- package/src/proxy/evaluator.ts +176 -0
- package/src/proxy/index.ts +259 -0
- package/src/proxy/profiles.ts +48 -0
- package/src/proxy/server.ts +499 -0
- package/src/proxy/stdio-bridge.ts +171 -0
- package/src/proxy/types.ts +40 -0
- package/src/proxy/verify.ts +202 -0
- package/src/server.ts +435 -0
- package/src/storage/index.ts +3 -0
- package/src/storage/interface.ts +21 -0
- package/src/storage/memory.ts +27 -0
- package/src/storage/sqlite.ts +45 -0
- package/src/tools/README.md +13 -0
- package/src/utils/canonical.ts +14 -0
- package/src/utils/constants.ts +3 -0
- package/src/utils/timestamp.ts +12 -0
- package/src/utils/uuid.ts +2 -0
- package/dist/context.d.ts +0 -39
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -113
- package/dist/context.js.map +0 -1
- package/dist/core/measurement.d.ts +0 -16
- package/dist/core/measurement.d.ts.map +0 -1
- package/dist/core/measurement.js +0 -18
- package/dist/core/measurement.js.map +0 -1
- package/dist/crypto/canonicalize.d.ts +0 -7
- package/dist/crypto/canonicalize.d.ts.map +0 -1
- package/dist/crypto/canonicalize.js +0 -21
- package/dist/crypto/canonicalize.js.map +0 -1
- package/dist/crypto/keys.d.ts +0 -10
- package/dist/crypto/keys.d.ts.map +0 -1
- package/dist/crypto/keys.js +0 -19
- package/dist/crypto/keys.js.map +0 -1
- package/dist/prompts/drift-analysis.d.ts +0 -13
- package/dist/prompts/drift-analysis.d.ts.map +0 -1
- package/dist/prompts/drift-analysis.js +0 -43
- package/dist/prompts/drift-analysis.js.map +0 -1
- package/dist/prompts/governance-report.d.ts +0 -7
- package/dist/prompts/governance-report.d.ts.map +0 -1
- package/dist/prompts/governance-report.js +0 -26
- package/dist/prompts/governance-report.js.map +0 -1
- package/dist/prompts/nccoe-demo.d.ts +0 -14
- package/dist/prompts/nccoe-demo.d.ts.map +0 -1
- package/dist/prompts/nccoe-demo.js +0 -47
- package/dist/prompts/nccoe-demo.js.map +0 -1
- package/dist/resources/cosai-mapping.d.ts +0 -24
- package/dist/resources/cosai-mapping.d.ts.map +0 -1
- package/dist/resources/cosai-mapping.js +0 -127
- package/dist/resources/cosai-mapping.js.map +0 -1
- package/dist/resources/crypto-primitives.d.ts +0 -3
- package/dist/resources/crypto-primitives.d.ts.map +0 -1
- package/dist/resources/crypto-primitives.js +0 -52
- package/dist/resources/crypto-primitives.js.map +0 -1
- package/dist/resources/sample-bundle.d.ts +0 -6
- package/dist/resources/sample-bundle.d.ts.map +0 -1
- package/dist/resources/sample-bundle.js +0 -58
- package/dist/resources/sample-bundle.js.map +0 -1
- package/dist/resources/specification.d.ts +0 -3
- package/dist/resources/specification.d.ts.map +0 -1
- package/dist/resources/specification.js +0 -161
- package/dist/resources/specification.js.map +0 -1
- package/dist/tools/create-artifact.d.ts +0 -25
- package/dist/tools/create-artifact.d.ts.map +0 -1
- package/dist/tools/create-artifact.js +0 -85
- package/dist/tools/create-artifact.js.map +0 -1
- package/dist/tools/delegate-subagent.d.ts +0 -18
- package/dist/tools/delegate-subagent.d.ts.map +0 -1
- package/dist/tools/delegate-subagent.js +0 -50
- package/dist/tools/delegate-subagent.js.map +0 -1
- package/dist/tools/disclose-claim.d.ts +0 -14
- package/dist/tools/disclose-claim.d.ts.map +0 -1
- package/dist/tools/disclose-claim.js +0 -23
- package/dist/tools/disclose-claim.js.map +0 -1
- package/dist/tools/export-bundle.d.ts +0 -8
- package/dist/tools/export-bundle.d.ts.map +0 -1
- package/dist/tools/export-bundle.js +0 -25
- package/dist/tools/export-bundle.js.map +0 -1
- package/dist/tools/full-lifecycle.d.ts +0 -16
- package/dist/tools/full-lifecycle.d.ts.map +0 -1
- package/dist/tools/full-lifecycle.js +0 -121
- package/dist/tools/full-lifecycle.js.map +0 -1
- package/dist/tools/generate-receipt.d.ts +0 -16
- package/dist/tools/generate-receipt.d.ts.map +0 -1
- package/dist/tools/generate-receipt.js +0 -31
- package/dist/tools/generate-receipt.js.map +0 -1
- package/dist/tools/get-chain.d.ts +0 -14
- package/dist/tools/get-chain.d.ts.map +0 -1
- package/dist/tools/get-chain.js +0 -45
- package/dist/tools/get-chain.js.map +0 -1
- package/dist/tools/get-portal-state.d.ts +0 -8
- package/dist/tools/get-portal-state.d.ts.map +0 -1
- package/dist/tools/get-portal-state.js +0 -15
- package/dist/tools/get-portal-state.js.map +0 -1
- package/dist/tools/init-chain.d.ts +0 -10
- package/dist/tools/init-chain.d.ts.map +0 -1
- package/dist/tools/init-chain.js +0 -13
- package/dist/tools/init-chain.js.map +0 -1
- package/dist/tools/measure-behavior.d.ts +0 -12
- package/dist/tools/measure-behavior.d.ts.map +0 -1
- package/dist/tools/measure-behavior.js +0 -29
- package/dist/tools/measure-behavior.js.map +0 -1
- package/dist/tools/measure-subject.d.ts +0 -15
- package/dist/tools/measure-subject.d.ts.map +0 -1
- package/dist/tools/measure-subject.js +0 -106
- package/dist/tools/measure-subject.js.map +0 -1
- package/dist/tools/quarantine-status.d.ts +0 -8
- package/dist/tools/quarantine-status.d.ts.map +0 -1
- package/dist/tools/quarantine-status.js +0 -16
- package/dist/tools/quarantine-status.js.map +0 -1
- package/dist/tools/revoke-artifact.d.ts +0 -13
- package/dist/tools/revoke-artifact.d.ts.map +0 -1
- package/dist/tools/revoke-artifact.js +0 -24
- package/dist/tools/revoke-artifact.js.map +0 -1
- package/dist/tools/rotate-keys.d.ts +0 -13
- package/dist/tools/rotate-keys.d.ts.map +0 -1
- package/dist/tools/rotate-keys.js +0 -39
- package/dist/tools/rotate-keys.js.map +0 -1
- package/dist/tools/server-info.d.ts +0 -8
- package/dist/tools/server-info.d.ts.map +0 -1
- package/dist/tools/server-info.js +0 -23
- package/dist/tools/server-info.js.map +0 -1
- package/dist/tools/set-verification-tier.d.ts +0 -11
- package/dist/tools/set-verification-tier.d.ts.map +0 -1
- package/dist/tools/set-verification-tier.js +0 -31
- package/dist/tools/set-verification-tier.js.map +0 -1
- package/dist/tools/start-monitoring.d.ts +0 -12
- package/dist/tools/start-monitoring.d.ts.map +0 -1
- package/dist/tools/start-monitoring.js +0 -17
- package/dist/tools/start-monitoring.js.map +0 -1
- package/dist/tools/trigger-measurement.d.ts +0 -15
- package/dist/tools/trigger-measurement.d.ts.map +0 -1
- package/dist/tools/trigger-measurement.js +0 -86
- package/dist/tools/trigger-measurement.js.map +0 -1
- package/dist/tools/verify-artifact.d.ts +0 -13
- package/dist/tools/verify-artifact.d.ts.map +0 -1
- package/dist/tools/verify-artifact.js +0 -6
- package/dist/tools/verify-artifact.js.map +0 -1
- package/dist/tools/verify-bundle.d.ts +0 -13
- package/dist/tools/verify-bundle.d.ts.map +0 -1
- package/dist/tools/verify-bundle.js +0 -6
- package/dist/tools/verify-bundle.js.map +0 -1
- package/dist/types.d.ts +0 -261
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -8
- package/dist/types.js.map +0 -1
package/dist/server.js
CHANGED
|
@@ -1,77 +1,136 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AGA MCP Server
|
|
2
|
+
* AGA MCP Server. The Portal (ref 150) as an MCP service.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* V3 NIST-aligned behaviors:
|
|
5
|
+
* 1. Every measurement generates a receipt (match OR mismatch)
|
|
6
|
+
* 2. TTL checked on every measurement (fail-closed)
|
|
7
|
+
* 3. Mid-session revocation via revoke_artifact tool
|
|
8
|
+
* 4. Governance middleware: portal state checked before tool execution
|
|
9
|
+
* 5. Auto-chaining: every operation writes to continuity chain
|
|
6
10
|
*/
|
|
7
11
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
12
|
import { z } from 'zod';
|
|
9
|
-
import {
|
|
13
|
+
import { generateKeyPair, pkToHex } from './crypto/sign.js';
|
|
14
|
+
import { sha256Str } from './crypto/hash.js';
|
|
15
|
+
import { computeSubjectIdFromString } from './core/subject.js';
|
|
16
|
+
import { performAttestation } from './core/attestation.js';
|
|
17
|
+
import { generateArtifact, hashArtifact } from './core/artifact.js';
|
|
18
|
+
import { Portal } from './core/portal.js';
|
|
19
|
+
import { generateReceipt } from './core/receipt.js';
|
|
20
|
+
import { createGenesisEvent, appendEvent, verifyChainIntegrity } from './core/chain.js';
|
|
21
|
+
import { createCheckpoint, eventInclusionProof } from './core/checkpoint.js';
|
|
22
|
+
import { generateBundle, verifyBundleOffline } from './core/bundle.js';
|
|
23
|
+
import { processDisclosure } from './core/disclosure.js';
|
|
24
|
+
import { initQuarantine } from './core/quarantine.js';
|
|
25
|
+
import { MemoryStorage } from './storage/index.js';
|
|
26
|
+
import { utcNow } from './utils/timestamp.js';
|
|
27
|
+
import { deriveArtifact } from './core/delegation.js';
|
|
10
28
|
import { createGovernanceWrapper } from './middleware/governance.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
import { generateSampleBundle, SAMPLE_BUNDLE_URI } from './resources/sample-bundle.js';
|
|
35
|
-
import { CRYPTO_PRIMITIVES_DOC, CRYPTO_PRIMITIVES_URI } from './resources/crypto-primitives.js';
|
|
36
|
-
// ── Prompts ──────────────────────────────────────────────────────
|
|
37
|
-
import { NCCOE_DEMO_PROMPT } from './prompts/nccoe-demo.js';
|
|
38
|
-
import { GOVERNANCE_REPORT_PROMPT } from './prompts/governance-report.js';
|
|
39
|
-
import { DRIFT_ANALYSIS_PROMPT } from './prompts/drift-analysis.js';
|
|
29
|
+
import { BehavioralMonitor } from './core/behavioral.js';
|
|
30
|
+
// ── Default Policies ────────────────────────────────────────────
|
|
31
|
+
const DEFAULT_ENFORCEMENT = {
|
|
32
|
+
measurement_cadence_ms: 1000, ttl_seconds: 3600,
|
|
33
|
+
enforcement_triggers: ['QUARANTINE', 'TERMINATE'],
|
|
34
|
+
re_attestation_required: true,
|
|
35
|
+
measurement_types: ['FILE_SYSTEM_STATE', 'CONFIG_MANIFEST'],
|
|
36
|
+
};
|
|
37
|
+
const DEFAULT_CLAIMS = {
|
|
38
|
+
claims_taxonomy: [
|
|
39
|
+
{ claim_id: 'identity.name', sensitivity: 'S3_HIGH', substitutes: ['identity.pseudonym', 'identity.org'], inference_risks: [], permitted_modes: ['PROOF_ONLY'] },
|
|
40
|
+
{ claim_id: 'identity.pseudonym', sensitivity: 'S2_MODERATE', substitutes: ['identity.org'], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN'] },
|
|
41
|
+
{ claim_id: 'identity.org', sensitivity: 'S1_LOW', substitutes: [], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL'] },
|
|
42
|
+
{ claim_id: 'identity.age', sensitivity: 'S3_HIGH', substitutes: ['identity.age_range', 'identity.is_adult'], inference_risks: [], permitted_modes: ['PROOF_ONLY'] },
|
|
43
|
+
{ claim_id: 'identity.age_range', sensitivity: 'S2_MODERATE', substitutes: ['identity.is_adult'], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL'] },
|
|
44
|
+
{ claim_id: 'identity.is_adult', sensitivity: 'S1_LOW', substitutes: [], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_FULL'] },
|
|
45
|
+
],
|
|
46
|
+
substitution_rules: [],
|
|
47
|
+
};
|
|
48
|
+
const CLAIM_VALUES = {
|
|
49
|
+
'identity.name': 'Alice Johnson', 'identity.pseudonym': 'AJ-7742', 'identity.org': 'Attested Intelligence',
|
|
50
|
+
'identity.age': 32, 'identity.age_range': '25-34', 'identity.is_adult': true,
|
|
51
|
+
};
|
|
40
52
|
// ── Server Factory ──────────────────────────────────────────────
|
|
41
53
|
export async function createAGAServer() {
|
|
42
|
-
const server = new McpServer({ name: 'aga-mcp-server', version: '
|
|
43
|
-
const
|
|
44
|
-
|
|
54
|
+
const server = new McpServer({ name: 'aga-mcp-server', version: '0.1.0' });
|
|
55
|
+
const storage = new MemoryStorage();
|
|
56
|
+
await storage.initialize();
|
|
57
|
+
const issuerKP = generateKeyPair();
|
|
58
|
+
const portalKP = generateKeyPair();
|
|
59
|
+
const chainKP = generateKeyPair();
|
|
60
|
+
const portal = new Portal();
|
|
61
|
+
let quarantine = null;
|
|
62
|
+
let chainInitialized = false;
|
|
63
|
+
// ── Auto-chain helper (auto-inits if needed) ──────────────────
|
|
64
|
+
async function autoChain(type, payload) {
|
|
65
|
+
if (!chainInitialized) {
|
|
66
|
+
const genesis = createGenesisEvent(chainKP, sha256Str('AGA Protocol Specification v1.0.0'));
|
|
67
|
+
await storage.storeEvent(genesis);
|
|
68
|
+
chainInitialized = true;
|
|
69
|
+
portal.sequenceCounter = 0;
|
|
70
|
+
portal.lastLeafHash = genesis.leaf_hash;
|
|
71
|
+
}
|
|
72
|
+
const prev = await storage.getLatestEvent();
|
|
73
|
+
if (!prev)
|
|
74
|
+
throw new Error('Chain initialization failed');
|
|
75
|
+
const event = appendEvent(type, payload, prev, chainKP);
|
|
76
|
+
await storage.storeEvent(event);
|
|
77
|
+
portal.sequenceCounter = event.sequence_number;
|
|
78
|
+
portal.lastLeafHash = event.leaf_hash;
|
|
79
|
+
return event;
|
|
80
|
+
}
|
|
81
|
+
const j = (x) => ({ content: [{ type: 'text', text: JSON.stringify(x, null, 2) }] });
|
|
82
|
+
// ── Governance middleware (NCCoE Section 4: Portal as PEP) ────
|
|
83
|
+
const quarantineRef = { get current() { return quarantine; } };
|
|
84
|
+
const behavioralMonitor = new BehavioralMonitor();
|
|
45
85
|
function governedTool(name, description, schema, handler) {
|
|
46
|
-
const wrap = createGovernanceWrapper(
|
|
86
|
+
const wrap = createGovernanceWrapper(portal, quarantineRef, name, behavioralMonitor);
|
|
47
87
|
server.tool(name, description, schema, wrap(handler));
|
|
48
88
|
}
|
|
49
89
|
// ══════════════════════════════════════════════════════════════
|
|
50
|
-
//
|
|
51
|
-
// ══════════════════════════════════════════════════════════════
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
90
|
+
// TOOL: get_server_info
|
|
91
|
+
// ══════════════════════════════════════════════════════════════
|
|
92
|
+
server.tool('get_server_info', 'Get AGA server info, public keys, and portal state.', {}, async () => j({
|
|
93
|
+
server: 'AGA MCP Server', version: '0.1.0',
|
|
94
|
+
protocol: 'Attested Governance Artifacts v1.0.0',
|
|
95
|
+
nist_references: ['NIST-2025-0035', 'NCCoE AI Agent Identity'],
|
|
96
|
+
issuer_public_key: pkToHex(issuerKP.publicKey),
|
|
97
|
+
portal_public_key: pkToHex(portalKP.publicKey),
|
|
98
|
+
chain_public_key: pkToHex(chainKP.publicKey),
|
|
99
|
+
chain_initialized: chainInitialized,
|
|
100
|
+
portal_state: portal.state,
|
|
101
|
+
}));
|
|
102
|
+
// ══════════════════════════════════════════════════════════════
|
|
103
|
+
// TOOL: get_portal_state - V3 RESTORED (was dropped in V2)
|
|
104
|
+
// ══════════════════════════════════════════════════════════════
|
|
105
|
+
server.tool('get_portal_state', 'Get current portal state, loaded artifact info, and enforcement status.', {}, async () => j({
|
|
106
|
+
state: portal.state,
|
|
107
|
+
artifact_loaded: !!portal.artifact,
|
|
108
|
+
sealed_hash: portal.artifact?.sealed_hash ?? null,
|
|
109
|
+
ttl_seconds: portal.artifact?.enforcement_parameters.ttl_seconds ?? null,
|
|
110
|
+
issued_at: portal.artifact?.issued_timestamp ?? null,
|
|
111
|
+
enforcement_triggers: portal.artifact?.enforcement_parameters.enforcement_triggers ?? [],
|
|
112
|
+
sequence_counter: portal.sequenceCounter,
|
|
113
|
+
quarantine_active: quarantine?.active ?? false,
|
|
114
|
+
}));
|
|
115
|
+
// ══════════════════════════════════════════════════════════════
|
|
116
|
+
// TOOL: init_chain
|
|
117
|
+
// ══════════════════════════════════════════════════════════════
|
|
118
|
+
server.tool('init_chain', 'Initialize continuity chain with genesis event.', { specification_hash: z.string().optional() }, async ({ specification_hash }) => {
|
|
119
|
+
if (chainInitialized)
|
|
120
|
+
return j({ success: false, error: 'Chain already initialized' });
|
|
121
|
+
const genesis = createGenesisEvent(chainKP, specification_hash ?? sha256Str('AGA Protocol Specification v1.0.0'));
|
|
122
|
+
await storage.storeEvent(genesis);
|
|
123
|
+
chainInitialized = true;
|
|
124
|
+
portal.sequenceCounter = 0;
|
|
125
|
+
portal.lastLeafHash = genesis.leaf_hash;
|
|
126
|
+
return j({ success: true, genesis_event_id: genesis.event_id, genesis_leaf_hash: genesis.leaf_hash });
|
|
127
|
+
});
|
|
128
|
+
// ══════════════════════════════════════════════════════════════
|
|
129
|
+
// TOOL: attest_subject
|
|
130
|
+
// ══════════════════════════════════════════════════════════════
|
|
131
|
+
server.tool('attest_subject', 'Attest subject, generate sealed Policy Artifact. Auto-loads into portal.', {
|
|
132
|
+
subject_content: z.string().describe('Content/bytes of the subject'),
|
|
133
|
+
subject_metadata: z.object({ filename: z.string().optional(), version: z.string().optional(), author: z.string().optional(), content_type: z.string().optional() }),
|
|
75
134
|
evidence_items: z.array(z.object({ label: z.string(), content: z.string() })).default([]),
|
|
76
135
|
behavioral_baseline: z.object({
|
|
77
136
|
permitted_tools: z.array(z.string()),
|
|
@@ -79,162 +138,231 @@ export async function createAGAServer() {
|
|
|
79
138
|
forbidden_sequences: z.array(z.array(z.string())),
|
|
80
139
|
window_ms: z.number(),
|
|
81
140
|
}).optional(),
|
|
82
|
-
}, async (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
141
|
+
}, async ({ subject_content, subject_metadata, evidence_items, behavioral_baseline }) => {
|
|
142
|
+
const subId = computeSubjectIdFromString(subject_content, subject_metadata);
|
|
143
|
+
const policyRef = sha256Str(JSON.stringify(DEFAULT_ENFORCEMENT));
|
|
144
|
+
const att = performAttestation({ subject_identifier: subId, policy_reference: policyRef, evidence_items });
|
|
145
|
+
if (!att.success || !att.sealed_hash || !att.seal_salt)
|
|
146
|
+
return j({ success: false, error: att.rejection_reason });
|
|
147
|
+
const artifact = generateArtifact({
|
|
148
|
+
subject_identifier: subId, policy_reference: policyRef, policy_version: 1,
|
|
149
|
+
sealed_hash: att.sealed_hash, seal_salt: att.seal_salt,
|
|
150
|
+
enforcement_parameters: DEFAULT_ENFORCEMENT, disclosure_policy: DEFAULT_CLAIMS,
|
|
151
|
+
evidence_commitments: att.evidence_commitments, issuer_keypair: issuerKP,
|
|
152
|
+
});
|
|
153
|
+
await storage.storeArtifact(artifact);
|
|
154
|
+
portal.reset();
|
|
155
|
+
portal.loadArtifact(artifact, pkToHex(issuerKP.publicKey));
|
|
156
|
+
quarantine = null;
|
|
157
|
+
behavioralMonitor.reset();
|
|
158
|
+
if (behavioral_baseline)
|
|
159
|
+
behavioralMonitor.setBaseline(behavioral_baseline);
|
|
160
|
+
await autoChain('POLICY_ISSUANCE', { artifact_hash: hashArtifact(artifact), sealed_hash: artifact.sealed_hash });
|
|
161
|
+
return j({
|
|
162
|
+
success: true, artifact_hash: hashArtifact(artifact), sealed_hash: artifact.sealed_hash,
|
|
163
|
+
subject_identifier: subId, portal_state: portal.state,
|
|
164
|
+
issuer_public_key: pkToHex(issuerKP.publicKey),
|
|
165
|
+
});
|
|
102
166
|
});
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}, async (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
167
|
+
// ══════════════════════════════════════════════════════════════
|
|
168
|
+
// TOOL: measure_integrity
|
|
169
|
+
// V3: Generates receipt for EVERY measurement (match or mismatch)
|
|
170
|
+
// V3: Checks TTL and revocation (fail-closed)
|
|
171
|
+
// ══════════════════════════════════════════════════════════════
|
|
172
|
+
governedTool('measure_integrity', 'Measure subject state, compare to sealed reference. Generates signed receipt for every measurement.', {
|
|
173
|
+
subject_content: z.string().describe('Current content of the subject'),
|
|
174
|
+
subject_metadata: z.object({ filename: z.string().optional(), version: z.string().optional(), author: z.string().optional(), content_type: z.string().optional() }),
|
|
175
|
+
}, async ({ subject_content, subject_metadata }) => {
|
|
176
|
+
if (!portal.artifact)
|
|
177
|
+
return j({ success: false, error: 'No artifact loaded. Call attest_subject first.' });
|
|
178
|
+
if (portal.state === 'TERMINATED')
|
|
179
|
+
return j({ success: false, error: 'Portal is terminated. Re-attest required.' });
|
|
180
|
+
const result = portal.measure(new TextEncoder().encode(subject_content), subject_metadata);
|
|
181
|
+
const artRef = hashArtifact(portal.artifact);
|
|
182
|
+
const currentStr = result.currentBytesHash ? `${result.currentBytesHash}||${result.currentMetaHash}` : 'UNAVAILABLE';
|
|
183
|
+
const sealedStr = `${result.expectedBytesHash}||${result.expectedMetaHash}`;
|
|
184
|
+
// Determine enforcement action
|
|
185
|
+
let action = null;
|
|
186
|
+
let driftDesc = null;
|
|
187
|
+
if (!result.ttl_ok) {
|
|
188
|
+
driftDesc = 'TTL expired - fail-closed termination';
|
|
189
|
+
action = 'TERMINATE';
|
|
190
|
+
}
|
|
191
|
+
else if (result.revoked) {
|
|
192
|
+
driftDesc = 'Artifact revoked - fail-closed termination';
|
|
193
|
+
action = 'TERMINATE';
|
|
194
|
+
}
|
|
195
|
+
else if (!result.match) {
|
|
196
|
+
driftDesc = 'Subject modified - hash mismatch';
|
|
197
|
+
action = portal.artifact.enforcement_parameters.enforcement_triggers[0] ?? 'ALERT_ONLY';
|
|
198
|
+
portal.enforce(action);
|
|
199
|
+
if (action === 'QUARANTINE')
|
|
200
|
+
quarantine = initQuarantine();
|
|
201
|
+
}
|
|
202
|
+
// V3: Receipt for EVERY measurement - match or mismatch
|
|
203
|
+
const receipt = generateReceipt({
|
|
204
|
+
subjectId: portal.artifact.subject_identifier, artifactRef: artRef,
|
|
205
|
+
currentHash: currentStr, sealedHash: sealedStr,
|
|
206
|
+
driftDetected: !result.match, driftDescription: driftDesc,
|
|
207
|
+
action, measurementType: portal.artifact.enforcement_parameters.measurement_types.join(','),
|
|
208
|
+
seq: portal.sequenceCounter + 1, prevLeaf: portal.lastLeafHash, portalKP,
|
|
209
|
+
});
|
|
210
|
+
await storage.storeReceipt(receipt);
|
|
211
|
+
await autoChain('INTERACTION_RECEIPT', { receipt_id: receipt.receipt_id, drift_detected: !result.match, enforcement_action: action });
|
|
212
|
+
return j({
|
|
213
|
+
success: true, match: result.match, drift_detected: !result.match,
|
|
214
|
+
ttl_ok: result.ttl_ok, revoked: result.revoked,
|
|
215
|
+
enforcement_action: action, portal_state: portal.state,
|
|
216
|
+
receipt_id: receipt.receipt_id,
|
|
217
|
+
});
|
|
140
218
|
});
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
disclosure_mode: z.enum(['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL']).optional(),
|
|
147
|
-
}, async (args) => handleDiscloseClaim({
|
|
148
|
-
claim_id: args.claim_id,
|
|
149
|
-
requester_id: args.requester_id,
|
|
150
|
-
mode: args.disclosure_mode ?? args.mode,
|
|
151
|
-
}, ctx));
|
|
152
|
-
// 13. aga_get_chain (ungoverned)
|
|
153
|
-
server.tool('aga_get_chain', 'Get continuity chain events with optional verification and filtering.', {
|
|
154
|
-
start_seq: z.number().optional(),
|
|
155
|
-
end_seq: z.number().optional(),
|
|
156
|
-
verify: z.boolean().optional(),
|
|
157
|
-
filter_type: z.string().optional().describe('Filter: all, behavioral, delegations, receipts, revocations, attestations, disclosure, keys'),
|
|
158
|
-
}, async (args) => handleGetChain(args, ctx));
|
|
159
|
-
// 14. aga_quarantine_status (ungoverned)
|
|
160
|
-
server.tool('aga_quarantine_status', 'Get quarantine state and forensic capture status.', {}, async () => handleQuarantineStatus({}, ctx));
|
|
161
|
-
// 15. aga_revoke_artifact (governed)
|
|
162
|
-
governedTool('aga_revoke_artifact', 'Revoke an active policy artifact mid-session. Supports TERMINATED or SAFE_STATE transition.', {
|
|
163
|
-
sealed_hash: z.string().optional().describe('Sealed hash of artifact to revoke'),
|
|
219
|
+
// ══════════════════════════════════════════════════════════════
|
|
220
|
+
// TOOL: revoke_artifact - V3 NEW (NCCoE Phase 3b)
|
|
221
|
+
// ══════════════════════════════════════════════════════════════
|
|
222
|
+
governedTool('revoke_artifact', 'Revoke an active policy artifact mid-session. Portal terminates on next measurement. (NCCoE Phase 3b)', {
|
|
223
|
+
sealed_hash: z.string().describe('Sealed hash of artifact to revoke'),
|
|
164
224
|
reason: z.string().describe('Reason for revocation'),
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
225
|
+
}, async ({ sealed_hash, reason }) => {
|
|
226
|
+
portal.revoke(sealed_hash);
|
|
227
|
+
const record = {
|
|
228
|
+
artifact_sealed_hash: sealed_hash, reason,
|
|
229
|
+
revoked_by: pkToHex(issuerKP.publicKey), timestamp: utcNow(),
|
|
230
|
+
};
|
|
231
|
+
await autoChain('REVOCATION', record);
|
|
232
|
+
return j({ success: true, revoked: sealed_hash, portal_state: portal.state, reason });
|
|
233
|
+
});
|
|
234
|
+
// ══════════════════════════════════════════════════════════════
|
|
235
|
+
// TOOL: verify_chain
|
|
236
|
+
// ══════════════════════════════════════════════════════════════
|
|
237
|
+
server.tool('verify_chain', 'Verify continuity chain integrity.', {}, async () => {
|
|
238
|
+
const events = await storage.getAllEvents();
|
|
239
|
+
if (!events.length)
|
|
240
|
+
return j({ success: false, error: 'No events in chain' });
|
|
241
|
+
const result = verifyChainIntegrity(events);
|
|
242
|
+
return j({ success: true, chain_valid: result.valid, events_verified: events.length, broken_at: result.brokenAt, error: result.error });
|
|
243
|
+
});
|
|
244
|
+
// ══════════════════════════════════════════════════════════════
|
|
245
|
+
// TOOL: create_checkpoint
|
|
246
|
+
// ══════════════════════════════════════════════════════════════
|
|
247
|
+
governedTool('create_checkpoint', 'Batch events into Merkle tree, anchor.', { anchor_network: z.string().default('local') }, async ({ anchor_network }) => {
|
|
248
|
+
const lastCP = await storage.getLatestCheckpoint();
|
|
249
|
+
const startSeq = lastCP ? lastCP.batch_end_sequence + 1 : 0;
|
|
250
|
+
const latest = await storage.getLatestEvent();
|
|
251
|
+
if (!latest)
|
|
252
|
+
return j({ success: false, error: 'No events' });
|
|
253
|
+
const events = await storage.getEvents(startSeq, latest.sequence_number);
|
|
254
|
+
if (!events.length)
|
|
255
|
+
return j({ success: false, error: 'No new events since last checkpoint' });
|
|
256
|
+
const { checkpoint, payload } = createCheckpoint(events, anchor_network);
|
|
257
|
+
await storage.storeCheckpoint(checkpoint);
|
|
258
|
+
await autoChain('ANCHOR_BATCH', payload);
|
|
259
|
+
return j({ success: true, merkle_root: checkpoint.merkle_root, events_checkpointed: events.length, transaction_id: checkpoint.transaction_id });
|
|
260
|
+
});
|
|
261
|
+
// ══════════════════════════════════════════════════════════════
|
|
262
|
+
// TOOL: generate_evidence_bundle
|
|
263
|
+
// ══════════════════════════════════════════════════════════════
|
|
264
|
+
governedTool('generate_evidence_bundle', 'Package artifact + receipts + Merkle proofs for offline verification.', {}, async () => {
|
|
265
|
+
const artifact = await storage.getLatestArtifact();
|
|
266
|
+
if (!artifact)
|
|
267
|
+
return j({ success: false, error: 'No artifact' });
|
|
268
|
+
const cp = await storage.getLatestCheckpoint();
|
|
269
|
+
if (!cp)
|
|
270
|
+
return j({ success: false, error: 'No checkpoint. Call create_checkpoint first.' });
|
|
271
|
+
const receipts = await storage.getReceiptsByArtifact(hashArtifact(artifact));
|
|
272
|
+
const batchEvents = await storage.getEvents(cp.batch_start_sequence, cp.batch_end_sequence);
|
|
273
|
+
const proofs = receipts
|
|
274
|
+
.filter(r => r.sequence_number >= cp.batch_start_sequence && r.sequence_number <= cp.batch_end_sequence)
|
|
275
|
+
.map(r => eventInclusionProof(batchEvents, r.sequence_number));
|
|
276
|
+
const bundle = generateBundle(artifact, receipts, proofs, cp, portalKP);
|
|
277
|
+
return j({ success: true, bundle, offline_verifiable: true, receipt_count: receipts.length, proof_count: proofs.length });
|
|
278
|
+
});
|
|
279
|
+
// ══════════════════════════════════════════════════════════════
|
|
280
|
+
// TOOL: verify_bundle_offline (Section J)
|
|
281
|
+
// ══════════════════════════════════════════════════════════════
|
|
282
|
+
governedTool('verify_bundle_offline', 'Verify evidence bundle offline. (Section J)', { bundle: z.any(), pinned_public_key: z.string() }, async ({ bundle, pinned_public_key }) => j({ success: true, verification: verifyBundleOffline(bundle, pinned_public_key) }));
|
|
283
|
+
// ══════════════════════════════════════════════════════════════
|
|
284
|
+
// TOOL: request_claim
|
|
285
|
+
// ══════════════════════════════════════════════════════════════
|
|
286
|
+
governedTool('request_claim', 'Request disclosure of a claim. Auto-substitutes if denied.', { claim_id: z.string(), requester_id: z.string().default('anonymous'), mode: z.enum(['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL']).default('REVEAL_MIN') }, async ({ claim_id, requester_id, mode }) => {
|
|
287
|
+
const latest = await storage.getLatestEvent();
|
|
288
|
+
const result = processDisclosure({ requested_claim_id: claim_id, requester_id, mode, timestamp: utcNow() }, DEFAULT_CLAIMS, CLAIM_VALUES, 1, latest?.sequence_number ?? 0, portalKP);
|
|
289
|
+
if (result.substitution_receipt)
|
|
290
|
+
await autoChain('SUBSTITUTION', result.substitution_receipt);
|
|
291
|
+
else
|
|
292
|
+
await autoChain('DISCLOSURE', { claim_id, mode, permitted: result.permitted });
|
|
293
|
+
return j({ success: true, ...result });
|
|
294
|
+
});
|
|
295
|
+
// ══════════════════════════════════════════════════════════════
|
|
296
|
+
// TOOL: list_claims
|
|
297
|
+
// ══════════════════════════════════════════════════════════════
|
|
298
|
+
server.tool('list_claims', 'List available claims with sensitivity levels.', {}, async () => {
|
|
299
|
+
return j({ claims: DEFAULT_CLAIMS.claims_taxonomy.map(c => ({ claim_id: c.claim_id, sensitivity: c.sensitivity, substitutes: c.substitutes, permitted_modes: c.permitted_modes })) });
|
|
300
|
+
});
|
|
301
|
+
// ══════════════════════════════════════════════════════════════
|
|
302
|
+
// TOOL: delegate_to_subagent (NCCoE: constrained sub-mandates)
|
|
303
|
+
// ══════════════════════════════════════════════════════════════
|
|
304
|
+
governedTool('delegate_to_subagent', 'Derive a constrained policy artifact for a sub-agent. Scope can only diminish, never expand. (NCCoE constrained delegation)', {
|
|
305
|
+
enforcement_triggers: z.array(z.string()).describe('Subset of parent enforcement triggers'),
|
|
306
|
+
measurement_types: z.array(z.string()).describe('Subset of parent measurement types'),
|
|
307
|
+
requested_ttl_seconds: z.number().describe('Requested TTL (will be clamped to parent remaining)'),
|
|
308
|
+
delegation_purpose: z.string().describe('Purpose of the delegation'),
|
|
309
|
+
}, async ({ enforcement_triggers, measurement_types, requested_ttl_seconds, delegation_purpose }) => {
|
|
310
|
+
if (!portal.artifact)
|
|
311
|
+
return j({ success: false, error: 'No artifact loaded. Call attest_subject first.' });
|
|
312
|
+
const result = deriveArtifact(portal.artifact, {
|
|
313
|
+
enforcement_triggers: enforcement_triggers,
|
|
314
|
+
measurement_types: measurement_types,
|
|
315
|
+
requested_ttl_seconds,
|
|
316
|
+
delegation_purpose,
|
|
317
|
+
}, issuerKP);
|
|
318
|
+
if (result.success) {
|
|
319
|
+
await autoChain('ATTESTATION', {
|
|
320
|
+
type: 'DELEGATION',
|
|
321
|
+
parent_artifact_hash: result.parent_artifact_hash,
|
|
322
|
+
child_artifact_hash: result.child_artifact_hash,
|
|
323
|
+
effective_ttl: result.effective_ttl_seconds,
|
|
324
|
+
scope_reduction: result.scope_reduction,
|
|
325
|
+
purpose: delegation_purpose,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return j(result);
|
|
329
|
+
});
|
|
330
|
+
// ══════════════════════════════════════════════════════════════
|
|
331
|
+
// TOOL: measure_behavior (NIST-2025-0035)
|
|
332
|
+
// ══════════════════════════════════════════════════════════════
|
|
333
|
+
server.tool('measure_behavior', 'Measure behavioral patterns of agent tool usage. Detects unauthorized tools, rate violations, and forbidden sequences. (NIST-2025-0035)', {}, async () => {
|
|
334
|
+
const measurement = behavioralMonitor.measure();
|
|
335
|
+
if (measurement.drift_detected) {
|
|
336
|
+
await autoChain('INTERACTION_RECEIPT', {
|
|
337
|
+
type: 'BEHAVIORAL_DRIFT',
|
|
338
|
+
violations: measurement.violations,
|
|
339
|
+
behavioral_hash: measurement.behavioral_hash,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
return j({
|
|
343
|
+
success: true,
|
|
344
|
+
...measurement,
|
|
345
|
+
violation_count: measurement.violations.length,
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
// ══════════════════════════════════════════════════════════════
|
|
349
|
+
// TOOL: get_receipts - V3 NEW
|
|
350
|
+
// ══════════════════════════════════════════════════════════════
|
|
351
|
+
server.tool('get_receipts', 'Get all signed receipts, optionally filtered by artifact.', { artifact_hash: z.string().optional() }, async ({ artifact_hash }) => {
|
|
352
|
+
const receipts = artifact_hash
|
|
353
|
+
? await storage.getReceiptsByArtifact(artifact_hash)
|
|
354
|
+
: await storage.getAllReceipts();
|
|
355
|
+
return j({ count: receipts.length, receipts: receipts.map(r => ({ receipt_id: r.receipt_id, drift_detected: r.drift_detected, enforcement_action: r.enforcement_action, measurement_type: r.measurement_type, timestamp: r.timestamp })) });
|
|
356
|
+
});
|
|
357
|
+
// ══════════════════════════════════════════════════════════════
|
|
358
|
+
// TOOL: get_chain_events - V3 NEW
|
|
359
|
+
// ══════════════════════════════════════════════════════════════
|
|
360
|
+
server.tool('get_chain_events', 'Get continuity chain events.', { start_seq: z.number().optional(), end_seq: z.number().optional() }, async ({ start_seq, end_seq }) => {
|
|
361
|
+
const events = (start_seq !== undefined && end_seq !== undefined)
|
|
362
|
+
? await storage.getEvents(start_seq, end_seq)
|
|
363
|
+
: await storage.getAllEvents();
|
|
364
|
+
return j({ count: events.length, events: events.map(e => ({ sequence_number: e.sequence_number, event_type: e.event_type, event_id: e.event_id, timestamp: e.timestamp, leaf_hash: e.leaf_hash.slice(0, 16) + '...' })) });
|
|
210
365
|
});
|
|
211
|
-
server.resource('crypto-primitives', CRYPTO_PRIMITIVES_URI, { mimeType: 'text/markdown', description: 'AGA cryptographic primitives documentation' }, async () => ({ contents: [{ uri: CRYPTO_PRIMITIVES_URI, mimeType: 'text/markdown', text: CRYPTO_PRIMITIVES_DOC }] }));
|
|
212
|
-
// ══════════════════════════════════════════════════════════════
|
|
213
|
-
// 3 PROMPTS
|
|
214
|
-
// ══════════════════════════════════════════════════════════════
|
|
215
|
-
server.prompt(NCCOE_DEMO_PROMPT.name, NCCOE_DEMO_PROMPT.description, {
|
|
216
|
-
agent_code: z.string().optional().describe('The agent source code to attest'),
|
|
217
|
-
include_behavioral: z.string().optional().describe('Include behavioral drift detection phase'),
|
|
218
|
-
}, async (args) => ({
|
|
219
|
-
messages: [{
|
|
220
|
-
role: 'user',
|
|
221
|
-
content: { type: 'text', text: NCCOE_DEMO_PROMPT.template(args) },
|
|
222
|
-
}],
|
|
223
|
-
}));
|
|
224
|
-
server.prompt(GOVERNANCE_REPORT_PROMPT.name, GOVERNANCE_REPORT_PROMPT.description, {}, async () => ({
|
|
225
|
-
messages: [{
|
|
226
|
-
role: 'user',
|
|
227
|
-
content: { type: 'text', text: GOVERNANCE_REPORT_PROMPT.template() },
|
|
228
|
-
}],
|
|
229
|
-
}));
|
|
230
|
-
server.prompt(DRIFT_ANALYSIS_PROMPT.name, DRIFT_ANALYSIS_PROMPT.description, {
|
|
231
|
-
drift_type: z.string().optional().describe('Type of drift: binary, behavioral, or both'),
|
|
232
|
-
}, async (args) => ({
|
|
233
|
-
messages: [{
|
|
234
|
-
role: 'user',
|
|
235
|
-
content: { type: 'text', text: DRIFT_ANALYSIS_PROMPT.template(args) },
|
|
236
|
-
}],
|
|
237
|
-
}));
|
|
238
366
|
return server;
|
|
239
367
|
}
|
|
240
368
|
//# sourceMappingURL=server.js.map
|