cli-jaw 2.2.19 → 2.2.21
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/README.md +97 -3
- package/dist/bin/commands/dispatch.js +62 -16
- package/dist/bin/commands/dispatch.js.map +1 -1
- package/dist/server.js +14 -0
- package/dist/server.js.map +1 -1
- package/dist/src/agent/spawn/process-kill.js +96 -2
- package/dist/src/agent/spawn/process-kill.js.map +1 -1
- package/dist/src/agent/spawn.js +34 -65
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/bgtask/runner.js +26 -21
- package/dist/src/bgtask/runner.js.map +1 -1
- package/dist/src/cli/acp-client.js +11 -5
- package/dist/src/cli/acp-client.js.map +1 -1
- package/dist/src/cli/cli-status-worker.js +22 -3
- package/dist/src/cli/cli-status-worker.js.map +1 -1
- package/dist/src/cli/cli-status.js +7 -1
- package/dist/src/cli/cli-status.js.map +1 -1
- package/dist/src/cli/employee-handler.js +3 -2
- package/dist/src/cli/employee-handler.js.map +1 -1
- package/dist/src/cli/handlers.js +1 -0
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/code-mode/acp-host.js +22 -10
- package/dist/src/code-mode/acp-host.js.map +1 -1
- package/dist/src/core/config.js +23 -0
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/db.js +16 -0
- package/dist/src/core/db.js.map +1 -1
- package/dist/src/core/dispatch-approval-ingress.js +59 -0
- package/dist/src/core/dispatch-approval-ingress.js.map +1 -0
- package/dist/src/core/dispatch-approval.js +135 -0
- package/dist/src/core/dispatch-approval.js.map +1 -0
- package/dist/src/core/employees.js +22 -4
- package/dist/src/core/employees.js.map +1 -1
- package/dist/src/core/runtime-settings.js +27 -0
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/serve-log.js +66 -0
- package/dist/src/core/serve-log.js.map +1 -0
- package/dist/src/core/settings-merge.js +10 -1
- package/dist/src/core/settings-merge.js.map +1 -1
- package/dist/src/core/windows-shell.js +63 -0
- package/dist/src/core/windows-shell.js.map +1 -0
- package/dist/src/discord/bot.js +214 -147
- package/dist/src/discord/bot.js.map +1 -1
- package/dist/src/discord/gateway-supervisor.js +303 -0
- package/dist/src/discord/gateway-supervisor.js.map +1 -0
- package/dist/src/discord/rest-scheduler.js +448 -0
- package/dist/src/discord/rest-scheduler.js.map +1 -0
- package/dist/src/discord/send-only-client.js +90 -43
- package/dist/src/discord/send-only-client.js.map +1 -1
- package/dist/src/manager/lifecycle.js +7 -2
- package/dist/src/manager/lifecycle.js.map +1 -1
- package/dist/src/manager/notes/capabilities.js +9 -7
- package/dist/src/manager/notes/capabilities.js.map +1 -1
- package/dist/src/memory/bootstrap.js +5 -1
- package/dist/src/memory/bootstrap.js.map +1 -1
- package/dist/src/memory/host-toolchain.js +156 -0
- package/dist/src/memory/host-toolchain.js.map +1 -0
- package/dist/src/messaging/channel-capabilities.js +30 -0
- package/dist/src/messaging/channel-capabilities.js.map +1 -0
- package/dist/src/messaging/delivery-outcome.js +73 -0
- package/dist/src/messaging/delivery-outcome.js.map +1 -0
- package/dist/src/messaging/draft-stream.js +154 -0
- package/dist/src/messaging/draft-stream.js.map +1 -0
- package/dist/src/messaging/runtime.js +3 -9
- package/dist/src/messaging/runtime.js.map +1 -1
- package/dist/src/messaging/send.js +40 -8
- package/dist/src/messaging/send.js.map +1 -1
- package/dist/src/messaging/types.js +22 -1
- package/dist/src/messaging/types.js.map +1 -1
- package/dist/src/notes/search.js +6 -4
- package/dist/src/notes/search.js.map +1 -1
- package/dist/src/prompt/builder.js +110 -6
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/conversation-context.js +23 -0
- package/dist/src/prompt/conversation-context.js.map +1 -0
- package/dist/src/prompt/templates/a1-system.md +28 -12
- package/dist/src/prompt/templates/control-system.md +19 -6
- package/dist/src/prompt/templates/employee.md +16 -3
- package/dist/src/routes/orchestrate.js +83 -0
- package/dist/src/routes/orchestrate.js.map +1 -1
- package/dist/src/security/path-guards.js +157 -27
- package/dist/src/security/path-guards.js.map +1 -1
- package/dist/src/slack/api.js +38 -5
- package/dist/src/slack/api.js.map +1 -1
- package/dist/src/slack/bot.js +244 -37
- package/dist/src/slack/bot.js.map +1 -1
- package/dist/src/slack/context.js +192 -0
- package/dist/src/slack/context.js.map +1 -0
- package/dist/src/slack/conversation.js +275 -0
- package/dist/src/slack/conversation.js.map +1 -0
- package/dist/src/slack/enrichment-cache.js +334 -0
- package/dist/src/slack/enrichment-cache.js.map +1 -0
- package/dist/src/slack/history.js +47 -8
- package/dist/src/slack/history.js.map +1 -1
- package/dist/src/slack/identity.js +99 -190
- package/dist/src/slack/identity.js.map +1 -1
- package/dist/src/slack/ingress.js +91 -3
- package/dist/src/slack/ingress.js.map +1 -1
- package/dist/src/slack/progress.js +39 -51
- package/dist/src/slack/progress.js.map +1 -1
- package/dist/src/slack/thread-tracker.js +88 -0
- package/dist/src/slack/thread-tracker.js.map +1 -1
- package/dist/src/telegram/bot.js +127 -56
- package/dist/src/telegram/bot.js.map +1 -1
- package/dist/src/telegram/update-offset.js +152 -0
- package/dist/src/telegram/update-offset.js.map +1 -0
- package/package.json +1 -1
- package/public/dist/assets/{AdvancedExport-c41zCkwB.js → AdvancedExport-IOkupLFE.js} +1 -1
- package/public/dist/assets/Agent-DtgCvkB_.js +1 -0
- package/public/dist/assets/{Browser-B52Bdaeu.js → Browser-J4TPo4bX.js} +1 -1
- package/public/dist/assets/{BrowserPanel-Bh3JpkZO.js → BrowserPanel-C0aa2gja.js} +1 -1
- package/public/dist/assets/{ChannelsDiscord-D9FLnZso.js → ChannelsDiscord-D4fD-9hP.js} +1 -1
- package/public/dist/assets/{ChannelsSlack-CVNKtoo4.js → ChannelsSlack-_KBwRonM.js} +1 -1
- package/public/dist/assets/{ChannelsTelegram-BOCOPrBc.js → ChannelsTelegram-tihzSWVE.js} +1 -1
- package/public/dist/assets/{CodeCanvas-CbfPP7Ad.js → CodeCanvas-CaeLVtZi.js} +2 -2
- package/public/dist/assets/{DashboardEmbeddingSection-DMgHZQnn.js → DashboardEmbeddingSection-DiqlLiLj.js} +1 -1
- package/public/dist/assets/{DashboardMeta-DennaaA_.js → DashboardMeta-Dsj8kEuW.js} +1 -1
- package/public/dist/assets/{DesignPanel-DcL369nB.js → DesignPanel-B8CAf6sH.js} +1 -1
- package/public/dist/assets/{DiffPanel-B_ljObDk.js → DiffPanel-BTZRq6eG.js} +1 -1
- package/public/dist/assets/{Display-hGuSn_W5.js → Display-nkXitDjD.js} +1 -1
- package/public/dist/assets/{DocPanel-K8A2pm_1.js → DocPanel-ogNttSee.js} +1 -1
- package/public/dist/assets/{Employees-B5YXk5ma.js → Employees-CU_1YnrA.js} +1 -1
- package/public/dist/assets/{FolderPanel-CV52EzwG.js → FolderPanel-D0w_zD66.js} +1 -1
- package/public/dist/assets/{HealthBadge-megTlF4n.js → HealthBadge-CUaJ1PQH.js} +1 -1
- package/public/dist/assets/{Heartbeat-DDmZARWw.js → Heartbeat-BeAP2bMO.js} +1 -1
- package/public/dist/assets/{InlineWarn-DDzeHxQw.js → InlineWarn-D-fmcQXD.js} +1 -1
- package/public/dist/assets/MarkdownRenderer-B6HbiZ6i.js +1 -0
- package/public/dist/assets/{MarkdownRenderer-CXrilOsG.js → MarkdownRenderer-Cd3kkg_s.js} +2 -2
- package/public/dist/assets/{Mcp-BHWnJ6SP.js → Mcp-2HD1qR7F.js} +1 -1
- package/public/dist/assets/{Memory-CUbviW7N.js → Memory-frrIhLly.js} +1 -1
- package/public/dist/assets/{MilkdownWysiwygEditor-BKOCDI4Z.js → MilkdownWysiwygEditor-BkEzO5cz.js} +1 -1
- package/public/dist/assets/{ModelProvider-ngg8xTuB.js → ModelProvider-DqUvwyZ6.js} +1 -1
- package/public/dist/assets/{Network-AWpSkALD.js → Network-DfzqHi9q.js} +1 -1
- package/public/dist/assets/{NotesGraphWorkspace-Dm1xUFl8.js → NotesGraphWorkspace-BRIiraP9.js} +1 -1
- package/public/dist/assets/{PanelLayoutProvider-XpTo-i_s.js → PanelLayoutProvider-B9fYsunp.js} +1 -1
- package/public/dist/assets/Permissions-ByUy_5DT.js +1 -0
- package/public/dist/assets/{Permissions-CnKt44dN.js → Permissions-RgyF1O6q.js} +1 -1
- package/public/dist/assets/{Profile-DnIE2ios.js → Profile-DXKtAzfg.js} +1 -1
- package/public/dist/assets/{Prompts-B9aKLall.js → Prompts-C7njPWCu.js} +1 -1
- package/public/dist/assets/{SpeechKeys-K4Be_o7z.js → SpeechKeys-B7SDWzo9.js} +1 -1
- package/public/dist/assets/{TelegramHub-CFwSkzHP.js → TelegramHub-C61X3f-H.js} +1 -1
- package/public/dist/assets/{TerminalPanel-CdlFZHAK.js → TerminalPanel-DlUFPyzc.js} +1 -1
- package/public/dist/assets/{TransportStatusChips-CjEySMis.js → TransportStatusChips-B0NR0ljO.js} +1 -1
- package/public/dist/assets/{app-is76CHGZ.js → app-DUbf-v7B.js} +4 -4
- package/public/dist/assets/architecture-7EHR7CIX-Byg-B8Sh.js +1 -0
- package/public/dist/assets/{architectureDiagram-3BPJPVTR-q8idz3H3.js → architectureDiagram-3BPJPVTR-DA7niVYs.js} +1 -1
- package/public/dist/assets/bgtask-badge-B8KhuBa7.js +1 -0
- package/public/dist/assets/{bgtask-badge-B0B1nXUs.js → bgtask-badge-jIH69Dp3.js} +1 -1
- package/public/dist/assets/{blockDiagram-GPEHLZMM-DGB0dsia.js → blockDiagram-GPEHLZMM-czRsW1WP.js} +1 -1
- package/public/dist/assets/{bounded-set-CFlZiEF4.js → bounded-set-DXkYOGnQ.js} +1 -1
- package/public/dist/assets/{c4Diagram-AAUBKEIU-ChP5YfVt.js → c4Diagram-AAUBKEIU-zoRyRo1y.js} +1 -1
- package/public/dist/assets/channel-Cr7Dmg2t.js +1 -0
- package/public/dist/assets/{chunk-2J33WTMH-D3OPoEHg.js → chunk-2J33WTMH-DMaZjiDe.js} +1 -1
- package/public/dist/assets/{chunk-3OPIFGDE-CULJ8ZHF.js → chunk-3OPIFGDE-fm0Uteda.js} +1 -1
- package/public/dist/assets/{chunk-4BX2VUAB-DGgktZYr.js → chunk-4BX2VUAB-DU36Vmpr.js} +1 -1
- package/public/dist/assets/{chunk-4EGX6M5U-BD3v8KR4.js → chunk-4EGX6M5U-CYPeQu4F.js} +1 -1
- package/public/dist/assets/chunk-55IACEB6-Dkm6BnqN.js +1 -0
- package/public/dist/assets/{chunk-5DO6E6H7-B-FbGqHn.js → chunk-5DO6E6H7-CIcLA1n6.js} +1 -1
- package/public/dist/assets/{chunk-5ZQYHXKU-DVpWOoGS.js → chunk-5ZQYHXKU-NjOvV6Nd.js} +1 -1
- package/public/dist/assets/{chunk-727SXJPM-CZjR7q6H.js → chunk-727SXJPM-CUOujQg0.js} +1 -1
- package/public/dist/assets/{chunk-AQP2D5EJ-BlGjnlsV.js → chunk-AQP2D5EJ-2nFXTQ0W.js} +1 -1
- package/public/dist/assets/{chunk-BR22UD5L-MK8KuB9X.js → chunk-BR22UD5L-BoyFFQuR.js} +1 -1
- package/public/dist/assets/{chunk-BSJP7CBP-ypXC4wBv.js → chunk-BSJP7CBP-B1MMwNrU.js} +1 -1
- package/public/dist/assets/{chunk-CSCIHK7Q-CmvetykJ.js → chunk-CSCIHK7Q-C0MOgWVt.js} +1 -1
- package/public/dist/assets/{chunk-FHYWG6QK-Do5csWDm.js → chunk-FHYWG6QK-CmUWtJPn.js} +1 -1
- package/public/dist/assets/{chunk-FMBD7UC4-BXpT25MP.js → chunk-FMBD7UC4-BEz4FhFn.js} +1 -1
- package/public/dist/assets/{chunk-KSCS5N6A-DtlfLqto.js → chunk-KSCS5N6A-B2XGqWQY.js} +1 -1
- package/public/dist/assets/{chunk-L5ZTLDWV-Czv9NkHn.js → chunk-L5ZTLDWV-CfZ2hrJ2.js} +1 -1
- package/public/dist/assets/{chunk-LZXEDZCA-vD7oFdiq.js → chunk-LZXEDZCA-BXuFCBsZ.js} +1 -1
- package/public/dist/assets/{chunk-MPE355IW-2ei0PVn0.js → chunk-MPE355IW-BdSiU-oV.js} +1 -1
- package/public/dist/assets/{chunk-MZUSXYTE-JO_qTk4K.js → chunk-MZUSXYTE-VYfI8Uwx.js} +1 -1
- package/public/dist/assets/{chunk-N66VUXT2-BXL-FniY.js → chunk-N66VUXT2-DJVNyglo.js} +1 -1
- package/public/dist/assets/{chunk-ND2GUHAM-B9SIO-4a.js → chunk-ND2GUHAM-1k8TCCsJ.js} +1 -1
- package/public/dist/assets/{chunk-NZK2D7GU-CqOo06-Z.js → chunk-NZK2D7GU-CkYWftT8.js} +1 -1
- package/public/dist/assets/{chunk-O5CBEL6O-BWbe_grt.js → chunk-O5CBEL6O-B5g0NbhD.js} +1 -1
- package/public/dist/assets/{chunk-PUPMXCY4-aFTMGBaR.js → chunk-PUPMXCY4-DJKmByz8.js} +1 -1
- package/public/dist/assets/chunk-QZHKN3VN-C6ktI6EQ.js +1 -0
- package/public/dist/assets/{chunk-UIBZB4QT-S8EH0jZR.js → chunk-UIBZB4QT-DgLbPJ3_.js} +1 -1
- package/public/dist/assets/{chunk-WCWK7LTN-EgrNk7Dj.js → chunk-WCWK7LTN-DWxi0w0a.js} +1 -1
- package/public/dist/assets/chunk-WU5MYG2G-Cwe6QZ3_.js +1 -0
- package/public/dist/assets/{chunk-XPW4576I-8oydVjY6.js → chunk-XPW4576I-CaTDAC52.js} +1 -1
- package/public/dist/assets/classDiagram-4FO5ZUOK-BzLBk9sv.js +1 -0
- package/public/dist/assets/classDiagram-v2-Q7XG4LA2-9K8wUz3g.js +1 -0
- package/public/dist/assets/{copy-text-BDs2wKjA.js → copy-text-Dy0kfmb9.js} +1 -1
- package/public/dist/assets/{cose-bilkent-S5V4N54A-PNmvcq_6.js → cose-bilkent-S5V4N54A-B9Tcz6qW.js} +1 -1
- package/public/dist/assets/{dagre-BM42HDAG-BP_m3uo9.js → dagre-BM42HDAG-OH37BMnf.js} +1 -1
- package/public/dist/assets/{dagre-Ct2n78X9.js → dagre-BsKKQnyU.js} +1 -1
- package/public/dist/assets/{diagram-2AECGRRQ-DhgfR-ol.js → diagram-2AECGRRQ-B1t73Wn1.js} +1 -1
- package/public/dist/assets/{diagram-5GNKFQAL-BRLvmdeK.js → diagram-5GNKFQAL-DBGIcSxH.js} +1 -1
- package/public/dist/assets/{diagram-KO2AKTUF-Co3C18-Q.js → diagram-KO2AKTUF-uRuKS97A.js} +1 -1
- package/public/dist/assets/{diagram-LMA3HP47-3SwoWQij.js → diagram-LMA3HP47-XMEHnr3B.js} +1 -1
- package/public/dist/assets/{diagram-OG6HWLK6-bjEryAd3.js → diagram-OG6HWLK6-B_vRUJSJ.js} +1 -1
- package/public/dist/assets/{dist-BvQlb9-o.js → dist-BCCaGGDY.js} +1 -1
- package/public/dist/assets/{dist-CvzAXxlb.js → dist-BPE4W9iX.js} +1 -1
- package/public/dist/assets/{dist-CFU9RsAu.js → dist-BQMBTYXL.js} +1 -1
- package/public/dist/assets/{dist-BlMOeJym.js → dist-BaPGPaX4.js} +1 -1
- package/public/dist/assets/{dist-B6T-R4xY.js → dist-Bg80xGMJ.js} +1 -1
- package/public/dist/assets/{dist-CS1XLdz3.js → dist-BspKh_Zg.js} +1 -1
- package/public/dist/assets/{dist-qUky5WRy.js → dist-CBnlLSQZ.js} +1 -1
- package/public/dist/assets/{dist-BMC_dTfR.js → dist-CD7tjeNO.js} +1 -1
- package/public/dist/assets/{dist-w2YzIhc5.js → dist-CINTuhik.js} +1 -1
- package/public/dist/assets/{dist-cBBDKBli.js → dist-CTpw6PFT.js} +1 -1
- package/public/dist/assets/{dist-BqzMcuh8.js → dist-CczLsP0o.js} +1 -1
- package/public/dist/assets/{dist-ph7PUr0c.js → dist-CdfDDy4r.js} +1 -1
- package/public/dist/assets/{dist-D8SW_REQ.js → dist-CgIOBybm.js} +1 -1
- package/public/dist/assets/dist-Cl_pRobr.js +1 -0
- package/public/dist/assets/{dist-DTcoHNXr.js → dist-CruwQXwE.js} +1 -1
- package/public/dist/assets/{dist-BDPUxeoi.js → dist-CuL30i1H.js} +1 -1
- package/public/dist/assets/{dist-DMZVNaIe.js → dist-CvE8Qa9r.js} +1 -1
- package/public/dist/assets/{dist-B8V2LYzt.js → dist-Cy3mcP1e.js} +1 -1
- package/public/dist/assets/{dist-C7pD0dEn.js → dist-CzCFEnHw.js} +1 -1
- package/public/dist/assets/{dist-DStWZVZ0.js → dist-D2h9T4I9.js} +1 -1
- package/public/dist/assets/{dist-DmjSXJAP.js → dist-D3ShDeDU.js} +1 -1
- package/public/dist/assets/{dist-CC2vK_6S.js → dist-D8Zky4R1.js} +1 -1
- package/public/dist/assets/{dist-DN-hkAIC.js → dist-DKd_hdkE.js} +1 -1
- package/public/dist/assets/{dist-CjzfPsGt.js → dist-DLOg6n0b.js} +1 -1
- package/public/dist/assets/{dist-DdJuxxG7.js → dist-DS7cuuIk.js} +1 -1
- package/public/dist/assets/dist-DW0I56_o.js +1 -0
- package/public/dist/assets/{dist-BSf40pae.js → dist-JnCmAxGR.js} +1 -1
- package/public/dist/assets/{dist-DhgwoIqj.js → dist-TombgBki.js} +1 -1
- package/public/dist/assets/dist-hBRIxDzG.js +1 -0
- package/public/dist/assets/dist-z5Z70wW8.js +1 -0
- package/public/dist/assets/{dockerfile-C0jniLkw.js → dockerfile-DkX5AHzr.js} +1 -1
- package/public/dist/assets/{employees-eiW0cC8z.js → employees-BNy8a6XX.js} +1 -1
- package/public/dist/assets/{erDiagram-TEJ5UH35-DQBxHU1q.js → erDiagram-TEJ5UH35-CTHxg4ER.js} +1 -1
- package/public/dist/assets/{error-normalize-BzeO0SXE.js → error-normalize-CLRJh19F.js} +1 -1
- package/public/dist/assets/eventmodeling-FCH6USID-LckY84Wp.js +1 -0
- package/public/dist/assets/{factor-nzjoQ9cK.js → factor-Xro2mWdw.js} +1 -1
- package/public/dist/assets/{fields-zkeByFQW.js → fields-BwOMlwS0.js} +1 -1
- package/public/dist/assets/{flowDiagram-I6XJVG4X-BN90fCt5.js → flowDiagram-I6XJVG4X-DgCs6PPU.js} +1 -1
- package/public/dist/assets/{ganttDiagram-6RSMTGT7-B-JAlIhh.js → ganttDiagram-6RSMTGT7-DGjdFJRc.js} +1 -1
- package/public/dist/assets/gitGraph-WXDBUCRP-DXhEIZXY.js +1 -0
- package/public/dist/assets/{gitGraphDiagram-PVQCEYII-CLL2G5U-.js → gitGraphDiagram-PVQCEYII-DvCWiClL.js} +1 -1
- package/public/dist/assets/{graphlib-B6dRm8vZ.js → graphlib-B06FTUqA.js} +1 -1
- package/public/dist/assets/{iframe-renderer-C7qQJX4c.js → iframe-renderer-C6Zwg9w4.js} +2 -2
- package/public/dist/assets/iframe-renderer-DBmV8gCQ.js +1 -0
- package/public/dist/assets/info-J43DQDTF-iXM3vzuR.js +1 -0
- package/public/dist/assets/{infoDiagram-5YYISTIA-CftYDPfc.js → infoDiagram-5YYISTIA-DxkbyTf_.js} +1 -1
- package/public/dist/assets/{ishikawaDiagram-YF4QCWOH-BVa5AJbz.js → ishikawaDiagram-YF4QCWOH-fyJrRZTW.js} +1 -1
- package/public/dist/assets/javascript-DZFdG8BN.js +1 -0
- package/public/dist/assets/{journeyDiagram-JHISSGLW-BeUKm6ME.js → journeyDiagram-JHISSGLW-Dd6CvR-c.js} +1 -1
- package/public/dist/assets/{kanban-definition-UN3LZRKU-K5DYNY4p.js → kanban-definition-UN3LZRKU-C2ZH4LXA.js} +1 -1
- package/public/dist/assets/{manager-Bjuh1jpq.js → manager-DzCR6Pam.js} +4 -4
- package/public/dist/assets/{memory--Q8Tb5SZ.js → memory-C4O44HMr.js} +1 -1
- package/public/dist/assets/memory-Dt_Ji6aP.js +1 -0
- package/public/dist/assets/mermaid-loader-CylkLQP5.js +1 -0
- package/public/dist/assets/{mermaid-parser.core-Cz70RgAa.js → mermaid-parser.core-C-9KB617.js} +1 -1
- package/public/dist/assets/{mermaid.core-Dj5GOPe1.js → mermaid.core-8XY13b72.js} +2 -2
- package/public/dist/assets/mermaid.core-BEuf6y5_.js +1 -0
- package/public/dist/assets/{message-history-CfAHmCDW.js → message-history-DCxD21J1.js} +1 -1
- package/public/dist/assets/message-history-DyISauiv.js +1 -0
- package/public/dist/assets/{mindmap-definition-RKZ34NQL-PsH0E_3e.js → mindmap-definition-RKZ34NQL-DUQBUbUA.js} +1 -1
- package/public/dist/assets/{nsis-BI3I3OhH.js → nsis-iX94j4T9.js} +1 -1
- package/public/dist/assets/packet-YPE3B663-SclsNpNx.js +1 -0
- package/public/dist/assets/{page-shell-LF7vVVfG.js → page-shell-GpE8A-FA.js} +1 -1
- package/public/dist/assets/pie-LRSECV5Y-CF43gDO6.js +1 -0
- package/public/dist/assets/{pieDiagram-4H26LBE5-Dtwtlr0z.js → pieDiagram-4H26LBE5-ChOXpmZ5.js} +1 -1
- package/public/dist/assets/{pug-DHfNwv1w.js → pug-C8nPBT90.js} +1 -1
- package/public/dist/assets/{quadrantDiagram-W4KKPZXB-CAFUbaV6.js → quadrantDiagram-W4KKPZXB-lbpz07e4.js} +1 -1
- package/public/dist/assets/radar-GUYGQ44K-BsylzLX_.js +1 -0
- package/public/dist/assets/{render-BDso7Yb5.js → render-A--hkukv.js} +2 -2
- package/public/dist/assets/{requirementDiagram-4Y6WPE33-CvBM4AjK.js → requirementDiagram-4Y6WPE33-CrApoE_l.js} +1 -1
- package/public/dist/assets/{sankeyDiagram-5OEKKPKP-cordQgRs.js → sankeyDiagram-5OEKKPKP-Df1lU-mT.js} +1 -1
- package/public/dist/assets/{sequenceDiagram-3UESZ5HK-DDAqRdga.js → sequenceDiagram-3UESZ5HK-CelQN5jY.js} +1 -1
- package/public/dist/assets/settings-3ZdoKHIf.js +56 -0
- package/public/dist/assets/settings-C6Pku2GC.js +1 -0
- package/public/dist/assets/{settings-core-BxuFkt4a.js → settings-core-CQe1uP6x.js} +17 -17
- package/public/dist/assets/settings-core-DqwLJkgP.js +1 -0
- package/public/dist/assets/settings-types-DPhhM-cj.js +1 -0
- package/public/dist/assets/{sidebar-BNT58qR0.js → sidebar-DxFp_449.js} +3 -3
- package/public/dist/assets/{skills-CwRBcm3m.js → skills-BU4q8Q8n.js} +1 -1
- package/public/dist/assets/skills-x2gH-1Ry.js +1 -0
- package/public/dist/assets/{slash-commands-cm0U58n7.js → slash-commands-BiXOgZ5B.js} +1 -1
- package/public/dist/assets/slash-commands-s8eR7Kd1.js +1 -0
- package/public/dist/assets/{stateDiagram-AJRCARHV-DUaoSRgZ.js → stateDiagram-AJRCARHV-CeyXWXrg.js} +1 -1
- package/public/dist/assets/stateDiagram-v2-BHNVJYJU-Bhb8zTjh.js +1 -0
- package/public/dist/assets/{timeline-definition-PNZ67QCA-D85QNy9b.js → timeline-definition-PNZ67QCA-DP0lPzQ_.js} +1 -1
- package/public/dist/assets/{trace-drawer-BuwO4m2P.js → trace-drawer-2BTQCor6.js} +1 -1
- package/public/dist/assets/treeView-BLDUP644-DHq0vQpf.js +1 -0
- package/public/dist/assets/treemap-LRROVOQU-vKngXIla.js +1 -0
- package/public/dist/assets/ui-CB0L33o0.js +1 -0
- package/public/dist/assets/{ui-C-LHMki1.js → ui-Csy42uNW.js} +1 -1
- package/public/dist/assets/{vennDiagram-CIIHVFJN-CQSILdx8.js → vennDiagram-CIIHVFJN-WB9mzv1f.js} +1 -1
- package/public/dist/assets/wardley-L42UT6IY-B1jQOSA5.js +1 -0
- package/public/dist/assets/{wardleyDiagram-YWT4CUSO-BZEVMlJ4.js → wardleyDiagram-YWT4CUSO-CapVnCz5.js} +1 -1
- package/public/dist/assets/{wiki-link-suggestions-Dp6kBQVu.js → wiki-link-suggestions-cvpqJp6c.js} +1 -1
- package/public/dist/assets/{xychartDiagram-2RQKCTM6-C8573Tgs.js → xychartDiagram-2RQKCTM6-DduDB3Cd.js} +1 -1
- package/public/dist/index.html +1 -1
- package/public/dist/manager/index.html +1 -1
- package/public/js/features/settings-cli-status.ts +11 -5
- package/public/js/features/settings-types.ts +35 -3
- package/public/manager/src/settings/cli-status-polling.ts +84 -0
- package/public/manager/src/settings/pages/Agent.tsx +111 -16
- package/scripts/install-officecli.ps1 +38 -2
- package/scripts/install.ps1 +1 -1
- package/public/dist/assets/Agent-nMPZsMfN.js +0 -1
- package/public/dist/assets/MarkdownRenderer-DZVh_xX2.js +0 -1
- package/public/dist/assets/Permissions-DNT0TxYL.js +0 -1
- package/public/dist/assets/architecture-7EHR7CIX-D-6Nx315.js +0 -1
- package/public/dist/assets/bgtask-badge-B2jUZ5mC.js +0 -1
- package/public/dist/assets/channel-ByNDsZsH.js +0 -1
- package/public/dist/assets/chunk-55IACEB6-CQFLXxVc.js +0 -1
- package/public/dist/assets/chunk-QZHKN3VN-Becu19mF.js +0 -1
- package/public/dist/assets/chunk-WU5MYG2G-CkoHFn0F.js +0 -1
- package/public/dist/assets/classDiagram-4FO5ZUOK-DVGoKviY.js +0 -1
- package/public/dist/assets/classDiagram-v2-Q7XG4LA2-BIZeptY-.js +0 -1
- package/public/dist/assets/dist-BmXnOAlo.js +0 -1
- package/public/dist/assets/dist-DLY5I6dK.js +0 -1
- package/public/dist/assets/dist-DPHcMCqI.js +0 -1
- package/public/dist/assets/dist-xHOEvyuU.js +0 -1
- package/public/dist/assets/eventmodeling-FCH6USID-BB1OVDLb.js +0 -1
- package/public/dist/assets/gitGraph-WXDBUCRP-DAWTa5Fn.js +0 -1
- package/public/dist/assets/iframe-renderer-D7PB_yrC.js +0 -1
- package/public/dist/assets/info-J43DQDTF-C530y5-j.js +0 -1
- package/public/dist/assets/javascript-DbM-pSY-.js +0 -1
- package/public/dist/assets/memory-rsKN0aa2.js +0 -1
- package/public/dist/assets/mermaid-loader-Bd9rYyxD.js +0 -1
- package/public/dist/assets/mermaid.core-TSG49mwm.js +0 -1
- package/public/dist/assets/message-history-BttkY77h.js +0 -1
- package/public/dist/assets/packet-YPE3B663-BHcxn4sy.js +0 -1
- package/public/dist/assets/pie-LRSECV5Y-DjigSia_.js +0 -1
- package/public/dist/assets/radar-GUYGQ44K-DPCrmsHJ.js +0 -1
- package/public/dist/assets/settings-CqnIqxkG.js +0 -56
- package/public/dist/assets/settings-core-CdZ7oKhM.js +0 -1
- package/public/dist/assets/settings-pPMHNs0G.js +0 -1
- package/public/dist/assets/skills-DiVoaVdS.js +0 -1
- package/public/dist/assets/slash-commands-Bx4saHwR.js +0 -1
- package/public/dist/assets/stateDiagram-v2-BHNVJYJU-BAesfdhr.js +0 -1
- package/public/dist/assets/treeView-BLDUP644-DmufUMul.js +0 -1
- package/public/dist/assets/treemap-LRROVOQU-Cg48uw_D.js +0 -1
- package/public/dist/assets/ui-XPQDPe-5.js +0 -1
- package/public/dist/assets/wardley-L42UT6IY-QZOEXU7f.js +0 -1
- /package/public/dist/assets/{agent-meta-Y3DE6sxh.js → agent-meta-Bl-Q0EgC.js} +0 -0
- /package/public/dist/assets/{api-B25zNNFJ.js → api-FOqKQ9fm.js} +0 -0
- /package/public/dist/assets/{apl-2tE96F_Y.js → apl-CYLd9I-9.js} +0 -0
- /package/public/dist/assets/{asciiarmor-ynSKiC17.js → asciiarmor-7YwhfGDq.js} +0 -0
- /package/public/dist/assets/{asn1-CfqO1VY8.js → asn1-BlhHp3qx.js} +0 -0
- /package/public/dist/assets/{asterisk-DSiRJoqT.js → asterisk-Q0-IBwUt.js} +0 -0
- /package/public/dist/assets/{brainfuck-DTcanv-8.js → brainfuck-CM8jf4Gu.js} +0 -0
- /package/public/dist/assets/{chunk-AGHRB4JF-BXLzSehp.js → chunk-AGHRB4JF-Cdp9MZGh.js} +0 -0
- /package/public/dist/assets/{chunk-NNHCCRGN-D69GtSOc.js → chunk-NNHCCRGN-ChI2WAS0.js} +0 -0
- /package/public/dist/assets/{clike-qn72CMAj.js → clike-BcV5UqGE.js} +0 -0
- /package/public/dist/assets/{clojure-m8yDiYVc.js → clojure-XHu9GAjV.js} +0 -0
- /package/public/dist/assets/{cmake-4AHAWHiF.js → cmake-DhPsEu0W.js} +0 -0
- /package/public/dist/assets/{cobol-CxxJP5eX.js → cobol-BEekiT-v.js} +0 -0
- /package/public/dist/assets/{coffeescript-BAB3zi48.js → coffeescript-Bgk4ZVWF.js} +0 -0
- /package/public/dist/assets/{commonlisp-BPbWuAds.js → commonlisp-Dw4PRJwx.js} +0 -0
- /package/public/dist/assets/{crystal-CGuSsWYR.js → crystal-CJ-iCD_G.js} +0 -0
- /package/public/dist/assets/{css-DszbR74r.js → css-BDUaiSMY.js} +0 -0
- /package/public/dist/assets/{cypher-GUnmv522.js → cypher-CJ05ZgAu.js} +0 -0
- /package/public/dist/assets/{cytoscape.esm-D_XyYSBG.js → cytoscape.esm-PBXWcYR1.js} +0 -0
- /package/public/dist/assets/{d-Cfm0cznj.js → d-BfHF1VVF.js} +0 -0
- /package/public/dist/assets/{desktop-bridge-CvdhnJQo.js → desktop-bridge-DtydAvqu.js} +0 -0
- /package/public/dist/assets/{diff-C6rPA7NX.js → diff-BVcHwfdB.js} +0 -0
- /package/public/dist/assets/{dist-AgQwqBLq.js → dist-BbhtVnRz.js} +0 -0
- /package/public/dist/assets/{dtd-Dxh5tS6M.js → dtd-Bg0TgBY9.js} +0 -0
- /package/public/dist/assets/{dylan-BdIVFR1j.js → dylan-BQ0i5j3T.js} +0 -0
- /package/public/dist/assets/{ebnf-iU-8xYFu.js → ebnf-QSFUkOiT.js} +0 -0
- /package/public/dist/assets/{ecl-DjbzOHI6.js → ecl-oXh4vhiy.js} +0 -0
- /package/public/dist/assets/{eiffel-B2ID8LZ3.js → eiffel-S15DDWzw.js} +0 -0
- /package/public/dist/assets/{elm-B6vPcfMj.js → elm-B746ZFPi.js} +0 -0
- /package/public/dist/assets/{erlang-nDQwRdZV.js → erlang-GRIYhTbY.js} +0 -0
- /package/public/dist/assets/{fcl-Bf86o55I.js → fcl-DjQMeb0v.js} +0 -0
- /package/public/dist/assets/{folder-drag-payload-Bhln9Mk2.js → folder-drag-payload-CJ0dxhZa.js} +0 -0
- /package/public/dist/assets/{forth-CeQJji0n.js → forth-DNnBFTm6.js} +0 -0
- /package/public/dist/assets/{fortran-Dm_CqDsH.js → fortran-yg6K9z9n.js} +0 -0
- /package/public/dist/assets/{gas-e3EfgE3p.js → gas-fbsH19hy.js} +0 -0
- /package/public/dist/assets/{gherkin-Dn_7tSzg.js → gherkin-BCy9haeT.js} +0 -0
- /package/public/dist/assets/{groovy-LaKuGRkK.js → groovy-Cm4gdIYU.js} +0 -0
- /package/public/dist/assets/{haskell-D9nNX9Mr.js → haskell-Dq28dVw2.js} +0 -0
- /package/public/dist/assets/{haxe-Rp176QXJ.js → haxe-BrZpr4Ca.js} +0 -0
- /package/public/dist/assets/{http-BOeYLbuM.js → http-B3zr0y0o.js} +0 -0
- /package/public/dist/assets/{idl-DHv3vdme.js → idl-C9CL9hdG.js} +0 -0
- /package/public/dist/assets/{javascript-Dk2fbl1a.js → javascript-DD7UxIxH.js} +0 -0
- /package/public/dist/assets/{jsx-runtime-gFMgZ0TQ.js → jsx-runtime-CYoNlHAD.js} +0 -0
- /package/public/dist/assets/{julia-D7CKCk5I.js → julia-CjwfSXBk.js} +0 -0
- /package/public/dist/assets/{livescript-gRbr9rhj.js → livescript-vRjI6jFU.js} +0 -0
- /package/public/dist/assets/{lua-CgZ_7bxf.js → lua-CxVmDfKg.js} +0 -0
- /package/public/dist/assets/{mathematica-B6bTyoab.js → mathematica-DJZPFt8k.js} +0 -0
- /package/public/dist/assets/{mbox-C8oQj1cJ.js → mbox-CxBBnlIA.js} +0 -0
- /package/public/dist/assets/{mirc-v6L6kZuh.js → mirc-CBWc0vcU.js} +0 -0
- /package/public/dist/assets/{mllike-CWu4RdWO.js → mllike-DYddHpeS.js} +0 -0
- /package/public/dist/assets/{modelica-B3NBpX1d.js → modelica-B94rrYMn.js} +0 -0
- /package/public/dist/assets/{mscgen-C8u7qRYw.js → mscgen-D0PO0iPT.js} +0 -0
- /package/public/dist/assets/{mumps-DHjVG4PS.js → mumps-BdPrWvs5.js} +0 -0
- /package/public/dist/assets/{nginx-BMt87X3t.js → nginx-C7cLiM4x.js} +0 -0
- /package/public/dist/assets/{notes-graph-settings-BgNrT_58.js → notes-graph-settings-Cl4lMj-A.js} +0 -0
- /package/public/dist/assets/{ntriples-C8U-Jud2.js → ntriples-DLMpvgb1.js} +0 -0
- /package/public/dist/assets/{octave-Bq37AoFm.js → octave-DeJPElAr.js} +0 -0
- /package/public/dist/assets/{oz-D6HxSRn3.js → oz-4dtXWqwe.js} +0 -0
- /package/public/dist/assets/{pascal-BBqiAVg6.js → pascal-TdeXcL-o.js} +0 -0
- /package/public/dist/assets/{path-utils-LsJeDCKF.js → path-utils-CHwADH-r.js} +0 -0
- /package/public/dist/assets/{perl-sHANlXjx.js → perl-DfpfXWOH.js} +0 -0
- /package/public/dist/assets/{pig-Cufgew--.js → pig-xQ4essgV.js} +0 -0
- /package/public/dist/assets/{powershell--Q4mDip6.js → powershell-Dfw2t4-B.js} +0 -0
- /package/public/dist/assets/{properties-DoVpJ-kT.js → properties-CrJLOvU2.js} +0 -0
- /package/public/dist/assets/{protobuf-B5OiV2Zv.js → protobuf-BYv78GYU.js} +0 -0
- /package/public/dist/assets/{provider-icons-VDfahiUp.js → provider-icons-CXA2mnPO.js} +0 -0
- /package/public/dist/assets/{puppet-Ce_CFfqW.js → puppet-DnsvBfcg.js} +0 -0
- /package/public/dist/assets/{python-pK7Wt6QH.js → python-mfoZJSDM.js} +0 -0
- /package/public/dist/assets/{q-Dd3Ltku0.js → q-BrTIu4PU.js} +0 -0
- /package/public/dist/assets/{r-CsX__2f0.js → r-FO7GgXB8.js} +0 -0
- /package/public/dist/assets/{rough.esm--LLpAgPj.js → rough.esm-DeGVhNS9.js} +0 -0
- /package/public/dist/assets/{rpm-D78AjDAl.js → rpm-D8Wbdep5.js} +0 -0
- /package/public/dist/assets/{ruby-D_-KI498.js → ruby-Cg1fwXaw.js} +0 -0
- /package/public/dist/assets/{sas-D-GUPiy4.js → sas-Ch1GEx-n.js} +0 -0
- /package/public/dist/assets/{scheme-DF9WwQDv.js → scheme-DGFmPoR2.js} +0 -0
- /package/public/dist/assets/{settings-client-CjbBShxm.js → settings-client-D9KY2Ufl.js} +0 -0
- /package/public/dist/assets/{shell-BTUwbV-w.js → shell-BBoIO9l0.js} +0 -0
- /package/public/dist/assets/{sieve--Z-EbGZo.js → sieve-8oEe6gDx.js} +0 -0
- /package/public/dist/assets/{simple-mode-BUow4bpn.js → simple-mode-BNw0K2rL.js} +0 -0
- /package/public/dist/assets/{smalltalk-C2YIwVx3.js → smalltalk-ChbxX23N.js} +0 -0
- /package/public/dist/assets/{solr-CYVq4fbf.js → solr-BwGyzi2H.js} +0 -0
- /package/public/dist/assets/{sparql-Ccd4fsFv.js → sparql-D9wgprRx.js} +0 -0
- /package/public/dist/assets/{spreadsheet-DW0WgMrS.js → spreadsheet-BySehl32.js} +0 -0
- /package/public/dist/assets/{sql-C71Zp6qn.js → sql-B6Phvk1R.js} +0 -0
- /package/public/dist/assets/{stex-CKuX0g_6.js → stex-32iK7T_9.js} +0 -0
- /package/public/dist/assets/{stylus-CBH8s0NO.js → stylus-C689wDNM.js} +0 -0
- /package/public/dist/assets/{swift-CfZoxKRA.js → swift-DZwxTp-L.js} +0 -0
- /package/public/dist/assets/{tcl-D5MGbeQu.js → tcl-BSOjIY_8.js} +0 -0
- /package/public/dist/assets/{textile-DJ3U30FW.js → textile-xOWO1SH7.js} +0 -0
- /package/public/dist/assets/{tiddlywiki-_fe1dHUq.js → tiddlywiki-B8jhOxrf.js} +0 -0
- /package/public/dist/assets/{tiki-Dd1udTrQ.js → tiki-OG7n6UAo.js} +0 -0
- /package/public/dist/assets/{toml-xpw8pqjz.js → toml-DkxT-aUR.js} +0 -0
- /package/public/dist/assets/{troff-CgWiec8m.js → troff-vE5gOX7Y.js} +0 -0
- /package/public/dist/assets/{ttcn-CSwmFrer.js → ttcn-CPOduycD.js} +0 -0
- /package/public/dist/assets/{ttcn-cfg-B5HVIC6z.js → ttcn-cfg-DmA__-R_.js} +0 -0
- /package/public/dist/assets/{turtle-Cl_SuWQk.js → turtle-CEzrJHdY.js} +0 -0
- /package/public/dist/assets/{vb-BT131bSf.js → vb-Cii5IQTv.js} +0 -0
- /package/public/dist/assets/{vbscript-D6S8_XkU.js → vbscript-DcZWGZ_S.js} +0 -0
- /package/public/dist/assets/{velocity-9HkI645n.js → velocity-BEag7EnK.js} +0 -0
- /package/public/dist/assets/{vendor-utils-DJY0EWnQ.js → vendor-utils-BK07iQND.js} +0 -0
- /package/public/dist/assets/{verilog-BzMguKeI.js → verilog-DMw8DKoT.js} +0 -0
- /package/public/dist/assets/{vhdl-bHScWzT1.js → vhdl-M4wLPuJt.js} +0 -0
- /package/public/dist/assets/{w3c-keyname-a_sRwNLm.js → w3c-keyname-hgmz1BF7.js} +0 -0
- /package/public/dist/assets/{webidl-CbgaVHNS.js → webidl-CjehKbx5.js} +0 -0
- /package/public/dist/assets/{wiki-link-resolver-DyFzBTIQ.js → wiki-link-resolver-N9fDy5zP.js} +0 -0
- /package/public/dist/assets/{xquery-DWZPmAiC.js → xquery-CYbd_YmJ.js} +0 -0
- /package/public/dist/assets/{yacas-CEdW4z4K.js → yacas-ClBNsli2.js} +0 -0
- /package/public/dist/assets/{z80-CMH3qxNg.js → z80-nGsPT_fm.js} +0 -0
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// bursty tool events would otherwise burn the budget and get throttled.
|
|
11
11
|
// - Best-effort. A failed status post/edit must never break the answer path.
|
|
12
12
|
import { slackApi, describeSlackError } from './api.js';
|
|
13
|
+
import { startDraftStream } from '../messaging/draft-stream.js';
|
|
13
14
|
import { toMrkdwn } from './format.js';
|
|
14
15
|
/** Minimum gap between chat.update calls for one run (Slack tier limit). */
|
|
15
16
|
const EDIT_INTERVAL_MS = 1200;
|
|
@@ -33,66 +34,53 @@ export function statusFromToolEvent(data, fallback) {
|
|
|
33
34
|
}
|
|
34
35
|
export async function startSlackProgress(token, target, initialText, options = {}) {
|
|
35
36
|
const fetchOpts = options.fetchImpl ? { fetchImpl: options.fetchImpl } : {};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
flushTimer = null;
|
|
62
|
-
void flush().finally(() => { if (pendingText !== null)
|
|
63
|
-
schedule(); });
|
|
64
|
-
}, wait);
|
|
65
|
-
// A pending edit must never hold the process open.
|
|
66
|
-
flushTimer.unref?.();
|
|
37
|
+
const transport = {
|
|
38
|
+
async post(text) {
|
|
39
|
+
const result = await slackApi(token, 'chat.postMessage', {
|
|
40
|
+
channel: target.targetId,
|
|
41
|
+
text,
|
|
42
|
+
...(target.threadId ? { thread_ts: target.threadId } : {}),
|
|
43
|
+
}, fetchOpts);
|
|
44
|
+
return result.ok && result.data?.ts ? result.data.ts : null;
|
|
45
|
+
},
|
|
46
|
+
async edit(ts, text) {
|
|
47
|
+
const result = await slackApi(token, 'chat.update', { channel: target.targetId, ts, text }, fetchOpts);
|
|
48
|
+
if (!result.ok) {
|
|
49
|
+
throw Object.assign(new Error(result.error || 'chat_update_failed'), {
|
|
50
|
+
slackData: result.data,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
async remove(ts) {
|
|
55
|
+
const result = await slackApi(token, 'chat.delete', { channel: target.targetId, ts }, fetchOpts);
|
|
56
|
+
if (!result.ok) {
|
|
57
|
+
throw Object.assign(new Error(result.error || 'chat_delete_failed'), {
|
|
58
|
+
slackData: result.data,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
},
|
|
67
62
|
};
|
|
63
|
+
const stream = await startDraftStream(transport, toMrkdwn(truncateStatus(initialText)), {
|
|
64
|
+
minEditIntervalMs: EDIT_INTERVAL_MS,
|
|
65
|
+
maxChars: MAX_STATUS_LEN,
|
|
66
|
+
...options.draftClock,
|
|
67
|
+
onError(operation, error) {
|
|
68
|
+
const typed = error;
|
|
69
|
+
describeSlackError(typed.message || `${operation}_failed`, typed.slackData);
|
|
70
|
+
},
|
|
71
|
+
});
|
|
68
72
|
return {
|
|
69
73
|
update(text) {
|
|
70
|
-
if (done || !messageTs)
|
|
71
|
-
return;
|
|
72
74
|
const next = truncateStatus(text);
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
pendingText = next;
|
|
76
|
-
schedule();
|
|
75
|
+
if (next)
|
|
76
|
+
stream.update(toMrkdwn(next));
|
|
77
77
|
},
|
|
78
78
|
async finish() {
|
|
79
|
-
done = true;
|
|
80
|
-
pendingText = null;
|
|
81
|
-
if (flushTimer) {
|
|
82
|
-
clearTimeout(flushTimer);
|
|
83
|
-
flushTimer = null;
|
|
84
|
-
}
|
|
85
|
-
if (!messageTs)
|
|
86
|
-
return;
|
|
87
|
-
const ts = messageTs;
|
|
88
|
-
messageTs = null;
|
|
89
79
|
// The answer arrives as its own message, so the status placeholder
|
|
90
80
|
// is deleted rather than left as a stale "working…" line.
|
|
91
|
-
|
|
92
|
-
if (!result.ok)
|
|
93
|
-
describeSlackError(result.error || 'chat_delete_failed', result.data);
|
|
81
|
+
await stream.discard();
|
|
94
82
|
},
|
|
95
|
-
ts() { return
|
|
83
|
+
ts() { return stream.handle(); },
|
|
96
84
|
};
|
|
97
85
|
}
|
|
98
86
|
//# sourceMappingURL=progress.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/slack/progress.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,uEAAuE;AACvE,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,EAAE;AACF,gBAAgB;AAChB,4EAA4E;AAC5E,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/slack/progress.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,uEAAuE;AACvE,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,EAAE;AACF,gBAAgB;AAChB,4EAA4E;AAC5E,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAgD,MAAM,8BAA8B,CAAC;AAE9G,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,4EAA4E;AAC5E,MAAM,cAAc,GAAG,GAAG,CAAC;AAS3B,MAAM,UAAU,cAAc,CAAC,IAAY;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC;AAC1F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B,EAAE,QAAgB;IAC/E,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,IAAI,QAAQ,CAAC;IAC/B,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,KAAa,EACb,MAAoB,EACpB,WAAmB,EACnB,UAGI,EAAE;IAEN,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,SAAS,GAAmB;QAC9B,KAAK,CAAC,IAAI,CAAC,IAAI;YACX,MAAM,MAAM,GAAG,MAAM,QAAQ,CACzB,KAAK,EACL,kBAAkB,EAClB;gBACI,OAAO,EAAE,MAAM,CAAC,QAAQ;gBACxB,IAAI;gBACJ,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7D,EACD,SAAS,CACZ,CAAC;YACF,OAAO,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAChE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI;YACf,MAAM,MAAM,GAAG,MAAM,QAAQ,CACzB,KAAK,EAAE,aAAa,EACpB,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EACtC,SAAS,CACZ,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC,EAAE;oBACjE,SAAS,EAAE,MAAM,CAAC,IAAI;iBACzB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE;YACX,MAAM,MAAM,GAAG,MAAM,QAAQ,CACzB,KAAK,EAAE,aAAa,EACpB,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,EAChC,SAAS,CACZ,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,oBAAoB,CAAC,EAAE;oBACjE,SAAS,EAAE,MAAM,CAAC,IAAI;iBACzB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;KACJ,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACjC,SAAS,EACT,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,EACrC;QACI,iBAAiB,EAAE,gBAAgB;QACnC,QAAQ,EAAE,cAAc;QACxB,GAAG,OAAO,CAAC,UAAU;QACrB,OAAO,CAAC,SAAS,EAAE,KAAK;YACpB,MAAM,KAAK,GAAG,KAAwD,CAAC;YACvE,kBAAkB,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,SAAS,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAChF,CAAC;KACJ,CACJ,CAAC;IACF,OAAO;QACH,MAAM,CAAC,IAAY;YACf,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,IAAI;gBAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,MAAM;YACR,mEAAmE;YACnE,0DAA0D;YAC1D,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QACD,EAAE,KAAoB,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;KAClD,CAAC;AACN,CAAC"}
|
|
@@ -78,6 +78,94 @@ export function isThreadParticipated(channel, threadTs) {
|
|
|
78
78
|
return false;
|
|
79
79
|
return load().has(threadKey(channel, threadTs));
|
|
80
80
|
}
|
|
81
|
+
/** key -> current owner and whether history was actually injected. */
|
|
82
|
+
const prefetchClaimed = new Map();
|
|
83
|
+
const PREFETCH_CLAIM_CAP = 500;
|
|
84
|
+
let prefetchToken = 0;
|
|
85
|
+
let prefetchUse = 0;
|
|
86
|
+
function prefetchKey(channel, threadTs, owner) {
|
|
87
|
+
return `${threadKey(channel, threadTs)}:${owner.global}:${owner.scope}`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Claim the one-time prefetch for a thread.
|
|
91
|
+
*
|
|
92
|
+
* Returns a token on success and 0 when the thread is already claimed.
|
|
93
|
+
* Synchronous test-and-set: the caller runs it before any `await`, so two
|
|
94
|
+
* envelopes arriving in the same tick cannot both win.
|
|
95
|
+
*
|
|
96
|
+
* The token exists because releasing is asynchronous. Without it a late
|
|
97
|
+
* release from an abandoned attempt would delete whichever claim happened to
|
|
98
|
+
* hold the key by then — the classic ABA: A claims, A times out and releases,
|
|
99
|
+
* B claims, A's straggler releases B's claim, and the thread gets prefetched
|
|
100
|
+
* twice.
|
|
101
|
+
*/
|
|
102
|
+
export function claimThreadPrefetch(channel, threadTs, owner) {
|
|
103
|
+
if (!channel || !threadTs)
|
|
104
|
+
return 0;
|
|
105
|
+
const key = prefetchKey(channel, threadTs, owner);
|
|
106
|
+
const existing = prefetchClaimed.get(key);
|
|
107
|
+
if (existing) {
|
|
108
|
+
existing.lastUsed = ++prefetchUse;
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
if (prefetchClaimed.size >= PREFETCH_CLAIM_CAP) {
|
|
112
|
+
// Active owners are singleflight locks, not cache entries. Evicting one
|
|
113
|
+
// lets another envelope claim the same live thread and inject history
|
|
114
|
+
// twice. Only completed claims may give ground under pressure.
|
|
115
|
+
let removed = 0;
|
|
116
|
+
const target = Math.floor(PREFETCH_CLAIM_CAP / 2);
|
|
117
|
+
const completed = [...prefetchClaimed.entries()]
|
|
118
|
+
.filter(([, claim]) => claim.committed)
|
|
119
|
+
.sort((a, b) => a[1].lastUsed - b[1].lastUsed);
|
|
120
|
+
for (const [stale] of completed) {
|
|
121
|
+
prefetchClaimed.delete(stale);
|
|
122
|
+
removed += 1;
|
|
123
|
+
if (removed >= target)
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
// All bounded slots can legitimately be in flight. Decline rather than
|
|
127
|
+
// queue or violate singleflight; a later message can retry after one
|
|
128
|
+
// owner commits or releases.
|
|
129
|
+
if (prefetchClaimed.size >= PREFETCH_CLAIM_CAP)
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
const token = ++prefetchToken;
|
|
133
|
+
prefetchClaimed.set(key, { token, committed: false, lastUsed: ++prefetchUse });
|
|
134
|
+
return token;
|
|
135
|
+
}
|
|
136
|
+
/** Mark that this owner actually injected history; completed claims are evictable. */
|
|
137
|
+
export function commitThreadPrefetch(channel, threadTs, owner, token) {
|
|
138
|
+
if (!channel || !threadTs || !token)
|
|
139
|
+
return false;
|
|
140
|
+
const claim = prefetchClaimed.get(prefetchKey(channel, threadTs, owner));
|
|
141
|
+
if (!claim || claim.token !== token)
|
|
142
|
+
return false;
|
|
143
|
+
claim.committed = true;
|
|
144
|
+
claim.lastUsed = ++prefetchUse;
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Give a claim back when no history was actually injected.
|
|
149
|
+
*
|
|
150
|
+
* Without this a failed or skipped first attempt would silently consume the
|
|
151
|
+
* thread's only chance: every later message would see the thread as already
|
|
152
|
+
* prefetched and the agent would never receive the earlier conversation.
|
|
153
|
+
*
|
|
154
|
+
* Only the CURRENT owner may release. A stale token is a no-op.
|
|
155
|
+
*/
|
|
156
|
+
export function releaseThreadPrefetch(channel, threadTs, owner, token) {
|
|
157
|
+
if (!channel || !threadTs || !token)
|
|
158
|
+
return;
|
|
159
|
+
const key = prefetchKey(channel, threadTs, owner);
|
|
160
|
+
if (prefetchClaimed.get(key)?.token !== token)
|
|
161
|
+
return;
|
|
162
|
+
prefetchClaimed.delete(key);
|
|
163
|
+
}
|
|
164
|
+
export function resetThreadPrefetchClaims() {
|
|
165
|
+
prefetchClaimed.clear();
|
|
166
|
+
prefetchToken = 0;
|
|
167
|
+
prefetchUse = 0;
|
|
168
|
+
}
|
|
81
169
|
/** Test hook: point the store at a temp file and drop the cache. */
|
|
82
170
|
export function resetThreadTrackerForTest(filePath) {
|
|
83
171
|
threads = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-tracker.js","sourceRoot":"","sources":["../../../src/slack/thread-tracker.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,iEAAiE;AACjE,0DAA0D;AAC1D,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,yEAAyE;AACzE,6DAA6D;AAE7D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"thread-tracker.js","sourceRoot":"","sources":["../../../src/slack/thread-tracker.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,iEAAiE;AACjE,0DAA0D;AAC1D,8CAA8C;AAC9C,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,yEAAyE;AACzE,6DAA6D;AAE7D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,+DAA+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,IAAI,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;AAC1D,8EAA8E;AAC9E,mEAAmE;AACnE,IAAI,OAAO,GAA+B,IAAI,CAAC;AAE/C,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,QAAgB;IACvD,OAAO,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;AACpC,CAAC;AAED,SAAS,IAAI;IACT,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACxD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC,CAAC,qEAAqE,CAAC,CAAC;IACjF,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,IAAI,CAAC,GAAwB;IAClC,MAAM,GAAG,GAAG,SAAS,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,qEAAqE;QACrE,mEAAmE;QACnE,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;IAC9E,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,QAAgB;IACpE,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,OAAO;IAClC,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,GAAG,CAAC,IAAI,GAAG,iBAAiB,EAAE,CAAC;QAC/B,qEAAqE;QACrE,+DAA+D;QAC/D,oEAAoE;QACpE,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,yEAAyE;IACzE,8CAA8C;IAC9C,IAAI,KAAK,IAAI,OAAO;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,QAAgB;IAClE,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC;AAeD,sEAAsE;AACtE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;AACzD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,IAAI,aAAa,GAAG,CAAC,CAAC;AACtB,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,SAAS,WAAW,CAAC,OAAe,EAAE,QAAgB,EAAE,KAAwB;IAC5E,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAC/B,OAAe,EAAE,QAAgB,EAAE,KAAwB;IAE3D,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACX,QAAQ,CAAC,QAAQ,GAAG,EAAE,WAAW,CAAC;QAClC,OAAO,CAAC,CAAC;IACb,CAAC;IACD,IAAI,eAAe,CAAC,IAAI,IAAI,kBAAkB,EAAE,CAAC;QAC7C,wEAAwE;QACxE,sEAAsE;QACtE,+DAA+D;QAC/D,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC;aAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;aACtC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;YAC9B,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,CAAC;YACb,IAAI,OAAO,IAAI,MAAM;gBAAE,MAAM;QACjC,CAAC;QACD,uEAAuE;QACvE,qEAAqE;QACrE,6BAA6B;QAC7B,IAAI,eAAe,CAAC,IAAI,IAAI,kBAAkB;YAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,KAAK,GAAG,EAAE,aAAa,CAAC;IAC9B,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/E,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAChC,OAAe,EAAE,QAAgB,EAAE,KAAwB,EAAE,KAAa;IAE1E,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAClD,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,QAAQ,GAAG,EAAE,WAAW,CAAC;IAC/B,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACjC,OAAe,EAAE,QAAgB,EAAE,KAAwB,EAAE,KAAa;IAE1E,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK;QAAE,OAAO;IAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,KAAK;QAAE,OAAO;IACtD,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,yBAAyB;IACrC,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,aAAa,GAAG,CAAC,CAAC;IAClB,WAAW,GAAG,CAAC,CAAC;AACpB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,yBAAyB,CAAC,QAAiB;IACvD,OAAO,GAAG,IAAI,CAAC;IACf,SAAS,GAAG,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/src/telegram/bot.js
CHANGED
|
@@ -26,6 +26,8 @@ import { getLastActiveTarget, registerTransport, setLastActiveTarget, setLatestS
|
|
|
26
26
|
import { registerSendTransport, sendChannelOutput } from '../messaging/send.js';
|
|
27
27
|
import { escapeHtmlTg, createForwarderLifecycle, createTelegramForwarder, relayTelegramImages, } from './forwarder.js';
|
|
28
28
|
import { sendTelegramMarkdown } from './rich-message.js';
|
|
29
|
+
import { db } from '../core/db.js';
|
|
30
|
+
import { TelegramDurablePoller, TelegramUpdateOffsetStore } from './update-offset.js';
|
|
29
31
|
export { escapeHtmlTg, markdownToTelegramHtml, chunkTelegramMessage, createForwarderLifecycle, createTelegramForwarder, } from './forwarder.js';
|
|
30
32
|
// Re-exported from collect.ts (extracted in Phase B)
|
|
31
33
|
import { orchestrateAndCollect, orchestrateAndCollectData } from '../orchestrator/collect.js';
|
|
@@ -33,8 +35,8 @@ import { log } from '../core/logger.js';
|
|
|
33
35
|
export { orchestrateAndCollect };
|
|
34
36
|
import { startPendingElicitation, handleElicitationCallback, discardPendingElicitation, } from './elicitation-buttons.js';
|
|
35
37
|
import { redactOutboundPayload, redactOutboundText, logErrorText, userErrorText } from '../messaging/redact.js';
|
|
36
|
-
import { createSeenSet, DELIVERY_DEDUPE_TTL_MS } from '../messaging/dedupe.js';
|
|
37
38
|
import { sendWithRetryPolicy } from '../messaging/retry.js';
|
|
39
|
+
import { handleApprovalCommand, registerProductionTransport } from '../core/dispatch-approval-ingress.js';
|
|
38
40
|
// ─── State ───────────────────────────────────────────
|
|
39
41
|
export let telegramBot = null;
|
|
40
42
|
export const telegramActiveChatIds = new Set();
|
|
@@ -43,6 +45,8 @@ let tgInitLock = false;
|
|
|
43
45
|
let tg409RetryCount = 0;
|
|
44
46
|
const TG_MAX_RETRIES = 3;
|
|
45
47
|
let botUsername = null;
|
|
48
|
+
let telegramPoller = null;
|
|
49
|
+
const telegramFinalDeliveryFailures = new Set();
|
|
46
50
|
/**
|
|
47
51
|
* The bot's own user id, learned from getMe at startup.
|
|
48
52
|
*
|
|
@@ -50,6 +54,24 @@ let botUsername = null;
|
|
|
50
54
|
* the is_bot flag, which is why those are two separate checks.
|
|
51
55
|
*/
|
|
52
56
|
let botUserId = null;
|
|
57
|
+
export function setTelegramBotUserIdForTest(value) { botUserId = value; }
|
|
58
|
+
let telegramApprovalIngress = null;
|
|
59
|
+
function createTelegramPollingIngress() {
|
|
60
|
+
const transport = Object.freeze({ platform: 'telegram' });
|
|
61
|
+
registerProductionTransport(transport);
|
|
62
|
+
return transport;
|
|
63
|
+
}
|
|
64
|
+
export function handleTelegramUpdate(update, transport = telegramApprovalIngress) {
|
|
65
|
+
const message = update['message'];
|
|
66
|
+
const text = typeof message?.text === 'string' ? message.text : '';
|
|
67
|
+
const fromIdRaw = message?.from?.id;
|
|
68
|
+
const fromId = typeof fromIdRaw === 'number' ? fromIdRaw : undefined;
|
|
69
|
+
const approval = handleApprovalCommand(transport, {
|
|
70
|
+
...update,
|
|
71
|
+
__jawSelf: isSelfEcho({ fromId, isBot: message?.from?.is_bot, botUserId, allowBots: settings["telegram"]?.allowBots }),
|
|
72
|
+
}, text);
|
|
73
|
+
return approval.handled;
|
|
74
|
+
}
|
|
53
75
|
/**
|
|
54
76
|
* Whether an update should be dropped as our own output or another bot's.
|
|
55
77
|
*
|
|
@@ -66,8 +88,7 @@ export function isSelfEcho(input) {
|
|
|
66
88
|
return true;
|
|
67
89
|
return false;
|
|
68
90
|
}
|
|
69
|
-
|
|
70
|
-
const telegramSeenUpdates = createSeenSet(DELIVERY_DEDUPE_TTL_MS);
|
|
91
|
+
const telegramUpdateOffsets = new TelegramUpdateOffsetStore(db);
|
|
71
92
|
let targetReplyForwarderInstalled = false;
|
|
72
93
|
const telegramForwarderLifecycle = createForwarderLifecycle({
|
|
73
94
|
addListener: addBroadcastListener,
|
|
@@ -155,6 +176,16 @@ export async function shutdownTelegram() {
|
|
|
155
176
|
tgRetryTimer = null;
|
|
156
177
|
}
|
|
157
178
|
detachTelegramForwarder();
|
|
179
|
+
if (telegramPoller) {
|
|
180
|
+
const oldPoller = telegramPoller;
|
|
181
|
+
telegramPoller = null;
|
|
182
|
+
try {
|
|
183
|
+
await oldPoller.stop();
|
|
184
|
+
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
log.warn('[telegram:poller-stop]', logErrorText(e));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
158
189
|
if (!telegramBot)
|
|
159
190
|
return;
|
|
160
191
|
const old = telegramBot;
|
|
@@ -364,6 +395,11 @@ async function _initTelegramInner() {
|
|
|
364
395
|
await new Promise(r => setTimeout(r, 2000));
|
|
365
396
|
}
|
|
366
397
|
}
|
|
398
|
+
const stoppingPoller = telegramPoller?.stop().catch((e) => {
|
|
399
|
+
log.warn('[telegram:poller-stop]', logErrorText(e));
|
|
400
|
+
});
|
|
401
|
+
telegramPoller = null;
|
|
402
|
+
await stoppingPoller;
|
|
367
403
|
const envToken = process.env["TELEGRAM_TOKEN"];
|
|
368
404
|
if (envToken)
|
|
369
405
|
settings["telegram"].token = envToken;
|
|
@@ -467,38 +503,21 @@ async function _initTelegramInner() {
|
|
|
467
503
|
}
|
|
468
504
|
await next();
|
|
469
505
|
});
|
|
470
|
-
// Drop a redelivered update. grammY replays from the last committed offset
|
|
471
|
-
// after a reconnect, so the same update_id can arrive twice — and each one
|
|
472
|
-
// would start another agent run.
|
|
473
|
-
//
|
|
474
|
-
// Placed AFTER the allowlist and mention gates deliberately: dedupe
|
|
475
|
-
// upstream of them lets traffic we never process fill the seen-set — memory
|
|
476
|
-
// an outsider controls, and a budget an unmentioned group message can
|
|
477
|
-
// exhaust before a real one arrives. A duplicate that WOULD be processed
|
|
478
|
-
// passes both gates too, so nothing is lost by checking later.
|
|
479
|
-
bot.use(async (ctx, next) => {
|
|
480
|
-
const updateId = ctx.update?.update_id;
|
|
481
|
-
if (updateId !== undefined && telegramSeenUpdates.seen(String(updateId))) {
|
|
482
|
-
log.info(`[tg:duplicate] update_id=${updateId}`);
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
await next();
|
|
486
|
-
});
|
|
487
506
|
bot.command('start', (ctx) => ctx.reply(t('tg.connected', {}, currentLocale())));
|
|
488
507
|
bot.command('id', (ctx) => ctx.reply(`Chat ID: <code>${ctx.chat?.id ?? ''}</code>`, { parse_mode: 'HTML' }));
|
|
489
508
|
// Inline-keyboard elicitation answers (single_select fences → buttons).
|
|
490
509
|
bot.callbackQuery(/^elic:/, async (ctx) => {
|
|
491
510
|
const cbChatId = ctx.chat?.id;
|
|
492
511
|
if (!cbChatId) {
|
|
493
|
-
await ctx.answerCallbackQuery()
|
|
512
|
+
await ctx.answerCallbackQuery();
|
|
494
513
|
return;
|
|
495
514
|
}
|
|
496
515
|
const result = handleElicitationCallback(String(cbChatId), ctx.callbackQuery.data ?? '');
|
|
497
516
|
if (result.kind === 'stale') {
|
|
498
|
-
await ctx.answerCallbackQuery({ text: t('tg.elicitationExpired', {}, currentLocale()) })
|
|
517
|
+
await ctx.answerCallbackQuery({ text: t('tg.elicitationExpired', {}, currentLocale()) });
|
|
499
518
|
return;
|
|
500
519
|
}
|
|
501
|
-
await ctx.answerCallbackQuery({ text: redactOutboundText(result.ack) })
|
|
520
|
+
await ctx.answerCallbackQuery({ text: redactOutboundText(result.ack) });
|
|
502
521
|
// Best-effort: freeze the tapped question's keyboard so the choice reads as taken.
|
|
503
522
|
await ctx.editMessageReplyMarkup({ reply_markup: { inline_keyboard: [] } }).catch(() => { });
|
|
504
523
|
if (result.kind === 'complete') {
|
|
@@ -533,22 +552,54 @@ async function _initTelegramInner() {
|
|
|
533
552
|
};
|
|
534
553
|
if (result.action === 'queued') {
|
|
535
554
|
log.info(`[tg:queue] agent busy, queued (${result.pending} pending)`);
|
|
536
|
-
await ctx.reply(t('tg.queued', { count: result.pending }, currentLocale()));
|
|
537
555
|
// 큐 처리 후 응답을 이 채팅으로 전달 — requestId로 request-level 격리
|
|
538
556
|
const requestId = result.requestId;
|
|
539
|
-
const
|
|
540
|
-
|
|
557
|
+
const finalDeliveryControl = {};
|
|
558
|
+
const finalDelivery = new Promise((resolve, reject) => {
|
|
559
|
+
let timer;
|
|
560
|
+
let settled = false;
|
|
561
|
+
const cleanup = () => {
|
|
562
|
+
clearTimeout(timer);
|
|
541
563
|
removeBroadcastListener(queueHandler);
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
564
|
+
};
|
|
565
|
+
finalDeliveryControl.cancel = (reason) => {
|
|
566
|
+
if (settled)
|
|
567
|
+
return;
|
|
568
|
+
settled = true;
|
|
569
|
+
cleanup();
|
|
570
|
+
reject(reason);
|
|
571
|
+
};
|
|
572
|
+
const queueHandler = (type, data) => {
|
|
573
|
+
if (type !== 'orchestrate_done' || !data["text"] || data["origin"] !== 'telegram' || data["requestId"] !== requestId)
|
|
574
|
+
return;
|
|
575
|
+
if (settled)
|
|
576
|
+
return;
|
|
577
|
+
settled = true;
|
|
578
|
+
cleanup();
|
|
579
|
+
void sendTelegramMarkdown(ctx.api, chat.id, String(data["text"]), replyOptsOf(ctx))
|
|
580
|
+
.then(() => {
|
|
581
|
+
resolve();
|
|
582
|
+
void relayTelegramImages(bot, chat.id, String(data["text"]), responseTarget).catch(() => { });
|
|
583
|
+
void sendElicitationKeyboards(chat.id, data["elicitationSpecs"]).catch(() => { });
|
|
546
584
|
})
|
|
547
|
-
.catch(
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
585
|
+
.catch(reject);
|
|
586
|
+
};
|
|
587
|
+
timer = setTimeout(() => {
|
|
588
|
+
finalDeliveryControl.cancel?.(new Error('telegram_queue_delivery_timeout'));
|
|
589
|
+
}, 300000);
|
|
590
|
+
addBroadcastListener(queueHandler);
|
|
591
|
+
});
|
|
592
|
+
void finalDelivery.catch(() => { });
|
|
593
|
+
try {
|
|
594
|
+
await ctx.reply(t('tg.queued', { count: result.pending }, currentLocale()));
|
|
595
|
+
await finalDelivery;
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
finalDeliveryControl.cancel?.(error);
|
|
599
|
+
await finalDelivery.catch(() => { });
|
|
600
|
+
telegramFinalDeliveryFailures.add(ctx.update.update_id);
|
|
601
|
+
throw error;
|
|
602
|
+
}
|
|
552
603
|
return;
|
|
553
604
|
}
|
|
554
605
|
if (result.action === 'rejected') {
|
|
@@ -649,6 +700,7 @@ async function _initTelegramInner() {
|
|
|
649
700
|
} : null;
|
|
650
701
|
if (toolHandler)
|
|
651
702
|
addBroadcastListener(toolHandler);
|
|
703
|
+
let finalDeliveryStarted = false;
|
|
652
704
|
try {
|
|
653
705
|
const { text: collectedText, data: doneData } = await orchestrateAndCollectData(prompt, stripUndefined({
|
|
654
706
|
origin: 'telegram', chatId: chat.id, requestId: submitRequestId, _skipInsert: true,
|
|
@@ -667,10 +719,11 @@ async function _initTelegramInner() {
|
|
|
667
719
|
if (statusMsgId) {
|
|
668
720
|
ctx.api.deleteMessage(chat.id, statusMsgId).catch(() => { });
|
|
669
721
|
}
|
|
722
|
+
finalDeliveryStarted = true;
|
|
670
723
|
await sendTelegramMarkdown(ctx.api, chat.id, collectedText, replyOptsOf(ctx));
|
|
671
|
-
await relayTelegramImages(bot, chat.id, collectedText, responseTarget);
|
|
672
|
-
await sendElicitationKeyboards(chat.id, doneData["elicitationSpecs"]);
|
|
673
724
|
log.info(`[tg:out] ${chat.id}: ${redactOutboundText(collectedText).slice(0, 80)}`);
|
|
725
|
+
void relayTelegramImages(bot, chat.id, collectedText, responseTarget).catch(() => { });
|
|
726
|
+
void sendElicitationKeyboards(chat.id, doneData["elicitationSpecs"]).catch(() => { });
|
|
674
727
|
}
|
|
675
728
|
catch (err) {
|
|
676
729
|
clearInterval(typingInterval);
|
|
@@ -685,6 +738,8 @@ async function _initTelegramInner() {
|
|
|
685
738
|
}
|
|
686
739
|
log.error('[tg:error]', logErrorText(err));
|
|
687
740
|
await ctx.reply(`❌ Error: ${userErrorText(err)}`);
|
|
741
|
+
if (finalDeliveryStarted)
|
|
742
|
+
telegramFinalDeliveryFailures.add(ctx.update.update_id);
|
|
688
743
|
}
|
|
689
744
|
}
|
|
690
745
|
bot.on('message:text', async (ctx) => {
|
|
@@ -742,7 +797,7 @@ async function _initTelegramInner() {
|
|
|
742
797
|
}
|
|
743
798
|
return;
|
|
744
799
|
}
|
|
745
|
-
tgOrchestrate(ctx, text, text);
|
|
800
|
+
await tgOrchestrate(ctx, text, text);
|
|
746
801
|
});
|
|
747
802
|
bot.on('message:photo', async (ctx) => {
|
|
748
803
|
const photos = ctx.message.photo;
|
|
@@ -757,7 +812,7 @@ async function _initTelegramInner() {
|
|
|
757
812
|
}));
|
|
758
813
|
const filePath = saveUpload(dlResult["buffer"], `photo${dlResult["ext"]}`);
|
|
759
814
|
const prompt = buildMediaPrompt(filePath, caption);
|
|
760
|
-
tgOrchestrate(ctx, prompt, `${t('tg.imageCaption', { caption }, currentLocale())}`);
|
|
815
|
+
await tgOrchestrate(ctx, prompt, `${t('tg.imageCaption', { caption }, currentLocale())}`);
|
|
761
816
|
}
|
|
762
817
|
catch (err) {
|
|
763
818
|
log.error('[tg:photo:error]', logErrorText(err));
|
|
@@ -776,14 +831,14 @@ async function _initTelegramInner() {
|
|
|
776
831
|
}));
|
|
777
832
|
const filePath = saveUpload(dlResult["buffer"], doc.file_name || 'document');
|
|
778
833
|
const prompt = buildMediaPrompt(filePath, caption);
|
|
779
|
-
tgOrchestrate(ctx, prompt, `[📎 ${doc.file_name || 'file'}] ${caption}`);
|
|
834
|
+
await tgOrchestrate(ctx, prompt, `[📎 ${doc.file_name || 'file'}] ${caption}`);
|
|
780
835
|
}
|
|
781
836
|
catch (err) {
|
|
782
837
|
log.error('[tg:doc:error]', logErrorText(err));
|
|
783
838
|
await ctx.reply(t('tg.fileFail', { msg: userErrorText(err) }, currentLocale()));
|
|
784
839
|
}
|
|
785
840
|
});
|
|
786
|
-
bot.on('message:voice', (ctx) => handleVoice(ctx, currentLocale, tgOrchestrate));
|
|
841
|
+
bot.on('message:voice', async (ctx) => { await handleVoice(ctx, currentLocale, tgOrchestrate); });
|
|
787
842
|
// Identity first: the self-echo guard needs it, and the refusal below has
|
|
788
843
|
// to happen BEFORE anything is attached. Returning after attaching left the
|
|
789
844
|
// forwarder wired to a bot that never starts, still trying to send.
|
|
@@ -794,17 +849,17 @@ async function _initTelegramInner() {
|
|
|
794
849
|
botUserId = null;
|
|
795
850
|
try {
|
|
796
851
|
const me = await bot.api.getMe();
|
|
852
|
+
bot.botInfo = me;
|
|
797
853
|
botUsername = me.username || null;
|
|
798
854
|
botUserId = me.id ?? null;
|
|
799
855
|
}
|
|
800
856
|
catch (err) {
|
|
801
857
|
log.warn('[tg] getMe failed; bot identity unknown', logErrorText(err));
|
|
802
858
|
}
|
|
803
|
-
//
|
|
804
|
-
//
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
log.error('[tg] refusing to start: allowBots is on but the bot identity could not be read');
|
|
859
|
+
// The durable offset is scoped by bot identity, so polling must not start
|
|
860
|
+
// when getMe cannot provide that identity.
|
|
861
|
+
if (botUserId === null) {
|
|
862
|
+
log.error(logErrorText('[tg] refusing to start durable polling: bot identity could not be read'));
|
|
808
863
|
return;
|
|
809
864
|
}
|
|
810
865
|
// ─── Global Forwarding: non-Telegram responses → Telegram ───
|
|
@@ -814,18 +869,34 @@ async function _initTelegramInner() {
|
|
|
814
869
|
void syncTelegramCommands(bot).catch((e) => {
|
|
815
870
|
log.warn('[tg:commands] setMyCommands failed:', logErrorText(e));
|
|
816
871
|
});
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
872
|
+
const poller = new TelegramDurablePoller({
|
|
873
|
+
api: bot.api,
|
|
874
|
+
key: String(botUserId),
|
|
875
|
+
store: telegramUpdateOffsets,
|
|
876
|
+
handleUpdateThroughFinalDelivery: async (update) => {
|
|
877
|
+
try {
|
|
878
|
+
if (handleTelegramUpdate(update, telegramApprovalIngress))
|
|
879
|
+
return;
|
|
880
|
+
await bot.handleUpdate(update);
|
|
881
|
+
if (telegramFinalDeliveryFailures.has(update.update_id)) {
|
|
882
|
+
throw new Error('telegram_final_delivery_failed');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
finally {
|
|
886
|
+
telegramFinalDeliveryFailures.delete(update.update_id);
|
|
887
|
+
}
|
|
888
|
+
},
|
|
823
889
|
onStart: (info) => {
|
|
824
890
|
tg409RetryCount = 0;
|
|
825
|
-
|
|
891
|
+
const skipped = info.skippedThroughUpdateId === null ? '' : `; skipped through update ${info.skippedThroughUpdateId}`;
|
|
892
|
+
log.info(`[tg] ✅ @${botUsername ?? botUserId} durable polling active at offset ${info.nextOffset}${skipped}`);
|
|
826
893
|
},
|
|
827
|
-
})
|
|
828
|
-
|
|
894
|
+
});
|
|
895
|
+
telegramPoller = poller;
|
|
896
|
+
telegramApprovalIngress = createTelegramPollingIngress();
|
|
897
|
+
poller.start().catch((err) => {
|
|
898
|
+
const telegramError = err;
|
|
899
|
+
const is409 = telegramError.error_code === 409 || telegramError.message?.includes('409');
|
|
829
900
|
if (is409) {
|
|
830
901
|
tg409RetryCount++;
|
|
831
902
|
if (tg409RetryCount > TG_MAX_RETRIES) {
|
|
@@ -839,7 +910,7 @@ async function _initTelegramInner() {
|
|
|
839
910
|
}
|
|
840
911
|
}
|
|
841
912
|
else {
|
|
842
|
-
log.error('[tg:fatal]', logErrorText(err));
|
|
913
|
+
log.error('[tg:fatal] Telegram durability bootstrap/polling failed; no uncommitted backlog consumed', logErrorText(err));
|
|
843
914
|
}
|
|
844
915
|
});
|
|
845
916
|
telegramBot = bot;
|