maka-agent 0.2.0-dev.3.20260830 → 0.2.0-dev.5.20260830
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/cli-core.js +1 -0
- package/dist/eval-bundle-path.js +1 -1
- package/dist/pi-tui-runner.js +3 -1
- package/dist/runtime-host-cli.js +37 -3
- package/dist/runtime-host-onboarding.js +10 -1
- package/dist/runtime-host-peer-mesh-management-command.js +17 -0
- package/dist/runtime-host-setup-command.js +33 -15
- package/dist/runtime-host-systemd-service.js +9 -3
- package/dist/runtime-host-tui-context.js +2 -6
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/node_modules/@maka/eval/dist/external-subject.js +1 -1
- package/node_modules/@maka/eval/dist/harbor-external-subject.js +2 -2
- package/node_modules/@maka/runtime/dist/sandbox/macos-seatbelt.js +68 -9
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +22 -3
- package/node_modules/@maka/runtime-host/dist/operator/peer-mesh-management-frame.js +14 -0
- package/{packages/eval/dist/index.js → node_modules/@maka/runtime-host/dist/peer-mesh/display-name.js} +12 -10
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +32 -21
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +207 -47
- package/node_modules/@maka/runtime-host/dist/peer-mesh/owner.js +2 -0
- package/node_modules/@maka/runtime-host/dist/peer-mesh/store.js +18 -5
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
- package/node_modules/@maka/runtime-host/dist/protocol/peer-mesh.js +59 -2
- package/node_modules/@maka/runtime-host/dist/server/access-authority.js +11 -7
- package/node_modules/@maka/runtime-host/dist/server/connection-session.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-service.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/peer-mesh-authority.js +19 -0
- package/package.json +1 -2
- package/packages/eval/dist/attempt-store.js +0 -138
- package/packages/eval/dist/cli.js +0 -119
- package/packages/eval/dist/experiment-directory.js +0 -59
- package/packages/eval/dist/experiment.js +0 -49
- package/packages/eval/dist/external-subject.js +0 -488
- package/packages/eval/dist/harbor-external-subject.js +0 -929
- package/packages/eval/dist/harbor-maka-subject.js +0 -83
- package/packages/eval/dist/harness-environment.js +0 -80
- package/packages/eval/dist/harness-executor.js +0 -1013
- package/packages/eval/dist/install-preflight.js +0 -201
- package/packages/eval/dist/maka-artifacts.js +0 -126
- package/packages/eval/dist/maka-runtime-policy.js +0 -42
- package/packages/eval/dist/maka-subject.js +0 -268
- package/packages/eval/dist/metering-checkpoint.js +0 -80
- package/packages/eval/dist/provider-admission.js +0 -39
- package/packages/eval/dist/provider-metering.js +0 -67
- package/packages/eval/dist/provider-web-tool-surface.js +0 -74
- package/packages/eval/dist/relay-result-frame.js +0 -38
- package/packages/eval/dist/result.js +0 -94
- package/packages/eval/dist/runner.js +0 -290
- package/packages/eval/dist/spec.js +0 -135
- package/packages/eval/dist/toolchain-verification.js +0 -130
- package/packages/eval/harbor/deepseek-codex-models.json +0 -69
- package/packages/eval/harbor/deepseek-harness-profile/cordis.patch.yml +0 -140
- package/packages/eval/harbor/deepseek-harness-profile/cordis.yml +0 -18
- package/packages/eval/harbor/deepseek-harness-profile/package.json +0 -10
- package/packages/eval/harbor/docker-compose-egress-proxy.yaml +0 -57
- package/packages/eval/harbor/egress-proxy/Dockerfile +0 -25
- package/packages/eval/harbor/egress-proxy/entrypoint.sh +0 -62
- package/packages/eval/harbor/egress-proxy/network-policy +0 -148
- package/packages/eval/harbor/egress_filter.py +0 -435
- package/packages/eval/harbor/eval_framework.py +0 -40
- package/packages/eval/harbor/relay_agent.py +0 -686
- package/packages/eval/harbor/run_trial.py +0 -223
- package/packages/eval/package.json +0 -20
package/dist/cli-core.js
CHANGED
|
@@ -435,6 +435,7 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
435
435
|
expectedTarget: command.expectedTarget,
|
|
436
436
|
...(command.meshId !== undefined ? { meshId: command.meshId } : {}),
|
|
437
437
|
...(command.peerId ? { peerId: command.peerId } : {}),
|
|
438
|
+
...(command.displayName !== undefined ? { displayName: command.displayName } : {}),
|
|
438
439
|
});
|
|
439
440
|
}
|
|
440
441
|
case 'runtime-host-service-update': {
|
package/dist/eval-bundle-path.js
CHANGED
|
@@ -23,7 +23,7 @@ export function configureInstalledEvalBundle(environment = process.env, packageR
|
|
|
23
23
|
if (Object.hasOwn(environment, MAKA_EVAL_BUNDLE_ENV))
|
|
24
24
|
return;
|
|
25
25
|
try {
|
|
26
|
-
if (!statSync(resolve(packageRoot, '
|
|
26
|
+
if (!statSync(resolve(packageRoot, 'node_modules/@maka/eval')).isDirectory())
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
catch {
|
package/dist/pi-tui-runner.js
CHANGED
|
@@ -870,6 +870,7 @@ export async function runMakaPiTui(input) {
|
|
|
870
870
|
// in place after `/setup` saves so newly configured models are immediately
|
|
871
871
|
// available — the single source the picker and connection/model lookups read.
|
|
872
872
|
let modelChoices = input.modelChoices;
|
|
873
|
+
let connectionIdentities = input.connectionIdentities;
|
|
873
874
|
// Monotonic attempt id: each setup submit captures one, and any transition
|
|
874
875
|
// that abandons the in-flight attempt (back, re-pick, close) increments it so
|
|
875
876
|
// a late verify/save settlement cannot clobber a newer attempt.
|
|
@@ -1142,7 +1143,7 @@ export async function runMakaPiTui(input) {
|
|
|
1142
1143
|
model = summary.model;
|
|
1143
1144
|
connectionId = summary.llmConnectionId;
|
|
1144
1145
|
connectionSlug = summary.llmConnectionSlug;
|
|
1145
|
-
const identityNotice = sessionConnectionIdentityNotice(summary,
|
|
1146
|
+
const identityNotice = sessionConnectionIdentityNotice(summary, connectionIdentities, input.locale ?? 'en');
|
|
1146
1147
|
if (announceIdentity && identityNotice && identityNotice !== connectionIdentityNotice) {
|
|
1147
1148
|
state.entries.push({ kind: 'notice', level: 'error', text: identityNotice });
|
|
1148
1149
|
}
|
|
@@ -1832,6 +1833,7 @@ export async function runMakaPiTui(input) {
|
|
|
1832
1833
|
// attempt must not overwrite choices refreshed by a newer save.
|
|
1833
1834
|
if (result.refresh.kind === 'ok') {
|
|
1834
1835
|
modelChoices = result.refresh.modelChoices;
|
|
1836
|
+
connectionIdentities = result.refresh.connectionIdentities;
|
|
1835
1837
|
}
|
|
1836
1838
|
if (input.firstRun) {
|
|
1837
1839
|
beginClose();
|
package/dist/runtime-host-cli.js
CHANGED
|
@@ -752,17 +752,28 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
752
752
|
action !== 'leave' &&
|
|
753
753
|
action !== 'close' &&
|
|
754
754
|
action !== 'reconcile' &&
|
|
755
|
-
action !== 'transit'
|
|
755
|
+
action !== 'transit' &&
|
|
756
|
+
action !== 'rename' &&
|
|
757
|
+
action !== 'rename-mesh') {
|
|
756
758
|
return error(action
|
|
757
759
|
? `Unexpected runtime-host service mesh command: ${action}`
|
|
758
|
-
: 'runtime-host service mesh requires status, create, invite, join, remove, leave, close, reconcile, or
|
|
760
|
+
: 'runtime-host service mesh requires status, create, invite, join, remove, leave, close, reconcile, transit, rename, or rename-mesh');
|
|
759
761
|
}
|
|
760
762
|
let meshId;
|
|
761
763
|
let peerId;
|
|
764
|
+
let displayName;
|
|
765
|
+
let clientDataRoot;
|
|
762
766
|
const options = parseManagedServiceOptions(argv.slice(1), {
|
|
763
767
|
allowConfiguration: false,
|
|
764
768
|
allowFramed: true,
|
|
765
769
|
valueOptions: {
|
|
770
|
+
'--client-data-root': (value) => {
|
|
771
|
+
if (clientDataRoot !== undefined)
|
|
772
|
+
return error('Duplicate --client-data-root');
|
|
773
|
+
if (!isSafeAbsolutePath(value))
|
|
774
|
+
return error('--client-data-root must be an absolute path');
|
|
775
|
+
clientDataRoot = value;
|
|
776
|
+
},
|
|
766
777
|
'--mesh': (value) => {
|
|
767
778
|
if (meshId !== undefined)
|
|
768
779
|
return error('Duplicate --mesh');
|
|
@@ -777,6 +788,14 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
777
788
|
return error('--peer requires a valid Peer ID');
|
|
778
789
|
peerId = value;
|
|
779
790
|
},
|
|
791
|
+
'--name': (value) => {
|
|
792
|
+
if (displayName !== undefined)
|
|
793
|
+
return error('Duplicate --name');
|
|
794
|
+
if (!value.trim() || value.trim().length > 80) {
|
|
795
|
+
return error('--name requires a display name of at most 80 characters');
|
|
796
|
+
}
|
|
797
|
+
displayName = value.trim();
|
|
798
|
+
},
|
|
780
799
|
},
|
|
781
800
|
flagOptions: {
|
|
782
801
|
'--off': () => {
|
|
@@ -784,6 +803,11 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
784
803
|
return error('mesh transit accepts either --mesh or --off');
|
|
785
804
|
meshId = null;
|
|
786
805
|
},
|
|
806
|
+
'--clear-name': () => {
|
|
807
|
+
if (displayName !== undefined)
|
|
808
|
+
return error('mesh rename accepts --name or --clear-name');
|
|
809
|
+
displayName = null;
|
|
810
|
+
},
|
|
787
811
|
},
|
|
788
812
|
});
|
|
789
813
|
if ('kind' in options)
|
|
@@ -791,7 +815,11 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
791
815
|
if (!options.managedRootId || !options.operatorDeploymentId || !options.expectedTarget) {
|
|
792
816
|
return error('runtime-host service mesh requires --managed-root-id, --operator-deployment-id, and an expected target');
|
|
793
817
|
}
|
|
794
|
-
const needsMesh = action === 'invite' ||
|
|
818
|
+
const needsMesh = action === 'invite' ||
|
|
819
|
+
action === 'remove' ||
|
|
820
|
+
action === 'leave' ||
|
|
821
|
+
action === 'close' ||
|
|
822
|
+
action === 'rename-mesh';
|
|
795
823
|
if (needsMesh && typeof meshId !== 'string') {
|
|
796
824
|
return error(`runtime-host service mesh ${action} requires --mesh`);
|
|
797
825
|
}
|
|
@@ -809,6 +837,11 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
809
837
|
if (action === 'transit' && meshId === undefined) {
|
|
810
838
|
return error('runtime-host service mesh transit requires --mesh or --off');
|
|
811
839
|
}
|
|
840
|
+
if ((action === 'rename' || action === 'rename-mesh') !== (displayName !== undefined)) {
|
|
841
|
+
return error(action === 'rename'
|
|
842
|
+
? 'runtime-host service mesh rename requires --name or --clear-name'
|
|
843
|
+
: '--name and --clear-name are only valid with mesh rename or rename-mesh');
|
|
844
|
+
}
|
|
812
845
|
return {
|
|
813
846
|
kind: 'runtime-host-service-peer-mesh',
|
|
814
847
|
action,
|
|
@@ -819,6 +852,7 @@ function parseServicePeerMeshCommand(argv) {
|
|
|
819
852
|
expectedTarget: options.expectedTarget,
|
|
820
853
|
...(meshId !== undefined ? { meshId } : {}),
|
|
821
854
|
...(peerId ? { peerId } : {}),
|
|
855
|
+
...(displayName !== undefined ? { displayName } : {}),
|
|
822
856
|
};
|
|
823
857
|
}
|
|
824
858
|
function parseUpdatePolicy(value) {
|
|
@@ -50,12 +50,14 @@ export function createRuntimeHostOnboardingSurface(connection) {
|
|
|
50
50
|
return result;
|
|
51
51
|
}
|
|
52
52
|
try {
|
|
53
|
+
const catalog = await readRuntimeHostConnectionCatalog(connection);
|
|
53
54
|
return {
|
|
54
55
|
kind: 'ok',
|
|
55
56
|
connection: result.connection,
|
|
56
57
|
refresh: {
|
|
57
58
|
kind: 'ok',
|
|
58
|
-
modelChoices: projectRuntimeHostModelChoices(
|
|
59
|
+
modelChoices: projectRuntimeHostModelChoices(catalog),
|
|
60
|
+
connectionIdentities: projectRuntimeHostConnectionIdentities(catalog),
|
|
59
61
|
},
|
|
60
62
|
};
|
|
61
63
|
}
|
|
@@ -108,6 +110,13 @@ export function projectRuntimeHostModelChoices(catalog) {
|
|
|
108
110
|
}
|
|
109
111
|
return choices;
|
|
110
112
|
}
|
|
113
|
+
export function projectRuntimeHostConnectionIdentities(catalog) {
|
|
114
|
+
return catalog.connections.map((connection) => ({
|
|
115
|
+
connectionId: connection.connectionId,
|
|
116
|
+
connectionSlug: connection.slug,
|
|
117
|
+
enabled: connection.enabled,
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
111
120
|
export function projectProviders(catalog) {
|
|
112
121
|
const entries = [];
|
|
113
122
|
for (const provider of listApiKeyOnboardableProviders()) {
|
|
@@ -139,6 +139,23 @@ async function executePeerMeshAction(connection, options, invitation) {
|
|
|
139
139
|
meshId: requiredOption(options.meshId, 'Mesh ID'),
|
|
140
140
|
}),
|
|
141
141
|
};
|
|
142
|
+
case 'rename':
|
|
143
|
+
return {
|
|
144
|
+
kind: 'result',
|
|
145
|
+
action: 'rename',
|
|
146
|
+
result: await request('peer.mesh.display-name.set', {
|
|
147
|
+
displayName: requiredOption(options.displayName, 'Display name'),
|
|
148
|
+
}),
|
|
149
|
+
};
|
|
150
|
+
case 'rename-mesh':
|
|
151
|
+
return {
|
|
152
|
+
kind: 'result',
|
|
153
|
+
action: 'rename-mesh',
|
|
154
|
+
result: await request('peer.mesh.rename', {
|
|
155
|
+
meshId: requiredMeshId(options.meshId),
|
|
156
|
+
displayName: requiredOption(options.displayName, 'Display name'),
|
|
157
|
+
}),
|
|
158
|
+
};
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
161
|
function requiredOption(value, label) {
|
|
@@ -22,7 +22,7 @@ import { join, resolve } from 'node:path';
|
|
|
22
22
|
import { isDeepStrictEqual } from 'node:util';
|
|
23
23
|
import { truncateUtf8 } from '@maka/core/diagnostic-log';
|
|
24
24
|
import { generalizedErrorMessage } from '@maka/core/redaction';
|
|
25
|
-
import { activateRuntimeHostManagedDeployment, connectRemoteRuntimeHost, ensureRuntimeHostPeerIdentity, } from '@maka/runtime-host/client';
|
|
25
|
+
import { activateRuntimeHostManagedDeployment, connectRemoteRuntimeHost, ensureRuntimeHostPeerIdentity, RuntimeHostOperationError, } from '@maka/runtime-host/client';
|
|
26
26
|
import { RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError, encodeRuntimeHostSetupFrame, isSha512PackageIntegrity, resolveRuntimeHostManagedDeployment, RUNTIME_HOST_SETUP_ERROR_CODE_MAX_BYTES, RUNTIME_HOST_SETUP_ERROR_MESSAGE_MAX_BYTES, } from '@maka/runtime-host/operator';
|
|
27
27
|
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, } from '@maka/runtime-host/protocol';
|
|
28
28
|
import { prepareRuntimeHostAccessCredential, replaceRuntimeHostAccessCredential, revokeRuntimeHostAccessCredential, RuntimeHostAccessUnavailableError, } from './runtime-host-access-command.js';
|
|
@@ -34,7 +34,7 @@ import { repairStorageRootAfterRemount, resolveStorageRoot } from '@maka/storage
|
|
|
34
34
|
import { createPlatformRuntimeHostServiceBackend, discoverRuntimeHostLifecycleProvider, resolveRuntimeHostLifecycleProvider, } from './runtime-host-service-management-command.js';
|
|
35
35
|
import { allocateRuntimeHostLoopbackPort, allocateRuntimeHostPeerPort, effectiveRuntimeHostProjectDirectoryRoots, manageRuntimeHostService, readRuntimeHostManagedServiceConfig, removeRuntimeHostServiceFile, resolveRuntimeHostManagedServiceConfigPath, resolveRuntimeHostManagedServiceId, resolveRuntimeHostManagedProjectDirectoryRoots, RuntimeHostServiceManagerError, withRuntimeHostManagedServiceDeploymentLock, withRuntimeHostManagedServiceLifecycleLock, } from './runtime-host-service-manager.js';
|
|
36
36
|
import { expandWildcardListenAddresses } from './runtime-host-peer-management-command.js';
|
|
37
|
-
import { canDiscardRuntimeHostLifecycleDesiredArtifacts, replaceRuntimeHostLifecycle, resolveRecoverableRuntimeHostManagedDeployment, RUNTIME_HOST_READY_TIMEOUT_MS, } from './runtime-host-lifecycle-transaction.js';
|
|
37
|
+
import { canDiscardRuntimeHostLifecycleDesiredArtifacts, replaceRuntimeHostLifecycle, resolveRecoverableRuntimeHostManagedDeployment, RUNTIME_HOST_READY_TIMEOUT_MS, RuntimeHostLifecycleTransactionError, } from './runtime-host-lifecycle-transaction.js';
|
|
38
38
|
import { resolveRuntimeHostManagedPeerKeyPath, resolveRuntimeHostPeerNativePath, } from './runtime-host-peer-artifact.js';
|
|
39
39
|
import { activateRuntimeHostManagedDeploymentWithReconciliation } from './runtime-host-activation-command.js';
|
|
40
40
|
const SETUP_LOCK_TIMEOUT_MS = 5 * 60_000;
|
|
@@ -192,12 +192,13 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
192
192
|
await assertLegacyArtifactsAbsent(legacyBackend);
|
|
193
193
|
if (legacyToMigrate)
|
|
194
194
|
await assertCompatibleExistingVersion(legacyStatus, options.version);
|
|
195
|
-
if (current && current.launch.package.version !== options.version) {
|
|
195
|
+
if (current && current.launch.package.version !== options.version && !options.updateExisting) {
|
|
196
196
|
throw new RuntimeHostSetupError('version_change_requires_update', `Runtime Host ${current.launch.package.version} is already installed; changing to ${options.version} requires the update workflow`);
|
|
197
197
|
}
|
|
198
198
|
const resolvedPackage = await resolveRuntimeHostSetupPackage(options, deps);
|
|
199
199
|
const { candidate } = resolvedPackage;
|
|
200
|
-
|
|
200
|
+
const packageChanged = current !== undefined && !sameExactPackage(current, candidate);
|
|
201
|
+
if (current && packageChanged && !options.updateExisting) {
|
|
201
202
|
throw new RuntimeHostSetupError('version_change_requires_update', `Runtime Host ${current.launch.package.version} is already installed; changing its exact package requires the update workflow`);
|
|
202
203
|
}
|
|
203
204
|
const lifecycleOffer = current?.lifecycle.mode === 'supervised'
|
|
@@ -214,14 +215,16 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
214
215
|
sourcePackageRoot: packageRoot,
|
|
215
216
|
version: candidate.version,
|
|
216
217
|
packageIntegrity: candidate.integrity,
|
|
218
|
+
...(current ? { deploymentRoot: current.deploymentRoot } : {}),
|
|
217
219
|
});
|
|
218
220
|
let committed = false;
|
|
219
221
|
try {
|
|
220
222
|
const desired = await prepareSupervisedDeploymentConfig(options, deps, capability, deployment.cliPath, deployment.root, candidate, current, legacyToMigrate, lifecycleOffer);
|
|
221
|
-
if (current &&
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
223
|
+
if (current &&
|
|
224
|
+
!sameDesiredManagedDeployment(current, desired) &&
|
|
225
|
+
!options.updateExisting &&
|
|
226
|
+
current.lifecycle.mode === 'supervised') {
|
|
227
|
+
throw new RuntimeHostSetupError('configuration_changed', 'Change an existing supervised Runtime Host through its explicit configure or update workflow');
|
|
225
228
|
}
|
|
226
229
|
emit({ kind: 'progress', phase: 'installing_service' });
|
|
227
230
|
if (legacyToMigrate) {
|
|
@@ -233,9 +236,11 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
233
236
|
operation: legacyToMigrate
|
|
234
237
|
? 'legacy_migration'
|
|
235
238
|
: current
|
|
236
|
-
?
|
|
237
|
-
? '
|
|
238
|
-
:
|
|
239
|
+
? packageChanged
|
|
240
|
+
? 'update'
|
|
241
|
+
: isDeepStrictEqual(current.lifecycle, desired.lifecycle)
|
|
242
|
+
? 'configure'
|
|
243
|
+
: 'lifecycle_change'
|
|
239
244
|
: 'install',
|
|
240
245
|
...(current ? { current } : {}),
|
|
241
246
|
desired,
|
|
@@ -247,6 +252,7 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
247
252
|
.then(() => undefined),
|
|
248
253
|
}
|
|
249
254
|
: {}),
|
|
255
|
+
allowInterruptActiveTasks: Boolean(current && packageChanged && options.updateExisting),
|
|
250
256
|
deps: lifecycleDeps,
|
|
251
257
|
});
|
|
252
258
|
if (replacement.kind === 'active_tasks') {
|
|
@@ -286,8 +292,13 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
286
292
|
};
|
|
287
293
|
}
|
|
288
294
|
catch (error) {
|
|
289
|
-
if (!
|
|
290
|
-
|
|
295
|
+
if (!committed && canDiscardRuntimeHostLifecycleDesiredArtifacts(error)) {
|
|
296
|
+
if (current && packageChanged) {
|
|
297
|
+
await deployment.rollback().catch(() => undefined);
|
|
298
|
+
}
|
|
299
|
+
else if (!current) {
|
|
300
|
+
await removeRuntimeHostManagedDeployment(deployment.root, capability.rootId).catch(() => undefined);
|
|
301
|
+
}
|
|
291
302
|
}
|
|
292
303
|
throw error;
|
|
293
304
|
}
|
|
@@ -552,6 +563,7 @@ async function runRuntimeHostOnDemandSetupLocked(options, deps, emit) {
|
|
|
552
563
|
activateDesired: async () => {
|
|
553
564
|
await deps.activateDesired({ rootId: capability.rootId });
|
|
554
565
|
},
|
|
566
|
+
allowInterruptActiveTasks: Boolean(current && packageChanged && options.updateExisting),
|
|
555
567
|
deps: lifecycleDeps,
|
|
556
568
|
});
|
|
557
569
|
if (replacement.kind === 'active_tasks') {
|
|
@@ -700,7 +712,7 @@ async function pairAndVerifyRuntimeHostSetup(options, target, deps, emit) {
|
|
|
700
712
|
break;
|
|
701
713
|
}
|
|
702
714
|
catch (error) {
|
|
703
|
-
if (!(error
|
|
715
|
+
if (!isTransientPairingAvailabilityError(error) || Date.now() >= deadline) {
|
|
704
716
|
throw error;
|
|
705
717
|
}
|
|
706
718
|
await new Promise((resolveWait) => setTimeout(resolveWait, Math.min(PAIRING_AVAILABILITY_POLL_MS, deadline - Date.now())));
|
|
@@ -757,6 +769,11 @@ async function pairAndVerifyRuntimeHostSetup(options, target, deps, emit) {
|
|
|
757
769
|
throw error;
|
|
758
770
|
}
|
|
759
771
|
}
|
|
772
|
+
function isTransientPairingAvailabilityError(error) {
|
|
773
|
+
return (error instanceof RuntimeHostAccessUnavailableError ||
|
|
774
|
+
(error instanceof RuntimeHostOperationError &&
|
|
775
|
+
(error.code === 'host_not_ready' || error.code === 'host_draining')));
|
|
776
|
+
}
|
|
760
777
|
async function assertCompatibleExistingVersion(status, version) {
|
|
761
778
|
if (!status.service.config) {
|
|
762
779
|
if (!status.service.installed)
|
|
@@ -828,7 +845,8 @@ function setupFailure(error) {
|
|
|
828
845
|
error instanceof RuntimeHostManagedDeploymentError ||
|
|
829
846
|
error instanceof RuntimeHostDeploymentAuthorityError ||
|
|
830
847
|
error instanceof RuntimeHostUpdateDiscoveryError ||
|
|
831
|
-
error instanceof RuntimeHostUpdatePackageError
|
|
848
|
+
error instanceof RuntimeHostUpdatePackageError ||
|
|
849
|
+
error instanceof RuntimeHostLifecycleTransactionError) {
|
|
832
850
|
code = error.code;
|
|
833
851
|
message = error.message;
|
|
834
852
|
}
|
|
@@ -127,7 +127,7 @@ export function createSystemdUserRuntimeHostService(serviceId, options) {
|
|
|
127
127
|
await runLifecycleAction(context, 'restart');
|
|
128
128
|
await ensureSystemdUpdateSchedulerStartedIfInstalled(scheduler);
|
|
129
129
|
},
|
|
130
|
-
retire: () =>
|
|
130
|
+
retire: () => retireSystemdSupervisor(context),
|
|
131
131
|
logs: async () => {
|
|
132
132
|
const readJournal = async (unitName) => {
|
|
133
133
|
const result = await runJournalctl([
|
|
@@ -220,7 +220,7 @@ export function createSystemdUserRuntimeHostLifecycleProvider(serviceId, options
|
|
|
220
220
|
await context.runSystemctl(['reset-failed', context.unitName]);
|
|
221
221
|
await runLifecycleAction(context, 'start');
|
|
222
222
|
},
|
|
223
|
-
retire: () =>
|
|
223
|
+
retire: () => retireSystemdSupervisor(context),
|
|
224
224
|
logs: () => readJournal(context.unitName),
|
|
225
225
|
uninstall: () => uninstallSystemdSupervisor(context),
|
|
226
226
|
},
|
|
@@ -507,7 +507,7 @@ async function stopSystemdManagedDeployment(service, scheduler) {
|
|
|
507
507
|
errors.push(error);
|
|
508
508
|
}
|
|
509
509
|
try {
|
|
510
|
-
await
|
|
510
|
+
await retireSystemdSupervisor(service);
|
|
511
511
|
}
|
|
512
512
|
catch (error) {
|
|
513
513
|
errors.push(error);
|
|
@@ -516,6 +516,12 @@ async function stopSystemdManagedDeployment(service, scheduler) {
|
|
|
516
516
|
throw new RuntimeHostServiceManagerError('service_manager_operation_failed', 'Unable to stop the Runtime Host managed deployment', { cause: new AggregateError(errors) });
|
|
517
517
|
}
|
|
518
518
|
}
|
|
519
|
+
async function retireSystemdSupervisor(context) {
|
|
520
|
+
const status = await readSystemdStatus(context);
|
|
521
|
+
if (!isSystemdUnitRunning(status))
|
|
522
|
+
return;
|
|
523
|
+
await runLifecycleAction(context, 'stop');
|
|
524
|
+
}
|
|
519
525
|
async function removeSystemdUpdateScheduler(context) {
|
|
520
526
|
const timerStatus = await readSystemdStatus(context.timer);
|
|
521
527
|
await stopSystemdUpdateScheduler(context);
|
|
@@ -26,7 +26,7 @@ import { readRuntimeHostAgentGraphEpochs, readRuntimeHostInvocableSkills, readRu
|
|
|
26
26
|
import { runtimeHostProfileUsesHostWorkspace } from '@maka/runtime-host/profile-kind';
|
|
27
27
|
import { connectRuntimeHostCli, readHostChatDefaultPermissionMode, resolveRuntimeHostCliTarget, } from './runtime-host-cli-context.js';
|
|
28
28
|
import { createRuntimeHostMakaSessionDriver, } from './runtime-host-session-driver.js';
|
|
29
|
-
import { createRuntimeHostOnboardingSurface, projectRuntimeHostModelChoices, } from './runtime-host-onboarding.js';
|
|
29
|
+
import { createRuntimeHostOnboardingSurface, projectRuntimeHostConnectionIdentities, projectRuntimeHostModelChoices, } from './runtime-host-onboarding.js';
|
|
30
30
|
import { createTuiMcpController, } from './tui-mcp-control.js';
|
|
31
31
|
export async function createRuntimeHostTuiContext(input) {
|
|
32
32
|
const connected = await connectRuntimeHostCli({
|
|
@@ -88,11 +88,7 @@ export async function createRuntimeHostTuiContext(input) {
|
|
|
88
88
|
...(selectedTarget.connectionId === undefined
|
|
89
89
|
? {}
|
|
90
90
|
: { connectionId: selectedTarget.connectionId }),
|
|
91
|
-
connectionIdentities: catalog
|
|
92
|
-
connectionId: entry.connectionId,
|
|
93
|
-
connectionSlug: entry.slug,
|
|
94
|
-
enabled: entry.enabled,
|
|
95
|
-
})),
|
|
91
|
+
connectionIdentities: projectRuntimeHostConnectionIdentities(catalog),
|
|
96
92
|
connectionName: selectedTarget.connection?.name ?? selectedTarget.connectionSlug,
|
|
97
93
|
...(selectedTarget.connection
|
|
98
94
|
? { providerType: selectedTarget.connection.providerType }
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -21,7 +21,7 @@ import { join } from 'node:path';
|
|
|
21
21
|
import { meteringCheckpointMacMatches, readBoundedRegularFile } from './metering-checkpoint.js';
|
|
22
22
|
import { deriveMetering } from './provider-metering.js';
|
|
23
23
|
import { TOOLCHAIN_IDENTITIES, TOOLCHAIN_IDENTITY_ENV, isExternalProfile, verifyToolchainDirectory, } from './toolchain-verification.js';
|
|
24
|
-
const BUNDLED_EXTERNAL_WRAPPER = '/opt/maka-agent/
|
|
24
|
+
const BUNDLED_EXTERNAL_WRAPPER = '/opt/maka-agent/node_modules/@maka/eval/dist/harbor-external-subject.js';
|
|
25
25
|
export function createExternalSubjectAdapter() {
|
|
26
26
|
const verifiedToolchains = new Map();
|
|
27
27
|
return {
|
|
@@ -44,7 +44,7 @@ const PROFILE_PREPARERS = {
|
|
|
44
44
|
codex: async ({ env, home, root, proxyBaseUrl }) => {
|
|
45
45
|
env.OPENAI_API_KEY = 'maka-eval-local';
|
|
46
46
|
env.CODEX_HOME = home;
|
|
47
|
-
const catalog = rooted(root, '/opt/maka-agent/
|
|
47
|
+
const catalog = rooted(root, '/opt/maka-agent/node_modules/@maka/eval/harbor/deepseek-codex-models.json');
|
|
48
48
|
await writeFile(join(home, 'config.toml'), [
|
|
49
49
|
'model_provider = "maka-http"',
|
|
50
50
|
`model_catalog_json = ${JSON.stringify(catalog)}`,
|
|
@@ -198,7 +198,7 @@ const PROFILE_PREPARERS = {
|
|
|
198
198
|
env.DSH_HOME = join(home, 'dsh');
|
|
199
199
|
const profile = join(env.DSH_HOME, 'profiles', DEEPSEEK_HARNESS_PROFILE);
|
|
200
200
|
await mkdir(profile, { recursive: true, mode: 0o700 });
|
|
201
|
-
const source = rooted(root, '/opt/maka-agent/
|
|
201
|
+
const source = rooted(root, '/opt/maka-agent/node_modules/@maka/eval/harbor/deepseek-harness-profile');
|
|
202
202
|
for (const file of ['package.json', 'cordis.yml', 'cordis.patch.yml']) {
|
|
203
203
|
await copyFile(join(source, file), join(profile, file));
|
|
204
204
|
}
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { readlinkSync, realpathSync } from 'node:fs';
|
|
20
|
+
import { basename, dirname, resolve } from 'node:path';
|
|
19
21
|
export const MACOS_SEATBELT_EXECUTABLE = '/usr/bin/sandbox-exec';
|
|
20
22
|
export const MACOS_SEATBELT_BASE_POLICY = `(version 1)
|
|
21
23
|
(deny default)
|
|
@@ -301,30 +303,87 @@ function resolveRoots(profile, pathContext) {
|
|
|
301
303
|
writableRoots,
|
|
302
304
|
deniedRoots,
|
|
303
305
|
protectedWritableRoots: profile.fileSystem.protectedMetadata && writableRoots.length > 0
|
|
304
|
-
? uniqueRoots([
|
|
306
|
+
? uniqueRoots([
|
|
307
|
+
...protectedWritableRoots,
|
|
308
|
+
...pathContext.workspaceRoots.map(resolveRootPath),
|
|
309
|
+
])
|
|
305
310
|
: [],
|
|
306
311
|
protectedMetadataNames: profile.fileSystem.protectedMetadata?.names ?? [],
|
|
307
|
-
runtimeReadableRoots: uniqueRoots(pathContext.runtimeReadableRoots ?? []),
|
|
308
|
-
executableRoots: uniqueRoots(pathContext.executableRoots ?? []),
|
|
312
|
+
runtimeReadableRoots: uniqueRoots((pathContext.runtimeReadableRoots ?? []).map(resolveRootPath)),
|
|
313
|
+
executableRoots: uniqueRoots((pathContext.executableRoots ?? []).map(resolveRootPath)),
|
|
309
314
|
};
|
|
310
315
|
}
|
|
311
316
|
function rootsForEntry(entry, pathContext) {
|
|
312
317
|
if (entry.kind === 'path') {
|
|
313
|
-
return [{ path: entry.path, match: entry.match ?? 'subtree' }];
|
|
318
|
+
return [{ path: resolveRootPath(entry.path), match: entry.match ?? 'subtree' }];
|
|
314
319
|
}
|
|
315
320
|
switch (entry.special) {
|
|
316
321
|
case ':root':
|
|
317
|
-
return [{ path: '/', match: 'subtree' }];
|
|
322
|
+
return [{ path: resolveRootPath('/'), match: 'subtree' }];
|
|
318
323
|
case ':workspace_roots':
|
|
319
|
-
return pathContext.workspaceRoots.map((path) => ({
|
|
324
|
+
return pathContext.workspaceRoots.map((path) => ({
|
|
325
|
+
path: resolveRootPath(path),
|
|
326
|
+
match: 'subtree',
|
|
327
|
+
}));
|
|
320
328
|
case ':tmpdir':
|
|
321
|
-
return pathContext.tmpdir
|
|
329
|
+
return pathContext.tmpdir
|
|
330
|
+
? [{ path: resolveRootPath(pathContext.tmpdir), match: 'subtree' }]
|
|
331
|
+
: [];
|
|
322
332
|
case ':slash_tmp':
|
|
323
|
-
return [{ path: pathContext.slashTmp ?? '/tmp', match: 'subtree' }];
|
|
333
|
+
return [{ path: resolveRootPath(pathContext.slashTmp ?? '/tmp'), match: 'subtree' }];
|
|
324
334
|
case ':minimal':
|
|
325
|
-
return (pathContext.minimalRoots ?? []).map((path) => ({
|
|
335
|
+
return (pathContext.minimalRoots ?? []).map((path) => ({
|
|
336
|
+
path: resolveRootPath(path),
|
|
337
|
+
match: 'subtree',
|
|
338
|
+
}));
|
|
326
339
|
}
|
|
327
340
|
}
|
|
341
|
+
const MAX_DANGLING_SYMLINK_HOPS = 40;
|
|
342
|
+
/**
|
|
343
|
+
* Seatbelt evaluates kernel-resolved paths, so every root must be emitted in
|
|
344
|
+
* canonical form. A root may not exist yet (a deny for a file that has not
|
|
345
|
+
* been created), so canonicalize the deepest existing ancestor and re-append
|
|
346
|
+
* the missing tail, mirroring `realpathAllowMissing`; an allow and its deny
|
|
347
|
+
* then stay in the same path space. Any other resolution failure (EACCES,
|
|
348
|
+
* ELOOP, ...) propagates and fails policy construction: emitting a root in
|
|
349
|
+
* lexical path space could split an allow from its deny across aliases.
|
|
350
|
+
*/
|
|
351
|
+
function resolveRootPath(path) {
|
|
352
|
+
let cursor = resolve(path);
|
|
353
|
+
const missing = [];
|
|
354
|
+
let hops = 0;
|
|
355
|
+
while (true) {
|
|
356
|
+
try {
|
|
357
|
+
return resolve(realpathSync(cursor), ...missing.reverse());
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
if (!isMissingPathError(error))
|
|
361
|
+
throw error;
|
|
362
|
+
let link = null;
|
|
363
|
+
try {
|
|
364
|
+
link = readlinkSync(cursor);
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
link = null;
|
|
368
|
+
}
|
|
369
|
+
if (link !== null) {
|
|
370
|
+
if (++hops > MAX_DANGLING_SYMLINK_HOPS)
|
|
371
|
+
throw new Error(`Root ${JSON.stringify(path)} traverses too many dangling symlinks.`);
|
|
372
|
+
cursor = resolve(dirname(cursor), link);
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const parent = dirname(cursor);
|
|
376
|
+
if (parent === cursor)
|
|
377
|
+
throw error;
|
|
378
|
+
missing.push(basename(cursor));
|
|
379
|
+
cursor = parent;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function isMissingPathError(error) {
|
|
384
|
+
const code = error?.code;
|
|
385
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
386
|
+
}
|
|
328
387
|
function addUniqueResolvedRoots(target, roots) {
|
|
329
388
|
for (const root of roots) {
|
|
330
389
|
if (!target.some((existing) => existing.path === root.path && existing.match === root.match)) {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { RuntimeHostPeerError, signRuntimeHostPeerIdentity, startRuntimeHostPeerEndpoint, verifyRuntimeHostPeerIdentity, } from '../transport/peer-native.js';
|
|
19
|
+
import { normalizePeerError, RuntimeHostPeerError, signRuntimeHostPeerIdentity, startRuntimeHostPeerEndpoint, verifyRuntimeHostPeerIdentity, } from '../transport/peer-native.js';
|
|
20
20
|
import { RuntimeHostPermanentReconnectError } from './reconnect-lifecycle.js';
|
|
21
21
|
export function createRuntimeHostPeerClientFromEnvironment(environment = process.env, options = {}) {
|
|
22
22
|
const nativePath = environment.MAKA_RUNTIME_HOST_PEER_NATIVE_PATH;
|
|
@@ -86,11 +86,30 @@ class RuntimeHostPeerClientImpl {
|
|
|
86
86
|
return Object.freeze({ ...this.#requireEndpoint().transitSnapshot });
|
|
87
87
|
}
|
|
88
88
|
configureTransit(input) {
|
|
89
|
-
return this.#requireEndpoint()
|
|
89
|
+
return this.#requireEndpoint()
|
|
90
|
+
.configureTransit(input)
|
|
91
|
+
.catch((error) => {
|
|
92
|
+
throw normalizePeerError(error);
|
|
93
|
+
});
|
|
90
94
|
}
|
|
91
95
|
async connect(input, signal) {
|
|
96
|
+
await this.#prepareRoutes(input, signal);
|
|
92
97
|
return this.#connect(input, signal, 'application');
|
|
93
98
|
}
|
|
99
|
+
async #prepareRoutes(input, signal) {
|
|
100
|
+
if (!this.#routeResolver?.prepareRoutes)
|
|
101
|
+
return;
|
|
102
|
+
const deadline = AbortSignal.timeout(Math.min(10_000, input.directDeadlineMs));
|
|
103
|
+
const operationSignal = signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
104
|
+
try {
|
|
105
|
+
await this.#routeResolver.prepareRoutes(input.peerId, operationSignal);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Route preparation enriches an invitation/profile with fresher Mesh
|
|
109
|
+
// routes. It must not suppress explicit routes the caller already has.
|
|
110
|
+
signal?.throwIfAborted();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
94
113
|
async connectMeshControl(input, signal) {
|
|
95
114
|
return this.#connect(input, signal, 'mesh-control');
|
|
96
115
|
}
|
|
@@ -193,7 +212,7 @@ class RuntimeHostPeerClientImpl {
|
|
|
193
212
|
}
|
|
194
213
|
catch (error) {
|
|
195
214
|
signal?.throwIfAborted();
|
|
196
|
-
throw error;
|
|
215
|
+
throw normalizePeerError(error);
|
|
197
216
|
}
|
|
198
217
|
finally {
|
|
199
218
|
settled = true;
|
|
@@ -30,6 +30,8 @@ const ACTION_SCHEMA = z.enum([
|
|
|
30
30
|
'close',
|
|
31
31
|
'reconcile',
|
|
32
32
|
'transit',
|
|
33
|
+
'rename',
|
|
34
|
+
'rename-mesh',
|
|
33
35
|
]);
|
|
34
36
|
const FRAME_SCHEMA = z.union([
|
|
35
37
|
z.object({ kind: z.literal('input'), action: z.literal('join') }).strict(),
|
|
@@ -93,6 +95,18 @@ function decodeFrame(value) {
|
|
|
93
95
|
action: 'transit',
|
|
94
96
|
result: decodePeerMeshQueryResult(frame.result),
|
|
95
97
|
};
|
|
98
|
+
case 'rename':
|
|
99
|
+
return {
|
|
100
|
+
kind: 'result',
|
|
101
|
+
action: 'rename',
|
|
102
|
+
result: decodePeerMeshQueryResult(frame.result),
|
|
103
|
+
};
|
|
104
|
+
case 'rename-mesh':
|
|
105
|
+
return {
|
|
106
|
+
kind: 'result',
|
|
107
|
+
action: 'rename-mesh',
|
|
108
|
+
result: decodePeerMeshQueryResult(frame.result),
|
|
109
|
+
};
|
|
96
110
|
case 'invite':
|
|
97
111
|
return {
|
|
98
112
|
kind: 'result',
|
|
@@ -16,13 +16,15 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
-
export
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
export const PEER_MESH_DISPLAY_NAME_MAX_LENGTH = 80;
|
|
20
|
+
export function canonicalPeerMeshDisplayName(value) {
|
|
21
|
+
if (typeof value !== 'string')
|
|
22
|
+
throw new Error('Invalid Peer Mesh display name');
|
|
23
|
+
const displayName = value.trim();
|
|
24
|
+
if (displayName.length === 0 ||
|
|
25
|
+
displayName.length > PEER_MESH_DISPLAY_NAME_MAX_LENGTH ||
|
|
26
|
+
/[\u0000-\u001f\u007f]/u.test(displayName)) {
|
|
27
|
+
throw new Error('Invalid Peer Mesh display name');
|
|
28
|
+
}
|
|
29
|
+
return displayName;
|
|
30
|
+
}
|