@parall/daemon 1.29.3 → 1.31.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 +12 -11
- package/bundle/parall-claude-agent.js +252 -85
- package/bundle/parall-codex-agent.js +248 -94
- package/bundle/parall-daemon.js +1076 -299
- package/bundle/parall-openclaw-agent.js +2 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +52 -2
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -0
- package/dist/filesystem.d.ts +7 -0
- package/dist/filesystem.d.ts.map +1 -0
- package/dist/filesystem.js +118 -0
- package/dist/index.js +30 -3
- package/dist/runtimes.d.ts +9 -8
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +47 -83
- package/dist/supervisor.d.ts +5 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +63 -0
- package/dist/updater-manifest.d.ts +39 -0
- package/dist/updater-manifest.d.ts.map +1 -0
- package/dist/updater-manifest.js +94 -0
- package/dist/updater.d.ts +60 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +409 -0
- package/package.json +6 -6
|
@@ -3,6 +3,34 @@
|
|
|
3
3
|
// ts/codex-agent/dist/index.js
|
|
4
4
|
import * as os3 from "node:os";
|
|
5
5
|
|
|
6
|
+
// ts/agent-core/dist/provider-config.js
|
|
7
|
+
function llmSource(pc) {
|
|
8
|
+
if (pc?.llm_source)
|
|
9
|
+
return pc.llm_source;
|
|
10
|
+
if (pc?.openai_api_key || pc?.openai_base_url || pc?.anthropic_auth_token || pc?.anthropic_base_url) {
|
|
11
|
+
return "custom";
|
|
12
|
+
}
|
|
13
|
+
return "parall";
|
|
14
|
+
}
|
|
15
|
+
function clearAllProviderCreds(env) {
|
|
16
|
+
delete env.ANTHROPIC_AUTH_TOKEN;
|
|
17
|
+
delete env.ANTHROPIC_BASE_URL;
|
|
18
|
+
delete env.ANTHROPIC_API_KEY;
|
|
19
|
+
delete env.OPENAI_API_KEY;
|
|
20
|
+
delete env.OPENAI_BASE_URL;
|
|
21
|
+
delete env.PRLL_CLAUDE_ALLOW_API_KEY;
|
|
22
|
+
}
|
|
23
|
+
function parseProviderConfig(env) {
|
|
24
|
+
const raw = env.PRLL_PROVIDER_CONFIG?.trim();
|
|
25
|
+
if (!raw)
|
|
26
|
+
return void 0;
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
throw new Error(`Invalid PRLL_PROVIDER_CONFIG JSON: ${String(err)}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
6
34
|
// ts/agent-core/dist/session-state.js
|
|
7
35
|
function normalizeSessionKey(sessionKey) {
|
|
8
36
|
return sessionKey.toLowerCase();
|
|
@@ -428,9 +456,13 @@ function createLogger(prefix) {
|
|
|
428
456
|
return {
|
|
429
457
|
info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
430
458
|
warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
431
|
-
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`)
|
|
459
|
+
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
460
|
+
child: (sub) => createLogger(`${prefix}:${sub}`)
|
|
432
461
|
};
|
|
433
462
|
}
|
|
463
|
+
function childLogger(logger, sub) {
|
|
464
|
+
return logger.child ? logger.child(sub) : logger;
|
|
465
|
+
}
|
|
434
466
|
|
|
435
467
|
// ts/agent-core/dist/gateway-base.js
|
|
436
468
|
import * as os from "node:os";
|
|
@@ -470,6 +502,7 @@ var ENDPOINTS = {
|
|
|
470
502
|
ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
|
|
471
503
|
ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
|
|
472
504
|
ORG_MEMBER_TASKS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/tasks`,
|
|
505
|
+
REF_SEARCH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/search`,
|
|
473
506
|
// Direct messages (org-scoped, atomic find-or-create + send)
|
|
474
507
|
DM: (orgId) => `${API_BASE}/orgs/${orgId}/dm`,
|
|
475
508
|
// Onboarding
|
|
@@ -513,6 +546,7 @@ var ENDPOINTS = {
|
|
|
513
546
|
AGENT_ACTIVITY: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/activity`,
|
|
514
547
|
AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
|
|
515
548
|
AGENT_ME: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me`,
|
|
549
|
+
AGENT_NEW_SESSION: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/new-session`,
|
|
516
550
|
AGENT_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions`,
|
|
517
551
|
AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
|
|
518
552
|
AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
|
|
@@ -551,6 +585,8 @@ var ENDPOINTS = {
|
|
|
551
585
|
MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
|
|
552
586
|
MACHINE_RUNTIME_AUTH_SESSIONS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions`,
|
|
553
587
|
MACHINE_RUNTIME_AUTH_SESSION_COMPLETE: (orgId, machineId, sessionId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions/${sessionId}/complete`,
|
|
588
|
+
MACHINE_REQUEST_UPDATE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/request-update`,
|
|
589
|
+
MACHINE_BROWSE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/browse`,
|
|
554
590
|
// Machine self-control-plane (mck_-scoped). The bearer token implicitly
|
|
555
591
|
// identifies the Machine, so there is no `:mid` URL parameter — these are
|
|
556
592
|
// "self" routes called by the daemon for its own host.
|
|
@@ -560,6 +596,7 @@ var ENDPOINTS = {
|
|
|
560
596
|
MACHINES_ME_AGENT_LAUNCH_CREDENTIAL: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/launch-credential`,
|
|
561
597
|
MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/workspace-state`,
|
|
562
598
|
MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
|
|
599
|
+
MACHINES_ME_BROWSE_RESPONSE: (requestId) => `${API_BASE}/machines/me/browse-response/${requestId}`,
|
|
563
600
|
// Tasks (org-scoped)
|
|
564
601
|
TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
|
|
565
602
|
TASK: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}`,
|
|
@@ -594,6 +631,12 @@ var ENDPOINTS = {
|
|
|
594
631
|
INVITATION_ACCEPT: (id) => `${API_BASE}/invitations/${id}/accept`,
|
|
595
632
|
INVITATION_DECLINE: (id) => `${API_BASE}/invitations/${id}/decline`,
|
|
596
633
|
INVITATION_BY_TOKEN: (token) => `${API_BASE}/invitations/by-token/${token}`,
|
|
634
|
+
// Org-level shareable invite link
|
|
635
|
+
ORG_INVITE_LINK: (orgId) => `${API_BASE}/orgs/${orgId}/invite-link`,
|
|
636
|
+
ORG_INVITE_LINK_REGENERATE: (orgId) => `${API_BASE}/orgs/${orgId}/invite-link/regenerate`,
|
|
637
|
+
ORG_INVITE_LINK_JOIN_REQUESTS: (orgId) => `${API_BASE}/orgs/${orgId}/invite-link/join-requests`,
|
|
638
|
+
ORG_INVITE_LINK_JOIN_REQUEST_DECIDE: (orgId, jrId) => `${API_BASE}/orgs/${orgId}/invite-link/join-requests/${jrId}/decide`,
|
|
639
|
+
INVITE_LINK_JOIN: `${API_BASE}/invite-link/join`,
|
|
597
640
|
// Wikis (org-scoped, served by wiki-service)
|
|
598
641
|
WIKIS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis`,
|
|
599
642
|
WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
|
|
@@ -713,6 +756,8 @@ var WS_EVENTS = {
|
|
|
713
756
|
INVITATION_ACCEPTED: "invitation.accepted",
|
|
714
757
|
INVITATION_DECLINED: "invitation.declined",
|
|
715
758
|
INVITATION_REVOKED: "invitation.revoked",
|
|
759
|
+
ORG_JOIN_REQUEST_NEW: "org.join_request.new",
|
|
760
|
+
ORG_INVITE_LINK_JOINED: "org.invite_link.joined",
|
|
716
761
|
AGENT_CONFIG_UPDATE: "agent_config.update",
|
|
717
762
|
PRESENCE_UPDATE: "presence.update",
|
|
718
763
|
WIKI_CHANGESET_CREATED: "wiki.changeset.created",
|
|
@@ -739,7 +784,11 @@ var WS_EVENTS = {
|
|
|
739
784
|
MACHINE_AGENT_ATTACHED: "machine.agent.attached",
|
|
740
785
|
MACHINE_AGENT_DETACHED: "machine.agent.detached",
|
|
741
786
|
MACHINE_STOP: "machine.stop",
|
|
742
|
-
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested"
|
|
787
|
+
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested",
|
|
788
|
+
MACHINE_FILESYSTEM_BROWSE: "machine.filesystem.browse",
|
|
789
|
+
MACHINE_UPDATE: "machine.update",
|
|
790
|
+
MACHINE_CONFIG_UPDATED: "machine.config.updated",
|
|
791
|
+
AGENT_NEW_SESSION: "agent.new_session"
|
|
743
792
|
};
|
|
744
793
|
|
|
745
794
|
// ts/sdk/dist/client.js
|
|
@@ -1068,6 +1117,9 @@ var ParallClient = class _ParallClient {
|
|
|
1068
1117
|
const res = await this.request("GET", ENDPOINTS.ORG_MEMBERS_ONLINE(orgId));
|
|
1069
1118
|
return res.user_ids ?? [];
|
|
1070
1119
|
}
|
|
1120
|
+
async searchRefs(orgId, params) {
|
|
1121
|
+
return this.request("GET", ENDPOINTS.REF_SEARCH(orgId), void 0, params);
|
|
1122
|
+
}
|
|
1071
1123
|
async removeOrgMember(orgId, userId) {
|
|
1072
1124
|
return this.request("DELETE", ENDPOINTS.ORG_MEMBER(orgId, userId));
|
|
1073
1125
|
}
|
|
@@ -1121,6 +1173,34 @@ var ParallClient = class _ParallClient {
|
|
|
1121
1173
|
async getInvitationByToken(token) {
|
|
1122
1174
|
return this.request("GET", ENDPOINTS.INVITATION_BY_TOKEN(token));
|
|
1123
1175
|
}
|
|
1176
|
+
// ---- Org-level shareable invite link ----
|
|
1177
|
+
/** Fetch the org's current invite link. Auto-creates on first call
|
|
1178
|
+
* so the settings UI never sees an empty state. */
|
|
1179
|
+
async getOrgInviteLink(orgId) {
|
|
1180
|
+
return this.request("GET", ENDPOINTS.ORG_INVITE_LINK(orgId));
|
|
1181
|
+
}
|
|
1182
|
+
/** Rotate the token in place. The old token stops resolving immediately. */
|
|
1183
|
+
async regenerateOrgInviteLink(orgId) {
|
|
1184
|
+
return this.request("POST", ENDPOINTS.ORG_INVITE_LINK_REGENERATE(orgId));
|
|
1185
|
+
}
|
|
1186
|
+
/** Toggle the require-approval flag on the org's invite link. */
|
|
1187
|
+
async updateOrgInviteLink(orgId, data) {
|
|
1188
|
+
return this.request("PATCH", ENDPOINTS.ORG_INVITE_LINK(orgId), data);
|
|
1189
|
+
}
|
|
1190
|
+
/** Redeem an invite-link token. Caller must be authenticated; the
|
|
1191
|
+
* token is the lookup key so this endpoint is NOT org-scoped. */
|
|
1192
|
+
async joinByInviteLink(token) {
|
|
1193
|
+
return this.request("POST", ENDPOINTS.INVITE_LINK_JOIN, { token });
|
|
1194
|
+
}
|
|
1195
|
+
/** Admin: list pending invite-link join requests for an org. */
|
|
1196
|
+
async listOrgJoinRequests(orgId) {
|
|
1197
|
+
const res = await this.request("GET", ENDPOINTS.ORG_INVITE_LINK_JOIN_REQUESTS(orgId));
|
|
1198
|
+
return res.data;
|
|
1199
|
+
}
|
|
1200
|
+
/** Admin: approve or reject a pending invite-link join request. */
|
|
1201
|
+
async decideOrgJoinRequest(orgId, jrId, decision) {
|
|
1202
|
+
return this.request("POST", ENDPOINTS.ORG_INVITE_LINK_JOIN_REQUEST_DECIDE(orgId, jrId), { decision });
|
|
1203
|
+
}
|
|
1124
1204
|
// ---- Direct Messages (org-scoped) ----
|
|
1125
1205
|
async sendDirectMessage(orgId, req) {
|
|
1126
1206
|
return this.request("POST", ENDPOINTS.DM(orgId), req);
|
|
@@ -1285,6 +1365,9 @@ var ParallClient = class _ParallClient {
|
|
|
1285
1365
|
return this.request("GET", ENDPOINTS.AGENT_ME(orgId));
|
|
1286
1366
|
}
|
|
1287
1367
|
// ---- Agent Sessions (org-scoped) ----
|
|
1368
|
+
async requestNewAgentSession(orgId, agentId) {
|
|
1369
|
+
return this.request("POST", ENDPOINTS.AGENT_NEW_SESSION(orgId, agentId));
|
|
1370
|
+
}
|
|
1288
1371
|
async createAgentSession(orgId, agentId, req) {
|
|
1289
1372
|
return this.request("POST", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), req);
|
|
1290
1373
|
}
|
|
@@ -1387,19 +1470,20 @@ var ParallClient = class _ParallClient {
|
|
|
1387
1470
|
}
|
|
1388
1471
|
// ---- Daemon-mode Machine management (org-scoped, user auth) ----
|
|
1389
1472
|
/**
|
|
1390
|
-
* Create a new daemon-mode Machine. Returns the Machine row +
|
|
1391
|
-
* mck_ token.
|
|
1473
|
+
* Create a new self-hosted daemon-mode Machine. Returns the Machine row +
|
|
1474
|
+
* one-shot mck_ token.
|
|
1392
1475
|
*/
|
|
1393
1476
|
async createMachine(orgId, opts) {
|
|
1394
1477
|
return this.request("POST", ENDPOINTS.MACHINES(orgId), opts);
|
|
1395
1478
|
}
|
|
1396
1479
|
/**
|
|
1397
|
-
* Returns
|
|
1398
|
-
* "Workspaces" UI list. Legacy 1:1 machines are
|
|
1480
|
+
* Returns local daemon_mode=true machines (non-terminated). Backs the
|
|
1481
|
+
* "Workspaces" UI list. Legacy 1:1 and retired hosted daemon machines are
|
|
1482
|
+
* excluded.
|
|
1399
1483
|
*/
|
|
1400
1484
|
async getDaemonMachines(orgId) {
|
|
1401
1485
|
const all = await this.getMachines(orgId);
|
|
1402
|
-
return all.filter((m) => m.daemon_mode && m.status !== "terminated");
|
|
1486
|
+
return all.filter((m) => m.daemon_mode && m.compute_mode === "local" && m.status !== "terminated");
|
|
1403
1487
|
}
|
|
1404
1488
|
/** Attach an agent to a daemon-mode Machine. */
|
|
1405
1489
|
async attachAgent(orgId, machineId, agentId, opts) {
|
|
@@ -1419,8 +1503,8 @@ var ParallClient = class _ParallClient {
|
|
|
1419
1503
|
async retryAgentWorkspaceSetup(orgId, machineId, agentId) {
|
|
1420
1504
|
return this.request("POST", ENDPOINTS.MACHINE_AGENT_WORKSPACE_SETUP(orgId, machineId, agentId));
|
|
1421
1505
|
}
|
|
1422
|
-
async patchMachineLLMSource(orgId, machineId,
|
|
1423
|
-
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), { llm_source:
|
|
1506
|
+
async patchMachineLLMSource(orgId, machineId, llmSource2) {
|
|
1507
|
+
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), { llm_source: llmSource2 });
|
|
1424
1508
|
}
|
|
1425
1509
|
/** Get machine-level runtime auth state. */
|
|
1426
1510
|
async getMachineRuntimeAuth(orgId, machineId) {
|
|
@@ -1461,8 +1545,9 @@ var ParallClient = class _ParallClient {
|
|
|
1461
1545
|
* daemon should call this on a fixed cadence (e.g. every 30s) so an
|
|
1462
1546
|
* external observer can detect a wedged supervisor.
|
|
1463
1547
|
*/
|
|
1464
|
-
async postMachineHeartbeat() {
|
|
1465
|
-
|
|
1548
|
+
async postMachineHeartbeat(daemonVersion) {
|
|
1549
|
+
const body = daemonVersion ? { daemon_version: daemonVersion } : void 0;
|
|
1550
|
+
return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH, body);
|
|
1466
1551
|
}
|
|
1467
1552
|
async reportAgentWorkspaceState(agentId, state) {
|
|
1468
1553
|
const res = await this.request("PUT", ENDPOINTS.MACHINES_ME_AGENT_WORKSPACE_STATE(agentId), state);
|
|
@@ -1484,9 +1569,19 @@ var ParallClient = class _ParallClient {
|
|
|
1484
1569
|
async getMachineWsTicket() {
|
|
1485
1570
|
return this.request("POST", ENDPOINTS.MACHINES_ME_WS_TICKET);
|
|
1486
1571
|
}
|
|
1572
|
+
async postBrowseResponse(requestId, response) {
|
|
1573
|
+
return this.request("POST", ENDPOINTS.MACHINES_ME_BROWSE_RESPONSE(requestId), response);
|
|
1574
|
+
}
|
|
1487
1575
|
async resizeMachine(orgId, machineId, spec) {
|
|
1488
1576
|
return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
|
|
1489
1577
|
}
|
|
1578
|
+
/** Signal a local daemon-mode Machine to check for and apply an update. */
|
|
1579
|
+
async requestMachineUpdate(orgId, machineId, mandatory = false) {
|
|
1580
|
+
await this.request("POST", ENDPOINTS.MACHINE_REQUEST_UPDATE(orgId, machineId), { mandatory });
|
|
1581
|
+
}
|
|
1582
|
+
async browseMachineFilesystem(orgId, machineId, path8) {
|
|
1583
|
+
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path8 }, void 0, false, { timeoutMs: 15e3 });
|
|
1584
|
+
}
|
|
1490
1585
|
/** Create a new machine key. Returns the raw key string (shown once) + metadata. */
|
|
1491
1586
|
async createMachineKey(orgId, machineId, name) {
|
|
1492
1587
|
return this.request("POST", ENDPOINTS.MACHINE_KEYS(orgId, machineId), name ? { name } : void 0);
|
|
@@ -2334,6 +2429,7 @@ var ParallWs = class {
|
|
|
2334
2429
|
};
|
|
2335
2430
|
|
|
2336
2431
|
// ts/agent-core/dist/gateway-base.js
|
|
2432
|
+
var LIVE_SESSION_STATUSES = /* @__PURE__ */ new Set(["open", "active", "idle"]);
|
|
2337
2433
|
function parseShutdownDeadlineMs(raw) {
|
|
2338
2434
|
if (!raw)
|
|
2339
2435
|
return void 0;
|
|
@@ -2399,6 +2495,7 @@ var ParallAgentGateway = class {
|
|
|
2399
2495
|
shuttingDown = false;
|
|
2400
2496
|
inFlightDispatches = 0;
|
|
2401
2497
|
drainResolvers = [];
|
|
2498
|
+
pendingRestartNotification = null;
|
|
2402
2499
|
DISPATCHED_MESSAGES_CAP = 5e3;
|
|
2403
2500
|
COLD_START_WINDOW_MS;
|
|
2404
2501
|
// SHUTDOWN_DEADLINE_MS is read by waitForDrain via the configured value
|
|
@@ -2413,7 +2510,7 @@ var ParallAgentGateway = class {
|
|
|
2413
2510
|
async run(abortSignal) {
|
|
2414
2511
|
const { ws, log: log2 } = this.opts;
|
|
2415
2512
|
ws.onStateChange((state) => {
|
|
2416
|
-
log2?.info(`
|
|
2513
|
+
log2?.info(`connection state \u2192 ${state}`);
|
|
2417
2514
|
});
|
|
2418
2515
|
ws.on("hello", async (data) => {
|
|
2419
2516
|
await this.handleHello(data);
|
|
@@ -2442,16 +2539,29 @@ var ParallAgentGateway = class {
|
|
|
2442
2539
|
await this.handleMessage(data);
|
|
2443
2540
|
});
|
|
2444
2541
|
ws.on("agent_config.update", async (data) => {
|
|
2445
|
-
this.opts.log?.info(`
|
|
2542
|
+
this.opts.log?.info(`config update notification (version=${data.version})`);
|
|
2446
2543
|
try {
|
|
2447
2544
|
await this.opts.onConfigUpdate?.(data);
|
|
2448
2545
|
} catch (err) {
|
|
2449
|
-
this.opts.log?.warn(`
|
|
2546
|
+
this.opts.log?.warn(`config update failed: ${String(err)}`);
|
|
2547
|
+
}
|
|
2548
|
+
});
|
|
2549
|
+
ws.on("agent.new_session", async (data) => {
|
|
2550
|
+
const prevId = data.previous_session_id ?? "";
|
|
2551
|
+
this.opts.log?.info(`new session signal received (previous=${prevId})`);
|
|
2552
|
+
this.sessionBindings.clear();
|
|
2553
|
+
if (prevId) {
|
|
2554
|
+
this.pendingRestartNotification = `[Harness Notification] This is a fresh session. Your previous session (${prevId}) was ended by the user and you have been restarted.`;
|
|
2555
|
+
}
|
|
2556
|
+
try {
|
|
2557
|
+
await this.opts.onNewSession?.(prevId);
|
|
2558
|
+
} catch (err) {
|
|
2559
|
+
this.opts.log?.warn(`onNewSession callback failed: ${String(err)}`);
|
|
2450
2560
|
}
|
|
2451
2561
|
});
|
|
2452
2562
|
ws.on("recovery.overflow", () => {
|
|
2453
|
-
this.opts.log?.warn(`
|
|
2454
|
-
this.catchUpFromDispatch().catch((err) => this.opts.log?.warn(`
|
|
2563
|
+
this.opts.log?.warn(`recovery.overflow \u2014 triggering full catch-up`);
|
|
2564
|
+
this.catchUpFromDispatch().catch((err) => this.opts.log?.warn(`overflow catch-up failed: ${String(err)}`));
|
|
2455
2565
|
});
|
|
2456
2566
|
ws.on("task.assigned", async (data) => {
|
|
2457
2567
|
if (data.assignee_id !== this.opts.agentUserId)
|
|
@@ -2465,7 +2575,7 @@ var ParallAgentGateway = class {
|
|
|
2465
2575
|
});
|
|
2466
2576
|
}
|
|
2467
2577
|
} catch (err) {
|
|
2468
|
-
this.opts.log?.error(`
|
|
2578
|
+
this.opts.log?.error(`task dispatch failed for ${data.id}: ${String(err)}`);
|
|
2469
2579
|
}
|
|
2470
2580
|
});
|
|
2471
2581
|
ws.on("dispatch.new", async (data) => {
|
|
@@ -2479,7 +2589,7 @@ var ParallAgentGateway = class {
|
|
|
2479
2589
|
});
|
|
2480
2590
|
}
|
|
2481
2591
|
} catch (err) {
|
|
2482
|
-
this.opts.log?.error(`
|
|
2592
|
+
this.opts.log?.error(`task comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2483
2593
|
}
|
|
2484
2594
|
} else if (data.event_type === "task_update") {
|
|
2485
2595
|
if (!data.task_id)
|
|
@@ -2491,7 +2601,7 @@ var ParallAgentGateway = class {
|
|
|
2491
2601
|
});
|
|
2492
2602
|
}
|
|
2493
2603
|
} catch (err) {
|
|
2494
|
-
this.opts.log?.error(`
|
|
2604
|
+
this.opts.log?.error(`task update dispatch failed for ${data.task_id}: ${String(err)}`);
|
|
2495
2605
|
}
|
|
2496
2606
|
} else if (data.event_type === "schedule.fire") {
|
|
2497
2607
|
if (!data.source_id)
|
|
@@ -2503,7 +2613,7 @@ var ParallAgentGateway = class {
|
|
|
2503
2613
|
});
|
|
2504
2614
|
}
|
|
2505
2615
|
} catch (err) {
|
|
2506
|
-
this.opts.log?.error(`
|
|
2616
|
+
this.opts.log?.error(`schedule fire dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2507
2617
|
}
|
|
2508
2618
|
} else if (data.event_type === "approval_decided") {
|
|
2509
2619
|
if (!data.source_id)
|
|
@@ -2515,13 +2625,13 @@ var ParallAgentGateway = class {
|
|
|
2515
2625
|
});
|
|
2516
2626
|
}
|
|
2517
2627
|
} catch (err) {
|
|
2518
|
-
this.opts.log?.error(`
|
|
2628
|
+
this.opts.log?.error(`approval decided dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
2519
2629
|
}
|
|
2520
2630
|
} else if (data.event_type !== "message" && data.event_type !== "task_assign") {
|
|
2521
|
-
this.opts.log?.info(`
|
|
2631
|
+
this.opts.log?.info(`dispatch.new with unhandled event_type=${String(data.event_type)} (id=${data.id}) \u2014 no-op`);
|
|
2522
2632
|
}
|
|
2523
2633
|
});
|
|
2524
|
-
this.opts.log?.info(`
|
|
2634
|
+
this.opts.log?.info(`connecting to ${this.opts.connectionLabel ?? "Parall WS"}...`);
|
|
2525
2635
|
await ws.connect();
|
|
2526
2636
|
return new Promise((resolve4) => {
|
|
2527
2637
|
abortSignal.addEventListener("abort", async () => {
|
|
@@ -2635,7 +2745,7 @@ var ParallAgentGateway = class {
|
|
|
2635
2745
|
}
|
|
2636
2746
|
});
|
|
2637
2747
|
} catch (err) {
|
|
2638
|
-
this.opts.log?.warn(`
|
|
2748
|
+
this.opts.log?.warn(`failed to create input step: ${String(err)}`);
|
|
2639
2749
|
}
|
|
2640
2750
|
}
|
|
2641
2751
|
async createRuntimeStep(sessionId, event, runtimeEvent, stepIdFilePath, contextFilePath) {
|
|
@@ -2713,12 +2823,12 @@ var ParallAgentGateway = class {
|
|
|
2713
2823
|
target_type: target.target_type,
|
|
2714
2824
|
target_id: target.target_id,
|
|
2715
2825
|
content: { text: runtimeEvent.message, suppressed: false },
|
|
2716
|
-
projection:
|
|
2826
|
+
projection: false
|
|
2717
2827
|
});
|
|
2718
2828
|
break;
|
|
2719
2829
|
}
|
|
2720
2830
|
} catch (err) {
|
|
2721
|
-
this.opts.log?.warn(`
|
|
2831
|
+
this.opts.log?.warn(`failed to create ${runtimeEvent.type} step: ${String(err)}`);
|
|
2722
2832
|
}
|
|
2723
2833
|
}
|
|
2724
2834
|
writeContextFile(filePath, ctx) {
|
|
@@ -2726,7 +2836,7 @@ var ParallAgentGateway = class {
|
|
|
2726
2836
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2727
2837
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2728
2838
|
} catch (err) {
|
|
2729
|
-
this.opts.log?.warn(`
|
|
2839
|
+
this.opts.log?.warn(`failed to write context file ${filePath}: ${String(err)}`);
|
|
2730
2840
|
}
|
|
2731
2841
|
}
|
|
2732
2842
|
updateContextFileStepId(filePath, stepId) {
|
|
@@ -2736,7 +2846,7 @@ var ParallAgentGateway = class {
|
|
|
2736
2846
|
ctx.step_id = stepId;
|
|
2737
2847
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2738
2848
|
} catch (err) {
|
|
2739
|
-
this.opts.log?.warn(`
|
|
2849
|
+
this.opts.log?.warn(`failed to update context file step_id ${filePath}: ${String(err)}`);
|
|
2740
2850
|
}
|
|
2741
2851
|
}
|
|
2742
2852
|
updateContextFileSessionId(filePath, sessionId) {
|
|
@@ -2746,7 +2856,7 @@ var ParallAgentGateway = class {
|
|
|
2746
2856
|
ctx.session_id = sessionId;
|
|
2747
2857
|
fs.writeFileSync(filePath, JSON.stringify(ctx), "utf8");
|
|
2748
2858
|
} catch (err) {
|
|
2749
|
-
this.opts.log?.warn(`
|
|
2859
|
+
this.opts.log?.warn(`failed to update context file session_id ${filePath}: ${String(err)}`);
|
|
2750
2860
|
}
|
|
2751
2861
|
}
|
|
2752
2862
|
/** @deprecated Use writeContextFile / updateContextFileStepId. */
|
|
@@ -2755,7 +2865,7 @@ var ParallAgentGateway = class {
|
|
|
2755
2865
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
2756
2866
|
fs.writeFileSync(filePath, stepId, "utf8");
|
|
2757
2867
|
} catch (err) {
|
|
2758
|
-
this.opts.log?.warn(`
|
|
2868
|
+
this.opts.log?.warn(`failed to write step id file ${filePath}: ${String(err)}`);
|
|
2759
2869
|
}
|
|
2760
2870
|
}
|
|
2761
2871
|
/** @deprecated Use writeContextFile / updateContextFileStepId. */
|
|
@@ -2789,6 +2899,17 @@ var ParallAgentGateway = class {
|
|
|
2789
2899
|
parent_session_id: parentSessionId,
|
|
2790
2900
|
runtime_ref: Object.keys(runtimeRef).length > 0 ? runtimeRef : void 0
|
|
2791
2901
|
});
|
|
2902
|
+
if (!LIVE_SESSION_STATUSES.has(session.status)) {
|
|
2903
|
+
this.opts.log?.warn?.(`createAgentSession returned terminal session ${session.id} (${session.status}), resetting runtime for ${sessionKey}`);
|
|
2904
|
+
this.sessionBindings.delete(sessionKey);
|
|
2905
|
+
try {
|
|
2906
|
+
await this.opts.onSessionStale?.(sessionKey);
|
|
2907
|
+
} catch (e) {
|
|
2908
|
+
this.opts.log?.warn?.(`onSessionStale failed: ${e}`);
|
|
2909
|
+
}
|
|
2910
|
+
this.opts.log?.info?.(`stale session self-heal complete for ${sessionKey} \u2014 next dispatch will create a fresh session`);
|
|
2911
|
+
throw new Error(`Agent session ${session.id} is terminal (${session.status})`);
|
|
2912
|
+
}
|
|
2792
2913
|
const binding = {
|
|
2793
2914
|
sessionKey,
|
|
2794
2915
|
agentSessionId: session.id,
|
|
@@ -2812,9 +2933,13 @@ var ParallAgentGateway = class {
|
|
|
2812
2933
|
// catch-up on the replacement pod — otherwise we silently drop work.
|
|
2813
2934
|
async runDispatch(event, sessionKey, bodyForAgent, earlierEvents = [], captureText) {
|
|
2814
2935
|
if (this.shuttingDown) {
|
|
2815
|
-
this.opts.log?.info(`
|
|
2936
|
+
this.opts.log?.info(`skipping dispatch for ${event.messageId} (shutting down) \u2014 leaving unacked for catch-up on replacement pod`);
|
|
2816
2937
|
return false;
|
|
2817
2938
|
}
|
|
2939
|
+
if (this.pendingRestartNotification) {
|
|
2940
|
+
bodyForAgent = this.pendingRestartNotification + "\n\n---\n\n" + bodyForAgent;
|
|
2941
|
+
this.pendingRestartNotification = null;
|
|
2942
|
+
}
|
|
2818
2943
|
setSessionChatId(sessionKey, event.targetId);
|
|
2819
2944
|
setSessionMessageId(sessionKey, event.messageId);
|
|
2820
2945
|
setDispatchMessageId(sessionKey, event.messageId);
|
|
@@ -2944,7 +3069,7 @@ var ParallAgentGateway = class {
|
|
|
2944
3069
|
item.resolve(true);
|
|
2945
3070
|
}
|
|
2946
3071
|
} catch (err) {
|
|
2947
|
-
this.opts.log?.error(`
|
|
3072
|
+
this.opts.log?.error(`fork dispatch failed for ${last.messageId}: ${String(err)}`);
|
|
2948
3073
|
for (const item of items) {
|
|
2949
3074
|
item.resolve(false);
|
|
2950
3075
|
}
|
|
@@ -2962,7 +3087,7 @@ var ParallAgentGateway = class {
|
|
|
2962
3087
|
try {
|
|
2963
3088
|
historyPath = this.opts.dispatchAdapter.getSessionHistoryPath?.(fork.fork.sessionKey);
|
|
2964
3089
|
} catch (err) {
|
|
2965
|
-
this.opts.log?.warn?.(`
|
|
3090
|
+
this.opts.log?.warn?.(`failed to resolve fork history path: ${String(err)}`);
|
|
2966
3091
|
}
|
|
2967
3092
|
this.dispatchState.pendingForkResults.push({
|
|
2968
3093
|
forkSessionKey: fork.fork.sessionKey,
|
|
@@ -3013,7 +3138,7 @@ var ParallAgentGateway = class {
|
|
|
3013
3138
|
try {
|
|
3014
3139
|
while (this.dispatchState.mainBuffer.length > 0) {
|
|
3015
3140
|
if (this.shuttingDown) {
|
|
3016
|
-
this.opts.log?.info(`
|
|
3141
|
+
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
3142
|
break;
|
|
3018
3143
|
}
|
|
3019
3144
|
const targetId = this.dispatchState.mainBuffer[0].targetId;
|
|
@@ -3079,7 +3204,7 @@ var ParallAgentGateway = class {
|
|
|
3079
3204
|
this.dispatchState.mainBuffer.push(event);
|
|
3080
3205
|
if (this.dispatchState.mainCurrentTargetId === event.targetId && await this.opts.dispatchAdapter.enqueueDuringDispatch?.(this.opts.runtimeKey, buildEventBody(event))) {
|
|
3081
3206
|
this.startInjectedTyping(event);
|
|
3082
|
-
this.opts.log?.info(`
|
|
3207
|
+
this.opts.log?.info(`steer injected for ${event.messageId} (will drain for bookkeeping)`);
|
|
3083
3208
|
}
|
|
3084
3209
|
if (!this.dispatchState.mainDispatching && !this.draining && this.dispatchState.mainBuffer.length > 0) {
|
|
3085
3210
|
this.dispatchState.mainDispatching = true;
|
|
@@ -3108,7 +3233,7 @@ var ParallAgentGateway = class {
|
|
|
3108
3233
|
preDispatchBranchPoint: this.dispatchState.mainPreDispatchBranchPoint
|
|
3109
3234
|
});
|
|
3110
3235
|
if (!fork) {
|
|
3111
|
-
this.opts.log?.warn(`
|
|
3236
|
+
this.opts.log?.warn(`fork failed, buffering event for main session`);
|
|
3112
3237
|
this.dispatchState.mainBuffer.push(event);
|
|
3113
3238
|
return false;
|
|
3114
3239
|
}
|
|
@@ -3124,7 +3249,7 @@ var ParallAgentGateway = class {
|
|
|
3124
3249
|
activeFork.queue.push({ event, resolve: resolve4 });
|
|
3125
3250
|
});
|
|
3126
3251
|
this.runForkDrainLoop(activeFork).catch((err) => {
|
|
3127
|
-
this.opts.log?.error(`
|
|
3252
|
+
this.opts.log?.error(`fork drain loop error: ${String(err)}`);
|
|
3128
3253
|
});
|
|
3129
3254
|
return firstEventPromise;
|
|
3130
3255
|
}
|
|
@@ -3144,7 +3269,7 @@ var ParallAgentGateway = class {
|
|
|
3144
3269
|
this.chatInfoMap.set(chatId, chatInfo);
|
|
3145
3270
|
return chatInfo;
|
|
3146
3271
|
} catch (err) {
|
|
3147
|
-
this.opts.log?.warn(`
|
|
3272
|
+
this.opts.log?.warn(`failed to resolve chat ${chatId}: ${String(err)}`);
|
|
3148
3273
|
return null;
|
|
3149
3274
|
}
|
|
3150
3275
|
}
|
|
@@ -3217,7 +3342,7 @@ var ParallAgentGateway = class {
|
|
|
3217
3342
|
this.dispatchedMessages.delete(data.id);
|
|
3218
3343
|
}
|
|
3219
3344
|
} catch (err) {
|
|
3220
|
-
this.opts.log?.error(`
|
|
3345
|
+
this.opts.log?.error(`event dispatch failed for ${data.id}: ${String(err)}`);
|
|
3221
3346
|
this.dispatchedMessages.delete(data.id);
|
|
3222
3347
|
}
|
|
3223
3348
|
}
|
|
@@ -3226,11 +3351,11 @@ var ParallAgentGateway = class {
|
|
|
3226
3351
|
return false;
|
|
3227
3352
|
const dedupeKey = `${task.id}:${task.updated_at}`;
|
|
3228
3353
|
if (this.dispatchedTasks.has(dedupeKey)) {
|
|
3229
|
-
this.opts.log?.info(`
|
|
3354
|
+
this.opts.log?.info(`skipping already-dispatched task ${task.identifier ?? task.id}`);
|
|
3230
3355
|
return false;
|
|
3231
3356
|
}
|
|
3232
3357
|
this.dispatchedTasks.add(dedupeKey);
|
|
3233
|
-
this.opts.log?.info(`
|
|
3358
|
+
this.opts.log?.info(`task assigned: ${task.identifier ?? task.id} "${task.title}"`);
|
|
3234
3359
|
const parts = [`Title: ${task.title}`];
|
|
3235
3360
|
parts.push(`Status: ${task.status}`, `Priority: ${task.priority}`);
|
|
3236
3361
|
if (task.project_id)
|
|
@@ -3271,7 +3396,7 @@ var ParallAgentGateway = class {
|
|
|
3271
3396
|
const isAssignee = task.assignee_id === this.opts.agentUserId;
|
|
3272
3397
|
const isCreatorUpdate = opts.allowCreator === true && task.creator_id === this.opts.agentUserId;
|
|
3273
3398
|
if (!isAssignee && !isCreatorUpdate) {
|
|
3274
|
-
this.opts.log?.info(`
|
|
3399
|
+
this.opts.log?.info(`skipping stale task dispatch ${ackSourceId ?? taskId} \u2014 assigned to ${task.assignee_id}, creator ${task.creator_id}`);
|
|
3275
3400
|
return true;
|
|
3276
3401
|
}
|
|
3277
3402
|
return this.handleTaskAssignment(task, ackSourceId);
|
|
@@ -3289,7 +3414,7 @@ var ParallAgentGateway = class {
|
|
|
3289
3414
|
} catch (err) {
|
|
3290
3415
|
const status = err?.status;
|
|
3291
3416
|
if (status === 404) {
|
|
3292
|
-
this.opts.log?.info(`
|
|
3417
|
+
this.opts.log?.info(`skipping deleted comment ${commentId}, acking stale dispatch`);
|
|
3293
3418
|
this.dispatchedTasks.delete(dedupeKey);
|
|
3294
3419
|
return true;
|
|
3295
3420
|
}
|
|
@@ -3301,7 +3426,7 @@ var ParallAgentGateway = class {
|
|
|
3301
3426
|
return true;
|
|
3302
3427
|
}
|
|
3303
3428
|
if (comment.hints?.no_reply) {
|
|
3304
|
-
this.opts.log?.info(`
|
|
3429
|
+
this.opts.log?.info(`skipping no_reply task comment ${commentId}, acking stale dispatch`);
|
|
3305
3430
|
this.dispatchedTasks.delete(dedupeKey);
|
|
3306
3431
|
return true;
|
|
3307
3432
|
}
|
|
@@ -3311,7 +3436,7 @@ var ParallAgentGateway = class {
|
|
|
3311
3436
|
} catch {
|
|
3312
3437
|
}
|
|
3313
3438
|
const taskLabel = task ? `${task.identifier ?? task.id} "${task.title}"` : taskId;
|
|
3314
|
-
this.opts.log?.info(`
|
|
3439
|
+
this.opts.log?.info(`task comment on ${taskLabel} by ${actorId ?? "unknown"}`);
|
|
3315
3440
|
const parts = [];
|
|
3316
3441
|
if (task) {
|
|
3317
3442
|
parts.push(`Task: ${task.title} (prll://${task.id})`);
|
|
@@ -3361,10 +3486,10 @@ var ParallAgentGateway = class {
|
|
|
3361
3486
|
} catch (err) {
|
|
3362
3487
|
const status = err?.status;
|
|
3363
3488
|
if (status === 404) {
|
|
3364
|
-
this.opts.log?.warn(`
|
|
3489
|
+
this.opts.log?.warn(`schedule run ${runId} not accessible (404), acking stale dispatch`);
|
|
3365
3490
|
return true;
|
|
3366
3491
|
}
|
|
3367
|
-
this.opts.log?.warn(`
|
|
3492
|
+
this.opts.log?.warn(`schedule run fetch failed for ${runId}, leaving pending: ${String(err)}`);
|
|
3368
3493
|
return false;
|
|
3369
3494
|
}
|
|
3370
3495
|
if (!run)
|
|
@@ -3378,7 +3503,7 @@ var ParallAgentGateway = class {
|
|
|
3378
3503
|
if (this.dispatchedTasks.has(dedupeKey))
|
|
3379
3504
|
return false;
|
|
3380
3505
|
this.dispatchedTasks.add(dedupeKey);
|
|
3381
|
-
this.opts.log?.info(`
|
|
3506
|
+
this.opts.log?.info(`schedule fired: ${run.id} (schedule ${run.schedule_id})`);
|
|
3382
3507
|
const event = {
|
|
3383
3508
|
type: "schedule",
|
|
3384
3509
|
// Route by schedule_id (not attached chat_id) so concurrent fires of
|
|
@@ -3415,10 +3540,10 @@ var ParallAgentGateway = class {
|
|
|
3415
3540
|
} catch (err) {
|
|
3416
3541
|
const status = err?.status;
|
|
3417
3542
|
if (status === 404 || status === 403) {
|
|
3418
|
-
this.opts.log?.warn(`
|
|
3543
|
+
this.opts.log?.warn(`approval ${approvalId} not accessible (${status}), acking stale dispatch`);
|
|
3419
3544
|
return true;
|
|
3420
3545
|
}
|
|
3421
|
-
this.opts.log?.warn(`
|
|
3546
|
+
this.opts.log?.warn(`approval fetch failed for ${approvalId}, leaving pending: ${String(err)}`);
|
|
3422
3547
|
return false;
|
|
3423
3548
|
}
|
|
3424
3549
|
if (!approval)
|
|
@@ -3429,7 +3554,7 @@ var ParallAgentGateway = class {
|
|
|
3429
3554
|
if (this.dispatchedTasks.has(dedupeKey))
|
|
3430
3555
|
return false;
|
|
3431
3556
|
this.dispatchedTasks.add(dedupeKey);
|
|
3432
|
-
this.opts.log?.info(`
|
|
3557
|
+
this.opts.log?.info(`approval decided: ${approval.id} (${approval.status})`);
|
|
3433
3558
|
const statusLabel = approval.status === "approved" ? "Approved" : "Rejected";
|
|
3434
3559
|
const execInfo = approval.execution_status ? ` | execution: ${approval.execution_status}` : "";
|
|
3435
3560
|
const body = `${statusLabel}: ${approval.title}${execInfo}`;
|
|
@@ -3479,14 +3604,14 @@ var ParallAgentGateway = class {
|
|
|
3479
3604
|
try {
|
|
3480
3605
|
dispatched = await this.handleTaskDispatch(item.task_id, item.source_id ?? item.task_id);
|
|
3481
3606
|
} catch (err) {
|
|
3482
|
-
this.opts.log?.warn(`
|
|
3607
|
+
this.opts.log?.warn(`catch-up task fetch failed for ${item.task_id}, leaving pending: ${String(err)}`);
|
|
3483
3608
|
continue;
|
|
3484
3609
|
}
|
|
3485
3610
|
} else if (item.event_type === "task_update" && item.task_id) {
|
|
3486
3611
|
try {
|
|
3487
3612
|
dispatched = await this.handleTaskDispatch(item.task_id, item.source_id ?? item.task_id, { allowCreator: true });
|
|
3488
3613
|
} catch (err) {
|
|
3489
|
-
this.opts.log?.warn(`
|
|
3614
|
+
this.opts.log?.warn(`catch-up task fetch failed for ${item.task_id}, leaving pending: ${String(err)}`);
|
|
3490
3615
|
continue;
|
|
3491
3616
|
}
|
|
3492
3617
|
} else if (item.event_type === "task_comment" && item.source_id && item.task_id) {
|
|
@@ -3508,7 +3633,7 @@ var ParallAgentGateway = class {
|
|
|
3508
3633
|
msg = null;
|
|
3509
3634
|
} else {
|
|
3510
3635
|
msgFetchFailed = true;
|
|
3511
|
-
this.opts.log?.warn(`
|
|
3636
|
+
this.opts.log?.warn(`catch-up message fetch failed for ${item.source_id}, leaving pending: ${String(err)}`);
|
|
3512
3637
|
}
|
|
3513
3638
|
}
|
|
3514
3639
|
if (msgFetchFailed) {
|
|
@@ -3539,13 +3664,13 @@ var ParallAgentGateway = class {
|
|
|
3539
3664
|
});
|
|
3540
3665
|
}
|
|
3541
3666
|
} catch (err) {
|
|
3542
|
-
this.opts.log?.warn(`
|
|
3667
|
+
this.opts.log?.warn(`catch-up dispatch ${item.id} (${item.event_type}) failed: ${String(err)}`);
|
|
3543
3668
|
}
|
|
3544
3669
|
}
|
|
3545
3670
|
cursor = !this.shuttingDown && page.has_more ? page.next_cursor : void 0;
|
|
3546
3671
|
} while (cursor);
|
|
3547
3672
|
if (processed > 0 || skippedOld > 0) {
|
|
3548
|
-
this.opts.log?.info(`
|
|
3673
|
+
this.opts.log?.info(`dispatch catch-up: processed ${processed}, skipped ${skippedOld} old item(s)`);
|
|
3549
3674
|
}
|
|
3550
3675
|
}
|
|
3551
3676
|
async handleHello(data) {
|
|
@@ -3554,7 +3679,7 @@ var ParallAgentGateway = class {
|
|
|
3554
3679
|
const intervalSec = data.heartbeat_interval > 0 ? data.heartbeat_interval : 30;
|
|
3555
3680
|
try {
|
|
3556
3681
|
const count = await fetchAllChats(client, config.org_id, this.chatInfoMap);
|
|
3557
|
-
log2?.info(`
|
|
3682
|
+
log2?.info(`WebSocket connected, ${count} chats cached`);
|
|
3558
3683
|
await this.opts.onSessionReady?.({
|
|
3559
3684
|
activeSessionId: this.activeSessionId,
|
|
3560
3685
|
ws: this.opts.ws,
|
|
@@ -3568,7 +3693,7 @@ var ParallAgentGateway = class {
|
|
|
3568
3693
|
const expectedMs = intervalSec * 1e3;
|
|
3569
3694
|
const drift = now - this.lastHeartbeatAt - expectedMs;
|
|
3570
3695
|
if (drift > 15e3) {
|
|
3571
|
-
log2?.warn(`
|
|
3696
|
+
log2?.warn(`heartbeat drift ${drift}ms \u2014 event loop may be blocked`);
|
|
3572
3697
|
}
|
|
3573
3698
|
this.lastHeartbeatAt = now;
|
|
3574
3699
|
if (this.opts.ws.state !== "connected")
|
|
@@ -3584,10 +3709,10 @@ var ParallAgentGateway = class {
|
|
|
3584
3709
|
const isFirstHello = !this.hadSuccessfulHello;
|
|
3585
3710
|
this.hadSuccessfulHello = true;
|
|
3586
3711
|
this.catchUpFromDispatch(isFirstHello).catch((err) => {
|
|
3587
|
-
log2?.warn(`
|
|
3712
|
+
log2?.warn(`dispatch catch-up failed: ${String(err)}`);
|
|
3588
3713
|
});
|
|
3589
3714
|
} catch (err) {
|
|
3590
|
-
log2?.error(`
|
|
3715
|
+
log2?.error(`failed to fetch chats: ${String(err)}`);
|
|
3591
3716
|
}
|
|
3592
3717
|
}
|
|
3593
3718
|
// Resolves when in-flight dispatches hit 0 or the deadline elapses.
|
|
@@ -3613,12 +3738,12 @@ var ParallAgentGateway = class {
|
|
|
3613
3738
|
async shutdown() {
|
|
3614
3739
|
this.shuttingDown = true;
|
|
3615
3740
|
if (this.inFlightDispatches > 0) {
|
|
3616
|
-
this.opts.log?.info(`
|
|
3741
|
+
this.opts.log?.info(`draining ${this.inFlightDispatches} in-flight dispatch(es), deadline ${this.SHUTDOWN_DEADLINE_MS}ms`);
|
|
3617
3742
|
await this.waitForDrain(this.SHUTDOWN_DEADLINE_MS);
|
|
3618
3743
|
if (this.inFlightDispatches > 0) {
|
|
3619
|
-
this.opts.log?.warn(`
|
|
3744
|
+
this.opts.log?.warn(`drain deadline hit; ${this.inFlightDispatches} dispatch(es) still running \u2014 they will be killed by process exit`);
|
|
3620
3745
|
} else {
|
|
3621
|
-
this.opts.log?.info(`
|
|
3746
|
+
this.opts.log?.info(`drain complete`);
|
|
3622
3747
|
}
|
|
3623
3748
|
}
|
|
3624
3749
|
if (this.heartbeatTimer)
|
|
@@ -3629,7 +3754,7 @@ var ParallAgentGateway = class {
|
|
|
3629
3754
|
this.activeDispatches.clear();
|
|
3630
3755
|
await this.opts.onBeforeDisconnect?.();
|
|
3631
3756
|
this.opts.ws.disconnect();
|
|
3632
|
-
this.opts.log?.info(`
|
|
3757
|
+
this.opts.log?.info(`disconnected`);
|
|
3633
3758
|
}
|
|
3634
3759
|
};
|
|
3635
3760
|
|
|
@@ -4243,8 +4368,8 @@ function resolveCodexAgentConfig(env = process.env) {
|
|
|
4243
4368
|
const apiKey = requireEnv(env, "PRLL_API_KEY");
|
|
4244
4369
|
const orgId = requireEnv(env, "PRLL_ORG_ID");
|
|
4245
4370
|
const codexHome = resolvePath(env.PRLL_CODEX_HOME?.trim() || env.CODEX_HOME?.trim() || path4.join(env.HOME || os2.homedir(), ".codex"));
|
|
4246
|
-
const stateDir = resolvePath(env.
|
|
4247
|
-
const workspaceDir = resolvePath(env.
|
|
4371
|
+
const stateDir = resolvePath(env.PRLL_STATE_DIR?.trim() || path4.join(env.HOME || os2.homedir(), ".parall-agent"));
|
|
4372
|
+
const workspaceDir = resolvePath(env.PRLL_WORKSPACE_DIR?.trim() || path4.join(stateDir, "workspace"));
|
|
4248
4373
|
return {
|
|
4249
4374
|
apiUrl,
|
|
4250
4375
|
apiKey,
|
|
@@ -5262,7 +5387,7 @@ var CodexAppServerAdapter = class {
|
|
|
5262
5387
|
setActiveTurn(threadId, sink, log2) {
|
|
5263
5388
|
const existing = this.activeTurns.get(threadId);
|
|
5264
5389
|
if (existing) {
|
|
5265
|
-
(log2 ?? this.opts.log)?.warn?.(`
|
|
5390
|
+
(log2 ?? this.opts.log)?.warn?.(`thread ${threadId} already had an active turn; failing the previous dispatch`);
|
|
5266
5391
|
existing.push({ kind: "error", message: `thread ${threadId} replaced by concurrent turn` });
|
|
5267
5392
|
existing.close();
|
|
5268
5393
|
}
|
|
@@ -5296,7 +5421,7 @@ var CodexAppServerAdapter = class {
|
|
|
5296
5421
|
this.pendingInjections.set(sessionKey, (this.pendingInjections.get(sessionKey) ?? 0) + 1);
|
|
5297
5422
|
return true;
|
|
5298
5423
|
} catch (err) {
|
|
5299
|
-
this.opts.log?.warn?.(`
|
|
5424
|
+
this.opts.log?.warn?.(`turn/steer failed: ${errToString(err)}`);
|
|
5300
5425
|
return false;
|
|
5301
5426
|
}
|
|
5302
5427
|
}
|
|
@@ -5309,7 +5434,7 @@ var CodexAppServerAdapter = class {
|
|
|
5309
5434
|
this.pendingInjections.delete(sessionKey);
|
|
5310
5435
|
const threadId2 = this.opts.sessionManager.getThreadId(sessionKey);
|
|
5311
5436
|
if (threadId2 && this.client && !this.client.isDisposed()) {
|
|
5312
|
-
(this.opts.log ?? context.log)?.info?.(
|
|
5437
|
+
(this.opts.log ?? context.log)?.info?.(`${pending} steer injection(s) already sent; skipping turn/start`);
|
|
5313
5438
|
yield {
|
|
5314
5439
|
type: "runtime_session",
|
|
5315
5440
|
runtimeSessionId: threadId2,
|
|
@@ -5317,7 +5442,7 @@ var CodexAppServerAdapter = class {
|
|
|
5317
5442
|
};
|
|
5318
5443
|
return;
|
|
5319
5444
|
}
|
|
5320
|
-
(this.opts.log ?? context.log)?.warn?.(`
|
|
5445
|
+
(this.opts.log ?? context.log)?.warn?.(`pending steer invalidated (subprocess died); falling through to normal dispatch`);
|
|
5321
5446
|
}
|
|
5322
5447
|
await this.ensureStarted(context.log);
|
|
5323
5448
|
const client = this.client;
|
|
@@ -5343,7 +5468,7 @@ var CodexAppServerAdapter = class {
|
|
|
5343
5468
|
this.opts.sessionManager.recordThreadId(sessionKey, threadId);
|
|
5344
5469
|
this.resumedThreadIds.add(threadId);
|
|
5345
5470
|
} catch (err) {
|
|
5346
|
-
log2?.warn?.(`
|
|
5471
|
+
log2?.warn?.(`thread/resume failed (${errToString(err)}); attempting one-shot fresh-thread start`);
|
|
5347
5472
|
let freshThreadId;
|
|
5348
5473
|
try {
|
|
5349
5474
|
freshThreadId = await this.openThread(client, { resumeId: void 0 });
|
|
@@ -5378,7 +5503,7 @@ var CodexAppServerAdapter = class {
|
|
|
5378
5503
|
preparedImages = prepared.attachments.images;
|
|
5379
5504
|
releasePreparedAttachments = pinLocalAttachmentPaths(preparedImages);
|
|
5380
5505
|
} catch (err) {
|
|
5381
|
-
log2?.warn?.(`
|
|
5506
|
+
log2?.warn?.(`failed to prepare local attachments: ${errToString(err)}`);
|
|
5382
5507
|
}
|
|
5383
5508
|
const turnInput = buildTurnInput(preparedBody, preparedImages);
|
|
5384
5509
|
const startTurn = (targetThreadId) => client.sendRequest("turn/start", {
|
|
@@ -5399,7 +5524,7 @@ var CodexAppServerAdapter = class {
|
|
|
5399
5524
|
yield { type: "error", message: `Codex turn/start failed: ${message}` };
|
|
5400
5525
|
return;
|
|
5401
5526
|
}
|
|
5402
|
-
log2?.warn?.(`
|
|
5527
|
+
log2?.warn?.(`turn/start on thread ${threadId} failed (${message}); attempting one-shot fresh-thread retry`);
|
|
5403
5528
|
this.activeTurns.delete(threadId);
|
|
5404
5529
|
let freshThreadId;
|
|
5405
5530
|
try {
|
|
@@ -5500,7 +5625,7 @@ var CodexAppServerAdapter = class {
|
|
|
5500
5625
|
const result = await client.sendRequest("thread/fork", forkParams);
|
|
5501
5626
|
const forkedThreadId = extractThreadId(result);
|
|
5502
5627
|
if (!forkedThreadId) {
|
|
5503
|
-
this.opts.log?.warn?.("
|
|
5628
|
+
this.opts.log?.warn?.("thread/fork returned no thread id");
|
|
5504
5629
|
return null;
|
|
5505
5630
|
}
|
|
5506
5631
|
this.opts.sessionManager.recordThreadId(handle.sessionKey, forkedThreadId);
|
|
@@ -5513,7 +5638,7 @@ var CodexAppServerAdapter = class {
|
|
|
5513
5638
|
this.opts.sessionManager.cleanupFork(fork.sessionKey);
|
|
5514
5639
|
}
|
|
5515
5640
|
logForkFailure(err) {
|
|
5516
|
-
this.opts.log?.warn?.(`
|
|
5641
|
+
this.opts.log?.warn?.(`thread/fork failed: ${errToString(err)}`);
|
|
5517
5642
|
return null;
|
|
5518
5643
|
}
|
|
5519
5644
|
async stop() {
|
|
@@ -5571,7 +5696,7 @@ var CodexAppServerAdapter = class {
|
|
|
5571
5696
|
env.PRLL_CONTEXT_FILE = this.opts.contextFilePath;
|
|
5572
5697
|
}
|
|
5573
5698
|
const args = ["app-server", "--listen", "stdio://"];
|
|
5574
|
-
(log2 ?? this.opts.log)?.info?.(`
|
|
5699
|
+
(log2 ?? this.opts.log)?.info?.(`spawning ${this.opts.codexBin} ${args.join(" ")}`);
|
|
5575
5700
|
const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.codexBin) : this.opts.codexBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
|
|
5576
5701
|
cwd: this.opts.workspaceDir,
|
|
5577
5702
|
env,
|
|
@@ -5580,7 +5705,7 @@ var CodexAppServerAdapter = class {
|
|
|
5580
5705
|
});
|
|
5581
5706
|
proc.stderr.setEncoding("utf8");
|
|
5582
5707
|
proc.stderr.on("data", (chunk) => {
|
|
5583
|
-
(log2 ?? this.opts.log)?.warn?.(`
|
|
5708
|
+
(log2 ?? this.opts.log)?.warn?.(`[stderr] ${chunk.trim()}`);
|
|
5584
5709
|
});
|
|
5585
5710
|
const client = new JsonRpcStdioClient(proc, void 0, (p) => {
|
|
5586
5711
|
if (!IS_WIN32 || !p.pid || !killWin32Tree(p.pid)) {
|
|
@@ -5615,9 +5740,9 @@ var CodexAppServerAdapter = class {
|
|
|
5615
5740
|
const reason = err ? `spawn error: ${err.message}` : `exited (code=${code ?? "null"}${signal ? `, signal=${signal}` : ""})`;
|
|
5616
5741
|
const logger = log2 ?? this.opts.log;
|
|
5617
5742
|
if (this.stopping) {
|
|
5618
|
-
logger?.info?.(`
|
|
5743
|
+
logger?.info?.(`app-server subprocess ${reason} during graceful stop`);
|
|
5619
5744
|
} else {
|
|
5620
|
-
logger?.warn?.(`
|
|
5745
|
+
logger?.warn?.(`app-server subprocess ${reason}; resetting adapter`);
|
|
5621
5746
|
}
|
|
5622
5747
|
this.client?.dispose(err ?? new Error(`app-server ${reason}`));
|
|
5623
5748
|
for (const activeSink of this.activeTurns.values()) {
|
|
@@ -6641,9 +6766,12 @@ function ensureParallProvider(codexHome, apiUrl, log2) {
|
|
|
6641
6766
|
].join("\n");
|
|
6642
6767
|
const headerIdx = content.indexOf(sectionHeader);
|
|
6643
6768
|
if (headerIdx !== -1) {
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6769
|
+
let blockEnd = findSectionEnd(content, headerIdx + sectionHeader.length + 1);
|
|
6770
|
+
let authIdx = content.indexOf(authHeader, blockEnd);
|
|
6771
|
+
while (authIdx !== -1 && content.substring(blockEnd, authIdx).trim() === "") {
|
|
6772
|
+
blockEnd = findSectionEnd(content, authIdx + authHeader.length + 1);
|
|
6773
|
+
authIdx = content.indexOf(authHeader, blockEnd);
|
|
6774
|
+
}
|
|
6647
6775
|
content = content.substring(0, headerIdx) + providerBlock + content.substring(blockEnd);
|
|
6648
6776
|
} else {
|
|
6649
6777
|
content = content.trimEnd() + "\n\n" + providerBlock + "\n";
|
|
@@ -6682,6 +6810,7 @@ ${systemPrompt.replace(/\\/g, "\\\\").replace(/"""/g, '\\"""')}
|
|
|
6682
6810
|
|
|
6683
6811
|
// ts/codex-agent/dist/index.js
|
|
6684
6812
|
var log = createLogger("codex-agent");
|
|
6813
|
+
var activeLog = log;
|
|
6685
6814
|
async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
6686
6815
|
try {
|
|
6687
6816
|
return await client.getAgentMe(orgId);
|
|
@@ -6693,7 +6822,24 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
|
6693
6822
|
return { ...user, agent_profile: null };
|
|
6694
6823
|
}
|
|
6695
6824
|
}
|
|
6825
|
+
function resolveProviderEnv() {
|
|
6826
|
+
const pc = parseProviderConfig(process.env);
|
|
6827
|
+
if (!pc)
|
|
6828
|
+
return;
|
|
6829
|
+
clearAllProviderCreds(process.env);
|
|
6830
|
+
const source = llmSource(pc);
|
|
6831
|
+
if (source === "parall") {
|
|
6832
|
+
process.env.OPENAI_API_KEY = process.env.PRLL_API_KEY;
|
|
6833
|
+
process.env.OPENAI_BASE_URL = `${process.env.PRLL_API_URL}/api/llm/v1`;
|
|
6834
|
+
} else if (source === "custom") {
|
|
6835
|
+
if (pc.openai_api_key)
|
|
6836
|
+
process.env.OPENAI_API_KEY = pc.openai_api_key;
|
|
6837
|
+
if (pc.openai_base_url)
|
|
6838
|
+
process.env.OPENAI_BASE_URL = pc.openai_base_url;
|
|
6839
|
+
}
|
|
6840
|
+
}
|
|
6696
6841
|
async function main() {
|
|
6842
|
+
resolveProviderEnv();
|
|
6697
6843
|
const config = resolveCodexAgentConfig(process.env);
|
|
6698
6844
|
const client = new ParallClient({
|
|
6699
6845
|
baseUrl: config.apiUrl,
|
|
@@ -6702,13 +6848,15 @@ async function main() {
|
|
|
6702
6848
|
});
|
|
6703
6849
|
const me = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
6704
6850
|
const agentUserId = me.id;
|
|
6705
|
-
|
|
6851
|
+
const agentLog = childLogger(log, agentUserId);
|
|
6852
|
+
activeLog = agentLog;
|
|
6853
|
+
ensureWorkspaceTrusted(config.codexHome, config.workspaceDir, agentLog);
|
|
6706
6854
|
const useParallProvider = isParallProxyMode();
|
|
6707
6855
|
if (useParallProvider) {
|
|
6708
|
-
ensureParallProvider(config.codexHome, config.apiUrl,
|
|
6709
|
-
|
|
6856
|
+
ensureParallProvider(config.codexHome, config.apiUrl, agentLog);
|
|
6857
|
+
agentLog.info("parall custom provider configured (Responses API HTTP/SSE mode)");
|
|
6710
6858
|
}
|
|
6711
|
-
ensureCodexWorkspace(config.workspaceDir,
|
|
6859
|
+
ensureCodexWorkspace(config.workspaceDir, agentLog, {
|
|
6712
6860
|
userId: agentUserId,
|
|
6713
6861
|
displayName: me.display_name,
|
|
6714
6862
|
description: me.agent_profile?.description ?? void 0
|
|
@@ -6716,21 +6864,21 @@ async function main() {
|
|
|
6716
6864
|
const runtimeKey = config.runtimeKey || buildCodexRuntimeKey(agentUserId);
|
|
6717
6865
|
const mainContextFilePath = contextFilePathForSession(config.stateDir, runtimeKey);
|
|
6718
6866
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
6719
|
-
const sessionManager = new CodexSessionManager(runtimeKey, sessionStateFilePath,
|
|
6867
|
+
const sessionManager = new CodexSessionManager(runtimeKey, sessionStateFilePath, agentLog);
|
|
6720
6868
|
const resolvedWsUrl = resolveWsUrl(config.apiUrl, config.wsUrl, config.swimlaneName);
|
|
6721
6869
|
const ws = new ParallWs({
|
|
6722
6870
|
getTicket: () => client.getWsTicket(),
|
|
6723
6871
|
wsUrl: resolvedWsUrl
|
|
6724
6872
|
});
|
|
6725
|
-
const configMgr = createPlatformConfigManager({ client, stateDir: config.stateDir, runtimeType: "codex", log });
|
|
6873
|
+
const configMgr = createPlatformConfigManager({ client, stateDir: config.stateDir, runtimeType: "codex", log: agentLog });
|
|
6726
6874
|
const platformDefaults = await configMgr.fetch();
|
|
6727
6875
|
let platformManaged = isPlatformManagedProfile(me.agent_profile);
|
|
6728
6876
|
const resolvedModel = platformManaged ? platformDefaults.model ?? config.model : config.model;
|
|
6729
6877
|
const resolvedEffort = platformManaged ? platformDefaults.thinkingEffort ?? config.reasoningEffort : config.reasoningEffort;
|
|
6730
6878
|
if (platformDefaults.model)
|
|
6731
|
-
|
|
6879
|
+
agentLog.info(`platform config: model=${platformDefaults.model} (${platformManaged ? "applied" : "ignored, model_management=self"})`);
|
|
6732
6880
|
if (platformDefaults.thinkingEffort)
|
|
6733
|
-
|
|
6881
|
+
agentLog.info(`platform config: reasoning_effort=${platformDefaults.thinkingEffort} (${platformManaged ? "applied" : "ignored, model_management=self"})`);
|
|
6734
6882
|
const adapter = new CodexAppServerAdapter({
|
|
6735
6883
|
codexBin: config.codexBin,
|
|
6736
6884
|
codexHome: config.codexHome,
|
|
@@ -6740,7 +6888,7 @@ async function main() {
|
|
|
6740
6888
|
sandbox: config.sandbox,
|
|
6741
6889
|
approvalPolicy: config.approvalPolicy,
|
|
6742
6890
|
sessionManager,
|
|
6743
|
-
log,
|
|
6891
|
+
log: agentLog,
|
|
6744
6892
|
contextFilePath: mainContextFilePath,
|
|
6745
6893
|
useParallProvider
|
|
6746
6894
|
});
|
|
@@ -6765,7 +6913,7 @@ async function main() {
|
|
|
6765
6913
|
driver: "app-server"
|
|
6766
6914
|
},
|
|
6767
6915
|
dispatchAdapter: adapter,
|
|
6768
|
-
log,
|
|
6916
|
+
log: agentLog,
|
|
6769
6917
|
shutdownDeadlineMs: parseShutdownDeadlineMs(process.env.PRLL_SHUTDOWN_DEADLINE_MS),
|
|
6770
6918
|
contextFilePathForSession: (sessionKey) => contextFilePathForSession(config.stateDir, sessionKey),
|
|
6771
6919
|
stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
|
|
@@ -6786,6 +6934,12 @@ async function main() {
|
|
|
6786
6934
|
model: platformManaged ? updated.model ?? config.model : config.model ?? null,
|
|
6787
6935
|
reasoningEffort: platformManaged ? updated.thinkingEffort ?? config.reasoningEffort : config.reasoningEffort ?? null
|
|
6788
6936
|
});
|
|
6937
|
+
},
|
|
6938
|
+
onNewSession: () => {
|
|
6939
|
+
sessionManager.clearMainThread();
|
|
6940
|
+
},
|
|
6941
|
+
onSessionStale: () => {
|
|
6942
|
+
sessionManager.clearMainThread();
|
|
6789
6943
|
}
|
|
6790
6944
|
});
|
|
6791
6945
|
const abortController = new AbortController();
|
|
@@ -6793,7 +6947,7 @@ async function main() {
|
|
|
6793
6947
|
process.on("SIGINT", abort);
|
|
6794
6948
|
process.on("SIGTERM", abort);
|
|
6795
6949
|
try {
|
|
6796
|
-
|
|
6950
|
+
agentLog.info(`starting self-hosted Codex runtime (app-server driver) for ${me.display_name} (${agentUserId})`);
|
|
6797
6951
|
await gateway.run(abortController.signal);
|
|
6798
6952
|
} finally {
|
|
6799
6953
|
await adapter.stop();
|
|
@@ -6802,7 +6956,7 @@ async function main() {
|
|
|
6802
6956
|
}
|
|
6803
6957
|
}
|
|
6804
6958
|
main().catch((err) => {
|
|
6805
|
-
|
|
6959
|
+
activeLog.error(`fatal: ${String(err)}`);
|
|
6806
6960
|
process.exitCode = 1;
|
|
6807
6961
|
});
|
|
6808
6962
|
/*! Bundled license information:
|