@parall/daemon 1.28.1 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/manifest.json +10 -10
- package/bundle/parall-claude-agent.js +236 -111
- package/bundle/parall-codex-agent.js +335 -129
- package/bundle/parall-daemon.js +848 -137
- package/bundle/parall-openclaw-agent.js +22 -14
- package/dist/config.d.ts +3 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -2
- package/dist/index.js +6 -11
- package/dist/runtimes.d.ts +9 -1
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +49 -3
- package/dist/supervisor.d.ts +14 -6
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +171 -18
- package/dist/workspace.d.ts +11 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +436 -0
- package/package.json +7 -5
|
@@ -112,6 +112,9 @@ function buildEventBody(event) {
|
|
|
112
112
|
}
|
|
113
113
|
return lines.join("\n") + buildSendMessageHint(event);
|
|
114
114
|
}
|
|
115
|
+
function buildEventBodyForForkResult(event) {
|
|
116
|
+
return buildEventBody(event).replace(/\n<system-reminder>[\s\S]*<\/system-reminder>$/, "");
|
|
117
|
+
}
|
|
115
118
|
function buildSendMessageHint(event) {
|
|
116
119
|
if (event.noReply)
|
|
117
120
|
return "";
|
|
@@ -143,14 +146,16 @@ function buildForkResultPrefix(results) {
|
|
|
143
146
|
if (!results.length)
|
|
144
147
|
return "";
|
|
145
148
|
const blocks = results.map((result) => {
|
|
146
|
-
const lines = [
|
|
147
|
-
|
|
149
|
+
const lines = [];
|
|
150
|
+
for (const body of result.eventBodies) {
|
|
151
|
+
lines.push(body);
|
|
152
|
+
}
|
|
153
|
+
lines.push(`[This event was handled by a parallel fork session. Do NOT re-handle, re-reply, or duplicate work for it.]`);
|
|
154
|
+
lines.push(`[Fork summary: ${result.agentSummary ? sanitizeMeta(result.agentSummary) : "No fork summary available \u2014 the fork completed without producing a text summary. Check the target chat/task for any actions the fork already took before acting."}]`);
|
|
148
155
|
if (result.actions.length)
|
|
149
|
-
lines.push(`[
|
|
150
|
-
if (result.agentSummary)
|
|
151
|
-
lines.push(`[Summary: ${sanitizeMeta(result.agentSummary)}]`);
|
|
156
|
+
lines.push(`[Fork actions: ${result.actions.join("; ")}]`);
|
|
152
157
|
if (result.historyPath)
|
|
153
|
-
lines.push(`[
|
|
158
|
+
lines.push(`[Fork history: ${result.historyPath}]`);
|
|
154
159
|
return lines.join("\n");
|
|
155
160
|
});
|
|
156
161
|
return blocks.join("\n\n") + "\n\n---\n\n";
|
|
@@ -418,11 +423,19 @@ Messages may arrive with a \`[Thread: prll://msg_xxx]\` line in the event block,
|
|
|
418
423
|
- Keep thread replies focused on the original topic
|
|
419
424
|
`;
|
|
420
425
|
|
|
426
|
+
// ts/agent-core/dist/logger.js
|
|
427
|
+
function createLogger(prefix) {
|
|
428
|
+
return {
|
|
429
|
+
info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
430
|
+
warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
431
|
+
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`)
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
|
|
421
435
|
// ts/agent-core/dist/gateway-base.js
|
|
422
436
|
import * as os from "node:os";
|
|
423
437
|
import * as fs from "node:fs";
|
|
424
438
|
import * as path from "node:path";
|
|
425
|
-
import { randomUUID } from "node:crypto";
|
|
426
439
|
|
|
427
440
|
// ts/sdk/dist/types.js
|
|
428
441
|
var MENTION_ALL_USER_ID = "all";
|
|
@@ -440,6 +453,8 @@ var ENDPOINTS = {
|
|
|
440
453
|
AUTH_CHECK_EMAIL: `${API_BASE}/auth/check-email`,
|
|
441
454
|
AUTH_VERIFY_EMAIL: `${API_BASE}/auth/verify-email`,
|
|
442
455
|
AUTH_RESEND_CODE: `${API_BASE}/auth/resend-code`,
|
|
456
|
+
AUTH_FORGOT_PASSWORD: `${API_BASE}/auth/forgot-password`,
|
|
457
|
+
AUTH_RESET_PASSWORD: `${API_BASE}/auth/reset-password`,
|
|
443
458
|
// Users
|
|
444
459
|
USERS_ME: `${API_BASE}/users/me`,
|
|
445
460
|
USER_AVATAR: `${API_BASE}/users/me/avatar`,
|
|
@@ -473,8 +488,10 @@ var ENDPOINTS = {
|
|
|
473
488
|
CHAT_MESSAGES: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/messages`,
|
|
474
489
|
// Messages (global, by message ID)
|
|
475
490
|
MESSAGE: (id) => `${API_BASE}/messages/${id}`,
|
|
476
|
-
MESSAGE_PATCHES: (id) => `${API_BASE}/messages/${id}/patches`,
|
|
477
491
|
MESSAGE_REPLIES: (id) => `${API_BASE}/messages/${id}/replies`,
|
|
492
|
+
MESSAGE_WATCH: (id) => `${API_BASE}/messages/${id}/watch`,
|
|
493
|
+
MESSAGE_WATCHERS: (id) => `${API_BASE}/messages/${id}/watchers`,
|
|
494
|
+
MESSAGE_WATCHING: (id) => `${API_BASE}/messages/${id}/watching`,
|
|
478
495
|
// Upload (org-scoped)
|
|
479
496
|
UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
|
|
480
497
|
UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
|
|
@@ -500,6 +517,7 @@ var ENDPOINTS = {
|
|
|
500
517
|
AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
|
|
501
518
|
AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
|
|
502
519
|
AGENT_SESSION_STEP: (orgId, agentId, sessionId, stepId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps/${stepId}`,
|
|
520
|
+
AGENT_STEP_BY_ID: (orgId, stepId) => `${API_BASE}/orgs/${orgId}/agent-steps/${stepId}`,
|
|
503
521
|
AGENT_TASKS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/tasks`,
|
|
504
522
|
AGENT_RUNTIME_AUTH: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/runtime-auth`,
|
|
505
523
|
AGENT_RUNTIME_AUTH_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/runtime-auth-sessions`,
|
|
@@ -524,9 +542,15 @@ var ENDPOINTS = {
|
|
|
524
542
|
// Attach/Detach bind an agent to/from a daemon Machine.
|
|
525
543
|
MACHINE_ATTACH_AGENT: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}`,
|
|
526
544
|
MACHINE_DETACH_AGENT: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}`,
|
|
545
|
+
MACHINE_WORKSPACE_STATES: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/workspace-states`,
|
|
546
|
+
MACHINE_AGENT_DAEMON_CONFIG: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/daemon-config`,
|
|
547
|
+
MACHINE_AGENT_WORKSPACE_SETUP: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/workspace/setup`,
|
|
548
|
+
MACHINE_LLM_SOURCE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
|
|
527
549
|
MACHINE_RUNTIME_AUTH: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
|
|
528
550
|
MACHINE_KEYS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys`,
|
|
529
551
|
MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
|
|
552
|
+
MACHINE_RUNTIME_AUTH_SESSIONS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions`,
|
|
553
|
+
MACHINE_RUNTIME_AUTH_SESSION_COMPLETE: (orgId, machineId, sessionId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions/${sessionId}/complete`,
|
|
530
554
|
// Machine self-control-plane (mck_-scoped). The bearer token implicitly
|
|
531
555
|
// identifies the Machine, so there is no `:mid` URL parameter — these are
|
|
532
556
|
// "self" routes called by the daemon for its own host.
|
|
@@ -534,6 +558,7 @@ var ENDPOINTS = {
|
|
|
534
558
|
MACHINES_ME_AGENTS: `${API_BASE}/machines/me/agents`,
|
|
535
559
|
MACHINES_ME_HEALTH: `${API_BASE}/machines/me/health`,
|
|
536
560
|
MACHINES_ME_AGENT_LAUNCH_CREDENTIAL: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/launch-credential`,
|
|
561
|
+
MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/workspace-state`,
|
|
537
562
|
MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
|
|
538
563
|
// Tasks (org-scoped)
|
|
539
564
|
TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
|
|
@@ -713,7 +738,8 @@ var WS_EVENTS = {
|
|
|
713
738
|
MACHINE_HELLO: "machine.hello",
|
|
714
739
|
MACHINE_AGENT_ATTACHED: "machine.agent.attached",
|
|
715
740
|
MACHINE_AGENT_DETACHED: "machine.agent.detached",
|
|
716
|
-
MACHINE_STOP: "machine.stop"
|
|
741
|
+
MACHINE_STOP: "machine.stop",
|
|
742
|
+
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested"
|
|
717
743
|
};
|
|
718
744
|
|
|
719
745
|
// ts/sdk/dist/client.js
|
|
@@ -733,7 +759,9 @@ var ParallClient = class _ParallClient {
|
|
|
733
759
|
"/auth/logout",
|
|
734
760
|
"/auth/verify-email",
|
|
735
761
|
"/auth/resend-code",
|
|
736
|
-
"/auth/check-email"
|
|
762
|
+
"/auth/check-email",
|
|
763
|
+
"/auth/forgot-password",
|
|
764
|
+
"/auth/reset-password"
|
|
737
765
|
]);
|
|
738
766
|
/** Proactive refresh when token expires within this window (seconds). */
|
|
739
767
|
static REFRESH_THRESHOLD_S = 5 * 60;
|
|
@@ -971,6 +999,12 @@ var ParallClient = class _ParallClient {
|
|
|
971
999
|
async resendCode(email) {
|
|
972
1000
|
return this.request("POST", ENDPOINTS.AUTH_RESEND_CODE, { email });
|
|
973
1001
|
}
|
|
1002
|
+
async forgotPassword(email) {
|
|
1003
|
+
return this.request("POST", ENDPOINTS.AUTH_FORGOT_PASSWORD, { email });
|
|
1004
|
+
}
|
|
1005
|
+
async resetPassword(token, newPassword) {
|
|
1006
|
+
return this.request("POST", ENDPOINTS.AUTH_RESET_PASSWORD, { token, new_password: newPassword });
|
|
1007
|
+
}
|
|
974
1008
|
// ---- WebSocket ----
|
|
975
1009
|
async getWsTicket() {
|
|
976
1010
|
return this.request("POST", ENDPOINTS.WS_TICKET);
|
|
@@ -1167,9 +1201,6 @@ var ParallClient = class _ParallClient {
|
|
|
1167
1201
|
async deleteMessage(id) {
|
|
1168
1202
|
return this.request("DELETE", ENDPOINTS.MESSAGE(id));
|
|
1169
1203
|
}
|
|
1170
|
-
async patchMessage(id, req) {
|
|
1171
|
-
return this.request("POST", ENDPOINTS.MESSAGE_PATCHES(id), req);
|
|
1172
|
-
}
|
|
1173
1204
|
async getMessageReplies(id, params) {
|
|
1174
1205
|
return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
|
|
1175
1206
|
}
|
|
@@ -1180,8 +1211,8 @@ var ParallClient = class _ParallClient {
|
|
|
1180
1211
|
async completeUpload(orgId, attachmentId) {
|
|
1181
1212
|
return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
|
|
1182
1213
|
}
|
|
1183
|
-
async getFileUrl(id) {
|
|
1184
|
-
return this.request("GET", ENDPOINTS.FILE(id));
|
|
1214
|
+
async getFileUrl(id, opts) {
|
|
1215
|
+
return this.request("GET", ENDPOINTS.FILE(id), void 0, opts?.download ? { download: true } : void 0);
|
|
1185
1216
|
}
|
|
1186
1217
|
// ---- Approvals ----
|
|
1187
1218
|
async getApproval(id) {
|
|
@@ -1262,8 +1293,7 @@ var ParallClient = class _ParallClient {
|
|
|
1262
1293
|
* @param params.status - Comma-separated status filter (e.g., `'open'`).
|
|
1263
1294
|
*/
|
|
1264
1295
|
async getAgentSessions(orgId, agentId, params) {
|
|
1265
|
-
|
|
1266
|
-
return res.data;
|
|
1296
|
+
return this.request("GET", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), void 0, params);
|
|
1267
1297
|
}
|
|
1268
1298
|
async getAgentSession(orgId, agentId, sessionId) {
|
|
1269
1299
|
return this.request("GET", ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId));
|
|
@@ -1275,12 +1305,14 @@ var ParallClient = class _ParallClient {
|
|
|
1275
1305
|
return this.request("POST", ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), req);
|
|
1276
1306
|
}
|
|
1277
1307
|
async getAgentSessionSteps(orgId, agentId, sessionId, params) {
|
|
1278
|
-
|
|
1279
|
-
return res.data;
|
|
1308
|
+
return this.request("GET", ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), void 0, params);
|
|
1280
1309
|
}
|
|
1281
1310
|
async getAgentSessionStep(orgId, agentId, sessionId, stepId) {
|
|
1282
1311
|
return this.request("GET", ENDPOINTS.AGENT_SESSION_STEP(orgId, agentId, sessionId, stepId));
|
|
1283
1312
|
}
|
|
1313
|
+
async getAgentStepById(orgId, stepId) {
|
|
1314
|
+
return this.request("GET", ENDPOINTS.AGENT_STEP_BY_ID(orgId, stepId));
|
|
1315
|
+
}
|
|
1284
1316
|
// ---- Agent runtime auth (hosted Claude OAuth) ----
|
|
1285
1317
|
async getAgentRuntimeAuth(orgId, agentId) {
|
|
1286
1318
|
return this.request("GET", ENDPOINTS.AGENT_RUNTIME_AUTH(orgId, agentId));
|
|
@@ -1377,10 +1409,32 @@ var ParallClient = class _ParallClient {
|
|
|
1377
1409
|
async detachAgent(orgId, machineId, agentId) {
|
|
1378
1410
|
return this.request("DELETE", ENDPOINTS.MACHINE_DETACH_AGENT(orgId, machineId, agentId));
|
|
1379
1411
|
}
|
|
1412
|
+
async listAgentWorkspaceStates(orgId, machineId) {
|
|
1413
|
+
const res = await this.request("GET", ENDPOINTS.MACHINE_WORKSPACE_STATES(orgId, machineId));
|
|
1414
|
+
return res.data;
|
|
1415
|
+
}
|
|
1416
|
+
async patchAgentDaemonConfig(orgId, machineId, agentId, daemonConfig) {
|
|
1417
|
+
return this.request("PATCH", ENDPOINTS.MACHINE_AGENT_DAEMON_CONFIG(orgId, machineId, agentId), { daemon_config: daemonConfig });
|
|
1418
|
+
}
|
|
1419
|
+
async retryAgentWorkspaceSetup(orgId, machineId, agentId) {
|
|
1420
|
+
return this.request("POST", ENDPOINTS.MACHINE_AGENT_WORKSPACE_SETUP(orgId, machineId, agentId));
|
|
1421
|
+
}
|
|
1422
|
+
async patchMachineLLMSource(orgId, machineId, llmSource) {
|
|
1423
|
+
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), { llm_source: llmSource });
|
|
1424
|
+
}
|
|
1380
1425
|
/** Get machine-level runtime auth state. */
|
|
1381
1426
|
async getMachineRuntimeAuth(orgId, machineId) {
|
|
1382
1427
|
return this.request("GET", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
|
|
1383
1428
|
}
|
|
1429
|
+
async startMachineRuntimeAuthSession(orgId, machineId, req = {}) {
|
|
1430
|
+
return this.request("POST", ENDPOINTS.MACHINE_RUNTIME_AUTH_SESSIONS(orgId, machineId), req);
|
|
1431
|
+
}
|
|
1432
|
+
async completeMachineRuntimeAuthSession(orgId, machineId, sessionId, req) {
|
|
1433
|
+
return this.request("POST", ENDPOINTS.MACHINE_RUNTIME_AUTH_SESSION_COMPLETE(orgId, machineId, sessionId), req);
|
|
1434
|
+
}
|
|
1435
|
+
async disconnectMachineRuntimeAuth(orgId, machineId) {
|
|
1436
|
+
return this.request("DELETE", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
|
|
1437
|
+
}
|
|
1384
1438
|
// ---- Machine self-control-plane (mck_-scoped) ----
|
|
1385
1439
|
//
|
|
1386
1440
|
// The four methods below are intended to be called from a daemon-mode
|
|
@@ -1410,6 +1464,12 @@ var ParallClient = class _ParallClient {
|
|
|
1410
1464
|
async postMachineHeartbeat() {
|
|
1411
1465
|
return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH);
|
|
1412
1466
|
}
|
|
1467
|
+
async reportAgentWorkspaceState(agentId, state) {
|
|
1468
|
+
const res = await this.request("PUT", ENDPOINTS.MACHINES_ME_AGENT_WORKSPACE_STATE(agentId), state);
|
|
1469
|
+
if (res?.status === "ignored_stale") {
|
|
1470
|
+
throw new ApiError(409, "Workspace state report ignored as stale", "STALE_WORKSPACE_STATE");
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1413
1473
|
/**
|
|
1414
1474
|
* `POST /machines/me/agents/{agentId}/launch-credential` — mint a
|
|
1415
1475
|
* short-lived `agk_*` for one of this Machine's attached agents. The
|
|
@@ -1559,6 +1619,20 @@ var ParallClient = class _ParallClient {
|
|
|
1559
1619
|
const res = await this.request("GET", ENDPOINTS.TASK_WATCHERS(orgId, taskId));
|
|
1560
1620
|
return res.data;
|
|
1561
1621
|
}
|
|
1622
|
+
async watchThread(threadRootId) {
|
|
1623
|
+
return this.request("POST", ENDPOINTS.MESSAGE_WATCH(threadRootId));
|
|
1624
|
+
}
|
|
1625
|
+
async unwatchThread(threadRootId) {
|
|
1626
|
+
return this.request("DELETE", ENDPOINTS.MESSAGE_WATCH(threadRootId));
|
|
1627
|
+
}
|
|
1628
|
+
async getThreadWatchers(threadRootId) {
|
|
1629
|
+
const res = await this.request("GET", ENDPOINTS.MESSAGE_WATCHERS(threadRootId));
|
|
1630
|
+
return res.data;
|
|
1631
|
+
}
|
|
1632
|
+
async isWatchingThread(threadRootId) {
|
|
1633
|
+
const res = await this.request("GET", ENDPOINTS.MESSAGE_WATCHING(threadRootId));
|
|
1634
|
+
return res.watching;
|
|
1635
|
+
}
|
|
1562
1636
|
async getSubtasks(orgId, taskId) {
|
|
1563
1637
|
const res = await this.request("GET", ENDPOINTS.TASK_SUBTASKS(orgId, taskId));
|
|
1564
1638
|
return res.data;
|
|
@@ -1855,14 +1929,28 @@ var ParallClient = class _ParallClient {
|
|
|
1855
1929
|
params.set("machine_id", opts.machine_id);
|
|
1856
1930
|
if (opts?.unresolved_machine)
|
|
1857
1931
|
params.set("unresolved_machine", "true");
|
|
1932
|
+
if (opts?.from)
|
|
1933
|
+
params.set("from", opts.from);
|
|
1934
|
+
if (opts?.to)
|
|
1935
|
+
params.set("to", opts.to);
|
|
1858
1936
|
const qs = params.toString();
|
|
1859
1937
|
return this.request("GET", `${ENDPOINTS.BILLING_TRANSACTIONS(orgId)}${qs ? `?${qs}` : ""}`);
|
|
1860
1938
|
}
|
|
1861
|
-
async listBillingTransactionAgentGroups(orgId) {
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1939
|
+
async listBillingTransactionAgentGroups(orgId, opts) {
|
|
1940
|
+
const params = new URLSearchParams({ group_by: "agent" });
|
|
1941
|
+
if (opts?.from)
|
|
1942
|
+
params.set("from", opts.from);
|
|
1943
|
+
if (opts?.to)
|
|
1944
|
+
params.set("to", opts.to);
|
|
1945
|
+
return this.request("GET", `${ENDPOINTS.BILLING_TRANSACTIONS(orgId)}?${params}`);
|
|
1946
|
+
}
|
|
1947
|
+
async listBillingTransactionMachineGroups(orgId, opts) {
|
|
1948
|
+
const params = new URLSearchParams({ group_by: "machine" });
|
|
1949
|
+
if (opts?.from)
|
|
1950
|
+
params.set("from", opts.from);
|
|
1951
|
+
if (opts?.to)
|
|
1952
|
+
params.set("to", opts.to);
|
|
1953
|
+
return this.request("GET", `${ENDPOINTS.BILLING_TRANSACTIONS(orgId)}?${params}`);
|
|
1866
1954
|
}
|
|
1867
1955
|
async createCheckout(orgId, req) {
|
|
1868
1956
|
return this.request("POST", ENDPOINTS.BILLING_CHECKOUT(orgId), req);
|
|
@@ -1913,6 +2001,12 @@ var ApiError = class extends Error {
|
|
|
1913
2001
|
};
|
|
1914
2002
|
|
|
1915
2003
|
// ts/sdk/dist/ws.js
|
|
2004
|
+
function isRetryableNetworkError(err) {
|
|
2005
|
+
return err instanceof Error && err.name === "ApiError" && "status" in err && err.status === 0;
|
|
2006
|
+
}
|
|
2007
|
+
function isBrowserRuntime() {
|
|
2008
|
+
return typeof window !== "undefined";
|
|
2009
|
+
}
|
|
1916
2010
|
var ParallWs = class {
|
|
1917
2011
|
ws = null;
|
|
1918
2012
|
options;
|
|
@@ -1948,7 +2042,11 @@ var ParallWs = class {
|
|
|
1948
2042
|
try {
|
|
1949
2043
|
ticket = await this.options.getTicket();
|
|
1950
2044
|
} catch (err) {
|
|
1951
|
-
|
|
2045
|
+
if (isBrowserRuntime() && isRetryableNetworkError(err)) {
|
|
2046
|
+
console.warn("Failed to get WS ticket:", err);
|
|
2047
|
+
} else {
|
|
2048
|
+
console.error("Failed to get WS ticket:", err);
|
|
2049
|
+
}
|
|
1952
2050
|
if (this.options.reconnect) {
|
|
1953
2051
|
this.scheduleReconnect();
|
|
1954
2052
|
} else {
|
|
@@ -2277,6 +2375,7 @@ var ParallAgentGateway = class {
|
|
|
2277
2375
|
opts;
|
|
2278
2376
|
chatInfoMap = /* @__PURE__ */ new Map();
|
|
2279
2377
|
activeDispatches = /* @__PURE__ */ new Map();
|
|
2378
|
+
injectedTypingCounts = /* @__PURE__ */ new Map();
|
|
2280
2379
|
dispatchedTasks = /* @__PURE__ */ new Set();
|
|
2281
2380
|
dispatchedMessages = /* @__PURE__ */ new Set();
|
|
2282
2381
|
forkStates = /* @__PURE__ */ new Map();
|
|
@@ -2312,9 +2411,9 @@ var ParallAgentGateway = class {
|
|
|
2312
2411
|
this.SHUTDOWN_DEADLINE_MS = opts.shutdownDeadlineMs ?? 6e4;
|
|
2313
2412
|
}
|
|
2314
2413
|
async run(abortSignal) {
|
|
2315
|
-
const { ws, log } = this.opts;
|
|
2414
|
+
const { ws, log: log2 } = this.opts;
|
|
2316
2415
|
ws.onStateChange((state) => {
|
|
2317
|
-
|
|
2416
|
+
log2?.info(`parall[${this.opts.accountId}]: connection state \u2192 ${state}`);
|
|
2318
2417
|
});
|
|
2319
2418
|
ws.on("hello", async (data) => {
|
|
2320
2419
|
await this.handleHello(data);
|
|
@@ -2471,6 +2570,34 @@ var ParallAgentGateway = class {
|
|
|
2471
2570
|
if (this.opts.ws.state === "connected")
|
|
2472
2571
|
this.opts.ws.sendTyping(chatId, "stop");
|
|
2473
2572
|
}
|
|
2573
|
+
shouldShowTyping(event) {
|
|
2574
|
+
return event.type === "message" && event.targetId.startsWith("cht_") && !event.noReply;
|
|
2575
|
+
}
|
|
2576
|
+
startInjectedTyping(event) {
|
|
2577
|
+
if (!this.shouldShowTyping(event))
|
|
2578
|
+
return;
|
|
2579
|
+
this.startTyping(event.targetId);
|
|
2580
|
+
this.injectedTypingCounts.set(event.targetId, (this.injectedTypingCounts.get(event.targetId) ?? 0) + 1);
|
|
2581
|
+
}
|
|
2582
|
+
takeInjectedTypingCount(chatId) {
|
|
2583
|
+
const count = this.injectedTypingCounts.get(chatId) ?? 0;
|
|
2584
|
+
this.injectedTypingCounts.delete(chatId);
|
|
2585
|
+
return count;
|
|
2586
|
+
}
|
|
2587
|
+
async runDispatchWithTyping(event, sessionKey, bodyForAgent, earlierEvents = [], captureText, opts = {}) {
|
|
2588
|
+
const showTyping = !opts.suppressStart && (this.shouldShowTyping(event) || earlierEvents.some((e) => this.shouldShowTyping(e)));
|
|
2589
|
+
if (showTyping)
|
|
2590
|
+
this.startTyping(event.targetId);
|
|
2591
|
+
try {
|
|
2592
|
+
return await this.runDispatch(event, sessionKey, bodyForAgent, earlierEvents, captureText);
|
|
2593
|
+
} finally {
|
|
2594
|
+
if (showTyping)
|
|
2595
|
+
this.stopTyping(event.targetId);
|
|
2596
|
+
for (let i = 0; i < (opts.injectedTypingCount ?? 0); i++) {
|
|
2597
|
+
this.stopTyping(event.targetId);
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2474
2601
|
buildDispatchContext(event, sessionKey) {
|
|
2475
2602
|
const binding = this.sessionBindings.get(sessionKey);
|
|
2476
2603
|
return {
|
|
@@ -2503,7 +2630,8 @@ var ParallAgentGateway = class {
|
|
|
2503
2630
|
trigger_ref: event.type === "task" ? { task_id: event.targetId } : event.type === "task_comment" ? { comment_id: event.messageId, task_id: event.targetId } : event.type === "schedule" ? { schedule_id: event.targetId, run_id: event.messageId } : event.type === "approval" ? { approval_id: event.messageId } : { message_id: event.messageId },
|
|
2504
2631
|
sender_id: event.senderId,
|
|
2505
2632
|
sender_name: event.senderName,
|
|
2506
|
-
summary: event.body.substring(0, 200)
|
|
2633
|
+
summary: event.body.substring(0, 200),
|
|
2634
|
+
...event.sentAt ? { sent_at: event.sentAt } : {}
|
|
2507
2635
|
}
|
|
2508
2636
|
});
|
|
2509
2637
|
} catch (err) {
|
|
@@ -2727,7 +2855,8 @@ var ParallAgentGateway = class {
|
|
|
2727
2855
|
continue;
|
|
2728
2856
|
}
|
|
2729
2857
|
if (!binding) {
|
|
2730
|
-
|
|
2858
|
+
const detail = runtimeEvent.type === "error" ? `: ${runtimeEvent.message}` : "";
|
|
2859
|
+
throw new Error(`runtime emitted ${runtimeEvent.type} before runtime_session${detail}`);
|
|
2731
2860
|
}
|
|
2732
2861
|
if (!triggerMessageSet) {
|
|
2733
2862
|
triggerMessageSet = true;
|
|
@@ -2801,7 +2930,7 @@ var ParallAgentGateway = class {
|
|
|
2801
2930
|
const earlier = events.slice(0, -1);
|
|
2802
2931
|
try {
|
|
2803
2932
|
const batchText = [];
|
|
2804
|
-
const dispatched = await this.
|
|
2933
|
+
const dispatched = await this.runDispatchWithTyping(last, fork.fork.sessionKey, buildForkScopePrefix(last) + buildEventBody(last), earlier, batchText);
|
|
2805
2934
|
if (!dispatched) {
|
|
2806
2935
|
for (const item of items) {
|
|
2807
2936
|
item.resolve(false);
|
|
@@ -2842,6 +2971,7 @@ var ParallAgentGateway = class {
|
|
|
2842
2971
|
targetId: fork.targetId,
|
|
2843
2972
|
summary: fork.processedEvents.length === 1 ? `${first.type} from ${first.senderName} in ${first.targetName ?? fork.targetId}` : `${fork.processedEvents.length} events in ${first.targetName ?? fork.targetId}`
|
|
2844
2973
|
},
|
|
2974
|
+
eventBodies: fork.processedEvents.map((e) => buildEventBodyForForkResult(e)),
|
|
2845
2975
|
actions: [],
|
|
2846
2976
|
agentSummary,
|
|
2847
2977
|
historyPath
|
|
@@ -2881,32 +3011,11 @@ var ParallAgentGateway = class {
|
|
|
2881
3011
|
return;
|
|
2882
3012
|
this.draining = true;
|
|
2883
3013
|
try {
|
|
2884
|
-
while (this.dispatchState.mainBuffer.length > 0
|
|
3014
|
+
while (this.dispatchState.mainBuffer.length > 0) {
|
|
2885
3015
|
if (this.shuttingDown) {
|
|
2886
3016
|
this.opts.log?.info(`parall[${this.opts.accountId}]: drainMainBuffer halted (shutting down) \u2014 ${this.dispatchState.mainBuffer.length} buffered, ${this.dispatchState.pendingForkResults.length} pending fork results left for catch-up`);
|
|
2887
3017
|
break;
|
|
2888
3018
|
}
|
|
2889
|
-
if (this.dispatchState.mainBuffer.length === 0 && this.dispatchState.pendingForkResults.length > 0) {
|
|
2890
|
-
const pending = this.dispatchState.pendingForkResults.splice(0);
|
|
2891
|
-
const forkPrefix2 = buildForkResultPrefix(pending);
|
|
2892
|
-
const syntheticEvent = {
|
|
2893
|
-
type: "message",
|
|
2894
|
-
targetId: "_orchestrator",
|
|
2895
|
-
targetType: "system",
|
|
2896
|
-
senderId: "system",
|
|
2897
|
-
senderName: "system",
|
|
2898
|
-
messageId: `synthetic-${this.opts.accountId}-${randomUUID()}`,
|
|
2899
|
-
body: "[Orchestrator: fork session(s) completed \u2014 review results above]"
|
|
2900
|
-
};
|
|
2901
|
-
this.dispatchState.mainCurrentTargetId = void 0;
|
|
2902
|
-
this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
|
|
2903
|
-
const dispatched2 = await this.runDispatch(syntheticEvent, this.opts.runtimeKey, forkPrefix2 + buildEventBody(syntheticEvent));
|
|
2904
|
-
if (!dispatched2) {
|
|
2905
|
-
this.dispatchState.pendingForkResults.unshift(...pending);
|
|
2906
|
-
break;
|
|
2907
|
-
}
|
|
2908
|
-
continue;
|
|
2909
|
-
}
|
|
2910
3019
|
const targetId = this.dispatchState.mainBuffer[0].targetId;
|
|
2911
3020
|
const events = [];
|
|
2912
3021
|
while (this.dispatchState.mainBuffer[0]?.targetId === targetId) {
|
|
@@ -2914,12 +3023,13 @@ var ParallAgentGateway = class {
|
|
|
2914
3023
|
}
|
|
2915
3024
|
const event = events[events.length - 1];
|
|
2916
3025
|
const earlier = events.slice(0, -1);
|
|
2917
|
-
const
|
|
2918
|
-
const
|
|
3026
|
+
const hasPendingInjections = this.opts.dispatchAdapter.hasPendingInjections?.(this.opts.runtimeKey) ?? false;
|
|
3027
|
+
const injectedTypingCount = hasPendingInjections ? this.takeInjectedTypingCount(event.targetId) : 0;
|
|
3028
|
+
const pendingFork = hasPendingInjections ? [] : this.dispatchState.pendingForkResults.splice(0);
|
|
2919
3029
|
const forkPrefix = buildForkResultPrefix(pendingFork);
|
|
2920
3030
|
this.dispatchState.mainCurrentTargetId = event.targetId;
|
|
2921
3031
|
this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
|
|
2922
|
-
const dispatched = await this.
|
|
3032
|
+
const dispatched = await this.runDispatchWithTyping(event, this.opts.runtimeKey, forkPrefix + buildEventBody(event), earlier, void 0, { suppressStart: injectedTypingCount > 0, injectedTypingCount });
|
|
2923
3033
|
if (!dispatched) {
|
|
2924
3034
|
this.dispatchState.mainBuffer.unshift(...events);
|
|
2925
3035
|
this.dispatchState.pendingForkResults.unshift(...pendingFork);
|
|
@@ -2953,7 +3063,7 @@ var ParallAgentGateway = class {
|
|
|
2953
3063
|
this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
|
|
2954
3064
|
let dispatched = false;
|
|
2955
3065
|
try {
|
|
2956
|
-
dispatched = await this.
|
|
3066
|
+
dispatched = await this.runDispatchWithTyping(event, this.opts.runtimeKey, forkPrefix + buildEventBody(event));
|
|
2957
3067
|
if (!dispatched) {
|
|
2958
3068
|
this.dispatchState.pendingForkResults.unshift(...pendingFork);
|
|
2959
3069
|
}
|
|
@@ -2966,10 +3076,15 @@ var ParallAgentGateway = class {
|
|
|
2966
3076
|
if (this.shuttingDown) {
|
|
2967
3077
|
return false;
|
|
2968
3078
|
}
|
|
2969
|
-
if (this.dispatchState.mainCurrentTargetId === event.targetId && this.opts.dispatchAdapter.enqueueDuringDispatch?.(this.opts.runtimeKey, buildEventBody(event))) {
|
|
2970
|
-
this.opts.log?.info(`parall[${this.opts.accountId}]: steer injected to stdin for ${event.messageId} (will drain for bookkeeping)`);
|
|
2971
|
-
}
|
|
2972
3079
|
this.dispatchState.mainBuffer.push(event);
|
|
3080
|
+
if (this.dispatchState.mainCurrentTargetId === event.targetId && await this.opts.dispatchAdapter.enqueueDuringDispatch?.(this.opts.runtimeKey, buildEventBody(event))) {
|
|
3081
|
+
this.startInjectedTyping(event);
|
|
3082
|
+
this.opts.log?.info(`parall[${this.opts.accountId}]: steer injected for ${event.messageId} (will drain for bookkeeping)`);
|
|
3083
|
+
}
|
|
3084
|
+
if (!this.dispatchState.mainDispatching && !this.draining && this.dispatchState.mainBuffer.length > 0) {
|
|
3085
|
+
this.dispatchState.mainDispatching = true;
|
|
3086
|
+
void this.drainMainBuffer();
|
|
3087
|
+
}
|
|
2973
3088
|
return false;
|
|
2974
3089
|
}
|
|
2975
3090
|
case "buffer-fork": {
|
|
@@ -3071,6 +3186,7 @@ var ParallAgentGateway = class {
|
|
|
3071
3186
|
threadRootId: message.thread_root_id ?? void 0,
|
|
3072
3187
|
noReply: message.hints?.no_reply ?? false,
|
|
3073
3188
|
attachments: attachments.length > 0 ? attachments : void 0,
|
|
3189
|
+
sentAt: message.created_at,
|
|
3074
3190
|
ackSourceType: "message",
|
|
3075
3191
|
ackSourceId: message.id
|
|
3076
3192
|
}
|
|
@@ -3092,9 +3208,6 @@ var ParallAgentGateway = class {
|
|
|
3092
3208
|
return;
|
|
3093
3209
|
}
|
|
3094
3210
|
const event = decision.event;
|
|
3095
|
-
const willDispatch = !this.dispatchState.mainDispatching || this.dispatchState.mainCurrentTargetId !== chatId;
|
|
3096
|
-
if (willDispatch)
|
|
3097
|
-
this.startTyping(chatId);
|
|
3098
3211
|
try {
|
|
3099
3212
|
const dispatched = await this.handleInboundEvent(event);
|
|
3100
3213
|
if (dispatched) {
|
|
@@ -3106,9 +3219,6 @@ var ParallAgentGateway = class {
|
|
|
3106
3219
|
} catch (err) {
|
|
3107
3220
|
this.opts.log?.error(`parall[${this.opts.accountId}]: event dispatch failed for ${data.id}: ${String(err)}`);
|
|
3108
3221
|
this.dispatchedMessages.delete(data.id);
|
|
3109
|
-
} finally {
|
|
3110
|
-
if (willDispatch)
|
|
3111
|
-
this.stopTyping(chatId);
|
|
3112
3222
|
}
|
|
3113
3223
|
}
|
|
3114
3224
|
async handleTaskAssignment(task, ackSourceId) {
|
|
@@ -3138,6 +3248,7 @@ var ParallAgentGateway = class {
|
|
|
3138
3248
|
senderName: "system",
|
|
3139
3249
|
messageId: task.id,
|
|
3140
3250
|
body: parts.join("\n"),
|
|
3251
|
+
sentAt: task.updated_at ?? task.created_at,
|
|
3141
3252
|
ackSourceType: "task_activity",
|
|
3142
3253
|
ackSourceId
|
|
3143
3254
|
};
|
|
@@ -3438,12 +3549,12 @@ var ParallAgentGateway = class {
|
|
|
3438
3549
|
}
|
|
3439
3550
|
}
|
|
3440
3551
|
async handleHello(data) {
|
|
3441
|
-
const { client, config, log } = this.opts;
|
|
3552
|
+
const { client, config, log: log2 } = this.opts;
|
|
3442
3553
|
this.sessionId = data.session_id ?? "";
|
|
3443
3554
|
const intervalSec = data.heartbeat_interval > 0 ? data.heartbeat_interval : 30;
|
|
3444
3555
|
try {
|
|
3445
3556
|
const count = await fetchAllChats(client, config.org_id, this.chatInfoMap);
|
|
3446
|
-
|
|
3557
|
+
log2?.info(`parall[${this.opts.accountId}]: WebSocket connected, ${count} chats cached`);
|
|
3447
3558
|
await this.opts.onSessionReady?.({
|
|
3448
3559
|
activeSessionId: this.activeSessionId,
|
|
3449
3560
|
ws: this.opts.ws,
|
|
@@ -3457,7 +3568,7 @@ var ParallAgentGateway = class {
|
|
|
3457
3568
|
const expectedMs = intervalSec * 1e3;
|
|
3458
3569
|
const drift = now - this.lastHeartbeatAt - expectedMs;
|
|
3459
3570
|
if (drift > 15e3) {
|
|
3460
|
-
|
|
3571
|
+
log2?.warn(`parall[${this.opts.accountId}]: heartbeat drift ${drift}ms \u2014 event loop may be blocked`);
|
|
3461
3572
|
}
|
|
3462
3573
|
this.lastHeartbeatAt = now;
|
|
3463
3574
|
if (this.opts.ws.state !== "connected")
|
|
@@ -3473,10 +3584,10 @@ var ParallAgentGateway = class {
|
|
|
3473
3584
|
const isFirstHello = !this.hadSuccessfulHello;
|
|
3474
3585
|
this.hadSuccessfulHello = true;
|
|
3475
3586
|
this.catchUpFromDispatch(isFirstHello).catch((err) => {
|
|
3476
|
-
|
|
3587
|
+
log2?.warn(`parall[${this.opts.accountId}]: dispatch catch-up failed: ${String(err)}`);
|
|
3477
3588
|
});
|
|
3478
3589
|
} catch (err) {
|
|
3479
|
-
|
|
3590
|
+
log2?.error(`parall[${this.opts.accountId}]: failed to fetch chats: ${String(err)}`);
|
|
3480
3591
|
}
|
|
3481
3592
|
}
|
|
3482
3593
|
// Resolves when in-flight dispatches hit 0 or the deadline elapses.
|
|
@@ -3581,7 +3692,7 @@ function extractDefaults(config, runtimeType) {
|
|
|
3581
3692
|
return { model, thinkingEffort };
|
|
3582
3693
|
}
|
|
3583
3694
|
function createPlatformConfigManager(opts) {
|
|
3584
|
-
const { client, stateDir, runtimeType, log } = opts;
|
|
3695
|
+
const { client, stateDir, runtimeType, log: log2 } = opts;
|
|
3585
3696
|
let cachedVersion;
|
|
3586
3697
|
let currentDefaults = { model: null, thinkingEffort: null };
|
|
3587
3698
|
let currentRawConfig = null;
|
|
@@ -3598,20 +3709,20 @@ function createPlatformConfigManager(opts) {
|
|
|
3598
3709
|
fresh = await client.getPlatformConfig(cachedVersion);
|
|
3599
3710
|
} catch (err) {
|
|
3600
3711
|
if (cached) {
|
|
3601
|
-
|
|
3712
|
+
log2?.warn(`platform config fetch failed, using cached version ${cachedVersion}: ${String(err)}`);
|
|
3602
3713
|
return currentDefaults;
|
|
3603
3714
|
}
|
|
3604
|
-
|
|
3715
|
+
log2?.warn(`platform config fetch failed and no cache available: ${String(err)}`);
|
|
3605
3716
|
return currentDefaults;
|
|
3606
3717
|
}
|
|
3607
3718
|
if (fresh === null) {
|
|
3608
3719
|
return currentDefaults;
|
|
3609
3720
|
}
|
|
3610
3721
|
if (fresh.schema_version !== void 0 && fresh.schema_version > SUPPORTED_SCHEMA_VERSION) {
|
|
3611
|
-
|
|
3722
|
+
log2?.warn(`platform config schema_version ${fresh.schema_version} > supported (${SUPPORTED_SCHEMA_VERSION}), keeping current`);
|
|
3612
3723
|
return currentDefaults;
|
|
3613
3724
|
}
|
|
3614
|
-
|
|
3725
|
+
log2?.info(`platform config updated to version ${fresh.version}`);
|
|
3615
3726
|
saveCache(stateDir, fresh);
|
|
3616
3727
|
cachedVersion = fresh.version;
|
|
3617
3728
|
currentRawConfig = fresh.config;
|
|
@@ -4187,8 +4298,8 @@ function stepIdFilePathForSession(stateDir, sessionKey) {
|
|
|
4187
4298
|
// ts/claude-agent/dist/dispatch.js
|
|
4188
4299
|
import * as fs5 from "node:fs";
|
|
4189
4300
|
import * as path6 from "node:path";
|
|
4190
|
-
import { randomUUID
|
|
4191
|
-
import { spawn } from "node:child_process";
|
|
4301
|
+
import { randomUUID } from "node:crypto";
|
|
4302
|
+
import { execSync as execSync2, spawn } from "node:child_process";
|
|
4192
4303
|
|
|
4193
4304
|
// ts/agent-core/dist/internal/attachment-input.js
|
|
4194
4305
|
import { execSync } from "node:child_process";
|
|
@@ -4489,7 +4600,7 @@ function sameFileIdentity(a, b) {
|
|
|
4489
4600
|
function sameFile(a, b) {
|
|
4490
4601
|
return sameFileIdentity(a, b) && a.size === b.size && a.mtimeMs === b.mtimeMs;
|
|
4491
4602
|
}
|
|
4492
|
-
async function cleanupOldAttachmentFiles(rootDir, ttlMs,
|
|
4603
|
+
async function cleanupOldAttachmentFiles(rootDir, ttlMs, log2, preserveDirs) {
|
|
4493
4604
|
let entries;
|
|
4494
4605
|
try {
|
|
4495
4606
|
entries = await fs4.readdir(rootDir, { withFileTypes: true });
|
|
@@ -4511,11 +4622,11 @@ async function cleanupOldAttachmentFiles(rootDir, ttlMs, log, preserveDirs) {
|
|
|
4511
4622
|
await fs4.rm(fullPath, { recursive: true, force: true });
|
|
4512
4623
|
}
|
|
4513
4624
|
} catch (err) {
|
|
4514
|
-
|
|
4625
|
+
log2?.warn?.(`agent-core: failed to clean attachment temp dir ${fullPath}: ${String(err)}`);
|
|
4515
4626
|
}
|
|
4516
4627
|
}));
|
|
4517
4628
|
}
|
|
4518
|
-
async function pruneAttachmentCache(rootDir, maxBytes,
|
|
4629
|
+
async function pruneAttachmentCache(rootDir, maxBytes, log2, preserveDirs) {
|
|
4519
4630
|
if (maxBytes <= 0)
|
|
4520
4631
|
return;
|
|
4521
4632
|
let entries;
|
|
@@ -4538,7 +4649,7 @@ async function pruneAttachmentCache(rootDir, maxBytes, log, preserveDirs) {
|
|
|
4538
4649
|
dirs.push({ path: fullPath, mtimeMs: stat.mtimeMs, size });
|
|
4539
4650
|
total += size;
|
|
4540
4651
|
} catch (err) {
|
|
4541
|
-
|
|
4652
|
+
log2?.warn?.(`agent-core: failed to inspect attachment cache dir ${fullPath}: ${String(err)}`);
|
|
4542
4653
|
}
|
|
4543
4654
|
}
|
|
4544
4655
|
if (total <= maxBytes)
|
|
@@ -4553,7 +4664,7 @@ async function pruneAttachmentCache(rootDir, maxBytes, log, preserveDirs) {
|
|
|
4553
4664
|
await fs4.rm(dir.path, { recursive: true, force: true });
|
|
4554
4665
|
total -= dir.size;
|
|
4555
4666
|
} catch (err) {
|
|
4556
|
-
|
|
4667
|
+
log2?.warn?.(`agent-core: failed to prune attachment cache dir ${dir.path}: ${String(err)}`);
|
|
4557
4668
|
}
|
|
4558
4669
|
}
|
|
4559
4670
|
}
|
|
@@ -4948,6 +5059,20 @@ async function* parseClaudeStreamJson(readable) {
|
|
|
4948
5059
|
}
|
|
4949
5060
|
|
|
4950
5061
|
// ts/claude-agent/dist/dispatch.js
|
|
5062
|
+
var IS_WIN32 = process.platform === "win32";
|
|
5063
|
+
function quoteWin32Arg(arg) {
|
|
5064
|
+
if (!/[\s"&|^<>()]/.test(arg))
|
|
5065
|
+
return arg;
|
|
5066
|
+
return `"${arg.replace(/"/g, '""')}"`;
|
|
5067
|
+
}
|
|
5068
|
+
function killWin32Tree(pid) {
|
|
5069
|
+
try {
|
|
5070
|
+
execSync2(`taskkill /T /F /PID ${pid}`, { windowsHide: true, stdio: "ignore" });
|
|
5071
|
+
return true;
|
|
5072
|
+
} catch {
|
|
5073
|
+
return false;
|
|
5074
|
+
}
|
|
5075
|
+
}
|
|
4951
5076
|
function buildSpawnEnv(parentEnv, claudeHome, context, opts) {
|
|
4952
5077
|
const env = { ...parentEnv };
|
|
4953
5078
|
if (!opts.allowApiKey) {
|
|
@@ -5089,12 +5214,12 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5089
5214
|
* state.steerReadPending so the next runTurn can drain it instead of
|
|
5090
5215
|
* silently losing the first event of the subsequent turn.
|
|
5091
5216
|
*/
|
|
5092
|
-
async *consumeSteerTurn(sessionKey,
|
|
5217
|
+
async *consumeSteerTurn(sessionKey, log2) {
|
|
5093
5218
|
const state = this.processes.get(sessionKey);
|
|
5094
5219
|
if (!state || state.done) {
|
|
5095
5220
|
throw new Error("claude-agent: process dead during steer consumption");
|
|
5096
5221
|
}
|
|
5097
|
-
const groupKey =
|
|
5222
|
+
const groupKey = randomUUID();
|
|
5098
5223
|
const parserNext = state.parser.next();
|
|
5099
5224
|
const firstRead = await Promise.race([
|
|
5100
5225
|
parserNext.then((r) => ({ kind: "value", result: r })),
|
|
@@ -5102,7 +5227,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5102
5227
|
]);
|
|
5103
5228
|
if (firstRead.kind === "timeout") {
|
|
5104
5229
|
state.steerReadPending = parserNext;
|
|
5105
|
-
|
|
5230
|
+
log2?.info?.(`claude-agent: steer turn timeout \u2014 steer was incorporated into previous turn`);
|
|
5106
5231
|
return;
|
|
5107
5232
|
}
|
|
5108
5233
|
let next = firstRead.result;
|
|
@@ -5132,15 +5257,15 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5132
5257
|
next = await state.parser.next();
|
|
5133
5258
|
}
|
|
5134
5259
|
}
|
|
5135
|
-
async *runTurn(sessionKey, promptBody,
|
|
5260
|
+
async *runTurn(sessionKey, promptBody, log2) {
|
|
5136
5261
|
let state;
|
|
5137
5262
|
try {
|
|
5138
|
-
state = this.ensureProcess(sessionKey,
|
|
5263
|
+
state = this.ensureProcess(sessionKey, log2);
|
|
5139
5264
|
} catch (err) {
|
|
5140
5265
|
yield { type: "error", message: `Claude spawn failed: ${String(err)}` };
|
|
5141
5266
|
return;
|
|
5142
5267
|
}
|
|
5143
|
-
const groupKey =
|
|
5268
|
+
const groupKey = randomUUID();
|
|
5144
5269
|
let sawError = false;
|
|
5145
5270
|
try {
|
|
5146
5271
|
this.writeUserMessage(state.handle, promptBody);
|
|
@@ -5178,9 +5303,12 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5178
5303
|
if (next.done) {
|
|
5179
5304
|
state.done = true;
|
|
5180
5305
|
this.processes.delete(sessionKey);
|
|
5306
|
+
const detail = state.handle.stderrChunks.join("").trim();
|
|
5307
|
+
const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
|
|
5308
|
+
if (detail) {
|
|
5309
|
+
log2?.warn?.(`claude-agent: subprocess stderr: ${detail}`);
|
|
5310
|
+
}
|
|
5181
5311
|
if (!sawError) {
|
|
5182
|
-
const detail = state.handle.stderrChunks.join("").trim();
|
|
5183
|
-
const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
|
|
5184
5312
|
yield {
|
|
5185
5313
|
type: "error",
|
|
5186
5314
|
message: detail || `Claude exited with code ${exit.code ?? "unknown"}${exit.signal ? ` (${exit.signal})` : ""}`
|
|
@@ -5220,7 +5348,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5220
5348
|
yield { ...parsed, groupKey };
|
|
5221
5349
|
}
|
|
5222
5350
|
}
|
|
5223
|
-
ensureProcess(sessionKey,
|
|
5351
|
+
ensureProcess(sessionKey, log2) {
|
|
5224
5352
|
if (this.shuttingDown) {
|
|
5225
5353
|
throw new Error("claude-agent: adapter shutting down, refusing new process");
|
|
5226
5354
|
}
|
|
@@ -5235,21 +5363,22 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5235
5363
|
this.processes.delete(sessionKey);
|
|
5236
5364
|
}
|
|
5237
5365
|
}
|
|
5238
|
-
const handle = this.spawnProcess(sessionKey,
|
|
5366
|
+
const handle = this.spawnProcess(sessionKey, log2);
|
|
5239
5367
|
const parser = parseClaudeStreamJson(handle.proc.stdout);
|
|
5240
5368
|
const state = { handle, parser, done: false, needsRestart: false };
|
|
5241
5369
|
this.processes.set(sessionKey, state);
|
|
5242
5370
|
this.opts.sessionManager.registerProcess(sessionKey, handle);
|
|
5243
5371
|
return state;
|
|
5244
5372
|
}
|
|
5245
|
-
spawnProcess(sessionKey,
|
|
5373
|
+
spawnProcess(sessionKey, log2) {
|
|
5246
5374
|
const args = this.buildArgs(sessionKey);
|
|
5247
5375
|
const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), { allowApiKey: this.opts.allowApiKey, effortLevel: this._effortLevel });
|
|
5248
|
-
|
|
5249
|
-
const proc = spawn(this.opts.claudeBin, args, {
|
|
5376
|
+
log2?.info(`claude-agent: spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
|
|
5377
|
+
const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
|
|
5250
5378
|
cwd: this.opts.workspaceDir,
|
|
5251
5379
|
env,
|
|
5252
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
5380
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
5381
|
+
shell: IS_WIN32
|
|
5253
5382
|
});
|
|
5254
5383
|
if (!proc.stdout || !proc.stderr || !proc.stdin) {
|
|
5255
5384
|
throw new Error("Claude subprocess did not provide stdio pipes");
|
|
@@ -5261,7 +5390,9 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5261
5390
|
proc.stdin.on("error", () => {
|
|
5262
5391
|
proc.stdin.destroy();
|
|
5263
5392
|
if (proc.exitCode === null && proc.signalCode === null) {
|
|
5264
|
-
proc.
|
|
5393
|
+
if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
|
|
5394
|
+
proc.kill("SIGTERM");
|
|
5395
|
+
}
|
|
5265
5396
|
}
|
|
5266
5397
|
});
|
|
5267
5398
|
const exitPromise = new Promise((resolve3) => {
|
|
@@ -5282,7 +5413,9 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5282
5413
|
}
|
|
5283
5414
|
if (state.handle.proc.exitCode === null && state.handle.proc.signalCode === null) {
|
|
5284
5415
|
try {
|
|
5285
|
-
state.handle.proc.
|
|
5416
|
+
if (!IS_WIN32 || !state.handle.proc.pid || !killWin32Tree(state.handle.proc.pid)) {
|
|
5417
|
+
state.handle.proc.kill("SIGTERM");
|
|
5418
|
+
}
|
|
5286
5419
|
} catch {
|
|
5287
5420
|
}
|
|
5288
5421
|
}
|
|
@@ -5300,7 +5433,6 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5300
5433
|
}
|
|
5301
5434
|
buildArgs(sessionKey) {
|
|
5302
5435
|
const args = [
|
|
5303
|
-
"-p",
|
|
5304
5436
|
"--verbose",
|
|
5305
5437
|
"--input-format",
|
|
5306
5438
|
"stream-json",
|
|
@@ -5351,7 +5483,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
|
|
|
5351
5483
|
// ts/claude-agent/dist/session-manager.js
|
|
5352
5484
|
import * as fs6 from "node:fs";
|
|
5353
5485
|
import * as path7 from "node:path";
|
|
5354
|
-
import { randomUUID as
|
|
5486
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
5355
5487
|
var ClaudeSessionManager = class _ClaudeSessionManager {
|
|
5356
5488
|
mainSessionKey;
|
|
5357
5489
|
stateFilePath;
|
|
@@ -5388,7 +5520,7 @@ var ClaudeSessionManager = class _ClaudeSessionManager {
|
|
|
5388
5520
|
const parentSessionId = this.sessionIds.get(parentSessionKey);
|
|
5389
5521
|
if (!parentSessionId)
|
|
5390
5522
|
return null;
|
|
5391
|
-
const sessionKey = `claude-fork:${
|
|
5523
|
+
const sessionKey = `claude-fork:${randomUUID2()}`;
|
|
5392
5524
|
this.pendingForkParents.set(sessionKey, parentSessionId);
|
|
5393
5525
|
return {
|
|
5394
5526
|
sessionKey,
|
|
@@ -5522,7 +5654,7 @@ var ClaudeSessionManager = class _ClaudeSessionManager {
|
|
|
5522
5654
|
// ts/claude-agent/dist/workspace.js
|
|
5523
5655
|
import * as fs7 from "node:fs";
|
|
5524
5656
|
import * as path8 from "node:path";
|
|
5525
|
-
function ensureClaudeWorkspace(workspaceDir,
|
|
5657
|
+
function ensureClaudeWorkspace(workspaceDir, log2, agentIdentity) {
|
|
5526
5658
|
const systemPrompt = [
|
|
5527
5659
|
buildIdentity(agentIdentity),
|
|
5528
5660
|
BRIDGE_WORKSPACE_INSTRUCTIONS,
|
|
@@ -5540,13 +5672,7 @@ function ensureClaudeWorkspace(workspaceDir, log, agentIdentity) {
|
|
|
5540
5672
|
}
|
|
5541
5673
|
|
|
5542
5674
|
// ts/claude-agent/dist/index.js
|
|
5543
|
-
|
|
5544
|
-
return {
|
|
5545
|
-
info: (msg) => console.log(`[${prefix}] ${msg}`),
|
|
5546
|
-
warn: (msg) => console.warn(`[${prefix}] ${msg}`),
|
|
5547
|
-
error: (msg) => console.error(`[${prefix}] ${msg}`)
|
|
5548
|
-
};
|
|
5549
|
-
}
|
|
5675
|
+
var log = createLogger("claude-agent");
|
|
5550
5676
|
async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
5551
5677
|
try {
|
|
5552
5678
|
return await client.getAgentMe(orgId);
|
|
@@ -5560,7 +5686,6 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
|
5560
5686
|
}
|
|
5561
5687
|
async function main() {
|
|
5562
5688
|
const config = resolveClaudeAgentConfig(process.env);
|
|
5563
|
-
const log = createLogger("claude-agent");
|
|
5564
5689
|
if (config.allowApiKey && (process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN)) {
|
|
5565
5690
|
log.warn("PRLL_CLAUDE_ALLOW_API_KEY=1 \u2014 ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN will reach the Claude CLI; billing routes through Anthropic API pay-per-use instead of Claude.ai OAuth.");
|
|
5566
5691
|
}
|
|
@@ -5680,6 +5805,6 @@ async function main() {
|
|
|
5680
5805
|
}
|
|
5681
5806
|
}
|
|
5682
5807
|
main().catch((err) => {
|
|
5683
|
-
|
|
5808
|
+
log.error(`fatal: ${String(err)}`);
|
|
5684
5809
|
process.exitCode = 1;
|
|
5685
5810
|
});
|