@parall/daemon 1.42.0 → 1.42.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 +11 -11
- package/bundle/parall-browser-pod.js +3 -3
- package/bundle/parall-claude-agent.js +81 -43
- package/bundle/parall-codex-agent.js +305 -46
- package/bundle/parall-daemon.js +9 -4
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +15 -2
- package/package.json +6 -6
package/bundle/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.42.
|
|
3
|
-
"built_at": "2026-07-
|
|
2
|
+
"version": "1.42.1",
|
|
3
|
+
"built_at": "2026-07-11T03:40:29.108Z",
|
|
4
4
|
"min_node_version": "20.0.0",
|
|
5
5
|
"files": {
|
|
6
6
|
"bb-browser-daemon.js": {
|
|
@@ -16,25 +16,25 @@
|
|
|
16
16
|
"size": 18
|
|
17
17
|
},
|
|
18
18
|
"parall-browser-pod.js": {
|
|
19
|
-
"sha256": "
|
|
20
|
-
"size":
|
|
19
|
+
"sha256": "4e98a70b593c352f4fa99cd2ff8b350346437942bd1134e3d500211585c5a94a",
|
|
20
|
+
"size": 1699246
|
|
21
21
|
},
|
|
22
22
|
"parall-claude-agent.js": {
|
|
23
|
-
"sha256": "
|
|
24
|
-
"size":
|
|
23
|
+
"sha256": "8d7d9a8c8b6d1d90f7e84489fd05c059c5c5d24d321274ff3916f12454df2e19",
|
|
24
|
+
"size": 1626635
|
|
25
25
|
},
|
|
26
26
|
"parall-codex-agent.js": {
|
|
27
|
-
"sha256": "
|
|
28
|
-
"size":
|
|
27
|
+
"sha256": "5ab229def8061ab05bc040571d5cb175bb7c9d8fce565682ab04c6b1a81b8649",
|
|
28
|
+
"size": 1664012
|
|
29
29
|
},
|
|
30
30
|
"parall-daemon.js": {
|
|
31
|
-
"sha256": "
|
|
32
|
-
"size":
|
|
31
|
+
"sha256": "354bdc719c5bde1e7f4eaae19f1d895fced7b1a6feee8590d727812b6e5fe2f4",
|
|
32
|
+
"size": 1719706
|
|
33
33
|
},
|
|
34
34
|
"parall-openclaw-agent.js": {
|
|
35
35
|
"sha256": "505433b4bf3a4b8dbb7b96978d8693d6c48079f4513282ff1ee59a6d13b3eddf",
|
|
36
36
|
"size": 9801
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
-
"signature": "
|
|
39
|
+
"signature": "T/TtjoBJx65Xb8MftcuGyi+F0J8kpPBmzKIl8hMLP+igdhlAzKTLEHvDN4gB72BOd7lUHOFLwufiyyUye/TbCg=="
|
|
40
40
|
}
|
|
@@ -36213,9 +36213,9 @@ var ParallClient = class _ParallClient {
|
|
|
36213
36213
|
async retryAgentWorkspaceSetup(orgId, machineId, agentId) {
|
|
36214
36214
|
return this.request("POST", ENDPOINTS.MACHINE_AGENT_WORKSPACE_SETUP(orgId, machineId, agentId));
|
|
36215
36215
|
}
|
|
36216
|
-
async patchMachineLLMSource(orgId, machineId,
|
|
36216
|
+
async patchMachineLLMSource(orgId, machineId, llmSource2) {
|
|
36217
36217
|
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), {
|
|
36218
|
-
llm_source:
|
|
36218
|
+
llm_source: llmSource2
|
|
36219
36219
|
});
|
|
36220
36220
|
}
|
|
36221
36221
|
/**
|
|
@@ -36442,7 +36442,7 @@ var ParallClient = class _ParallClient {
|
|
|
36442
36442
|
async claimDispatch(orgId, req) {
|
|
36443
36443
|
return this.request("POST", ENDPOINTS.DISPATCH_CLAIM(orgId), req);
|
|
36444
36444
|
}
|
|
36445
|
-
/** Fold
|
|
36445
|
+
/** Fold into a live lane: 409 STALE_LANE when dethroned; 409 INELIGIBLE_REF for a bad ref. */
|
|
36446
36446
|
async steerDispatch(orgId, req) {
|
|
36447
36447
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
36448
36448
|
}
|
|
@@ -28641,7 +28641,7 @@ var ParallClient = class _ParallClient {
|
|
|
28641
28641
|
async claimDispatch(orgId, req) {
|
|
28642
28642
|
return this.request("POST", ENDPOINTS.DISPATCH_CLAIM(orgId), req);
|
|
28643
28643
|
}
|
|
28644
|
-
/** Fold
|
|
28644
|
+
/** Fold into a live lane: 409 STALE_LANE when dethroned; 409 INELIGIBLE_REF for a bad ref. */
|
|
28645
28645
|
async steerDispatch(orgId, req) {
|
|
28646
28646
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
28647
28647
|
}
|
|
@@ -30118,7 +30118,7 @@ async function dispatchLaneGroup(host, opts) {
|
|
|
30118
30118
|
async function consumeTypedDispatch(host, ref, run, ack) {
|
|
30119
30119
|
if (!host.laneLedger || host.ledgerDisabled) {
|
|
30120
30120
|
if (await run(ref.dispatchEventId))
|
|
30121
|
-
ack(ref.dispatchEventId);
|
|
30121
|
+
await ack(ref.dispatchEventId);
|
|
30122
30122
|
return;
|
|
30123
30123
|
}
|
|
30124
30124
|
let lane;
|
|
@@ -30128,7 +30128,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30128
30128
|
if (err instanceof LedgerUnsupportedError) {
|
|
30129
30129
|
host.disableLedger("claim endpoint missing");
|
|
30130
30130
|
if (await run(ref.dispatchEventId))
|
|
30131
|
-
ack(ref.dispatchEventId);
|
|
30131
|
+
await ack(ref.dispatchEventId);
|
|
30132
30132
|
return;
|
|
30133
30133
|
}
|
|
30134
30134
|
throw err;
|
|
@@ -30139,7 +30139,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30139
30139
|
}
|
|
30140
30140
|
try {
|
|
30141
30141
|
if (await run(lane.typedDispatchEventId))
|
|
30142
|
-
ack(lane.typedDispatchEventId);
|
|
30142
|
+
await ack(lane.typedDispatchEventId);
|
|
30143
30143
|
} finally {
|
|
30144
30144
|
await host.laneLedger.completeIfIdle(lane.laneKey, false).catch(() => {
|
|
30145
30145
|
});
|
|
@@ -30593,29 +30593,33 @@ var ParallAgentGateway = class {
|
|
|
30593
30593
|
try {
|
|
30594
30594
|
await this.consumeTypedDispatch(data.dispatch_event_id ? { dispatchEventId: data.dispatch_event_id } : { sourceType: "task_activity", sourceId: data.id }, (dispatchEventId) => this.handleTaskAssignment(data, data.id, dispatchEventId), (dispatchEventId) => {
|
|
30595
30595
|
if (dispatchEventId) {
|
|
30596
|
-
this.
|
|
30596
|
+
return this.ackDispatchEvent(dispatchEventId, () => {
|
|
30597
|
+
this.dispatchedTasks.delete(`${data.id}:${data.updated_at}`);
|
|
30597
30598
|
});
|
|
30598
|
-
return;
|
|
30599
30599
|
}
|
|
30600
|
-
this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30600
|
+
return this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30601
30601
|
source_type: "task_activity",
|
|
30602
30602
|
source_id: data.id
|
|
30603
|
-
}).
|
|
30604
|
-
});
|
|
30603
|
+
}).then(() => void 0, () => void 0);
|
|
30605
30604
|
});
|
|
30606
30605
|
} catch (err) {
|
|
30607
30606
|
this.opts.log?.error(`task dispatch failed for ${data.id}: ${String(err)}`);
|
|
30608
30607
|
}
|
|
30609
30608
|
});
|
|
30610
30609
|
ws.on("dispatch.new", async (data) => {
|
|
30611
|
-
if (data.event_type === "
|
|
30610
|
+
if (data.event_type === "task_assign") {
|
|
30611
|
+
if (!data.task_id)
|
|
30612
|
+
return;
|
|
30613
|
+
try {
|
|
30614
|
+
await this.handleTaskAssignmentRedrive(data);
|
|
30615
|
+
} catch (err) {
|
|
30616
|
+
this.opts.log?.error(`task assignment re-drive failed for ${data.task_id}: ${String(err)}`);
|
|
30617
|
+
}
|
|
30618
|
+
} else if (data.event_type === "task_comment") {
|
|
30612
30619
|
if (!data.source_id || !data.task_id)
|
|
30613
30620
|
return;
|
|
30614
30621
|
try {
|
|
30615
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleTaskComment(data.source_id, data.task_id ?? "", data.actor_id, data.delivery_reason), () =>
|
|
30616
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30617
|
-
});
|
|
30618
|
-
});
|
|
30622
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleTaskComment(data.source_id, data.task_id ?? "", data.actor_id, data.delivery_reason), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30619
30623
|
} catch (err) {
|
|
30620
30624
|
this.opts.log?.error(`task comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30621
30625
|
}
|
|
@@ -30623,10 +30627,7 @@ var ParallAgentGateway = class {
|
|
|
30623
30627
|
if (!data.source_id)
|
|
30624
30628
|
return;
|
|
30625
30629
|
try {
|
|
30626
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () =>
|
|
30627
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30628
|
-
});
|
|
30629
|
-
});
|
|
30630
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30630
30631
|
} catch (err) {
|
|
30631
30632
|
this.opts.log?.error(`wiki comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30632
30633
|
}
|
|
@@ -30637,10 +30638,7 @@ var ParallAgentGateway = class {
|
|
|
30637
30638
|
await this.consumeTypedDispatch({ dispatchEventId: data.id }, (dispatchEventId) => this.handleTaskDispatch(data.task_id ?? "", data.source_id ?? data.task_id ?? "", {
|
|
30638
30639
|
allowCreator: true,
|
|
30639
30640
|
dispatchEventId
|
|
30640
|
-
}), () =>
|
|
30641
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30642
|
-
});
|
|
30643
|
-
});
|
|
30641
|
+
}), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30644
30642
|
} catch (err) {
|
|
30645
30643
|
this.opts.log?.error(`task update dispatch failed for ${data.task_id}: ${String(err)}`);
|
|
30646
30644
|
}
|
|
@@ -30648,10 +30646,7 @@ var ParallAgentGateway = class {
|
|
|
30648
30646
|
if (!data.source_id)
|
|
30649
30647
|
return;
|
|
30650
30648
|
try {
|
|
30651
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () =>
|
|
30652
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30653
|
-
});
|
|
30654
|
-
});
|
|
30649
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30655
30650
|
} catch (err) {
|
|
30656
30651
|
this.opts.log?.error(`schedule fire dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30657
30652
|
}
|
|
@@ -30659,10 +30654,7 @@ var ParallAgentGateway = class {
|
|
|
30659
30654
|
if (!data.source_id)
|
|
30660
30655
|
return;
|
|
30661
30656
|
try {
|
|
30662
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () =>
|
|
30663
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30664
|
-
});
|
|
30665
|
-
});
|
|
30657
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30666
30658
|
} catch (err) {
|
|
30667
30659
|
this.opts.log?.error(`external trigger dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30668
30660
|
}
|
|
@@ -30670,10 +30662,7 @@ var ParallAgentGateway = class {
|
|
|
30670
30662
|
if (!data.source_id)
|
|
30671
30663
|
return;
|
|
30672
30664
|
try {
|
|
30673
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () =>
|
|
30674
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30675
|
-
});
|
|
30676
|
-
});
|
|
30665
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30677
30666
|
} catch (err) {
|
|
30678
30667
|
this.opts.log?.error(`channel message dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30679
30668
|
}
|
|
@@ -30681,10 +30670,7 @@ var ParallAgentGateway = class {
|
|
|
30681
30670
|
if (!data.source_id)
|
|
30682
30671
|
return;
|
|
30683
30672
|
try {
|
|
30684
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleApprovalDecided(data.source_id, data.actor_id, data.chat_id ?? null), () =>
|
|
30685
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30686
|
-
});
|
|
30687
|
-
});
|
|
30673
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleApprovalDecided(data.source_id, data.actor_id, data.chat_id ?? null), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30688
30674
|
} catch (err) {
|
|
30689
30675
|
this.opts.log?.error(`approval decided dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30690
30676
|
}
|
|
@@ -30694,7 +30680,7 @@ var ParallAgentGateway = class {
|
|
|
30694
30680
|
} catch (err) {
|
|
30695
30681
|
this.opts.log?.error(`message re-drive failed for ${data.source_id}: ${String(err)}`);
|
|
30696
30682
|
}
|
|
30697
|
-
} else if (data.event_type !== "message"
|
|
30683
|
+
} else if (data.event_type !== "message") {
|
|
30698
30684
|
this.opts.log?.info(`dispatch.new with unhandled event_type=${String(data.event_type)} (id=${data.id}) \u2014 no-op`);
|
|
30699
30685
|
}
|
|
30700
30686
|
});
|
|
@@ -30762,6 +30748,50 @@ var ParallAgentGateway = class {
|
|
|
30762
30748
|
consumeTypedDispatch(ref, run, ack) {
|
|
30763
30749
|
return consumeTypedDispatch(this.laneFlowHost(), ref, run, ack);
|
|
30764
30750
|
}
|
|
30751
|
+
// Typed completion must wait until the administrative ack has either
|
|
30752
|
+
// committed or failed. Errors stay best-effort: a failed ack leaves the row
|
|
30753
|
+
// received, so Complete releases and re-drives it safely.
|
|
30754
|
+
ackDispatchEvent(dispatchEventId, onFailure) {
|
|
30755
|
+
return this.opts.client.ackDispatchByID(this.opts.config.org_id, dispatchEventId).then(() => void 0, (err) => {
|
|
30756
|
+
onFailure?.();
|
|
30757
|
+
this.opts.log?.warn(`dispatch ack failed for ${dispatchEventId}, releasing for re-drive: ${String(err)}`);
|
|
30758
|
+
});
|
|
30759
|
+
}
|
|
30760
|
+
clearTypedDispatchDedupe(item) {
|
|
30761
|
+
switch (item.event_type) {
|
|
30762
|
+
case "task_assign":
|
|
30763
|
+
case "task_update":
|
|
30764
|
+
if (item.task_id) {
|
|
30765
|
+
const prefix = `${item.task_id}:`;
|
|
30766
|
+
for (const key of this.dispatchedTasks) {
|
|
30767
|
+
if (key.startsWith(prefix))
|
|
30768
|
+
this.dispatchedTasks.delete(key);
|
|
30769
|
+
}
|
|
30770
|
+
}
|
|
30771
|
+
break;
|
|
30772
|
+
case "task_comment":
|
|
30773
|
+
case "wiki_comment":
|
|
30774
|
+
if (item.source_id)
|
|
30775
|
+
this.dispatchedTasks.delete(`comment:${item.source_id}`);
|
|
30776
|
+
break;
|
|
30777
|
+
case "schedule.fire":
|
|
30778
|
+
if (item.source_id)
|
|
30779
|
+
this.dispatchedTasks.delete(`schedule_run:${item.source_id}`);
|
|
30780
|
+
break;
|
|
30781
|
+
case "external_trigger":
|
|
30782
|
+
if (item.source_id)
|
|
30783
|
+
this.dispatchedTasks.delete(`external_trigger_run:${item.source_id}`);
|
|
30784
|
+
break;
|
|
30785
|
+
case "channel_message":
|
|
30786
|
+
if (item.source_id)
|
|
30787
|
+
this.dispatchedMessages.delete(`channel_message:${item.source_id}`);
|
|
30788
|
+
break;
|
|
30789
|
+
case "approval_decided":
|
|
30790
|
+
if (item.source_id)
|
|
30791
|
+
this.dispatchedTasks.delete(`approval:${item.source_id}`);
|
|
30792
|
+
break;
|
|
30793
|
+
}
|
|
30794
|
+
}
|
|
30765
30795
|
buildDispatchContext(event, sessionKey) {
|
|
30766
30796
|
const binding = this.sessionBindings.get(sessionKey);
|
|
30767
30797
|
return {
|
|
@@ -31728,6 +31758,17 @@ var ParallAgentGateway = class {
|
|
|
31728
31758
|
chat_id: item.chat_id
|
|
31729
31759
|
});
|
|
31730
31760
|
}
|
|
31761
|
+
// A task assignment's first delivery rides task.assigned, but a typed lane
|
|
31762
|
+
// released without an effect is re-driven as dispatch.new. Reuse the exact
|
|
31763
|
+
// typed claim path used by catch-up so that recovery does not require a
|
|
31764
|
+
// runtime reconnect.
|
|
31765
|
+
async handleTaskAssignmentRedrive(item) {
|
|
31766
|
+
if (!item.task_id)
|
|
31767
|
+
return;
|
|
31768
|
+
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
|
31769
|
+
dispatchEventId
|
|
31770
|
+
}), (dispatchEventId) => this.ackDispatchEvent(dispatchEventId ?? item.id, () => this.clearTypedDispatchDedupe(item)));
|
|
31771
|
+
}
|
|
31731
31772
|
consumeMessageWorkItem(item) {
|
|
31732
31773
|
return consumeMessageWorkItem(this.laneFlowHost(), item);
|
|
31733
31774
|
}
|
|
@@ -32193,10 +32234,7 @@ var ParallAgentGateway = class {
|
|
|
32193
32234
|
}
|
|
32194
32235
|
processed++;
|
|
32195
32236
|
try {
|
|
32196
|
-
const ackItem = () =>
|
|
32197
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, item.id).catch(() => {
|
|
32198
|
-
});
|
|
32199
|
-
};
|
|
32237
|
+
const ackItem = () => this.ackDispatchEvent(item.id, () => this.clearTypedDispatchDedupe(item));
|
|
32200
32238
|
if (item.event_type === "task_assign" && item.task_id) {
|
|
32201
32239
|
try {
|
|
32202
32240
|
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
|
@@ -28641,7 +28641,7 @@ var ParallClient = class _ParallClient {
|
|
|
28641
28641
|
async claimDispatch(orgId, req) {
|
|
28642
28642
|
return this.request("POST", ENDPOINTS.DISPATCH_CLAIM(orgId), req);
|
|
28643
28643
|
}
|
|
28644
|
-
/** Fold
|
|
28644
|
+
/** Fold into a live lane: 409 STALE_LANE when dethroned; 409 INELIGIBLE_REF for a bad ref. */
|
|
28645
28645
|
async steerDispatch(orgId, req) {
|
|
28646
28646
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
28647
28647
|
}
|
|
@@ -30118,7 +30118,7 @@ async function dispatchLaneGroup(host, opts) {
|
|
|
30118
30118
|
async function consumeTypedDispatch(host, ref, run, ack) {
|
|
30119
30119
|
if (!host.laneLedger || host.ledgerDisabled) {
|
|
30120
30120
|
if (await run(ref.dispatchEventId))
|
|
30121
|
-
ack(ref.dispatchEventId);
|
|
30121
|
+
await ack(ref.dispatchEventId);
|
|
30122
30122
|
return;
|
|
30123
30123
|
}
|
|
30124
30124
|
let lane;
|
|
@@ -30128,7 +30128,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30128
30128
|
if (err instanceof LedgerUnsupportedError) {
|
|
30129
30129
|
host.disableLedger("claim endpoint missing");
|
|
30130
30130
|
if (await run(ref.dispatchEventId))
|
|
30131
|
-
ack(ref.dispatchEventId);
|
|
30131
|
+
await ack(ref.dispatchEventId);
|
|
30132
30132
|
return;
|
|
30133
30133
|
}
|
|
30134
30134
|
throw err;
|
|
@@ -30139,7 +30139,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30139
30139
|
}
|
|
30140
30140
|
try {
|
|
30141
30141
|
if (await run(lane.typedDispatchEventId))
|
|
30142
|
-
ack(lane.typedDispatchEventId);
|
|
30142
|
+
await ack(lane.typedDispatchEventId);
|
|
30143
30143
|
} finally {
|
|
30144
30144
|
await host.laneLedger.completeIfIdle(lane.laneKey, false).catch(() => {
|
|
30145
30145
|
});
|
|
@@ -30593,29 +30593,33 @@ var ParallAgentGateway = class {
|
|
|
30593
30593
|
try {
|
|
30594
30594
|
await this.consumeTypedDispatch(data.dispatch_event_id ? { dispatchEventId: data.dispatch_event_id } : { sourceType: "task_activity", sourceId: data.id }, (dispatchEventId) => this.handleTaskAssignment(data, data.id, dispatchEventId), (dispatchEventId) => {
|
|
30595
30595
|
if (dispatchEventId) {
|
|
30596
|
-
this.
|
|
30596
|
+
return this.ackDispatchEvent(dispatchEventId, () => {
|
|
30597
|
+
this.dispatchedTasks.delete(`${data.id}:${data.updated_at}`);
|
|
30597
30598
|
});
|
|
30598
|
-
return;
|
|
30599
30599
|
}
|
|
30600
|
-
this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30600
|
+
return this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30601
30601
|
source_type: "task_activity",
|
|
30602
30602
|
source_id: data.id
|
|
30603
|
-
}).
|
|
30604
|
-
});
|
|
30603
|
+
}).then(() => void 0, () => void 0);
|
|
30605
30604
|
});
|
|
30606
30605
|
} catch (err) {
|
|
30607
30606
|
this.opts.log?.error(`task dispatch failed for ${data.id}: ${String(err)}`);
|
|
30608
30607
|
}
|
|
30609
30608
|
});
|
|
30610
30609
|
ws.on("dispatch.new", async (data) => {
|
|
30611
|
-
if (data.event_type === "
|
|
30610
|
+
if (data.event_type === "task_assign") {
|
|
30611
|
+
if (!data.task_id)
|
|
30612
|
+
return;
|
|
30613
|
+
try {
|
|
30614
|
+
await this.handleTaskAssignmentRedrive(data);
|
|
30615
|
+
} catch (err) {
|
|
30616
|
+
this.opts.log?.error(`task assignment re-drive failed for ${data.task_id}: ${String(err)}`);
|
|
30617
|
+
}
|
|
30618
|
+
} else if (data.event_type === "task_comment") {
|
|
30612
30619
|
if (!data.source_id || !data.task_id)
|
|
30613
30620
|
return;
|
|
30614
30621
|
try {
|
|
30615
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleTaskComment(data.source_id, data.task_id ?? "", data.actor_id, data.delivery_reason), () =>
|
|
30616
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30617
|
-
});
|
|
30618
|
-
});
|
|
30622
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleTaskComment(data.source_id, data.task_id ?? "", data.actor_id, data.delivery_reason), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30619
30623
|
} catch (err) {
|
|
30620
30624
|
this.opts.log?.error(`task comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30621
30625
|
}
|
|
@@ -30623,10 +30627,7 @@ var ParallAgentGateway = class {
|
|
|
30623
30627
|
if (!data.source_id)
|
|
30624
30628
|
return;
|
|
30625
30629
|
try {
|
|
30626
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () =>
|
|
30627
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30628
|
-
});
|
|
30629
|
-
});
|
|
30630
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30630
30631
|
} catch (err) {
|
|
30631
30632
|
this.opts.log?.error(`wiki comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30632
30633
|
}
|
|
@@ -30637,10 +30638,7 @@ var ParallAgentGateway = class {
|
|
|
30637
30638
|
await this.consumeTypedDispatch({ dispatchEventId: data.id }, (dispatchEventId) => this.handleTaskDispatch(data.task_id ?? "", data.source_id ?? data.task_id ?? "", {
|
|
30638
30639
|
allowCreator: true,
|
|
30639
30640
|
dispatchEventId
|
|
30640
|
-
}), () =>
|
|
30641
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30642
|
-
});
|
|
30643
|
-
});
|
|
30641
|
+
}), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30644
30642
|
} catch (err) {
|
|
30645
30643
|
this.opts.log?.error(`task update dispatch failed for ${data.task_id}: ${String(err)}`);
|
|
30646
30644
|
}
|
|
@@ -30648,10 +30646,7 @@ var ParallAgentGateway = class {
|
|
|
30648
30646
|
if (!data.source_id)
|
|
30649
30647
|
return;
|
|
30650
30648
|
try {
|
|
30651
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () =>
|
|
30652
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30653
|
-
});
|
|
30654
|
-
});
|
|
30649
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30655
30650
|
} catch (err) {
|
|
30656
30651
|
this.opts.log?.error(`schedule fire dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30657
30652
|
}
|
|
@@ -30659,10 +30654,7 @@ var ParallAgentGateway = class {
|
|
|
30659
30654
|
if (!data.source_id)
|
|
30660
30655
|
return;
|
|
30661
30656
|
try {
|
|
30662
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () =>
|
|
30663
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30664
|
-
});
|
|
30665
|
-
});
|
|
30657
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30666
30658
|
} catch (err) {
|
|
30667
30659
|
this.opts.log?.error(`external trigger dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30668
30660
|
}
|
|
@@ -30670,10 +30662,7 @@ var ParallAgentGateway = class {
|
|
|
30670
30662
|
if (!data.source_id)
|
|
30671
30663
|
return;
|
|
30672
30664
|
try {
|
|
30673
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () =>
|
|
30674
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30675
|
-
});
|
|
30676
|
-
});
|
|
30665
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30677
30666
|
} catch (err) {
|
|
30678
30667
|
this.opts.log?.error(`channel message dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30679
30668
|
}
|
|
@@ -30681,10 +30670,7 @@ var ParallAgentGateway = class {
|
|
|
30681
30670
|
if (!data.source_id)
|
|
30682
30671
|
return;
|
|
30683
30672
|
try {
|
|
30684
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleApprovalDecided(data.source_id, data.actor_id, data.chat_id ?? null), () =>
|
|
30685
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30686
|
-
});
|
|
30687
|
-
});
|
|
30673
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleApprovalDecided(data.source_id, data.actor_id, data.chat_id ?? null), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30688
30674
|
} catch (err) {
|
|
30689
30675
|
this.opts.log?.error(`approval decided dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30690
30676
|
}
|
|
@@ -30694,7 +30680,7 @@ var ParallAgentGateway = class {
|
|
|
30694
30680
|
} catch (err) {
|
|
30695
30681
|
this.opts.log?.error(`message re-drive failed for ${data.source_id}: ${String(err)}`);
|
|
30696
30682
|
}
|
|
30697
|
-
} else if (data.event_type !== "message"
|
|
30683
|
+
} else if (data.event_type !== "message") {
|
|
30698
30684
|
this.opts.log?.info(`dispatch.new with unhandled event_type=${String(data.event_type)} (id=${data.id}) \u2014 no-op`);
|
|
30699
30685
|
}
|
|
30700
30686
|
});
|
|
@@ -30762,6 +30748,50 @@ var ParallAgentGateway = class {
|
|
|
30762
30748
|
consumeTypedDispatch(ref, run, ack) {
|
|
30763
30749
|
return consumeTypedDispatch(this.laneFlowHost(), ref, run, ack);
|
|
30764
30750
|
}
|
|
30751
|
+
// Typed completion must wait until the administrative ack has either
|
|
30752
|
+
// committed or failed. Errors stay best-effort: a failed ack leaves the row
|
|
30753
|
+
// received, so Complete releases and re-drives it safely.
|
|
30754
|
+
ackDispatchEvent(dispatchEventId, onFailure) {
|
|
30755
|
+
return this.opts.client.ackDispatchByID(this.opts.config.org_id, dispatchEventId).then(() => void 0, (err) => {
|
|
30756
|
+
onFailure?.();
|
|
30757
|
+
this.opts.log?.warn(`dispatch ack failed for ${dispatchEventId}, releasing for re-drive: ${String(err)}`);
|
|
30758
|
+
});
|
|
30759
|
+
}
|
|
30760
|
+
clearTypedDispatchDedupe(item) {
|
|
30761
|
+
switch (item.event_type) {
|
|
30762
|
+
case "task_assign":
|
|
30763
|
+
case "task_update":
|
|
30764
|
+
if (item.task_id) {
|
|
30765
|
+
const prefix = `${item.task_id}:`;
|
|
30766
|
+
for (const key of this.dispatchedTasks) {
|
|
30767
|
+
if (key.startsWith(prefix))
|
|
30768
|
+
this.dispatchedTasks.delete(key);
|
|
30769
|
+
}
|
|
30770
|
+
}
|
|
30771
|
+
break;
|
|
30772
|
+
case "task_comment":
|
|
30773
|
+
case "wiki_comment":
|
|
30774
|
+
if (item.source_id)
|
|
30775
|
+
this.dispatchedTasks.delete(`comment:${item.source_id}`);
|
|
30776
|
+
break;
|
|
30777
|
+
case "schedule.fire":
|
|
30778
|
+
if (item.source_id)
|
|
30779
|
+
this.dispatchedTasks.delete(`schedule_run:${item.source_id}`);
|
|
30780
|
+
break;
|
|
30781
|
+
case "external_trigger":
|
|
30782
|
+
if (item.source_id)
|
|
30783
|
+
this.dispatchedTasks.delete(`external_trigger_run:${item.source_id}`);
|
|
30784
|
+
break;
|
|
30785
|
+
case "channel_message":
|
|
30786
|
+
if (item.source_id)
|
|
30787
|
+
this.dispatchedMessages.delete(`channel_message:${item.source_id}`);
|
|
30788
|
+
break;
|
|
30789
|
+
case "approval_decided":
|
|
30790
|
+
if (item.source_id)
|
|
30791
|
+
this.dispatchedTasks.delete(`approval:${item.source_id}`);
|
|
30792
|
+
break;
|
|
30793
|
+
}
|
|
30794
|
+
}
|
|
30765
30795
|
buildDispatchContext(event, sessionKey) {
|
|
30766
30796
|
const binding = this.sessionBindings.get(sessionKey);
|
|
30767
30797
|
return {
|
|
@@ -31728,6 +31758,17 @@ var ParallAgentGateway = class {
|
|
|
31728
31758
|
chat_id: item.chat_id
|
|
31729
31759
|
});
|
|
31730
31760
|
}
|
|
31761
|
+
// A task assignment's first delivery rides task.assigned, but a typed lane
|
|
31762
|
+
// released without an effect is re-driven as dispatch.new. Reuse the exact
|
|
31763
|
+
// typed claim path used by catch-up so that recovery does not require a
|
|
31764
|
+
// runtime reconnect.
|
|
31765
|
+
async handleTaskAssignmentRedrive(item) {
|
|
31766
|
+
if (!item.task_id)
|
|
31767
|
+
return;
|
|
31768
|
+
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
|
31769
|
+
dispatchEventId
|
|
31770
|
+
}), (dispatchEventId) => this.ackDispatchEvent(dispatchEventId ?? item.id, () => this.clearTypedDispatchDedupe(item)));
|
|
31771
|
+
}
|
|
31731
31772
|
consumeMessageWorkItem(item) {
|
|
31732
31773
|
return consumeMessageWorkItem(this.laneFlowHost(), item);
|
|
31733
31774
|
}
|
|
@@ -32193,10 +32234,7 @@ var ParallAgentGateway = class {
|
|
|
32193
32234
|
}
|
|
32194
32235
|
processed++;
|
|
32195
32236
|
try {
|
|
32196
|
-
const ackItem = () =>
|
|
32197
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, item.id).catch(() => {
|
|
32198
|
-
});
|
|
32199
|
-
};
|
|
32237
|
+
const ackItem = () => this.ackDispatchEvent(item.id, () => this.clearTypedDispatchDedupe(item));
|
|
32200
32238
|
if (item.event_type === "task_assign" && item.task_id) {
|
|
32201
32239
|
try {
|
|
32202
32240
|
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
|
@@ -35691,7 +35729,220 @@ function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
|
|
|
35691
35729
|
}
|
|
35692
35730
|
|
|
35693
35731
|
// ts/codex-agent/dist/workspace.js
|
|
35732
|
+
var CONFIG_LOCK_TIMINGS = {
|
|
35733
|
+
staleMs: 1e4,
|
|
35734
|
+
waitMs: 15e3,
|
|
35735
|
+
retryMs: 25
|
|
35736
|
+
};
|
|
35737
|
+
var SLEEP_SIGNAL = new Int32Array(new SharedArrayBuffer(4));
|
|
35738
|
+
function sleepSync(ms) {
|
|
35739
|
+
Atomics.wait(SLEEP_SIGNAL, 0, 0, ms);
|
|
35740
|
+
}
|
|
35741
|
+
function withConfigLock(codexHome, log2, fn) {
|
|
35742
|
+
const queueDir = path8.join(codexHome, "config.toml.lock.d");
|
|
35743
|
+
let ticketName = bakeryEnqueue(queueDir);
|
|
35744
|
+
let ticketPath = ticketName ? path8.join(queueDir, ticketName) : "";
|
|
35745
|
+
let acquired = false;
|
|
35746
|
+
let heldPath = "";
|
|
35747
|
+
const deadline = Date.now() + CONFIG_LOCK_TIMINGS.waitMs;
|
|
35748
|
+
while (ticketName && Date.now() < deadline) {
|
|
35749
|
+
let names;
|
|
35750
|
+
try {
|
|
35751
|
+
names = fs8.readdirSync(queueDir).sort();
|
|
35752
|
+
} catch {
|
|
35753
|
+
break;
|
|
35754
|
+
}
|
|
35755
|
+
if (!names.includes(ticketName)) {
|
|
35756
|
+
ticketName = bakeryEnqueue(queueDir);
|
|
35757
|
+
if (!ticketName)
|
|
35758
|
+
break;
|
|
35759
|
+
ticketPath = path8.join(queueDir, ticketName);
|
|
35760
|
+
continue;
|
|
35761
|
+
}
|
|
35762
|
+
const now = Date.now();
|
|
35763
|
+
let rescan = false;
|
|
35764
|
+
let blocked = false;
|
|
35765
|
+
let head;
|
|
35766
|
+
for (const name of names) {
|
|
35767
|
+
const entryPath = path8.join(queueDir, name);
|
|
35768
|
+
if (name.startsWith("held-")) {
|
|
35769
|
+
const enteredAt = Number.parseInt(name.slice(5, 20), 10);
|
|
35770
|
+
if (Number.isFinite(enteredAt) && now - enteredAt > CONFIG_LOCK_TIMINGS.staleMs) {
|
|
35771
|
+
try {
|
|
35772
|
+
fs8.unlinkSync(entryPath);
|
|
35773
|
+
} catch {
|
|
35774
|
+
}
|
|
35775
|
+
rescan = true;
|
|
35776
|
+
break;
|
|
35777
|
+
}
|
|
35778
|
+
blocked = true;
|
|
35779
|
+
break;
|
|
35780
|
+
}
|
|
35781
|
+
let mtimeMs;
|
|
35782
|
+
try {
|
|
35783
|
+
mtimeMs = fs8.statSync(entryPath).mtimeMs;
|
|
35784
|
+
} catch {
|
|
35785
|
+
rescan = true;
|
|
35786
|
+
break;
|
|
35787
|
+
}
|
|
35788
|
+
if (now - mtimeMs > CONFIG_LOCK_TIMINGS.staleMs) {
|
|
35789
|
+
try {
|
|
35790
|
+
fs8.unlinkSync(entryPath);
|
|
35791
|
+
} catch {
|
|
35792
|
+
}
|
|
35793
|
+
rescan = true;
|
|
35794
|
+
break;
|
|
35795
|
+
}
|
|
35796
|
+
if (name.startsWith("choosing-")) {
|
|
35797
|
+
blocked = true;
|
|
35798
|
+
break;
|
|
35799
|
+
}
|
|
35800
|
+
if (name.startsWith("t-")) {
|
|
35801
|
+
head = name;
|
|
35802
|
+
break;
|
|
35803
|
+
}
|
|
35804
|
+
}
|
|
35805
|
+
if (rescan)
|
|
35806
|
+
continue;
|
|
35807
|
+
if (!blocked && head === ticketName) {
|
|
35808
|
+
CONFIG_LOCK_TEST_HOOKS.beforeTicketEntry?.();
|
|
35809
|
+
const heldName = `held-${String(Date.now()).padStart(15, "0")}-${ticketName.slice(2)}`;
|
|
35810
|
+
const candidateHeldPath = path8.join(queueDir, heldName);
|
|
35811
|
+
try {
|
|
35812
|
+
fs8.renameSync(ticketPath, candidateHeldPath);
|
|
35813
|
+
} catch {
|
|
35814
|
+
continue;
|
|
35815
|
+
}
|
|
35816
|
+
heldPath = candidateHeldPath;
|
|
35817
|
+
acquired = true;
|
|
35818
|
+
break;
|
|
35819
|
+
}
|
|
35820
|
+
try {
|
|
35821
|
+
const t = /* @__PURE__ */ new Date();
|
|
35822
|
+
fs8.utimesSync(ticketPath, t, t);
|
|
35823
|
+
} catch {
|
|
35824
|
+
}
|
|
35825
|
+
sleepSync(CONFIG_LOCK_TIMINGS.retryMs);
|
|
35826
|
+
}
|
|
35827
|
+
if (!acquired) {
|
|
35828
|
+
log2?.warn(`could not acquire ${queueDir}; writing config.toml without lock`);
|
|
35829
|
+
if (ticketName) {
|
|
35830
|
+
try {
|
|
35831
|
+
fs8.unlinkSync(ticketPath);
|
|
35832
|
+
} catch {
|
|
35833
|
+
}
|
|
35834
|
+
}
|
|
35835
|
+
}
|
|
35836
|
+
try {
|
|
35837
|
+
fn();
|
|
35838
|
+
} finally {
|
|
35839
|
+
if (acquired) {
|
|
35840
|
+
try {
|
|
35841
|
+
fs8.unlinkSync(heldPath);
|
|
35842
|
+
} catch {
|
|
35843
|
+
}
|
|
35844
|
+
}
|
|
35845
|
+
}
|
|
35846
|
+
}
|
|
35847
|
+
var CONFIG_LOCK_TEST_HOOKS = {};
|
|
35848
|
+
function bakeryEnqueue(queueDir) {
|
|
35849
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
35850
|
+
const token = `${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
|
|
35851
|
+
const markerPath = path8.join(queueDir, `choosing-${token}`);
|
|
35852
|
+
try {
|
|
35853
|
+
fs8.mkdirSync(queueDir, { recursive: true });
|
|
35854
|
+
CONFIG_LOCK_TEST_HOOKS.beforeChoosingMarker?.();
|
|
35855
|
+
fs8.writeFileSync(markerPath, "", { flag: "wx" });
|
|
35856
|
+
} catch {
|
|
35857
|
+
return null;
|
|
35858
|
+
}
|
|
35859
|
+
try {
|
|
35860
|
+
let maxSeq = 0;
|
|
35861
|
+
for (const name of fs8.readdirSync(queueDir)) {
|
|
35862
|
+
if (!name.startsWith("t-"))
|
|
35863
|
+
continue;
|
|
35864
|
+
const seq = Number.parseInt(name.slice(2, 12), 10);
|
|
35865
|
+
if (Number.isFinite(seq) && seq > maxSeq)
|
|
35866
|
+
maxSeq = seq;
|
|
35867
|
+
}
|
|
35868
|
+
const ticketName = `t-${String(maxSeq + 1).padStart(10, "0")}-${token}`;
|
|
35869
|
+
const ticketPath = path8.join(queueDir, ticketName);
|
|
35870
|
+
CONFIG_LOCK_TEST_HOOKS.beforeTicketPublish?.();
|
|
35871
|
+
fs8.renameSync(markerPath, ticketPath);
|
|
35872
|
+
try {
|
|
35873
|
+
const t = /* @__PURE__ */ new Date();
|
|
35874
|
+
fs8.utimesSync(ticketPath, t, t);
|
|
35875
|
+
} catch {
|
|
35876
|
+
}
|
|
35877
|
+
return ticketName;
|
|
35878
|
+
} catch (err) {
|
|
35879
|
+
try {
|
|
35880
|
+
fs8.unlinkSync(markerPath);
|
|
35881
|
+
} catch {
|
|
35882
|
+
}
|
|
35883
|
+
if (err.code === "ENOENT")
|
|
35884
|
+
continue;
|
|
35885
|
+
return null;
|
|
35886
|
+
}
|
|
35887
|
+
}
|
|
35888
|
+
return null;
|
|
35889
|
+
}
|
|
35890
|
+
function writeConfigAtomic(filePath, content) {
|
|
35891
|
+
const realPath = resolveWriteTarget(filePath);
|
|
35892
|
+
let mode;
|
|
35893
|
+
try {
|
|
35894
|
+
mode = fs8.statSync(realPath).mode & 511;
|
|
35895
|
+
} catch {
|
|
35896
|
+
}
|
|
35897
|
+
const tmpPath = `${realPath}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
35898
|
+
let tmpCreated = false;
|
|
35899
|
+
try {
|
|
35900
|
+
fs8.writeFileSync(tmpPath, content, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
35901
|
+
tmpCreated = true;
|
|
35902
|
+
if (mode !== void 0)
|
|
35903
|
+
fs8.chmodSync(tmpPath, mode);
|
|
35904
|
+
fs8.renameSync(tmpPath, realPath);
|
|
35905
|
+
} catch (err) {
|
|
35906
|
+
if (tmpCreated || err.code !== "EEXIST") {
|
|
35907
|
+
try {
|
|
35908
|
+
fs8.unlinkSync(tmpPath);
|
|
35909
|
+
} catch {
|
|
35910
|
+
}
|
|
35911
|
+
}
|
|
35912
|
+
throw err;
|
|
35913
|
+
}
|
|
35914
|
+
}
|
|
35915
|
+
function resolveWriteTarget(filePath) {
|
|
35916
|
+
try {
|
|
35917
|
+
return fs8.realpathSync(filePath);
|
|
35918
|
+
} catch (err) {
|
|
35919
|
+
if (err.code !== "ENOENT")
|
|
35920
|
+
throw err;
|
|
35921
|
+
}
|
|
35922
|
+
const seen = /* @__PURE__ */ new Set();
|
|
35923
|
+
let p = path8.resolve(filePath);
|
|
35924
|
+
for (let depth = 0; depth < 40; depth++) {
|
|
35925
|
+
if (seen.has(p)) {
|
|
35926
|
+
throw new Error(`symlink cycle at ${p} while resolving ${filePath}`);
|
|
35927
|
+
}
|
|
35928
|
+
seen.add(p);
|
|
35929
|
+
let link;
|
|
35930
|
+
try {
|
|
35931
|
+
link = fs8.readlinkSync(p);
|
|
35932
|
+
} catch (err) {
|
|
35933
|
+
const code = err.code;
|
|
35934
|
+
if (code === "ENOENT" || code === "EINVAL")
|
|
35935
|
+
return p;
|
|
35936
|
+
throw err;
|
|
35937
|
+
}
|
|
35938
|
+
p = path8.resolve(path8.dirname(p), link);
|
|
35939
|
+
}
|
|
35940
|
+
throw new Error(`symlink chain deeper than 40 while resolving ${filePath}`);
|
|
35941
|
+
}
|
|
35694
35942
|
function ensureWorkspaceTrusted(codexHome, workspaceDir, log2) {
|
|
35943
|
+
withConfigLock(codexHome, log2, () => ensureWorkspaceTrustedLocked(codexHome, workspaceDir, log2));
|
|
35944
|
+
}
|
|
35945
|
+
function ensureWorkspaceTrustedLocked(codexHome, workspaceDir, log2) {
|
|
35695
35946
|
const configPath = path8.join(codexHome, "config.toml");
|
|
35696
35947
|
const normalizedPath = path8.resolve(workspaceDir);
|
|
35697
35948
|
try {
|
|
@@ -35712,8 +35963,13 @@ function ensureWorkspaceTrusted(codexHome, workspaceDir, log2) {
|
|
|
35712
35963
|
}
|
|
35713
35964
|
}
|
|
35714
35965
|
const projects = parsed?.projects;
|
|
35715
|
-
|
|
35966
|
+
const existingTrust = projects?.[normalizedPath]?.trust_level;
|
|
35967
|
+
if (existingTrust === "trusted")
|
|
35968
|
+
return;
|
|
35969
|
+
if (existingTrust !== void 0) {
|
|
35970
|
+
log2?.warn(`Codex config marks ${normalizedPath} as trust_level=${JSON.stringify(existingTrust)}; respecting the explicit decision \u2014 project-level developer_instructions will not load for this workspace`);
|
|
35716
35971
|
return;
|
|
35972
|
+
}
|
|
35717
35973
|
const escapedPath = normalizedPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
35718
35974
|
const sectionHeader = `[projects."${escapedPath}"]`;
|
|
35719
35975
|
const trustLine = 'trust_level = "trusted"';
|
|
@@ -35737,7 +35993,7 @@ ${trustLine}
|
|
|
35737
35993
|
content = content.substring(0, afterHeader) + trustLine + "\n" + content.substring(afterHeader);
|
|
35738
35994
|
}
|
|
35739
35995
|
}
|
|
35740
|
-
|
|
35996
|
+
writeConfigAtomic(configPath, content);
|
|
35741
35997
|
} else if (projects?.[normalizedPath] !== void 0) {
|
|
35742
35998
|
log2?.warn(`Codex config.toml has non-canonical header for ${normalizedPath}; skipping trust write`);
|
|
35743
35999
|
} else if (projects && !content.includes("[projects.")) {
|
|
@@ -35761,6 +36017,9 @@ function isParallProxyMode(env = process.env) {
|
|
|
35761
36017
|
return baseUrl === apiUrl || baseUrl.startsWith(`${apiUrl}/`);
|
|
35762
36018
|
}
|
|
35763
36019
|
function ensureParallProvider(codexHome, apiUrl, log2) {
|
|
36020
|
+
withConfigLock(codexHome, log2, () => ensureParallProviderLocked(codexHome, apiUrl));
|
|
36021
|
+
}
|
|
36022
|
+
function ensureParallProviderLocked(codexHome, apiUrl) {
|
|
35764
36023
|
const configPath = path8.join(codexHome, "config.toml");
|
|
35765
36024
|
const baseUrl = apiUrl.replace(/\/$/, "") + "/api/llm/v1";
|
|
35766
36025
|
try {
|
|
@@ -35798,7 +36057,7 @@ function ensureParallProvider(codexHome, apiUrl, log2) {
|
|
|
35798
36057
|
content = content.trimEnd() + "\n\n" + providerBlock + "\n";
|
|
35799
36058
|
}
|
|
35800
36059
|
fs8.mkdirSync(codexHome, { recursive: true });
|
|
35801
|
-
|
|
36060
|
+
writeConfigAtomic(configPath, content);
|
|
35802
36061
|
} catch (err) {
|
|
35803
36062
|
throw new Error(`failed to write Parall provider config: ${String(err)}`);
|
|
35804
36063
|
}
|
package/bundle/parall-daemon.js
CHANGED
|
@@ -83,6 +83,9 @@ var init_daemon_update_mode = __esm({
|
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
// ts/agent-core/dist/provider-config.js
|
|
86
|
+
function llmSource(pc) {
|
|
87
|
+
return effectiveLLMSourceExplicit(pc) || "parall";
|
|
88
|
+
}
|
|
86
89
|
function effectiveLLMSourceExplicit(pc) {
|
|
87
90
|
if (pc?.llm_source)
|
|
88
91
|
return pc.llm_source;
|
|
@@ -1439,9 +1442,9 @@ var init_client = __esm({
|
|
|
1439
1442
|
async retryAgentWorkspaceSetup(orgId, machineId, agentId) {
|
|
1440
1443
|
return this.request("POST", ENDPOINTS.MACHINE_AGENT_WORKSPACE_SETUP(orgId, machineId, agentId));
|
|
1441
1444
|
}
|
|
1442
|
-
async patchMachineLLMSource(orgId, machineId,
|
|
1445
|
+
async patchMachineLLMSource(orgId, machineId, llmSource2) {
|
|
1443
1446
|
return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), {
|
|
1444
|
-
llm_source:
|
|
1447
|
+
llm_source: llmSource2
|
|
1445
1448
|
});
|
|
1446
1449
|
}
|
|
1447
1450
|
/**
|
|
@@ -1668,7 +1671,7 @@ var init_client = __esm({
|
|
|
1668
1671
|
async claimDispatch(orgId, req) {
|
|
1669
1672
|
return this.request("POST", ENDPOINTS.DISPATCH_CLAIM(orgId), req);
|
|
1670
1673
|
}
|
|
1671
|
-
/** Fold
|
|
1674
|
+
/** Fold into a live lane: 409 STALE_LANE when dethroned; 409 INELIGIBLE_REF for a bad ref. */
|
|
1672
1675
|
async steerDispatch(orgId, req) {
|
|
1673
1676
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
1674
1677
|
}
|
|
@@ -31153,7 +31156,9 @@ var init_runtimes = __esm({
|
|
|
31153
31156
|
args: [],
|
|
31154
31157
|
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
31155
31158
|
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
31156
|
-
|
|
31159
|
+
if (baseEnv.KUBERNETES_SERVICE_HOST || llmSource(pc) !== "runtime_auth") {
|
|
31160
|
+
env.PRLL_CODEX_HOME = path9.join(dirs.stateDir, ".codex");
|
|
31161
|
+
}
|
|
31157
31162
|
return env;
|
|
31158
31163
|
}
|
|
31159
31164
|
};
|
package/dist/runtimes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"runtimes.d.ts","sourceRoot":"","sources":["../src/runtimes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAa,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,YAAY,EAAE,cAAc,EAAE,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,CACN,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,EACf,EAAE,CAAC,EAAE,cAAc,GAClB,MAAM,CAAC,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAoFD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAerE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAInD"}
|
package/dist/runtimes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { clearAllProviderCreds } from '@parall/agent-core';
|
|
3
|
+
import { clearAllProviderCreds, llmSource } from '@parall/agent-core';
|
|
4
4
|
import { resolveBundleDir } from './config.js';
|
|
5
5
|
export { clearAllProviderCreds };
|
|
6
6
|
function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
@@ -31,7 +31,20 @@ const codexAdapter = {
|
|
|
31
31
|
args: [],
|
|
32
32
|
buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
33
33
|
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
34
|
-
|
|
34
|
+
// CODEX_HOME placement: shared with the operator ONLY for local
|
|
35
|
+
// runtime_auth agents — they need the credential `codex login` writes to
|
|
36
|
+
// CODEX_HOME / ~/.codex (a headless child cannot log in itself; an
|
|
37
|
+
// isolated home strands them in a permanent 401 loop), and they never
|
|
38
|
+
// write the [model_providers.parall] block. Every other source keeps the
|
|
39
|
+
// isolated per-agent home: a parall-mode bridge rewrites that provider
|
|
40
|
+
// block with ITS OWN api_url and threads select the provider by fixed
|
|
41
|
+
// name, so through a shared config.toml a staging daemon's rewrite would
|
|
42
|
+
// route a coexisting prod agent's traffic (and its agk_ key) to the
|
|
43
|
+
// staging endpoint. K8s daemons always isolate, mirroring the Claude
|
|
44
|
+
// home policy (supervisor spawnAgentOnce).
|
|
45
|
+
if (baseEnv.KUBERNETES_SERVICE_HOST || llmSource(pc) !== 'runtime_auth') {
|
|
46
|
+
env.PRLL_CODEX_HOME = path.join(dirs.stateDir, '.codex');
|
|
47
|
+
}
|
|
35
48
|
return env;
|
|
36
49
|
},
|
|
37
50
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/daemon",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.1",
|
|
4
4
|
"description": "Parall local agent runtime — daemon supervisor + bridge runtimes, bundled as standalone JS files",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@aws-sdk/client-s3": "3.984.0",
|
|
34
34
|
"@pinixai/bb-browser-pro": "0.15.0",
|
|
35
|
-
"@parall/
|
|
36
|
-
"@parall/
|
|
37
|
-
"@parall/
|
|
38
|
-
"@parall/
|
|
39
|
-
"@parall/
|
|
35
|
+
"@parall/sdk": "1.42.1",
|
|
36
|
+
"@parall/claude-agent": "1.42.1",
|
|
37
|
+
"@parall/codex-agent": "1.42.1",
|
|
38
|
+
"@parall/openclaw-agent": "1.42.1",
|
|
39
|
+
"@parall/agent-core": "1.42.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^22.0.0",
|