@nowcrew/daemon 0.6.89 → 0.6.91-beta.1
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 +64 -3
- package/dist/agent-ability/materializer.js +21 -10
- package/dist/agent-environment-contract.js +55 -0
- package/dist/agent-environment-control.js +24 -0
- package/dist/agent-environment-execution.js +98 -0
- package/dist/agent-environments.js +275 -0
- package/dist/automatic-daemon-installer.js +49 -1
- package/dist/computer-main.js +18 -0
- package/dist/computer-profile.js +17 -4
- package/dist/computer-setup-client.js +318 -0
- package/dist/computer-setup-orchestration.js +203 -0
- package/dist/computer-setup.js +244 -0
- package/dist/config.js +30 -12
- package/dist/console-formatter.js +3 -3
- package/dist/console.js +15 -2
- package/dist/daemon-update-eligibility.js +1 -1
- package/dist/daemon-updater.js +2 -12
- package/dist/execution-journal.js +9 -6
- package/dist/execution-protocol.js +1 -0
- package/dist/execution-runner.js +13 -8
- package/dist/i18n.js +19 -0
- package/dist/list-models.js +12 -12
- package/dist/local-execution-lease.js +22 -0
- package/dist/local-executor.js +57 -84
- package/dist/local-memory/candidate.js +43 -0
- package/dist/local-memory/index-budget.js +8 -0
- package/dist/local-memory/inventory-cli.js +61 -0
- package/dist/local-memory/inventory-preview.js +159 -0
- package/dist/local-memory/inventory-source.js +159 -0
- package/dist/local-memory/pending-match.js +29 -0
- package/dist/local-memory/pending-query.js +100 -0
- package/dist/local-memory/pending-schema.js +29 -0
- package/dist/local-memory/pending-source.js +126 -0
- package/dist/local-memory/pending.js +34 -84
- package/dist/local-memory/prompt.js +19 -12
- package/dist/local-memory/read-cli.js +97 -12
- package/dist/local-memory/rollout.js +82 -0
- package/dist/local-memory/runtime.js +23 -17
- package/dist/local-memory/work-log-execution.js +31 -0
- package/dist/local-memory/work-log.js +58 -0
- package/dist/local-memory/write.js +27 -58
- package/dist/local-runtime-environment.js +50 -0
- package/dist/machine-environment-cache.js +147 -0
- package/dist/machine-environment-contract.js +10 -0
- package/dist/machine-environment-control.js +27 -0
- package/dist/machine-environment-policy.js +75 -0
- package/dist/machine-environment-process.js +110 -0
- package/dist/machine-info.js +70 -25
- package/dist/machine-runtime-environment.js +189 -0
- package/dist/machine-shell-environment-capture.js +135 -0
- package/dist/machine-windows-environment-capture.js +215 -0
- package/dist/machine-windows-environment-script.js +158 -0
- package/dist/main.js +4 -69
- package/dist/marketplace-command.js +21 -0
- package/dist/marketplace-controller.js +80 -0
- package/dist/marketplace-protocol.js +38 -0
- package/dist/marketplace-remote.js +48 -0
- package/dist/marketplace-runner.js +235 -0
- package/dist/marketplace-serve.js +41 -0
- package/dist/marketplace-source.js +103 -0
- package/dist/message-file-preview.js +246 -0
- package/dist/pre-admission-rejection.js +64 -0
- package/dist/project-skills/execution-adapter.js +3 -2
- package/dist/project-skills/runtime-launch.js +14 -0
- package/dist/provider-env.js +26 -15
- package/dist/runner.js +17 -4
- package/dist/runtime-environment-merge.js +16 -0
- package/dist/runtime-health-handler.js +10 -0
- package/dist/runtime-health.js +3 -1
- package/dist/runtime-path.js +22 -12
- package/dist/runtime-probe.js +35 -6
- package/dist/runtimes/acp-probe-transport.js +69 -0
- package/dist/runtimes/claude-models.js +20 -9
- package/dist/runtimes/deepseek-harness-launch.js +10 -0
- package/dist/runtimes/deepseek-harness-profile.js +92 -0
- package/dist/runtimes/deepseek-harness-runner.js +226 -0
- package/dist/runtimes/deepseek-harness.js +76 -15
- package/dist/runtimes/harness-probe-retry.js +42 -0
- package/dist/runtimes/hermes-models.js +2 -1
- package/dist/runtimes/kimi-acp-runner.js +78 -13
- package/dist/runtimes/opencode.js +2 -2
- package/dist/serve.js +88 -178
- package/dist/storage-identity.js +0 -3
- package/dist/storage-serve-adapter.js +6 -72
- package/dist/supervised-runtime.js +17 -2
- package/dist/token.js +0 -1
- package/dist/workspace-control-handler.js +27 -0
- package/dist/workspace-fs.js +66 -15
- package/dist/workspace.js +1 -1
- package/package.json +13 -12
- package/dist/codex-home-launch.js +0 -7
- package/dist/codex-home-mode-controller.js +0 -68
- package/dist/daemon-migration-controller.js +0 -211
- package/dist/daemon-migration-wiring.js +0 -22
- package/dist/runtimes/codex-home-migration-cli.js +0 -26
- package/dist/runtimes/codex-home-migration.js +0 -112
- package/dist/runtimes/codex-home.js +0 -236
- package/dist/storage-control.js +0 -212
- package/dist/storage-copy.js +0 -628
- package/dist/storage-credential-guard.js +0 -21
- package/dist/storage-doctor.js +0 -228
- package/dist/storage-manifest.js +0 -1027
- package/dist/storage-migration-controller.js +0 -440
- package/dist/storage-migration-manifest.js +0 -105
- package/dist/storage-migration-policy.js +0 -100
- package/dist/storage-runtime-controller.js +0 -381
- package/dist/storage-runtime-readiness.js +0 -241
- package/dist/storage-safe-fs.js +0 -302
- package/dist/storage-status-delivery.js +0 -224
- package/dist/storage-status-replay.js +0 -140
- package/dist/storage-target-confirmation.js +0 -129
- package/dist/storage-worker-command.js +0 -37
- package/dist/storage-worker-executor.js +0 -447
- package/dist/storage-worker-handoff.js +0 -151
- package/dist/storage-worker-operation.js +0 -294
- package/dist/storage-worker-status.js +0 -259
package/dist/serve.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/** 常驻控制面桥接;按请求拉起本地 runtime。 */
|
|
2
|
+
import { handleAgentEnvironmentFrame } from "./agent-environment-control.js";
|
|
3
|
+
import { handleMachineEnvironmentFrame } from "./machine-environment-control.js";
|
|
4
|
+
import { createMachineRuntimeEnvironment } from "./machine-runtime-environment.js";
|
|
5
5
|
import { WebSocket } from "ws";
|
|
6
|
+
import { persistPreAdmissionRejection, rejectQueuedAdmission } from "./pre-admission-rejection.js";
|
|
6
7
|
import { join } from "node:path";
|
|
7
8
|
import { randomUUID } from "node:crypto";
|
|
8
9
|
import { dslog, setSlogDefaults, drainSpool, flushSlog } from "./slog.js";
|
|
9
10
|
import { mergeRunAgentResults, reportScheduledStartFailure, runAgent } from "./runner.js";
|
|
10
11
|
import { buildOriginDecisionRetryPrompt, buildScheduledPrompt } from "./prompt.js";
|
|
11
|
-
import {
|
|
12
|
+
import { daemonCapabilities, daemonCapabilityBindings, } from "./machine-info.js";
|
|
12
13
|
import { reconcileExecutionJournal } from "./execution-recovery.js";
|
|
13
14
|
import { initReleaseSlog, reportDaemonConnectionClose, reportReleaseError } from "./release-channel-guard.js";
|
|
14
|
-
import {
|
|
15
|
-
import { listWorkspace, readWorkspaceFile } from "./workspace-fs.js";
|
|
16
|
-
import { listSkills } from "./skills.js";
|
|
15
|
+
import { handleWorkspaceControlRequest } from "./workspace-control-handler.js";
|
|
17
16
|
import { inspectRaftWorkspace, importRaftWorkspace } from "./workspace-import.js";
|
|
18
|
-
import { listRuntimeModels } from "./list-models.js";
|
|
19
17
|
import { normalizeScheduledContext } from "./scheduled-report.js";
|
|
20
18
|
import { formatDaemonLogLine } from "./log-format.js";
|
|
21
19
|
import { reportAgentRunComplete } from "./scheduled-run-report.js";
|
|
@@ -49,12 +47,10 @@ import { createProjectSkillsReconciler, } from "./project-skills/reconciler.js";
|
|
|
49
47
|
import { initializedProjectSkillsReconciler } from "./project-skills/initialized-reconciler.js";
|
|
50
48
|
import { parseMemoryPruneTraceId } from "./memory-prune-diagnostics.js";
|
|
51
49
|
import { probeRuntimeHealth } from "./runtime-health.js";
|
|
52
|
-
import {
|
|
50
|
+
import { createServeMarketplace } from "./marketplace-serve.js";
|
|
53
51
|
import { buildControlPlaneUrl } from "./control-plane-url.js";
|
|
54
|
-
import { createServeMigrationController, handleMigrationControlMessage } from "./daemon-migration-wiring.js";
|
|
55
|
-
import { createCodexHomeModeController } from "./codex-home-mode-controller.js";
|
|
56
52
|
import { resolveDaemonLocalStateRootFromEnv } from "./daemon-local-home.js";
|
|
57
|
-
import {
|
|
53
|
+
import { bindStorageServerIdentity, createStorageIdentityAdmission, } from "./storage-serve-adapter.js";
|
|
58
54
|
export { buildControlPlaneUrl } from "./control-plane-url.js";
|
|
59
55
|
// normalize.ts 的活动种类 → activity 枚举
|
|
60
56
|
const ACTIVITY_MAP = {
|
|
@@ -80,9 +76,6 @@ export function serve(config, opts = {}) {
|
|
|
80
76
|
?? (config.agentMemory === null ? undefined : createAgentMemoryBridge(config.agentMemory));
|
|
81
77
|
const executionTelemetry = createExecutionTelemetryJournal(config.agentsRoot);
|
|
82
78
|
const executeProtocol = opts.execution?.runExecution ?? runExecution;
|
|
83
|
-
let detectedExecutionRuntimes = [], executionRuntimesKnown = false;
|
|
84
|
-
let runtimeFacts = null;
|
|
85
|
-
const runtimeProbe = createRuntimeProbeCoordinator();
|
|
86
79
|
const localHome = opts.localHome ?? resolveDaemonLocalStateRootFromEnv();
|
|
87
80
|
const hostCoordinator = opts.execution?.hostCoordinator
|
|
88
81
|
?? createHostExecutionCoordinator({
|
|
@@ -112,11 +105,9 @@ export function serve(config, opts = {}) {
|
|
|
112
105
|
install: opts.update?.install ?? ((input) => installExactDaemonUpdate({
|
|
113
106
|
...input,
|
|
114
107
|
localSlots,
|
|
115
|
-
hostCoordinator,
|
|
116
108
|
})),
|
|
117
109
|
prepareRestart: opts.update?.prepareRestart ?? (() => prepareDaemonRestart({
|
|
118
110
|
localSlots,
|
|
119
|
-
hostCoordinator,
|
|
120
111
|
})),
|
|
121
112
|
scheduleRestart: opts.update?.scheduleRestart ?? scheduleServiceRestart,
|
|
122
113
|
sendStatus: (frame) => {
|
|
@@ -127,28 +118,14 @@ export function serve(config, opts = {}) {
|
|
|
127
118
|
catch { /* reconnect/timeout reconciliation handles a lost status frame */ }
|
|
128
119
|
},
|
|
129
120
|
});
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
config,
|
|
133
|
-
...(opts.profileName === undefined ? {} : { profileName: opts.profileName }),
|
|
134
|
-
isBusy: () => executionRuns.size > 0 || legacyRuns.size > 0,
|
|
135
|
-
sendStatus: (frame) => { try {
|
|
136
|
-
if (ws?.readyState === WebSocket.OPEN)
|
|
137
|
-
ws.send(JSON.stringify(frame));
|
|
138
|
-
}
|
|
139
|
-
catch { /* reconnect */ } },
|
|
140
|
-
});
|
|
141
|
-
const codexHomeModeController = createCodexHomeModeController({ ...(opts.profileName === undefined ? {} : { profileName: opts.profileName }), scheduleRestart: opts.update?.scheduleRestart ?? scheduleServiceRestart, getServiceSpec: async () => { const eligibility = await updateEligibility(); return eligibility.eligible ? eligibility.serviceSpec : null; }, isBusy: () => executionRuns.size > 0 || legacyRuns.size > 0, sendStatus: (frame) => { try {
|
|
142
|
-
if (ws?.readyState === WebSocket.OPEN)
|
|
143
|
-
ws.send(JSON.stringify(frame));
|
|
144
|
-
}
|
|
145
|
-
catch { /* reconnect */ } } });
|
|
121
|
+
const marketplace = createServeMarketplace(config, localSlots, hostCoordinator);
|
|
122
|
+
const storageIdentityAdmission = createStorageIdentityAdmission(opts.storageRuntime);
|
|
146
123
|
const projectionCoordinator = createAgentProjectionCoordinator();
|
|
147
124
|
const { projectRegistry, projectWorkspaceRegistry, projectDependencyProvisioner } = createProjectRegistryWiring(config.agentsRoot, opts.execution?.dependencies);
|
|
148
125
|
const agentAbilityRuntime = createAgentAbilityRuntime(config.agentsRoot, {
|
|
149
126
|
...opts.agentAbility,
|
|
150
127
|
coordinator: projectionCoordinator,
|
|
151
|
-
isAdmissionClosed:
|
|
128
|
+
isAdmissionClosed: storageIdentityAdmission.isAdmissionClosed,
|
|
152
129
|
});
|
|
153
130
|
let projectSkillsController;
|
|
154
131
|
const projectSkillsReconciler = opts.projectSkills?.reconciler ?? createProjectSkillsReconciler({
|
|
@@ -169,7 +146,7 @@ export function serve(config, opts = {}) {
|
|
|
169
146
|
}
|
|
170
147
|
catch { /* 下一次 ready 或项目操作会重新发送完整快照 */ }
|
|
171
148
|
},
|
|
172
|
-
isAdmissionClosed:
|
|
149
|
+
isAdmissionClosed: storageIdentityAdmission.isAdmissionClosed,
|
|
173
150
|
reconcile: (handle, bindings) => projectSkillsReconciler.reconcile(handle, bindings),
|
|
174
151
|
});
|
|
175
152
|
const logRegistryFailure = (error) => dslog("project_skills.registry_failed", "本机项目注册表读取失败,本次不上报项目清单(能力不受影响)", {
|
|
@@ -177,7 +154,7 @@ export function serve(config, opts = {}) {
|
|
|
177
154
|
});
|
|
178
155
|
const machineHelloPublisher = createMachineHelloPublisher({
|
|
179
156
|
effective: (hello) => {
|
|
180
|
-
const configuredIdentity = opts.
|
|
157
|
+
const configuredIdentity = opts.storageRuntime?.identity;
|
|
181
158
|
const currentIdentity = typeof configuredIdentity === "function"
|
|
182
159
|
? configuredIdentity()
|
|
183
160
|
: configuredIdentity;
|
|
@@ -185,25 +162,19 @@ export function serve(config, opts = {}) {
|
|
|
185
162
|
},
|
|
186
163
|
onSent: (hello) => log(`📤 已上报机器信息: ${hello.hostname} · ${hello.os} · installed=[${hello.runtimes.join(",")}] · executable=[${hello.executionRuntimes.join(",")}] · agents=[${hello.agentHandles.join(",")}]`),
|
|
187
164
|
});
|
|
165
|
+
const machineRuntime = createMachineRuntimeEnvironment({
|
|
166
|
+
config,
|
|
167
|
+
...(opts.machineEnvironment === undefined ? {} : { provider: opts.machineEnvironment }),
|
|
168
|
+
...(opts.machineInfo === undefined ? {} : { machineInfo: opts.machineInfo }),
|
|
169
|
+
...(opts.profileName === undefined ? {} : { profileName: opts.profileName }),
|
|
170
|
+
additionalCapabilities: async () => managedDaemonCapabilities(updateEligibility),
|
|
171
|
+
publish: machineHelloPublisher.publish,
|
|
172
|
+
onError: (code, context) => dslog("execution.runtime_detection_failed", "机器环境或 runtime 探测失败", { level: "ERROR", error_code: code, ...context }),
|
|
173
|
+
});
|
|
174
|
+
machineRuntime.prewarm();
|
|
188
175
|
const initializedProjectSkills = initializedProjectSkillsReconciler(() => projectSkillsController.ensureScanned(), projectSkillsReconciler);
|
|
189
176
|
const configuredCapabilities = opts.machineInfo?.capabilities ?? daemonCapabilities(process.platform);
|
|
190
|
-
const
|
|
191
|
-
const storageStatusDelivery = createServeStorageStatusDelivery(opts.storageMigration, {
|
|
192
|
-
onPersistenceError: (error) => dslog("daemon.storage_status_outbox_failed", "存储迁移状态 outbox 持久化失败", { level: "ERROR", error_message: error.message }),
|
|
193
|
-
transmit: (frame) => { try {
|
|
194
|
-
if (ws?.readyState === WebSocket.OPEN)
|
|
195
|
-
ws.send(JSON.stringify(frame));
|
|
196
|
-
}
|
|
197
|
-
catch { /* retry */ } },
|
|
198
|
-
});
|
|
199
|
-
const storageMigrationRuntime = attachStorageMigrationRuntime(opts.storageMigration, {
|
|
200
|
-
isBusy: () => executionRuns.size > 0 || legacyRuns.size > 0,
|
|
201
|
-
waitForExecutionFrames: () => executionFrameQueue,
|
|
202
|
-
flushLocalState: flushSlog,
|
|
203
|
-
sendStatus: storageStatusDelivery.send,
|
|
204
|
-
});
|
|
205
|
-
storageMigrationAdmissionClosed = storageMigrationRuntime.isAdmissionClosed;
|
|
206
|
-
const prepareCapabilities = async () => daemonCapabilityBindings(process.platform, [...storageCapabilities, ...await managedDaemonCapabilities(updateEligibility)]);
|
|
177
|
+
const prepareCapabilities = async () => daemonCapabilityBindings(process.platform, [...configuredCapabilities, ...await managedDaemonCapabilities(updateEligibility)]);
|
|
207
178
|
const safeExecutionSend = (frame) => {
|
|
208
179
|
try {
|
|
209
180
|
if (ws?.readyState !== WebSocket.OPEN)
|
|
@@ -237,6 +208,11 @@ export function serve(config, opts = {}) {
|
|
|
237
208
|
return;
|
|
238
209
|
}
|
|
239
210
|
safeExecutionSend(frame);
|
|
211
|
+
if (frame.type === "execution:rejected" && frame.preAdmissionProof) {
|
|
212
|
+
const entry = await executionJournal.get(frame.executionId);
|
|
213
|
+
if (entry?.completion)
|
|
214
|
+
completionRetransmitter.track(entry.completion);
|
|
215
|
+
}
|
|
240
216
|
};
|
|
241
217
|
const replayExecutionTelemetry = async () => {
|
|
242
218
|
const frames = await executionTelemetry.replay();
|
|
@@ -312,67 +288,29 @@ export function serve(config, opts = {}) {
|
|
|
312
288
|
if (stopped)
|
|
313
289
|
return;
|
|
314
290
|
const wsUrl = (opts.buildControlPlaneUrl ?? buildControlPlaneUrl)(config.serverUrl, config.machineToken, process.platform, undefined, capabilities.controlPlaneUrl);
|
|
315
|
-
|
|
291
|
+
const connectionSocket = createWebSocket(wsUrl);
|
|
292
|
+
ws = connectionSocket;
|
|
293
|
+
const sendToConnection = (frame) => {
|
|
294
|
+
try {
|
|
295
|
+
if (!stopped && ws === connectionSocket && connectionSocket.readyState === WebSocket.OPEN)
|
|
296
|
+
connectionSocket.send(JSON.stringify(frame));
|
|
297
|
+
}
|
|
298
|
+
catch { /* 旧连接请求由服务端超时处理。 */ }
|
|
299
|
+
};
|
|
316
300
|
let connectionEpochToken;
|
|
317
|
-
|
|
301
|
+
connectionSocket.on("open", () => {
|
|
318
302
|
connectionEpochToken = projectSkillsController.beginConnectionEpoch();
|
|
319
|
-
|
|
320
|
-
const openedSocket =
|
|
303
|
+
storageIdentityAdmission.beginIdentityBinding();
|
|
304
|
+
const openedSocket = connectionSocket;
|
|
305
|
+
const connectionId = randomUUID();
|
|
321
306
|
backoff = 1000;
|
|
322
307
|
connectedAt = Date.now();
|
|
323
308
|
log(`🔌 已连接控制面 ${config.serverUrl}`);
|
|
324
|
-
dslog("daemon.ws_open", "已连接控制面", { server_url: config.serverUrl });
|
|
309
|
+
dslog("daemon.ws_open", "已连接控制面", { server_url: config.serverUrl, connection_id: connectionId });
|
|
325
310
|
// 连上了才有机会把离线期间(断连原因/退出前)落盘的日志补传上去
|
|
326
311
|
void drainSpool();
|
|
327
312
|
// 上报本机信息 (hostname/os/daemon 版本/已装 runtimes)
|
|
328
|
-
|
|
329
|
-
const storageReplay = replayStorageMigrationStatus(opts.storageMigration, openedSocket, () => ws === openedSocket, (error) => {
|
|
330
|
-
dslog("daemon.storage_status_replay_failed", "存储迁移状态重放失败", {
|
|
331
|
-
level: "ERROR", error_message: error.message,
|
|
332
|
-
});
|
|
333
|
-
}, storageStatusDelivery.send);
|
|
334
|
-
const { detectInstalled, detectExecutable = detectExecutionRuntimesWithSignal } = opts.machineInfo ?? {};
|
|
335
|
-
const helloPromise = (opts.machineInfo?.collect ?? collectMachineHello)(config.agentsRoot, config.executionLimits, process.platform, {
|
|
336
|
-
...(detectInstalled ? { detectInstalled } : {}),
|
|
337
|
-
...(opts.profileName === undefined ? {} : { profileName: opts.profileName }),
|
|
338
|
-
// First hello must not wait for third-party handshakes; optional transports arrive in the refresh.
|
|
339
|
-
detectExecutable: async (installed) => conservativeExecutionRuntimes(installed),
|
|
340
|
-
additionalCapabilities: async () => [...(await managedDaemonCapabilities(updateEligibility)), ...(opts.profileName === undefined ? [] : ["codex_home_mode_v1"])],
|
|
341
|
-
capabilities: capabilities.machineHello,
|
|
342
|
-
codexHomeMode: config.codexHomeMode,
|
|
343
|
-
});
|
|
344
|
-
runtimeFacts = helloPromise
|
|
345
|
-
.then(async (hello) => {
|
|
346
|
-
if (hello.executionProtocol === undefined) {
|
|
347
|
-
executionRuntimesKnown = true;
|
|
348
|
-
return [];
|
|
349
|
-
}
|
|
350
|
-
const detected = await runtimeProbe.detect(hello.runtimes, detectExecutable);
|
|
351
|
-
executionRuntimesKnown = true;
|
|
352
|
-
await storageReplay;
|
|
353
|
-
if (ws === openedSocket && openedSocket.readyState === WebSocket.OPEN
|
|
354
|
-
&& detected.some((runtime) => !hello.executionRuntimes.includes(runtime))) {
|
|
355
|
-
detectedExecutionRuntimes = detected;
|
|
356
|
-
machineHelloPublisher.publish({ ...hello, executionRuntimes: [...detected] }, openedSocket);
|
|
357
|
-
}
|
|
358
|
-
return detected;
|
|
359
|
-
})
|
|
360
|
-
.catch((error) => {
|
|
361
|
-
executionRuntimesKnown = true;
|
|
362
|
-
dslog("execution.runtime_detection_failed", "runtime 探测失败", {
|
|
363
|
-
level: "ERROR", error_message: error.message,
|
|
364
|
-
});
|
|
365
|
-
return [];
|
|
366
|
-
});
|
|
367
|
-
void helloPromise
|
|
368
|
-
.then(async (hello) => {
|
|
369
|
-
await storageReplay;
|
|
370
|
-
if (ws !== openedSocket || openedSocket.readyState !== WebSocket.OPEN)
|
|
371
|
-
return;
|
|
372
|
-
detectedExecutionRuntimes = hello.executionRuntimes;
|
|
373
|
-
machineHelloPublisher.publish(hello, openedSocket);
|
|
374
|
-
})
|
|
375
|
-
.catch(() => { });
|
|
313
|
+
machineRuntime.open(openedSocket, { capabilities: capabilities.machineHello, beforePublish: Promise.resolve(), connectionId });
|
|
376
314
|
opts.onOpen?.(ws);
|
|
377
315
|
void sendSnapshot(`reconnect-${randomUUID()}`);
|
|
378
316
|
void executionJournal.replay()
|
|
@@ -401,8 +339,8 @@ export function serve(config, opts = {}) {
|
|
|
401
339
|
});
|
|
402
340
|
});
|
|
403
341
|
});
|
|
404
|
-
|
|
405
|
-
if (stopped)
|
|
342
|
+
connectionSocket.on("message", async (data) => {
|
|
343
|
+
if (stopped || ws !== connectionSocket)
|
|
406
344
|
return;
|
|
407
345
|
let decoded;
|
|
408
346
|
try {
|
|
@@ -414,8 +352,10 @@ export function serve(config, opts = {}) {
|
|
|
414
352
|
if (typeof decoded !== "object" || decoded === null)
|
|
415
353
|
return;
|
|
416
354
|
const rawType = "type" in decoded && typeof decoded.type === "string" ? decoded.type : "";
|
|
417
|
-
if (
|
|
355
|
+
if (rawType === "machine:environment:get" || rawType === "machine:environment:refresh") {
|
|
356
|
+
await handleMachineEnvironmentFrame(decoded, machineRuntime.provider, sendToConnection);
|
|
418
357
|
return;
|
|
358
|
+
}
|
|
419
359
|
if (rawType === "daemon:update" || rawType === "daemon:restart") {
|
|
420
360
|
void updateController.handle(decoded).catch((error) => {
|
|
421
361
|
dslog("daemon.control_failed", "daemon 控制操作处理失败", {
|
|
@@ -424,19 +364,6 @@ export function serve(config, opts = {}) {
|
|
|
424
364
|
});
|
|
425
365
|
return;
|
|
426
366
|
}
|
|
427
|
-
if (rawType === "daemon:migrate") {
|
|
428
|
-
void handleMigrationControlMessage(migrationController, decoded).catch((error) => dslog("daemon.migration_failed", "daemon 布局迁移失败", { level: "ERROR", error_message: error.message }));
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
if (rawType === "daemon:codex-home-mode") {
|
|
432
|
-
void codexHomeModeController.handle(decoded).catch((error) => dslog("daemon.codex_home_mode_failed", "Codex Home 模式切换失败", { level: "ERROR", error_message: error.message }));
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
if (handleStorageMigrationControl(opts.storageMigration, rawType, decoded, storageStatusDelivery.send, (kind, error) => {
|
|
436
|
-
dslog(kind === "migration" ? "daemon.storage_migration_failed" : "daemon.storage_migration_confirmation_failed", kind === "migration" ? "存储迁移控制操作失败" : "存储迁移 hello 确认处理失败", { level: "ERROR", error_message: error.message });
|
|
437
|
-
})) {
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
367
|
if (rawType.startsWith("execution:")) {
|
|
441
368
|
const parsedExecution = ServerToDaemonExecutionFrameSchema.safeParse(decoded);
|
|
442
369
|
if (!parsedExecution.success) {
|
|
@@ -498,10 +425,10 @@ export function serve(config, opts = {}) {
|
|
|
498
425
|
return;
|
|
499
426
|
}
|
|
500
427
|
const spec = frame;
|
|
501
|
-
if (
|
|
428
|
+
if (storageIdentityAdmission.isAdmissionClosed()) {
|
|
502
429
|
safeExecutionSend(ExecutionRejectedSchema.parse({
|
|
503
430
|
type: "execution:rejected", protocolVersion: 1, executionId: spec.executionId,
|
|
504
|
-
reason: "resource_limit", message: "Storage
|
|
431
|
+
reason: "resource_limit", message: "Storage identity binding is not complete",
|
|
505
432
|
at: new Date().toISOString(),
|
|
506
433
|
}));
|
|
507
434
|
return;
|
|
@@ -560,18 +487,8 @@ export function serve(config, opts = {}) {
|
|
|
560
487
|
: spec.context.scheduledRunId === undefined ? "normal" : "scheduled";
|
|
561
488
|
let reservation = sharedSlots.reserve(spec.agent.handle, "execution", executionClass);
|
|
562
489
|
if (!reservation.accepted) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
execution_id: spec.executionId,
|
|
566
|
-
agent_handle: spec.agent.handle,
|
|
567
|
-
execution_class: executionClass,
|
|
568
|
-
...reservation.facts,
|
|
569
|
-
});
|
|
570
|
-
safeExecutionSend(ExecutionRejectedSchema.parse({
|
|
571
|
-
type: "execution:rejected", protocolVersion: 1, executionId: spec.executionId,
|
|
572
|
-
reason: "resource_limit", message: "Local machine execution queue is full",
|
|
573
|
-
at: new Date().toISOString(),
|
|
574
|
-
}));
|
|
490
|
+
await rejectQueuedAdmission({ journal: executionJournal, knownExecutionHashes, executionRuns,
|
|
491
|
+
report: reportExecutionFrame, replay: sendJournalStatus }, spec, executionClass, reservation.facts);
|
|
575
492
|
return;
|
|
576
493
|
}
|
|
577
494
|
knownExecutionHashes.set(spec.executionId, hash);
|
|
@@ -710,9 +627,7 @@ export function serve(config, opts = {}) {
|
|
|
710
627
|
let availableRuntimes;
|
|
711
628
|
try {
|
|
712
629
|
availableRuntimes = opts.execution?.availableRuntimes?.()
|
|
713
|
-
??
|
|
714
|
-
? detectedExecutionRuntimes
|
|
715
|
-
: await (runtimeFacts ?? Promise.resolve(detectedExecutionRuntimes)));
|
|
630
|
+
?? await machineRuntime.availableRuntimes(spec.runtime.name);
|
|
716
631
|
}
|
|
717
632
|
catch (error) {
|
|
718
633
|
cleanupExecutionReservation("runtime_detection_failed");
|
|
@@ -729,6 +644,7 @@ export function serve(config, opts = {}) {
|
|
|
729
644
|
}
|
|
730
645
|
const execution = executeProtocol(config, spec, {
|
|
731
646
|
...opts.execution?.dependencies,
|
|
647
|
+
machineEnvironment: machineRuntime.provider,
|
|
732
648
|
capabilities: capabilities.executionRunner,
|
|
733
649
|
projectSkills: opts.execution?.dependencies?.projectSkills ?? initializedProjectSkills,
|
|
734
650
|
abilityRelease: opts.execution?.dependencies?.abilityRelease ?? agentAbilityRuntime.materializer,
|
|
@@ -741,6 +657,13 @@ export function serve(config, opts = {}) {
|
|
|
741
657
|
...reservation.facts,
|
|
742
658
|
},
|
|
743
659
|
report: reportExecutionFrame,
|
|
660
|
+
confirmPreAdmission: async (rejection) => {
|
|
661
|
+
const prior = await executionJournal.get(spec.executionId);
|
|
662
|
+
if (prior !== null || stopped || knownExecutionHashes.get(spec.executionId) !== hash
|
|
663
|
+
|| executionRuns.get(spec.executionId) !== execution)
|
|
664
|
+
return false;
|
|
665
|
+
return await persistPreAdmissionRejection(executionJournal, spec, rejection) !== null;
|
|
666
|
+
},
|
|
744
667
|
startupGate: runtimeStartupGate,
|
|
745
668
|
startupTimeoutMs: config.executionLimits.startupTimeoutMs,
|
|
746
669
|
onRuntimePhase: (phase, runtime) => {
|
|
@@ -812,17 +735,17 @@ export function serve(config, opts = {}) {
|
|
|
812
735
|
// ready 帧带 server 视角的 machineId/workspaceId → 作为后续所有日志的默认关联键
|
|
813
736
|
const r = msg;
|
|
814
737
|
setSlogDefaults({ machine_id: r.machineId, workspace_id: r.workspaceId });
|
|
815
|
-
if (opts.
|
|
738
|
+
if (opts.storageRuntime !== undefined && typeof r.workspaceId === "string" && typeof r.machineId === "string") {
|
|
816
739
|
const bindingSocket = ws;
|
|
817
|
-
|
|
740
|
+
bindStorageServerIdentity(opts.storageRuntime, { workspaceId: r.workspaceId, machineId: r.machineId }, {
|
|
818
741
|
onBound: () => {
|
|
819
742
|
if (bindingSocket !== ws || bindingSocket?.readyState !== WebSocket.OPEN)
|
|
820
743
|
return;
|
|
821
|
-
|
|
744
|
+
storageIdentityAdmission.completeIdentityBinding();
|
|
822
745
|
machineHelloPublisher.republish();
|
|
823
746
|
},
|
|
824
747
|
onError: (error) => {
|
|
825
|
-
dslog("daemon.storage_identity_bind_failed", "
|
|
748
|
+
dslog("daemon.storage_identity_bind_failed", "存储 Workspace 身份绑定失败", { level: "ERROR", error_message: error.message });
|
|
826
749
|
if (bindingSocket === ws && bindingSocket?.readyState === WebSocket.OPEN)
|
|
827
750
|
bindingSocket.close(1011, "storage identity binding failed");
|
|
828
751
|
},
|
|
@@ -867,15 +790,17 @@ export function serve(config, opts = {}) {
|
|
|
867
790
|
return;
|
|
868
791
|
}
|
|
869
792
|
if (msg.type === "runtime-health:probe") {
|
|
870
|
-
const result = await
|
|
793
|
+
const result = await machineRuntime.health(msg, opts.runtimeHealth?.probe);
|
|
871
794
|
if (result !== null) {
|
|
872
|
-
|
|
873
|
-
ws?.send(JSON.stringify({ type: "fs:result", ...result }));
|
|
874
|
-
}
|
|
875
|
-
catch { /* server 会超时 */ }
|
|
795
|
+
sendToConnection({ type: "fs:result", ...result });
|
|
876
796
|
}
|
|
877
797
|
return;
|
|
878
798
|
}
|
|
799
|
+
if (marketplace.handle(msg, frame => { try {
|
|
800
|
+
ws?.send(JSON.stringify(frame));
|
|
801
|
+
}
|
|
802
|
+
catch { /* server 会按请求超时处理 */ } }))
|
|
803
|
+
return;
|
|
879
804
|
if (await agentAbilityRuntime.tryHandleControlMessage(msg, serverCapabilities, (frame) => ws?.send(JSON.stringify(frame))))
|
|
880
805
|
return;
|
|
881
806
|
// 导入 raft agent 工作区:inspect 反填 name/description;import 复制用户内容
|
|
@@ -901,31 +826,16 @@ export function serve(config, opts = {}) {
|
|
|
901
826
|
}
|
|
902
827
|
return;
|
|
903
828
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
try {
|
|
910
|
-
ws?.send(JSON.stringify({ type: "fs:result", reqId: req.reqId, ...r }));
|
|
911
|
-
}
|
|
912
|
-
catch { /* 忽略 */ }
|
|
913
|
-
};
|
|
914
|
-
try {
|
|
915
|
-
const data2 = req.type === "fs:list" ? await listWorkspace(root, req.path)
|
|
916
|
-
: req.type === "fs:read" ? await readWorkspaceFile(root, req.path)
|
|
917
|
-
: req.type === "skills:list" ? await listSkills(req.runtime)
|
|
918
|
-
: { models: await listRuntimeModels(req.type === "probe-models" ? (req.runtime ?? "") : "") };
|
|
919
|
-
reply({ ok: true, data: data2 });
|
|
920
|
-
}
|
|
921
|
-
catch (e) {
|
|
922
|
-
reply({ ok: false, error: e.message });
|
|
923
|
-
}
|
|
829
|
+
if (await handleAgentEnvironmentFrame(msg, config.agentsRoot, sendToConnection))
|
|
830
|
+
return;
|
|
831
|
+
const fileResult = await handleWorkspaceControlRequest(msg, config.agentsRoot, projectWorkspaceRegistry, machineRuntime.models);
|
|
832
|
+
if (fileResult) {
|
|
833
|
+
sendToConnection(fileResult);
|
|
924
834
|
return;
|
|
925
835
|
}
|
|
926
836
|
if (msg.type !== "agent:start")
|
|
927
837
|
return; // ready/error 等忽略
|
|
928
|
-
if (
|
|
838
|
+
if (storageIdentityAdmission.isAdmissionClosed())
|
|
929
839
|
return;
|
|
930
840
|
// 任务键:scheduled run 用 runId(每次运行独立 cwd/work-log;overlap 由 server 端 skip_if_running 管,
|
|
931
841
|
// daemon 的 running 去重只兜底"同一 run 重复投递");普通唤醒仍是 线程锚点 ?? 频道。
|
|
@@ -1128,6 +1038,7 @@ export function serve(config, opts = {}) {
|
|
|
1128
1038
|
...(!scheduled && msg.wake?.seq !== undefined ? { wakeContextUpToSeq: msg.wake.seq } : {}),
|
|
1129
1039
|
...(attemptWake ? { wake: attemptWake } : {}),
|
|
1130
1040
|
}, reportActivity, reportConsole, {
|
|
1041
|
+
machineEnvironment: machineRuntime.provider,
|
|
1131
1042
|
cancellation: controller.cancellation,
|
|
1132
1043
|
startupGate: runtimeStartupGate,
|
|
1133
1044
|
startupTimeoutMs: config.executionLimits.startupTimeoutMs,
|
|
@@ -1290,8 +1201,9 @@ export function serve(config, opts = {}) {
|
|
|
1290
1201
|
void flushSlog(); // 每轮收尾冲一次,保证 run.end 尽快可查
|
|
1291
1202
|
}
|
|
1292
1203
|
});
|
|
1293
|
-
|
|
1294
|
-
|
|
1204
|
+
connectionSocket.on("close", (code) => {
|
|
1205
|
+
machineRuntime.close(connectionSocket);
|
|
1206
|
+
if (stopped || ws !== connectionSocket)
|
|
1295
1207
|
return;
|
|
1296
1208
|
// server 能力随连接失效;下个连接的 ready 帧重新声明(防降级重连后沿用过期能力)。
|
|
1297
1209
|
serverCapabilities = new Set();
|
|
@@ -1315,9 +1227,9 @@ export function serve(config, opts = {}) {
|
|
|
1315
1227
|
}, backoff);
|
|
1316
1228
|
backoff = Math.min(backoff * 2, maxBackoff);
|
|
1317
1229
|
});
|
|
1318
|
-
|
|
1230
|
+
connectionSocket.on("error", () => {
|
|
1319
1231
|
if (!stopped)
|
|
1320
|
-
|
|
1232
|
+
connectionSocket.close();
|
|
1321
1233
|
});
|
|
1322
1234
|
}
|
|
1323
1235
|
const ready = (async () => {
|
|
@@ -1355,9 +1267,7 @@ export function serve(config, opts = {}) {
|
|
|
1355
1267
|
stopPromise = (async () => {
|
|
1356
1268
|
stopped = true;
|
|
1357
1269
|
concurrencyTelemetry.stop();
|
|
1358
|
-
runtimeProbe.stop();
|
|
1359
1270
|
completionRetransmitter.stop();
|
|
1360
|
-
storageStatusDelivery.stop();
|
|
1361
1271
|
const deadline = createShutdownDeadline(shutdownTimeoutMs);
|
|
1362
1272
|
if (reconnectTimer !== null) {
|
|
1363
1273
|
clearTimeout(reconnectTimer);
|
|
@@ -1365,10 +1275,10 @@ export function serve(config, opts = {}) {
|
|
|
1365
1275
|
}
|
|
1366
1276
|
const webSocketClosed = closeWebSocketWithinDeadline(ws, deadline.signal);
|
|
1367
1277
|
const pending = [
|
|
1278
|
+
machineRuntime.stop(),
|
|
1368
1279
|
webSocketClosed,
|
|
1369
1280
|
updateController.drain(),
|
|
1370
|
-
|
|
1371
|
-
codexHomeModeController.drain(),
|
|
1281
|
+
marketplace.stop(),
|
|
1372
1282
|
executionFrameQueue,
|
|
1373
1283
|
...executionRuns.values(),
|
|
1374
1284
|
...[...legacyRuns.values()].map((run) => run.done),
|
package/dist/storage-identity.js
CHANGED
|
@@ -39,8 +39,5 @@ export function storageHelloIdentity(input) {
|
|
|
39
39
|
daemonRootFingerprint: fingerprint("daemon-root", layout.daemonRoot),
|
|
40
40
|
agentRootFingerprint: fingerprint("agent-root", layout.agentItemsRoot),
|
|
41
41
|
...(ownership === undefined ? {} : { storageOwnership: ownership }),
|
|
42
|
-
...(installation.storageMigrationId === undefined
|
|
43
|
-
? {}
|
|
44
|
-
: { storageMigrationId: installation.storageMigrationId }),
|
|
45
42
|
});
|
|
46
43
|
}
|
|
@@ -1,55 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
if (options === undefined)
|
|
5
|
-
return configured;
|
|
6
|
-
return Object.freeze([...new Set([
|
|
7
|
-
...configured,
|
|
8
|
-
STORAGE_MIGRATION_STATUS_CAPABILITY,
|
|
9
|
-
...(options.ready ? [STORAGE_MIGRATION_CAPABILITY] : []),
|
|
10
|
-
])]);
|
|
1
|
+
export function bindStorageServerIdentity(options, identity, callbacks) {
|
|
2
|
+
void Promise.resolve().then(() => options.bindServerIdentity?.(identity))
|
|
3
|
+
.then(callbacks.onBound).catch(callbacks.onError);
|
|
11
4
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (bind === undefined) {
|
|
15
|
-
if (options?.ready === true)
|
|
16
|
-
callbacks.onBound();
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
void Promise.resolve().then(() => bind(identity)).then(callbacks.onBound).catch(callbacks.onError);
|
|
20
|
-
}
|
|
21
|
-
export function createServeStorageStatusDelivery(options, dependencies) {
|
|
22
|
-
return createStorageStatusDelivery({
|
|
23
|
-
...(options?.statusOutboxPath === undefined ? {} : { outboxPath: options.statusOutboxPath }),
|
|
24
|
-
...(options?.statusRetryMs === undefined ? {} : { retryMs: options.statusRetryMs }),
|
|
25
|
-
...dependencies,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
export function attachStorageMigrationRuntime(options, dependencies) {
|
|
29
|
-
let migrationAdmissionClosed = false;
|
|
5
|
+
/** 新连接必须重新验证 Server 身份,不能沿用上一次连接的执行准入。 */
|
|
6
|
+
export function createStorageIdentityAdmission(options) {
|
|
30
7
|
let identityAdmissionClosed = options?.bindServerIdentity !== undefined;
|
|
31
|
-
if (options?.ready === true) {
|
|
32
|
-
options.attach?.({
|
|
33
|
-
gate: {
|
|
34
|
-
isBusy: dependencies.isBusy,
|
|
35
|
-
closeAndFlush: async () => {
|
|
36
|
-
migrationAdmissionClosed = true;
|
|
37
|
-
await dependencies.waitForExecutionFrames();
|
|
38
|
-
if (dependencies.isBusy()) {
|
|
39
|
-
migrationAdmissionClosed = false;
|
|
40
|
-
throw Object.assign(new Error("active execution entered before storage migration quiesce"), {
|
|
41
|
-
code: "runtime_busy",
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
await dependencies.flushLocalState();
|
|
45
|
-
},
|
|
46
|
-
reopen: () => { migrationAdmissionClosed = false; },
|
|
47
|
-
},
|
|
48
|
-
sendStatus: dependencies.sendStatus,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
8
|
return Object.freeze({
|
|
52
|
-
isAdmissionClosed: () =>
|
|
9
|
+
isAdmissionClosed: () => identityAdmissionClosed,
|
|
53
10
|
beginIdentityBinding: () => {
|
|
54
11
|
if (options?.bindServerIdentity !== undefined)
|
|
55
12
|
identityAdmissionClosed = true;
|
|
@@ -57,26 +14,3 @@ export function attachStorageMigrationRuntime(options, dependencies) {
|
|
|
57
14
|
completeIdentityBinding: () => { identityAdmissionClosed = false; },
|
|
58
15
|
});
|
|
59
16
|
}
|
|
60
|
-
export function replayStorageMigrationStatus(options, socket, isCurrent, onError, deliver) {
|
|
61
|
-
return options?.replayStatus?.((frame) => {
|
|
62
|
-
if (!isCurrent())
|
|
63
|
-
return;
|
|
64
|
-
if (deliver !== undefined)
|
|
65
|
-
deliver(frame);
|
|
66
|
-
else if (socket.readyState === socket.OPEN)
|
|
67
|
-
socket.send(JSON.stringify(frame));
|
|
68
|
-
}).catch(onError) ?? Promise.resolve();
|
|
69
|
-
}
|
|
70
|
-
export function handleStorageMigrationControl(options, rawType, raw, sendStatus, onError) {
|
|
71
|
-
if (rawType === "daemon:storage-doctor" || rawType === "daemon:storage-migrate") {
|
|
72
|
-
if (options?.ready === true)
|
|
73
|
-
void options.controller.handle(raw).catch((error) => onError("migration", error));
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
if (rawType !== "daemon:storage-migration-confirmed")
|
|
77
|
-
return false;
|
|
78
|
-
const confirm = options?.ready === false ? options.confirm : undefined;
|
|
79
|
-
if (confirm !== undefined)
|
|
80
|
-
void confirm(raw, sendStatus).catch((error) => onError("confirmation", error));
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
import { startDormantSupervisor, } from "./execution-supervisor.js";
|
|
3
3
|
import { buildClaudeLaunch } from "./runtimes/claude.js";
|
|
4
|
-
import { DEEPSEEK_HARNESS_CONFIG_ENV, deepSeekHarnessConfigPath, } from "./runtimes/deepseek-harness.js";
|
|
4
|
+
import { DEEPSEEK_HARNESS_CONFIG_ENV, deepSeekHarnessConfigPath, deepSeekHarnessLauncher, } from "./runtimes/deepseek-harness.js";
|
|
5
5
|
import { RuntimeCancelledError } from "./runtime-cancellation.js";
|
|
6
6
|
export function supervisorLaunch(request) {
|
|
7
7
|
const common = {
|
|
@@ -82,7 +82,22 @@ export function supervisorLaunch(request) {
|
|
|
82
82
|
if (request.runtime === "deepseek-harness") {
|
|
83
83
|
if (request.resume)
|
|
84
84
|
throw new Error("DeepSeek Harness ACP does not support session resume");
|
|
85
|
-
const
|
|
85
|
+
const launcher = deepSeekHarnessLauncher(request.env);
|
|
86
|
+
if (launcher.kind === "profile") {
|
|
87
|
+
return {
|
|
88
|
+
command: process.execPath,
|
|
89
|
+
args: [fileURLToPath(new URL("./runtimes/deepseek-harness-runner.js", import.meta.url)),
|
|
90
|
+
"--bin", request.bin, ...(launcher.patchPath ? ["--patch", launcher.patchPath] : [])],
|
|
91
|
+
cwd: request.cwd, env: request.env,
|
|
92
|
+
stdinText: JSON.stringify({ systemPrompt: request.systemPrompt, wakePrompt: request.wakePrompt,
|
|
93
|
+
stateRoot: request.harnessStateRoot ?? request.cwd, skillRoots: request.harnessSkillRoots ?? [],
|
|
94
|
+
effectivePermission: request.effectivePermission }),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if ((request.harnessSkillRoots?.length ?? 0) > 0) {
|
|
98
|
+
throw new Error("DeepSeek Harness bound Skills require the modern dsh ACP profile");
|
|
99
|
+
}
|
|
100
|
+
const configPath = deepSeekHarnessConfigPath(request.env);
|
|
86
101
|
if (configPath === null) {
|
|
87
102
|
throw new Error(`${DEEPSEEK_HARNESS_CONFIG_ENV} must be an absolute path`);
|
|
88
103
|
}
|
package/dist/token.js
CHANGED