@yaoyuanchao/dingtalk 1.7.10 → 1.7.11

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/monitor.ts +24 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaoyuanchao/dingtalk",
3
- "version": "1.7.10",
3
+ "version": "1.7.11",
4
4
  "type": "module",
5
5
  "description": "DingTalk channel plugin for ClawdBot/OpenClaw with Stream Mode support",
6
6
  "license": "MIT",
package/src/monitor.ts CHANGED
@@ -1493,6 +1493,22 @@ async function flushMessageBuffer(bufferKey: string): Promise<void> {
1493
1493
  });
1494
1494
  }
1495
1495
 
1496
+ /**
1497
+ * Resolve queue lane suffix based on message content.
1498
+ * /btw and abort/status commands get their own lanes so they can run
1499
+ * in parallel with the main message queue (matching Feishu/Telegram behaviour).
1500
+ */
1501
+ function resolveQueueLane(text: string): string {
1502
+ const t = text.trim();
1503
+ // /btw side question — separate lane
1504
+ if (/^\/btw(\s|:|$)/i.test(t)) return ':btw';
1505
+ // abort / stop — control lane
1506
+ if (/^\/stop(\s|$)/i.test(t) || /^(stop|esc|abort|cancel|exit|halt|interrupt)$/i.test(t)) return ':control';
1507
+ // status commands — control lane
1508
+ if (/^\/(help|commands|tools|status|tasks|context)(\s|$)/i.test(t)) return ':control';
1509
+ return '';
1510
+ }
1511
+
1496
1512
  /**
1497
1513
  * Dispatch a message to the agent (after aggregation or immediately).
1498
1514
  * Enqueues into per-session queue to prevent concurrent processing.
@@ -1513,16 +1529,21 @@ async function dispatchMessage(params: {
1513
1529
  const { ctx, conversationId } = params;
1514
1530
  const { account, log } = ctx;
1515
1531
 
1516
- const queueKey = `${account.accountId}:${conversationId}`;
1532
+ const lane = resolveQueueLane(params.rawBody);
1533
+ const mainQueueKey = `${account.accountId}:${conversationId}`;
1534
+ const queueKey = `${mainQueueKey}${lane}`;
1517
1535
  // Check both the explicit queue AND recent delivery activity.
1518
1536
  // The SDK's dispatchReplyFromConfig may resolve before the agent's full turn
1519
1537
  // completes (followup turns run in background), clearing the queue entry
1520
1538
  // while deliveries are still happening.
1521
- const isQueueBusy = sessionQueues.has(queueKey) || hasActiveDelivery(queueKey);
1539
+ // btw/control lanes check against their OWN key (not the main queue)
1540
+ // they are allowed to run in parallel with the main queue.
1541
+ const isQueueBusy = sessionQueues.has(queueKey) || (lane === '' && hasActiveDelivery(mainQueueKey));
1522
1542
 
1523
1543
  // If queue is busy, add emotion reaction on user's message to indicate queued
1544
+ // (skip for btw/control lanes — they bypass the main queue by design)
1524
1545
  let queueAckCleanup: (() => Promise<void>) | null = null;
1525
- if (isQueueBusy) {
1546
+ if (isQueueBusy && lane === '') {
1526
1547
  log?.info?.("[dingtalk] Queue busy for " + queueKey + ", adding queue reaction");
1527
1548
  try {
1528
1549
  if (account.clientId && account.clientSecret && params.msg.msgId && conversationId) {