botmux 3.2.1-canary.0 → 3.3.0
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/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +4 -0
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +8 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli/deferred-topic-send.d.ts +37 -0
- package/dist/cli/deferred-topic-send.d.ts.map +1 -0
- package/dist/cli/deferred-topic-send.js +69 -0
- package/dist/cli/deferred-topic-send.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +160 -34
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +17 -12
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +4 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +78 -8
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/deferred-schedule-settlement.d.ts +20 -0
- package/dist/core/deferred-schedule-settlement.d.ts.map +1 -0
- package/dist/core/deferred-schedule-settlement.js +18 -0
- package/dist/core/deferred-schedule-settlement.js.map +1 -0
- package/dist/core/deferred-topic-binding.d.ts +19 -0
- package/dist/core/deferred-topic-binding.d.ts.map +1 -0
- package/dist/core/deferred-topic-binding.js +55 -0
- package/dist/core/deferred-topic-binding.js.map +1 -0
- package/dist/core/scheduler.d.ts +26 -20
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +114 -56
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +47 -15
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +178 -84
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +7 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +51 -1
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +90 -5
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +12 -3
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +32 -8
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/web/dashboard-components.d.ts +7 -0
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-components.js +11 -2
- package/dist/dashboard/web/dashboard-components.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +30 -6
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts +2 -0
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +74 -27
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-O37SAQD5.js → bot-defaults-page-B5AY4B2J.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-6QHMLMIM.js → chunk-CUV65BIQ.js} +3 -3
- package/dist/dashboard-web/chunks/{chunk-O2DPQL7C.js → chunk-JNRSPKLS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FYALHCPG.js → chunk-P6GO5KT4.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-QFMH6ITB.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-B42PCL5P.js → chunk-UBOLHQCK.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-DZBQ42MH.js → connectors-page-KTC2QWNW.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-3IEGRZKQ.js → groups-page-B3EKGOLY.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-X3ADRON3.js → insights-page-X6RXNCWX.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-IV36RGQY.js → monitor-room-LLRA5LQW.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-ADFKVON4.js → monitoring-page-7MT5FEOS.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-CALAOWNS.js → office-page-KD46D5TD.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-SLMGLK3M.js → overview-page-JUWNH32O.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-L7JJ4FFV.js → roles-page-P6F7NLOI.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-page-XIHWZST4.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-page-OKJ5YWUZ.js → sessions-page-2VECQ27T.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-P6MI2ZUE.js → settings-page-HMIUE2JA.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-FT7BVZ6X.js → skills-page-A46KVWBL.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-DEYCPUFB.js → team-federation-page-SDUC56DF.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-4IOWREZG.js → v3-page-J5JOTUSQ.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-2VMBETZH.js → whiteboards-page-U7LSOAWI.js} +1 -1
- package/dist/dashboard-web/style.css +34 -4
- package/dist/dashboard.js +16 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +16 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +16 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/ask-card.d.ts.map +1 -1
- package/dist/im/lark/ask-card.js +52 -4
- package/dist/im/lark/ask-card.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +3 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +1 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +1 -1
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/schedules-card.d.ts +2 -2
- package/dist/im/lark/schedules-card.d.ts.map +1 -1
- package/dist/im/lark/schedules-card.js +50 -34
- package/dist/im/lark/schedules-card.js.map +1 -1
- package/dist/index-daemon.js +13 -1
- package/dist/index-daemon.js.map +1 -1
- package/dist/services/schedule-store.d.ts +6 -2
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +19 -4
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +4 -5
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +36 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +40 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +45 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/input-gate.d.ts +0 -41
- package/dist/utils/input-gate.d.ts.map +1 -1
- package/dist/utils/input-gate.js +0 -41
- package/dist/utils/input-gate.js.map +1 -1
- package/dist/utils/pending-input-queue.d.ts +10 -0
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +15 -0
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/worker.js +105 -48
- package/dist/worker.js.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +3 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +14 -3
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/dist/workflows/v3/architect.js +1 -1
- package/dist/workflows/v3/architect.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -0
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +2 -0
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +10 -2
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/run-envelope.d.ts +24 -24
- package/dist/workflows/v3/runtime.d.ts +5 -0
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +1 -0
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/chunk-I35DXGM4.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-Z3672POL.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/pi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAIxD,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"pi.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/pi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAIxD,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CA8CjE;AAED,eAAO,MAAM,MAAM,wBAAkB,CAAC"}
|
package/dist/adapters/cli/pi.js
CHANGED
|
@@ -22,6 +22,10 @@ export function createPiAdapter(pathOverride) {
|
|
|
22
22
|
return `pi --session-id ${sessionId}`;
|
|
23
23
|
},
|
|
24
24
|
passesInitialPromptViaArgs: true,
|
|
25
|
+
// tmux reports "command too long" around ~12KB total launch argv on some
|
|
26
|
+
// deployments, well below OS ARG_MAX. Keep short Pi prompts on argv (legacy
|
|
27
|
+
// behavior) but route long first messages/cards through writeInput instead.
|
|
28
|
+
maxInitialPromptArgBytes: 4096,
|
|
25
29
|
async writeInput(pty, content) {
|
|
26
30
|
if (pty.pasteText && pty.sendSpecialKeys) {
|
|
27
31
|
pty.pasteText(content);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.js","sourceRoot":"","sources":["../../../src/adapters/cli/pi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,YAAqB;IACnD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;IACjD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE,CAAC,uBAAuB,CAAC;QACpC,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE;YACpC,MAAM,IAAI,GAAG;gBACX,cAAc,EAAE,SAAS;aAC1B,CAAC;YACF,wEAAwE;YACxE,sEAAsE;YACtE,IAAI,aAAa;gBAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,CAAC,EAAE,SAAS,EAAE;YAC9B,OAAO,mBAAmB,SAAS,EAAE,CAAC;QACxC,CAAC;QAED,0BAA0B,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"pi.js","sourceRoot":"","sources":["../../../src/adapters/cli/pi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,YAAqB;IACnD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;IACjD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE,CAAC,uBAAuB,CAAC;QACpC,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE;YACpC,MAAM,IAAI,GAAG;gBACX,cAAc,EAAE,SAAS;aAC1B,CAAC;YACF,wEAAwE;YACxE,sEAAsE;YACtE,IAAI,aAAa;gBAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,CAAC,EAAE,SAAS,EAAE;YAC9B,OAAO,mBAAmB,SAAS,EAAE,CAAC;QACxC,CAAC;QAED,0BAA0B,EAAE,IAAI;QAChC,yEAAyE;QACzE,4EAA4E;QAC5E,4EAA4E;QAC5E,wBAAwB,EAAE,IAAI;QAE9B,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACzC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBACvB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,YAAY,OAAO,WAAW,CAAC,CAAC;gBAC1C,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS;QAC5B,WAAW,EAAE,eAAe;QAC5B,YAAY,EAAE,SAAS;QACvB,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,oBAAoB;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC"}
|
|
@@ -103,8 +103,15 @@ export interface CliAdapter {
|
|
|
103
103
|
remoteThreadId?: string;
|
|
104
104
|
}): string[];
|
|
105
105
|
/** When true, the adapter passes the initial prompt via CLI args (e.g. -i).
|
|
106
|
-
* The worker skips queuing the prompt for stdin write
|
|
106
|
+
* The worker skips queuing the prompt for stdin write unless another
|
|
107
|
+
* defer condition routes it through the post-start input queue. */
|
|
107
108
|
readonly passesInitialPromptViaArgs?: boolean;
|
|
109
|
+
/** Only meaningful with passesInitialPromptViaArgs. If set, prompts whose
|
|
110
|
+
* UTF-8 byte length is GREATER than this adapter-specific limit are not
|
|
111
|
+
* baked into launch args; the worker defers them to the normal post-start
|
|
112
|
+
* input queue. This guards backend launchers (notably tmux) whose command
|
|
113
|
+
* string limit can be much lower than OS ARG_MAX. */
|
|
114
|
+
readonly maxInitialPromptArgBytes?: number;
|
|
108
115
|
/** Only meaningful with passesInitialPromptViaArgs. When true, the CLI
|
|
109
116
|
* silently drops its initial-prompt launch flag on a RESUME spawn (e.g.
|
|
110
117
|
* OpenCode applies `--prompt` to new sessions only and ignores it with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;4EAGwE;IACxE,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;IACxC;6DACyD;IACzD,eAAe,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC;IACpD,8FAA8F;IAC9F,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;2FAEuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;yEAEqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;+DAC2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;sBAIsB;AACtB,MAAM,WAAW,gBAAgB;IAC/B;yDACqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,sFAAsF;IACtF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,YAAY,CAAC;IACpD,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC;CAC/C;AAED,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAE5C,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;yCAKqC;IACrC,SAAS,CAAC,IAAI,EAAE;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sFAAsF;QACtF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB;;0EAEkE;QAClE,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,+EAA+E;QAC/E,MAAM,CAAC,EAAE,OAAO,qBAAqB,EAAE,MAAM,CAAC;QAC9C;;qFAE6E;QAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,mGAAmG;QACnG,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,oEAAoE;QACpE,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB;;;;gEAIwD;QACxD,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB;;;oFAG4E;QAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,MAAM,EAAE,CAAC;IAEb
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface DeferredScheduleRunData {
|
|
2
|
+
taskId: string;
|
|
3
|
+
turnId: string;
|
|
4
|
+
routingAnchor: string;
|
|
5
|
+
topicTitle?: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DeferredTopicSendSession {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
chatId: string;
|
|
11
|
+
larkAppId: string;
|
|
12
|
+
deferredScheduleRun?: DeferredScheduleRunData;
|
|
13
|
+
}
|
|
14
|
+
export interface DeferredTopicSendResult {
|
|
15
|
+
handled: boolean;
|
|
16
|
+
messageId?: string;
|
|
17
|
+
rootMessageId?: string;
|
|
18
|
+
materializedNow?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Route one `botmux send` effect for a lazily-materialized schedule topic.
|
|
21
|
+
* The per-session file lock spans the provider request so two concurrent CLI
|
|
22
|
+
* processes cannot both create a root. A stable provider UUID (sessionId)
|
|
23
|
+
* makes retry-after-local-write-failure converge on the same Lark message. */
|
|
24
|
+
export declare function dispatchDeferredTopicSend(opts: {
|
|
25
|
+
dataDir: string;
|
|
26
|
+
session: DeferredTopicSendSession;
|
|
27
|
+
currentTurnId?: string;
|
|
28
|
+
explicitTopLevel: boolean;
|
|
29
|
+
reuseBoundRootWhenTopLevel?: boolean;
|
|
30
|
+
content: string;
|
|
31
|
+
msgType: string;
|
|
32
|
+
uuid?: string;
|
|
33
|
+
sendRoot: (content: string, msgType: string, uuid: string) => Promise<string>;
|
|
34
|
+
sendTitleSeed: (title: string, uuid: string) => Promise<string>;
|
|
35
|
+
replyRoot: (rootMessageId: string, content: string, msgType: string, uuid?: string) => Promise<string>;
|
|
36
|
+
}): Promise<DeferredTopicSendResult>;
|
|
37
|
+
//# sourceMappingURL=deferred-topic-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-topic-send.d.ts","sourceRoot":"","sources":["../../src/cli/deferred-topic-send.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;8EAG8E;AAC9E,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACxG,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA+DnC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { readDeferredTopicBinding, withDeferredTopicBindingLock, writeDeferredTopicBinding, } from '../core/deferred-topic-binding.js';
|
|
2
|
+
/** Route one `botmux send` effect for a lazily-materialized schedule topic.
|
|
3
|
+
* The per-session file lock spans the provider request so two concurrent CLI
|
|
4
|
+
* processes cannot both create a root. A stable provider UUID (sessionId)
|
|
5
|
+
* makes retry-after-local-write-failure converge on the same Lark message. */
|
|
6
|
+
export async function dispatchDeferredTopicSend(opts) {
|
|
7
|
+
const run = opts.session.deferredScheduleRun;
|
|
8
|
+
if (!run)
|
|
9
|
+
return { handled: false };
|
|
10
|
+
return withDeferredTopicBindingLock(opts.dataDir, opts.session.sessionId, async () => {
|
|
11
|
+
const existing = readDeferredTopicBinding(opts.dataDir, opts.session.sessionId);
|
|
12
|
+
if (existing) {
|
|
13
|
+
if (existing.turnId !== run.turnId
|
|
14
|
+
|| existing.chatId !== opts.session.chatId
|
|
15
|
+
|| existing.larkAppId !== opts.session.larkAppId
|
|
16
|
+
|| existing.routingAnchor !== run.routingAnchor) {
|
|
17
|
+
throw new Error('deferred topic binding identity mismatch');
|
|
18
|
+
}
|
|
19
|
+
if (opts.explicitTopLevel && !opts.reuseBoundRootWhenTopLevel)
|
|
20
|
+
return { handled: false };
|
|
21
|
+
const messageId = await opts.replyRoot(existing.rootMessageId, opts.content, opts.msgType, opts.uuid);
|
|
22
|
+
return { handled: true, messageId, rootMessageId: existing.rootMessageId, materializedNow: false };
|
|
23
|
+
}
|
|
24
|
+
// Only the scheduled turn itself may materialize an as-yet invisible run.
|
|
25
|
+
// A stale/local process without the exact turn marker must not publish it.
|
|
26
|
+
if (!opts.currentTurnId || opts.currentTurnId !== run.turnId) {
|
|
27
|
+
// A missing binding after the scheduled turn must fail closed. Falling
|
|
28
|
+
// through to ordinary chat-scope routing would leak a resumed/stale
|
|
29
|
+
// hidden session's output to the group top level. Explicit --top-level
|
|
30
|
+
// remains the deliberate escape hatch for an operator.
|
|
31
|
+
if (opts.explicitTopLevel)
|
|
32
|
+
return { handled: false };
|
|
33
|
+
throw new Error('deferred topic is not materialized for this turn');
|
|
34
|
+
}
|
|
35
|
+
const title = run.topicTitle?.trim();
|
|
36
|
+
let rootMessageId;
|
|
37
|
+
let messageId;
|
|
38
|
+
if (title) {
|
|
39
|
+
rootMessageId = await opts.sendTitleSeed(title, opts.session.sessionId);
|
|
40
|
+
const binding = {
|
|
41
|
+
sessionId: opts.session.sessionId,
|
|
42
|
+
turnId: run.turnId,
|
|
43
|
+
chatId: opts.session.chatId,
|
|
44
|
+
larkAppId: opts.session.larkAppId,
|
|
45
|
+
routingAnchor: run.routingAnchor,
|
|
46
|
+
rootMessageId,
|
|
47
|
+
createdAt: new Date().toISOString(),
|
|
48
|
+
};
|
|
49
|
+
writeDeferredTopicBinding(opts.dataDir, binding);
|
|
50
|
+
messageId = await opts.replyRoot(rootMessageId, opts.content, opts.msgType, opts.uuid);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
rootMessageId = await opts.sendRoot(opts.content, opts.msgType, opts.session.sessionId);
|
|
54
|
+
const binding = {
|
|
55
|
+
sessionId: opts.session.sessionId,
|
|
56
|
+
turnId: run.turnId,
|
|
57
|
+
chatId: opts.session.chatId,
|
|
58
|
+
larkAppId: opts.session.larkAppId,
|
|
59
|
+
routingAnchor: run.routingAnchor,
|
|
60
|
+
rootMessageId,
|
|
61
|
+
createdAt: new Date().toISOString(),
|
|
62
|
+
};
|
|
63
|
+
writeDeferredTopicBinding(opts.dataDir, binding);
|
|
64
|
+
messageId = rootMessageId;
|
|
65
|
+
}
|
|
66
|
+
return { handled: true, messageId, rootMessageId, materializedNow: true };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=deferred-topic-send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-topic-send.js","sourceRoot":"","sources":["../../src/cli/deferred-topic-send.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAi+EA,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAwlKrF;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,CAAC,EAC9F,KAAK,EAAE,MAAM,EACb,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,2BAA2B,EAAE,UAAU,GAAG,IAAI,CAAC,GACzF,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA8F7B"}
|
package/dist/cli.js
CHANGED
|
@@ -46,11 +46,13 @@ import { buildBotFromAddFlags, editInputFromFlags, isScriptedSetupInvocation, ma
|
|
|
46
46
|
import { interactiveSelect, pickChoice, pickCliSelection } from './setup/interactive-select.js';
|
|
47
47
|
import { buildPreset, serializePreset, presetFilename } from './setup/agent-preset.js';
|
|
48
48
|
import { logger } from './utils/logger.js';
|
|
49
|
+
import { scrubSessionCliHomeEnv } from './utils/child-env.js';
|
|
49
50
|
import { scheduleTimeZone } from './utils/timezone.js';
|
|
50
51
|
import { expandHomePath, invalidWorkingDirs } from './utils/working-dir.js';
|
|
51
52
|
import { firstPositional } from './cli/arg-utils.js';
|
|
52
53
|
import { isColdResumeDormant, sessionListDisposition } from './cli/session-list-liveness.js';
|
|
53
54
|
import { dispatchPrimaryMessage, findStdinAliasAttachment, normalizeInteractiveCardInput, sendFileAttachments, sendVideoAttachments, shouldSendAsPureVideo, validateVideoAttachments } from './cli/send-dispatch.js';
|
|
55
|
+
import { dispatchDeferredTopicSend } from './cli/deferred-topic-send.js';
|
|
54
56
|
import { resolveDaemonExternalHostEnv } from './cli/daemon-lifecycle-env.js';
|
|
55
57
|
import { buildPm2SpawnCommand } from './cli/pm2-command.js';
|
|
56
58
|
import { callDashboard } from './cli/dashboard-endpoint.js';
|
|
@@ -146,7 +148,18 @@ function pm2Bin() {
|
|
|
146
148
|
}
|
|
147
149
|
/** Env for pm2 invocations with an isolated PM2_HOME. */
|
|
148
150
|
function pm2Env(home = PM2_HOME) {
|
|
149
|
-
|
|
151
|
+
const env = { ...process.env, PM2_HOME: home };
|
|
152
|
+
// pm2 persists the caller's env into every managed app (and into dump.pm2
|
|
153
|
+
// for resurrect), so a `botmux start/restart` invoked from ANY process that
|
|
154
|
+
// carries a session-level CLI home pointer — most commonly a bot's own
|
|
155
|
+
// session during self-upgrade, whose env holds its injected
|
|
156
|
+
// CLAUDE_CONFIG_DIR — would poison ALL workers, making every non-isolated
|
|
157
|
+
// bot read/write a sibling bot's home. Strip at this boundary so the daemon
|
|
158
|
+
// stays session-agnostic; daemon/worker boot scrub the same keys against
|
|
159
|
+
// stale dumps (see SESSION_CLI_HOME_ENV_KEYS for the full story, including
|
|
160
|
+
// why GROK_HOME is exempt and why deleting beats pinning a default).
|
|
161
|
+
scrubSessionCliHomeEnv(env);
|
|
162
|
+
return env;
|
|
150
163
|
}
|
|
151
164
|
function listPm2GodDaemonPids(home = PM2_HOME) {
|
|
152
165
|
if (process.platform !== 'linux')
|
|
@@ -4057,6 +4070,9 @@ async function cmdResume() {
|
|
|
4057
4070
|
else if (errCode === 'adopt_unsupported') {
|
|
4058
4071
|
console.error('❌ adopt 接管会话不支持 resume。');
|
|
4059
4072
|
}
|
|
4073
|
+
else if (errCode === 'deferred_unmaterialized') {
|
|
4074
|
+
console.error('❌ 该静默定时轮次未创建话题,隐藏会话只保留审计记录,不能 resume。');
|
|
4075
|
+
}
|
|
4060
4076
|
else {
|
|
4061
4077
|
console.error(`❌ 恢复失败: ${errCode}`);
|
|
4062
4078
|
}
|
|
@@ -4231,8 +4247,10 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
|
|
|
4231
4247
|
定时任务(可在 CLI 会话内自动推断 chat):
|
|
4232
4248
|
schedule list 列出所有任务
|
|
4233
4249
|
schedule add <schedule> <prompt> 添加任务(ex: "30m" / "every 2h" / "每日9:00" / "0 9 * * *")
|
|
4234
|
-
--
|
|
4235
|
-
--
|
|
4250
|
+
--top-level 在群消息顶层执行(后续会话形态跟随普通群会话模式)
|
|
4251
|
+
--topic --root-msg-id <om_...> 固定在指定话题下执行
|
|
4252
|
+
--new-topic [--topic-title ...] 每次创建新话题和独立会话
|
|
4253
|
+
--silent 静默执行:不发「执行中」提示,模型判断是否 botmux send 报警
|
|
4236
4254
|
schedule remove <id> 删除任务
|
|
4237
4255
|
schedule pause|resume <id> 暂停/恢复
|
|
4238
4256
|
schedule run <id> 标记立即执行
|
|
@@ -4711,9 +4729,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4711
4729
|
return;
|
|
4712
4730
|
}
|
|
4713
4731
|
if (sub === 'add') {
|
|
4714
|
-
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic', '--silent']);
|
|
4732
|
+
const [rawSchedule, ...promptParts] = positionals(rest, ['--new-topic', '--top-level', '--topic', '--silent']);
|
|
4715
4733
|
if (!rawSchedule) {
|
|
4716
|
-
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--root-msg-id ROOT] [--lark-app-id APP] [--workdir DIR] [--
|
|
4734
|
+
console.error('用法: botmux schedule add <schedule> <prompt> [--name NAME] [--chat-id CHAT] [--top-level | --topic --root-msg-id ROOT | --new-topic [--topic-title TITLE]] [--lark-app-id APP] [--workdir DIR] [--silent]');
|
|
4717
4735
|
process.exit(1);
|
|
4718
4736
|
}
|
|
4719
4737
|
// prompt may come from positional or --prompt flag
|
|
@@ -4724,25 +4742,50 @@ async function cmdSchedule(sub, rest) {
|
|
|
4724
4742
|
}
|
|
4725
4743
|
const cur = detectCurrentSession();
|
|
4726
4744
|
const chatId = argValue(rest, '--chat-id') ?? cur?.chatId;
|
|
4727
|
-
const
|
|
4745
|
+
const explicitRootMessageId = argValue(rest, '--root-msg-id');
|
|
4746
|
+
const rootMessageId = explicitRootMessageId
|
|
4747
|
+
?? (chatId && chatId === cur?.chatId ? cur.rootMessageId : undefined);
|
|
4728
4748
|
const larkAppId = argValue(rest, '--lark-app-id') ?? cur?.larkAppId;
|
|
4729
4749
|
const workingDir = argValue(rest, '--workdir') ?? cur?.workingDir ?? process.cwd();
|
|
4730
4750
|
const name = argValue(rest, '--name') ?? (promptArg.length > 20 ? promptArg.slice(0, 20) + '…' : promptArg);
|
|
4731
|
-
|
|
4732
|
-
const
|
|
4733
|
-
|
|
4734
|
-
|
|
4751
|
+
const legacyDeliver = argValue(rest, '--deliver');
|
|
4752
|
+
const wantsNewTopic = rest.includes('--new-topic') || legacyDeliver === 'new-topic';
|
|
4753
|
+
const wantsTopLevel = rest.includes('--top-level');
|
|
4754
|
+
const wantsTopic = rest.includes('--topic');
|
|
4755
|
+
if ([wantsNewTopic, wantsTopLevel, wantsTopic].filter(Boolean).length > 1) {
|
|
4756
|
+
console.error('--top-level、--topic 与 --new-topic 只能选择一个。');
|
|
4757
|
+
process.exit(1);
|
|
4758
|
+
}
|
|
4759
|
+
const requestedDeliver = legacyDeliver;
|
|
4760
|
+
const deliver = requestedDeliver === 'local' ? 'local' : 'origin';
|
|
4735
4761
|
// --silent: fires post no "执行中" banner; the spawned turn stays quiet and
|
|
4736
4762
|
// the model only `botmux send`s when the alert condition in the prompt is met.
|
|
4737
4763
|
const silent = rest.includes('--silent');
|
|
4738
|
-
if (silent && deliver === 'new-topic') {
|
|
4739
|
-
console.error('--silent 与 --new-topic 不能同时使用:新话题必须由首条消息开启。要「有异常才开新话题」,请在 prompt 里指示模型报警时用 botmux send 顶层发送。');
|
|
4740
|
-
process.exit(1);
|
|
4741
|
-
}
|
|
4742
4764
|
if (!chatId) {
|
|
4743
4765
|
console.error('无法推断 chat-id。请加上 --chat-id <CHAT_ID>,或从 Lark 话题内的 CLI 会话中运行本命令。');
|
|
4744
4766
|
process.exit(1);
|
|
4745
4767
|
}
|
|
4768
|
+
const executionPosition = wantsNewTopic
|
|
4769
|
+
? 'new-topic'
|
|
4770
|
+
: wantsTopLevel
|
|
4771
|
+
? 'top-level'
|
|
4772
|
+
: wantsTopic
|
|
4773
|
+
? 'topic'
|
|
4774
|
+
: cur?.scope === 'chat' ? 'top-level' : rootMessageId ? 'topic' : 'top-level';
|
|
4775
|
+
const scope = executionPosition === 'topic' ? 'thread' : 'chat';
|
|
4776
|
+
if (scope === 'thread' && !rootMessageId) {
|
|
4777
|
+
console.error('话题下执行需要 --root-msg-id <ROOT_MESSAGE_ID>,或从 Lark 话题会话中运行。');
|
|
4778
|
+
process.exit(1);
|
|
4779
|
+
}
|
|
4780
|
+
const topicTitle = argValue(rest, '--topic-title');
|
|
4781
|
+
if (topicTitle && executionPosition !== 'new-topic') {
|
|
4782
|
+
console.error('--topic-title 仅可与 --new-topic 一起使用。');
|
|
4783
|
+
process.exit(1);
|
|
4784
|
+
}
|
|
4785
|
+
if (topicTitle && Array.from(topicTitle.trim()).length > 200) {
|
|
4786
|
+
console.error('--topic-title 最多 200 个字符。');
|
|
4787
|
+
process.exit(1);
|
|
4788
|
+
}
|
|
4746
4789
|
let parsed;
|
|
4747
4790
|
try {
|
|
4748
4791
|
parsed = scheduler.parseSchedule(rawSchedule);
|
|
@@ -4764,7 +4807,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4764
4807
|
creatorRootMessageId: cur?.rootMessageId,
|
|
4765
4808
|
creatorLarkAppId: cur?.larkAppId,
|
|
4766
4809
|
chatType: cur?.chatType === 'p2p' ? 'p2p' : 'topic_group',
|
|
4767
|
-
scope
|
|
4810
|
+
scope,
|
|
4811
|
+
executionPosition,
|
|
4812
|
+
topicTitle,
|
|
4768
4813
|
deliver,
|
|
4769
4814
|
silent,
|
|
4770
4815
|
});
|
|
@@ -4773,7 +4818,9 @@ async function cmdSchedule(sub, rest) {
|
|
|
4773
4818
|
console.log(` 规则: ${parsed.display}`);
|
|
4774
4819
|
console.log(` 下次执行: ${next}`);
|
|
4775
4820
|
console.log(` 工作目录: ${workingDir}`);
|
|
4776
|
-
console.log(`
|
|
4821
|
+
console.log(` 执行位置: ${executionPosition === 'new-topic' ? '每次新话题' : executionPosition === 'top-level' ? '群消息顶层' : '话题下'}`);
|
|
4822
|
+
if (executionPosition === 'new-topic' && topicTitle?.trim())
|
|
4823
|
+
console.log(` 新话题标题: ${topicTitle.trim()}`);
|
|
4777
4824
|
if (silent)
|
|
4778
4825
|
console.log(' 静默: 触发时不发「执行中」提示,由模型判断是否需要 botmux send 报警');
|
|
4779
4826
|
return;
|
|
@@ -5417,6 +5464,10 @@ function riffModeSession(opts = {}) {
|
|
|
5417
5464
|
const scopeEnv = process.env.BOTMUX_SESSION_SCOPE;
|
|
5418
5465
|
const scope = scopeEnv === 'chat' || scopeEnv === 'thread' ? scopeEnv : (rootMessageId ? 'thread' : 'chat');
|
|
5419
5466
|
const ownerOpenId = process.env.BOTMUX_OWNER_OPEN_ID;
|
|
5467
|
+
const deferredTaskId = process.env.BOTMUX_DEFERRED_SCHEDULE_TASK_ID;
|
|
5468
|
+
const deferredTurnId = process.env.BOTMUX_DEFERRED_SCHEDULE_TURN_ID;
|
|
5469
|
+
const deferredRoutingAnchor = process.env.BOTMUX_DEFERRED_SCHEDULE_ROUTING_ANCHOR;
|
|
5470
|
+
const deferredCreatedAt = process.env.BOTMUX_DEFERRED_SCHEDULE_CREATED_AT;
|
|
5420
5471
|
const botConfig = {
|
|
5421
5472
|
larkAppId: appId,
|
|
5422
5473
|
larkAppSecret: appSecret,
|
|
@@ -5434,6 +5485,19 @@ function riffModeSession(opts = {}) {
|
|
|
5434
5485
|
larkAppId: appId,
|
|
5435
5486
|
scope,
|
|
5436
5487
|
ownerOpenId,
|
|
5488
|
+
...(deferredTaskId && deferredTurnId && deferredRoutingAnchor && deferredCreatedAt
|
|
5489
|
+
? {
|
|
5490
|
+
deferredScheduleRun: {
|
|
5491
|
+
taskId: deferredTaskId,
|
|
5492
|
+
turnId: deferredTurnId,
|
|
5493
|
+
routingAnchor: deferredRoutingAnchor,
|
|
5494
|
+
...(process.env.BOTMUX_DEFERRED_SCHEDULE_TOPIC_TITLE
|
|
5495
|
+
? { topicTitle: process.env.BOTMUX_DEFERRED_SCHEDULE_TOPIC_TITLE }
|
|
5496
|
+
: {}),
|
|
5497
|
+
createdAt: deferredCreatedAt,
|
|
5498
|
+
},
|
|
5499
|
+
}
|
|
5500
|
+
: {}),
|
|
5437
5501
|
// 刻意不设 quoteTargetSenderOpenId:env 是任务创建时冻结的,follow-up 轮
|
|
5438
5502
|
// 换了触发人后 --mention-back 会错误 @ 最初 owner。riff routing 明确禁用
|
|
5439
5503
|
// mention-back(@ 硬门会拒绝并提示 agent 改用 --mention <本轮 sender>)。
|
|
@@ -5707,6 +5771,8 @@ async function cmdSend(rest) {
|
|
|
5707
5771
|
console.error(`session ${sid} 缺少 larkAppId`);
|
|
5708
5772
|
process.exit(1);
|
|
5709
5773
|
}
|
|
5774
|
+
let deferredMaterializedByThisCommand = false;
|
|
5775
|
+
let deferredTopicRootMessageIdForOutput;
|
|
5710
5776
|
// 本轮的回复锚点:优先按 turnId 精确取 per-turn 落点(排队/并发轮次不再被
|
|
5711
5777
|
// 后到轮次覆盖 currentReplyTarget 而塌成群顶层 plain),无记录再退回单槽。
|
|
5712
5778
|
const turnReplyTarget = pickTurnReplyTarget(s, currentTurnId);
|
|
@@ -5855,23 +5921,45 @@ async function cmdSend(rest) {
|
|
|
5855
5921
|
}
|
|
5856
5922
|
else {
|
|
5857
5923
|
revalidateVcMeetingManagedSend();
|
|
5858
|
-
const canonicalTarget = resolveSendTarget({
|
|
5859
|
-
into: sendInto,
|
|
5860
|
-
topLevel: sendTopLevel,
|
|
5861
|
-
chatScope: s.scope === 'chat',
|
|
5862
|
-
chatId: canonicalOutput.targetChatId,
|
|
5863
|
-
rootMessageId: s.rootMessageId,
|
|
5864
|
-
replyTargetRootId: turnReplyTarget?.rootMessageId,
|
|
5865
|
-
replyTargetTurnId: turnReplyTarget?.turnId,
|
|
5866
|
-
replyTargetQuoteOnly: turnReplyTarget?.quoteOnly,
|
|
5867
|
-
currentTurnId,
|
|
5868
|
-
});
|
|
5869
5924
|
const managedProviderOptions = prepared
|
|
5870
5925
|
? { suppressHook: true }
|
|
5871
5926
|
: undefined;
|
|
5872
|
-
|
|
5873
|
-
? await
|
|
5874
|
-
|
|
5927
|
+
const deferred = !sendInto && (!overrideChatId || overrideChatId === s.chatId)
|
|
5928
|
+
? await dispatchDeferredTopicSend({
|
|
5929
|
+
dataDir: resolveDataDir(),
|
|
5930
|
+
session: s,
|
|
5931
|
+
currentTurnId,
|
|
5932
|
+
explicitTopLevel: sendTopLevel,
|
|
5933
|
+
reuseBoundRootWhenTopLevel: deferredMaterializedByThisCommand,
|
|
5934
|
+
content: canonicalOutput.content,
|
|
5935
|
+
msgType: canonicalOutput.msgType,
|
|
5936
|
+
uuid: prepared?.providerKey,
|
|
5937
|
+
sendRoot: (body, type, uuid) => sendMessage(appId, targetChatId, body, type, uuid, undefined, managedProviderOptions),
|
|
5938
|
+
sendTitleSeed: (title, uuid) => sendMessage(appId, targetChatId, title, 'text', uuid),
|
|
5939
|
+
replyRoot: (root, body, type, uuid) => replyMessage(appId, root, body, type, true, uuid, undefined, managedProviderOptions),
|
|
5940
|
+
})
|
|
5941
|
+
: { handled: false };
|
|
5942
|
+
if (deferred.handled && deferred.messageId) {
|
|
5943
|
+
deferredMaterializedByThisCommand ||= deferred.materializedNow === true;
|
|
5944
|
+
deferredTopicRootMessageIdForOutput = deferred.rootMessageId;
|
|
5945
|
+
messageId = deferred.messageId;
|
|
5946
|
+
}
|
|
5947
|
+
else {
|
|
5948
|
+
const canonicalTarget = resolveSendTarget({
|
|
5949
|
+
into: sendInto,
|
|
5950
|
+
topLevel: sendTopLevel,
|
|
5951
|
+
chatScope: s.scope === 'chat',
|
|
5952
|
+
chatId: canonicalOutput.targetChatId,
|
|
5953
|
+
rootMessageId: s.rootMessageId,
|
|
5954
|
+
replyTargetRootId: turnReplyTarget?.rootMessageId,
|
|
5955
|
+
replyTargetTurnId: turnReplyTarget?.turnId,
|
|
5956
|
+
replyTargetQuoteOnly: turnReplyTarget?.quoteOnly,
|
|
5957
|
+
currentTurnId,
|
|
5958
|
+
});
|
|
5959
|
+
messageId = canonicalTarget.mode === 'plain'
|
|
5960
|
+
? await sendMessage(appId, canonicalTarget.chatId, canonicalOutput.content, canonicalOutput.msgType, prepared?.providerKey, undefined, managedProviderOptions)
|
|
5961
|
+
: await replyMessage(appId, canonicalTarget.rootMessageId, canonicalOutput.content, canonicalOutput.msgType, canonicalTarget.mode === 'thread', prepared?.providerKey, undefined, managedProviderOptions);
|
|
5962
|
+
}
|
|
5875
5963
|
if (prepared?.kind === 'send' || prepared?.kind === 'succeeded') {
|
|
5876
5964
|
finishVcMeetingImReply(resolveDataDir(), prepared.ref, messageId);
|
|
5877
5965
|
}
|
|
@@ -5879,7 +5967,9 @@ async function cmdSend(rest) {
|
|
|
5879
5967
|
recordVcMeetingPrimaryOutput(messageId, canonicalOutput.targetChatId);
|
|
5880
5968
|
// 语音也是一次回复:写 bridge fallback marker,否则本轮会被判为"没发 botmux send"
|
|
5881
5969
|
// 而触发兜底,多补一张文本卡。与文本/卡片路径同口径:仅同话题回复才记。
|
|
5882
|
-
if (!sendTopLevel
|
|
5970
|
+
if ((!sendTopLevel || !!deferredTopicRootMessageIdForOutput)
|
|
5971
|
+
&& (!overrideChatId || overrideChatId === s.chatId)
|
|
5972
|
+
&& !sendInto) {
|
|
5883
5973
|
try {
|
|
5884
5974
|
const markerDir = join(resolveDataDir(), 'turn-sends');
|
|
5885
5975
|
if (!existsSync(markerDir))
|
|
@@ -5889,7 +5979,16 @@ async function cmdSend(rest) {
|
|
|
5889
5979
|
catch { /* best-effort:漏记只多一条兜底,不致命 */ }
|
|
5890
5980
|
}
|
|
5891
5981
|
console.error(`✓ 已发送语音 ${messageId} | ${Math.round(out.durationMs / 1000)}s`);
|
|
5892
|
-
console.log(JSON.stringify({
|
|
5982
|
+
console.log(JSON.stringify({
|
|
5983
|
+
success: true,
|
|
5984
|
+
messageId,
|
|
5985
|
+
sessionId: sid,
|
|
5986
|
+
kind: 'voice',
|
|
5987
|
+
durationMs: out.durationMs,
|
|
5988
|
+
...(deferredTopicRootMessageIdForOutput
|
|
5989
|
+
? { deferredTopicRootMessageId: deferredTopicRootMessageIdForOutput, turnId: currentTurnId }
|
|
5990
|
+
: {}),
|
|
5991
|
+
}));
|
|
5893
5992
|
}
|
|
5894
5993
|
catch (e) {
|
|
5895
5994
|
console.error(`语音发送失败:${e?.message ?? e}`);
|
|
@@ -6108,10 +6207,33 @@ async function cmdSend(rest) {
|
|
|
6108
6207
|
// Dispatch helper: top-level / chat-scope send vs reply-in-thread, single
|
|
6109
6208
|
// decision point. Used for file attachments (always plain in chat scope).
|
|
6110
6209
|
const sendTarget = resolveSendTarget({ into: sendInto, topLevel: sendTopLevel, chatScope: isChatScope, chatId: targetChatId, rootMessageId: s.rootMessageId, replyTargetRootId: turnReplyTarget?.rootMessageId, replyTargetTurnId: turnReplyTarget?.turnId, replyTargetQuoteOnly: turnReplyTarget?.quoteOnly, currentTurnId });
|
|
6111
|
-
const dispatch = (content, msgType, uuid, suppressHook) => {
|
|
6210
|
+
const dispatch = async (content, msgType, uuid, suppressHook) => {
|
|
6112
6211
|
// This closure also carries attachments, so every Lark call re-checks the
|
|
6113
6212
|
// exact durable attempt/member instead of inheriting the early cmd gate.
|
|
6114
6213
|
revalidateVcMeetingManagedSend();
|
|
6214
|
+
if (!sendInto && (!overrideChatId || overrideChatId === s.chatId)) {
|
|
6215
|
+
const deferred = await dispatchDeferredTopicSend({
|
|
6216
|
+
dataDir: resolveDataDir(),
|
|
6217
|
+
session: s,
|
|
6218
|
+
currentTurnId,
|
|
6219
|
+
explicitTopLevel: sendTopLevel,
|
|
6220
|
+
reuseBoundRootWhenTopLevel: deferredMaterializedByThisCommand,
|
|
6221
|
+
content,
|
|
6222
|
+
msgType,
|
|
6223
|
+
uuid,
|
|
6224
|
+
sendRoot: (body, type, rootUuid) => sendMessage(appId, targetChatId, body, type, rootUuid, hookContext, suppressHook ? { suppressHook: true } : undefined),
|
|
6225
|
+
// The optional title is the root seed and the actual alert follows as
|
|
6226
|
+
// its first reply. Do not emit a user outbound hook for presentation-
|
|
6227
|
+
// only seed text; the alert itself still goes through the hook path.
|
|
6228
|
+
sendTitleSeed: (title, rootUuid) => sendMessage(appId, targetChatId, title, 'text', rootUuid),
|
|
6229
|
+
replyRoot: (root, body, type, replyUuid) => replyMessage(appId, root, body, type, true, replyUuid, hookContext, suppressHook ? { suppressHook: true } : undefined),
|
|
6230
|
+
});
|
|
6231
|
+
if (deferred.handled && deferred.messageId) {
|
|
6232
|
+
deferredMaterializedByThisCommand ||= deferred.materializedNow === true;
|
|
6233
|
+
deferredTopicRootMessageIdForOutput = deferred.rootMessageId;
|
|
6234
|
+
return deferred.messageId;
|
|
6235
|
+
}
|
|
6236
|
+
}
|
|
6115
6237
|
return sendTarget.mode === 'plain'
|
|
6116
6238
|
? sendMessage(appId, sendTarget.chatId, content, msgType, uuid, hookContext, suppressHook ? { suppressHook: true } : undefined)
|
|
6117
6239
|
: replyMessage(appId, sendTarget.rootMessageId, content, msgType, sendTarget.mode === 'thread', uuid, hookContext, suppressHook ? { suppressHook: true } : undefined);
|
|
@@ -6538,8 +6660,9 @@ async function cmdSend(rest) {
|
|
|
6538
6660
|
// sends can suppress transcript fallback when their content appears to
|
|
6539
6661
|
// cover the same final answer; detoured sends suppress only when they
|
|
6540
6662
|
// closed a pending response card for this turn.
|
|
6541
|
-
if (shouldRecordBridgeMarker)
|
|
6663
|
+
if (shouldRecordBridgeMarker || deferredTopicRootMessageIdForOutput) {
|
|
6542
6664
|
recordBridgeSendMarker(sentAtMs, messageId, text);
|
|
6665
|
+
}
|
|
6543
6666
|
// Send attachments as separate messages — best-effort. The primary message
|
|
6544
6667
|
// is already delivered above; a failing attachment must not throw out to the
|
|
6545
6668
|
// catch below (which would report total failure / exit 1 for an already-sent
|
|
@@ -6619,6 +6742,9 @@ async function cmdSend(rest) {
|
|
|
6619
6742
|
sessionId: sid,
|
|
6620
6743
|
quotedMessageId: primaryQuotedId,
|
|
6621
6744
|
mentioned: mentions.map(m => ({ open_id: m.open_id, name: m.name })),
|
|
6745
|
+
...(deferredTopicRootMessageIdForOutput
|
|
6746
|
+
? { deferredTopicRootMessageId: deferredTopicRootMessageIdForOutput, turnId: currentTurnId }
|
|
6747
|
+
: {}),
|
|
6622
6748
|
...(attention.requested ? { attentionRaised, attentionError } : {}),
|
|
6623
6749
|
...(failedAttachments.length > 0
|
|
6624
6750
|
? { failedAttachments: failedAttachments.map(f => f.path) }
|