@dharma-ai-labs/agent-fabric 0.2.45 → 0.2.47

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.
@@ -7,7 +7,7 @@ import { join } from 'node:path';
7
7
  import test from 'node:test';
8
8
  import { fileURLToPath, pathToFileURL } from 'node:url';
9
9
  import { promisify } from 'node:util';
10
- import { acceptedTrajectoryHead, activateAgyPlugin, attestAgySkillActivation, attestHermesSkillBundleActivation, actionDecisionCapabilityFreshUntil, canonicalFilesystemPath, controlAgentDecisionUrl, installAvailableNativeAgentFabricBootstraps, assertCapsuleAuthorizedByCurrentPolicy, assertRecoveredTaskWorkspacePolicy, assertTaskWorkspacePolicy, assertTaskSkillPin, installNativeAgentFabricBootstrap, installClaudeReadOnlyProjectPermissions, installRepositoryAgentFabricSkill, isDirectExecution, isTransientBootstrapError, materializeWorkspacePolicy, applyServerEvidencePolicy, materializeInlineSkillFiles, nativeSkillDirectory, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, requireCompletedBootstrapEvidence, retryBootstrapOnboarding, synchronizeBootstrapEvidence, recoverLegacySkillBundleIdAfterAuthorizationFailure, installedBundleIdForSkillPollAfterAuthorizationFailure, recoveredTaskPolicyWasSuperseded, relayProcessState, releaseDailyContentUpload, reserveDailyContentUpload, run, runAssistantCommand, sourceRepositoryFingerprint, stableRepositoryLauncherContents, summarizeBootstrapOrganizationApi, ensureAgyReadOnlyAttestationPermission, attestAgySkillBundleActivation, responseTextFromEvent, taskResponsePreview, taskReceiptSession, taskSkillPinFailureCode, verifyAgentFabricSkillInstallation, waitForRelayReadiness, withWorkspacePolicyRefreshLock, withWorkspaceSkillActivationLock, } from './index.js';
10
+ import { acceptedTrajectoryHead, activateAgyPlugin, attestAgySkillActivation, attestHermesSkillBundleActivation, actionDecisionCapabilityFreshUntil, canonicalFilesystemPath, controlAgentDecisionUrl, installAvailableNativeAgentFabricBootstraps, assertCapsuleAuthorizedByCurrentPolicy, assertRecoveredTaskWorkspacePolicy, assertTaskWorkspacePolicy, assertTaskSkillPin, installNativeAgentFabricBootstrap, installClaudeReadOnlyProjectPermissions, installRepositoryAgentFabricSkill, isDirectExecution, isTransientBootstrapError, materializeWorkspacePolicy, applyServerEvidencePolicy, materializeInlineSkillFiles, nativeSkillDirectory, normalizeGitRemoteIdentity, postTaskOutcome, parseCliOptions, parseSelectedProviderIds, pathExistsOrThrow, portalUrl, providerHintFromEnvironment, providerHintFromProcessArgv, probeRelayConnection, preflightBootstrapWorkspaceIdentity, rawLocalRetentionDays, requireCompletedBootstrapEvidence, retryBootstrapOnboarding, synchronizeBootstrapEvidence, recoverLegacySkillBundleIdAfterAuthorizationFailure, installedBundleIdForSkillPollAfterAuthorizationFailure, recoveredTaskPolicyWasSuperseded, relayProcessState, releaseDailyContentUpload, reserveDailyContentUpload, run, runAssistantCommand, sourceRepositoryFingerprint, stableRepositoryLauncherContents, summarizeBootstrapOrganizationApi, ensureAgyReadOnlyAttestationPermission, attestAgySkillBundleActivation, responseTextFromEvent, taskResponsePreview, taskReceiptSession, taskSkillPinFailureCode, verifyAgentFabricSkillInstallation, waitForRelayReadiness, withWorkspacePolicyRefreshLock, withWorkspaceSkillActivationLock, } from './index.js';
11
11
  import { canonicalize, signCanonicalObject } from '@dharma-ai-labs/agent-fabric-contracts';
12
12
  import { buildTrajectoryCapsule } from '@dharma-ai-labs/agent-fabric-evidence-reduction';
13
13
  import { CLI_USAGE } from './usage.js';
@@ -164,6 +164,15 @@ test('bootstrap provider detection uses host signals without changing the portal
164
164
  assert.equal(providerHintFromEnvironment({ AGY_CONFIG_DIR: '/tmp/agy' }), 'agy');
165
165
  assert.equal(providerHintFromEnvironment({ HERMES_HOME: '/tmp/hermes' }), 'hermes');
166
166
  assert.equal(providerHintFromEnvironment({}), null);
167
+ assert.equal(providerHintFromProcessArgv([
168
+ ['/usr/bin/npm', 'exec'],
169
+ ['/bin/bash', '-lc', 'npm exec -- dharma bootstrap'],
170
+ ['/home/developer/.local/bin/agy', '--dangerously-skip-permissions'],
171
+ ]), 'agy');
172
+ assert.equal(providerHintFromProcessArgv([
173
+ ['/usr/bin/node', '/tmp/agy-helper.js'],
174
+ ['/bin/bash', '-lc', 'cat /tmp/hermes-notes'],
175
+ ]), null);
167
176
  });
168
177
  test('repository launchers stay version-pinned without depending on the npm-exec cache path', () => {
169
178
  const launcher = stableRepositoryLauncherContents('0.2.40');
@@ -589,6 +598,96 @@ test('organization commands require environment credentials and explicit confirm
589
598
  process.env.DHARMA_ORG_API_TOKEN = originalToken;
590
599
  }
591
600
  });
601
+ test('evaluation CLI validates cost before launch and reads authoritative status and results', async () => {
602
+ const root = await mkdtemp(join(tmpdir(), 'dharma-evaluation-cli-'));
603
+ const packagePath = join(root, 'task-package.json');
604
+ await writeFile(packagePath, JSON.stringify({
605
+ package_id: 'checkout-handoff-v1',
606
+ schema_version: 'managed-evaluation-task-package-v1',
607
+ description: 'Checkout handoff evidence boundary.',
608
+ evaluation_contract: {
609
+ version: 'managed-evaluation-contract-v1',
610
+ standard: {
611
+ profile: 'cognitive-integrity-v1',
612
+ hardGates: ['task_score_threshold', 'blocked_action_avoidance'],
613
+ },
614
+ operationalCriteria: { requiredTraceFields: ['runId', 'traceId'] },
615
+ comparison: {
616
+ mode: 'paired_direct_stateful',
617
+ primaryArm: 'stateful_dharma_runtime',
618
+ baselineArm: 'direct_baseline',
619
+ },
620
+ releaseDecision: { expression: 'primary_arm_all_standard_gates_and_threshold' },
621
+ },
622
+ tasks: [{
623
+ task_id: 'checkout-001',
624
+ scenario: { user_message: 'Resolve the checkout failure using only supplied evidence.' },
625
+ }],
626
+ }));
627
+ const originalFetch = globalThis.fetch;
628
+ const originalToken = process.env.DHARMA_ORG_API_TOKEN;
629
+ const requests = [];
630
+ process.env.DHARMA_ORG_API_TOKEN = 'test-organization-token';
631
+ globalThis.fetch = (async (input, init) => {
632
+ const request = new Request(input, init);
633
+ requests.push(request);
634
+ const path = new URL(request.url).pathname;
635
+ const payload = path.endsWith('/preflight')
636
+ ? { ok: true, preflight: { taskCount: 1, trajectoryCount: 2, maximumCredits: 10_000 } }
637
+ : request.method === 'POST'
638
+ ? { ok: true, campaign: { id: 'campaign-1', status: 'running' } }
639
+ : {
640
+ ok: true,
641
+ campaigns: [{ id: 'campaign-1', status: 'completed' }],
642
+ sessions: [{ id: 'session-1', status: 'completed' }],
643
+ tasks: [{ id: 'task-1', scorer_config: { evaluation_contract: { version: 'managed-evaluation-contract-v1' } } }],
644
+ results: [{ id: 'result-1', metadata: { verdict: { pass: true } } }],
645
+ };
646
+ return new Response(JSON.stringify(payload), {
647
+ status: request.method === 'POST' ? 201 : 200,
648
+ headers: { 'content-type': 'application/json' },
649
+ });
650
+ });
651
+ const base = [
652
+ '--file', packagePath,
653
+ '--organization-id', 'org_northstar',
654
+ '--hq-url', 'https://www.dharma-ai.io',
655
+ '--agent-id', '11111111-1111-4111-8111-111111111111',
656
+ ];
657
+ try {
658
+ const validated = await run(['evaluations', 'validate', ...base]);
659
+ assert.equal(validated.ok, true);
660
+ assert.equal(validated.preflight.trajectoryCount, 2);
661
+ const requestsBeforeUnconfirmedLaunch = requests.length;
662
+ await assert.rejects(() => run(['evaluations', 'launch', ...base]), /requires --confirm/);
663
+ assert.equal(requests.length, requestsBeforeUnconfirmedLaunch + 1, 'unconfirmed launch may preflight but must not launch');
664
+ const launched = await run(['evaluations', 'launch', ...base, '--confirm']);
665
+ assert.equal(launched.ok, true);
666
+ assert.equal(requests.at(-1)?.method, 'POST');
667
+ assert.match(new URL(requests.at(-1).url).pathname, /managed-evals\/campaigns$/);
668
+ const launchedBody = JSON.parse(await requests.at(-1).text());
669
+ assert.deepEqual(launchedBody.arms, ['direct_baseline', 'stateful_dharma_runtime']);
670
+ assert.equal(launchedBody.agentId, '11111111-1111-4111-8111-111111111111');
671
+ const status = await run([
672
+ 'evaluations', 'status', '--campaign-id', 'campaign-1', '--organization-id', 'org_northstar',
673
+ '--hq-url', 'https://www.dharma-ai.io',
674
+ ]);
675
+ assert.equal(status.campaigns.length, 1);
676
+ assert.equal(Object.hasOwn(status, 'results'), false);
677
+ const results = await run([
678
+ 'evaluations', 'results', '--campaign-id', 'campaign-1', '--organization-id', 'org_northstar',
679
+ '--hq-url', 'https://www.dharma-ai.io',
680
+ ]);
681
+ assert.equal(results.results.length, 1);
682
+ }
683
+ finally {
684
+ globalThis.fetch = originalFetch;
685
+ if (originalToken === undefined)
686
+ delete process.env.DHARMA_ORG_API_TOKEN;
687
+ else
688
+ process.env.DHARMA_ORG_API_TOKEN = originalToken;
689
+ }
690
+ });
592
691
  test('repository identity is credential-free and stable across Git transport forms', () => {
593
692
  assert.equal(normalizeGitRemoteIdentity('git@github.com:Dharma-AI-Labs/Northstar.git'), 'github.com/dharma-ai-labs/northstar');
594
693
  assert.equal(normalizeGitRemoteIdentity('https://oauth-token@github.com/dharma-ai-labs/northstar.git?ignored=1'), 'github.com/dharma-ai-labs/northstar');
@@ -1396,13 +1495,13 @@ test('relay probe opens an authenticated session without polling or leasing work
1396
1495
  },
1397
1496
  openSession: async (version) => {
1398
1497
  sessions += 1;
1399
- assert.equal(version, '0.2.45');
1498
+ assert.equal(version, '0.2.47');
1400
1499
  return { ok: true };
1401
1500
  },
1402
1501
  }));
1403
1502
  assert.equal(sessions, 1);
1404
1503
  assert.deepEqual(result, {
1405
- ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.45',
1504
+ ok: true, connected: true, organizationId: 'org_test', deviceId: 'device_test', relayVersion: '0.2.47',
1406
1505
  });
1407
1506
  });
1408
1507
  test('relay probe fails closed when the server does not acknowledge the session', async () => {