@dharma-ai-labs/agent-fabric 0.2.115 → 0.2.116
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 +16 -0
- package/dist/codexBoundSession.d.ts +2 -1
- package/dist/codexBoundSession.d.ts.map +1 -1
- package/dist/codexBoundSession.js.map +1 -1
- package/dist/codexInboxSession.d.ts +2 -0
- package/dist/codexInboxSession.d.ts.map +1 -1
- package/dist/codexInboxSession.js +1 -0
- package/dist/codexInboxSession.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/namedSessionEvidence.d.ts +26 -0
- package/dist/namedSessionEvidence.d.ts.map +1 -0
- package/dist/namedSessionEvidence.js +112 -0
- package/dist/namedSessionEvidence.js.map +1 -0
- package/dist/namedSessionEvidence.test.d.ts +2 -0
- package/dist/namedSessionEvidence.test.d.ts.map +1 -0
- package/dist/namedSessionEvidence.test.js +240 -0
- package/dist/namedSessionEvidence.test.js.map +1 -0
- package/dist/namedSessionService.d.ts +4 -1
- package/dist/namedSessionService.d.ts.map +1 -1
- package/dist/namedSessionService.js +50 -7
- package/dist/namedSessionService.js.map +1 -1
- package/dist/namedSessionService.test.js +215 -125
- package/dist/namedSessionService.test.js.map +1 -1
- package/dist/schemas/codex-local-work-capture.schema.json +44 -0
- package/dist/schemas/named-session-evidence.schema.json +29 -0
- package/package.json +4 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LocalVault, LocalProviderSessionBinding } from '@dharma-ai-labs/agent-fabric-local-vault';
|
|
2
|
+
import type { OrganizationPolicy } from '@dharma-ai-labs/agent-fabric-policy';
|
|
3
|
+
import type { CodexLocalWorkCapture } from '@dharma-ai-labs/agent-fabric-provider-adapters/experimental/codex-session';
|
|
4
|
+
export interface NamedSessionEvidenceReceipt {
|
|
5
|
+
schema: 'dharma.named-session-evidence/v1';
|
|
6
|
+
organizationId: string;
|
|
7
|
+
deviceId: string;
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
bindingId: string;
|
|
10
|
+
workId: string;
|
|
11
|
+
captureId: string;
|
|
12
|
+
captureHash: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
state: 'queued' | 'unavailable' | 'blocked';
|
|
15
|
+
trajectoryId: string | null;
|
|
16
|
+
capsuleHash: string | null;
|
|
17
|
+
code: 'relay_outbox_queued' | 'native_turn_unavailable' | 'evidence_queue_failed';
|
|
18
|
+
acceptedLearningObservation: false;
|
|
19
|
+
}
|
|
20
|
+
export declare function queueNamedSessionEvidence(input: {
|
|
21
|
+
vault: LocalVault;
|
|
22
|
+
capture: CodexLocalWorkCapture;
|
|
23
|
+
binding: Pick<LocalProviderSessionBinding, 'organizationId' | 'repositoryBindingId' | 'workspaceId' | 'deviceId' | 'endpointId' | 'membershipId' | 'provider' | 'bindingId' | 'sessionId' | 'workspaceRoot'>;
|
|
24
|
+
policy: OrganizationPolicy;
|
|
25
|
+
}): Promise<NamedSessionEvidenceReceipt>;
|
|
26
|
+
//# sourceMappingURL=namedSessionEvidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedSessionEvidence.d.ts","sourceRoot":"","sources":["../src/namedSessionEvidence.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,0CAA0C,CAAC;AACxG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAI9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2EAA2E,CAAC;AAEvH,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,kCAAkC,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;IAC5C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,qBAAqB,GAAG,yBAAyB,GAAG,uBAAuB,CAAC;IAClF,2BAA2B,EAAE,KAAK,CAAC;CACpC;AA0CD,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,gBAAgB,GAAG,qBAAqB,GAAG,aAAa,GAAG,UAAU,GAC5G,YAAY,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,eAAe,CAAC,CAAC;IAC9F,MAAM,EAAE,kBAAkB,CAAC;CAC5B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAoDvC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { validateContract } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
4
|
+
import { buildTrajectoryCapsule, trajectoryCapsuleHash } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
|
|
5
|
+
import { assertPolicy } from '@dharma-ai-labs/agent-fabric-policy';
|
|
6
|
+
import { stripProtectedNativeContent } from '@dharma-ai-labs/agent-fabric-provider-adapters';
|
|
7
|
+
function object(value) {
|
|
8
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
9
|
+
}
|
|
10
|
+
function sourceRecords(capture, workspace) {
|
|
11
|
+
const records = [], completed = new Set();
|
|
12
|
+
function addItem(item, receivedAt, started) {
|
|
13
|
+
const type = String(item.type || '');
|
|
14
|
+
const tools = ['commandExecution', 'mcpToolCall', 'dynamicToolCall'];
|
|
15
|
+
if (started && !tools.includes(type))
|
|
16
|
+
return;
|
|
17
|
+
const key = typeof item.id === 'string' ? item.id : JSON.stringify(item);
|
|
18
|
+
if (!started) {
|
|
19
|
+
if (completed.has(key))
|
|
20
|
+
return;
|
|
21
|
+
completed.add(key);
|
|
22
|
+
}
|
|
23
|
+
const kind = tools.includes(type) ? started ? 'tool_call' : 'tool_result'
|
|
24
|
+
: type === 'userMessage' ? 'user_message' : type === 'agentMessage' ? 'agent_message'
|
|
25
|
+
: type === 'fileChange' ? 'file_write' : 'metadata';
|
|
26
|
+
records.push({ native: stripProtectedNativeContent({ ...item, type: kind, providerItemType: type }), sourcePath: 'dharma-codex-turn',
|
|
27
|
+
line: records.length + 1, workspace, timestamp: receivedAt, kind, coverage: 'partial' });
|
|
28
|
+
}
|
|
29
|
+
for (const event of capture.events) {
|
|
30
|
+
const { method } = event.notification, params = object(event.notification.params);
|
|
31
|
+
const turn = object(params.turn);
|
|
32
|
+
if (params.threadId !== capture.providerThreadId
|
|
33
|
+
|| (params.turnId !== undefined && params.turnId !== capture.providerTurnId)
|
|
34
|
+
|| (turn.id !== undefined && turn.id !== capture.providerTurnId))
|
|
35
|
+
throw new Error('named_session_evidence_scope_mismatch');
|
|
36
|
+
if (method === 'item/started' || method === 'item/completed') {
|
|
37
|
+
addItem(object(params.item), event.receivedAt, method === 'item/started');
|
|
38
|
+
}
|
|
39
|
+
else if (method === 'turn/completed') {
|
|
40
|
+
if (turn.status !== capture.providerTurnState)
|
|
41
|
+
throw new Error('named_session_evidence_integrity_failed');
|
|
42
|
+
if (Array.isArray(turn.items))
|
|
43
|
+
for (const item of turn.items)
|
|
44
|
+
addItem(object(item), event.receivedAt, false);
|
|
45
|
+
records.push({ native: { type: 'session_state', status: turn.status, error: turn.error ?? null },
|
|
46
|
+
sourcePath: 'dharma-codex-turn', line: records.length + 1, workspace, timestamp: event.receivedAt,
|
|
47
|
+
kind: 'session_state', coverage: 'partial' });
|
|
48
|
+
}
|
|
49
|
+
else if (method === 'error') {
|
|
50
|
+
records.push({ native: { type: 'error', error: params.error ?? null }, sourcePath: 'dharma-codex-turn',
|
|
51
|
+
line: records.length + 1, workspace, timestamp: event.receivedAt, kind: 'error', coverage: 'partial' });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return records;
|
|
55
|
+
}
|
|
56
|
+
export async function queueNamedSessionEvidence(input) {
|
|
57
|
+
const { capture, binding, vault, policy } = input;
|
|
58
|
+
const valid = await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/codex-local-work-capture/v1', capture);
|
|
59
|
+
if (!valid.ok)
|
|
60
|
+
throw new Error('named_session_evidence_invalid');
|
|
61
|
+
for (const key of ['organizationId', 'repositoryBindingId', 'workspaceId', 'deviceId', 'endpointId',
|
|
62
|
+
'membershipId', 'provider', 'bindingId']) {
|
|
63
|
+
if (capture[key] !== binding[key])
|
|
64
|
+
throw new Error('named_session_evidence_scope_mismatch');
|
|
65
|
+
}
|
|
66
|
+
if (capture.providerThreadId !== binding.sessionId || policy.organizationId !== binding.organizationId
|
|
67
|
+
|| (policy.serverAuthorization && policy.serverAuthorization.workspaceId !== binding.workspaceId)) {
|
|
68
|
+
throw new Error('named_session_evidence_scope_mismatch');
|
|
69
|
+
}
|
|
70
|
+
const eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(capture.events)).digest('hex')}`;
|
|
71
|
+
if (eventsHash !== capture.eventsHash || Date.parse(capture.startedAt) > Date.parse(capture.closedAt)) {
|
|
72
|
+
throw new Error('named_session_evidence_integrity_failed');
|
|
73
|
+
}
|
|
74
|
+
assertPolicy(policy);
|
|
75
|
+
const raw = Buffer.from(JSON.stringify(capture));
|
|
76
|
+
const captureHash = `sha256:${createHash('sha256').update(raw).digest('hex')}`;
|
|
77
|
+
const base = { schema: 'dharma.named-session-evidence/v1', organizationId: binding.organizationId,
|
|
78
|
+
deviceId: binding.deviceId, workspaceId: binding.workspaceId, bindingId: binding.bindingId, workId: capture.workId,
|
|
79
|
+
captureId: capture.captureId, captureHash, createdAt: capture.closedAt, acceptedLearningObservation: false };
|
|
80
|
+
if (!capture.providerTurnId || !capture.events.length || capture.providerTurnState === 'unconfirmed') {
|
|
81
|
+
return { ...base, state: 'unavailable', trajectoryId: null, capsuleHash: null, code: 'native_turn_unavailable' };
|
|
82
|
+
}
|
|
83
|
+
// Turn notifications do not prove full context, executed model, or applied skill. Preserve that limit in the capsule.
|
|
84
|
+
const session = { provider: 'codex', sessionId: `codex-turn:${binding.sessionId}:${capture.providerTurnId}`,
|
|
85
|
+
sourcePath: 'dharma-codex-turn', workspace: binding.workspaceRoot, records: sourceRecords(capture, binding.workspaceRoot),
|
|
86
|
+
coverage: 'partial', startedAt: capture.startedAt, endedAt: capture.closedAt };
|
|
87
|
+
if (!session.records.length)
|
|
88
|
+
return { ...base, state: 'unavailable', trajectoryId: null, capsuleHash: null,
|
|
89
|
+
code: 'native_turn_unavailable' };
|
|
90
|
+
const capsule = buildTrajectoryCapsule({ organizationId: binding.organizationId, deviceId: binding.deviceId,
|
|
91
|
+
workspaceId: binding.workspaceId, session, policy, rawContentId: captureHash, rawBytes: raw.length,
|
|
92
|
+
rawKind: 'raw-provider-turn' });
|
|
93
|
+
capsule.coverage.missingFields = [...new Set([...capsule.coverage.missingFields.filter(field => field !== 'workspace_on_some_events'),
|
|
94
|
+
'turn_notifications_only', 'executed_model_unreported', 'applied_skill_unverified', ...capture.limitations])];
|
|
95
|
+
capsule.capsuleHash = trajectoryCapsuleHash(capsule);
|
|
96
|
+
const checked = await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/trajectory-capsule/v2', capsule);
|
|
97
|
+
if (!checked.ok || Buffer.byteLength(JSON.stringify(capsule)) > policy.evidence.maximumCapsuleBytes) {
|
|
98
|
+
throw new Error('named_session_evidence_capsule_invalid');
|
|
99
|
+
}
|
|
100
|
+
const existing = vault.getCapsuleMetadata(capsule.trajectoryId, capsule.revision);
|
|
101
|
+
if (existing && existing.capsuleHash !== capsule.capsuleHash)
|
|
102
|
+
throw new Error('named_session_evidence_revision_conflict');
|
|
103
|
+
if (!existing)
|
|
104
|
+
await vault.commitCapture({ raw: { plaintext: raw, kind: 'raw-provider-turn', expectedContentId: captureHash },
|
|
105
|
+
capsule: { plaintext: Buffer.from(JSON.stringify(capsule)), trajectoryId: capsule.trajectoryId,
|
|
106
|
+
revision: capsule.revision, capsuleHash: capsule.capsuleHash },
|
|
107
|
+
session: { sessionId: session.sessionId, provider: session.provider, workspaceId: binding.workspaceId,
|
|
108
|
+
sourceLocator: session.sourcePath, status: session.coverage, observedAt: session.endedAt } });
|
|
109
|
+
vault.queueCapsuleSync(capsule.trajectoryId, capsule.revision);
|
|
110
|
+
return { ...base, state: 'queued', trajectoryId: capsule.trajectoryId, capsuleHash: capsule.capsuleHash, code: 'relay_outbox_queued' };
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=namedSessionEvidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedSessionEvidence.js","sourceRoot":"","sources":["../src/namedSessionEvidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedSessionEvidence.test.d.ts","sourceRoot":"","sources":["../src/namedSessionEvidence.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { createHash, generateKeyPairSync, randomBytes, randomUUID } from 'node:crypto';
|
|
3
|
+
import { mkdtemp, readFile } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import test from 'node:test';
|
|
7
|
+
import { LocalVault } from '@dharma-ai-labs/agent-fabric-local-vault';
|
|
8
|
+
import { signCanonicalObject, validateContract } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
9
|
+
import { verifyServerAuthorizedPolicy } from '@dharma-ai-labs/agent-fabric-policy';
|
|
10
|
+
import { queueNamedSessionEvidence } from './namedSessionEvidence.js';
|
|
11
|
+
import { syncPendingRetentionCapsules } from './index.js';
|
|
12
|
+
function fixture() {
|
|
13
|
+
const identity = { organizationId: 'org_test', repositoryBindingId: randomUUID(), workspaceId: randomUUID(),
|
|
14
|
+
endpointId: randomUUID(), membershipId: randomUUID(), deviceId: randomUUID(), provider: 'codex' };
|
|
15
|
+
const bindingId = randomUUID(), sessionId = randomUUID(), turnId = randomUUID();
|
|
16
|
+
const startedAt = new Date(Date.now() - 1000).toISOString(), closedAt = new Date().toISOString();
|
|
17
|
+
const events = [
|
|
18
|
+
{ method: 'item/completed', params: { threadId: sessionId, turnId,
|
|
19
|
+
item: { id: 'user-1', type: 'userMessage', content: [{ type: 'text', text: 'Run public tests.' }] } } },
|
|
20
|
+
{ method: 'item/started', params: { threadId: sessionId, turnId,
|
|
21
|
+
item: { id: 'command-1', type: 'commandExecution', command: 'npm test', status: 'inProgress' } } },
|
|
22
|
+
{ method: 'item/completed', params: { threadId: sessionId, turnId,
|
|
23
|
+
item: { id: 'command-1', type: 'commandExecution', command: 'npm test', exitCode: 0, aggregatedOutput: 'SYNTHETIC_TEST_OUTPUT' } } },
|
|
24
|
+
{ method: 'item/completed', params: { threadId: sessionId, turnId,
|
|
25
|
+
item: { id: 'answer-1', type: 'agentMessage', phase: 'final_answer', text: 'Public tests passed.' } } },
|
|
26
|
+
{ method: 'turn/completed', params: { threadId: sessionId, turn: { id: turnId, status: 'completed', items: [] } } },
|
|
27
|
+
].map((notification, sequence) => ({ sequence, receivedAt: closedAt, notification }));
|
|
28
|
+
const capture = { schema: 'dharma.codex-local-work-capture/v1', captureId: randomUUID(),
|
|
29
|
+
...identity, bindingId, workId: randomUUID(), providerThreadId: sessionId, providerTurnId: turnId,
|
|
30
|
+
startedAt, closedAt, workOutcome: 'completed', providerTurnState: 'completed', captureScope: 'turn_notifications',
|
|
31
|
+
coverage: 'observed', limitations: [], droppedEvents: 0, acceptedLearningObservation: false, executedModel: null,
|
|
32
|
+
events, eventsHash: `sha256:${createHash('sha256').update(JSON.stringify(events)).digest('hex')}` };
|
|
33
|
+
const policy = { schema: 'dharma.organization-policy/v2', organizationId: identity.organizationId,
|
|
34
|
+
revision: 'rev_test', evidence: { defaultMode: 'deep', registeredWorkspaceOnly: true,
|
|
35
|
+
automaticDisclosure: { mode: 'local_analysis' }, excludePaths: ['**/.env', '**/private-graders/**'],
|
|
36
|
+
maximumCapsuleBytes: 1_000_000, maximumDailyUploadBytes: 5_000_000, maximumExpansionBytes: 1_000_000 },
|
|
37
|
+
tasks: { defaultNetwork: 'deny', defaultGit: 'task_branch', writePaths: ['src/**'],
|
|
38
|
+
requireLocalConfirmationFor: [], allowedCommands: { test: { argv: ['npm', 'test'], timeoutSeconds: 60 } } },
|
|
39
|
+
skills: { automaticInstall: true, automaticPromotionMaxRisk: 'R2', canaryPercent: 10 }, retention: {}, budgets: {} };
|
|
40
|
+
return { capture, policy, binding: { ...identity, bindingId, sessionId, workspaceRoot: '/synthetic/repository' } };
|
|
41
|
+
}
|
|
42
|
+
async function withVault(operation) {
|
|
43
|
+
const root = await mkdtemp(join(tmpdir(), 'named-evidence-'));
|
|
44
|
+
const vault = await LocalVault.open({ root, masterKey: randomBytes(32) });
|
|
45
|
+
try {
|
|
46
|
+
await operation(vault, root);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
vault.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
test('native named turns enter the encrypted relay outbox, not the accepted learning counter', async () => {
|
|
53
|
+
await withVault(async (vault, root) => {
|
|
54
|
+
const input = fixture();
|
|
55
|
+
const result = await queueNamedSessionEvidence({ ...input, vault });
|
|
56
|
+
assert.equal(result.state, 'queued');
|
|
57
|
+
assert.equal(result.acceptedLearningObservation, false);
|
|
58
|
+
assert.equal((await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/named-session-evidence/v1', result)).ok, true);
|
|
59
|
+
const pending = await vault.listPendingCapsuleSyncs();
|
|
60
|
+
assert.equal(pending.length, 1);
|
|
61
|
+
const capsule = pending[0].capsule;
|
|
62
|
+
assert.equal(capsule.deviceId, input.binding.deviceId);
|
|
63
|
+
assert.equal(capsule.workspaceId, input.binding.workspaceId);
|
|
64
|
+
assert.equal((await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/trajectory-capsule/v2', capsule)).ok, true);
|
|
65
|
+
assert.equal(JSON.stringify(capsule).includes('SYNTHETIC_TEST_OUTPUT'), false);
|
|
66
|
+
assert.equal(capsule.coverage && capsule.coverage.state, 'partial');
|
|
67
|
+
assert.ok(capsule.coverage.missingFields.includes('turn_notifications_only'));
|
|
68
|
+
assert.deepEqual(capsule.localAnalysis.toolDiscipline, { calls: 1, results: 1, unmatchedCalls: 0, orphanResults: 0 });
|
|
69
|
+
const digest = result.captureHash.slice(7);
|
|
70
|
+
assert.equal((await readFile(join(root, 'blobs', digest.slice(0, 2), `${digest}.blob`)))
|
|
71
|
+
.includes(Buffer.from('SYNTHETIC_TEST_OUTPUT')), false);
|
|
72
|
+
assert.ok((await vault.getBlob(result.captureHash)).includes(Buffer.from('SYNTHETIC_TEST_OUTPUT')));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
test('queue replay is idempotent, but another real turn has a distinct trajectory', async () => {
|
|
76
|
+
await withVault(async (vault) => {
|
|
77
|
+
const input = fixture();
|
|
78
|
+
const first = await queueNamedSessionEvidence({ ...input, vault });
|
|
79
|
+
assert.deepEqual(await queueNamedSessionEvidence({ ...input, vault }), first);
|
|
80
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 1);
|
|
81
|
+
const other = fixture();
|
|
82
|
+
other.binding = input.binding;
|
|
83
|
+
for (const key of ['organizationId', 'repositoryBindingId', 'workspaceId', 'deviceId', 'endpointId', 'membershipId', 'bindingId']) {
|
|
84
|
+
other.capture[key] = input.binding[key];
|
|
85
|
+
}
|
|
86
|
+
other.capture.providerThreadId = input.binding.sessionId;
|
|
87
|
+
for (const event of other.capture.events)
|
|
88
|
+
event.notification.params = {
|
|
89
|
+
...event.notification.params, threadId: input.binding.sessionId
|
|
90
|
+
};
|
|
91
|
+
other.capture.eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(other.capture.events)).digest('hex')}`;
|
|
92
|
+
const second = await queueNamedSessionEvidence({ ...other, vault });
|
|
93
|
+
assert.notEqual(second.trajectoryId, first.trajectoryId);
|
|
94
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 2);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
test('foreign scope, changed hashes, and forged policy do not enter the queue', async () => {
|
|
98
|
+
await withVault(async (vault) => {
|
|
99
|
+
for (const key of ['organizationId', 'repositoryBindingId', 'workspaceId', 'deviceId', 'endpointId', 'membershipId', 'bindingId']) {
|
|
100
|
+
const input = fixture();
|
|
101
|
+
Object.assign(input.capture, { [key]: key === 'organizationId' ? 'org_foreign' : randomUUID() });
|
|
102
|
+
await assert.rejects(queueNamedSessionEvidence({ ...input, vault }), /scope_mismatch/);
|
|
103
|
+
}
|
|
104
|
+
const input = fixture();
|
|
105
|
+
input.capture.eventsHash = `sha256:${'0'.repeat(64)}`;
|
|
106
|
+
await assert.rejects(queueNamedSessionEvidence({ ...input, vault }), /integrity_failed/);
|
|
107
|
+
const foreign = fixture();
|
|
108
|
+
foreign.policy.organizationId = 'org_foreign';
|
|
109
|
+
await assert.rejects(queueNamedSessionEvidence({ ...foreign, vault }), /scope_mismatch/);
|
|
110
|
+
const forged = fixture();
|
|
111
|
+
forged.policy.evidence.automaticDisclosure = { mode: 'customer_authorized_content',
|
|
112
|
+
consentReceiptId: 'unverified', allowedContentClasses: ['native_provider_payload'] };
|
|
113
|
+
await assert.rejects(queueNamedSessionEvidence({ ...forged, vault }));
|
|
114
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 0);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
test('unconfirmed and empty turns remain local and explicit; failed executions are partial evidence', async () => {
|
|
118
|
+
await withVault(async (vault) => {
|
|
119
|
+
for (const change of [{ providerTurnId: null, coverage: 'unavailable' },
|
|
120
|
+
{ providerTurnState: 'unconfirmed' }, { events: [] }]) {
|
|
121
|
+
const input = fixture();
|
|
122
|
+
Object.assign(input.capture, change);
|
|
123
|
+
input.capture.eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(input.capture.events)).digest('hex')}`;
|
|
124
|
+
const result = await queueNamedSessionEvidence({ ...input, vault });
|
|
125
|
+
assert.equal(result.state, 'unavailable');
|
|
126
|
+
assert.equal(result.acceptedLearningObservation, false);
|
|
127
|
+
}
|
|
128
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 0);
|
|
129
|
+
const failed = fixture();
|
|
130
|
+
failed.capture.workOutcome = 'failed';
|
|
131
|
+
failed.capture.providerTurnState = 'failed';
|
|
132
|
+
const terminal = failed.capture.events.at(-1);
|
|
133
|
+
terminal.notification.params.turn.status = 'failed';
|
|
134
|
+
failed.capture.eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(failed.capture.events)).digest('hex')}`;
|
|
135
|
+
assert.equal((await queueNamedSessionEvidence({ ...failed, vault })).state, 'queued');
|
|
136
|
+
const capsule = (await vault.listPendingCapsuleSyncs())[0].capsule;
|
|
137
|
+
assert.equal(capsule.status, 'partial');
|
|
138
|
+
assert.ok(capsule.localAnalysis.semanticReviewRecommended);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
test('signed content disclosure filters protected provider fields, secrets and private paths', async () => {
|
|
142
|
+
await withVault(async (vault) => {
|
|
143
|
+
const input = fixture(), keys = generateKeyPairSync('ed25519');
|
|
144
|
+
input.policy.evidence.pseudonymizeIdentity = true;
|
|
145
|
+
const disclosure = { mode: 'customer_authorized_content', consentReceiptId: 'approved-test-consent',
|
|
146
|
+
allowedContentClasses: ['native_provider_payload'] };
|
|
147
|
+
input.policy.evidence.automaticDisclosure = disclosure;
|
|
148
|
+
const unsigned = { schema: 'dharma.workspace-policy-authorization/v1',
|
|
149
|
+
organizationId: input.binding.organizationId, workspaceId: input.binding.workspaceId,
|
|
150
|
+
policy: { revision: input.policy.revision, evidence: { ...input.policy.evidence,
|
|
151
|
+
automaticDisclosure: disclosure, pseudonymizeIdentity: true } },
|
|
152
|
+
issuedAt: new Date(Date.now() - 1000).toISOString(), expiresAt: new Date(Date.now() + 60000).toISOString(), keyVersion: 'test' };
|
|
153
|
+
input.policy.serverAuthorization = { ...unsigned, signature: signCanonicalObject(unsigned, keys.privateKey) };
|
|
154
|
+
const command = input.capture.events[2].notification.params.item;
|
|
155
|
+
command.encryptedContent = 'PROTECTED_NATIVE_CANARY';
|
|
156
|
+
command.aggregatedOutput = 'SYNTHETIC_TEST_OUTPUT';
|
|
157
|
+
command.result = { apiKey: 'SECRET_FIELD_CANARY' };
|
|
158
|
+
const answer = input.capture.events[3].notification.params.item;
|
|
159
|
+
answer.path = 'private-graders/hidden.json';
|
|
160
|
+
answer.text = 'PRIVATE_GRADER_CANARY';
|
|
161
|
+
input.capture.eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(input.capture.events)).digest('hex')}`;
|
|
162
|
+
verifyServerAuthorizedPolicy({ policy: input.policy, publicKeyEd25519: keys.publicKey.export({ format: 'jwk' }).x,
|
|
163
|
+
organizationId: input.binding.organizationId, workspaceId: input.binding.workspaceId });
|
|
164
|
+
await queueNamedSessionEvidence({ ...input, vault });
|
|
165
|
+
const wire = JSON.stringify((await vault.listPendingCapsuleSyncs())[0].capsule);
|
|
166
|
+
assert.ok(wire.includes('SYNTHETIC_TEST_OUTPUT'));
|
|
167
|
+
for (const excluded of ['PROTECTED_NATIVE_CANARY', 'SECRET_FIELD_CANARY', 'PRIVATE_GRADER_CANARY']) {
|
|
168
|
+
assert.equal(wire.includes(excluded), false);
|
|
169
|
+
}
|
|
170
|
+
input.policy.serverAuthorization.expiresAt = new Date(Date.now() - 1).toISOString();
|
|
171
|
+
await assert.rejects(queueNamedSessionEvidence({ ...input, vault }));
|
|
172
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 1);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
test('encrypted evidence outbox survives reopening without dispatching another provider turn', async () => {
|
|
176
|
+
const root = await mkdtemp(join(tmpdir(), 'named-evidence-restart-')), masterKey = randomBytes(32);
|
|
177
|
+
let vault = await LocalVault.open({ root, masterKey });
|
|
178
|
+
const input = fixture();
|
|
179
|
+
const first = await queueNamedSessionEvidence({ ...input, vault });
|
|
180
|
+
vault.close();
|
|
181
|
+
vault = await LocalVault.open({ root, masterKey });
|
|
182
|
+
try {
|
|
183
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 1);
|
|
184
|
+
assert.deepEqual(await queueNamedSessionEvidence({ ...input, vault }), first);
|
|
185
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 1);
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
vault.close();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
test('scoped capture cannot smuggle another thread or turn through a recomputed hash', async () => {
|
|
192
|
+
await withVault(async (vault) => {
|
|
193
|
+
for (const key of ['threadId', 'turnId']) {
|
|
194
|
+
const input = fixture();
|
|
195
|
+
input.capture.events[0].notification.params[key] = randomUUID();
|
|
196
|
+
input.capture.eventsHash = `sha256:${createHash('sha256').update(JSON.stringify(input.capture.events)).digest('hex')}`;
|
|
197
|
+
await assert.rejects(queueNamedSessionEvidence({ ...input, vault }), /scope_mismatch/);
|
|
198
|
+
}
|
|
199
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 0);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
test('normal relay drain admits scoped partial turns, resumes offline delivery, and preserves revoked raw evidence', async () => {
|
|
203
|
+
await withVault(async (vault, root) => {
|
|
204
|
+
const previous = process.env.DHARMA_HOME;
|
|
205
|
+
process.env.DHARMA_HOME = join(root, 'home');
|
|
206
|
+
try {
|
|
207
|
+
const input = fixture(), receipt = await queueNamedSessionEvidence({ ...input, vault });
|
|
208
|
+
let offline = true, sends = 0;
|
|
209
|
+
const fabric = { config: { organizationId: input.binding.organizationId, deviceId: input.binding.deviceId },
|
|
210
|
+
async syncTrajectory(capsule) {
|
|
211
|
+
assert.equal(capsule.trajectoryId, receipt.trajectoryId);
|
|
212
|
+
sends++;
|
|
213
|
+
if (offline)
|
|
214
|
+
throw new Error('offline');
|
|
215
|
+
return { ok: true };
|
|
216
|
+
} };
|
|
217
|
+
await assert.rejects(syncPendingRetentionCapsules(vault, fabric, input.policy, input.binding.workspaceId), /offline/);
|
|
218
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 1);
|
|
219
|
+
offline = false;
|
|
220
|
+
assert.equal(await syncPendingRetentionCapsules(vault, fabric, input.policy, input.binding.workspaceId), 1);
|
|
221
|
+
assert.equal(await syncPendingRetentionCapsules(vault, fabric, input.policy, input.binding.workspaceId), 0);
|
|
222
|
+
assert.equal(sends, 2);
|
|
223
|
+
const revoked = fixture();
|
|
224
|
+
const denied = await queueNamedSessionEvidence({ ...revoked, vault });
|
|
225
|
+
revoked.policy.evidence.automaticDisclosure = { mode: 'metadata_only' };
|
|
226
|
+
const noSend = { config: { organizationId: revoked.binding.organizationId, deviceId: revoked.binding.deviceId },
|
|
227
|
+
syncTrajectory: async () => { throw new Error('revoked content must never be sent'); } };
|
|
228
|
+
assert.equal(await syncPendingRetentionCapsules(vault, noSend, revoked.policy, revoked.binding.workspaceId), 0);
|
|
229
|
+
assert.equal((await vault.listPendingCapsuleSyncs()).length, 0);
|
|
230
|
+
assert.ok(await vault.getBlob(denied.captureHash));
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
if (previous === undefined)
|
|
234
|
+
delete process.env.DHARMA_HOME;
|
|
235
|
+
else
|
|
236
|
+
process.env.DHARMA_HOME = previous;
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
//# sourceMappingURL=namedSessionEvidence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namedSessionEvidence.test.js","sourceRoot":"","sources":["../src/namedSessionEvidence.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { LocalProviderSessionIdentity, LocalVault } from '@dharma-ai-labs/agent-fabric-local-vault';
|
|
2
|
-
import type
|
|
2
|
+
import { type SessionQuestionVerifier } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
3
3
|
import { openCodexInboxSession } from './codexInboxSession.js';
|
|
4
|
+
import type { CodexLocalWorkCapture } from '@dharma-ai-labs/agent-fabric-provider-adapters/experimental/codex-session';
|
|
5
|
+
import type { NamedSessionEvidenceReceipt } from './namedSessionEvidence.js';
|
|
4
6
|
export interface NamedSessionRegistration {
|
|
5
7
|
schema: 'dharma.named-session/v1';
|
|
6
8
|
name: string;
|
|
@@ -30,6 +32,7 @@ export declare function runNamedSessionService(input: {
|
|
|
30
32
|
authorizeContent: Parameters<typeof openCodexInboxSession>[0]['authorizeContent'];
|
|
31
33
|
localWriteRoots: string[];
|
|
32
34
|
authorizeLocalWork(): Promise<boolean>;
|
|
35
|
+
queueEvidence?(capture: CodexLocalWorkCapture): Promise<NamedSessionEvidenceReceipt>;
|
|
33
36
|
withActivationBoundary<T>(operation: () => Promise<T>): Promise<T>;
|
|
34
37
|
signal: AbortSignal;
|
|
35
38
|
}): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namedSessionService.d.ts","sourceRoot":"","sources":["../src/namedSessionService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,4BAA4B,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACzG,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"namedSessionService.d.ts","sourceRoot":"","sources":["../src/namedSessionService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,4BAA4B,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACzG,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACxG,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2EAA2E,CAAC;AACvH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAE7E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,yBAAyB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;CAClB;AAwBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;;;;EAO3D;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAS3G;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,iBAOnF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,oCAyBrG;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,wBAAwB,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IACxE,aAAa,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC5E,gBAAgB,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAClF,QAAQ,EAAE,uBAAuB,CAAC;IAClC,gBAAgB,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAClF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,aAAa,CAAC,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACrF,sBAAsB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,EAAE,WAAW,CAAC;CACrB;;;GAwJA"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { chmod, lstat, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { createConnection, createServer } from 'node:net';
|
|
4
|
-
import { resolve } from 'node:path';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
import { validateContract } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
5
6
|
import { openCodexInboxSession } from './codexInboxSession.js';
|
|
6
7
|
function validateRegistration(value, name) {
|
|
7
8
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
@@ -188,18 +189,52 @@ export async function runNamedSessionService(input) {
|
|
|
188
189
|
const intent = await input.vault.putBlob(Buffer.from(JSON.stringify({ workId: request.workId,
|
|
189
190
|
prompt: request.prompt, bindingId: binding.bindingId })), 'named-session-work-intent');
|
|
190
191
|
budget.beginWork(request.workId, intent);
|
|
192
|
+
let nativeEvidence = null;
|
|
191
193
|
try {
|
|
192
194
|
const result = await input.withActivationBoundary(() => owner.runWork({ workId: request.workId,
|
|
193
|
-
prompt: request.prompt, maximumProviderCostCents: registration.maximumTurnCostCents
|
|
194
|
-
|
|
195
|
+
prompt: request.prompt, maximumProviderCostCents: registration.maximumTurnCostCents,
|
|
196
|
+
onTurnEvidence: async (capture) => {
|
|
197
|
+
const valid = await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/codex-local-work-capture/v1', capture);
|
|
198
|
+
if (!valid.ok)
|
|
199
|
+
throw new Error('codex_session_evidence_invalid');
|
|
200
|
+
const contentHash = await input.vault.putBlob(Buffer.from(JSON.stringify(capture)), 'raw-provider-turn');
|
|
201
|
+
nativeEvidence = { schema: capture.schema, captureId: capture.captureId, contentHash,
|
|
202
|
+
coverage: capture.coverage, limitations: capture.limitations, providerTurnState: capture.providerTurnState,
|
|
203
|
+
acceptedLearningObservation: false };
|
|
204
|
+
if (input.queueEvidence) {
|
|
205
|
+
let synchronization;
|
|
206
|
+
try {
|
|
207
|
+
synchronization = await input.queueEvidence(capture);
|
|
208
|
+
const checked = await validateContract(join(import.meta.dirname, 'schemas'), 'https://schemas.dharma-ai.io/named-session-evidence/v1', synchronization);
|
|
209
|
+
if (!checked.ok || synchronization.captureHash !== contentHash || synchronization.captureId !== capture.captureId
|
|
210
|
+
|| synchronization.organizationId !== capture.organizationId || synchronization.deviceId !== capture.deviceId
|
|
211
|
+
|| synchronization.workspaceId !== capture.workspaceId || synchronization.bindingId !== capture.bindingId
|
|
212
|
+
|| synchronization.workId !== capture.workId)
|
|
213
|
+
throw new Error('named_session_evidence_receipt_invalid');
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Evidence failure cannot rewrite the actual coding result or authorize another provider turn.
|
|
217
|
+
synchronization = { schema: 'dharma.named-session-evidence/v1', organizationId: capture.organizationId,
|
|
218
|
+
deviceId: capture.deviceId, workspaceId: capture.workspaceId, bindingId: capture.bindingId,
|
|
219
|
+
workId: capture.workId, captureId: capture.captureId, captureHash: contentHash, createdAt: capture.closedAt,
|
|
220
|
+
state: 'blocked', trajectoryId: null, capsuleHash: null, code: 'evidence_queue_failed',
|
|
221
|
+
acceptedLearningObservation: false };
|
|
222
|
+
}
|
|
223
|
+
nativeEvidence.synchronization = synchronization;
|
|
224
|
+
}
|
|
225
|
+
} }));
|
|
226
|
+
const receipt = { ...result, intentHash: intent, nativeEvidence };
|
|
227
|
+
const blob = await input.vault.putBlob(Buffer.from(JSON.stringify(receipt)), 'named-session-work');
|
|
195
228
|
budget.finishWork(request.workId, 'completed', blob);
|
|
196
229
|
await health();
|
|
197
|
-
return { ok: true, ...
|
|
230
|
+
return { ok: true, ...receipt, completionHash: blob };
|
|
198
231
|
}
|
|
199
232
|
catch (error) {
|
|
200
|
-
const blob = await input.vault.putBlob(Buffer.from(JSON.stringify({ workId: request.workId,
|
|
201
|
-
code: error instanceof Error ? error.message : 'named_session_work_failed' })), 'named-session-work-failure');
|
|
233
|
+
const blob = await input.vault.putBlob(Buffer.from(JSON.stringify({ workId: request.workId, intentHash: intent,
|
|
234
|
+
code: error instanceof Error ? error.message : 'named_session_work_failed', nativeEvidence })), 'named-session-work-failure');
|
|
202
235
|
budget.finishWork(request.workId, 'failed', blob);
|
|
236
|
+
if (!await owner.assertActive())
|
|
237
|
+
closing = true;
|
|
203
238
|
await health();
|
|
204
239
|
throw error;
|
|
205
240
|
}
|
|
@@ -226,7 +261,15 @@ export async function runNamedSessionService(input) {
|
|
|
226
261
|
await chmod(paths.socket, 0o600);
|
|
227
262
|
await health();
|
|
228
263
|
while (!closing && !input.signal.aborted) {
|
|
229
|
-
|
|
264
|
+
let result;
|
|
265
|
+
try {
|
|
266
|
+
result = await enqueue(() => input.withActivationBoundary(() => owner.runNext()));
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
if (closing || input.signal.aborted)
|
|
270
|
+
break;
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
230
273
|
lastObservation = result;
|
|
231
274
|
await health();
|
|
232
275
|
if (result.state === 'reply_pending')
|