flow-external-agent-parity-integration.test.mjs
120 lines 3.9 KB
Raw
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge Human 1 day ago
1 /**
2 * Tier 2 — INTEGRATION: MCP = Hub handler = CLI parity for grants + agent_bundle gate off.
3 */
4 import { describe, it, beforeEach, afterEach } from 'node:test';
5 import assert from 'node:assert/strict';
6 import fs from 'node:fs';
7 import path from 'node:path';
8 import { fileURLToPath } from 'node:url';
9
10 import { handleFlowProjectRequest } from '../lib/flow/flow-handlers.mjs';
11 import {
12 handleFlowExternalGrantMintRequest,
13 handleFlowExternalGrantListRequest,
14 } from '../lib/flow/external-agent.mjs';
15 import { upsertFlowVersion } from '../lib/flow/flow-store.mjs';
16 import {
17 writeExternalAgentPolicy,
18 makeExternalToolFlowBundle,
19 } from './fixtures/flow/external-agent-helpers.mjs';
20
21 const __dirname = path.dirname(fileURLToPath(import.meta.url));
22 const tmpRoot = path.join(__dirname, 'fixtures', 'tmp-flow-external-agent-parity');
23
24 function stripVolatileMint(payload) {
25 const copy = structuredClone(payload);
26 delete copy.bearer;
27 if (copy.grant) {
28 delete copy.grant.grant_id;
29 delete copy.grant.expires_at;
30 delete copy.grant.issued_at;
31 }
32 delete copy.expires_at;
33 return copy;
34 }
35
36 describe('Flow external-agent — parity integration', () => {
37 const dataDir = path.join(tmpRoot, 'data');
38 const vaultId = 'default';
39
40 beforeEach(() => {
41 fs.rmSync(tmpRoot, { recursive: true, force: true });
42 fs.mkdirSync(dataDir, { recursive: true });
43 writeExternalAgentPolicy(dataDir);
44 process.env.FLOW_EXTERNAL_AGENT_ENABLED = '1';
45 const bundle = makeExternalToolFlowBundle();
46 upsertFlowVersion(dataDir, vaultId, bundle.flow, bundle.steps);
47 });
48
49 afterEach(() => {
50 fs.rmSync(tmpRoot, { recursive: true, force: true });
51 delete process.env.FLOW_EXTERNAL_AGENT_ENABLED;
52 });
53
54 it('mint parity across Hub and CLI surfaces', () => {
55 const hub = handleFlowExternalGrantMintRequest({
56 dataDir,
57 vaultId,
58 role: 'admin',
59 flowId: 'flow_ext_agent_test',
60 flowVersion: '1.0.0',
61 requestedTools: ['web_search'],
62 });
63 const cli = handleFlowExternalGrantMintRequest({
64 dataDir,
65 vaultId,
66 cliScopes: ['personal', 'project'],
67 flowId: 'flow_ext_agent_test',
68 flowVersion: '1.0.0',
69 requestedTools: ['web_search'],
70 });
71 assert.equal(hub.ok, true);
72 assert.equal(cli.ok, true);
73 assert.deepEqual(stripVolatileMint(hub.payload), stripVolatileMint(cli.payload));
74 assert.ok(hub.payload.bearer.startsWith('fgrnt_bearer_'));
75 });
76
77 it('gate off ⇒ agent_bundle FLOW_HARNESS_UNSUPPORTED', () => {
78 delete process.env.FLOW_EXTERNAL_AGENT_ENABLED;
79 const policyPath = path.join(dataDir, 'hub_flow_external_agent_policy.json');
80 fs.rmSync(policyPath);
81 const result = handleFlowProjectRequest({
82 dataDir,
83 vaultId,
84 flowId: 'flow_ext_agent_test',
85 harness: 'agent_bundle',
86 cliScopes: ['personal'],
87 });
88 assert.equal(result.ok, false);
89 assert.equal(result.code, 'FLOW_HARNESS_UNSUPPORTED');
90 });
91
92 it('gate off ⇒ mint FLOW_EXTERNAL_AGENT_DISABLED', () => {
93 delete process.env.FLOW_EXTERNAL_AGENT_ENABLED;
94 const policyPath = path.join(dataDir, 'hub_flow_external_agent_policy.json');
95 fs.rmSync(policyPath);
96 const result = handleFlowExternalGrantMintRequest({
97 dataDir,
98 vaultId,
99 flowId: 'flow_ext_agent_test',
100 flowVersion: '1.0.0',
101 requestedTools: ['web_search'],
102 });
103 assert.equal(result.ok, false);
104 assert.equal(result.code, 'FLOW_EXTERNAL_AGENT_DISABLED');
105 });
106
107 it('list returns grants without bearer', () => {
108 handleFlowExternalGrantMintRequest({
109 dataDir,
110 vaultId,
111 flowId: 'flow_ext_agent_test',
112 flowVersion: '1.0.0',
113 requestedTools: ['web_search'],
114 });
115 const list = handleFlowExternalGrantListRequest({ dataDir, vaultId });
116 assert.equal(list.ok, true);
117 assert.equal(list.payload.grants.length, 1);
118 assert.equal(JSON.stringify(list.payload).includes('bearer'), false);
119 });
120 });
File History 1 commit
sha256:8915fe406161f95c1681f9469375e7bae5b28c884f00bedbdef65e4b0cd0738d docs(flow): commit FLOW-V0-SPEC.md hygiene for 7A-INT merge Human 1 day ago