@parall/parall 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/dist/index.bundle.mjs +81 -43
- package/package.json +3 -3
package/dist/index.bundle.mjs
CHANGED
|
@@ -28578,7 +28578,7 @@ var ParallClient = class _ParallClient {
|
|
|
28578
28578
|
async claimDispatch(orgId, req) {
|
|
28579
28579
|
return this.request("POST", ENDPOINTS.DISPATCH_CLAIM(orgId), req);
|
|
28580
28580
|
}
|
|
28581
|
-
/** Fold
|
|
28581
|
+
/** Fold into a live lane: 409 STALE_LANE when dethroned; 409 INELIGIBLE_REF for a bad ref. */
|
|
28582
28582
|
async steerDispatch(orgId, req) {
|
|
28583
28583
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
28584
28584
|
}
|
|
@@ -30055,7 +30055,7 @@ async function dispatchLaneGroup(host, opts) {
|
|
|
30055
30055
|
async function consumeTypedDispatch(host, ref, run, ack) {
|
|
30056
30056
|
if (!host.laneLedger || host.ledgerDisabled) {
|
|
30057
30057
|
if (await run(ref.dispatchEventId))
|
|
30058
|
-
ack(ref.dispatchEventId);
|
|
30058
|
+
await ack(ref.dispatchEventId);
|
|
30059
30059
|
return;
|
|
30060
30060
|
}
|
|
30061
30061
|
let lane;
|
|
@@ -30065,7 +30065,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30065
30065
|
if (err instanceof LedgerUnsupportedError) {
|
|
30066
30066
|
host.disableLedger("claim endpoint missing");
|
|
30067
30067
|
if (await run(ref.dispatchEventId))
|
|
30068
|
-
ack(ref.dispatchEventId);
|
|
30068
|
+
await ack(ref.dispatchEventId);
|
|
30069
30069
|
return;
|
|
30070
30070
|
}
|
|
30071
30071
|
throw err;
|
|
@@ -30076,7 +30076,7 @@ async function consumeTypedDispatch(host, ref, run, ack) {
|
|
|
30076
30076
|
}
|
|
30077
30077
|
try {
|
|
30078
30078
|
if (await run(lane.typedDispatchEventId))
|
|
30079
|
-
ack(lane.typedDispatchEventId);
|
|
30079
|
+
await ack(lane.typedDispatchEventId);
|
|
30080
30080
|
} finally {
|
|
30081
30081
|
await host.laneLedger.completeIfIdle(lane.laneKey, false).catch(() => {
|
|
30082
30082
|
});
|
|
@@ -30530,29 +30530,33 @@ var ParallAgentGateway = class {
|
|
|
30530
30530
|
try {
|
|
30531
30531
|
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) => {
|
|
30532
30532
|
if (dispatchEventId) {
|
|
30533
|
-
this.
|
|
30533
|
+
return this.ackDispatchEvent(dispatchEventId, () => {
|
|
30534
|
+
this.dispatchedTasks.delete(`${data.id}:${data.updated_at}`);
|
|
30534
30535
|
});
|
|
30535
|
-
return;
|
|
30536
30536
|
}
|
|
30537
|
-
this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30537
|
+
return this.opts.client.ackDispatch(this.opts.config.org_id, {
|
|
30538
30538
|
source_type: "task_activity",
|
|
30539
30539
|
source_id: data.id
|
|
30540
|
-
}).
|
|
30541
|
-
});
|
|
30540
|
+
}).then(() => void 0, () => void 0);
|
|
30542
30541
|
});
|
|
30543
30542
|
} catch (err) {
|
|
30544
30543
|
this.opts.log?.error(`task dispatch failed for ${data.id}: ${String(err)}`);
|
|
30545
30544
|
}
|
|
30546
30545
|
});
|
|
30547
30546
|
ws.on("dispatch.new", async (data) => {
|
|
30548
|
-
if (data.event_type === "
|
|
30547
|
+
if (data.event_type === "task_assign") {
|
|
30548
|
+
if (!data.task_id)
|
|
30549
|
+
return;
|
|
30550
|
+
try {
|
|
30551
|
+
await this.handleTaskAssignmentRedrive(data);
|
|
30552
|
+
} catch (err) {
|
|
30553
|
+
this.opts.log?.error(`task assignment re-drive failed for ${data.task_id}: ${String(err)}`);
|
|
30554
|
+
}
|
|
30555
|
+
} else if (data.event_type === "task_comment") {
|
|
30549
30556
|
if (!data.source_id || !data.task_id)
|
|
30550
30557
|
return;
|
|
30551
30558
|
try {
|
|
30552
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleTaskComment(data.source_id, data.task_id ?? "", data.actor_id, data.delivery_reason), () =>
|
|
30553
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30554
|
-
});
|
|
30555
|
-
});
|
|
30559
|
+
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)));
|
|
30556
30560
|
} catch (err) {
|
|
30557
30561
|
this.opts.log?.error(`task comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30558
30562
|
}
|
|
@@ -30560,10 +30564,7 @@ var ParallAgentGateway = class {
|
|
|
30560
30564
|
if (!data.source_id)
|
|
30561
30565
|
return;
|
|
30562
30566
|
try {
|
|
30563
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () =>
|
|
30564
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30565
|
-
});
|
|
30566
|
-
});
|
|
30567
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.handleWikiComment(data.source_id, data.actor_id, data.delivery_reason), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30567
30568
|
} catch (err) {
|
|
30568
30569
|
this.opts.log?.error(`wiki comment dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30569
30570
|
}
|
|
@@ -30574,10 +30575,7 @@ var ParallAgentGateway = class {
|
|
|
30574
30575
|
await this.consumeTypedDispatch({ dispatchEventId: data.id }, (dispatchEventId) => this.handleTaskDispatch(data.task_id ?? "", data.source_id ?? data.task_id ?? "", {
|
|
30575
30576
|
allowCreator: true,
|
|
30576
30577
|
dispatchEventId
|
|
30577
|
-
}), () =>
|
|
30578
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30579
|
-
});
|
|
30580
|
-
});
|
|
30578
|
+
}), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30581
30579
|
} catch (err) {
|
|
30582
30580
|
this.opts.log?.error(`task update dispatch failed for ${data.task_id}: ${String(err)}`);
|
|
30583
30581
|
}
|
|
@@ -30585,10 +30583,7 @@ var ParallAgentGateway = class {
|
|
|
30585
30583
|
if (!data.source_id)
|
|
30586
30584
|
return;
|
|
30587
30585
|
try {
|
|
30588
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () =>
|
|
30589
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30590
|
-
});
|
|
30591
|
-
});
|
|
30586
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleScheduleFire(data.source_id, data.actor_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30592
30587
|
} catch (err) {
|
|
30593
30588
|
this.opts.log?.error(`schedule fire dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30594
30589
|
}
|
|
@@ -30596,10 +30591,7 @@ var ParallAgentGateway = class {
|
|
|
30596
30591
|
if (!data.source_id)
|
|
30597
30592
|
return;
|
|
30598
30593
|
try {
|
|
30599
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () =>
|
|
30600
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30601
|
-
});
|
|
30602
|
-
});
|
|
30594
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleExternalTriggerRun(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30603
30595
|
} catch (err) {
|
|
30604
30596
|
this.opts.log?.error(`external trigger dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30605
30597
|
}
|
|
@@ -30607,10 +30599,7 @@ var ParallAgentGateway = class {
|
|
|
30607
30599
|
if (!data.source_id)
|
|
30608
30600
|
return;
|
|
30609
30601
|
try {
|
|
30610
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () =>
|
|
30611
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30612
|
-
});
|
|
30613
|
-
});
|
|
30602
|
+
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleChannelMessage(data.source_id), () => this.ackDispatchEvent(data.id, () => this.clearTypedDispatchDedupe(data)));
|
|
30614
30603
|
} catch (err) {
|
|
30615
30604
|
this.opts.log?.error(`channel message dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30616
30605
|
}
|
|
@@ -30618,10 +30607,7 @@ var ParallAgentGateway = class {
|
|
|
30618
30607
|
if (!data.source_id)
|
|
30619
30608
|
return;
|
|
30620
30609
|
try {
|
|
30621
|
-
await this.consumeTypedDispatch({ dispatchEventId: data.id }, () => this.fetchAndHandleApprovalDecided(data.source_id, data.actor_id, data.chat_id ?? null), () =>
|
|
30622
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, data.id).catch(() => {
|
|
30623
|
-
});
|
|
30624
|
-
});
|
|
30610
|
+
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)));
|
|
30625
30611
|
} catch (err) {
|
|
30626
30612
|
this.opts.log?.error(`approval decided dispatch failed for ${data.source_id}: ${String(err)}`);
|
|
30627
30613
|
}
|
|
@@ -30631,7 +30617,7 @@ var ParallAgentGateway = class {
|
|
|
30631
30617
|
} catch (err) {
|
|
30632
30618
|
this.opts.log?.error(`message re-drive failed for ${data.source_id}: ${String(err)}`);
|
|
30633
30619
|
}
|
|
30634
|
-
} else if (data.event_type !== "message"
|
|
30620
|
+
} else if (data.event_type !== "message") {
|
|
30635
30621
|
this.opts.log?.info(`dispatch.new with unhandled event_type=${String(data.event_type)} (id=${data.id}) \u2014 no-op`);
|
|
30636
30622
|
}
|
|
30637
30623
|
});
|
|
@@ -30699,6 +30685,50 @@ var ParallAgentGateway = class {
|
|
|
30699
30685
|
consumeTypedDispatch(ref, run, ack) {
|
|
30700
30686
|
return consumeTypedDispatch(this.laneFlowHost(), ref, run, ack);
|
|
30701
30687
|
}
|
|
30688
|
+
// Typed completion must wait until the administrative ack has either
|
|
30689
|
+
// committed or failed. Errors stay best-effort: a failed ack leaves the row
|
|
30690
|
+
// received, so Complete releases and re-drives it safely.
|
|
30691
|
+
ackDispatchEvent(dispatchEventId, onFailure) {
|
|
30692
|
+
return this.opts.client.ackDispatchByID(this.opts.config.org_id, dispatchEventId).then(() => void 0, (err) => {
|
|
30693
|
+
onFailure?.();
|
|
30694
|
+
this.opts.log?.warn(`dispatch ack failed for ${dispatchEventId}, releasing for re-drive: ${String(err)}`);
|
|
30695
|
+
});
|
|
30696
|
+
}
|
|
30697
|
+
clearTypedDispatchDedupe(item) {
|
|
30698
|
+
switch (item.event_type) {
|
|
30699
|
+
case "task_assign":
|
|
30700
|
+
case "task_update":
|
|
30701
|
+
if (item.task_id) {
|
|
30702
|
+
const prefix = `${item.task_id}:`;
|
|
30703
|
+
for (const key of this.dispatchedTasks) {
|
|
30704
|
+
if (key.startsWith(prefix))
|
|
30705
|
+
this.dispatchedTasks.delete(key);
|
|
30706
|
+
}
|
|
30707
|
+
}
|
|
30708
|
+
break;
|
|
30709
|
+
case "task_comment":
|
|
30710
|
+
case "wiki_comment":
|
|
30711
|
+
if (item.source_id)
|
|
30712
|
+
this.dispatchedTasks.delete(`comment:${item.source_id}`);
|
|
30713
|
+
break;
|
|
30714
|
+
case "schedule.fire":
|
|
30715
|
+
if (item.source_id)
|
|
30716
|
+
this.dispatchedTasks.delete(`schedule_run:${item.source_id}`);
|
|
30717
|
+
break;
|
|
30718
|
+
case "external_trigger":
|
|
30719
|
+
if (item.source_id)
|
|
30720
|
+
this.dispatchedTasks.delete(`external_trigger_run:${item.source_id}`);
|
|
30721
|
+
break;
|
|
30722
|
+
case "channel_message":
|
|
30723
|
+
if (item.source_id)
|
|
30724
|
+
this.dispatchedMessages.delete(`channel_message:${item.source_id}`);
|
|
30725
|
+
break;
|
|
30726
|
+
case "approval_decided":
|
|
30727
|
+
if (item.source_id)
|
|
30728
|
+
this.dispatchedTasks.delete(`approval:${item.source_id}`);
|
|
30729
|
+
break;
|
|
30730
|
+
}
|
|
30731
|
+
}
|
|
30702
30732
|
buildDispatchContext(event, sessionKey) {
|
|
30703
30733
|
const binding = this.sessionBindings.get(sessionKey);
|
|
30704
30734
|
return {
|
|
@@ -31665,6 +31695,17 @@ var ParallAgentGateway = class {
|
|
|
31665
31695
|
chat_id: item.chat_id
|
|
31666
31696
|
});
|
|
31667
31697
|
}
|
|
31698
|
+
// A task assignment's first delivery rides task.assigned, but a typed lane
|
|
31699
|
+
// released without an effect is re-driven as dispatch.new. Reuse the exact
|
|
31700
|
+
// typed claim path used by catch-up so that recovery does not require a
|
|
31701
|
+
// runtime reconnect.
|
|
31702
|
+
async handleTaskAssignmentRedrive(item) {
|
|
31703
|
+
if (!item.task_id)
|
|
31704
|
+
return;
|
|
31705
|
+
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
|
31706
|
+
dispatchEventId
|
|
31707
|
+
}), (dispatchEventId) => this.ackDispatchEvent(dispatchEventId ?? item.id, () => this.clearTypedDispatchDedupe(item)));
|
|
31708
|
+
}
|
|
31668
31709
|
consumeMessageWorkItem(item) {
|
|
31669
31710
|
return consumeMessageWorkItem(this.laneFlowHost(), item);
|
|
31670
31711
|
}
|
|
@@ -32130,10 +32171,7 @@ var ParallAgentGateway = class {
|
|
|
32130
32171
|
}
|
|
32131
32172
|
processed++;
|
|
32132
32173
|
try {
|
|
32133
|
-
const ackItem = () =>
|
|
32134
|
-
this.opts.client.ackDispatchByID(this.opts.config.org_id, item.id).catch(() => {
|
|
32135
|
-
});
|
|
32136
|
-
};
|
|
32174
|
+
const ackItem = () => this.ackDispatchEvent(item.id, () => this.clearTypedDispatchDedupe(item));
|
|
32137
32175
|
if (item.event_type === "task_assign" && item.task_id) {
|
|
32138
32176
|
try {
|
|
32139
32177
|
await this.consumeTypedDispatch({ dispatchEventId: item.id }, (dispatchEventId) => this.handleTaskDispatch(item.task_id ?? "", item.source_id ?? item.task_id ?? "", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/parall",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.1",
|
|
4
4
|
"description": "OpenClaw channel plugin for Parall IM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"openclaw.plugin.json"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@parall/agent-core": "1.42.
|
|
20
|
-
"@parall/sdk": "1.42.
|
|
19
|
+
"@parall/agent-core": "1.42.1",
|
|
20
|
+
"@parall/sdk": "1.42.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^22.0.0",
|