@dharma-ai-labs/agent-fabric 0.2.3 → 0.2.5
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/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -11
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +56 -1
- package/dist/index.test.js.map +1 -1
- package/dist/schemas/action-decision-acknowledgement.schema.json +17 -0
- package/dist/schemas/action-decision-receipt.schema.json +30 -0
- package/dist/schemas/action-decision-task-request.schema.json +48 -0
- package/dist/schemas/server-signing-keyset.schema.json +18 -0
- package/dist/schemas/task-action.schema.json +24 -0
- package/dist/schemas/task-envelope.schema.json +53 -0
- package/package.json +9 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { type ProviderId } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
2
|
+
import { type ProviderCapability, type ProviderId, type TrustedServerSigningKeyset } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
3
3
|
import { type TrajectoryCapsule } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
|
|
4
4
|
import { type OrganizationPolicy } from '@dharma-ai-labs/agent-fabric-policy';
|
|
5
5
|
import { type ProviderSession } from '@dharma-ai-labs/agent-fabric-provider-adapters';
|
|
@@ -54,6 +54,8 @@ export declare function assertTaskSkillPin(pinned: TaskEnvelope['skillBundle'],
|
|
|
54
54
|
export declare function taskSkillPinFailureCode(error: unknown): string;
|
|
55
55
|
export declare function requireExplicitConfirmation(flags: Map<string, string | boolean>, action: string): void;
|
|
56
56
|
export declare function parseSelectedProviderIds(values: Array<string | boolean>): ProviderId[] | null;
|
|
57
|
+
export declare function actionDecisionCapabilityFreshUntil(keyset: TrustedServerSigningKeyset, trustedKeyVersions: string[], now?: Date): string;
|
|
58
|
+
export declare function receiptAwareProviderCapabilities(providers: ProviderCapability[], now?: Date): Promise<ProviderCapability[]>;
|
|
57
59
|
export declare function installRepositoryAgentFabricSkill(input: {
|
|
58
60
|
workspace: string;
|
|
59
61
|
hqUrl: string;
|
|
@@ -86,6 +88,18 @@ export declare function assertTaskWorkspacePolicy(input: {
|
|
|
86
88
|
};
|
|
87
89
|
policy: Pick<OrganizationPolicy, 'organizationId' | 'serverAuthorization'>;
|
|
88
90
|
}): void;
|
|
91
|
+
export declare function acknowledgeTaskActionDecision(input: {
|
|
92
|
+
task: Pick<TaskEnvelope, 'taskId' | 'actionDecision'>;
|
|
93
|
+
receipt: Pick<TaskReceipt, 'actionAcknowledgement'>;
|
|
94
|
+
postEnforcement: (decisionId: string, acknowledgement: NonNullable<TaskReceipt['actionAcknowledgement']>) => Promise<unknown>;
|
|
95
|
+
}): Promise<boolean>;
|
|
96
|
+
export declare function postTaskOutcome(input: {
|
|
97
|
+
task: Pick<TaskEnvelope, 'taskId' | 'actionDecision'>;
|
|
98
|
+
receipt: Pick<TaskReceipt, 'status' | 'actionAcknowledgement'>;
|
|
99
|
+
payload: Record<string, unknown>;
|
|
100
|
+
postEnforcement: (decisionId: string, acknowledgement: NonNullable<TaskReceipt['actionAcknowledgement']>) => Promise<unknown>;
|
|
101
|
+
postEvent: (taskId: string, eventType: TaskReceipt['status'], payload: Record<string, unknown>) => Promise<unknown>;
|
|
102
|
+
}): Promise<unknown>;
|
|
89
103
|
export declare function nativeSkillDirectory(provider: ProviderId, env?: NodeJS.ProcessEnv, home?: string): string;
|
|
90
104
|
export declare function installNativeAgentFabricBootstrap(input: {
|
|
91
105
|
provider: ProviderId;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7,16 +7,16 @@ import { homedir } from 'node:os';
|
|
|
7
7
|
import { basename, dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { promisify } from 'node:util';
|
|
10
|
-
import { canonicalize, sha256, validateContract, verifyCanonicalObject } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
10
|
+
import { canonicalize, createActionDecisionPublicKeyResolver, sha256, validateContract, validateTrustedServerSigningKeysetContract, verifyCanonicalObject, verifyInitialServerSigningKeyset, } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
11
11
|
import { buildTrajectoryCapsule, redactValue, referencesExcludedPath, trajectoryCapsuleHash } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
|
|
12
12
|
import { assertPolicy, loadOrganizationPolicy, verifyServerAuthorizedPolicy } from '@dharma-ai-labs/agent-fabric-policy';
|
|
13
13
|
import { agyAdapter, claudeAdapter, codexAdapter, providerAdapters } from '@dharma-ai-labs/agent-fabric-provider-adapters';
|
|
14
|
-
import { AgentFabricClient, beginEnrollment, loadOrCreateDeviceIdentity, normalizeHqUrl, pollEnrollment, deleteActiveSkillAuthorizationAnchor, loadActiveSkillAuthorizationAnchor, loadDeviceEnrollmentAnchor, saveActiveSkillAuthorizationAnchor, isDefinitiveAgentFabricRejection, saveDeviceConfig, saveDeviceEnrollmentAnchor, } from '@dharma-ai-labs/agent-fabric-relay-client';
|
|
14
|
+
import { AgentFabricClient, beginEnrollment, loadOrCreateDeviceIdentity, normalizeHqUrl, pollEnrollment, deleteActiveSkillAuthorizationAnchor, loadActiveSkillAuthorizationAnchor, loadDeviceEnrollmentAnchor, saveActiveSkillAuthorizationAnchor, isDefinitiveAgentFabricRejection, recoverDeviceEnrollmentConsistency, saveDeviceConfig, saveDeviceEnrollmentAnchor, } from '@dharma-ai-labs/agent-fabric-relay-client';
|
|
15
15
|
import { AgentFabricClient as AgentFabricApiClient } from '@dharma-ai-labs/agent-fabric-sdk';
|
|
16
16
|
import { getActiveSkillBundleAuthorization, getExpiredSkillBundleAuthorizationForReplacement, getLegacySkillBundleIdForUpgrade, installSkillBundle, rollbackUnconfirmedSkillBundle, verifySkillBundle } from '@dharma-ai-labs/agent-fabric-skill-manager';
|
|
17
|
-
import { executeTask, FileTaskReceiptStore, providerInstructionsForTask, } from '@dharma-ai-labs/agent-fabric-task-runner';
|
|
17
|
+
import { executeTask, FileActionExecutionJournal, FileTaskReceiptStore, providerInstructionsForTask, } from '@dharma-ai-labs/agent-fabric-task-runner';
|
|
18
18
|
import { CLI_USAGE } from './usage.js';
|
|
19
|
-
const VERSION = '0.2.
|
|
19
|
+
const VERSION = '0.2.5';
|
|
20
20
|
const USAGE = CLI_USAGE;
|
|
21
21
|
const execFileAsync = promisify(execFile);
|
|
22
22
|
export function parseCliOptions(args) {
|
|
@@ -1268,6 +1268,13 @@ async function login(flags) {
|
|
|
1268
1268
|
deviceName: pending.name, platform: pending.platform, publicKeyEd25519: pending.publicKeyEd25519,
|
|
1269
1269
|
serverPublicKeyEd25519: result.serverPublicKeyEd25519, relayUrl: result.relayUrl, enrolledAt: new Date().toISOString(),
|
|
1270
1270
|
};
|
|
1271
|
+
if (result.serverSigningKeyset) {
|
|
1272
|
+
const candidate = result.serverSigningKeyset;
|
|
1273
|
+
const verification = verifyInitialServerSigningKeyset(candidate, createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: result.serverPublicKeyEd25519 }, format: 'jwk' }), pending.organizationId);
|
|
1274
|
+
if (!verification.ok)
|
|
1275
|
+
throw new Error(`Enrollment signing keyset was rejected: ${verification.reason}.`);
|
|
1276
|
+
config.serverSigningKeyset = candidate;
|
|
1277
|
+
}
|
|
1271
1278
|
await saveDeviceConfig(configPath(), config);
|
|
1272
1279
|
await saveDeviceEnrollmentAnchor({ config });
|
|
1273
1280
|
await rm(pendingEnrollmentPath(), { force: true });
|
|
@@ -1665,11 +1672,68 @@ export function parseSelectedProviderIds(values) {
|
|
|
1665
1672
|
}
|
|
1666
1673
|
return selected;
|
|
1667
1674
|
}
|
|
1675
|
+
export function actionDecisionCapabilityFreshUntil(keyset, trustedKeyVersions, now = new Date()) {
|
|
1676
|
+
const trustedExpiries = keyset.keys
|
|
1677
|
+
.filter((key) => trustedKeyVersions.includes(key.keyVersion))
|
|
1678
|
+
.map((key) => Date.parse(key.notAfter));
|
|
1679
|
+
const earliestExpiry = Math.min(Date.parse(keyset.expiresAt), ...trustedExpiries);
|
|
1680
|
+
if (!Number.isFinite(earliestExpiry) || earliestExpiry <= now.getTime()) {
|
|
1681
|
+
throw new Error('trusted_server_signing_keys_invalid_or_expired');
|
|
1682
|
+
}
|
|
1683
|
+
return new Date(Math.min(now.getTime() + 5 * 60_000, earliestExpiry)).toISOString();
|
|
1684
|
+
}
|
|
1668
1685
|
function selectedProviderAdapters(providerIds) {
|
|
1669
1686
|
return providerIds
|
|
1670
1687
|
? providerAdapters.filter((adapter) => providerIds.includes(adapter.providerId))
|
|
1671
1688
|
: providerAdapters;
|
|
1672
1689
|
}
|
|
1690
|
+
export async function receiptAwareProviderCapabilities(providers, now = new Date()) {
|
|
1691
|
+
const selfTestedAt = now.toISOString();
|
|
1692
|
+
let freshUntil = now.toISOString();
|
|
1693
|
+
let receiverState = 'unavailable';
|
|
1694
|
+
let reason = 'device_not_enrolled';
|
|
1695
|
+
let trustedKeyVersions = [];
|
|
1696
|
+
try {
|
|
1697
|
+
const config = await recoverDeviceEnrollmentConsistency({ configPath: configPath(), now });
|
|
1698
|
+
await loadDeviceEnrollmentAnchor({ config });
|
|
1699
|
+
const keyset = config.serverSigningKeyset;
|
|
1700
|
+
if (!keyset)
|
|
1701
|
+
throw new Error('trusted_server_signing_keyset_unavailable');
|
|
1702
|
+
if (!validateTrustedServerSigningKeysetContract(keyset).ok
|
|
1703
|
+
|| Date.parse(keyset.expiresAt) <= now.getTime()) {
|
|
1704
|
+
throw new Error('trusted_server_signing_keyset_invalid_or_expired');
|
|
1705
|
+
}
|
|
1706
|
+
const resolver = createActionDecisionPublicKeyResolver(keyset, now);
|
|
1707
|
+
trustedKeyVersions = keyset.keys
|
|
1708
|
+
.filter((key) => resolver(key.keyVersion) !== null)
|
|
1709
|
+
.map((key) => key.keyVersion);
|
|
1710
|
+
if (trustedKeyVersions.length === 0)
|
|
1711
|
+
throw new Error('trusted_server_signing_keys_unavailable');
|
|
1712
|
+
freshUntil = actionDecisionCapabilityFreshUntil(keyset, trustedKeyVersions, now);
|
|
1713
|
+
await new FileActionExecutionJournal(resolve(dharmaHome(), 'relay', 'action-execution-journal')).selfTest();
|
|
1714
|
+
receiverState = 'available';
|
|
1715
|
+
reason = '';
|
|
1716
|
+
}
|
|
1717
|
+
catch (error) {
|
|
1718
|
+
reason = error instanceof Error ? error.message : String(error);
|
|
1719
|
+
}
|
|
1720
|
+
return providers.map((provider) => {
|
|
1721
|
+
const available = provider.taskExecution === 'available' && receiverState === 'available';
|
|
1722
|
+
return {
|
|
1723
|
+
...provider,
|
|
1724
|
+
actionDecisionReceipts: available ? 'available' : 'unavailable',
|
|
1725
|
+
actionDecisionReceiver: {
|
|
1726
|
+
protocol: 'action_decision_receipts_v1',
|
|
1727
|
+
protocolVersion: 1,
|
|
1728
|
+
journalSchema: 'dharma.action-execution-journal/v1',
|
|
1729
|
+
state: available ? 'available' : 'unavailable',
|
|
1730
|
+
selfTestedAt, freshUntil,
|
|
1731
|
+
trustedKeyVersions: available ? trustedKeyVersions : [],
|
|
1732
|
+
...(!available ? { reason: provider.taskExecution !== 'available' ? 'provider_task_execution_unavailable' : reason } : {}),
|
|
1733
|
+
},
|
|
1734
|
+
};
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1673
1737
|
async function repositoriesList(flags) {
|
|
1674
1738
|
const verbose = flags.has('verbose') || flags.has('diagnostic');
|
|
1675
1739
|
return {
|
|
@@ -1743,7 +1807,7 @@ async function workspaceSync(flags, positional) {
|
|
|
1743
1807
|
return syncWorkspacePolicy(fabric, await bindRepositoryAgent(fabric, item), policyRevision, true, providerIds);
|
|
1744
1808
|
}
|
|
1745
1809
|
async function syncWorkspacePolicy(fabric, item, policyRevision, apply = true, providerIds = null) {
|
|
1746
|
-
const providers = await Promise.all(selectedProviderAdapters(providerIds).map((adapter) => adapter.capability()));
|
|
1810
|
+
const providers = await receiptAwareProviderCapabilities(await Promise.all(selectedProviderAdapters(providerIds).map((adapter) => adapter.capability())));
|
|
1747
1811
|
const response = await fabric.registerWorkspace({
|
|
1748
1812
|
workspaceId: item.workspaceId, name: item.name, routeHash: item.routeHash,
|
|
1749
1813
|
repositoryRemoteHash: item.repositoryRemoteHash, defaultBranch: item.defaultBranch,
|
|
@@ -2018,7 +2082,7 @@ async function onboard(flags) {
|
|
|
2018
2082
|
controlBranch: registered.controlBranch,
|
|
2019
2083
|
policyRevision: authoritativeRevision,
|
|
2020
2084
|
});
|
|
2021
|
-
const providers = await Promise.all(selectedProviderAdapters(providerIds).map((adapter) => adapter.capability()));
|
|
2085
|
+
const providers = await receiptAwareProviderCapabilities(await Promise.all(selectedProviderAdapters(providerIds).map((adapter) => adapter.capability())));
|
|
2022
2086
|
const nativeSkillResult = await installAvailableNativeAgentFabricBootstraps({
|
|
2023
2087
|
providers,
|
|
2024
2088
|
workspace,
|
|
@@ -2415,6 +2479,23 @@ export function assertTaskWorkspacePolicy(input) {
|
|
|
2415
2479
|
throw new Error('Task workspace policy does not match the signed task and local registration.');
|
|
2416
2480
|
}
|
|
2417
2481
|
}
|
|
2482
|
+
export async function acknowledgeTaskActionDecision(input) {
|
|
2483
|
+
const acknowledgement = input.receipt.actionAcknowledgement;
|
|
2484
|
+
if (!acknowledgement)
|
|
2485
|
+
return false;
|
|
2486
|
+
const decisionId = input.task.actionDecision?.id;
|
|
2487
|
+
if (!decisionId)
|
|
2488
|
+
throw new Error('Task produced an action acknowledgement without an embedded decision.');
|
|
2489
|
+
if (acknowledgement.taskId !== input.task.taskId) {
|
|
2490
|
+
throw new Error('Task action acknowledgement does not match the executed task.');
|
|
2491
|
+
}
|
|
2492
|
+
await input.postEnforcement(decisionId, acknowledgement);
|
|
2493
|
+
return true;
|
|
2494
|
+
}
|
|
2495
|
+
export async function postTaskOutcome(input) {
|
|
2496
|
+
await acknowledgeTaskActionDecision(input);
|
|
2497
|
+
return input.postEvent(input.task.taskId, input.receipt.status, input.payload);
|
|
2498
|
+
}
|
|
2418
2499
|
async function stageSignedTaskTrajectoryRecovery(taskId, workspaceId, policy, prepared) {
|
|
2419
2500
|
const { LocalVault, loadOrCreateVaultMasterKey } = await loadVaultModule();
|
|
2420
2501
|
const vault = await LocalVault.open({
|
|
@@ -2617,6 +2698,13 @@ async function executeOneTask(fabric, leaseSeconds) {
|
|
|
2617
2698
|
receipt = await executeTask({
|
|
2618
2699
|
task, policy: taskPolicy, workspace: workspace.path, relayStateDirectory: resolve(dharmaHome(), 'relay'), serverPublicKey,
|
|
2619
2700
|
receiptStore: new FileTaskReceiptStore(resolve(dharmaHome(), 'relay', 'receipts')),
|
|
2701
|
+
...(task.actionDecision ? {
|
|
2702
|
+
actionDecisions: {
|
|
2703
|
+
resolvePublicKey: config.serverSigningKeyset
|
|
2704
|
+
? createActionDecisionPublicKeyResolver(config.serverSigningKeyset)
|
|
2705
|
+
: () => null,
|
|
2706
|
+
},
|
|
2707
|
+
} : {}),
|
|
2620
2708
|
});
|
|
2621
2709
|
}
|
|
2622
2710
|
finally {
|
|
@@ -2642,9 +2730,15 @@ async function executeOneTask(fabric, leaseSeconds) {
|
|
|
2642
2730
|
: null;
|
|
2643
2731
|
if (prepared)
|
|
2644
2732
|
await stageSignedTaskTrajectoryRecovery(task.taskId, workspace.workspaceId, taskPolicy, prepared);
|
|
2645
|
-
await
|
|
2646
|
-
|
|
2647
|
-
|
|
2733
|
+
await postTaskOutcome({
|
|
2734
|
+
task,
|
|
2735
|
+
receipt,
|
|
2736
|
+
payload: {
|
|
2737
|
+
...summary,
|
|
2738
|
+
...(prepared ? { trajectoryCapsuleHash: prepared.capsule.capsuleHash } : {}),
|
|
2739
|
+
},
|
|
2740
|
+
postEnforcement: (decisionId, acknowledgement) => fabric.postActionEnforcement(decisionId, acknowledgement),
|
|
2741
|
+
postEvent: (taskId, eventType, payload) => fabric.postTaskEvent(taskId, eventType, payload),
|
|
2648
2742
|
});
|
|
2649
2743
|
let trajectory = null;
|
|
2650
2744
|
if (receipt.status === 'completed' && task.skillBundle) {
|
|
@@ -3126,7 +3220,9 @@ export async function run(argv) {
|
|
|
3126
3220
|
if (command === 'login')
|
|
3127
3221
|
return login(flags);
|
|
3128
3222
|
if (command === 'providers' && subcommand === 'list')
|
|
3129
|
-
return {
|
|
3223
|
+
return {
|
|
3224
|
+
providers: await receiptAwareProviderCapabilities(await Promise.all(providerAdapters.map((adapter) => adapter.capability()))),
|
|
3225
|
+
};
|
|
3130
3226
|
if (command === 'repositories' && subcommand === 'discover') {
|
|
3131
3227
|
return repositoriesDiscover(flags, positional.slice(2), repeated.get('root') || []);
|
|
3132
3228
|
}
|
|
@@ -3140,7 +3236,7 @@ export async function run(argv) {
|
|
|
3140
3236
|
return {
|
|
3141
3237
|
...listed,
|
|
3142
3238
|
relay: await relayProcessState(),
|
|
3143
|
-
providers: await Promise.all(providerAdapters.map((adapter) => adapter.capability())),
|
|
3239
|
+
providers: await receiptAwareProviderCapabilities(await Promise.all(providerAdapters.map((adapter) => adapter.capability()))),
|
|
3144
3240
|
};
|
|
3145
3241
|
}
|
|
3146
3242
|
if (command === 'workspace' && subcommand === 'add')
|