@nowcrew/daemon 0.6.88-beta.21 → 0.6.88-beta.23
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.
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* launchd Background policy can stall dsh's synchronous startup reads before ACP.
|
|
3
|
+
* Apply application resource policy to this short-lived child, never the daemon.
|
|
4
|
+
* taskpolicy execs the target; no shell, alternate PATH, or protocol bypass.
|
|
5
|
+
*/
|
|
6
|
+
export function deepSeekHarnessLaunch(bin, args, platform = process.platform) {
|
|
7
|
+
return platform === "darwin"
|
|
8
|
+
? { bin: "/usr/sbin/taskpolicy", args: ["-a", "--", bin, ...args] }
|
|
9
|
+
: { bin, args: [...args] };
|
|
10
|
+
}
|
|
@@ -7,6 +7,7 @@ import { isAbsolute } from "node:path";
|
|
|
7
7
|
import spawn from "cross-spawn";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { client, methods, ndJsonStream, PROTOCOL_VERSION, } from "@agentclientprotocol/sdk";
|
|
10
|
+
import { deepSeekHarnessLaunch } from "./deepseek-harness-launch.js";
|
|
10
11
|
import { prepareHarnessProfile } from "./deepseek-harness-profile.js";
|
|
11
12
|
import { mapAcpUpdate } from "./kimi-acp-runner.js";
|
|
12
13
|
import { prepareThreadDelivery } from "../thread-input-delivery.js";
|
|
@@ -56,7 +57,8 @@ export async function runHarness(input, bin, patchPath) {
|
|
|
56
57
|
env: process.env,
|
|
57
58
|
...(patchPath ? { patchPath } : {}),
|
|
58
59
|
});
|
|
59
|
-
const
|
|
60
|
+
const launch = deepSeekHarnessLaunch(bin, profile.args);
|
|
61
|
+
const child = spawn(launch.bin, launch.args, {
|
|
60
62
|
cwd: profile.home,
|
|
61
63
|
env: profile.env,
|
|
62
64
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -180,7 +182,7 @@ export async function runHarness(input, bin, patchPath) {
|
|
|
180
182
|
if (!cancelled)
|
|
181
183
|
process.stderr.write(spawnError
|
|
182
184
|
? "DeepSeek Harness launch failed; verify the installed dsh executable.\n"
|
|
183
|
-
: `DeepSeek Harness ACP execution failed at ${stage}; verify the pinned version
|
|
185
|
+
: `DeepSeek Harness ACP execution failed at ${stage}; verify DEEPSEEK_API_KEY, model access, the pinned version and profile patch.\n`);
|
|
184
186
|
}
|
|
185
187
|
finally {
|
|
186
188
|
try {
|
|
@@ -3,6 +3,7 @@ import { isAbsolute } from "node:path";
|
|
|
3
3
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
+
import { deepSeekHarnessLaunch } from "./deepseek-harness-launch.js";
|
|
6
7
|
import { prepareHarnessProfile } from "./deepseek-harness-profile.js";
|
|
7
8
|
import { probeKimiAcp, AcpProbeCleanupError } from "./kimi-acp-runner.js";
|
|
8
9
|
export const DEEPSEEK_HARNESS_CONFIG_ENV = "NOWCREW_DEEPSEEK_HARNESS_CONFIG";
|
|
@@ -52,11 +53,13 @@ export async function probeDeepSeekHarnessAcp(options, spawnProcess = spawn) {
|
|
|
52
53
|
env: process.env,
|
|
53
54
|
...(launcher.patchPath ? { patchPath: launcher.patchPath } : {}),
|
|
54
55
|
});
|
|
56
|
+
const launch = deepSeekHarnessLaunch(options.bin, profile.args);
|
|
55
57
|
return await probeKimiAcp({
|
|
56
58
|
...options,
|
|
59
|
+
bin: launch.bin,
|
|
57
60
|
provider: "deepseek-harness",
|
|
58
61
|
effectivePermission: "sandboxed",
|
|
59
|
-
launchArgs:
|
|
62
|
+
launchArgs: launch.args,
|
|
60
63
|
launchEnv: profile.env,
|
|
61
64
|
launchCwd: root,
|
|
62
65
|
}, spawnProcess);
|
|
@@ -13,7 +13,12 @@ import { prepareThreadDelivery } from "../thread-input-delivery.js";
|
|
|
13
13
|
import { startFirstProgressWatchdog } from "./progress-watchdog.js";
|
|
14
14
|
import { assertKimiLegacyPromptFits, buildKimiArgs } from "./kimi.js";
|
|
15
15
|
const ERROR_MESSAGE_CAP = 2_000;
|
|
16
|
-
|
|
16
|
+
// macOS launchd cold-starts ACP runtimes materially slower than an interactive
|
|
17
|
+
// shell. DeepSeek Harness was measured at ~4.4s before returning initialize
|
|
18
|
+
// under launchd, while the daemon also creates an isolated profile. Keep this
|
|
19
|
+
// bounded below the control-plane request budget, with the existing 1s/2s
|
|
20
|
+
// Harness retries providing the outer bound.
|
|
21
|
+
export const ACP_PROBE_TIMEOUT_MS = 10_000;
|
|
17
22
|
function jsonLine(event) {
|
|
18
23
|
if (process.stdout.write(`${JSON.stringify(event)}\n`))
|
|
19
24
|
return Promise.resolve();
|
|
@@ -222,6 +227,15 @@ export async function probeKimiAcp(options, spawnProcess = spawn) {
|
|
|
222
227
|
env: { ...launchEnv, PATH: augmentedPath(launchEnv) },
|
|
223
228
|
stdio: ["pipe", "pipe", "pipe"],
|
|
224
229
|
});
|
|
230
|
+
// spawn errors are emitted by ChildProcess, not its stdio streams. A missing
|
|
231
|
+
// launcher must fail admission, not become an uncaught daemon exception.
|
|
232
|
+
const spawnFailed = new Promise((resolve) => {
|
|
233
|
+
child.once("error", () => {
|
|
234
|
+
if (reason === "initializing")
|
|
235
|
+
reason = "spawn_error";
|
|
236
|
+
resolve(false);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
225
239
|
child.once("spawn", () => {
|
|
226
240
|
spawnConfirmedMs = elapsed();
|
|
227
241
|
dslog("execution.acp_probe_spawned", "ACP 探测子进程已启动", fields());
|
|
@@ -256,13 +270,14 @@ export async function probeKimiAcp(options, spawnProcess = spawn) {
|
|
|
256
270
|
});
|
|
257
271
|
const result = await Promise.race([
|
|
258
272
|
connected,
|
|
273
|
+
spawnFailed,
|
|
259
274
|
new Promise((resolve) => {
|
|
260
275
|
timeout = setTimeout(() => {
|
|
261
276
|
if (reason === "initializing")
|
|
262
277
|
reason = "timeout";
|
|
263
278
|
void stopChild(child);
|
|
264
279
|
resolve(false);
|
|
265
|
-
},
|
|
280
|
+
}, ACP_PROBE_TIMEOUT_MS);
|
|
266
281
|
}),
|
|
267
282
|
new Promise((resolve) => {
|
|
268
283
|
onAbort = () => {
|