@parall/daemon 1.28.1 → 1.29.0
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/bundle/manifest.json +10 -10
- package/bundle/parall-claude-agent.js +107 -86
- package/bundle/parall-codex-agent.js +130 -101
- package/bundle/parall-daemon.js +161 -67
- package/bundle/parall-openclaw-agent.js +22 -14
- package/dist/index.js +4 -10
- package/dist/runtimes.d.ts +8 -1
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +49 -3
- package/dist/supervisor.d.ts +5 -6
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +41 -2
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createLogger } from "@parall/agent-core";
|
|
2
3
|
import { ParallClient } from "@parall/sdk";
|
|
3
4
|
import { resolveClaudeDaemonConfig, resolveWsUrl } from "./config.js";
|
|
4
5
|
import { DaemonSupervisor, sleepCancellable } from "./supervisor.js";
|
|
5
6
|
import { runCLI } from "./cli.js";
|
|
6
|
-
|
|
7
|
-
return {
|
|
8
|
-
info: (msg) => console.log(`[${prefix}] ${msg}`),
|
|
9
|
-
warn: (msg) => console.warn(`[${prefix}] ${msg}`),
|
|
10
|
-
error: (msg) => console.error(`[${prefix}] ${msg}`),
|
|
11
|
-
};
|
|
12
|
-
}
|
|
7
|
+
const log = createLogger("daemon");
|
|
13
8
|
function formatError(reason) {
|
|
14
9
|
if (reason instanceof Error) {
|
|
15
10
|
return reason.stack ?? reason.message;
|
|
@@ -73,7 +68,6 @@ async function runForever(config, client, log, signal) {
|
|
|
73
68
|
}
|
|
74
69
|
async function main() {
|
|
75
70
|
const config = resolveClaudeDaemonConfig(process.env);
|
|
76
|
-
const log = createLogger("daemon");
|
|
77
71
|
log.info(`boot: api=${config.apiUrl} pollMs=${config.pollIntervalMs} heartbeatMs=${config.heartbeatIntervalMs} agentBin=${config.agentBin}`);
|
|
78
72
|
log.info(`keepalive: bootstrapBackoffMs=${config.bootstrapBackoffMs} supervisorRestartBackoffMs=${config.supervisorRestartBackoffMs}`);
|
|
79
73
|
// The daemon talks to the API as a Machine — the bearer is mck_*.
|
|
@@ -110,11 +104,11 @@ runCLI(cliArgs)
|
|
|
110
104
|
if (result === "handled")
|
|
111
105
|
return;
|
|
112
106
|
main().catch((err) => {
|
|
113
|
-
|
|
107
|
+
log.error(`fatal: ${formatError(err)}`);
|
|
114
108
|
process.exitCode = 1;
|
|
115
109
|
});
|
|
116
110
|
})
|
|
117
111
|
.catch((err) => {
|
|
118
|
-
|
|
112
|
+
log.error(`fatal: ${formatError(err)}`);
|
|
119
113
|
process.exitCode = 1;
|
|
120
114
|
});
|
package/dist/runtimes.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
export interface ProviderConfig {
|
|
2
|
+
llm_source?: string;
|
|
3
|
+
openai_api_key?: string;
|
|
4
|
+
openai_base_url?: string;
|
|
5
|
+
anthropic_auth_token?: string;
|
|
6
|
+
anthropic_base_url?: string;
|
|
7
|
+
}
|
|
1
8
|
export interface RuntimeAdapter {
|
|
2
9
|
bin: string;
|
|
3
|
-
buildEnv(baseEnv: NodeJS.ProcessEnv, agentId: string, orgId: string, apiKey: string, dirs: AgentDirs): NodeJS.ProcessEnv;
|
|
10
|
+
buildEnv(baseEnv: NodeJS.ProcessEnv, agentId: string, orgId: string, apiKey: string, dirs: AgentDirs, pc?: ProviderConfig): NodeJS.ProcessEnv;
|
|
4
11
|
}
|
|
5
12
|
export interface AgentDirs {
|
|
6
13
|
stateDir: string;
|
package/dist/runtimes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC;CAC/I;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAsHD,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAErE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAInD"}
|
package/dist/runtimes.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
function llmSource(pc) {
|
|
3
|
+
if (pc?.llm_source)
|
|
4
|
+
return pc.llm_source;
|
|
5
|
+
if (pc?.openai_api_key ||
|
|
6
|
+
pc?.openai_base_url ||
|
|
7
|
+
pc?.anthropic_auth_token ||
|
|
8
|
+
pc?.anthropic_base_url) {
|
|
9
|
+
return "custom";
|
|
10
|
+
}
|
|
11
|
+
return "parall";
|
|
12
|
+
}
|
|
13
|
+
function clearAllProviderCreds(env) {
|
|
14
|
+
delete env.ANTHROPIC_AUTH_TOKEN;
|
|
15
|
+
delete env.ANTHROPIC_BASE_URL;
|
|
16
|
+
delete env.ANTHROPIC_API_KEY;
|
|
17
|
+
delete env.OPENAI_API_KEY;
|
|
18
|
+
delete env.OPENAI_BASE_URL;
|
|
19
|
+
delete env.PRLL_CLAUDE_ALLOW_API_KEY;
|
|
20
|
+
}
|
|
1
21
|
const claudeCodeAdapter = {
|
|
2
22
|
bin: "parall-claude-agent",
|
|
3
|
-
buildEnv(baseEnv, agentId, orgId, apiKey, dirs) {
|
|
23
|
+
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
4
24
|
const env = { ...baseEnv };
|
|
25
|
+
clearAllProviderCreds(env);
|
|
5
26
|
env.PRLL_API_KEY = apiKey;
|
|
6
27
|
env.PRLL_ORG_ID = orgId;
|
|
7
28
|
env.AGENT_ID = agentId;
|
|
@@ -9,8 +30,19 @@ const claudeCodeAdapter = {
|
|
|
9
30
|
env.PRLL_CLAUDE_HOME = dirs.claudeHome;
|
|
10
31
|
env.PRLL_CLAUDE_STATE_DIR = dirs.stateDir;
|
|
11
32
|
env.PRLL_CLAUDE_WORKSPACE_DIR = dirs.workspaceDir;
|
|
12
|
-
|
|
33
|
+
const source = llmSource(pc);
|
|
34
|
+
if (source === "parall") {
|
|
13
35
|
env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
36
|
+
env.ANTHROPIC_BASE_URL = `${baseEnv.PRLL_API_URL}/api/llm`;
|
|
37
|
+
env.PRLL_CLAUDE_ALLOW_API_KEY = "1";
|
|
38
|
+
}
|
|
39
|
+
else if (source === "custom") {
|
|
40
|
+
if (pc?.anthropic_auth_token) {
|
|
41
|
+
env.ANTHROPIC_AUTH_TOKEN = pc.anthropic_auth_token;
|
|
42
|
+
env.PRLL_CLAUDE_ALLOW_API_KEY = "1";
|
|
43
|
+
}
|
|
44
|
+
if (pc?.anthropic_base_url)
|
|
45
|
+
env.ANTHROPIC_BASE_URL = pc.anthropic_base_url;
|
|
14
46
|
}
|
|
15
47
|
delete env.PRLL_DAEMON_MODE;
|
|
16
48
|
return env;
|
|
@@ -18,14 +50,27 @@ const claudeCodeAdapter = {
|
|
|
18
50
|
};
|
|
19
51
|
const codexAdapter = {
|
|
20
52
|
bin: "parall-codex-agent",
|
|
21
|
-
buildEnv(baseEnv, agentId, orgId, apiKey, dirs) {
|
|
53
|
+
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
22
54
|
const env = { ...baseEnv };
|
|
55
|
+
clearAllProviderCreds(env);
|
|
23
56
|
env.PRLL_API_KEY = apiKey;
|
|
24
57
|
env.PRLL_ORG_ID = orgId;
|
|
25
58
|
env.AGENT_ID = agentId;
|
|
26
59
|
env.PRLL_AGENT_ID = agentId;
|
|
27
60
|
env.PRLL_CODEX_STATE_DIR = dirs.stateDir;
|
|
28
61
|
env.PRLL_CODEX_WORKSPACE_DIR = dirs.workspaceDir;
|
|
62
|
+
env.PRLL_CODEX_HOME = path.join(dirs.stateDir, ".codex");
|
|
63
|
+
const source = llmSource(pc);
|
|
64
|
+
if (source === "parall") {
|
|
65
|
+
env.OPENAI_API_KEY = apiKey;
|
|
66
|
+
env.OPENAI_BASE_URL = `${baseEnv.PRLL_API_URL}/api/llm/v1`;
|
|
67
|
+
}
|
|
68
|
+
else if (source === "custom") {
|
|
69
|
+
if (pc?.openai_api_key)
|
|
70
|
+
env.OPENAI_API_KEY = pc.openai_api_key;
|
|
71
|
+
if (pc?.openai_base_url)
|
|
72
|
+
env.OPENAI_BASE_URL = pc.openai_base_url;
|
|
73
|
+
}
|
|
29
74
|
delete env.PRLL_DAEMON_MODE;
|
|
30
75
|
return env;
|
|
31
76
|
},
|
|
@@ -48,6 +93,7 @@ const openclawAdapter = {
|
|
|
48
93
|
bin: "parall-openclaw-agent",
|
|
49
94
|
buildEnv(baseEnv, agentId, orgId, apiKey, dirs) {
|
|
50
95
|
const env = { ...baseEnv };
|
|
96
|
+
clearAllProviderCreds(env);
|
|
51
97
|
env.PRLL_API_KEY = apiKey;
|
|
52
98
|
env.PRLL_ORG_ID = orgId;
|
|
53
99
|
env.AGENT_ID = agentId;
|
package/dist/supervisor.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
import type { GatewayLogger } from "@parall/agent-core";
|
|
1
2
|
import { ParallClient } from "@parall/sdk";
|
|
2
3
|
import { type ClaudeDaemonConfig } from "./config.js";
|
|
3
|
-
export interface DaemonLogger {
|
|
4
|
-
info(msg: string): void;
|
|
5
|
-
warn(msg: string): void;
|
|
6
|
-
error(msg: string): void;
|
|
7
|
-
}
|
|
8
4
|
/**
|
|
9
5
|
* Sleep that wakes early on abort. Returns true if the full delay elapsed,
|
|
10
6
|
* false if aborted. Used by bootstrap retry and the outer keepalive in
|
|
@@ -31,8 +27,9 @@ export declare class DaemonSupervisor {
|
|
|
31
27
|
private ws;
|
|
32
28
|
private running;
|
|
33
29
|
private machineOrgId;
|
|
30
|
+
private machineLlmSource;
|
|
34
31
|
private stopResolve;
|
|
35
|
-
constructor(config: ClaudeDaemonConfig, client: ParallClient, log:
|
|
32
|
+
constructor(config: ClaudeDaemonConfig, client: ParallClient, log: GatewayLogger);
|
|
36
33
|
/** Start the supervisor. Returns a promise that resolves on `stop()`. */
|
|
37
34
|
run(signal: AbortSignal): Promise<void>;
|
|
38
35
|
/** Disconnect WS, cancel timers, SIGTERM all children, await exit. */
|
|
@@ -47,6 +44,8 @@ export declare class DaemonSupervisor {
|
|
|
47
44
|
private migrateFlatLayout;
|
|
48
45
|
private handleAgentAttached;
|
|
49
46
|
private handleAgentDetached;
|
|
47
|
+
private refreshMachineConfig;
|
|
48
|
+
private respawnAllChildren;
|
|
50
49
|
private restartChildNow;
|
|
51
50
|
private spawnAgent;
|
|
52
51
|
private startChild;
|
package/dist/supervisor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAkL,MAAM,aAAa,CAAC;AAC3N,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,aAAa,CAAC;AASrB;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAa3E;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAyB5B;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IASzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAVtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,WAAW,CAA6B;gBAG7B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,aAAa;IAGrC,yEAAyE;IACnE,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA4E7C,sEAAsE;IAChE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YA6Bb,kBAAkB;YAqClB,aAAa;IAqD3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;YA6CX,mBAAmB;YA6BnB,mBAAmB;YAgBnB,oBAAoB;YAcpB,kBAAkB;YAYlB,eAAe;YAcf,UAAU;IAgDxB,OAAO,CAAC,UAAU;YAyEJ,cAAc;IAyB5B,OAAO,CAAC,0BAA0B;CA8BnC"}
|
package/dist/supervisor.js
CHANGED
|
@@ -49,6 +49,7 @@ export class DaemonSupervisor {
|
|
|
49
49
|
ws = null;
|
|
50
50
|
running = false;
|
|
51
51
|
machineOrgId = null;
|
|
52
|
+
machineLlmSource = "parall";
|
|
52
53
|
stopResolve = null;
|
|
53
54
|
constructor(config, client, log) {
|
|
54
55
|
this.config = config;
|
|
@@ -85,7 +86,10 @@ export class DaemonSupervisor {
|
|
|
85
86
|
});
|
|
86
87
|
this.ws.on("machine.hello", (_data) => {
|
|
87
88
|
this.log.info("machine WS connected (machine.hello)");
|
|
88
|
-
void
|
|
89
|
+
void (async () => {
|
|
90
|
+
await this.refreshMachineConfig();
|
|
91
|
+
await this.fullReconcile();
|
|
92
|
+
})();
|
|
89
93
|
});
|
|
90
94
|
this.ws.on("machine.agent.attached", (data) => {
|
|
91
95
|
this.log.info(`WS: agent ${data.agent_id} attached`);
|
|
@@ -95,6 +99,14 @@ export class DaemonSupervisor {
|
|
|
95
99
|
this.log.info(`WS: agent ${data.agent_id} detached`);
|
|
96
100
|
void this.handleAgentDetached(data.agent_id);
|
|
97
101
|
});
|
|
102
|
+
this.ws.on("machine.config.updated", (data) => {
|
|
103
|
+
const newSource = data.llm_source ?? "parall";
|
|
104
|
+
if (newSource !== this.machineLlmSource) {
|
|
105
|
+
this.log.info(`WS: llm_source changed ${this.machineLlmSource} → ${newSource}, respawning all agents`);
|
|
106
|
+
this.machineLlmSource = newSource;
|
|
107
|
+
void this.respawnAllChildren();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
98
110
|
this.ws.on("machine.stop", (data) => {
|
|
99
111
|
this.log.info(`WS: machine.stop received (reason=${data.reason ?? "none"})`);
|
|
100
112
|
void this.stop();
|
|
@@ -143,6 +155,7 @@ export class DaemonSupervisor {
|
|
|
143
155
|
try {
|
|
144
156
|
const machine = await this.client.getMachineSelf();
|
|
145
157
|
this.machineOrgId = machine.org_id;
|
|
158
|
+
this.machineLlmSource = machine.llm_source ?? "parall";
|
|
146
159
|
this.log.info(`daemon online — machine_id=${machine.id} org=${machine.org_id} label=${machine.label}`);
|
|
147
160
|
return true;
|
|
148
161
|
}
|
|
@@ -305,6 +318,31 @@ export class DaemonSupervisor {
|
|
|
305
318
|
this.children.delete(agentId);
|
|
306
319
|
}
|
|
307
320
|
// ---- Spawn / restart ----
|
|
321
|
+
async refreshMachineConfig() {
|
|
322
|
+
try {
|
|
323
|
+
const machine = await this.client.getMachineSelf();
|
|
324
|
+
const newSource = machine.llm_source ?? "parall";
|
|
325
|
+
if (newSource !== this.machineLlmSource) {
|
|
326
|
+
this.log.info(`machine config refreshed: llm_source ${this.machineLlmSource} → ${newSource}`);
|
|
327
|
+
this.machineLlmSource = newSource;
|
|
328
|
+
await this.respawnAllChildren();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
this.log.warn(`refreshMachineConfig failed: ${String(err)}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
async respawnAllChildren() {
|
|
336
|
+
const states = [...this.children.values()];
|
|
337
|
+
for (const state of states) {
|
|
338
|
+
await this.terminateChild(state);
|
|
339
|
+
}
|
|
340
|
+
for (const state of states) {
|
|
341
|
+
if (!state.shuttingDown && this.running) {
|
|
342
|
+
await this.restartChildNow(state, "llm_source changed");
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
308
346
|
async restartChildNow(state, reason) {
|
|
309
347
|
if (!this.running || state.shuttingDown || state.child || state.restartTimer) {
|
|
310
348
|
return;
|
|
@@ -357,6 +395,7 @@ export class DaemonSupervisor {
|
|
|
357
395
|
runtimeType,
|
|
358
396
|
workspacePath: workspaceDir,
|
|
359
397
|
claudeHome,
|
|
398
|
+
providerConfig: attached.provider_config ?? { llm_source: this.machineLlmSource },
|
|
360
399
|
child: null,
|
|
361
400
|
credential,
|
|
362
401
|
restartAttempts: 0,
|
|
@@ -380,7 +419,7 @@ export class DaemonSupervisor {
|
|
|
380
419
|
workspaceDir: state.workspacePath,
|
|
381
420
|
claudeHome: state.claudeHome,
|
|
382
421
|
};
|
|
383
|
-
const env = adapter.buildEnv({ ...process.env, PRLL_API_URL: this.config.apiUrl }, state.agentId, state.orgId, state.credential.api_key, dirs);
|
|
422
|
+
const env = adapter.buildEnv({ ...process.env, PRLL_API_URL: this.config.apiUrl }, state.agentId, state.orgId, state.credential.api_key, dirs, state.providerConfig);
|
|
384
423
|
this.log.info(`spawning agent ${state.agentId} runtime=${state.runtimeType} bin=${adapter.bin} (attempt ${state.restartAttempts + 1})`);
|
|
385
424
|
const child = spawn(adapter.bin, [], {
|
|
386
425
|
env,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/daemon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.29.0",
|
|
4
4
|
"description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"main": "./bundle/parall-daemon.js",
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"bin": {
|
|
15
|
+
"daemon": "./bundle/parall-daemon.js",
|
|
15
16
|
"parall-daemon": "./bundle/parall-daemon.js",
|
|
16
17
|
"parall-claude-agent": "./bundle/parall-claude-agent.js",
|
|
17
18
|
"parall-codex-agent": "./bundle/parall-codex-agent.js",
|
|
@@ -28,10 +29,11 @@
|
|
|
28
29
|
"dist"
|
|
29
30
|
],
|
|
30
31
|
"dependencies": {
|
|
31
|
-
"@parall/
|
|
32
|
-
"@parall/
|
|
33
|
-
"@parall/
|
|
34
|
-
"@parall/
|
|
32
|
+
"@parall/agent-core": "1.29.0",
|
|
33
|
+
"@parall/sdk": "1.29.0",
|
|
34
|
+
"@parall/claude-agent": "1.29.0",
|
|
35
|
+
"@parall/codex-agent": "1.29.0",
|
|
36
|
+
"@parall/openclaw-agent": "1.29.0"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
39
|
"@types/node": "^22.0.0",
|