@parall/daemon 1.29.2 → 1.30.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 +8 -8
- package/bundle/parall-claude-agent.js +122 -72
- package/bundle/parall-codex-agent.js +128 -83
- package/bundle/parall-daemon.js +261 -105
- package/dist/filesystem.d.ts +7 -0
- package/dist/filesystem.d.ts.map +1 -0
- package/dist/filesystem.js +118 -0
- package/dist/supervisor.d.ts +1 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +30 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +2 -1
- package/package.json +6 -6
|
@@ -428,9 +428,13 @@ function createLogger(prefix) {
|
|
|
428
428
|
return {
|
|
429
429
|
info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
430
430
|
warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
431
|
-
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`)
|
|
431
|
+
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
432
|
+
child: (sub) => createLogger(`${prefix}:${sub}`)
|
|
432
433
|
};
|
|
433
434
|
}
|
|
435
|
+
function childLogger(logger, sub) {
|
|
436
|
+
return logger.child ? logger.child(sub) : logger;
|
|
437
|
+
}
|
|
434
438
|
|
|
435
439
|
// ts/agent-core/dist/gateway-base.js
|
|
436
440
|
import * as os from "node:os";
|
|
@@ -513,6 +517,7 @@ var ENDPOINTS = {
|
|
|
513
517
|
AGENT_ACTIVITY: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/activity`,
|
|
514
518
|
AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
|
|
515
519
|
AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
|
|
520
|
+
AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
|
|
516
521
|
AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
|
|
517
522
|
AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
|
|
518
523
|
AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
|
|
@@ -551,6 +556,7 @@ var ENDPOINTS = {
|
|
|
551
556
|
MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
|
|
552
557
|
MACHINE_RUNTIME_AUTH_SESSIONS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions`,
|
|
553
558
|
MACHINE_RUNTIME_AUTH_SESSION_COMPLETE: (orgId, machineId, sessionId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions/${sessionId}/complete`,
|
|
559
|
+
MACHINE_BROWSE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/browse`,
|
|
554
560
|
// Machine self-control-plane (mck_-scoped). The bearer token implicitly
|
|
555
561
|
// identifies the Machine, so there is no `:mid` URL parameter — these are
|
|
556
562
|
// "self" routes called by the daemon for its own host.
|
|
@@ -560,6 +566,7 @@ var ENDPOINTS = {
|
|
|
560
566
|
MACHINES_ME_AGENT_LAUNCH_CREDENTIAL: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/launch-credential`,
|
|
561
567
|
MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/workspace-state`,
|
|
562
568
|
MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
|
|
569
|
+
MACHINES_ME_BROWSE_RESPONSE: (requestId) => `${API_BASE}/machines/me/browse-response/${requestId}`,
|
|
563
570
|
// Tasks (org-scoped)
|
|
564
571
|
TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
|
|
565
572
|
TASK: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}`,
|
|
@@ -739,7 +746,9 @@ var WS_EVENTS = {
|
|
|
739
746
|
MACHINE_AGENT_ATTACHED: "machine.agent.attached",
|
|
740
747
|
MACHINE_AGENT_DETACHED: "machine.agent.detached",
|
|
741
748
|
MACHINE_STOP: "machine.stop",
|
|
742
|
-
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested"
|
|
749
|
+
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested",
|
|
750
|
+
MACHINE_FILESYSTEM_BROWSE: "machine.filesystem.browse",
|
|
751
|
+
AGENT_NEW_SESSION: "agent.new_session"
|
|
743
752
|
};
|
|
744
753
|
|
|
745
754
|
// ts/sdk/dist/client.js
|
|
@@ -1285,6 +1294,9 @@ var ParallClient = class _ParallClient {
|
|
|
1285
1294
|
return this.request("GET", ENDPOINTS.AGENT_ME(orgId));
|
|
1286
1295
|
}
|
|
1287
1296
|
// ---- Agent Sessions (org-scoped) ----
|
|
1297
|
+
async requestNewAgentSession(orgId, agentId) {
|
|
1298
|
+
return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
|
|
1299
|
+
}
|
|
1288
1300
|
async createAgentSession(orgId, agentId, req) {
|
|
1289
1301
|
return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
|
|
1290
1302
|
}
|
|
@@ -1484,9 +1496,15 @@ var ParallClient = class _ParallClient {
|
|
|
1484
1496
|
async getMachineWsTicket() {
|
|
1485
1497
|
return this.request("POST", ENDPOINTS.MACHINES_ME_WS_TICKET);
|
|
1486
1498
|
}
|
|
1499
|
+
async postBrowseResponse(requestId, response) {
|
|
1500
|
+
return this.request("POST", ENDPOINTS.MACHINES_ME_BROWSE_RESPONSE(requestId), response);
|
|
1501
|
+
}
|
|
1487
1502
|
async resizeMachine(orgId, machineId, spec) {
|
|
1488
1503
|
return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
|
|
1489
1504
|
}
|
|
1505
|
+
async browseMachineFilesystem(orgId, machineId, path9) {
|
|
1506
|
+
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path9 }, void 0, false, { timeoutMs: 15e3 });
|
|
1507
|
+
}
|
|
1490
1508
|
/** Create a new machine key. Returns the raw key string (shown once) + metadata. */
|
|
1491
1509
|
async createMachineKey(orgId, machineId, name) {
|
|
1492
1510
|
return this.request("POST", ENDPOINTS.MACHINE_KEYS(orgId, machineId), name ? { name } : void 0);
|
|
@@ -2399,6 +2417,7 @@ var ParallAgentGateway = class {
|
|
|
2399
2417
|
shuttingDown = false;
|
|
2400
2418
|
inFlightDispatches = 0;
|
|
2401
2419
|
drainResolvers = [];
|
|
2420
|
+
pendingRestartNotification = null;
|
|
2402
2421
|
DISPATCHED_MESSAGES_CAP = 5e3;
|
|
2403
2422
|
COLD_START_WINDOW_MS;
|
|
2404
2423
|
// SHUTDOWN_DEADLINE_MS is read by waitForDrain via the configured value
|
|
@@ -2413,7 +2432,7 @@ var ParallAgentGateway = class {
|
|
|
2413
2432
|
async run(abortSignal) {
|
|
2414
2433
|
const { ws, log: log2 } = this.opts;
|
|
2415
2434
|
ws.onStateChange((state) => {
|
|
2416
|
-
log2?.info(`
|
|
2435
|
+
log2?.info(`connection state \u2192 ${state}`);
|
|
2417
2436
|
});
|
|
2418
2437
|
ws.on("hello", async (data) => {
|
|
2419
2438
|
await this.handleHello(data);
|
|
@@ -2442,16 +2461,29 @@ var ParallAgentGateway = class {
|
|
|
2442
2461
|
await this.handleMessage(data);
|
|
2443
2462
|
});
|
|
2444
2463
|
ws.on("agent_config.update", async (data) => {
|
|
2445
|
-
this.opts.log?.info(`
|
|
2464
|
+
this.opts.log?.info(`config update notification (version=${data.version})`);
|
|
2446
2465
|
try {
|
|
2447
2466
|
await this.opts.onConfigUpdate?.(data);
|
|
2448
2467
|
} catch (err) {
|
|
2449
|
-
this.opts.log?.warn(`
|
|
2468
|
+
this.opts.log?.warn(`config update failed: ${String(err)}`);
|
|
2469
|
+
}
|
|
2470
|
+
});
|
|
2471
|
+
ws.on("agent.new_session", async (data) => {
|
|
2472
|
+
const prevId = data.previous_session_id ?? "";
|
|
2473
|
+
this.opts.log?.info(`new session signal received (previous=${prevId})`);
|
|
2474
|
+
this.sessionBindings.clear();
|
|
2475
|
+
if (prevId) {
|
|
2476
|
+
this.pendingRestartNotification = `[Harness Notification] This is a fresh session. Your previous session (${prevId}) was ended by the user and you have been restarted.`;
|
|
2477
|
+
}
|
|
2478
|
+
try {
|
|
2479
|
+
await this.opts.onNewSession?.(prevId);
|
|
2480
|
+
} catch (err) {
|
|
2481
|
+
this.opts.log?.warn(`onNewSession callback failed: ${String(err)}`);
|
|
2450
2482
|
}
|
|
2451
2483
|
});
|
|
2452
2484
|
ws.on("recovery.overflow", () => {
|
|
2453
|
-
this.opts.log?.warn(`
|
|
2454
|
-
this.catchUpFromDispatch().catch((err) => this.opts.log?.warn(`
|
|
2485
|
+
this.opts.log?.warn(`recovery.overflow \u2014 triggering full catch-up`);
|
|
2486
|
+
this.catchUpFromDispatch().catch((err) => this.opts.log?.warn(`overflow catch-up failed: ${String(err)}`));
|
|
2455
2487
|
});
|
|
2456
2488
|
ws.on("task.assigned", async (data) => {
|
|
2457
2489
|
if (data.assignee_id !== this.opts.agentUserId)
|
|
@@ -2465,7 +2497,7 @@ var ParallAgentGateway = class {
|
|
|
2465
2497
|
});
|
|
2466
2498
|
}
|
|
2467
2499
|
} catch (err) {
|
|
2468
|
-
this.opts.log?.error(`
|
|
2500
|
+
this.opts.log?.error(`task dispatch failed for ${data.id}: ${String(err)}`);
|
|
2469
2501
|
}
|
|
2470
2502
|
});
|
|
2471
2503
|
ws.on("dispatch.new", async (data) => {
|
|
@@ -2479,7 +2511,7 @@ var ParallAgentGateway = class {
|
|
|
2479
2511
|
});
|
|
2480
2512
|
}
|
|
2481
2513
|
} catch (err) {
|
|
2482
|
-
this.opts.log?.error(`
|
|
2514
|
+
this.opts.log?.error(`task comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2483
2515
|
}
|
|
2484
2516
|
} else if (data.event_type === "task_update") {
|
|
2485
2517
|
if (!data.task_id)
|
|
@@ -2491,7 +2523,7 @@ var ParallAgentGateway = class {
|
|
|
2491
2523
|
});
|
|
2492
2524
|
}
|
|
2493
2525
|
} catch (err) {
|
|
2494
|
-
this.opts.log?.error(`
|
|
2526
|
+
this.opts.log?.error(`task update dispatch failed for ${data.task_id}: ${String(err)}`);
|
|
2495
2527
|
}
|
|
2496
2528
|
} else if (data.event_type === "schedule.fire") {
|
|
2497
2529
|
if (!data.source_id)
|
|
@@ -2503,7 +2535,7 @@ var ParallAgentGateway = class {
|
|
|
2503
2535
|
});
|
|
2504
2536
|
}
|
|
2505
2537
|
} catch (err) {
|
|
2506
|
-
this.opts.log?.error(`
|
|
2538
|
+
this.opts.log?.error(`schedule fire dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2507
2539
|
}
|
|
2508
2540
|
} else if (data.event_type === "approval_decided") {
|
|
2509
2541
|
if (!data.source_id)
|
|
@@ -2515,13 +2547,13 @@ var ParallAgentGateway = class {
|
|
|
2515
2547
|
});
|
|
2516
2548
|
}
|
|
2517
2549
|
} catch (err) {
|
|
2518
|
-
this.opts.log?.error(`
|
|
2550
|
+
this.opts.log?.error(`approval decided dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2519
2551
|
}
|
|
2520
2552
|
} else if (data.event_type !== "message" && data.event_type !== "task_assign") {
|
|
2521
|
-
this.opts.log?.info(`
|
|
2553
|
+
this.opts.log?.info(`dispatch.new with unhandled event_type=${String(data.event_type)} (id=${data.id}) \u2014 no-op`);
|
|
2522
2554
|
}
|
|
2523
2555
|
});
|
|
2524
|
-
this.opts.log?.info(`
|
|
2556
|
+
this.opts.log?.info(`connecting to ${this.opts.connectionLabel ?? "Parall WS"}...`);
|
|
2525
2557
|
await ws.connect();
|
|
2526
2558
|
return new Promise((resolve3) => {
|
|
2527
2559
|
abortSignal.addEventListener("abort", async () => {
|
|
@@ -2635,7 +2667,7 @@ var ParallAgentGateway = class {
|
|
|
2635
2667
|
}
|
|
2636
2668
|
});
|
|
2637
2669
|
} catch (err) {
|
|
2638
|
-
this.opts.log?.warn(`
|
|
2670
|
+
this.opts.log?.warn(`failed to create input step: ${String(err)}`);
|
|
2639
2671
|
}
|
|
2640
2672
|
}
|
|
2641
2673
|
async createRuntimeStep(sessionId, event, runtimeEvent, stepIdFilePath, contextFilePath) {
|
|
@@ -2713,12 +2745,12 @@ var ParallAgentGateway = class {
|
|
|
2713
2745
|
target_type: target.target_type,
|
|
2714
2746
|
target_id: target.target_id,
|
|
2715
2747
|
content: { text: runtimeEvent.message, suppressed: false },
|
|
2716
|
-
projection:
|
|
2748
|
+
projection: false
|
|
2717
2749
|
});
|
|
2718
2750
|
break;
|
|
2719
2751
|
}
|
|
2720
2752
|
} catch (err) {
|
|
2721
|
-
this.opts.log?.warn(`
|
|
2753
|
+
this.opts.log?.warn(`failed to create ${runtimeEvent.type} step: ${String(err)}`);
|
|
2722
2754
|
}
|
|
2723
2755
|
}
|
|
2724
2756
|
writeContextFile(filePath, ctx) {
|
|
@@ -2726,7 +2758,7 @@ var ParallAgentGateway = class {
|
|
|
2726
2758
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2727
2759
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2728
2760
|
} catch (err) {
|
|
2729
|
-
this.opts.log?.warn(`
|
|
2761
|
+
this.opts.log?.warn(`failed to write context file ${filePath}: ${String(err)}`);
|
|
2730
2762
|
}
|
|
2731
2763
|
}
|
|
2732
2764
|
updateContextFileStepId(filePath, stepId) {
|
|
@@ -2736,7 +2768,7 @@ var ParallAgentGateway = class {
|
|
|
2736
2768
|
ctx.step_id = stepId;
|
|
2737
2769
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2738
2770
|
} catch (err) {
|
|
2739
|
-
this.opts.log?.warn(`
|
|
2771
|
+
this.opts.log?.warn(`failed to update context file step_id ${filePath}: ${String(err)}`);
|
|
2740
2772
|
}
|
|
2741
2773
|
}
|
|
2742
2774
|
updateContextFileSessionId(filePath, sessionId) {
|
|
@@ -2746,7 +2778,7 @@ var ParallAgentGateway = class {
|
|
|
2746
2778
|
ctx.session_id = sessionId;
|
|
2747
2779
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2748
2780
|
} catch (err) {
|
|
2749
|
-
this.opts.log?.warn(`
|
|
2781
|
+
this.opts.log?.warn(`failed to update context file session_id ${filePath}: ${String(err)}`);
|
|
2750
2782
|
}
|
|
2751
2783
|
}
|
|
2752
2784
|
/** @deprecated Use writeContextFile / updateContextFileStepId. */
|
|
@@ -2755,7 +2787,7 @@ var ParallAgentGateway = class {
|
|
|
2755
2787
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2756
2788
|
fs.writeFileSync(filePath, stepId, "utf8");
|
|
2757
2789
|
} catch (err) {
|
|
2758
|
-
this.opts.log?.warn(`
|
|
2790
|
+
this.opts.log?.warn(`failed to write step id file ${filePath}: ${String(err)}`);
|
|
2759
2791
|
}
|
|
2760
2792
|
}
|
|
2761
2793
|
/** @deprecated Use writeContextFile / updateContextFileStepId. */
|
|
@@ -2812,9 +2844,13 @@ var ParallAgentGateway = class {
|
|
|
2812
2844
|
// catch-up on the replacement pod — otherwise we silently drop work.
|
|
2813
2845
|
async runDispatch(event, sessionKey, bodyForAgent, earlierEvents = [], captureText) {
|
|
2814
2846
|
if (this.shuttingDown) {
|
|
2815
|
-
this.opts.log?.info(`
|
|
2847
|
+
this.opts.log?.info(`skipping dispatch for ${event.messageId} (shutting down) \u2014 leaving unacked for catch-up on replacement pod`);
|
|
2816
2848
|
return false;
|
|
2817
2849
|
}
|
|
2850
|
+
if (this.pendingRestartNotification) {
|
|
2851
|
+
bodyForAgent = this.pendingRestartNotification + "\n\n---\n\n" + bodyForAgent;
|
|
2852
|
+
this.pendingRestartNotification = null;
|
|
2853
|
+
}
|
|
2818
2854
|
setSessionChatId(sessionKey, event.targetId);
|
|
2819
2855
|
setSessionMessageId(sessionKey, event.messageId);
|
|
2820
2856
|
setDispatchMessageId(sessionKey, event.messageId);
|
|
@@ -2944,7 +2980,7 @@ var ParallAgentGateway = class {
|
|
|
2944
2980
|
item.resolve(true);
|
|
2945
2981
|
}
|
|
2946
2982
|
} catch (err) {
|
|
2947
|
-
this.opts.log?.error(`
|
|
2983
|
+
this.opts.log?.error(`fork dispatch failed for ${last.messageId}: ${String(err)}`);
|
|
2948
2984
|
for (const item of items) {
|
|
2949
2985
|
item.resolve(false);
|
|
2950
2986
|
}
|
|
@@ -2962,7 +2998,7 @@ var ParallAgentGateway = class {
|
|
|
2962
2998
|
try {
|
|
2963
2999
|
historyPath = this.opts.dispatchAdapter.getSessionHistoryPath?.(fork.fork.sessionKey);
|
|
2964
3000
|
} catch (err) {
|
|
2965
|
-
this.opts.log?.warn?.(`
|
|
3001
|
+
this.opts.log?.warn?.(`failed to resolve fork history path: ${String(err)}`);
|
|
2966
3002
|
}
|
|
2967
3003
|
this.dispatchState.pendingForkResults.push({
|
|
2968
3004
|
forkSessionKey: fork.fork.sessionKey,
|
|
@@ -3013,7 +3049,7 @@ var ParallAgentGateway = class {
|
|
|
3013
3049
|
try {
|
|
3014
3050
|
while (this.dispatchState.mainBuffer.length > 0) {
|
|
3015
3051
|
if (this.shuttingDown) {
|
|
3016
|
-
this.opts.log?.info(`
|
|
3052
|
+
this.opts.log?.info(`drainMainBuffer halted (shutting down) \u2014 ${this.dispatchState.mainBuffer.length} buffered, ${this.dispatchState.pendingForkResults.length} pending fork results left for catch-up`);
|
|
3017
3053
|
break;
|
|
3018
3054
|
}
|
|
3019
3055
|
const targetId = this.dispatchState.mainBuffer[0].targetId;
|
|
@@ -3079,7 +3115,7 @@ var ParallAgentGateway = class {
|
|
|
3079
3115
|
this.dispatchState.mainBuffer.push(event);
|
|
3080
3116
|
if (this.dispatchState.mainCurrentTargetId === event.targetId && await this.opts.dispatchAdapter.enqueueDuringDispatch?.(this.opts.runtimeKey, buildEventBody(event))) {
|
|
3081
3117
|
this.startInjectedTyping(event);
|
|
3082
|
-
this.opts.log?.info(`
|
|
3118
|
+
this.opts.log?.info(`steer injected for ${event.messageId} (will drain for bookkeeping)`);
|
|
3083
3119
|
}
|
|
3084
3120
|
if (!this.dispatchState.mainDispatching && !this.draining && this.dispatchState.mainBuffer.length > 0) {
|
|
3085
3121
|
this.dispatchState.mainDispatching = true;
|
|
@@ -3108,7 +3144,7 @@ var ParallAgentGateway = class {
|
|
|
3108
3144
|
preDispatchBranchPoint: this.dispatchState.mainPreDispatchBranchPoint
|
|
3109
3145
|
});
|
|
3110
3146
|
if (!fork) {
|
|
3111
|
-
this.opts.log?.warn(`
|
|
3147
|
+
this.opts.log?.warn(`fork failed, buffering event for main session`);
|
|
3112
3148
|
this.dispatchState.mainBuffer.push(event);
|
|
3113
3149
|
return false;
|
|
3114
3150
|
}
|
|
@@ -3124,7 +3160,7 @@ var ParallAgentGateway = class {
|
|
|
3124
3160
|
activeFork.queue.push({ event, resolve: resolve3 });
|
|
3125
3161
|
});
|
|
3126
3162
|
this.runForkDrainLoop(activeFork).catch((err) => {
|
|
3127
|
-
this.opts.log?.error(`
|
|
3163
|
+
this.opts.log?.error(`fork drain loop error: ${String(err)}`);
|
|
3128
3164
|
});
|
|
3129
3165
|
return firstEventPromise;
|
|
3130
3166
|
}
|
|
@@ -3144,7 +3180,7 @@ var ParallAgentGateway = class {
|
|
|
3144
3180
|
this.chatInfoMap.set(chatId, chatInfo);
|
|
3145
3181
|
return chatInfo;
|
|
3146
3182
|
} catch (err) {
|
|
3147
|
-
this.opts.log?.warn(`
|
|
3183
|
+
this.opts.log?.warn(`failed to resolve chat ${chatId}: ${String(err)}`);
|
|
3148
3184
|
return null;
|
|
3149
3185
|
}
|
|
3150
3186
|
}
|
|
@@ -3217,7 +3253,7 @@ var ParallAgentGateway = class {
|
|
|
3217
3253
|
this.dispatchedMessages.delete(data.id);
|
|
3218
3254
|
}
|
|
3219
3255
|
} catch (err) {
|
|
3220
|
-
this.opts.log?.error(`
|
|
3256
|
+
this.opts.log?.error(`event dispatch failed for ${data.id}: ${String(err)}`);
|
|
3221
3257
|
this.dispatchedMessages.delete(data.id);
|
|
3222
3258
|
}
|
|
3223
3259
|
}
|
|
@@ -3226,11 +3262,11 @@ var ParallAgentGateway = class {
|
|
|
3226
3262
|
return false;
|
|
3227
3263
|
const dedupeKey = `${task.id}:${task.updated_at}`;
|
|
3228
3264
|
if (this.dispatchedTasks.has(dedupeKey)) {
|
|
3229
|
-
this.opts.log?.info(`
|
|
3265
|
+
this.opts.log?.info(`skipping already-dispatched task ${task.identifier ?? task.id}`);
|
|
3230
3266
|
return false;
|
|
3231
3267
|
}
|
|
3232
3268
|
this.dispatchedTasks.add(dedupeKey);
|
|
3233
|
-
this.opts.log?.info(`
|
|
3269
|
+
this.opts.log?.info(`task assigned: ${task.identifier ?? task.id} "${task.title}"`);
|
|
3234
3270
|
const parts = [`Title: ${task.title}`];
|
|
3235
3271
|
parts.push(`Status: ${task.status}`, `Priority: ${task.priority}`);
|
|
3236
3272
|
if (task.project_id)
|
|
@@ -3271,7 +3307,7 @@ var ParallAgentGateway = class {
|
|
|
3271
3307
|
const isAssignee = task.assignee_id === this.opts.agentUserId;
|
|
3272
3308
|
const isCreatorUpdate = opts.allowCreator === true && task.creator_id === this.opts.agentUserId;
|
|
3273
3309
|
if (!isAssignee && !isCreatorUpdate) {
|
|
3274
|
-
this.opts.log?.info(`
|
|
3310
|
+
this.opts.log?.info(`skipping stale task dispatch ${ackSourceId ?? taskId} \u2014 assigned to ${task.assignee_id}, creator ${task.creator_id}`);
|
|
3275
3311
|
return true;
|
|
3276
3312
|
}
|
|
3277
3313
|
return this.handleTaskAssignment(task, ackSourceId);
|
|
@@ -3289,7 +3325,7 @@ var ParallAgentGateway = class {
|
|
|
3289
3325
|
} catch (err) {
|
|
3290
3326
|
const status = err?.status;
|
|
3291
3327
|
if (status === 404) {
|
|
3292
|
-
this.opts.log?.info(`
|
|
3328
|
+
this.opts.log?.info(`skipping deleted comment ${commentId}, acking stale dispatch`);
|
|
3293
3329
|
this.dispatchedTasks.delete(dedupeKey);
|
|
3294
3330
|
return true;
|
|
3295
3331
|
}
|
|
@@ -3301,7 +3337,7 @@ var ParallAgentGateway = class {
|
|
|
3301
3337
|
return true;
|
|
3302
3338
|
}
|
|
3303
3339
|
if (comment.hints?.no_reply) {
|
|
3304
|
-
this.opts.log?.info(`
|
|
3340
|
+
this.opts.log?.info(`skipping no_reply task comment ${commentId}, acking stale dispatch`);
|
|
3305
3341
|
this.dispatchedTasks.delete(dedupeKey);
|
|
3306
3342
|
return true;
|
|
3307
3343
|
}
|
|
@@ -3311,7 +3347,7 @@ var ParallAgentGateway = class {
|
|
|
3311
3347
|
} catch {
|
|
3312
3348
|
}
|
|
3313
3349
|
const taskLabel = task ? `${task.identifier ?? task.id} "${task.title}"` : taskId;
|
|
3314
|
-
this.opts.log?.info(`
|
|
3350
|
+
this.opts.log?.info(`task comment on ${taskLabel} by ${actorId ?? "unknown"}`);
|
|
3315
3351
|
const parts = [];
|
|
3316
3352
|
if (task) {
|
|
3317
3353
|
parts.push(`Task: ${task.title} (prll://${task.id})`);
|
|
@@ -3361,10 +3397,10 @@ var ParallAgentGateway = class {
|
|
|
3361
3397
|
} catch (err) {
|
|
3362
3398
|
const status = err?.status;
|
|
3363
3399
|
if (status === 404) {
|
|
3364
|
-
this.opts.log?.warn(`
|
|
3400
|
+
this.opts.log?.warn(`schedule run ${runId} not accessible (404), acking stale dispatch`);
|
|
3365
3401
|
return true;
|
|
3366
3402
|
}
|
|
3367
|
-
this.opts.log?.warn(`
|
|
3403
|
+
this.opts.log?.warn(`schedule run fetch failed for ${runId}, leaving pending: ${String(err)}`);
|
|
3368
3404
|
return false;
|
|
3369
3405
|
}
|
|
3370
3406
|
if (!run)
|
|
@@ -3378,7 +3414,7 @@ var ParallAgentGateway = class {
|
|
|
3378
3414
|
if (this.dispatchedTasks.has(dedupeKey))
|
|
3379
3415
|
return false;
|
|
3380
3416
|
this.dispatchedTasks.add(dedupeKey);
|
|
3381
|
-
this.opts.log?.info(`
|
|
3417
|
+
this.opts.log?.info(`schedule fired: ${run.id} (schedule ${run.schedule_id})`);
|
|
3382
3418
|
const event = {
|
|
3383
3419
|
type: "schedule",
|
|
3384
3420
|
// Route by schedule_id (not attached chat_id) so concurrent fires of
|
|
@@ -3415,10 +3451,10 @@ var ParallAgentGateway = class {
|
|
|
3415
3451
|
} catch (err) {
|
|
3416
3452
|
const status = err?.status;
|
|
3417
3453
|
if (status === 404 || status === 403) {
|
|
3418
|
-
this.opts.log?.warn(`
|
|
3454
|
+
this.opts.log?.warn(`approval ${approvalId} not accessible (${status}), acking stale dispatch`);
|
|
3419
3455
|
return true;
|
|
3420
3456
|
}
|
|
3421
|
-
this.opts.log?.warn(`
|
|
3457
|
+
this.opts.log?.warn(`approval fetch failed for ${approvalId}, leaving pending: ${String(err)}`);
|
|
3422
3458
|
return false;
|
|
3423
3459
|
}
|
|
3424
3460
|
if (!approval)
|
|
@@ -3429,7 +3465,7 @@ var ParallAgentGateway = class {
|
|
|
3429
3465
|
if (this.dispatchedTasks.has(dedupeKey))
|
|
3430
3466
|
return false;
|
|
3431
3467
|
this.dispatchedTasks.add(dedupeKey);
|
|
3432
|
-
this.opts.log?.info(`
|
|
3468
|
+
this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
|
|
3433
3469
|
const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
|
|
3434
3470
|
const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
|
|
3435
3471
|
const body = `${statusLabel}: ${approval.title}${execInfo}`;
|
|
@@ -3479,14 +3515,14 @@ var ParallAgentGateway = class {
|
|
|
3479
3515
|
try {
|
|
3480
3516
|
dispatched = await this.handleTaskDispatch(item.task_id, item.source_id ?? item.task_id);
|
|
3481
3517
|
} catch (err) {
|
|
3482
|
-
this.opts.log?.warn(`
|
|
3518
|
+
this.opts.log?.warn(`catch-up task fetch failed for ${item.task_id}, leaving pending: ${String(err)}`);
|
|
3483
3519
|
continue;
|
|
3484
3520
|
}
|
|
3485
3521
|
} else if (item.event_type === "task_update" && item.task_id) {
|
|
3486
3522
|
try {
|
|
3487
3523
|
dispatched = await this.handleTaskDispatch(item.task_id, item.source_id ?? item.task_id, { allowCreator: true });
|
|
3488
3524
|
} catch (err) {
|
|
3489
|
-
this.opts.log?.warn(`
|
|
3525
|
+
this.opts.log?.warn(`catch-up task fetch failed for ${item.task_id}, leaving pending: ${String(err)}`);
|
|
3490
3526
|
continue;
|
|
3491
3527
|
}
|
|
3492
3528
|
} else if (item.event_type === "task_comment" && item.source_id && item.task_id) {
|
|
@@ -3508,7 +3544,7 @@ var ParallAgentGateway = class {
|
|
|
3508
3544
|
msg = null;
|
|
3509
3545
|
} else {
|
|
3510
3546
|
msgFetchFailed = true;
|
|
3511
|
-
this.opts.log?.warn(`
|
|
3547
|
+
this.opts.log?.warn(`catch-up message fetch failed for ${item.source_id}, leaving pending: ${String(err)}`);
|
|
3512
3548
|
}
|
|
3513
3549
|
}
|
|
3514
3550
|
if (msgFetchFailed) {
|
|
@@ -3539,13 +3575,13 @@ var ParallAgentGateway = class {
|
|
|
3539
3575
|
});
|
|
3540
3576
|
}
|
|
3541
3577
|
} catch (err) {
|
|
3542
|
-
this.opts.log?.warn(`
|
|
3578
|
+
this.opts.log?.warn(`catch-up dispatch ${item.id} (${item.event_type}) failed: ${String(err)}`);
|
|
3543
3579
|
}
|
|
3544
3580
|
}
|
|
3545
3581
|
cursor = !this.shuttingDown && page.has_more ? page.next_cursor : void 0;
|
|
3546
3582
|
} while (cursor);
|
|
3547
3583
|
if (processed > 0 || skippedOld > 0) {
|
|
3548
|
-
this.opts.log?.info(`
|
|
3584
|
+
this.opts.log?.info(`dispatch catch-up: processed ${processed}, skipped ${skippedOld} old item(s)`);
|
|
3549
3585
|
}
|
|
3550
3586
|
}
|
|
3551
3587
|
async handleHello(data) {
|
|
@@ -3554,7 +3590,7 @@ var ParallAgentGateway = class {
|
|
|
3554
3590
|
const intervalSec = data.heartbeat_interval > 0 ? data.heartbeat_interval : 30;
|
|
3555
3591
|
try {
|
|
3556
3592
|
const count = await fetchAllChats(client, config.org_id, this.chatInfoMap);
|
|
3557
|
-
log2?.info(`
|
|
3593
|
+
log2?.info(`WebSocket connected, ${count} chats cached`);
|
|
3558
3594
|
await this.opts.onSessionReady?.({
|
|
3559
3595
|
activeSessionId: this.activeSessionId,
|
|
3560
3596
|
ws: this.opts.ws,
|
|
@@ -3568,7 +3604,7 @@ var ParallAgentGateway = class {
|
|
|
3568
3604
|
const expectedMs = intervalSec * 1e3;
|
|
3569
3605
|
const drift = now - this.lastHeartbeatAt - expectedMs;
|
|
3570
3606
|
if (drift > 15e3) {
|
|
3571
|
-
log2?.warn(`
|
|
3607
|
+
log2?.warn(`heartbeat drift ${drift}ms \u2014 event loop may be blocked`);
|
|
3572
3608
|
}
|
|
3573
3609
|
this.lastHeartbeatAt = now;
|
|
3574
3610
|
if (this.opts.ws.state !== "connected")
|
|
@@ -3584,10 +3620,10 @@ var ParallAgentGateway = class {
|
|
|
3584
3620
|
const isFirstHello = !this.hadSuccessfulHello;
|
|
3585
3621
|
this.hadSuccessfulHello = true;
|
|
3586
3622
|
this.catchUpFromDispatch(isFirstHello).catch((err) => {
|
|
3587
|
-
log2?.warn(`
|
|
3623
|
+
log2?.warn(`dispatch catch-up failed: ${String(err)}`);
|
|
3588
3624
|
});
|
|
3589
3625
|
} catch (err) {
|
|
3590
|
-
log2?.error(`
|
|
3626
|
+
log2?.error(`failed to fetch chats: ${String(err)}`);
|
|
3591
3627
|
}
|
|
3592
3628
|
}
|
|
3593
3629
|
// Resolves when in-flight dispatches hit 0 or the deadline elapses.
|
|
@@ -3613,12 +3649,12 @@ var ParallAgentGateway = class {
|
|
|
3613
3649
|
async shutdown() {
|
|
3614
3650
|
this.shuttingDown = true;
|
|
3615
3651
|
if (this.inFlightDispatches > 0) {
|
|
3616
|
-
this.opts.log?.info(`
|
|
3652
|
+
this.opts.log?.info(`draining ${this.inFlightDispatches} in-flight dispatch(es), deadline ${this.SHUTDOWN_DEADLINE_MS}ms`);
|
|
3617
3653
|
await this.waitForDrain(this.SHUTDOWN_DEADLINE_MS);
|
|
3618
3654
|
if (this.inFlightDispatches > 0) {
|
|
3619
|
-
this.opts.log?.warn(`
|
|
3655
|
+
this.opts.log?.warn(`drain deadline hit; ${this.inFlightDispatches} dispatch(es) still running \u2014 they will be killed by process exit`);
|
|
3620
3656
|
} else {
|
|
3621
|
-
this.opts.log?.info(`
|
|
3657
|
+
this.opts.log?.info(`drain complete`);
|
|
3622
3658
|
}
|
|
3623
3659
|
}
|
|
3624
3660
|
if (this.heartbeatTimer)
|
|
@@ -3629,7 +3665,7 @@ var ParallAgentGateway = class {
|
|
|
3629
3665
|
this.activeDispatches.clear();
|
|
3630
3666
|
await this.opts.onBeforeDisconnect?.();
|
|
3631
3667
|
this.opts.ws.disconnect();
|
|
3632
|
-
this.opts.log?.info(`
|
|
3668
|
+
this.opts.log?.info(`disconnected`);
|
|
3633
3669
|
}
|
|
3634
3670
|
};
|
|
3635
3671
|
|
|
@@ -5149,7 +5185,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5149
5185
|
const pending = this.pendingInjections.get(sessionKey) ?? 0;
|
|
5150
5186
|
if (pending > 0) {
|
|
5151
5187
|
this.pendingInjections.delete(sessionKey);
|
|
5152
|
-
context.log?.info?.(`
|
|
5188
|
+
context.log?.info?.(`consuming ${pending} steer turn(s)`);
|
|
5153
5189
|
for (let i = 0; i < pending; i++) {
|
|
5154
5190
|
yield* this.consumeSteerTurn(sessionKey, context.log);
|
|
5155
5191
|
}
|
|
@@ -5166,7 +5202,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5166
5202
|
promptBody = prepared.body;
|
|
5167
5203
|
releasePreparedAttachments = pinLocalAttachmentPaths(prepared.attachments.images);
|
|
5168
5204
|
} catch (err) {
|
|
5169
|
-
context.log?.warn?.(`
|
|
5205
|
+
context.log?.warn?.(`failed to prepare local attachments: ${String(err)}`);
|
|
5170
5206
|
}
|
|
5171
5207
|
try {
|
|
5172
5208
|
yield* this.runTurn(sessionKey, promptBody, context.log);
|
|
@@ -5217,7 +5253,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5217
5253
|
async *consumeSteerTurn(sessionKey, log2) {
|
|
5218
5254
|
const state = this.processes.get(sessionKey);
|
|
5219
5255
|
if (!state || state.done) {
|
|
5220
|
-
throw new Error("
|
|
5256
|
+
throw new Error("process dead during steer consumption");
|
|
5221
5257
|
}
|
|
5222
5258
|
const groupKey = randomUUID();
|
|
5223
5259
|
const parserNext = state.parser.next();
|
|
@@ -5227,7 +5263,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5227
5263
|
]);
|
|
5228
5264
|
if (firstRead.kind === "timeout") {
|
|
5229
5265
|
state.steerReadPending = parserNext;
|
|
5230
|
-
log2?.info?.(`
|
|
5266
|
+
log2?.info?.(`steer turn timeout \u2014 steer was incorporated into previous turn`);
|
|
5231
5267
|
return;
|
|
5232
5268
|
}
|
|
5233
5269
|
let next = firstRead.result;
|
|
@@ -5235,7 +5271,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5235
5271
|
if (next.done) {
|
|
5236
5272
|
state.done = true;
|
|
5237
5273
|
this.processes.delete(sessionKey);
|
|
5238
|
-
throw new Error("
|
|
5274
|
+
throw new Error("process exited while consuming steer turn");
|
|
5239
5275
|
}
|
|
5240
5276
|
const parsed = next.value;
|
|
5241
5277
|
if (parsed.type === "session_id") {
|
|
@@ -5306,7 +5342,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5306
5342
|
const detail = state.handle.stderrChunks.join("").trim();
|
|
5307
5343
|
const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
|
|
5308
5344
|
if (detail) {
|
|
5309
|
-
log2?.warn?.(`
|
|
5345
|
+
log2?.warn?.(`subprocess stderr: ${detail}`);
|
|
5310
5346
|
}
|
|
5311
5347
|
if (!sawError) {
|
|
5312
5348
|
yield {
|
|
@@ -5350,7 +5386,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5350
5386
|
}
|
|
5351
5387
|
ensureProcess(sessionKey, log2) {
|
|
5352
5388
|
if (this.shuttingDown) {
|
|
5353
|
-
throw new Error("
|
|
5389
|
+
throw new Error("adapter shutting down, refusing new process");
|
|
5354
5390
|
}
|
|
5355
5391
|
const existing = this.processes.get(sessionKey);
|
|
5356
5392
|
if (existing && !existing.done) {
|
|
@@ -5373,7 +5409,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5373
5409
|
spawnProcess(sessionKey, log2) {
|
|
5374
5410
|
const args = this.buildArgs(sessionKey);
|
|
5375
5411
|
const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), { allowApiKey: this.opts.allowApiKey, effortLevel: this._effortLevel });
|
|
5376
|
-
log2?.info(`
|
|
5412
|
+
log2?.info(`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
|
|
5377
5413
|
const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
|
|
5378
5414
|
cwd: this.opts.workspaceDir,
|
|
5379
5415
|
env,
|
|
@@ -5628,6 +5664,13 @@ var ClaudeSessionManager = class _ClaudeSessionManager {
|
|
|
5628
5664
|
}
|
|
5629
5665
|
}
|
|
5630
5666
|
}
|
|
5667
|
+
clearMainSession() {
|
|
5668
|
+
this.sessionIds.delete(this.mainSessionKey);
|
|
5669
|
+
try {
|
|
5670
|
+
fs6.unlinkSync(this.stateFilePath);
|
|
5671
|
+
} catch {
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5631
5674
|
restore() {
|
|
5632
5675
|
try {
|
|
5633
5676
|
const raw = fs6.readFileSync(this.stateFilePath, "utf8");
|
|
@@ -5673,6 +5716,7 @@ function ensureClaudeWorkspace(workspaceDir, log2, agentIdentity) {
|
|
|
5673
5716
|
|
|
5674
5717
|
// ts/claude-agent/dist/index.js
|
|
5675
5718
|
var log = createLogger("claude-agent");
|
|
5719
|
+
var activeLog = log;
|
|
5676
5720
|
async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
5677
5721
|
try {
|
|
5678
5722
|
return await client.getAgentMe(orgId);
|
|
@@ -5696,28 +5740,30 @@ async function main() {
|
|
|
5696
5740
|
});
|
|
5697
5741
|
const me = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
5698
5742
|
const agentUserId = me.id;
|
|
5699
|
-
|
|
5743
|
+
const agentLog = childLogger(log, agentUserId);
|
|
5744
|
+
activeLog = agentLog;
|
|
5745
|
+
ensureClaudeWorkspace(config.workspaceDir, agentLog, {
|
|
5700
5746
|
userId: agentUserId,
|
|
5701
5747
|
displayName: me.display_name,
|
|
5702
5748
|
description: me.agent_profile?.description ?? void 0
|
|
5703
5749
|
});
|
|
5704
5750
|
const runtimeKey = config.runtimeKey || buildClaudeRuntimeKey(agentUserId);
|
|
5705
5751
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
5706
|
-
const sessionManager = new ClaudeSessionManager(runtimeKey, sessionStateFilePath,
|
|
5752
|
+
const sessionManager = new ClaudeSessionManager(runtimeKey, sessionStateFilePath, agentLog);
|
|
5707
5753
|
const resolvedWsUrl = resolveWsUrl(config.apiUrl, config.wsUrl, config.swimlaneName);
|
|
5708
5754
|
const ws = new ParallWs({
|
|
5709
5755
|
getTicket: () => client.getWsTicket(),
|
|
5710
5756
|
wsUrl: resolvedWsUrl
|
|
5711
5757
|
});
|
|
5712
|
-
const configMgr = createPlatformConfigManager({ client, stateDir: config.stateDir, runtimeType: "claude-code", log });
|
|
5758
|
+
const configMgr = createPlatformConfigManager({ client, stateDir: config.stateDir, runtimeType: "claude-code", log: agentLog });
|
|
5713
5759
|
const platformDefaults = await configMgr.fetch();
|
|
5714
5760
|
let platformManaged = isPlatformManagedProfile(me.agent_profile);
|
|
5715
5761
|
const resolvedModel = platformManaged ? platformDefaults.model ?? config.model : config.model;
|
|
5716
5762
|
const resolvedEffort = platformManaged ? platformDefaults.thinkingEffort ?? (process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || void 0) : process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || void 0;
|
|
5717
5763
|
if (platformDefaults.model)
|
|
5718
|
-
|
|
5764
|
+
agentLog.info(`platform config: model=${platformDefaults.model} (${platformManaged ? "applied" : "ignored, model_management=self"})`);
|
|
5719
5765
|
if (platformDefaults.thinkingEffort)
|
|
5720
|
-
|
|
5766
|
+
agentLog.info(`platform config: thinking_effort=${platformDefaults.thinkingEffort} (${platformManaged ? "applied" : "ignored, model_management=self"})`);
|
|
5721
5767
|
const adapter = new ClaudeCodeAdapter({
|
|
5722
5768
|
claudeBin: config.claudeBin,
|
|
5723
5769
|
claudeHome: config.claudeHome,
|
|
@@ -5762,7 +5808,7 @@ async function main() {
|
|
|
5762
5808
|
claude_home: config.claudeHome
|
|
5763
5809
|
},
|
|
5764
5810
|
dispatchAdapter: adapter,
|
|
5765
|
-
log,
|
|
5811
|
+
log: agentLog,
|
|
5766
5812
|
shutdownDeadlineMs: parseShutdownDeadlineMs(process.env.PRLL_SHUTDOWN_DEADLINE_MS),
|
|
5767
5813
|
contextFilePathForSession: (sessionKey) => contextFilePathForSession(config.stateDir, sessionKey),
|
|
5768
5814
|
stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
|
|
@@ -5790,14 +5836,18 @@ async function main() {
|
|
|
5790
5836
|
// gateway's shuttingDown flag alone does not tear them down. Piggyback on
|
|
5791
5837
|
// onBeforeDisconnect to close stdin and SIGTERM any survivors after
|
|
5792
5838
|
// in-flight drains finish.
|
|
5793
|
-
onBeforeDisconnect: () => adapter.shutdown()
|
|
5839
|
+
onBeforeDisconnect: () => adapter.shutdown(),
|
|
5840
|
+
onNewSession: async () => {
|
|
5841
|
+
sessionManager.clearMainSession();
|
|
5842
|
+
await adapter.shutdown();
|
|
5843
|
+
}
|
|
5794
5844
|
});
|
|
5795
5845
|
const abortController = new AbortController();
|
|
5796
5846
|
const abort = () => abortController.abort();
|
|
5797
5847
|
process.on("SIGINT", abort);
|
|
5798
5848
|
process.on("SIGTERM", abort);
|
|
5799
5849
|
try {
|
|
5800
|
-
|
|
5850
|
+
agentLog.info(`starting self-hosted Claude runtime for ${me.display_name} (${agentUserId})`);
|
|
5801
5851
|
await gateway.run(abortController.signal);
|
|
5802
5852
|
} finally {
|
|
5803
5853
|
process.off("SIGINT", abort);
|
|
@@ -5805,6 +5855,6 @@ async function main() {
|
|
|
5805
5855
|
}
|
|
5806
5856
|
}
|
|
5807
5857
|
main().catch((err) => {
|
|
5808
|
-
|
|
5858
|
+
activeLog.error(`fatal: ${String(err)}`);
|
|
5809
5859
|
process.exitCode = 1;
|
|
5810
5860
|
});
|