@parall/daemon 1.29.0 → 1.29.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/manifest.json +8 -8
- package/bundle/parall-claude-agent.js +129 -25
- package/bundle/parall-codex-agent.js +205 -28
- package/bundle/parall-daemon.js +726 -106
- 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 +2 -1
- package/dist/runtimes.d.ts +1 -0
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +1 -1
- package/dist/supervisor.d.ts +9 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +130 -16
- package/dist/workspace.d.ts +11 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +439 -0
- package/package.json +6 -6
|
@@ -453,6 +453,8 @@ var ENDPOINTS = {
|
|
|
453
453
|
AUTH_CHECK_EMAIL: `${API_BASE}/auth/check-email`,
|
|
454
454
|
AUTH_VERIFY_EMAIL: `${API_BASE}/auth/verify-email`,
|
|
455
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`,
|
|
456
458
|
// Users
|
|
457
459
|
USERS_ME: `${API_BASE}/users/me`,
|
|
458
460
|
USER_AVATAR: `${API_BASE}/users/me/avatar`,
|
|
@@ -487,6 +489,9 @@ var ENDPOINTS = {
|
|
|
487
489
|
// Messages (global, by message ID)
|
|
488
490
|
MESSAGE: (id) => `${API_BASE}/messages/${id}`,
|
|
489
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`,
|
|
490
495
|
// Upload (org-scoped)
|
|
491
496
|
UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
|
|
492
497
|
UPLOAD_COMPLETE: (orgId) => `${API_BASE}/orgs/${orgId}/upload/complete`,
|
|
@@ -537,6 +542,9 @@ var ENDPOINTS = {
|
|
|
537
542
|
// Attach/Detach bind an agent to/from a daemon Machine.
|
|
538
543
|
MACHINE_ATTACH_AGENT: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}`,
|
|
539
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`,
|
|
540
548
|
MACHINE_LLM_SOURCE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
|
|
541
549
|
MACHINE_RUNTIME_AUTH: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
|
|
542
550
|
MACHINE_KEYS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys`,
|
|
@@ -550,6 +558,7 @@ var ENDPOINTS = {
|
|
|
550
558
|
MACHINES_ME_AGENTS: `${API_BASE}/machines/me/agents`,
|
|
551
559
|
MACHINES_ME_HEALTH: `${API_BASE}/machines/me/health`,
|
|
552
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`,
|
|
553
562
|
MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
|
|
554
563
|
// Tasks (org-scoped)
|
|
555
564
|
TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
|
|
@@ -729,7 +738,8 @@ var WS_EVENTS = {
|
|
|
729
738
|
MACHINE_HELLO: "machine.hello",
|
|
730
739
|
MACHINE_AGENT_ATTACHED: "machine.agent.attached",
|
|
731
740
|
MACHINE_AGENT_DETACHED: "machine.agent.detached",
|
|
732
|
-
MACHINE_STOP: "machine.stop"
|
|
741
|
+
MACHINE_STOP: "machine.stop",
|
|
742
|
+
MACHINE_WORKSPACE_SETUP_REQUESTED: "machine.workspace.setup.requested"
|
|
733
743
|
};
|
|
734
744
|
|
|
735
745
|
// ts/sdk/dist/client.js
|
|
@@ -749,7 +759,9 @@ var ParallClient = class _ParallClient {
|
|
|
749
759
|
"/auth/logout",
|
|
750
760
|
"/auth/verify-email",
|
|
751
761
|
"/auth/resend-code",
|
|
752
|
-
"/auth/check-email"
|
|
762
|
+
"/auth/check-email",
|
|
763
|
+
"/auth/forgot-password",
|
|
764
|
+
"/auth/reset-password"
|
|
753
765
|
]);
|
|
754
766
|
/** Proactive refresh when token expires within this window (seconds). */
|
|
755
767
|
static REFRESH_THRESHOLD_S = 5 * 60;
|
|
@@ -987,6 +999,12 @@ var ParallClient = class _ParallClient {
|
|
|
987
999
|
async resendCode(email) {
|
|
988
1000
|
return this.request("POST", ENDPOINTS.AUTH_RESEND_CODE, { email });
|
|
989
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
|
+
}
|
|
990
1008
|
// ---- WebSocket ----
|
|
991
1009
|
async getWsTicket() {
|
|
992
1010
|
return this.request("POST", ENDPOINTS.WS_TICKET);
|
|
@@ -1193,8 +1211,8 @@ var ParallClient = class _ParallClient {
|
|
|
1193
1211
|
async completeUpload(orgId, attachmentId) {
|
|
1194
1212
|
return this.request("POST", ENDPOINTS.UPLOAD_COMPLETE(orgId), { attachment_id: attachmentId });
|
|
1195
1213
|
}
|
|
1196
|
-
async getFileUrl(id) {
|
|
1197
|
-
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);
|
|
1198
1216
|
}
|
|
1199
1217
|
// ---- Approvals ----
|
|
1200
1218
|
async getApproval(id) {
|
|
@@ -1391,6 +1409,16 @@ var ParallClient = class _ParallClient {
|
|
|
1391
1409
|
async detachAgent(orgId, machineId, agentId) {
|
|
1392
1410
|
return this.request("DELETE", ENDPOINTS.MACHINE_DETACH_AGENT(orgId, machineId, agentId));
|
|
1393
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
|
+
}
|
|
1394
1422
|
async patchMachineLLMSource(orgId, machineId, llmSource) {
|
|
1395
1423
|
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), { llm_source: llmSource });
|
|
1396
1424
|
}
|
|
@@ -1436,6 +1464,12 @@ var ParallClient = class _ParallClient {
|
|
|
1436
1464
|
async postMachineHeartbeat() {
|
|
1437
1465
|
return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH);
|
|
1438
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
|
+
}
|
|
1439
1473
|
/**
|
|
1440
1474
|
* `POST /machines/me/agents/{agentId}/launch-credential` — mint a
|
|
1441
1475
|
* short-lived `agk_*` for one of this Machine's attached agents. The
|
|
@@ -1585,6 +1619,20 @@ var ParallClient = class _ParallClient {
|
|
|
1585
1619
|
const res = await this.request("GET", ENDPOINTS.TASK_WATCHERS(orgId, taskId));
|
|
1586
1620
|
return res.data;
|
|
1587
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
|
+
}
|
|
1588
1636
|
async getSubtasks(orgId, taskId) {
|
|
1589
1637
|
const res = await this.request("GET", ENDPOINTS.TASK_SUBTASKS(orgId, taskId));
|
|
1590
1638
|
return res.data;
|
|
@@ -1881,14 +1929,28 @@ var ParallClient = class _ParallClient {
|
|
|
1881
1929
|
params.set("machine_id", opts.machine_id);
|
|
1882
1930
|
if (opts?.unresolved_machine)
|
|
1883
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);
|
|
1884
1936
|
const qs = params.toString();
|
|
1885
1937
|
return this.request("GET", `${ENDPOINTS.BILLING_TRANSACTIONS(orgId)}${qs ? `?${qs}` : ""}`);
|
|
1886
1938
|
}
|
|
1887
|
-
async listBillingTransactionAgentGroups(orgId) {
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
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}`);
|
|
1892
1954
|
}
|
|
1893
1955
|
async createCheckout(orgId, req) {
|
|
1894
1956
|
return this.request("POST", ENDPOINTS.BILLING_CHECKOUT(orgId), req);
|
|
@@ -1939,6 +2001,12 @@ var ApiError = class extends Error {
|
|
|
1939
2001
|
};
|
|
1940
2002
|
|
|
1941
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
|
+
}
|
|
1942
2010
|
var ParallWs = class {
|
|
1943
2011
|
ws = null;
|
|
1944
2012
|
options;
|
|
@@ -1974,7 +2042,11 @@ var ParallWs = class {
|
|
|
1974
2042
|
try {
|
|
1975
2043
|
ticket = await this.options.getTicket();
|
|
1976
2044
|
} catch (err) {
|
|
1977
|
-
|
|
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
|
+
}
|
|
1978
2050
|
if (this.options.reconnect) {
|
|
1979
2051
|
this.scheduleReconnect();
|
|
1980
2052
|
} else {
|
|
@@ -2303,6 +2375,7 @@ var ParallAgentGateway = class {
|
|
|
2303
2375
|
opts;
|
|
2304
2376
|
chatInfoMap = /* @__PURE__ */ new Map();
|
|
2305
2377
|
activeDispatches = /* @__PURE__ */ new Map();
|
|
2378
|
+
injectedTypingCounts = /* @__PURE__ */ new Map();
|
|
2306
2379
|
dispatchedTasks = /* @__PURE__ */ new Set();
|
|
2307
2380
|
dispatchedMessages = /* @__PURE__ */ new Set();
|
|
2308
2381
|
forkStates = /* @__PURE__ */ new Map();
|
|
@@ -2497,6 +2570,34 @@ var ParallAgentGateway = class {
|
|
|
2497
2570
|
if (this.opts.ws.state === "connected")
|
|
2498
2571
|
this.opts.ws.sendTyping(chatId, "stop");
|
|
2499
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
|
+
}
|
|
2500
2601
|
buildDispatchContext(event, sessionKey) {
|
|
2501
2602
|
const binding = this.sessionBindings.get(sessionKey);
|
|
2502
2603
|
return {
|
|
@@ -2529,7 +2630,8 @@ var ParallAgentGateway = class {
|
|
|
2529
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 },
|
|
2530
2631
|
sender_id: event.senderId,
|
|
2531
2632
|
sender_name: event.senderName,
|
|
2532
|
-
summary: event.body.substring(0, 200)
|
|
2633
|
+
summary: event.body.substring(0, 200),
|
|
2634
|
+
...event.sentAt ? { sent_at: event.sentAt } : {}
|
|
2533
2635
|
}
|
|
2534
2636
|
});
|
|
2535
2637
|
} catch (err) {
|
|
@@ -2828,7 +2930,7 @@ var ParallAgentGateway = class {
|
|
|
2828
2930
|
const earlier = events.slice(0, -1);
|
|
2829
2931
|
try {
|
|
2830
2932
|
const batchText = [];
|
|
2831
|
-
const dispatched = await this.
|
|
2933
|
+
const dispatched = await this.runDispatchWithTyping(last, fork.fork.sessionKey, buildForkScopePrefix(last) + buildEventBody(last), earlier, batchText);
|
|
2832
2934
|
if (!dispatched) {
|
|
2833
2935
|
for (const item of items) {
|
|
2834
2936
|
item.resolve(false);
|
|
@@ -2921,12 +3023,13 @@ var ParallAgentGateway = class {
|
|
|
2921
3023
|
}
|
|
2922
3024
|
const event = events[events.length - 1];
|
|
2923
3025
|
const earlier = events.slice(0, -1);
|
|
2924
|
-
const
|
|
2925
|
-
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);
|
|
2926
3029
|
const forkPrefix = buildForkResultPrefix(pendingFork);
|
|
2927
3030
|
this.dispatchState.mainCurrentTargetId = event.targetId;
|
|
2928
3031
|
this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
|
|
2929
|
-
const dispatched = await this.
|
|
3032
|
+
const dispatched = await this.runDispatchWithTyping(event, this.opts.runtimeKey, forkPrefix + buildEventBody(event), earlier, void 0, { suppressStart: injectedTypingCount > 0, injectedTypingCount });
|
|
2930
3033
|
if (!dispatched) {
|
|
2931
3034
|
this.dispatchState.mainBuffer.unshift(...events);
|
|
2932
3035
|
this.dispatchState.pendingForkResults.unshift(...pendingFork);
|
|
@@ -2960,7 +3063,7 @@ var ParallAgentGateway = class {
|
|
|
2960
3063
|
this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
|
|
2961
3064
|
let dispatched = false;
|
|
2962
3065
|
try {
|
|
2963
|
-
dispatched = await this.
|
|
3066
|
+
dispatched = await this.runDispatchWithTyping(event, this.opts.runtimeKey, forkPrefix + buildEventBody(event));
|
|
2964
3067
|
if (!dispatched) {
|
|
2965
3068
|
this.dispatchState.pendingForkResults.unshift(...pendingFork);
|
|
2966
3069
|
}
|
|
@@ -2973,10 +3076,15 @@ var ParallAgentGateway = class {
|
|
|
2973
3076
|
if (this.shuttingDown) {
|
|
2974
3077
|
return false;
|
|
2975
3078
|
}
|
|
2976
|
-
if (this.dispatchState.mainCurrentTargetId === event.targetId && this.opts.dispatchAdapter.enqueueDuringDispatch?.(this.opts.runtimeKey, buildEventBody(event))) {
|
|
2977
|
-
this.opts.log?.info(`parall[${this.opts.accountId}]: steer injected to stdin for ${event.messageId} (will drain for bookkeeping)`);
|
|
2978
|
-
}
|
|
2979
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
|
+
}
|
|
2980
3088
|
return false;
|
|
2981
3089
|
}
|
|
2982
3090
|
case "buffer-fork": {
|
|
@@ -3078,6 +3186,7 @@ var ParallAgentGateway = class {
|
|
|
3078
3186
|
threadRootId: message.thread_root_id ?? void 0,
|
|
3079
3187
|
noReply: message.hints?.no_reply ?? false,
|
|
3080
3188
|
attachments: attachments.length > 0 ? attachments : void 0,
|
|
3189
|
+
sentAt: message.created_at,
|
|
3081
3190
|
ackSourceType: "message",
|
|
3082
3191
|
ackSourceId: message.id
|
|
3083
3192
|
}
|
|
@@ -3099,9 +3208,6 @@ var ParallAgentGateway = class {
|
|
|
3099
3208
|
return;
|
|
3100
3209
|
}
|
|
3101
3210
|
const event = decision.event;
|
|
3102
|
-
const willDispatch = !this.dispatchState.mainDispatching || this.dispatchState.mainCurrentTargetId !== chatId;
|
|
3103
|
-
if (willDispatch)
|
|
3104
|
-
this.startTyping(chatId);
|
|
3105
3211
|
try {
|
|
3106
3212
|
const dispatched = await this.handleInboundEvent(event);
|
|
3107
3213
|
if (dispatched) {
|
|
@@ -3113,9 +3219,6 @@ var ParallAgentGateway = class {
|
|
|
3113
3219
|
} catch (err) {
|
|
3114
3220
|
this.opts.log?.error(`parall[${this.opts.accountId}]: event dispatch failed for ${data.id}: ${String(err)}`);
|
|
3115
3221
|
this.dispatchedMessages.delete(data.id);
|
|
3116
|
-
} finally {
|
|
3117
|
-
if (willDispatch)
|
|
3118
|
-
this.stopTyping(chatId);
|
|
3119
3222
|
}
|
|
3120
3223
|
}
|
|
3121
3224
|
async handleTaskAssignment(task, ackSourceId) {
|
|
@@ -3145,6 +3248,7 @@ var ParallAgentGateway = class {
|
|
|
3145
3248
|
senderName: "system",
|
|
3146
3249
|
messageId: task.id,
|
|
3147
3250
|
body: parts.join("\n"),
|
|
3251
|
+
sentAt: task.updated_at ?? task.created_at,
|
|
3148
3252
|
ackSourceType: "task_activity",
|
|
3149
3253
|
ackSourceId
|
|
3150
3254
|
};
|
|
@@ -5143,6 +5247,8 @@ var CodexAppServerAdapter = class {
|
|
|
5143
5247
|
initialized = false;
|
|
5144
5248
|
startPromise = null;
|
|
5145
5249
|
activeTurns = /* @__PURE__ */ new Map();
|
|
5250
|
+
activeTurnIds = /* @__PURE__ */ new Map();
|
|
5251
|
+
pendingInjections = /* @__PURE__ */ new Map();
|
|
5146
5252
|
resumedThreadIds = /* @__PURE__ */ new Set();
|
|
5147
5253
|
stopping = false;
|
|
5148
5254
|
/**
|
|
@@ -5171,7 +5277,48 @@ var CodexAppServerAdapter = class {
|
|
|
5171
5277
|
if (config.reasoningEffort !== void 0)
|
|
5172
5278
|
this.opts.reasoningEffort = config.reasoningEffort ?? void 0;
|
|
5173
5279
|
}
|
|
5280
|
+
async enqueueDuringDispatch(sessionKey, body) {
|
|
5281
|
+
const client = this.client;
|
|
5282
|
+
if (!client || client.isDisposed())
|
|
5283
|
+
return false;
|
|
5284
|
+
const threadId = this.opts.sessionManager.getThreadId(sessionKey);
|
|
5285
|
+
if (!threadId)
|
|
5286
|
+
return false;
|
|
5287
|
+
const turnId = this.activeTurnIds.get(threadId);
|
|
5288
|
+
if (!turnId)
|
|
5289
|
+
return false;
|
|
5290
|
+
try {
|
|
5291
|
+
await client.sendRequest("turn/steer", {
|
|
5292
|
+
threadId,
|
|
5293
|
+
expectedTurnId: turnId,
|
|
5294
|
+
input: buildTurnInput(body, [])
|
|
5295
|
+
});
|
|
5296
|
+
this.pendingInjections.set(sessionKey, (this.pendingInjections.get(sessionKey) ?? 0) + 1);
|
|
5297
|
+
return true;
|
|
5298
|
+
} catch (err) {
|
|
5299
|
+
this.opts.log?.warn?.(`codex-agent: turn/steer failed: ${errToString(err)}`);
|
|
5300
|
+
return false;
|
|
5301
|
+
}
|
|
5302
|
+
}
|
|
5303
|
+
hasPendingInjections(sessionKey) {
|
|
5304
|
+
return (this.pendingInjections.get(sessionKey) ?? 0) > 0;
|
|
5305
|
+
}
|
|
5174
5306
|
async *dispatch({ event, bodyForAgent, sessionKey, context }) {
|
|
5307
|
+
const pending = this.pendingInjections.get(sessionKey) ?? 0;
|
|
5308
|
+
if (pending > 0) {
|
|
5309
|
+
this.pendingInjections.delete(sessionKey);
|
|
5310
|
+
const threadId2 = this.opts.sessionManager.getThreadId(sessionKey);
|
|
5311
|
+
if (threadId2 && this.client && !this.client.isDisposed()) {
|
|
5312
|
+
(this.opts.log ?? context.log)?.info?.(`codex-agent[${context.accountId}]: ${pending} steer injection(s) already sent; skipping turn/start`);
|
|
5313
|
+
yield {
|
|
5314
|
+
type: "runtime_session",
|
|
5315
|
+
runtimeSessionId: threadId2,
|
|
5316
|
+
runtimeLaneKey: sessionKey
|
|
5317
|
+
};
|
|
5318
|
+
return;
|
|
5319
|
+
}
|
|
5320
|
+
(this.opts.log ?? context.log)?.warn?.(`codex-agent[${context.accountId}]: pending steer invalidated (subprocess died); falling through to normal dispatch`);
|
|
5321
|
+
}
|
|
5175
5322
|
await this.ensureStarted(context.log);
|
|
5176
5323
|
const client = this.client;
|
|
5177
5324
|
if (!client) {
|
|
@@ -5284,7 +5431,9 @@ var CodexAppServerAdapter = class {
|
|
|
5284
5431
|
this.resumedThreadIds.add(freshThreadId);
|
|
5285
5432
|
threadId = freshThreadId;
|
|
5286
5433
|
}
|
|
5287
|
-
|
|
5434
|
+
const turnId = extractTurnId(turnStartResult);
|
|
5435
|
+
if (turnId)
|
|
5436
|
+
this.activeTurnIds.set(threadId, turnId);
|
|
5288
5437
|
yield {
|
|
5289
5438
|
type: "runtime_session",
|
|
5290
5439
|
runtimeSessionId: threadId,
|
|
@@ -5318,6 +5467,7 @@ var CodexAppServerAdapter = class {
|
|
|
5318
5467
|
} finally {
|
|
5319
5468
|
releasePreparedAttachments();
|
|
5320
5469
|
this.activeTurns.delete(threadId);
|
|
5470
|
+
this.activeTurnIds.delete(threadId);
|
|
5321
5471
|
if (!sawTurnEnd) {
|
|
5322
5472
|
sink.close();
|
|
5323
5473
|
}
|
|
@@ -5335,10 +5485,19 @@ var CodexAppServerAdapter = class {
|
|
|
5335
5485
|
return null;
|
|
5336
5486
|
const handle = this.opts.sessionManager.createForkSessionKey();
|
|
5337
5487
|
try {
|
|
5338
|
-
const
|
|
5488
|
+
const forkParams = {
|
|
5339
5489
|
threadId: parentThreadId,
|
|
5340
5490
|
ephemeral: true
|
|
5341
|
-
}
|
|
5491
|
+
};
|
|
5492
|
+
if (this.opts.useParallProvider) {
|
|
5493
|
+
forkParams.modelProvider = "parall";
|
|
5494
|
+
}
|
|
5495
|
+
if (this.opts.model)
|
|
5496
|
+
forkParams.model = this.opts.model;
|
|
5497
|
+
if (this.opts.reasoningEffort) {
|
|
5498
|
+
forkParams.config = { modelReasoningEffort: this.opts.reasoningEffort };
|
|
5499
|
+
}
|
|
5500
|
+
const result = await client.sendRequest("thread/fork", forkParams);
|
|
5342
5501
|
const forkedThreadId = extractThreadId(result);
|
|
5343
5502
|
if (!forkedThreadId) {
|
|
5344
5503
|
this.opts.log?.warn?.("codex-agent: thread/fork returned no thread id");
|
|
@@ -5364,6 +5523,8 @@ var CodexAppServerAdapter = class {
|
|
|
5364
5523
|
this.proc = null;
|
|
5365
5524
|
this.client = null;
|
|
5366
5525
|
this.initialized = false;
|
|
5526
|
+
this.activeTurnIds.clear();
|
|
5527
|
+
this.pendingInjections.clear();
|
|
5367
5528
|
if (client)
|
|
5368
5529
|
client.dispose(new Error("adapter stopped"));
|
|
5369
5530
|
if (proc && proc.exitCode === null && proc.signalCode === null) {
|
|
@@ -5379,6 +5540,8 @@ var CodexAppServerAdapter = class {
|
|
|
5379
5540
|
activeSink.close();
|
|
5380
5541
|
}
|
|
5381
5542
|
this.activeTurns.clear();
|
|
5543
|
+
this.activeTurnIds.clear();
|
|
5544
|
+
this.pendingInjections.clear();
|
|
5382
5545
|
this.client = null;
|
|
5383
5546
|
this.proc = null;
|
|
5384
5547
|
this.initialized = false;
|
|
@@ -5462,6 +5625,8 @@ var CodexAppServerAdapter = class {
|
|
|
5462
5625
|
activeSink.close();
|
|
5463
5626
|
}
|
|
5464
5627
|
this.activeTurns.clear();
|
|
5628
|
+
this.activeTurnIds.clear();
|
|
5629
|
+
this.pendingInjections.clear();
|
|
5465
5630
|
this.resumedThreadIds.clear();
|
|
5466
5631
|
this.client = null;
|
|
5467
5632
|
this.proc = null;
|
|
@@ -5507,6 +5672,7 @@ var CodexAppServerAdapter = class {
|
|
|
5507
5672
|
sink.push({ kind: "runtime", event });
|
|
5508
5673
|
}
|
|
5509
5674
|
if (method === "turn/completed") {
|
|
5675
|
+
this.activeTurnIds.delete(threadId);
|
|
5510
5676
|
sink.push({ kind: "turn_end", threadId });
|
|
5511
5677
|
}
|
|
5512
5678
|
}
|
|
@@ -5584,6 +5750,17 @@ function extractThreadId(result) {
|
|
|
5584
5750
|
return thread.id;
|
|
5585
5751
|
return void 0;
|
|
5586
5752
|
}
|
|
5753
|
+
function extractTurnId(result) {
|
|
5754
|
+
if (!result || typeof result !== "object")
|
|
5755
|
+
return void 0;
|
|
5756
|
+
const r = result;
|
|
5757
|
+
if (typeof r.turnId === "string")
|
|
5758
|
+
return r.turnId;
|
|
5759
|
+
const turn = r.turn;
|
|
5760
|
+
if (turn && typeof turn.id === "string")
|
|
5761
|
+
return turn.id;
|
|
5762
|
+
return void 0;
|
|
5763
|
+
}
|
|
5587
5764
|
function extractThreadIdFromNotification(params) {
|
|
5588
5765
|
if (!params || typeof params !== "object")
|
|
5589
5766
|
return void 0;
|