remoteclaw 0.0.0 → 0.1.0-next.2abd2fa
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/CHANGELOG.md +7 -0
- package/LICENSE +661 -0
- package/README.md +490 -0
- package/assets/chrome-extension/README.md +23 -0
- package/assets/chrome-extension/background-utils.js +48 -0
- package/assets/chrome-extension/background.js +899 -0
- package/assets/chrome-extension/icons/icon128.png +0 -0
- package/assets/chrome-extension/icons/icon16.png +0 -0
- package/assets/chrome-extension/icons/icon32.png +0 -0
- package/assets/chrome-extension/icons/icon48.png +0 -0
- package/assets/chrome-extension/manifest.json +25 -0
- package/assets/chrome-extension/options-validation.js +57 -0
- package/assets/chrome-extension/options.html +200 -0
- package/assets/chrome-extension/options.js +74 -0
- package/assets/clawtributor-avatar-placeholder.png +0 -0
- package/assets/dmg-background-small.png +0 -0
- package/assets/dmg-background.png +0 -0
- package/dist/account-lookup-0KDSp5Mj.js +11 -0
- package/dist/account-lookup-zvANGr2x.js +11 -0
- package/dist/accounts-BFy_Z3od.js +272 -0
- package/dist/accounts-BTXSfPWi.js +270 -0
- package/dist/accounts-BxGS70Do.js +36 -0
- package/dist/accounts-CNY1TGj1.js +47 -0
- package/dist/accounts-DBohBlww.js +32 -0
- package/dist/accounts-DqRQ75w3.js +36 -0
- package/dist/accounts-iODF3SK2.js +47 -0
- package/dist/ack-reactions-B11TAC2D.js +446 -0
- package/dist/ack-reactions-BWVjL4H6.js +446 -0
- package/dist/acp-cli-CA1xMmVo.js +1320 -0
- package/dist/acp-cli-CGo6fJVZ.js +1326 -0
- package/dist/active-listener-VzhWW8W6.js +37 -0
- package/dist/active-listener-z0qVEcom.js +37 -0
- package/dist/agent-CTizRPIJ.js +732 -0
- package/dist/agent-D2RVoS5g.js +731 -0
- package/dist/agent-helpers-B6VfZ9_u.js +606 -0
- package/dist/agent-helpers-CTx5KKJu.js +606 -0
- package/dist/agent-scope-BGYzhtWQ.js +121 -0
- package/dist/agent-scope-C50VuLKh.js +119 -0
- package/dist/agents-BuYn-obw.js +788 -0
- package/dist/agents.config-BSTxuTVd.js +116 -0
- package/dist/agents.config-p3V3b9u6.js +116 -0
- package/dist/ansi-D04X81yq.js +14 -0
- package/dist/api-BeQMq2iS.js +17 -0
- package/dist/api-CxX8-gGz.js +17 -0
- package/dist/argv-Co-b9Zsc.js +101 -0
- package/dist/audio-DPOuhNq7.js +43 -0
- package/dist/audio-VBcVDa08.js +43 -0
- package/dist/audio-preflight-BwmCYeuM.js +64 -0
- package/dist/audio-preflight-co8gjlPX.js +69 -0
- package/dist/audit-oH4urD3G.js +3138 -0
- package/dist/audit-qgtCT3ik.js +3138 -0
- package/dist/auth-CAczFgAO.js +448 -0
- package/dist/auth-Deh9i9Eg.js +448 -0
- package/dist/auth-profiles-BquJGKLC.js +279 -0
- package/dist/auth-profiles-D8vKiBPq.js +281 -0
- package/dist/banner-Cf978khN.js +294 -0
- package/dist/binaries-DXW6oATV.js +13 -0
- package/dist/bindings-CRU_udk8.js +69 -0
- package/dist/bindings-DQZAu8Wv.js +69 -0
- package/dist/bonjour-discovery-DdAk1VyO.js +378 -0
- package/dist/bonjour-discovery-DuhiIZZx.js +378 -0
- package/dist/boot/handler.js +1498 -0
- package/dist/brew-C4zKZsHX.js +46 -0
- package/dist/brew-DbSbN8sD.js +46 -0
- package/dist/browser-cli-CZC4h5V4.js +1687 -0
- package/dist/browser-cli-DAgi_aQk.js +1692 -0
- package/dist/build-info.json +5 -0
- package/dist/bundled/boot/HOOK.md +24 -0
- package/dist/bundled/command-logger/HOOK.md +122 -0
- package/dist/call-BbwtB9Y-.js +2828 -0
- package/dist/call-PivL7Uex.js +2829 -0
- package/dist/canvas-host/a2ui/.bundle.hash +1 -0
- package/dist/canvas-host/a2ui/a2ui.bundle.js +13193 -0
- package/dist/canvas-host/a2ui/index.html +307 -0
- package/dist/catalog-BqO6yem_.js +185 -0
- package/dist/catalog-DFmaYwfk.js +185 -0
- package/dist/channel-account-context-CvIDAtHS.js +550 -0
- package/dist/channel-account-context-q-o0pG1A.js +550 -0
- package/dist/channel-activity-BaCNOZpP.js +94 -0
- package/dist/channel-activity-C-G4n9BK.js +292 -0
- package/dist/channel-activity-DTKGf3j5.js +94 -0
- package/dist/channel-options-Cyappik_.js +32 -0
- package/dist/channel-options-DFnypY5S.js +33 -0
- package/dist/channel-selection-BGl53D5K.js +51 -0
- package/dist/channel-selection-NNPbxnyZ.js +51 -0
- package/dist/channel-web-DmhVkWbP.js +2134 -0
- package/dist/channel-web-kRC3UYBJ.js +2136 -0
- package/dist/channels-cli-C5XRkPJl.js +1421 -0
- package/dist/channels-cli-D6TqCI0m.js +1426 -0
- package/dist/channels-status-issues-CUc9mpeW.js +18 -0
- package/dist/channels-status-issues-DwRDzwrV.js +18 -0
- package/dist/chat-envelope-DEZ-5RY8.js +248 -0
- package/dist/chat-envelope-el7Uo-Fe.js +248 -0
- package/dist/chat-type-CYPyHAj-.js +11 -0
- package/dist/chat-type-DKb2TlGZ.js +11 -0
- package/dist/chrome-0QaGKb3L.js +1732 -0
- package/dist/chrome-CFeWdP0Y.js +1733 -0
- package/dist/chunk-CSQfUhgF.js +341 -0
- package/dist/chunk-D0Y_w4oX.js +341 -0
- package/dist/clack-prompter-B7tOxhJd.js +122 -0
- package/dist/clack-prompter-CCFnKP_1.js +121 -0
- package/dist/cleanup-utils-CqAVZz2b.js +94 -0
- package/dist/cleanup-utils-CwQvD73q.js +94 -0
- package/dist/cli/daemon-cli.js +9 -0
- package/dist/cli-BR2J3c4l.js +125 -0
- package/dist/cli-C1q1vSmN.js +130 -0
- package/dist/cli-name-BicfmwQX.js +23 -0
- package/dist/cli-name-C6rJGl18.js +23 -0
- package/dist/cli-utils-BhXbz2UF.js +16 -0
- package/dist/cli-utils-DZe_rVkZ.js +16 -0
- package/dist/client-C61M8zI3.js +22 -0
- package/dist/client-DdpmATKq.js +22 -0
- package/dist/clipboard-D7_SKHPK.js +31 -0
- package/dist/clipboard-Dzkx6Q2K.js +31 -0
- package/dist/command-format-CVfo8I5f.js +18 -0
- package/dist/command-format-DgXcqxBt.js +32 -0
- package/dist/command-logger/handler.js +57 -0
- package/dist/command-options-C4paWSGf.js +26 -0
- package/dist/command-options-CA30lfLK.js +26 -0
- package/dist/command-registry-CYjvOp8W.js +215 -0
- package/dist/commands-CDonBOrw.js +41 -0
- package/dist/commands-D_-bgTlO.js +41 -0
- package/dist/commands-registry-CWJv6xe2.js +892 -0
- package/dist/commands-registry-Ci8_cFk9.js +893 -0
- package/dist/common-CMI-qsF8.js +156 -0
- package/dist/common-DSVmydhm.js +156 -0
- package/dist/completion-cli-8iZJqfmX.js +452 -0
- package/dist/completion-cli-CYDjEZSt.js +452 -0
- package/dist/config-D5XU45KD.js +6953 -0
- package/dist/config-FHu9Bn4R.js +6951 -0
- package/dist/config-cli-Gehy4sav.js +241 -0
- package/dist/config-cli-RC9qMgJq.js +246 -0
- package/dist/config-eval-CjGZtLwx.js +102 -0
- package/dist/config-eval-H_wlEYIG.js +102 -0
- package/dist/config-guard-J-Q_DFWk.js +97 -0
- package/dist/config-guard-cB5a_ANg.js +75 -0
- package/dist/config-validation-BPNyd9_3.js +18 -0
- package/dist/config-validation-BPWuvhVe.js +18 -0
- package/dist/configure-CC2XdRRm.js +891 -0
- package/dist/configure-DxFBJuhZ.js +889 -0
- package/dist/constants-BmRFoHl0.js +67 -0
- package/dist/constants-C9WPAluB.js +67 -0
- package/dist/constants-ChptG3d7.js +12 -0
- package/dist/constants-DY6b-_Wl.js +12 -0
- package/dist/control-auth-D0tpV3ts.js +397 -0
- package/dist/control-auth-_-0PGRUs.js +397 -0
- package/dist/control-ui/apple-touch-icon.png +0 -0
- package/dist/control-ui/assets/index-B4ZM1lW1.js +7738 -0
- package/dist/control-ui/assets/index-B4ZM1lW1.js.map +1 -0
- package/dist/control-ui/assets/index-PED72sKF.css +1 -0
- package/dist/control-ui/assets/pt-BR-eq0TfCI7.js +2 -0
- package/dist/control-ui/assets/pt-BR-eq0TfCI7.js.map +1 -0
- package/dist/control-ui/assets/zh-CN-DmLG2MF9.js +2 -0
- package/dist/control-ui/assets/zh-CN-DmLG2MF9.js.map +1 -0
- package/dist/control-ui/assets/zh-TW-BLErH0EM.js +2 -0
- package/dist/control-ui/assets/zh-TW-BLErH0EM.js.map +1 -0
- package/dist/control-ui/favicon-32.png +0 -0
- package/dist/control-ui/favicon.ico +0 -0
- package/dist/control-ui/favicon.svg +67 -0
- package/dist/control-ui/index.html +17 -0
- package/dist/control-ui-assets-Cx_mw4D0.js +186 -0
- package/dist/control-ui-assets-W1AUuGrO.js +186 -0
- package/dist/conversation-label-C4SDz4sT.js +36 -0
- package/dist/conversation-label-D1frnvYe.js +36 -0
- package/dist/credentials-BHWUBHMd.js +91 -0
- package/dist/credentials-DFsi1_e8.js +91 -0
- package/dist/cron-cli-BzERxhr5.js +495 -0
- package/dist/cron-cli-C8j_uslU.js +490 -0
- package/dist/daemon-cli-C95XNbX0.js +1199 -0
- package/dist/daemon-cli-e6sURMqd.js +1197 -0
- package/dist/daemon-cli.js +15243 -0
- package/dist/daemon-install-CcohRvKV.js +55 -0
- package/dist/daemon-install-DDshfT0J.js +60 -0
- package/dist/daemon-install-helpers-CFGAfRlj.js +462 -0
- package/dist/daemon-install-helpers-DIUzSFG1.js +462 -0
- package/dist/daemon-runtime-CMnbwryP.js +13 -0
- package/dist/daemon-runtime-CvqE4ysg.js +13 -0
- package/dist/dangerous-name-matching-BzmiLXmA.js +45 -0
- package/dist/dangerous-name-matching-DaVRgwer.js +45 -0
- package/dist/dangerous-tools-BOLoCRv4.js +253 -0
- package/dist/dangerous-tools-Baq7Q-i6.js +253 -0
- package/dist/defaults-B5KStIBg.js +7 -0
- package/dist/defaults-xUAL2Z-F.js +7 -0
- package/dist/deliver-912khjLK.js +481 -0
- package/dist/deliver-D56J4-1F.js +481 -0
- package/dist/delivery-queue-Cfa9Wmxp.js +244 -0
- package/dist/delivery-queue-CxVRi4tw.js +244 -0
- package/dist/devices-cli-0qDhTgZR.js +316 -0
- package/dist/devices-cli-6SKMR2bV.js +321 -0
- package/dist/diagnostics-99iCgBUh.js +46 -0
- package/dist/diagnostics-VC0cz7kX.js +46 -0
- package/dist/directory-cli-5YXdoVdn.js +217 -0
- package/dist/directory-cli-D3IKCHmn.js +222 -0
- package/dist/dm-policy-shared-4rkjhcrM.js +22 -0
- package/dist/dm-policy-shared-D8lgnmrC.js +22 -0
- package/dist/dns-cli-11CtErVU.js +197 -0
- package/dist/dns-cli-SiEd_1Lq.js +202 -0
- package/dist/dock-BqNINg7k.js +928 -0
- package/dist/dock-CQuu41bw.js +929 -0
- package/dist/doctor-completion-BR1SlAT3.js +92 -0
- package/dist/doctor-completion-CZwpEhIK.js +92 -0
- package/dist/doctor-config-flow-BVkHcvoj.js +1933 -0
- package/dist/doctor-config-flow-DVYRn0An.js +1934 -0
- package/dist/enable-DcJnkzfz.js +59 -0
- package/dist/enable-ibNq4UWy.js +59 -0
- package/dist/entry.js +2620 -0
- package/dist/env-DeF64iu0.js +60 -0
- package/dist/env-vars-7aZqKPhk.js +93 -0
- package/dist/env-vars-CLGbxdpL.js +93 -0
- package/dist/errors-8F-77i6m.js +35 -0
- package/dist/errors-DZ199hOo.js +35 -0
- package/dist/exec-DbKuYyM1.js +164 -0
- package/dist/exec-DkFE7lqU.js +164 -0
- package/dist/export-html/template.css +1060 -0
- package/dist/export-html/template.html +88 -0
- package/dist/export-html/template.js +1797 -0
- package/dist/export-html/vendor/highlight.min.js +1213 -0
- package/dist/export-html/vendor/marked.min.js +6 -0
- package/dist/extensionAPI.js +11520 -0
- package/dist/fetch-BFSBLBkA.js +67 -0
- package/dist/fetch-C6XKGA11.js +67 -0
- package/dist/fetch-CEDsOiql.js +67 -0
- package/dist/fetch-timeout-DTIN7CGM.js +43 -0
- package/dist/fetch-timeout-DoySHqfO.js +43 -0
- package/dist/file-identity-BxlKD8Ys.js +12 -0
- package/dist/file-lock-CIvloidc.js +107 -0
- package/dist/file-lock-CzBL_VIx.js +107 -0
- package/dist/format-duration-CqUERz51.js +35 -0
- package/dist/format-duration-Ct-yiwkS.js +35 -0
- package/dist/format-relative-79_Y1n2Y.js +55 -0
- package/dist/format-relative-CxLpEQOX.js +55 -0
- package/dist/fs-safe-DSwT85uK.js +88 -0
- package/dist/fs-safe-DkBhNAc3.js +98 -0
- package/dist/gateway-cli-BEEZhCHv.js +23747 -0
- package/dist/gateway-cli-Nob0g_4y.js +23742 -0
- package/dist/gateway-rpc-CksB-N83.js +28 -0
- package/dist/gateway-rpc-Dq44SkOv.js +28 -0
- package/dist/gmail-setup-utils-Cnx8A5pW.js +422 -0
- package/dist/gmail-setup-utils-nkabbKOE.js +423 -0
- package/dist/health-RT-F3hzT.js +1423 -0
- package/dist/health-SOuaKNRa.js +1420 -0
- package/dist/health-format-BG95OE6N.js +28 -0
- package/dist/health-format-B_QRD8Si.js +28 -0
- package/dist/heartbeat-visibility-BxkZjE5m.js +125 -0
- package/dist/heartbeat-visibility-CGG-G7px.js +125 -0
- package/dist/heartbeat-wake-LGEgcXjs.js +182 -0
- package/dist/heartbeat-wake-Y97geucO.js +182 -0
- package/dist/help-format-DAxf0l_h.js +17 -0
- package/dist/help-format-NNm_Ov4H.js +17 -0
- package/dist/helpers-BAsMXprO.js +25 -0
- package/dist/helpers-DLgbkcEn.js +25 -0
- package/dist/helpers-R7bU5IBz.js +10 -0
- package/dist/helpers-kkeXif0Q.js +10 -0
- package/dist/hook-runner-global-DJ14gXFP.js +527 -0
- package/dist/hooks-cli-DyEKryW8.js +1217 -0
- package/dist/hooks-cli-RuEn0-oy.js +1222 -0
- package/dist/host-env-security-Bms2_EMV.js +92 -0
- package/dist/host-env-security-szwfmhC4.js +92 -0
- package/dist/image-ops-Bi6JPSkD.js +354 -0
- package/dist/image-ops-DWytvdh_.js +354 -0
- package/dist/import-D8BBZQgl.js +170 -0
- package/dist/import-DQ6NI4Fz.js +168 -0
- package/dist/inbound-context-CPkkQW0i.js +68 -0
- package/dist/inbound-context-DS_kpIYI.js +68 -0
- package/dist/inbound-path-policy-Bg4gZBx-.js +250 -0
- package/dist/inbound-path-policy-sdr5Ji0k.js +250 -0
- package/dist/index.js +569 -0
- package/dist/input-provenance-Bn6thJNm.js +35 -0
- package/dist/input-provenance-xUsSMOsz.js +35 -0
- package/dist/inspect-Dt8hogS3.js +559 -0
- package/dist/inspect-vYIL1oA0.js +559 -0
- package/dist/installs-aM5dWAyn.js +325 -0
- package/dist/installs-pWdqG8HL.js +325 -0
- package/dist/ip-C9q3Oq20.js +200 -0
- package/dist/ip-D0zgNmBV.js +200 -0
- package/dist/ipv4--2WXMVtE.js +46 -0
- package/dist/ipv4-CDQpx1A7.js +46 -0
- package/dist/ir-BpaAMTfW.js +940 -0
- package/dist/is-main-DN8-sNR5.js +30 -0
- package/dist/json-file-B7l5-Xhr.js +25 -0
- package/dist/json-file-ChO_R9yh.js +25 -0
- package/dist/json-files-CmpYSF4G.js +46 -0
- package/dist/json-files-DzpTak5i.js +46 -0
- package/dist/lanes-ByWMUgrz.js +58 -0
- package/dist/lanes-cHJ5arWg.js +58 -0
- package/dist/links-Bz4V7R_p.js +15 -0
- package/dist/links-C3soDNDH.js +15 -0
- package/dist/loader-Ccwsh8Sh.js +22624 -0
- package/dist/loader-y9MhJewT.js +22621 -0
- package/dist/local-roots-BrH0Q63K.js +313 -0
- package/dist/local-roots-nImrw2WR.js +314 -0
- package/dist/location-DBWCGNLq.js +43 -0
- package/dist/location-GbZ0bBRU.js +43 -0
- package/dist/logger-BWMPnILd.js +47 -0
- package/dist/logger-Bw3cFE5t.js +49 -0
- package/dist/logger-DyL5G2DO.js +12 -0
- package/dist/logger-GvipVDfh.js +12 -0
- package/dist/logging-C-nxX2fn.js +20 -0
- package/dist/logging-D8-Kozjc.js +19 -0
- package/dist/login-C_Kt57nO.js +62 -0
- package/dist/login-DOmWDMeP.js +61 -0
- package/dist/login-qr-CXU0wC5K.js +322 -0
- package/dist/login-qr-D0u6fdeO.js +327 -0
- package/dist/logs-cli-CschwP4d.js +238 -0
- package/dist/logs-cli-D7ayUvz_.js +233 -0
- package/dist/markdown-tables-CrmghPAr.js +29 -0
- package/dist/markdown-tables-jrnSPvZ6.js +29 -0
- package/dist/media-CojxZ45J.js +10492 -0
- package/dist/media-DN7yRfrH.js +940 -0
- package/dist/message-action-names-CtEZcmlU.js +2521 -0
- package/dist/message-action-names-WglOO_DT.js +2521 -0
- package/dist/message-channel-DzJqHVZD.js +91 -0
- package/dist/message-channel-uWMAiywE.js +91 -0
- package/dist/mime-BS3jhcZE.js +149 -0
- package/dist/mime-Cxh_64P6.js +149 -0
- package/dist/mutable-allowlist-detectors-DiZDtmlZ.js +64 -0
- package/dist/mutable-allowlist-detectors-U5ThQr9V.js +64 -0
- package/dist/net-Cg8AQeke.js +225 -0
- package/dist/net-D6D0wgcF.js +225 -0
- package/dist/node-cli-Q2-n3Fgv.js +24 -0
- package/dist/node-cli-Uf6lAntf.js +24 -0
- package/dist/nodes-cli-C2SoKfCv.js +1343 -0
- package/dist/nodes-cli-CQmlfx0K.js +1348 -0
- package/dist/nodes-screen-BR9sYoPa.js +250 -0
- package/dist/nodes-screen-Cw7Hv7M2.js +250 -0
- package/dist/note-Dlv4NmlQ.js +92 -0
- package/dist/note-kvWV4xtw.js +92 -0
- package/dist/npm-registry-spec-0qiKawvv.js +786 -0
- package/dist/npm-registry-spec-COvUzy5J.js +786 -0
- package/dist/npm-resolution-6v_Zm-9G.js +86 -0
- package/dist/npm-resolution-BFz7LeoN.js +86 -0
- package/dist/onboard-CgyU-mDL.js +407 -0
- package/dist/onboard-RI4vNTZd.js +405 -0
- package/dist/onboard-channels-DN5JoKPd.js +2548 -0
- package/dist/onboard-channels-DyAd1OZr.js +2547 -0
- package/dist/onboard-config-BCTthQ7J.js +24 -0
- package/dist/onboard-config-y-2cgT0V.js +24 -0
- package/dist/onboard-helpers-BCzZUD0z.js +363 -0
- package/dist/onboard-helpers-sDc2Ky6H.js +362 -0
- package/dist/onboard-remote-CJrMtttl.js +127 -0
- package/dist/onboard-remote-hyQIBguz.js +127 -0
- package/dist/onboarding-DCu1iBTV.js +541 -0
- package/dist/onboarding-zKMitzpb.js +543 -0
- package/dist/onboarding.finalize-ClHhYE2E.js +401 -0
- package/dist/onboarding.finalize-D5JkVJgg.js +398 -0
- package/dist/onboarding.gateway-config-DFh71Ndn.js +198 -0
- package/dist/onboarding.gateway-config-VBk6AP9U.js +191 -0
- package/dist/outbound-BYlZshIw.js +221 -0
- package/dist/outbound-CFfJC1j5.js +220 -0
- package/dist/outbound-attachment-BCNs1u1F.js +18 -0
- package/dist/outbound-attachment-B_0D60Yr.js +18 -0
- package/dist/outbound-attachment-o0seS0CP.js +18 -0
- package/dist/pairing-cli-BeydfoF9.js +122 -0
- package/dist/pairing-cli-DWzX866x.js +127 -0
- package/dist/pairing-labels-B-N8S5Fc.js +9 -0
- package/dist/pairing-labels-B_53dY5L.js +9 -0
- package/dist/pairing-store-BxdqFZGK.js +460 -0
- package/dist/pairing-store-CTkD51uW.js +459 -0
- package/dist/parse-log-line-enq8pduH.js +44 -0
- package/dist/parse-log-line-mz9TG6ig.js +44 -0
- package/dist/parse-timeout-BMP8a0_a.js +16 -0
- package/dist/parse-timeout-CDkco8kd.js +16 -0
- package/dist/path-env-DR5vn3QL.js +89 -0
- package/dist/path-env-qRJbjJzj.js +89 -0
- package/dist/path-guards-CIx4hURU.js +31 -0
- package/dist/path-guards-CrQOUlsq.js +31 -0
- package/dist/path-safety-DkT9RmTG.js +14 -0
- package/dist/path-safety-juI2XbO1.js +14 -0
- package/dist/paths-BTaH3rLn.js +232 -0
- package/dist/plugin-auto-enable-D23gv7Aw.js +302 -0
- package/dist/plugin-auto-enable-DuPS9XiJ.js +301 -0
- package/dist/plugin-registry-CNu_1KZz.js +33 -0
- package/dist/plugin-registry-DeHwd2jk.js +33 -0
- package/dist/plugin-sdk/account-id.d.ts +1 -0
- package/dist/plugin-sdk/account-id.js +34 -0
- package/dist/plugin-sdk/agents/agent-helpers/errors.d.ts +55 -0
- package/dist/plugin-sdk/agents/agent-helpers/google.d.ts +3 -0
- package/dist/plugin-sdk/agents/agent-helpers/images.d.ts +21 -0
- package/dist/plugin-sdk/agents/agent-helpers/message-sanitization.d.ts +14 -0
- package/dist/plugin-sdk/agents/agent-helpers/messaging-dedupe.d.ts +10 -0
- package/dist/plugin-sdk/agents/agent-helpers/openai.d.ts +9 -0
- package/dist/plugin-sdk/agents/agent-helpers/thinking.d.ts +5 -0
- package/dist/plugin-sdk/agents/agent-helpers/turns.d.ts +20 -0
- package/dist/plugin-sdk/agents/agent-helpers/types.d.ts +1 -0
- package/dist/plugin-sdk/agents/agent-helpers.d.ts +11 -0
- package/dist/plugin-sdk/agents/agent-messaging.d.ts +8 -0
- package/dist/plugin-sdk/agents/agent-paths.d.ts +1 -0
- package/dist/plugin-sdk/agents/agent-scope.d.ts +61 -0
- package/dist/plugin-sdk/agents/agent-types.d.ts +78 -0
- package/dist/plugin-sdk/agents/agent-utils.d.ts +39 -0
- package/dist/plugin-sdk/agents/announce-idempotency.d.ts +11 -0
- package/dist/plugin-sdk/agents/api-key-rotation.d.ts +22 -0
- package/dist/plugin-sdk/agents/auth-profiles/constants.d.ts +16 -0
- package/dist/plugin-sdk/agents/auth-profiles/display.d.ts +7 -0
- package/dist/plugin-sdk/agents/auth-profiles/doctor.d.ts +8 -0
- package/dist/plugin-sdk/agents/auth-profiles/oauth.d.ts +14 -0
- package/dist/plugin-sdk/agents/auth-profiles/paths.d.ts +4 -0
- package/dist/plugin-sdk/agents/auth-profiles/profiles.d.ts +12 -0
- package/dist/plugin-sdk/agents/auth-profiles/session-override.d.ts +18 -0
- package/dist/plugin-sdk/agents/auth-profiles/store.d.ts +10 -0
- package/dist/plugin-sdk/agents/auth-profiles/types.d.ts +13 -0
- package/dist/plugin-sdk/agents/auth-profiles.d.ts +8 -0
- package/dist/plugin-sdk/agents/block-chunker.d.ts +19 -0
- package/dist/plugin-sdk/agents/channel-tools.d.ts +27 -0
- package/dist/plugin-sdk/agents/cli-session.d.ts +3 -0
- package/dist/plugin-sdk/agents/current-time.d.ts +17 -0
- package/dist/plugin-sdk/agents/date-time.d.ts +13 -0
- package/dist/plugin-sdk/agents/defaults.d.ts +3 -0
- package/dist/plugin-sdk/agents/identity-avatar.d.ts +15 -0
- package/dist/plugin-sdk/agents/identity.d.ts +28 -0
- package/dist/plugin-sdk/agents/image-sanitization.d.ts +8 -0
- package/dist/plugin-sdk/agents/lanes.d.ts +3 -0
- package/dist/plugin-sdk/agents/live-auth-keys.d.ts +6 -0
- package/dist/plugin-sdk/agents/owner-display.d.ts +19 -0
- package/dist/plugin-sdk/agents/provider-auth.d.ts +40 -0
- package/dist/plugin-sdk/agents/provider-utils.d.ts +21 -0
- package/dist/plugin-sdk/agents/schema/typebox.d.ts +14 -0
- package/dist/plugin-sdk/agents/session-write-lock.d.ts +53 -0
- package/dist/plugin-sdk/agents/stable-stringify.d.ts +1 -0
- package/dist/plugin-sdk/agents/subagent-announce-queue.d.ts +24 -0
- package/dist/plugin-sdk/agents/subagent-announce.d.ts +39 -0
- package/dist/plugin-sdk/agents/subagent-depth.d.ts +11 -0
- package/dist/plugin-sdk/agents/subagent-lifecycle-events.d.ts +18 -0
- package/dist/plugin-sdk/agents/subagent-registry-cleanup.d.ts +24 -0
- package/dist/plugin-sdk/agents/subagent-registry-completion.d.ts +15 -0
- package/dist/plugin-sdk/agents/subagent-registry-queries.d.ts +11 -0
- package/dist/plugin-sdk/agents/subagent-registry-state.d.ts +7 -0
- package/dist/plugin-sdk/agents/subagent-registry.d.ts +45 -0
- package/dist/plugin-sdk/agents/subagent-registry.store.d.ts +5 -0
- package/dist/plugin-sdk/agents/subagent-registry.types.d.ts +34 -0
- package/dist/plugin-sdk/agents/subagent-spawn.d.ts +47 -0
- package/dist/plugin-sdk/agents/timeout.d.ts +8 -0
- package/dist/plugin-sdk/agents/tool-call-id.d.ts +27 -0
- package/dist/plugin-sdk/agents/tool-display-common.d.ts +32 -0
- package/dist/plugin-sdk/agents/tool-display.d.ts +15 -0
- package/dist/plugin-sdk/agents/tool-images.d.ts +10 -0
- package/dist/plugin-sdk/agents/tools/agent-step.d.ts +15 -0
- package/dist/plugin-sdk/agents/tools/common.d.ts +80 -0
- package/dist/plugin-sdk/agents/tools/discord-actions-guild.d.ts +4 -0
- package/dist/plugin-sdk/agents/tools/discord-actions-messaging.d.ts +6 -0
- package/dist/plugin-sdk/agents/tools/discord-actions-moderation-shared.d.ts +13 -0
- package/dist/plugin-sdk/agents/tools/discord-actions-moderation.d.ts +4 -0
- package/dist/plugin-sdk/agents/tools/discord-actions-presence.d.ts +4 -0
- package/dist/plugin-sdk/agents/tools/discord-actions.d.ts +5 -0
- package/dist/plugin-sdk/agents/tools/sessions-access.d.ts +42 -0
- package/dist/plugin-sdk/agents/tools/sessions-helpers.d.ts +52 -0
- package/dist/plugin-sdk/agents/tools/sessions-resolution.d.ts +59 -0
- package/dist/plugin-sdk/agents/tools/sessions-send-helpers.d.ts +34 -0
- package/dist/plugin-sdk/agents/tools/slack-actions.d.ts +15 -0
- package/dist/plugin-sdk/agents/tools/telegram-actions.d.ts +7 -0
- package/dist/plugin-sdk/agents/tools/whatsapp-actions.d.ts +3 -0
- package/dist/plugin-sdk/agents/tools/whatsapp-target-auth.d.ts +10 -0
- package/dist/plugin-sdk/agents/usage.d.ts +49 -0
- package/dist/plugin-sdk/agents/workspace.d.ts +1 -0
- package/dist/plugin-sdk/auto-reply/chunk.d.ts +45 -0
- package/dist/plugin-sdk/auto-reply/command-auth.d.ts +17 -0
- package/dist/plugin-sdk/auto-reply/command-detection.d.ts +13 -0
- package/dist/plugin-sdk/auto-reply/commands-args.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/commands-registry.d.ts +47 -0
- package/dist/plugin-sdk/auto-reply/commands-registry.data.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/commands-registry.types.d.ts +66 -0
- package/dist/plugin-sdk/auto-reply/dispatch.d.ts +32 -0
- package/dist/plugin-sdk/auto-reply/envelope.d.ts +58 -0
- package/dist/plugin-sdk/auto-reply/fallback-state.d.ts +55 -0
- package/dist/plugin-sdk/auto-reply/group-activation.d.ts +6 -0
- package/dist/plugin-sdk/auto-reply/heartbeat-reply-payload.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/heartbeat.d.ts +16 -0
- package/dist/plugin-sdk/auto-reply/inbound-debounce.d.ts +17 -0
- package/dist/plugin-sdk/auto-reply/media-note.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/model-runtime.d.ts +17 -0
- package/dist/plugin-sdk/auto-reply/model.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/abort.d.ts +32 -0
- package/dist/plugin-sdk/auto-reply/reply/agent-runner-execution.d.ts +59 -0
- package/dist/plugin-sdk/auto-reply/reply/agent-runner-helpers.d.ts +15 -0
- package/dist/plugin-sdk/auto-reply/reply/agent-runner-payloads.d.ts +27 -0
- package/dist/plugin-sdk/auto-reply/reply/agent-runner-utils.d.ts +152 -0
- package/dist/plugin-sdk/auto-reply/reply/agent-runner.d.ts +36 -0
- package/dist/plugin-sdk/auto-reply/reply/block-reply-coalescer.d.ts +15 -0
- package/dist/plugin-sdk/auto-reply/reply/block-reply-pipeline.d.ts +31 -0
- package/dist/plugin-sdk/auto-reply/reply/block-streaming.d.ts +22 -0
- package/dist/plugin-sdk/auto-reply/reply/body.d.ts +10 -0
- package/dist/plugin-sdk/auto-reply/reply/command-gates.d.ts +18 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-allowlist.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-config.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-context.d.ts +12 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-core.d.ts +13 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-export-session.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-info.d.ts +11 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-plugin.d.ts +13 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-session.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-setunset-standard.d.ts +10 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-setunset.d.ts +34 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-slash-parse.d.ts +24 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-status.d.ts +26 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-agents.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-focus.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-help.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-info.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-kill.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-list.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-log.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-send.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-spawn.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/action-unfocus.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents/shared.d.ts +81 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-subagents.d.ts +4 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-tts.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/reply/commands-types.d.ts +61 -0
- package/dist/plugin-sdk/auto-reply/reply/commands.d.ts +4 -0
- package/dist/plugin-sdk/auto-reply/reply/config-commands.d.ts +15 -0
- package/dist/plugin-sdk/auto-reply/reply/config-value.d.ts +4 -0
- package/dist/plugin-sdk/auto-reply/reply/debug-commands.d.ts +16 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.auth.d.ts +19 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.d.ts +6 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.fast-lane.d.ts +7 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.impl.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.levels.d.ts +20 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.params.d.ts +59 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.parse.d.ts +65 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.persist.d.ts +42 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.queue-validation.d.ts +10 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-handling.shared.d.ts +29 -0
- package/dist/plugin-sdk/auto-reply/reply/directive-parsing.d.ts +5 -0
- package/dist/plugin-sdk/auto-reply/reply/directives.d.ts +58 -0
- package/dist/plugin-sdk/auto-reply/reply/dispatch-from-config.d.ts +16 -0
- package/dist/plugin-sdk/auto-reply/reply/dispatcher-registry.d.ts +24 -0
- package/dist/plugin-sdk/auto-reply/reply/elevated-allowlist-matcher.d.ts +20 -0
- package/dist/plugin-sdk/auto-reply/reply/elevated-unavailable.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/followup-runner.d.ts +16 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply-directives-apply.d.ts +64 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply-directives-utils.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply-directives.d.ts +121 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply-inline-actions.d.ts +56 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply-run.d.ts +73 -0
- package/dist/plugin-sdk/auto-reply/reply/get-reply.d.ts +4 -0
- package/dist/plugin-sdk/auto-reply/reply/groups.d.ts +26 -0
- package/dist/plugin-sdk/auto-reply/reply/history.d.ts +72 -0
- package/dist/plugin-sdk/auto-reply/reply/inbound-context.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/inbound-dedupe.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/inbound-meta.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/inbound-text.d.ts +1 -0
- package/dist/plugin-sdk/auto-reply/reply/line-directives.d.ts +22 -0
- package/dist/plugin-sdk/auto-reply/reply/mentions.d.ts +19 -0
- package/dist/plugin-sdk/auto-reply/reply/normalize-reply.d.ts +11 -0
- package/dist/plugin-sdk/auto-reply/reply/origin-routing.d.ts +13 -0
- package/dist/plugin-sdk/auto-reply/reply/provider-dispatcher.d.ts +19 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/cleanup.d.ts +6 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/directive.d.ts +15 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/drain.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/enqueue.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/normalize.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/settings.d.ts +2 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/state.d.ts +20 -0
- package/dist/plugin-sdk/auto-reply/reply/queue/types.d.ts +87 -0
- package/dist/plugin-sdk/auto-reply/reply/queue-policy.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/queue.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-delivery.d.ts +27 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-directives.d.ts +14 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-dispatcher.d.ts +53 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-elevated.d.ts +16 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-inline.d.ts +8 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-payloads.d.ts +27 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-reference.d.ts +20 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-tags.d.ts +6 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-threading.d.ts +9 -0
- package/dist/plugin-sdk/auto-reply/reply/response-prefix-template.d.ts +51 -0
- package/dist/plugin-sdk/auto-reply/reply/route-reply.d.ts +56 -0
- package/dist/plugin-sdk/auto-reply/reply/session-reset-prompt.d.ts +1 -0
- package/dist/plugin-sdk/auto-reply/reply/session-run-accounting.d.ts +11 -0
- package/dist/plugin-sdk/auto-reply/reply/session-updates.d.ts +18 -0
- package/dist/plugin-sdk/auto-reply/reply/session-usage.d.ts +21 -0
- package/dist/plugin-sdk/auto-reply/reply/session.d.ts +26 -0
- package/dist/plugin-sdk/auto-reply/reply/strip-inbound-meta.d.ts +27 -0
- package/dist/plugin-sdk/auto-reply/reply/subagents-utils.d.ts +26 -0
- package/dist/plugin-sdk/auto-reply/reply/typing-mode.d.ts +27 -0
- package/dist/plugin-sdk/auto-reply/reply/typing.d.ts +18 -0
- package/dist/plugin-sdk/auto-reply/reply/untrusted-context.d.ts +1 -0
- package/dist/plugin-sdk/auto-reply/reply.d.ts +5 -0
- package/dist/plugin-sdk/auto-reply/send-policy.d.ts +6 -0
- package/dist/plugin-sdk/auto-reply/status.d.ts +59 -0
- package/dist/plugin-sdk/auto-reply/templating.d.ts +159 -0
- package/dist/plugin-sdk/auto-reply/thinking.d.ts +22 -0
- package/dist/plugin-sdk/auto-reply/tokens.d.ts +3 -0
- package/dist/plugin-sdk/auto-reply/types.d.ts +82 -0
- package/dist/plugin-sdk/channel-web.d.ts +6 -0
- package/dist/plugin-sdk/channels/account-summary.d.ts +17 -0
- package/dist/plugin-sdk/channels/ack-reactions.d.ts +29 -0
- package/dist/plugin-sdk/channels/allow-from.d.ts +11 -0
- package/dist/plugin-sdk/channels/allowlist-match.d.ts +16 -0
- package/dist/plugin-sdk/channels/allowlists/resolve-utils.d.ts +33 -0
- package/dist/plugin-sdk/channels/channel-config.d.ts +39 -0
- package/dist/plugin-sdk/channels/chat-type.d.ts +2 -0
- package/dist/plugin-sdk/channels/command-gating.d.ts +20 -0
- package/dist/plugin-sdk/channels/conversation-label.d.ts +2 -0
- package/dist/plugin-sdk/channels/dock.d.ts +25 -0
- package/dist/plugin-sdk/channels/draft-stream-controls.d.ts +54 -0
- package/dist/plugin-sdk/channels/draft-stream-loop.d.ts +13 -0
- package/dist/plugin-sdk/channels/location.d.ts +21 -0
- package/dist/plugin-sdk/channels/logging.d.ts +20 -0
- package/dist/plugin-sdk/channels/mention-gating.d.ts +27 -0
- package/dist/plugin-sdk/channels/model-overrides.d.ts +18 -0
- package/dist/plugin-sdk/channels/plugins/account-action-gate.d.ts +5 -0
- package/dist/plugin-sdk/channels/plugins/account-helpers.d.ts +6 -0
- package/dist/plugin-sdk/channels/plugins/actions/discord/handle-action.d.ts +3 -0
- package/dist/plugin-sdk/channels/plugins/actions/discord/handle-action.guild-admin.d.ts +9 -0
- package/dist/plugin-sdk/channels/plugins/actions/discord.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/actions/shared.d.ts +7 -0
- package/dist/plugin-sdk/channels/plugins/actions/signal.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/actions/telegram.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/agent-tools/whatsapp-login.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/allowlist-match.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/bluebubbles-actions.d.ts +48 -0
- package/dist/plugin-sdk/channels/plugins/channel-config.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/config-helpers.d.ts +14 -0
- package/dist/plugin-sdk/channels/plugins/config-schema.d.ts +3 -0
- package/dist/plugin-sdk/channels/plugins/config-writes.d.ts +7 -0
- package/dist/plugin-sdk/channels/plugins/directory-config.d.ts +16 -0
- package/dist/plugin-sdk/channels/plugins/group-mentions.d.ts +18 -0
- package/dist/plugin-sdk/channels/plugins/helpers.d.ts +8 -0
- package/dist/plugin-sdk/channels/plugins/index.d.ts +8 -0
- package/dist/plugin-sdk/channels/plugins/media-limits.d.ts +9 -0
- package/dist/plugin-sdk/channels/plugins/media-payload.d.ts +15 -0
- package/dist/plugin-sdk/channels/plugins/message-action-names.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/normalize/discord.d.ts +14 -0
- package/dist/plugin-sdk/channels/plugins/normalize/imessage.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/normalize/shared.d.ts +6 -0
- package/dist/plugin-sdk/channels/plugins/normalize/signal.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/normalize/slack.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/normalize/telegram.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/normalize/whatsapp.d.ts +3 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/channel-access-configure.d.ts +21 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/channel-access.d.ts +31 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/discord.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/helpers.d.ts +177 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/imessage.d.ts +6 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/signal.d.ts +7 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/slack.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/telegram.d.ts +4 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/whatsapp.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/onboarding-types.d.ts +77 -0
- package/dist/plugin-sdk/channels/plugins/outbound/load.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/pairing-message.d.ts +1 -0
- package/dist/plugin-sdk/channels/plugins/pairing.d.ts +16 -0
- package/dist/plugin-sdk/channels/plugins/registry-loader.d.ts +5 -0
- package/dist/plugin-sdk/channels/plugins/setup-helpers.d.ts +13 -0
- package/dist/plugin-sdk/channels/plugins/status-issues/bluebubbles.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/status-issues/discord.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/status-issues/shared.d.ts +29 -0
- package/dist/plugin-sdk/channels/plugins/status-issues/telegram.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/status-issues/whatsapp.d.ts +2 -0
- package/dist/plugin-sdk/channels/plugins/types.adapters.d.ts +288 -0
- package/dist/plugin-sdk/channels/plugins/types.core.d.ts +349 -0
- package/dist/plugin-sdk/channels/plugins/types.d.ts +6 -0
- package/dist/plugin-sdk/channels/plugins/types.plugin.d.ts +54 -0
- package/dist/plugin-sdk/channels/plugins/whatsapp-heartbeat.d.ts +11 -0
- package/dist/plugin-sdk/channels/plugins/whatsapp-shared.d.ts +5 -0
- package/dist/plugin-sdk/channels/registry.d.ts +15 -0
- package/dist/plugin-sdk/channels/reply-prefix.d.ts +24 -0
- package/dist/plugin-sdk/channels/sender-label.d.ts +9 -0
- package/dist/plugin-sdk/channels/session.d.ts +18 -0
- package/dist/plugin-sdk/channels/status-reactions.d.ts +62 -0
- package/dist/plugin-sdk/channels/targets.d.ts +42 -0
- package/dist/plugin-sdk/channels/telegram/api.d.ts +5 -0
- package/dist/plugin-sdk/channels/typing-lifecycle.d.ts +12 -0
- package/dist/plugin-sdk/channels/typing.d.ts +13 -0
- package/dist/plugin-sdk/channels/web/index.d.ts +1 -0
- package/dist/plugin-sdk/cli/cli-name.d.ts +3 -0
- package/dist/plugin-sdk/cli/command-format.d.ts +1 -0
- package/dist/plugin-sdk/cli/deps.d.ts +18 -0
- package/dist/plugin-sdk/cli/outbound-send-deps.d.ts +4 -0
- package/dist/plugin-sdk/cli/outbound-send-mapping.d.ts +10 -0
- package/dist/plugin-sdk/cli/parse-bytes.d.ts +4 -0
- package/dist/plugin-sdk/cli/parse-duration.d.ts +4 -0
- package/dist/plugin-sdk/cli/profile-utils.d.ts +2 -0
- package/dist/plugin-sdk/cli/progress.d.ts +24 -0
- package/dist/plugin-sdk/cli/wait.d.ts +1 -0
- package/dist/plugin-sdk/commands/agent/delivery.d.ts +25 -0
- package/dist/plugin-sdk/commands/agent/run-context.d.ts +2 -0
- package/dist/plugin-sdk/commands/agent/session-store.d.ts +16 -0
- package/dist/plugin-sdk/commands/agent/session.d.ts +33 -0
- package/dist/plugin-sdk/commands/agent/types.d.ts +89 -0
- package/dist/plugin-sdk/commands/agent.d.ts +14 -0
- package/dist/plugin-sdk/commands/daemon-runtime.d.ts +8 -0
- package/dist/plugin-sdk/commands/health.d.ts +63 -0
- package/dist/plugin-sdk/commands/oauth-flow.d.ts +21 -0
- package/dist/plugin-sdk/commands/onboard-helpers.d.ts +81 -0
- package/dist/plugin-sdk/commands/onboard-types.d.ts +69 -0
- package/dist/plugin-sdk/commands/signal-install.d.ts +30 -0
- package/dist/plugin-sdk/compat/legacy-names.d.ts +8 -0
- package/dist/plugin-sdk/config/agent-dirs.d.ts +14 -0
- package/dist/plugin-sdk/config/agent-limits.d.ts +6 -0
- package/dist/plugin-sdk/config/backup-rotation.d.ts +5 -0
- package/dist/plugin-sdk/config/cache-utils.d.ts +6 -0
- package/dist/plugin-sdk/config/commands.d.ts +20 -0
- package/dist/plugin-sdk/config/config-paths.d.ts +10 -0
- package/dist/plugin-sdk/config/config.d.ts +7 -0
- package/dist/plugin-sdk/config/dangerous-name-matching.d.ts +12 -0
- package/dist/plugin-sdk/config/defaults.d.ts +19 -0
- package/dist/plugin-sdk/config/discord-preview-streaming.d.ts +25 -0
- package/dist/plugin-sdk/config/env-preserve.d.ts +10 -0
- package/dist/plugin-sdk/config/env-substitution.d.ts +36 -0
- package/dist/plugin-sdk/config/env-vars.d.ts +6 -0
- package/dist/plugin-sdk/config/group-policy.d.ts +49 -0
- package/dist/plugin-sdk/config/includes.d.ts +32 -0
- package/dist/plugin-sdk/config/io.d.ts +60 -0
- package/dist/plugin-sdk/config/legacy-migrate.d.ts +5 -0
- package/dist/plugin-sdk/config/legacy.d.ts +6 -0
- package/dist/plugin-sdk/config/legacy.migrations.d.ts +1 -0
- package/dist/plugin-sdk/config/legacy.migrations.part-1.d.ts +2 -0
- package/dist/plugin-sdk/config/legacy.migrations.part-2.d.ts +2 -0
- package/dist/plugin-sdk/config/legacy.migrations.part-3.d.ts +2 -0
- package/dist/plugin-sdk/config/legacy.rules.d.ts +2 -0
- package/dist/plugin-sdk/config/legacy.shared.d.ts +19 -0
- package/dist/plugin-sdk/config/markdown-tables.d.ts +7 -0
- package/dist/plugin-sdk/config/merge-config.d.ts +7 -0
- package/dist/plugin-sdk/config/merge-patch.d.ts +5 -0
- package/dist/plugin-sdk/config/model-input.d.ts +9 -0
- package/dist/plugin-sdk/config/normalize-paths.d.ts +8 -0
- package/dist/plugin-sdk/config/paths.d.ts +57 -0
- package/dist/plugin-sdk/config/prototype-keys.d.ts +1 -0
- package/dist/plugin-sdk/config/runtime-group-policy.d.ts +56 -0
- package/dist/plugin-sdk/config/runtime-overrides.d.ts +15 -0
- package/dist/plugin-sdk/config/sessions/artifacts.d.ts +5 -0
- package/dist/plugin-sdk/config/sessions/constants.d.ts +2 -0
- package/dist/plugin-sdk/config/sessions/delivery-info.d.ts +16 -0
- package/dist/plugin-sdk/config/sessions/disk-budget.d.ts +28 -0
- package/dist/plugin-sdk/config/sessions/group.d.ts +11 -0
- package/dist/plugin-sdk/config/sessions/main-session.d.ts +43 -0
- package/dist/plugin-sdk/config/sessions/metadata.d.ts +16 -0
- package/dist/plugin-sdk/config/sessions/paths.d.ts +21 -0
- package/dist/plugin-sdk/config/sessions/reset.d.ts +43 -0
- package/dist/plugin-sdk/config/sessions/session-file.d.ts +15 -0
- package/dist/plugin-sdk/config/sessions/session-key.d.ts +8 -0
- package/dist/plugin-sdk/config/sessions/store.d.ts +123 -0
- package/dist/plugin-sdk/config/sessions/transcript.d.ts +18 -0
- package/dist/plugin-sdk/config/sessions/types.d.ts +160 -0
- package/dist/plugin-sdk/config/sessions.d.ts +13 -0
- package/dist/plugin-sdk/config/talk.d.ts +21 -0
- package/dist/plugin-sdk/config/telegram-custom-commands.d.ts +24 -0
- package/dist/plugin-sdk/config/types.agent-defaults.d.ts +268 -0
- package/dist/plugin-sdk/config/types.agents-shared.d.ts +49 -0
- package/dist/plugin-sdk/config/types.agents.d.ts +57 -0
- package/dist/plugin-sdk/config/types.approvals.d.ts +26 -0
- package/dist/plugin-sdk/config/types.auth.d.ts +28 -0
- package/dist/plugin-sdk/config/types.base.d.ts +203 -0
- package/dist/plugin-sdk/config/types.browser.d.ts +65 -0
- package/dist/plugin-sdk/config/types.channel-messaging-common.d.ts +44 -0
- package/dist/plugin-sdk/config/types.channels.d.ts +53 -0
- package/dist/plugin-sdk/config/types.cron.d.ts +26 -0
- package/dist/plugin-sdk/config/types.d.ts +27 -0
- package/dist/plugin-sdk/config/types.discord.d.ts +273 -0
- package/dist/plugin-sdk/config/types.gateway.d.ts +335 -0
- package/dist/plugin-sdk/config/types.googlechat.d.ts +107 -0
- package/dist/plugin-sdk/config/types.hooks.d.ts +123 -0
- package/dist/plugin-sdk/config/types.imessage.d.ts +77 -0
- package/dist/plugin-sdk/config/types.installs.d.ts +14 -0
- package/dist/plugin-sdk/config/types.irc.d.ts +54 -0
- package/dist/plugin-sdk/config/types.messages.d.ts +154 -0
- package/dist/plugin-sdk/config/types.models.d.ts +41 -0
- package/dist/plugin-sdk/config/types.msteams.d.ts +108 -0
- package/dist/plugin-sdk/config/types.node-host.d.ts +10 -0
- package/dist/plugin-sdk/config/types.plugins.d.ts +23 -0
- package/dist/plugin-sdk/config/types.queue.d.ts +14 -0
- package/dist/plugin-sdk/config/types.remoteclaw.d.ts +119 -0
- package/dist/plugin-sdk/config/types.signal.d.ts +46 -0
- package/dist/plugin-sdk/config/types.slack.d.ts +181 -0
- package/dist/plugin-sdk/config/types.telegram.d.ts +191 -0
- package/dist/plugin-sdk/config/types.tools.d.ts +322 -0
- package/dist/plugin-sdk/config/types.tts.d.ts +78 -0
- package/dist/plugin-sdk/config/types.whatsapp.d.ts +101 -0
- package/dist/plugin-sdk/config/validation.d.ts +37 -0
- package/dist/plugin-sdk/config/version.d.ts +8 -0
- package/dist/plugin-sdk/config/zod-schema.agent-defaults.d.ts +156 -0
- package/dist/plugin-sdk/config/zod-schema.agent-model.d.ts +5 -0
- package/dist/plugin-sdk/config/zod-schema.agent-runtime.d.ts +500 -0
- package/dist/plugin-sdk/config/zod-schema.agents.d.ts +298 -0
- package/dist/plugin-sdk/config/zod-schema.allowdeny.d.ts +13 -0
- package/dist/plugin-sdk/config/zod-schema.approvals.d.ts +15 -0
- package/dist/plugin-sdk/config/zod-schema.channels.d.ts +6 -0
- package/dist/plugin-sdk/config/zod-schema.core.d.ts +583 -0
- package/dist/plugin-sdk/config/zod-schema.d.ts +3434 -0
- package/dist/plugin-sdk/config/zod-schema.hooks.d.ts +85 -0
- package/dist/plugin-sdk/config/zod-schema.installs.d.ts +16 -0
- package/dist/plugin-sdk/config/zod-schema.providers-core.d.ts +3693 -0
- package/dist/plugin-sdk/config/zod-schema.providers-whatsapp.d.ts +235 -0
- package/dist/plugin-sdk/config/zod-schema.providers.d.ts +2200 -0
- package/dist/plugin-sdk/config/zod-schema.sensitive.d.ts +2 -0
- package/dist/plugin-sdk/config/zod-schema.session.d.ts +234 -0
- package/dist/plugin-sdk/cron/delivery.d.ts +9 -0
- package/dist/plugin-sdk/cron/legacy-delivery.d.ts +3 -0
- package/dist/plugin-sdk/cron/parse.d.ts +1 -0
- package/dist/plugin-sdk/cron/payload-migration.d.ts +3 -0
- package/dist/plugin-sdk/cron/schedule.d.ts +2 -0
- package/dist/plugin-sdk/cron/service/jobs.d.ts +21 -0
- package/dist/plugin-sdk/cron/service/locked.d.ts +2 -0
- package/dist/plugin-sdk/cron/service/normalize.d.ts +18 -0
- package/dist/plugin-sdk/cron/service/ops.d.ts +81 -0
- package/dist/plugin-sdk/cron/service/state.d.ts +125 -0
- package/dist/plugin-sdk/cron/service/store.d.ts +9 -0
- package/dist/plugin-sdk/cron/service/timer.d.ts +47 -0
- package/dist/plugin-sdk/cron/service.d.ts +66 -0
- package/dist/plugin-sdk/cron/session-reaper.d.ts +35 -0
- package/dist/plugin-sdk/cron/stagger.d.ts +8 -0
- package/dist/plugin-sdk/cron/store.d.ts +6 -0
- package/dist/plugin-sdk/cron/types.d.ts +131 -0
- package/dist/plugin-sdk/cron/webhook-url.d.ts +1 -0
- package/dist/plugin-sdk/daemon/constants.d.ts +35 -0
- package/dist/plugin-sdk/discord/accounts.d.ts +21 -0
- package/dist/plugin-sdk/discord/api.d.ts +11 -0
- package/dist/plugin-sdk/discord/audit.d.ts +29 -0
- package/dist/plugin-sdk/discord/chunk.d.ts +20 -0
- package/dist/plugin-sdk/discord/client.d.ts +21 -0
- package/dist/plugin-sdk/discord/components-registry.d.ts +16 -0
- package/dist/plugin-sdk/discord/components.d.ts +196 -0
- package/dist/plugin-sdk/discord/directory-live.d.ts +4 -0
- package/dist/plugin-sdk/discord/draft-chunking.d.ts +6 -0
- package/dist/plugin-sdk/discord/draft-stream.d.ts +21 -0
- package/dist/plugin-sdk/discord/gateway-logging.d.ts +8 -0
- package/dist/plugin-sdk/discord/guilds.d.ts +6 -0
- package/dist/plugin-sdk/discord/monitor/agent-components.d.ts +55 -0
- package/dist/plugin-sdk/discord/monitor/allow-list.d.ts +176 -0
- package/dist/plugin-sdk/discord/monitor/commands.d.ts +2 -0
- package/dist/plugin-sdk/discord/monitor/format.d.ts +13 -0
- package/dist/plugin-sdk/discord/monitor/gateway-plugin.d.ts +8 -0
- package/dist/plugin-sdk/discord/monitor/gateway-registry.d.ts +9 -0
- package/dist/plugin-sdk/discord/monitor/listeners.d.ts +44 -0
- package/dist/plugin-sdk/discord/monitor/message-handler.d.ts +5 -0
- package/dist/plugin-sdk/discord/monitor/message-handler.preflight.d.ts +14 -0
- package/dist/plugin-sdk/discord/monitor/message-handler.preflight.types.d.ts +95 -0
- package/dist/plugin-sdk/discord/monitor/message-handler.process.d.ts +2 -0
- package/dist/plugin-sdk/discord/monitor/message-utils.d.ts +40 -0
- package/dist/plugin-sdk/discord/monitor/native-command.d.ts +23 -0
- package/dist/plugin-sdk/discord/monitor/presence-cache.d.ts +9 -0
- package/dist/plugin-sdk/discord/monitor/presence.d.ts +5 -0
- package/dist/plugin-sdk/discord/monitor/provider.allowlist.d.ts +14 -0
- package/dist/plugin-sdk/discord/monitor/provider.d.ts +28 -0
- package/dist/plugin-sdk/discord/monitor/provider.lifecycle.d.ts +23 -0
- package/dist/plugin-sdk/discord/monitor/reply-context.d.ts +17 -0
- package/dist/plugin-sdk/discord/monitor/reply-delivery.d.ts +22 -0
- package/dist/plugin-sdk/discord/monitor/rest-fetch.d.ts +2 -0
- package/dist/plugin-sdk/discord/monitor/sender-identity.d.ts +31 -0
- package/dist/plugin-sdk/discord/monitor/system-events.d.ts +2 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.d.ts +5 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.discord-api.d.ts +36 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.lifecycle.d.ts +30 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.manager.d.ts +17 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.messages.d.ts +17 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.state.d.ts +61 -0
- package/dist/plugin-sdk/discord/monitor/thread-bindings.types.d.ts +64 -0
- package/dist/plugin-sdk/discord/monitor/threading.d.ts +106 -0
- package/dist/plugin-sdk/discord/monitor/typing.d.ts +5 -0
- package/dist/plugin-sdk/discord/monitor.d.ts +10 -0
- package/dist/plugin-sdk/discord/monitor.gateway.d.ts +12 -0
- package/dist/plugin-sdk/discord/pluralkit.d.ts +26 -0
- package/dist/plugin-sdk/discord/probe.d.ts +28 -0
- package/dist/plugin-sdk/discord/resolve-channels.d.ts +15 -0
- package/dist/plugin-sdk/discord/resolve-users.d.ts +14 -0
- package/dist/plugin-sdk/discord/send.channels.d.ts +17 -0
- package/dist/plugin-sdk/discord/send.components.d.ts +17 -0
- package/dist/plugin-sdk/discord/send.d.ts +10 -0
- package/dist/plugin-sdk/discord/send.emojis-stickers.d.ts +4 -0
- package/dist/plugin-sdk/discord/send.guild.d.ts +24 -0
- package/dist/plugin-sdk/discord/send.messages.d.ts +20 -0
- package/dist/plugin-sdk/discord/send.outbound.d.ts +57 -0
- package/dist/plugin-sdk/discord/send.permissions.d.ts +20 -0
- package/dist/plugin-sdk/discord/send.reactions.d.ts +15 -0
- package/dist/plugin-sdk/discord/send.shared.d.ts +85 -0
- package/dist/plugin-sdk/discord/send.types.d.ts +144 -0
- package/dist/plugin-sdk/discord/targets.d.ts +18 -0
- package/dist/plugin-sdk/discord/token.d.ts +11 -0
- package/dist/plugin-sdk/discord/voice/command.d.ts +15 -0
- package/dist/plugin-sdk/discord/voice/manager.d.ts +52 -0
- package/dist/plugin-sdk/discord/voice-message.d.ts +50 -0
- package/dist/plugin-sdk/gateway/call.d.ts +65 -0
- package/dist/plugin-sdk/gateway/chat-abort.d.ts +44 -0
- package/dist/plugin-sdk/gateway/chat-sanitize.d.ts +4 -0
- package/dist/plugin-sdk/gateway/client.d.ts +64 -0
- package/dist/plugin-sdk/gateway/control-ui-shared.d.ts +9 -0
- package/dist/plugin-sdk/gateway/credentials.d.ts +36 -0
- package/dist/plugin-sdk/gateway/device-auth.d.ts +11 -0
- package/dist/plugin-sdk/gateway/method-scopes.d.ts +22 -0
- package/dist/plugin-sdk/gateway/net.d.ts +77 -0
- package/dist/plugin-sdk/gateway/node-registry.d.ts +60 -0
- package/dist/plugin-sdk/gateway/protocol/client-info.d.ts +58 -0
- package/dist/plugin-sdk/gateway/protocol/index.d.ts +497 -0
- package/dist/plugin-sdk/gateway/protocol/schema/agent.d.ts +89 -0
- package/dist/plugin-sdk/gateway/protocol/schema/agents-models-skills.d.ts +188 -0
- package/dist/plugin-sdk/gateway/protocol/schema/channels.d.ts +134 -0
- package/dist/plugin-sdk/gateway/protocol/schema/config.d.ts +53 -0
- package/dist/plugin-sdk/gateway/protocol/schema/cron.d.ts +324 -0
- package/dist/plugin-sdk/gateway/protocol/schema/devices.d.ts +41 -0
- package/dist/plugin-sdk/gateway/protocol/schema/error-codes.d.ts +14 -0
- package/dist/plugin-sdk/gateway/protocol/schema/frames.d.ts +168 -0
- package/dist/plugin-sdk/gateway/protocol/schema/logs-chat.d.ts +45 -0
- package/dist/plugin-sdk/gateway/protocol/schema/nodes.d.ts +64 -0
- package/dist/plugin-sdk/gateway/protocol/schema/primitives.d.ts +4 -0
- package/dist/plugin-sdk/gateway/protocol/schema/protocol-schemas.d.ts +3 -0
- package/dist/plugin-sdk/gateway/protocol/schema/push.d.ts +15 -0
- package/dist/plugin-sdk/gateway/protocol/schema/sessions.d.ts +81 -0
- package/dist/plugin-sdk/gateway/protocol/schema/snapshot.d.ts +69 -0
- package/dist/plugin-sdk/gateway/protocol/schema/types.d.ts +120 -0
- package/dist/plugin-sdk/gateway/protocol/schema/wizard.d.ts +86 -0
- package/dist/plugin-sdk/gateway/protocol/schema.d.ts +16 -0
- package/dist/plugin-sdk/gateway/server/ws-types.d.ts +9 -0
- package/dist/plugin-sdk/gateway/server-broadcast.d.ts +17 -0
- package/dist/plugin-sdk/gateway/server-channels.d.ts +26 -0
- package/dist/plugin-sdk/gateway/server-constants.d.ts +10 -0
- package/dist/plugin-sdk/gateway/server-methods/types.d.ts +84 -0
- package/dist/plugin-sdk/gateway/server-shared.d.ts +7 -0
- package/dist/plugin-sdk/gateway/session-utils.fs.d.ts +48 -0
- package/dist/plugin-sdk/gateway/session-utils.types.d.ts +84 -0
- package/dist/plugin-sdk/gateway/ws-log.d.ts +5 -0
- package/dist/plugin-sdk/gateway/ws-logging.d.ts +4 -0
- package/dist/plugin-sdk/globals.d.ts +11 -0
- package/dist/plugin-sdk/hooks/internal-hooks.d.ts +140 -0
- package/dist/plugin-sdk/hooks/types.d.ts +62 -0
- package/dist/plugin-sdk/imessage/accounts.d.ts +16 -0
- package/dist/plugin-sdk/imessage/client.d.ts +46 -0
- package/dist/plugin-sdk/imessage/constants.d.ts +2 -0
- package/dist/plugin-sdk/imessage/monitor/abort-handler.d.ts +9 -0
- package/dist/plugin-sdk/imessage/monitor/deliver.d.ts +14 -0
- package/dist/plugin-sdk/imessage/monitor/echo-cache.d.ts +9 -0
- package/dist/plugin-sdk/imessage/monitor/inbound-processing.d.ts +96 -0
- package/dist/plugin-sdk/imessage/monitor/monitor-provider.d.ts +7 -0
- package/dist/plugin-sdk/imessage/monitor/parse-notification.d.ts +2 -0
- package/dist/plugin-sdk/imessage/monitor/runtime.d.ts +4 -0
- package/dist/plugin-sdk/imessage/monitor/types.d.ts +37 -0
- package/dist/plugin-sdk/imessage/monitor.d.ts +2 -0
- package/dist/plugin-sdk/imessage/probe.d.ts +17 -0
- package/dist/plugin-sdk/imessage/send.d.ts +34 -0
- package/dist/plugin-sdk/imessage/target-parsing-helpers.d.ts +45 -0
- package/dist/plugin-sdk/imessage/targets.d.ts +39 -0
- package/dist/plugin-sdk/index.d.ts +1 -0
- package/dist/plugin-sdk/index.js +24645 -0
- package/dist/plugin-sdk/infra/agent-events.d.ts +21 -0
- package/dist/plugin-sdk/infra/archive-path.d.ts +12 -0
- package/dist/plugin-sdk/infra/archive.d.ts +46 -0
- package/dist/plugin-sdk/infra/backoff.d.ts +8 -0
- package/dist/plugin-sdk/infra/brew.d.ts +8 -0
- package/dist/plugin-sdk/infra/channel-activity.d.ts +18 -0
- package/dist/plugin-sdk/infra/channel-summary.d.ts +6 -0
- package/dist/plugin-sdk/infra/dedupe.d.ts +12 -0
- package/dist/plugin-sdk/infra/device-auth-store.d.ts +18 -0
- package/dist/plugin-sdk/infra/device-identity.d.ts +11 -0
- package/dist/plugin-sdk/infra/device-pairing.d.ts +101 -0
- package/dist/plugin-sdk/infra/diagnostic-events.d.ts +140 -0
- package/dist/plugin-sdk/infra/diagnostic-flags.d.ts +4 -0
- package/dist/plugin-sdk/infra/dotenv.d.ts +3 -0
- package/dist/plugin-sdk/infra/env.d.ts +11 -0
- package/dist/plugin-sdk/infra/errors.d.ts +11 -0
- package/dist/plugin-sdk/infra/fetch.d.ts +2 -0
- package/dist/plugin-sdk/infra/file-identity.d.ts +5 -0
- package/dist/plugin-sdk/infra/file-lock.d.ts +2 -0
- package/dist/plugin-sdk/infra/format-time/format-datetime.d.ts +35 -0
- package/dist/plugin-sdk/infra/format-time/format-duration.d.ts +23 -0
- package/dist/plugin-sdk/infra/format-time/format-relative.d.ts +39 -0
- package/dist/plugin-sdk/infra/fs-safe.d.ts +25 -0
- package/dist/plugin-sdk/infra/gemini-auth.d.ts +16 -0
- package/dist/plugin-sdk/infra/git-commit.d.ts +4 -0
- package/dist/plugin-sdk/infra/git-root.d.ts +7 -0
- package/dist/plugin-sdk/infra/heartbeat-active-hours.d.ts +5 -0
- package/dist/plugin-sdk/infra/heartbeat-events-filter.d.ts +8 -0
- package/dist/plugin-sdk/infra/heartbeat-events.d.ts +21 -0
- package/dist/plugin-sdk/infra/heartbeat-reason.d.ts +5 -0
- package/dist/plugin-sdk/infra/heartbeat-runner.d.ts +45 -0
- package/dist/plugin-sdk/infra/heartbeat-visibility.d.ts +17 -0
- package/dist/plugin-sdk/infra/heartbeat-wake.d.ts +31 -0
- package/dist/plugin-sdk/infra/home-dir.d.ts +7 -0
- package/dist/plugin-sdk/infra/host-env-security.d.ts +21 -0
- package/dist/plugin-sdk/infra/http-body.d.ts +46 -0
- package/dist/plugin-sdk/infra/json-file.d.ts +2 -0
- package/dist/plugin-sdk/infra/json-files.d.ts +5 -0
- package/dist/plugin-sdk/infra/map-size.d.ts +1 -0
- package/dist/plugin-sdk/infra/net/fetch-guard.d.ts +21 -0
- package/dist/plugin-sdk/infra/net/hostname.d.ts +1 -0
- package/dist/plugin-sdk/infra/net/ssrf.d.ts +35 -0
- package/dist/plugin-sdk/infra/outbound/abort.d.ts +8 -0
- package/dist/plugin-sdk/infra/outbound/agent-delivery.d.ts +46 -0
- package/dist/plugin-sdk/infra/outbound/bound-delivery-router.d.ts +16 -0
- package/dist/plugin-sdk/infra/outbound/channel-selection.d.ts +11 -0
- package/dist/plugin-sdk/infra/outbound/channel-target.d.ts +6 -0
- package/dist/plugin-sdk/infra/outbound/deliver.d.ts +81 -0
- package/dist/plugin-sdk/infra/outbound/delivery-queue.d.ts +78 -0
- package/dist/plugin-sdk/infra/outbound/directory-cache.d.ts +24 -0
- package/dist/plugin-sdk/infra/outbound/envelope.d.ts +16 -0
- package/dist/plugin-sdk/infra/outbound/format.d.ts +39 -0
- package/dist/plugin-sdk/infra/outbound/identity.d.ts +8 -0
- package/dist/plugin-sdk/infra/outbound/message-action-spec.d.ts +5 -0
- package/dist/plugin-sdk/infra/outbound/payloads.d.ts +18 -0
- package/dist/plugin-sdk/infra/outbound/session-binding-service.d.ts +57 -0
- package/dist/plugin-sdk/infra/outbound/target-errors.d.ts +6 -0
- package/dist/plugin-sdk/infra/outbound/target-normalization.d.ts +4 -0
- package/dist/plugin-sdk/infra/outbound/target-resolver.d.ts +53 -0
- package/dist/plugin-sdk/infra/outbound/targets.d.ts +87 -0
- package/dist/plugin-sdk/infra/pairing-files.d.ts +23 -0
- package/dist/plugin-sdk/infra/pairing-pending.d.ts +13 -0
- package/dist/plugin-sdk/infra/pairing-token.d.ts +3 -0
- package/dist/plugin-sdk/infra/path-guards.d.ts +5 -0
- package/dist/plugin-sdk/infra/path-safety.d.ts +2 -0
- package/dist/plugin-sdk/infra/plain-object.d.ts +4 -0
- package/dist/plugin-sdk/infra/prototype-keys.d.ts +1 -0
- package/dist/plugin-sdk/infra/provider-usage.auth.d.ts +11 -0
- package/dist/plugin-sdk/infra/provider-usage.d.ts +4 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.claude.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.codex.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.copilot.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.d.ts +6 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.gemini.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.minimax.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.shared.d.ts +12 -0
- package/dist/plugin-sdk/infra/provider-usage.fetch.zai.d.ts +2 -0
- package/dist/plugin-sdk/infra/provider-usage.format.d.ts +13 -0
- package/dist/plugin-sdk/infra/provider-usage.load.d.ts +12 -0
- package/dist/plugin-sdk/infra/provider-usage.shared.d.ts +8 -0
- package/dist/plugin-sdk/infra/provider-usage.types.d.ts +17 -0
- package/dist/plugin-sdk/infra/restart.d.ts +70 -0
- package/dist/plugin-sdk/infra/retry-policy.d.ts +25 -0
- package/dist/plugin-sdk/infra/retry.d.ts +21 -0
- package/dist/plugin-sdk/infra/safe-executable-value.d.ts +1 -0
- package/dist/plugin-sdk/infra/scp-host.d.ts +2 -0
- package/dist/plugin-sdk/infra/secure-random.d.ts +2 -0
- package/dist/plugin-sdk/infra/session-cost-usage.d.ts +45 -0
- package/dist/plugin-sdk/infra/session-cost-usage.types.d.ts +153 -0
- package/dist/plugin-sdk/infra/session-maintenance-warning.d.ts +10 -0
- package/dist/plugin-sdk/infra/shell-env.d.ts +34 -0
- package/dist/plugin-sdk/infra/system-events.d.ts +18 -0
- package/dist/plugin-sdk/infra/tailnet.d.ts +8 -0
- package/dist/plugin-sdk/infra/tls/fingerprint.d.ts +1 -0
- package/dist/plugin-sdk/infra/tls/gateway.d.ts +16 -0
- package/dist/plugin-sdk/infra/tmp-remoteclaw-dir.d.ts +18 -0
- package/dist/plugin-sdk/infra/transport-ready.d.ts +16 -0
- package/dist/plugin-sdk/infra/unhandled-rejections.d.ts +15 -0
- package/dist/plugin-sdk/infra/ws.d.ts +2 -0
- package/dist/plugin-sdk/infra/wsl.d.ts +11 -0
- package/dist/plugin-sdk/line/accounts.d.ts +10 -0
- package/dist/plugin-sdk/line/actions.d.ts +22 -0
- package/dist/plugin-sdk/line/auto-reply-delivery.d.ts +38 -0
- package/dist/plugin-sdk/line/bot-access.d.ts +17 -0
- package/dist/plugin-sdk/line/bot-handlers.d.ts +13 -0
- package/dist/plugin-sdk/line/bot-message-context.d.ts +118 -0
- package/dist/plugin-sdk/line/bot.d.ts +24 -0
- package/dist/plugin-sdk/line/channel-access-token.d.ts +4 -0
- package/dist/plugin-sdk/line/config-schema.d.ts +64 -0
- package/dist/plugin-sdk/line/download.d.ts +7 -0
- package/dist/plugin-sdk/line/flex-templates/basic-cards.d.ts +46 -0
- package/dist/plugin-sdk/line/flex-templates/common.d.ts +2 -0
- package/dist/plugin-sdk/line/flex-templates/media-control-cards.d.ts +73 -0
- package/dist/plugin-sdk/line/flex-templates/message.d.ts +6 -0
- package/dist/plugin-sdk/line/flex-templates/schedule-cards.d.ts +55 -0
- package/dist/plugin-sdk/line/flex-templates/types.d.ts +19 -0
- package/dist/plugin-sdk/line/flex-templates.d.ts +5 -0
- package/dist/plugin-sdk/line/markdown-to-line.d.ts +72 -0
- package/dist/plugin-sdk/line/monitor.d.ts +28 -0
- package/dist/plugin-sdk/line/probe.d.ts +2 -0
- package/dist/plugin-sdk/line/reply-chunks.d.ts +24 -0
- package/dist/plugin-sdk/line/send.d.ts +91 -0
- package/dist/plugin-sdk/line/signature.d.ts +1 -0
- package/dist/plugin-sdk/line/template-messages.d.ts +100 -0
- package/dist/plugin-sdk/line/types.d.ts +113 -0
- package/dist/plugin-sdk/line/webhook-node.d.ts +15 -0
- package/dist/plugin-sdk/line/webhook-utils.d.ts +3 -0
- package/dist/plugin-sdk/line/webhook.d.ts +19 -0
- package/dist/plugin-sdk/link-understanding/apply.d.ts +10 -0
- package/dist/plugin-sdk/link-understanding/defaults.d.ts +2 -0
- package/dist/plugin-sdk/link-understanding/detect.d.ts +3 -0
- package/dist/plugin-sdk/link-understanding/format.d.ts +4 -0
- package/dist/plugin-sdk/link-understanding/runner.d.ts +11 -0
- package/dist/plugin-sdk/logger.d.ts +6 -0
- package/dist/plugin-sdk/logging/config.d.ts +4 -0
- package/dist/plugin-sdk/logging/console.d.ts +23 -0
- package/dist/plugin-sdk/logging/diagnostic-session-state.d.ts +30 -0
- package/dist/plugin-sdk/logging/diagnostic.d.ts +65 -0
- package/dist/plugin-sdk/logging/env-log-level.d.ts +2 -0
- package/dist/plugin-sdk/logging/levels.d.ts +5 -0
- package/dist/plugin-sdk/logging/logger.d.ts +44 -0
- package/dist/plugin-sdk/logging/node-require.d.ts +1 -0
- package/dist/plugin-sdk/logging/redact-identifier.d.ts +4 -0
- package/dist/plugin-sdk/logging/redact.d.ts +9 -0
- package/dist/plugin-sdk/logging/state.d.ts +19 -0
- package/dist/plugin-sdk/logging/subsystem.d.ts +18 -0
- package/dist/plugin-sdk/logging/timestamps.d.ts +1 -0
- package/dist/plugin-sdk/logging.d.ts +10 -0
- package/dist/plugin-sdk/markdown/fences.d.ts +10 -0
- package/dist/plugin-sdk/markdown/ir.d.ts +32 -0
- package/dist/plugin-sdk/markdown/render.d.ts +18 -0
- package/dist/plugin-sdk/markdown/tables.d.ts +2 -0
- package/dist/plugin-sdk/markdown/whatsapp.d.ts +14 -0
- package/dist/plugin-sdk/media/audio-tags.d.ts +10 -0
- package/dist/plugin-sdk/media/audio.d.ts +19 -0
- package/dist/plugin-sdk/media/base64.d.ts +6 -0
- package/dist/plugin-sdk/media/constants.d.ts +7 -0
- package/dist/plugin-sdk/media/fetch.d.ts +23 -0
- package/dist/plugin-sdk/media/image-ops.d.ts +41 -0
- package/dist/plugin-sdk/media/inbound-path-policy.d.ts +18 -0
- package/dist/plugin-sdk/media/input-files.d.ts +95 -0
- package/dist/plugin-sdk/media/local-roots.d.ts +3 -0
- package/dist/plugin-sdk/media/mime.d.ts +16 -0
- package/dist/plugin-sdk/media/outbound-attachment.d.ts +6 -0
- package/dist/plugin-sdk/media/parse.d.ts +8 -0
- package/dist/plugin-sdk/media/png-encode.d.ts +8 -0
- package/dist/plugin-sdk/media/read-response-with-limit.d.ts +7 -0
- package/dist/plugin-sdk/media/store.d.ts +33 -0
- package/dist/plugin-sdk/media-understanding/apply.d.ts +19 -0
- package/dist/plugin-sdk/media-understanding/attachments.d.ts +49 -0
- package/dist/plugin-sdk/media-understanding/audio-preflight.d.ts +16 -0
- package/dist/plugin-sdk/media-understanding/concurrency.d.ts +1 -0
- package/dist/plugin-sdk/media-understanding/defaults.d.ts +12 -0
- package/dist/plugin-sdk/media-understanding/errors.d.ts +6 -0
- package/dist/plugin-sdk/media-understanding/format.d.ts +7 -0
- package/dist/plugin-sdk/media-understanding/fs.d.ts +1 -0
- package/dist/plugin-sdk/media-understanding/output-extract.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/anthropic/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/deepgram/audio.d.ts +4 -0
- package/dist/plugin-sdk/media-understanding/providers/deepgram/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/google/audio.d.ts +3 -0
- package/dist/plugin-sdk/media-understanding/providers/google/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/google/inline-data.d.ts +20 -0
- package/dist/plugin-sdk/media-understanding/providers/google/video.d.ts +3 -0
- package/dist/plugin-sdk/media-understanding/providers/groq/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/index.d.ts +4 -0
- package/dist/plugin-sdk/media-understanding/providers/minimax/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/mistral/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/moonshot/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/moonshot/video.d.ts +3 -0
- package/dist/plugin-sdk/media-understanding/providers/openai/audio.d.ts +3 -0
- package/dist/plugin-sdk/media-understanding/providers/openai/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/providers/shared.d.ts +20 -0
- package/dist/plugin-sdk/media-understanding/providers/zai/index.d.ts +2 -0
- package/dist/plugin-sdk/media-understanding/resolve.d.ts +44 -0
- package/dist/plugin-sdk/media-understanding/runner.d.ts +34 -0
- package/dist/plugin-sdk/media-understanding/runner.entries.d.ts +33 -0
- package/dist/plugin-sdk/media-understanding/scope.d.ts +9 -0
- package/dist/plugin-sdk/media-understanding/types.d.ts +74 -0
- package/dist/plugin-sdk/media-understanding/video.d.ts +2 -0
- package/dist/plugin-sdk/middleware/channel-bridge.d.ts +39 -0
- package/dist/plugin-sdk/middleware/cli-runtime-base.d.ts +35 -0
- package/dist/plugin-sdk/middleware/delivery-adapter.d.ts +36 -0
- package/dist/plugin-sdk/middleware/error-classifier.d.ts +14 -0
- package/dist/plugin-sdk/middleware/mcp-side-effects.d.ts +20 -0
- package/dist/plugin-sdk/middleware/runtime-factory.d.ts +4 -0
- package/dist/plugin-sdk/middleware/runtimes/claude.d.ts +27 -0
- package/dist/plugin-sdk/middleware/runtimes/codex.d.ts +74 -0
- package/dist/plugin-sdk/middleware/runtimes/gemini.d.ts +52 -0
- package/dist/plugin-sdk/middleware/runtimes/opencode.d.ts +54 -0
- package/dist/plugin-sdk/middleware/session-map.d.ts +36 -0
- package/dist/plugin-sdk/middleware/system-prompt.d.ts +30 -0
- package/dist/plugin-sdk/middleware/types.d.ts +188 -0
- package/dist/plugin-sdk/pairing/pairing-labels.d.ts +2 -0
- package/dist/plugin-sdk/pairing/pairing-messages.d.ts +6 -0
- package/dist/plugin-sdk/pairing/pairing-store.d.ts +48 -0
- package/dist/plugin-sdk/plugin-sdk/account-id.d.ts +1 -0
- package/dist/plugin-sdk/plugin-sdk/agent-media-payload.d.ts +12 -0
- package/dist/plugin-sdk/plugin-sdk/allow-from.d.ts +32 -0
- package/dist/plugin-sdk/plugin-sdk/command-auth.d.ts +25 -0
- package/dist/plugin-sdk/plugin-sdk/config-paths.d.ts +6 -0
- package/dist/plugin-sdk/plugin-sdk/file-lock.d.ts +16 -0
- package/dist/plugin-sdk/plugin-sdk/group-access.d.ts +16 -0
- package/dist/plugin-sdk/plugin-sdk/index.d.ts +162 -0
- package/dist/plugin-sdk/plugin-sdk/json-store.d.ts +5 -0
- package/dist/plugin-sdk/plugin-sdk/onboarding.d.ts +11 -0
- package/dist/plugin-sdk/plugin-sdk/persistent-dedupe.d.ts +20 -0
- package/dist/plugin-sdk/plugin-sdk/reply-payload.d.ts +22 -0
- package/dist/plugin-sdk/plugin-sdk/run-command.d.ts +12 -0
- package/dist/plugin-sdk/plugin-sdk/runtime.d.ts +10 -0
- package/dist/plugin-sdk/plugin-sdk/slack-message-actions.d.ts +11 -0
- package/dist/plugin-sdk/plugin-sdk/status-helpers.d.ts +88 -0
- package/dist/plugin-sdk/plugin-sdk/temp-path.d.ts +12 -0
- package/dist/plugin-sdk/plugin-sdk/text-chunking.d.ts +1 -0
- package/dist/plugin-sdk/plugin-sdk/tool-send.d.ts +4 -0
- package/dist/plugin-sdk/plugin-sdk/webhook-path.d.ts +6 -0
- package/dist/plugin-sdk/plugin-sdk/webhook-targets.d.ts +23 -0
- package/dist/plugin-sdk/plugins/bundled-dir.d.ts +1 -0
- package/dist/plugin-sdk/plugins/commands.d.ts +83 -0
- package/dist/plugin-sdk/plugins/config-schema.d.ts +2 -0
- package/dist/plugin-sdk/plugins/config-state.d.ts +30 -0
- package/dist/plugin-sdk/plugins/discovery.d.ts +24 -0
- package/dist/plugin-sdk/plugins/hook-runner-global.d.ts +37 -0
- package/dist/plugin-sdk/plugins/hooks.d.ts +49 -0
- package/dist/plugin-sdk/plugins/http-path.d.ts +1 -0
- package/dist/plugin-sdk/plugins/http-registry.d.ts +13 -0
- package/dist/plugin-sdk/plugins/manifest-registry.d.ts +34 -0
- package/dist/plugin-sdk/plugins/manifest.d.ts +66 -0
- package/dist/plugin-sdk/plugins/path-safety.d.ts +5 -0
- package/dist/plugin-sdk/plugins/registry.d.ts +130 -0
- package/dist/plugin-sdk/plugins/runtime/native-deps.d.ts +8 -0
- package/dist/plugin-sdk/plugins/runtime/types.d.ts +310 -0
- package/dist/plugin-sdk/plugins/runtime.d.ts +5 -0
- package/dist/plugin-sdk/plugins/schema-validator.d.ts +10 -0
- package/dist/plugin-sdk/plugins/types.d.ts +487 -0
- package/dist/plugin-sdk/polls.d.ts +31 -0
- package/dist/plugin-sdk/process/command-queue.d.ts +51 -0
- package/dist/plugin-sdk/process/exec.d.ts +30 -0
- package/dist/plugin-sdk/process/lanes.d.ts +6 -0
- package/dist/plugin-sdk/process/spawn-utils.d.ts +26 -0
- package/dist/plugin-sdk/routing/account-id.d.ts +3 -0
- package/dist/plugin-sdk/routing/account-lookup.d.ts +1 -0
- package/dist/plugin-sdk/routing/bindings.d.ts +11 -0
- package/dist/plugin-sdk/routing/resolve-route.d.ts +42 -0
- package/dist/plugin-sdk/routing/session-key.d.ts +48 -0
- package/dist/plugin-sdk/runtime.d.ts +7 -0
- package/dist/plugin-sdk/security/channel-metadata.d.ts +6 -0
- package/dist/plugin-sdk/security/dm-policy-shared.d.ts +33 -0
- package/dist/plugin-sdk/security/external-content.d.ts +53 -0
- package/dist/plugin-sdk/security/safe-regex.d.ts +2 -0
- package/dist/plugin-sdk/security/scan-paths.d.ts +5 -0
- package/dist/plugin-sdk/security/secret-equal.d.ts +1 -0
- package/dist/plugin-sdk/sessions/input-provenance.d.ts +16 -0
- package/dist/plugin-sdk/sessions/level-overrides.d.ts +10 -0
- package/dist/plugin-sdk/sessions/model-overrides.d.ts +14 -0
- package/dist/plugin-sdk/sessions/send-policy.d.ts +11 -0
- package/dist/plugin-sdk/sessions/session-key-utils.d.ts +16 -0
- package/dist/plugin-sdk/sessions/session-label.d.ts +9 -0
- package/dist/plugin-sdk/sessions/transcript-events.d.ts +7 -0
- package/dist/plugin-sdk/shared/avatar-policy.d.ts +16 -0
- package/dist/plugin-sdk/shared/chat-content.d.ts +5 -0
- package/dist/plugin-sdk/shared/chat-envelope.d.ts +2 -0
- package/dist/plugin-sdk/shared/device-auth.d.ts +13 -0
- package/dist/plugin-sdk/shared/gateway-bind-url.d.ts +14 -0
- package/dist/plugin-sdk/shared/net/ip.d.ts +19 -0
- package/dist/plugin-sdk/shared/operator-scope-compat.d.ts +5 -0
- package/dist/plugin-sdk/shared/pid-alive.d.ts +1 -0
- package/dist/plugin-sdk/shared/process-scoped-map.d.ts +1 -0
- package/dist/plugin-sdk/shared/string-normalization.d.ts +4 -0
- package/dist/plugin-sdk/shared/subagents-format.d.ts +15 -0
- package/dist/plugin-sdk/shared/tailscale-status.d.ts +8 -0
- package/dist/plugin-sdk/shared/text/code-regions.d.ts +6 -0
- package/dist/plugin-sdk/shared/text/reasoning-tags.d.ts +6 -0
- package/dist/plugin-sdk/shared/text-chunking.d.ts +1 -0
- package/dist/plugin-sdk/signal/accounts.d.ts +17 -0
- package/dist/plugin-sdk/signal/client.d.ts +32 -0
- package/dist/plugin-sdk/signal/daemon.d.ts +26 -0
- package/dist/plugin-sdk/signal/format.d.ts +17 -0
- package/dist/plugin-sdk/signal/identity.d.ts +24 -0
- package/dist/plugin-sdk/signal/index.d.ts +5 -0
- package/dist/plugin-sdk/signal/monitor/event-handler.d.ts +5 -0
- package/dist/plugin-sdk/signal/monitor/event-handler.types.d.ts +125 -0
- package/dist/plugin-sdk/signal/monitor/mentions.d.ts +2 -0
- package/dist/plugin-sdk/signal/monitor.d.ts +25 -0
- package/dist/plugin-sdk/signal/probe.d.ts +7 -0
- package/dist/plugin-sdk/signal/reaction-level.d.ts +17 -0
- package/dist/plugin-sdk/signal/rpc-context.d.ts +9 -0
- package/dist/plugin-sdk/signal/send-reactions.d.ts +32 -0
- package/dist/plugin-sdk/signal/send.d.ts +25 -0
- package/dist/plugin-sdk/signal/sse-reconnect.d.ts +13 -0
- package/dist/plugin-sdk/slack/accounts.d.ts +32 -0
- package/dist/plugin-sdk/slack/actions.d.ts +56 -0
- package/dist/plugin-sdk/slack/blocks-fallback.d.ts +2 -0
- package/dist/plugin-sdk/slack/blocks-input.d.ts +3 -0
- package/dist/plugin-sdk/slack/channel-migration.d.ts +20 -0
- package/dist/plugin-sdk/slack/client.d.ts +4 -0
- package/dist/plugin-sdk/slack/directory-live.d.ts +4 -0
- package/dist/plugin-sdk/slack/draft-stream.d.ts +25 -0
- package/dist/plugin-sdk/slack/format.d.ts +7 -0
- package/dist/plugin-sdk/slack/http/index.d.ts +1 -0
- package/dist/plugin-sdk/slack/http/registry.d.ts +12 -0
- package/dist/plugin-sdk/slack/index.d.ts +6 -0
- package/dist/plugin-sdk/slack/message-actions.d.ts +4 -0
- package/dist/plugin-sdk/slack/modal-metadata.d.ts +7 -0
- package/dist/plugin-sdk/slack/monitor/allow-list.d.ts +23 -0
- package/dist/plugin-sdk/slack/monitor/auth.d.ts +11 -0
- package/dist/plugin-sdk/slack/monitor/channel-config.d.ts +43 -0
- package/dist/plugin-sdk/slack/monitor/commands.d.ts +9 -0
- package/dist/plugin-sdk/slack/monitor/context.d.ts +104 -0
- package/dist/plugin-sdk/slack/monitor/events/channels.d.ts +4 -0
- package/dist/plugin-sdk/slack/monitor/events/interactions.d.ts +4 -0
- package/dist/plugin-sdk/slack/monitor/events/members.d.ts +4 -0
- package/dist/plugin-sdk/slack/monitor/events/messages.d.ts +6 -0
- package/dist/plugin-sdk/slack/monitor/events/pins.d.ts +4 -0
- package/dist/plugin-sdk/slack/monitor/events/reactions.d.ts +4 -0
- package/dist/plugin-sdk/slack/monitor/events.d.ts +8 -0
- package/dist/plugin-sdk/slack/monitor/external-arg-menu-store.d.ts +18 -0
- package/dist/plugin-sdk/slack/monitor/media.d.ts +66 -0
- package/dist/plugin-sdk/slack/monitor/message-handler/dispatch.d.ts +12 -0
- package/dist/plugin-sdk/slack/monitor/message-handler/prepare.d.ts +13 -0
- package/dist/plugin-sdk/slack/monitor/message-handler/types.d.ts +22 -0
- package/dist/plugin-sdk/slack/monitor/message-handler.d.ts +11 -0
- package/dist/plugin-sdk/slack/monitor/mrkdwn.d.ts +1 -0
- package/dist/plugin-sdk/slack/monitor/policy.d.ts +5 -0
- package/dist/plugin-sdk/slack/monitor/provider.d.ts +7 -0
- package/dist/plugin-sdk/slack/monitor/replies.d.ts +53 -0
- package/dist/plugin-sdk/slack/monitor/room-context.d.ts +14 -0
- package/dist/plugin-sdk/slack/monitor/slash.d.ts +6 -0
- package/dist/plugin-sdk/slack/monitor/thread-resolution.d.ts +12 -0
- package/dist/plugin-sdk/slack/monitor/types.d.ts +97 -0
- package/dist/plugin-sdk/slack/monitor.d.ts +5 -0
- package/dist/plugin-sdk/slack/probe.d.ts +14 -0
- package/dist/plugin-sdk/slack/resolve-channels.d.ts +19 -0
- package/dist/plugin-sdk/slack/resolve-users.d.ts +26 -0
- package/dist/plugin-sdk/slack/send.d.ts +22 -0
- package/dist/plugin-sdk/slack/stream-mode.d.ts +23 -0
- package/dist/plugin-sdk/slack/streaming.d.ts +72 -0
- package/dist/plugin-sdk/slack/targets.d.ts +7 -0
- package/dist/plugin-sdk/slack/threading-tool-context.d.ts +10 -0
- package/dist/plugin-sdk/slack/threading.d.ts +29 -0
- package/dist/plugin-sdk/slack/token.d.ts +3 -0
- package/dist/plugin-sdk/slack/types.d.ts +58 -0
- package/dist/plugin-sdk/telegram/accounts.d.ts +21 -0
- package/dist/plugin-sdk/telegram/allowed-updates.d.ts +4 -0
- package/dist/plugin-sdk/telegram/api-logging.d.ts +11 -0
- package/dist/plugin-sdk/telegram/audit.d.ts +29 -0
- package/dist/plugin-sdk/telegram/bot/delivery.d.ts +35 -0
- package/dist/plugin-sdk/telegram/bot/helpers.d.ts +128 -0
- package/dist/plugin-sdk/telegram/bot/types.d.ts +28 -0
- package/dist/plugin-sdk/telegram/bot-access.d.ts +26 -0
- package/dist/plugin-sdk/telegram/bot-handlers.d.ts +2 -0
- package/dist/plugin-sdk/telegram/bot-message-context.d.ts +145 -0
- package/dist/plugin-sdk/telegram/bot-message-dispatch.d.ts +19 -0
- package/dist/plugin-sdk/telegram/bot-message.d.ts +20 -0
- package/dist/plugin-sdk/telegram/bot-native-command-menu.d.ts +33 -0
- package/dist/plugin-sdk/telegram/bot-native-commands.d.ts +59 -0
- package/dist/plugin-sdk/telegram/bot-updates.d.ts +31 -0
- package/dist/plugin-sdk/telegram/bot.d.ts +62 -0
- package/dist/plugin-sdk/telegram/button-types.d.ts +7 -0
- package/dist/plugin-sdk/telegram/caption.d.ts +5 -0
- package/dist/plugin-sdk/telegram/dm-access.d.ts +18 -0
- package/dist/plugin-sdk/telegram/draft-stream.d.ts +37 -0
- package/dist/plugin-sdk/telegram/fetch.d.ts +5 -0
- package/dist/plugin-sdk/telegram/format.d.ts +18 -0
- package/dist/plugin-sdk/telegram/group-access.d.ts +54 -0
- package/dist/plugin-sdk/telegram/group-config-helpers.d.ts +8 -0
- package/dist/plugin-sdk/telegram/group-migration.d.ts +20 -0
- package/dist/plugin-sdk/telegram/inline-buttons.d.ts +11 -0
- package/dist/plugin-sdk/telegram/lane-delivery.d.ts +56 -0
- package/dist/plugin-sdk/telegram/monitor.d.ts +19 -0
- package/dist/plugin-sdk/telegram/network-config.d.ts +33 -0
- package/dist/plugin-sdk/telegram/network-errors.d.ts +5 -0
- package/dist/plugin-sdk/telegram/outbound-params.d.ts +2 -0
- package/dist/plugin-sdk/telegram/probe.d.ts +17 -0
- package/dist/plugin-sdk/telegram/proxy.d.ts +1 -0
- package/dist/plugin-sdk/telegram/reaction-level.d.ts +11 -0
- package/dist/plugin-sdk/telegram/reasoning-lane-coordinator.d.ts +18 -0
- package/dist/plugin-sdk/telegram/send.d.ts +153 -0
- package/dist/plugin-sdk/telegram/sent-message-cache.d.ts +16 -0
- package/dist/plugin-sdk/telegram/status-reaction-variants.d.ts +21 -0
- package/dist/plugin-sdk/telegram/sticker-cache.d.ts +47 -0
- package/dist/plugin-sdk/telegram/target-writeback.d.ts +7 -0
- package/dist/plugin-sdk/telegram/targets.d.ts +11 -0
- package/dist/plugin-sdk/telegram/token.d.ts +13 -0
- package/dist/plugin-sdk/telegram/update-offset-store.d.ts +15 -0
- package/dist/plugin-sdk/telegram/voice.d.ts +16 -0
- package/dist/plugin-sdk/telegram/webhook.d.ts +20 -0
- package/dist/plugin-sdk/terminal/ansi.d.ts +2 -0
- package/dist/plugin-sdk/terminal/health-style.d.ts +1 -0
- package/dist/plugin-sdk/terminal/links.d.ts +6 -0
- package/dist/plugin-sdk/terminal/palette.d.ts +10 -0
- package/dist/plugin-sdk/terminal/progress-line.d.ts +3 -0
- package/dist/plugin-sdk/terminal/prompt-style.d.ts +3 -0
- package/dist/plugin-sdk/terminal/restore.d.ts +17 -0
- package/dist/plugin-sdk/terminal/theme.d.ts +15 -0
- package/dist/plugin-sdk/tts/tts-core.d.ts +38 -0
- package/dist/plugin-sdk/tts/tts.d.ts +177 -0
- package/dist/plugin-sdk/types/agent-types.d.ts +1 -0
- package/dist/plugin-sdk/utils/account-id.d.ts +1 -0
- package/dist/plugin-sdk/utils/boolean.d.ts +5 -0
- package/dist/plugin-sdk/utils/chunk-items.d.ts +1 -0
- package/dist/plugin-sdk/utils/delivery-context.d.ts +29 -0
- package/dist/plugin-sdk/utils/directive-tags.d.ts +29 -0
- package/dist/plugin-sdk/utils/fetch-timeout.d.ts +13 -0
- package/dist/plugin-sdk/utils/mask-api-key.d.ts +1 -0
- package/dist/plugin-sdk/utils/message-channel.d.ts +27 -0
- package/dist/plugin-sdk/utils/normalize-secret-input.d.ts +11 -0
- package/dist/plugin-sdk/utils/provider-utils.d.ts +9 -0
- package/dist/plugin-sdk/utils/queue-helpers.d.ts +80 -0
- package/dist/plugin-sdk/utils/reaction-level.d.ts +15 -0
- package/dist/plugin-sdk/utils/run-with-concurrency.d.ts +11 -0
- package/dist/plugin-sdk/utils/transcript-tools.d.ts +8 -0
- package/dist/plugin-sdk/utils/usage-format.d.ts +26 -0
- package/dist/plugin-sdk/utils/with-timeout.d.ts +1 -0
- package/dist/plugin-sdk/utils.d.ts +63 -0
- package/dist/plugin-sdk/version.d.ts +8 -0
- package/dist/plugin-sdk/web/accounts.d.ts +39 -0
- package/dist/plugin-sdk/web/active-listener.d.ts +25 -0
- package/dist/plugin-sdk/web/auth-store.d.ts +26 -0
- package/dist/plugin-sdk/web/auto-reply/constants.d.ts +1 -0
- package/dist/plugin-sdk/web/auto-reply/deliver-reply.d.ts +19 -0
- package/dist/plugin-sdk/web/auto-reply/heartbeat-runner.d.ts +20 -0
- package/dist/plugin-sdk/web/auto-reply/loggers.d.ts +4 -0
- package/dist/plugin-sdk/web/auto-reply/mentions.d.ts +19 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/ack-reaction.d.ts +13 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/broadcast.d.ts +16 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/commands.d.ts +2 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/echo.d.ts +17 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/group-activation.d.ts +9 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/group-gating.d.ts +33 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/group-members.d.ts +6 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/last-route.d.ts +15 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/message-line.d.ts +11 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/on-message.d.ts +24 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/peer.d.ts +2 -0
- package/dist/plugin-sdk/web/auto-reply/monitor/process-message.d.ts +40 -0
- package/dist/plugin-sdk/web/auto-reply/monitor.d.ts +5 -0
- package/dist/plugin-sdk/web/auto-reply/session-snapshot.d.ts +17 -0
- package/dist/plugin-sdk/web/auto-reply/types.d.ts +30 -0
- package/dist/plugin-sdk/web/auto-reply/util.d.ts +2 -0
- package/dist/plugin-sdk/web/auto-reply.d.ts +1 -0
- package/dist/plugin-sdk/web/auto-reply.impl.d.ts +5 -0
- package/dist/plugin-sdk/web/inbound/access-control.d.ts +36 -0
- package/dist/plugin-sdk/web/inbound/dedupe.d.ts +2 -0
- package/dist/plugin-sdk/web/inbound/extract.d.ts +13 -0
- package/dist/plugin-sdk/web/inbound/media.d.ts +7 -0
- package/dist/plugin-sdk/web/inbound/monitor.d.ts +30 -0
- package/dist/plugin-sdk/web/inbound/send-api.d.ts +22 -0
- package/dist/plugin-sdk/web/inbound/types.d.ts +41 -0
- package/dist/plugin-sdk/web/inbound.d.ts +4 -0
- package/dist/plugin-sdk/web/login-qr.d.ts +19 -0
- package/dist/plugin-sdk/web/login.d.ts +3 -0
- package/dist/plugin-sdk/web/media.d.ts +43 -0
- package/dist/plugin-sdk/web/outbound.d.ts +24 -0
- package/dist/plugin-sdk/web/qr-image.d.ts +4 -0
- package/dist/plugin-sdk/web/reconnect.d.ts +12 -0
- package/dist/plugin-sdk/web/session.d.ts +14 -0
- package/dist/plugin-sdk/web/vcard.d.ts +6 -0
- package/dist/plugin-sdk/whatsapp/normalize.d.ts +6 -0
- package/dist/plugin-sdk/whatsapp/resolve-outbound-target.d.ts +12 -0
- package/dist/plugin-sdk/wizard/prompts.d.ts +43 -0
- package/dist/plugin-sdk/wizard/session.d.ts +42 -0
- package/dist/plugins-BflZz0sp.js +453 -0
- package/dist/plugins-allowlist-BbTQ5Z2k.js +15 -0
- package/dist/plugins-allowlist-C20oaESO.js +15 -0
- package/dist/plugins-cli-DV82scUw.js +798 -0
- package/dist/plugins-cli-Qj1UyIZO.js +793 -0
- package/dist/plugins-woGRXMzU.js +455 -0
- package/dist/polls-B0CCBDeR.js +33 -0
- package/dist/polls-CwwHzYBM.js +33 -0
- package/dist/ports-DrruB2fK.js +370 -0
- package/dist/ports-GT1yV-Tg.js +96 -0
- package/dist/ports-NPqtlfp0.js +316 -0
- package/dist/ports-QMI4-F9m.js +96 -0
- package/dist/ports-lsof-Wteul3ju.js +27 -0
- package/dist/process-scoped-map-CV9kDvfG.js +39 -0
- package/dist/process-scoped-map-PEvnG75N.js +39 -0
- package/dist/program-CQmIaRUI.js +244 -0
- package/dist/program-context-DEU6ACnL.js +474 -0
- package/dist/program-context-jqeI5alP.js +17 -0
- package/dist/progress-C1kUfYL-.js +123 -0
- package/dist/progress-CBkSaM6z.js +124 -0
- package/dist/prompt-Bllj1dhc.js +21 -0
- package/dist/prompt-Yn2yClg1.js +21 -0
- package/dist/prompt-select-styled-BhTN6zE2.js +1650 -0
- package/dist/prompt-select-styled-WopXnjIy.js +1647 -0
- package/dist/prompt-style-DVEm3BZW.js +9 -0
- package/dist/prompt-style-DjEYC_s-.js +9 -0
- package/dist/provider-dispatcher-B4QMe-I6.js +659 -0
- package/dist/provider-dispatcher-Bfauw6zz.js +660 -0
- package/dist/provider-utils-3JTMJroG.js +79 -0
- package/dist/provider-utils-FaBmofiq.js +79 -0
- package/dist/proxy-DL3MD6-P.js +16 -0
- package/dist/proxy-DpNv2cSV.js +16 -0
- package/dist/push-apns-C0LyG-WB.js +713 -0
- package/dist/push-apns-DuG95AKC.js +711 -0
- package/dist/pw-ai-D9n6-Wa6.js +1906 -0
- package/dist/pw-ai-T280E6Mn.js +1910 -0
- package/dist/pw-ai-state-CGfLv6nV.js +11 -0
- package/dist/pw-ai-state-Dynx20hr.js +11 -0
- package/dist/qr-cli-DVECWTHN.js +352 -0
- package/dist/qr-cli-hSLixZCe.js +347 -0
- package/dist/redact-Dx1Fue21.js +191 -0
- package/dist/redact-eZq1uwNK.js +191 -0
- package/dist/redact-identifier-BTIWtaa-.js +15 -0
- package/dist/redact-identifier-CAagcfWA.js +15 -0
- package/dist/redact-snapshot-BZYLIqe-.js +2028 -0
- package/dist/redact-snapshot-C6hVx_9I.js +2028 -0
- package/dist/register.agent-Dmj-sgEl.js +1043 -0
- package/dist/register.agent-IspcBFeD.js +286 -0
- package/dist/register.configure-BqJEqyGL.js +130 -0
- package/dist/register.configure-PPkU_4Ea.js +124 -0
- package/dist/register.import-Bs-UkOs-.js +27 -0
- package/dist/register.import-DLng8g-e.js +30 -0
- package/dist/register.maintenance-BbpkJil3.js +497 -0
- package/dist/register.maintenance-C5nkOQxa.js +494 -0
- package/dist/register.message-C83Hi1b3.js +681 -0
- package/dist/register.message-D16isu4u.js +686 -0
- package/dist/register.onboard-B8EzX3wY.js +257 -0
- package/dist/register.onboard-CyRbr_0V.js +262 -0
- package/dist/register.setup-DWyoowAz.js +109 -0
- package/dist/register.setup-Dz6GwMnu.js +114 -0
- package/dist/register.status-health-sessions-CbQOfycz.js +423 -0
- package/dist/register.status-health-sessions-DXIWG47y.js +669 -0
- package/dist/register.subclis-DeGP5UPU.js +267 -0
- package/dist/remoteclaw-root-C2HV2VeC.js +88 -0
- package/dist/remoteclaw-root-DybYl8PL.js +88 -0
- package/dist/render-6ahYfPwj.js +104 -0
- package/dist/render-CCLsW6Lz.js +104 -0
- package/dist/render-uf6PvGMV.js +104 -0
- package/dist/replies-BKrzM0QI.js +136 -0
- package/dist/replies-Cl2gYBVt.js +136 -0
- package/dist/reply-CCu_DY64.js +13900 -0
- package/dist/reply-DSKC8kyS.js +13897 -0
- package/dist/reply-directives-BHJKp1Du.js +182 -0
- package/dist/reply-directives-CD2WycBM.js +182 -0
- package/dist/reply-payloads-D_BM1Anb.js +527 -0
- package/dist/reply-prefix-DBLCYiup.js +38 -0
- package/dist/reply-prefix-Q4DOJSn_.js +38 -0
- package/dist/resolve-route-CBVbY0xS.js +249 -0
- package/dist/resolve-route-DGEgTEif.js +249 -0
- package/dist/response-prefix-template-rVZQOViK.js +136 -0
- package/dist/response-prefix-template-up4REfuR.js +136 -0
- package/dist/retry-BhuXOEVR.js +77 -0
- package/dist/retry-DUjAzOBy.js +77 -0
- package/dist/retry-DnqPAqWp.js +77 -0
- package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
- package/dist/run-main-Um5xhxla.js +320 -0
- package/dist/runner-yVJ4HB2K.js +2294 -0
- package/dist/runner-z92MWZ3m.js +2294 -0
- package/dist/runtime-DJNp29jv.js +94 -0
- package/dist/runtime-guard-DZ_xuCc4.js +60 -0
- package/dist/runtime-guard-U-ewY_QH.js +60 -0
- package/dist/secret-equal-BbHdTtqY.js +11 -0
- package/dist/secret-equal-CXJEZiWb.js +11 -0
- package/dist/secure-random-CS2mSdTn.js +12 -0
- package/dist/secure-random-Pl9rPl0l.js +44 -0
- package/dist/secure-random-_dzDDlFo.js +12 -0
- package/dist/security-cli-CdwbWZUj.js +484 -0
- package/dist/security-cli-DP5QJpa5.js +478 -0
- package/dist/send-B1_Ymjb9.js +1778 -0
- package/dist/send-B84axiIa.js +29 -0
- package/dist/send-BN_zYVlx.js +547 -0
- package/dist/send-BqVOxAmK.js +1174 -0
- package/dist/send-Bx9bUGav.js +492 -0
- package/dist/send-C3pdJ6p-.js +2245 -0
- package/dist/send-CBGSXjfD.js +2245 -0
- package/dist/send-CGXyTF22.js +426 -0
- package/dist/send-CKavrhXj.js +11 -0
- package/dist/send-D08Je6DL.js +374 -0
- package/dist/send-D1aYEG-k.js +332 -0
- package/dist/send-DHldI3gf.js +492 -0
- package/dist/send-D_DUQJ6H.js +349 -0
- package/dist/send-Ds63eF4a.js +349 -0
- package/dist/send-YRVDWfSs.js +547 -0
- package/dist/send-xnwty9cY.js +1775 -0
- package/dist/server-BQFoyCRR.js +200 -0
- package/dist/server-DhXw25Jq.js +205 -0
- package/dist/server-lifecycle-BjCCyD3w.js +2437 -0
- package/dist/server-lifecycle-Coyr6Lda.js +2437 -0
- package/dist/server-node-events-De4WZQQD.js +393 -0
- package/dist/server-node-events-dXXayuqY.js +398 -0
- package/dist/service-Bjqii5nW.js +670 -0
- package/dist/service-fp29z5Ww.js +670 -0
- package/dist/session-DBL5nHDy.js +170 -0
- package/dist/session-cost-usage-DX09eTPU.js +627 -0
- package/dist/session-cost-usage-yYi525j3.js +627 -0
- package/dist/session-dirs-Cj5xi7zX.js +947 -0
- package/dist/session-dirs-DdF6TDsE.js +947 -0
- package/dist/session-key-5YLnn_qf.js +235 -0
- package/dist/session-key-C2n-VILA.js +235 -0
- package/dist/session-utils-CEtEq6bi.js +625 -0
- package/dist/session-utils-WmlWAs1r.js +625 -0
- package/dist/session-xKIW6gL2.js +170 -0
- package/dist/sessions--PykPynp.js +2593 -0
- package/dist/sessions-Bw4LRnSr.js +252 -0
- package/dist/ssrf-Ck9HDZpv.js +183 -0
- package/dist/ssrf-m7kFIobZ.js +183 -0
- package/dist/stagger-BXv_apuy.js +56 -0
- package/dist/stagger-MI9gd2rQ.js +56 -0
- package/dist/status-BmtCS3T1.js +21 -0
- package/dist/status-BrwHRn2B.js +21 -0
- package/dist/status-CtzYFLLF.js +2072 -0
- package/dist/status-DiN1cq2p.js +2068 -0
- package/dist/status.update-C55QM2xs.js +79 -0
- package/dist/status.update-CBmPXwYN.js +79 -0
- package/dist/store-C3tOpizT.js +64 -0
- package/dist/store-CPJXuhvQ.js +53 -0
- package/dist/store-SusmIfz7.js +2595 -0
- package/dist/store-v3P-OWhi.js +64 -0
- package/dist/strip-inbound-meta-DjKcSFaW.js +110 -0
- package/dist/strip-inbound-meta-jy3bkUab.js +110 -0
- package/dist/subagent-registry-Db4Ho_2Y.js +4858 -0
- package/dist/subagent-registry-Du_j0Fnt.js +4860 -0
- package/dist/subsystem-BUXAJwPD.js +1079 -0
- package/dist/subsystem-COd61u0P.js +1139 -0
- package/dist/system-cli-DYCpLO3T.js +75 -0
- package/dist/system-cli-eAk5wVbP.js +70 -0
- package/dist/systemd-DSnlM3jX.js +547 -0
- package/dist/systemd-TfK8GuTx.js +547 -0
- package/dist/systemd-linger-Axnc1xCb.js +75 -0
- package/dist/systemd-linger-_0_-RY4v.js +75 -0
- package/dist/table-C1rdyYl9.js +278 -0
- package/dist/table-DPTzZyhu.js +279 -0
- package/dist/tables-DI5LGEr1.js +55 -0
- package/dist/tables-PxcSPSO0.js +55 -0
- package/dist/tables-TWiml6b1.js +55 -0
- package/dist/tailnet-CEudzG0i.js +40 -0
- package/dist/tailnet-PnMrjwGT.js +40 -0
- package/dist/tailscale-DTATQxAG.js +230 -0
- package/dist/tailscale-Dbyahx0J.js +230 -0
- package/dist/target-errors-BDpPcwh5.js +26 -0
- package/dist/target-errors-DdIAPcMM.js +26 -0
- package/dist/targets-BMenhVHg.js +39 -0
- package/dist/targets-C-2xwh9f.js +45 -0
- package/dist/targets-C1NeMn2J.js +220 -0
- package/dist/targets-CcTME3bp.js +46 -0
- package/dist/targets-CmC5m7Ey.js +53 -0
- package/dist/targets-D-qLBpTA.js +79 -0
- package/dist/targets-D-u6Kyio.js +650 -0
- package/dist/targets-D7OKVXMI.js +650 -0
- package/dist/targets-D7PT_rdO.js +45 -0
- package/dist/targets-DB4vBpIQ.js +2172 -0
- package/dist/targets-DfqPGOmM.js +2173 -0
- package/dist/targets-DyybKefq.js +53 -0
- package/dist/targets-JCISV-hS.js +120 -0
- package/dist/targets-UncQvCVs.js +79 -0
- package/dist/text-format-BQ3z_OXA.js +9 -0
- package/dist/text-format-oWqzVmah.js +9 -0
- package/dist/tokens-B-jmvNR9.js +21 -0
- package/dist/tokens-DzFOtLlW.js +21 -0
- package/dist/tool-display-Br6mwaJc.js +785 -0
- package/dist/tool-display-sgNwLOBj.js +785 -0
- package/dist/tool-images-BNfIJ_Kj.js +263 -0
- package/dist/tool-images-kloBqxqK.js +263 -0
- package/dist/trash-DPi0aCCQ.js +125 -0
- package/dist/trash-D_Jd_yQZ.js +125 -0
- package/dist/tui-CHc0EfJO.js +3392 -0
- package/dist/tui-CyHwc2uX.js +3392 -0
- package/dist/tui-cli-BvwbrIYO.js +63 -0
- package/dist/tui-cli-C9I18SfW.js +58 -0
- package/dist/update-DxyjwCL2.js +349 -0
- package/dist/update-IX7vdqA8.js +349 -0
- package/dist/update-cli-CBeXUSzq.js +1373 -0
- package/dist/update-cli-DkAWmUrp.js +1370 -0
- package/dist/usage-BdhBT0Vz.js +57 -0
- package/dist/usage-BtQcAnf6.js +57 -0
- package/dist/usage-CYlQW4M2.js +5279 -0
- package/dist/usage-format-C3mNLfhI.js +31 -0
- package/dist/usage-format-DAaPzr_z.js +31 -0
- package/dist/utils-LBKvDoPx.js +631 -0
- package/dist/warning-filter.js +48 -0
- package/dist/web-BUYUdnRH.js +3065 -0
- package/dist/web-Dquzwqf4.js +70 -0
- package/dist/web-tS8diboh.js +76 -0
- package/dist/webhooks-cli-B7Vw3CMz.js +333 -0
- package/dist/webhooks-cli-BpZHQlVd.js +328 -0
- package/dist/whatsapp-actions-D5HXezjp.js +128 -0
- package/dist/whatsapp-actions-DaA291Ya.js +122 -0
- package/dist/widearea-dns-CsmBVbez.js +127 -0
- package/dist/widearea-dns-DSoaA-eH.js +127 -0
- package/dist/workspace-B4ZvVYT9.js +447 -0
- package/dist/workspace-B8PA8oxJ.js +449 -0
- package/dist/workspace-BzPeZDew.js +10 -0
- package/dist/workspace-DkGLVfOl.js +10 -0
- package/dist/wsl-BCnYV9O0.js +52 -0
- package/dist/wsl-B_sPlzWw.js +52 -0
- package/extensions/bluebubbles/README.md +45 -0
- package/extensions/bluebubbles/index.ts +19 -0
- package/extensions/bluebubbles/package.json +33 -0
- package/extensions/bluebubbles/remoteclaw.plugin.json +9 -0
- package/extensions/bluebubbles/src/account-resolve.ts +35 -0
- package/extensions/bluebubbles/src/accounts.ts +90 -0
- package/extensions/bluebubbles/src/actions.ts +460 -0
- package/extensions/bluebubbles/src/attachments.ts +268 -0
- package/extensions/bluebubbles/src/channel.ts +418 -0
- package/extensions/bluebubbles/src/chat.ts +329 -0
- package/extensions/bluebubbles/src/config-schema.ts +65 -0
- package/extensions/bluebubbles/src/history.ts +177 -0
- package/extensions/bluebubbles/src/media-send.ts +317 -0
- package/extensions/bluebubbles/src/monitor-normalize.ts +825 -0
- package/extensions/bluebubbles/src/monitor-processing.ts +1448 -0
- package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
- package/extensions/bluebubbles/src/monitor-shared.ts +41 -0
- package/extensions/bluebubbles/src/monitor.ts +534 -0
- package/extensions/bluebubbles/src/multipart.ts +32 -0
- package/extensions/bluebubbles/src/onboarding.ts +340 -0
- package/extensions/bluebubbles/src/probe.ts +163 -0
- package/extensions/bluebubbles/src/reactions.ts +182 -0
- package/extensions/bluebubbles/src/request-url.ts +12 -0
- package/extensions/bluebubbles/src/runtime.ts +34 -0
- package/extensions/bluebubbles/src/send-helpers.ts +53 -0
- package/extensions/bluebubbles/src/send.ts +472 -0
- package/extensions/bluebubbles/src/targets.ts +370 -0
- package/extensions/bluebubbles/src/test-harness.ts +79 -0
- package/extensions/bluebubbles/src/test-mocks.ts +11 -0
- package/extensions/bluebubbles/src/types.ts +135 -0
- package/extensions/device-pair/index.ts +529 -0
- package/extensions/device-pair/remoteclaw.plugin.json +20 -0
- package/extensions/diagnostics-otel/index.ts +15 -0
- package/extensions/diagnostics-otel/package.json +24 -0
- package/extensions/diagnostics-otel/remoteclaw.plugin.json +8 -0
- package/extensions/diagnostics-otel/src/service.ts +682 -0
- package/extensions/discord/index.ts +19 -0
- package/extensions/discord/package.json +11 -0
- package/extensions/discord/remoteclaw.plugin.json +9 -0
- package/extensions/discord/src/channel.ts +451 -0
- package/extensions/discord/src/runtime.ts +14 -0
- package/extensions/discord/src/subagent-hooks.ts +152 -0
- package/extensions/feishu/index.ts +63 -0
- package/extensions/feishu/package.json +34 -0
- package/extensions/feishu/remoteclaw.plugin.json +10 -0
- package/extensions/feishu/skills/feishu-doc/SKILL.md +105 -0
- package/extensions/feishu/skills/feishu-doc/references/block-types.md +103 -0
- package/extensions/feishu/skills/feishu-drive/SKILL.md +97 -0
- package/extensions/feishu/skills/feishu-perm/SKILL.md +119 -0
- package/extensions/feishu/skills/feishu-wiki/SKILL.md +111 -0
- package/extensions/feishu/src/accounts.ts +144 -0
- package/extensions/feishu/src/bitable.ts +739 -0
- package/extensions/feishu/src/bot.ts +1006 -0
- package/extensions/feishu/src/channel.ts +359 -0
- package/extensions/feishu/src/client.ts +118 -0
- package/extensions/feishu/src/config-schema.ts +226 -0
- package/extensions/feishu/src/dedup.ts +54 -0
- package/extensions/feishu/src/directory.ts +177 -0
- package/extensions/feishu/src/doc-schema.ts +47 -0
- package/extensions/feishu/src/docx.ts +536 -0
- package/extensions/feishu/src/drive-schema.ts +46 -0
- package/extensions/feishu/src/drive.ts +227 -0
- package/extensions/feishu/src/dynamic-agent.ts +131 -0
- package/extensions/feishu/src/external-keys.ts +19 -0
- package/extensions/feishu/src/media.ts +441 -0
- package/extensions/feishu/src/mention.ts +133 -0
- package/extensions/feishu/src/monitor.ts +397 -0
- package/extensions/feishu/src/onboarding.ts +351 -0
- package/extensions/feishu/src/outbound.ts +55 -0
- package/extensions/feishu/src/perm-schema.ts +52 -0
- package/extensions/feishu/src/perm.ts +173 -0
- package/extensions/feishu/src/policy.ts +120 -0
- package/extensions/feishu/src/probe.ts +44 -0
- package/extensions/feishu/src/reactions.ts +160 -0
- package/extensions/feishu/src/reply-dispatcher.ts +239 -0
- package/extensions/feishu/src/runtime.ts +14 -0
- package/extensions/feishu/src/send-result.ts +29 -0
- package/extensions/feishu/src/send-target.ts +25 -0
- package/extensions/feishu/src/send.ts +313 -0
- package/extensions/feishu/src/streaming-card.ts +218 -0
- package/extensions/feishu/src/targets.ts +78 -0
- package/extensions/feishu/src/tools-config.ts +21 -0
- package/extensions/feishu/src/types.ts +81 -0
- package/extensions/feishu/src/typing.ts +80 -0
- package/extensions/feishu/src/wiki-schema.ts +55 -0
- package/extensions/feishu/src/wiki.ts +232 -0
- package/extensions/googlechat/index.ts +19 -0
- package/extensions/googlechat/node_modules/.bin/remoteclaw +21 -0
- package/extensions/googlechat/package.json +37 -0
- package/extensions/googlechat/remoteclaw.plugin.json +9 -0
- package/extensions/googlechat/src/accounts.ts +147 -0
- package/extensions/googlechat/src/actions.ts +176 -0
- package/extensions/googlechat/src/api.ts +282 -0
- package/extensions/googlechat/src/auth.ts +137 -0
- package/extensions/googlechat/src/channel.ts +576 -0
- package/extensions/googlechat/src/monitor.ts +965 -0
- package/extensions/googlechat/src/onboarding.ts +270 -0
- package/extensions/googlechat/src/runtime.ts +14 -0
- package/extensions/googlechat/src/targets.ts +65 -0
- package/extensions/googlechat/src/types.config.ts +3 -0
- package/extensions/googlechat/src/types.ts +73 -0
- package/extensions/imessage/index.ts +17 -0
- package/extensions/imessage/package.json +12 -0
- package/extensions/imessage/remoteclaw.plugin.json +9 -0
- package/extensions/imessage/src/channel.ts +304 -0
- package/extensions/imessage/src/runtime.ts +14 -0
- package/extensions/irc/index.ts +17 -0
- package/extensions/irc/package.json +11 -0
- package/extensions/irc/remoteclaw.plugin.json +9 -0
- package/extensions/irc/src/accounts.ts +268 -0
- package/extensions/irc/src/channel.ts +364 -0
- package/extensions/irc/src/client.ts +439 -0
- package/extensions/irc/src/config-schema.ts +91 -0
- package/extensions/irc/src/connect-options.ts +30 -0
- package/extensions/irc/src/control-chars.ts +22 -0
- package/extensions/irc/src/inbound.ts +372 -0
- package/extensions/irc/src/monitor.ts +146 -0
- package/extensions/irc/src/normalize.ts +123 -0
- package/extensions/irc/src/onboarding.ts +479 -0
- package/extensions/irc/src/policy.ts +166 -0
- package/extensions/irc/src/probe.ts +53 -0
- package/extensions/irc/src/protocol.ts +169 -0
- package/extensions/irc/src/runtime.ts +14 -0
- package/extensions/irc/src/send.ts +88 -0
- package/extensions/irc/src/types.ts +99 -0
- package/extensions/line/index.ts +19 -0
- package/extensions/line/package.json +27 -0
- package/extensions/line/remoteclaw.plugin.json +9 -0
- package/extensions/line/src/card-command.ts +344 -0
- package/extensions/line/src/channel.ts +797 -0
- package/extensions/line/src/runtime.ts +14 -0
- package/extensions/matrix/CHANGELOG.md +32 -0
- package/extensions/matrix/index.ts +17 -0
- package/extensions/matrix/node_modules/.bin/markdown-it +21 -0
- package/extensions/matrix/package.json +33 -0
- package/extensions/matrix/remoteclaw.plugin.json +9 -0
- package/extensions/matrix/src/actions.ts +195 -0
- package/extensions/matrix/src/channel.ts +486 -0
- package/extensions/matrix/src/config-schema.ts +63 -0
- package/extensions/matrix/src/directory-live.ts +208 -0
- package/extensions/matrix/src/group-mentions.ts +52 -0
- package/extensions/matrix/src/matrix/accounts.ts +137 -0
- package/extensions/matrix/src/matrix/actions/client.ts +47 -0
- package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
- package/extensions/matrix/src/matrix/actions/messages.ts +126 -0
- package/extensions/matrix/src/matrix/actions/pins.ts +84 -0
- package/extensions/matrix/src/matrix/actions/reactions.ts +102 -0
- package/extensions/matrix/src/matrix/actions/room.ts +85 -0
- package/extensions/matrix/src/matrix/actions/summary.ts +75 -0
- package/extensions/matrix/src/matrix/actions/types.ts +85 -0
- package/extensions/matrix/src/matrix/actions.ts +15 -0
- package/extensions/matrix/src/matrix/active-client.ts +32 -0
- package/extensions/matrix/src/matrix/client/config.ts +219 -0
- package/extensions/matrix/src/matrix/client/create-client.ts +123 -0
- package/extensions/matrix/src/matrix/client/logging.ts +36 -0
- package/extensions/matrix/src/matrix/client/runtime.ts +4 -0
- package/extensions/matrix/src/matrix/client/shared.ts +201 -0
- package/extensions/matrix/src/matrix/client/storage.ts +131 -0
- package/extensions/matrix/src/matrix/client/types.ts +34 -0
- package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
- package/extensions/matrix/src/matrix/client.ts +14 -0
- package/extensions/matrix/src/matrix/credentials.ts +125 -0
- package/extensions/matrix/src/matrix/deps.ts +60 -0
- package/extensions/matrix/src/matrix/format.ts +22 -0
- package/extensions/matrix/src/matrix/index.ts +11 -0
- package/extensions/matrix/src/matrix/monitor/allowlist.ts +103 -0
- package/extensions/matrix/src/matrix/monitor/auto-join.ts +71 -0
- package/extensions/matrix/src/matrix/monitor/direct.ts +104 -0
- package/extensions/matrix/src/matrix/monitor/events.ts +148 -0
- package/extensions/matrix/src/matrix/monitor/handler.ts +688 -0
- package/extensions/matrix/src/matrix/monitor/index.ts +358 -0
- package/extensions/matrix/src/matrix/monitor/location.ts +100 -0
- package/extensions/matrix/src/matrix/monitor/media.ts +118 -0
- package/extensions/matrix/src/matrix/monitor/mentions.ts +62 -0
- package/extensions/matrix/src/matrix/monitor/replies.ts +124 -0
- package/extensions/matrix/src/matrix/monitor/room-info.ts +55 -0
- package/extensions/matrix/src/matrix/monitor/rooms.ts +47 -0
- package/extensions/matrix/src/matrix/monitor/threads.ts +68 -0
- package/extensions/matrix/src/matrix/monitor/types.ts +39 -0
- package/extensions/matrix/src/matrix/poll-types.ts +167 -0
- package/extensions/matrix/src/matrix/probe.ts +69 -0
- package/extensions/matrix/src/matrix/send/client.ts +97 -0
- package/extensions/matrix/src/matrix/send/formatting.ts +93 -0
- package/extensions/matrix/src/matrix/send/media.ts +230 -0
- package/extensions/matrix/src/matrix/send/targets.ts +150 -0
- package/extensions/matrix/src/matrix/send/types.ts +109 -0
- package/extensions/matrix/src/matrix/send-queue.ts +44 -0
- package/extensions/matrix/src/matrix/send.ts +265 -0
- package/extensions/matrix/src/onboarding.ts +446 -0
- package/extensions/matrix/src/outbound.ts +55 -0
- package/extensions/matrix/src/resolve-targets.ts +126 -0
- package/extensions/matrix/src/runtime.ts +14 -0
- package/extensions/matrix/src/tool-actions.ts +164 -0
- package/extensions/matrix/src/types.ts +116 -0
- package/extensions/mattermost/index.ts +17 -0
- package/extensions/mattermost/package.json +25 -0
- package/extensions/mattermost/remoteclaw.plugin.json +9 -0
- package/extensions/mattermost/src/channel.ts +439 -0
- package/extensions/mattermost/src/config-schema.ts +62 -0
- package/extensions/mattermost/src/group-mentions.ts +15 -0
- package/extensions/mattermost/src/mattermost/accounts.ts +128 -0
- package/extensions/mattermost/src/mattermost/client.ts +230 -0
- package/extensions/mattermost/src/mattermost/index.ts +9 -0
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +72 -0
- package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
- package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
- package/extensions/mattermost/src/mattermost/monitor.ts +1061 -0
- package/extensions/mattermost/src/mattermost/probe.ts +61 -0
- package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
- package/extensions/mattermost/src/mattermost/reactions.ts +124 -0
- package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
- package/extensions/mattermost/src/mattermost/send.ts +231 -0
- package/extensions/mattermost/src/normalize.ts +46 -0
- package/extensions/mattermost/src/onboarding-helpers.ts +1 -0
- package/extensions/mattermost/src/onboarding.ts +182 -0
- package/extensions/mattermost/src/runtime.ts +14 -0
- package/extensions/mattermost/src/types.ts +62 -0
- package/extensions/msteams/CHANGELOG.md +35 -0
- package/extensions/msteams/index.ts +17 -0
- package/extensions/msteams/package.json +32 -0
- package/extensions/msteams/remoteclaw.plugin.json +9 -0
- package/extensions/msteams/src/attachments/download.ts +282 -0
- package/extensions/msteams/src/attachments/graph.ts +354 -0
- package/extensions/msteams/src/attachments/html.ts +90 -0
- package/extensions/msteams/src/attachments/payload.ts +14 -0
- package/extensions/msteams/src/attachments/remote-media.ts +42 -0
- package/extensions/msteams/src/attachments/shared.ts +404 -0
- package/extensions/msteams/src/attachments/types.ts +37 -0
- package/extensions/msteams/src/attachments.ts +18 -0
- package/extensions/msteams/src/channel.ts +464 -0
- package/extensions/msteams/src/conversation-store-fs.ts +165 -0
- package/extensions/msteams/src/conversation-store-memory.ts +47 -0
- package/extensions/msteams/src/conversation-store.ts +41 -0
- package/extensions/msteams/src/directory-live.ts +108 -0
- package/extensions/msteams/src/errors.ts +190 -0
- package/extensions/msteams/src/file-consent-helpers.ts +73 -0
- package/extensions/msteams/src/file-consent.ts +126 -0
- package/extensions/msteams/src/file-lock.ts +1 -0
- package/extensions/msteams/src/graph-chat.ts +53 -0
- package/extensions/msteams/src/graph-upload.ts +452 -0
- package/extensions/msteams/src/graph-users.ts +29 -0
- package/extensions/msteams/src/graph.ts +81 -0
- package/extensions/msteams/src/inbound.ts +48 -0
- package/extensions/msteams/src/index.ts +4 -0
- package/extensions/msteams/src/media-helpers.ts +105 -0
- package/extensions/msteams/src/mentions.ts +114 -0
- package/extensions/msteams/src/messenger.ts +484 -0
- package/extensions/msteams/src/monitor-handler/inbound-media.ts +128 -0
- package/extensions/msteams/src/monitor-handler/message-handler.ts +661 -0
- package/extensions/msteams/src/monitor-handler.ts +162 -0
- package/extensions/msteams/src/monitor-types.ts +5 -0
- package/extensions/msteams/src/monitor.ts +305 -0
- package/extensions/msteams/src/onboarding.ts +406 -0
- package/extensions/msteams/src/outbound.ts +46 -0
- package/extensions/msteams/src/pending-uploads.ts +89 -0
- package/extensions/msteams/src/policy.ts +259 -0
- package/extensions/msteams/src/polls-store-memory.ts +32 -0
- package/extensions/msteams/src/polls.ts +315 -0
- package/extensions/msteams/src/probe.ts +94 -0
- package/extensions/msteams/src/reply-dispatcher.ts +132 -0
- package/extensions/msteams/src/resolve-allowlist.ts +198 -0
- package/extensions/msteams/src/runtime.ts +14 -0
- package/extensions/msteams/src/sdk-types.ts +19 -0
- package/extensions/msteams/src/sdk.ts +33 -0
- package/extensions/msteams/src/send-context.ts +164 -0
- package/extensions/msteams/src/send.ts +530 -0
- package/extensions/msteams/src/sent-message-cache.ts +44 -0
- package/extensions/msteams/src/storage.ts +25 -0
- package/extensions/msteams/src/store-fs.ts +44 -0
- package/extensions/msteams/src/test-runtime.ts +16 -0
- package/extensions/msteams/src/token-response.ts +11 -0
- package/extensions/msteams/src/token.ts +19 -0
- package/extensions/nextcloud-talk/index.ts +17 -0
- package/extensions/nextcloud-talk/package.json +30 -0
- package/extensions/nextcloud-talk/remoteclaw.plugin.json +9 -0
- package/extensions/nextcloud-talk/src/accounts.ts +170 -0
- package/extensions/nextcloud-talk/src/channel.ts +416 -0
- package/extensions/nextcloud-talk/src/config-schema.ts +72 -0
- package/extensions/nextcloud-talk/src/format.ts +79 -0
- package/extensions/nextcloud-talk/src/inbound.ts +343 -0
- package/extensions/nextcloud-talk/src/monitor.ts +275 -0
- package/extensions/nextcloud-talk/src/normalize.ts +39 -0
- package/extensions/nextcloud-talk/src/onboarding.ts +349 -0
- package/extensions/nextcloud-talk/src/policy.ts +180 -0
- package/extensions/nextcloud-talk/src/room-info.ts +125 -0
- package/extensions/nextcloud-talk/src/runtime.ts +14 -0
- package/extensions/nextcloud-talk/src/send.ts +215 -0
- package/extensions/nextcloud-talk/src/signature.ts +72 -0
- package/extensions/nextcloud-talk/src/types.ts +185 -0
- package/extensions/nostr/CHANGELOG.md +44 -0
- package/extensions/nostr/README.md +136 -0
- package/extensions/nostr/index.ts +68 -0
- package/extensions/nostr/package.json +30 -0
- package/extensions/nostr/remoteclaw.plugin.json +9 -0
- package/extensions/nostr/src/channel.ts +345 -0
- package/extensions/nostr/src/config-schema.ts +90 -0
- package/extensions/nostr/src/metrics.ts +458 -0
- package/extensions/nostr/src/nostr-bus.ts +719 -0
- package/extensions/nostr/src/nostr-profile-http.ts +519 -0
- package/extensions/nostr/src/nostr-profile-import.ts +262 -0
- package/extensions/nostr/src/nostr-profile.ts +277 -0
- package/extensions/nostr/src/nostr-state-store.ts +226 -0
- package/extensions/nostr/src/runtime.ts +14 -0
- package/extensions/nostr/src/seen-tracker.ts +289 -0
- package/extensions/nostr/src/types.ts +101 -0
- package/extensions/phone-control/index.ts +421 -0
- package/extensions/phone-control/remoteclaw.plugin.json +10 -0
- package/extensions/shared/resolve-target-test-helpers.ts +66 -0
- package/extensions/signal/index.ts +17 -0
- package/extensions/signal/package.json +12 -0
- package/extensions/signal/remoteclaw.plugin.json +9 -0
- package/extensions/signal/src/channel.ts +299 -0
- package/extensions/signal/src/runtime.ts +14 -0
- package/extensions/slack/index.ts +17 -0
- package/extensions/slack/package.json +12 -0
- package/extensions/slack/remoteclaw.plugin.json +9 -0
- package/extensions/slack/src/channel.ts +421 -0
- package/extensions/slack/src/runtime.ts +14 -0
- package/extensions/synology-chat/index.ts +17 -0
- package/extensions/synology-chat/package.json +28 -0
- package/extensions/synology-chat/remoteclaw.plugin.json +9 -0
- package/extensions/synology-chat/src/accounts.ts +87 -0
- package/extensions/synology-chat/src/channel.ts +347 -0
- package/extensions/synology-chat/src/client.ts +142 -0
- package/extensions/synology-chat/src/runtime.ts +20 -0
- package/extensions/synology-chat/src/security.ts +140 -0
- package/extensions/synology-chat/src/types.ts +60 -0
- package/extensions/synology-chat/src/webhook-handler.ts +221 -0
- package/extensions/talk-voice/index.ts +150 -0
- package/extensions/talk-voice/remoteclaw.plugin.json +10 -0
- package/extensions/telegram/index.ts +17 -0
- package/extensions/telegram/package.json +12 -0
- package/extensions/telegram/remoteclaw.plugin.json +9 -0
- package/extensions/telegram/src/channel.ts +569 -0
- package/extensions/telegram/src/runtime.ts +14 -0
- package/extensions/test-utils/runtime-env.ts +12 -0
- package/extensions/thread-ownership/index.ts +133 -0
- package/extensions/thread-ownership/remoteclaw.plugin.json +28 -0
- package/extensions/tlon/README.md +5 -0
- package/extensions/tlon/index.ts +17 -0
- package/extensions/tlon/package.json +29 -0
- package/extensions/tlon/remoteclaw.plugin.json +9 -0
- package/extensions/tlon/src/account-fields.ts +25 -0
- package/extensions/tlon/src/channel.ts +384 -0
- package/extensions/tlon/src/config-schema.ts +41 -0
- package/extensions/tlon/src/monitor/discovery.ts +78 -0
- package/extensions/tlon/src/monitor/history.ts +92 -0
- package/extensions/tlon/src/monitor/index.ts +596 -0
- package/extensions/tlon/src/monitor/processed-messages.ts +33 -0
- package/extensions/tlon/src/monitor/utils.ts +106 -0
- package/extensions/tlon/src/onboarding.ts +229 -0
- package/extensions/tlon/src/runtime.ts +14 -0
- package/extensions/tlon/src/targets.ts +89 -0
- package/extensions/tlon/src/types.ts +99 -0
- package/extensions/tlon/src/urbit/auth.ts +48 -0
- package/extensions/tlon/src/urbit/base-url.ts +57 -0
- package/extensions/tlon/src/urbit/channel-client.ts +158 -0
- package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
- package/extensions/tlon/src/urbit/context.ts +47 -0
- package/extensions/tlon/src/urbit/errors.ts +51 -0
- package/extensions/tlon/src/urbit/fetch.ts +39 -0
- package/extensions/tlon/src/urbit/send.ts +131 -0
- package/extensions/tlon/src/urbit/sse-client.ts +431 -0
- package/extensions/twitch/CHANGELOG.md +39 -0
- package/extensions/twitch/README.md +89 -0
- package/extensions/twitch/index.ts +20 -0
- package/extensions/twitch/package.json +17 -0
- package/extensions/twitch/remoteclaw.plugin.json +9 -0
- package/extensions/twitch/src/access-control.ts +166 -0
- package/extensions/twitch/src/actions.ts +174 -0
- package/extensions/twitch/src/client-manager-registry.ts +115 -0
- package/extensions/twitch/src/config-schema.ts +84 -0
- package/extensions/twitch/src/config.ts +116 -0
- package/extensions/twitch/src/monitor.ts +273 -0
- package/extensions/twitch/src/onboarding.ts +417 -0
- package/extensions/twitch/src/outbound.ts +187 -0
- package/extensions/twitch/src/plugin.ts +274 -0
- package/extensions/twitch/src/probe.ts +119 -0
- package/extensions/twitch/src/resolver.ts +137 -0
- package/extensions/twitch/src/runtime.ts +14 -0
- package/extensions/twitch/src/send.ts +136 -0
- package/extensions/twitch/src/status.ts +179 -0
- package/extensions/twitch/src/test-fixtures.ts +30 -0
- package/extensions/twitch/src/token.ts +94 -0
- package/extensions/twitch/src/twitch-client.ts +277 -0
- package/extensions/twitch/src/types.ts +141 -0
- package/extensions/twitch/src/utils/markdown.ts +98 -0
- package/extensions/twitch/src/utils/twitch.ts +80 -0
- package/extensions/voice-call/CHANGELOG.md +49 -0
- package/extensions/voice-call/README.md +181 -0
- package/extensions/voice-call/index.ts +512 -0
- package/extensions/voice-call/package.json +16 -0
- package/extensions/voice-call/remoteclaw.plugin.json +559 -0
- package/extensions/voice-call/src/allowlist.ts +19 -0
- package/extensions/voice-call/src/cli.ts +380 -0
- package/extensions/voice-call/src/config.ts +477 -0
- package/extensions/voice-call/src/core-bridge.ts +170 -0
- package/extensions/voice-call/src/manager/context.ts +41 -0
- package/extensions/voice-call/src/manager/events.ts +242 -0
- package/extensions/voice-call/src/manager/lookup.ts +35 -0
- package/extensions/voice-call/src/manager/outbound.ts +380 -0
- package/extensions/voice-call/src/manager/state.ts +48 -0
- package/extensions/voice-call/src/manager/store.ts +94 -0
- package/extensions/voice-call/src/manager/timers.ts +112 -0
- package/extensions/voice-call/src/manager/twiml.ts +9 -0
- package/extensions/voice-call/src/manager.ts +209 -0
- package/extensions/voice-call/src/media-stream.ts +527 -0
- package/extensions/voice-call/src/providers/base.ts +67 -0
- package/extensions/voice-call/src/providers/index.ts +10 -0
- package/extensions/voice-call/src/providers/mock.ts +165 -0
- package/extensions/voice-call/src/providers/plivo.ts +560 -0
- package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
- package/extensions/voice-call/src/providers/telnyx.ts +318 -0
- package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
- package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
- package/extensions/voice-call/src/providers/twilio/webhook.ts +33 -0
- package/extensions/voice-call/src/providers/twilio.ts +688 -0
- package/extensions/voice-call/src/response-generator.ts +174 -0
- package/extensions/voice-call/src/runtime.ts +217 -0
- package/extensions/voice-call/src/telephony-audio.ts +90 -0
- package/extensions/voice-call/src/telephony-tts.ts +106 -0
- package/extensions/voice-call/src/tunnel.ts +314 -0
- package/extensions/voice-call/src/types.ts +280 -0
- package/extensions/voice-call/src/utils.ts +14 -0
- package/extensions/voice-call/src/voice-mapping.ts +67 -0
- package/extensions/voice-call/src/webhook-security.ts +880 -0
- package/extensions/voice-call/src/webhook.ts +556 -0
- package/extensions/whatsapp/index.ts +17 -0
- package/extensions/whatsapp/package.json +12 -0
- package/extensions/whatsapp/remoteclaw.plugin.json +9 -0
- package/extensions/whatsapp/src/channel.ts +459 -0
- package/extensions/whatsapp/src/runtime.ts +14 -0
- package/extensions/zalo/CHANGELOG.md +29 -0
- package/extensions/zalo/README.md +50 -0
- package/extensions/zalo/index.ts +19 -0
- package/extensions/zalo/package.json +32 -0
- package/extensions/zalo/remoteclaw.plugin.json +9 -0
- package/extensions/zalo/src/accounts.ts +82 -0
- package/extensions/zalo/src/actions.ts +56 -0
- package/extensions/zalo/src/api.ts +208 -0
- package/extensions/zalo/src/channel.ts +398 -0
- package/extensions/zalo/src/config-schema.ts +27 -0
- package/extensions/zalo/src/group-access.ts +48 -0
- package/extensions/zalo/src/monitor.ts +675 -0
- package/extensions/zalo/src/monitor.webhook.ts +219 -0
- package/extensions/zalo/src/onboarding.ts +398 -0
- package/extensions/zalo/src/probe.ts +45 -0
- package/extensions/zalo/src/proxy.ts +24 -0
- package/extensions/zalo/src/runtime.ts +14 -0
- package/extensions/zalo/src/send.ts +124 -0
- package/extensions/zalo/src/status-issues.ts +53 -0
- package/extensions/zalo/src/token.ts +62 -0
- package/extensions/zalo/src/types.ts +48 -0
- package/extensions/zalouser/CHANGELOG.md +31 -0
- package/extensions/zalouser/README.md +225 -0
- package/extensions/zalouser/index.ts +31 -0
- package/extensions/zalouser/package.json +32 -0
- package/extensions/zalouser/remoteclaw.plugin.json +9 -0
- package/extensions/zalouser/src/accounts.ts +138 -0
- package/extensions/zalouser/src/channel.ts +652 -0
- package/extensions/zalouser/src/config-schema.ts +28 -0
- package/extensions/zalouser/src/monitor.ts +619 -0
- package/extensions/zalouser/src/onboarding.ts +428 -0
- package/extensions/zalouser/src/probe.ts +27 -0
- package/extensions/zalouser/src/runtime.ts +14 -0
- package/extensions/zalouser/src/send.ts +141 -0
- package/extensions/zalouser/src/status-issues.ts +89 -0
- package/extensions/zalouser/src/tool.ts +166 -0
- package/extensions/zalouser/src/types.ts +105 -0
- package/extensions/zalouser/src/zca.ts +198 -0
- package/package.json +251 -15
- package/remoteclaw.mjs +56 -0
- package/index.js +0 -4
|
@@ -0,0 +1,4858 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
|
|
2
|
+
import { _ as defaultRuntime, k as normalizeChannelId, o as createSubsystemLogger, qt as resolveStateDir } from "./entry.js";
|
|
3
|
+
import { n as saveJsonFile, t as loadJsonFile } from "./json-file-ChO_R9yh.js";
|
|
4
|
+
import { C as parseAgentSessionKey, S as isSubagentSessionKey, b as isAcpSessionKey, c as normalizeMainKey, h as normalizeAccountId, l as resolveAgentIdFromSessionKey, y as getSubagentDepth } from "./session-key-C2n-VILA.js";
|
|
5
|
+
import { _ as parseDurationMs, i as loadConfig, lt as DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "./config-FHu9Bn4R.js";
|
|
6
|
+
import { c as resolveSessionAgentId, s as resolveDefaultAgentId } from "./agent-scope-C50VuLKh.js";
|
|
7
|
+
import { a as isInternalMessageChannel, c as normalizeMessageChannel, n as isDeliverableMessageChannel, t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-uWMAiywE.js";
|
|
8
|
+
import { X as resolveMainSessionKey, b as mergeDeliveryContext, l as loadSessionStore, x as normalizeDeliveryContext, y as deliveryContextFromSession } from "./sessions--PykPynp.js";
|
|
9
|
+
import { r as normalizeChannelId$1, t as getChannelPlugin } from "./plugins-BflZz0sp.js";
|
|
10
|
+
import { m as resolveStorePath } from "./chat-envelope-DEZ-5RY8.js";
|
|
11
|
+
import { n as callGateway } from "./call-BbwtB9Y-.js";
|
|
12
|
+
import { r as CommandLane, s as onAgentEvent, t as AGENT_LANE_NESTED } from "./lanes-cHJ5arWg.js";
|
|
13
|
+
import { a as resolveEffectiveMessagesConfig, n as resolveResponsePrefixTemplate } from "./response-prefix-template-up4REfuR.js";
|
|
14
|
+
import { _ as sanitizeUserFacingText } from "./agent-helpers-CTx5KKJu.js";
|
|
15
|
+
import { r as isSilentReplyText, t as SILENT_REPLY_TOKEN } from "./tokens-B-jmvNR9.js";
|
|
16
|
+
import { t as getGlobalHookRunner, u as shouldSuppressReasoningPayload } from "./hook-runner-global-DJ14gXFP.js";
|
|
17
|
+
import os from "node:os";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
import fs from "node:fs";
|
|
20
|
+
import JSON5 from "json5";
|
|
21
|
+
import crypto from "node:crypto";
|
|
22
|
+
|
|
23
|
+
//#region src/utils/queue-helpers.ts
|
|
24
|
+
function clearQueueSummaryState(state) {
|
|
25
|
+
state.droppedCount = 0;
|
|
26
|
+
state.summaryLines = [];
|
|
27
|
+
}
|
|
28
|
+
function previewQueueSummaryPrompt(params) {
|
|
29
|
+
return buildQueueSummaryPrompt({
|
|
30
|
+
state: {
|
|
31
|
+
dropPolicy: params.state.dropPolicy,
|
|
32
|
+
droppedCount: params.state.droppedCount,
|
|
33
|
+
summaryLines: [...params.state.summaryLines]
|
|
34
|
+
},
|
|
35
|
+
noun: params.noun,
|
|
36
|
+
title: params.title
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function applyQueueRuntimeSettings(params) {
|
|
40
|
+
params.target.mode = params.settings.mode;
|
|
41
|
+
params.target.debounceMs = typeof params.settings.debounceMs === "number" ? Math.max(0, params.settings.debounceMs) : params.target.debounceMs;
|
|
42
|
+
params.target.cap = typeof params.settings.cap === "number" && params.settings.cap > 0 ? Math.floor(params.settings.cap) : params.target.cap;
|
|
43
|
+
params.target.dropPolicy = params.settings.dropPolicy ?? params.target.dropPolicy;
|
|
44
|
+
}
|
|
45
|
+
function elideQueueText(text, limit = 140) {
|
|
46
|
+
if (text.length <= limit) return text;
|
|
47
|
+
return `${text.slice(0, Math.max(0, limit - 1)).trimEnd()}…`;
|
|
48
|
+
}
|
|
49
|
+
function buildQueueSummaryLine(text, limit = 160) {
|
|
50
|
+
return elideQueueText(text.replace(/\s+/g, " ").trim(), limit);
|
|
51
|
+
}
|
|
52
|
+
function shouldSkipQueueItem(params) {
|
|
53
|
+
if (!params.dedupe) return false;
|
|
54
|
+
return params.dedupe(params.item, params.items);
|
|
55
|
+
}
|
|
56
|
+
function applyQueueDropPolicy(params) {
|
|
57
|
+
const cap = params.queue.cap;
|
|
58
|
+
if (cap <= 0 || params.queue.items.length < cap) return true;
|
|
59
|
+
if (params.queue.dropPolicy === "new") return false;
|
|
60
|
+
const dropCount = params.queue.items.length - cap + 1;
|
|
61
|
+
const dropped = params.queue.items.splice(0, dropCount);
|
|
62
|
+
if (params.queue.dropPolicy === "summarize") {
|
|
63
|
+
for (const item of dropped) {
|
|
64
|
+
params.queue.droppedCount += 1;
|
|
65
|
+
params.queue.summaryLines.push(buildQueueSummaryLine(params.summarize(item)));
|
|
66
|
+
}
|
|
67
|
+
const limit = Math.max(0, params.summaryLimit ?? cap);
|
|
68
|
+
while (params.queue.summaryLines.length > limit) params.queue.summaryLines.shift();
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
function waitForQueueDebounce(queue) {
|
|
73
|
+
if (process.env.REMOTECLAW_TEST_FAST === "1") return Promise.resolve();
|
|
74
|
+
const debounceMs = Math.max(0, queue.debounceMs);
|
|
75
|
+
if (debounceMs <= 0) return Promise.resolve();
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
const check = () => {
|
|
78
|
+
const since = Date.now() - queue.lastEnqueuedAt;
|
|
79
|
+
if (since >= debounceMs) {
|
|
80
|
+
resolve();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
setTimeout(check, debounceMs - since);
|
|
84
|
+
};
|
|
85
|
+
check();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function beginQueueDrain(map, key) {
|
|
89
|
+
const queue = map.get(key);
|
|
90
|
+
if (!queue || queue.draining) return;
|
|
91
|
+
queue.draining = true;
|
|
92
|
+
return queue;
|
|
93
|
+
}
|
|
94
|
+
async function drainNextQueueItem(items, run) {
|
|
95
|
+
const next = items[0];
|
|
96
|
+
if (!next) return false;
|
|
97
|
+
await run(next);
|
|
98
|
+
items.shift();
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
async function drainCollectItemIfNeeded(params) {
|
|
102
|
+
if (!params.forceIndividualCollect && !params.isCrossChannel) return "skipped";
|
|
103
|
+
if (params.isCrossChannel) params.setForceIndividualCollect?.(true);
|
|
104
|
+
return await drainNextQueueItem(params.items, params.run) ? "drained" : "empty";
|
|
105
|
+
}
|
|
106
|
+
async function drainCollectQueueStep(params) {
|
|
107
|
+
return await drainCollectItemIfNeeded({
|
|
108
|
+
forceIndividualCollect: params.collectState.forceIndividualCollect,
|
|
109
|
+
isCrossChannel: params.isCrossChannel,
|
|
110
|
+
setForceIndividualCollect: (next) => {
|
|
111
|
+
params.collectState.forceIndividualCollect = next;
|
|
112
|
+
},
|
|
113
|
+
items: params.items,
|
|
114
|
+
run: params.run
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function buildQueueSummaryPrompt(params) {
|
|
118
|
+
if (params.state.dropPolicy !== "summarize" || params.state.droppedCount <= 0) return;
|
|
119
|
+
const noun = params.noun;
|
|
120
|
+
const lines = [params.title ?? `[Queue overflow] Dropped ${params.state.droppedCount} ${noun}${params.state.droppedCount === 1 ? "" : "s"} due to cap.`];
|
|
121
|
+
if (params.state.summaryLines.length > 0) {
|
|
122
|
+
lines.push("Summary:");
|
|
123
|
+
for (const line of params.state.summaryLines) lines.push(`- ${line}`);
|
|
124
|
+
}
|
|
125
|
+
clearQueueSummaryState(params.state);
|
|
126
|
+
return lines.join("\n");
|
|
127
|
+
}
|
|
128
|
+
function buildCollectPrompt(params) {
|
|
129
|
+
const blocks = [params.title];
|
|
130
|
+
if (params.summary) blocks.push(params.summary);
|
|
131
|
+
params.items.forEach((item, idx) => {
|
|
132
|
+
blocks.push(params.renderItem(item, idx));
|
|
133
|
+
});
|
|
134
|
+
return blocks.join("\n\n");
|
|
135
|
+
}
|
|
136
|
+
function hasCrossChannelItems(items, resolveKey) {
|
|
137
|
+
const keys = /* @__PURE__ */ new Set();
|
|
138
|
+
let hasUnkeyed = false;
|
|
139
|
+
for (const item of items) {
|
|
140
|
+
const resolved = resolveKey(item);
|
|
141
|
+
if (resolved.cross) return true;
|
|
142
|
+
if (!resolved.key) {
|
|
143
|
+
hasUnkeyed = true;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
keys.add(resolved.key);
|
|
147
|
+
}
|
|
148
|
+
if (keys.size === 0) return false;
|
|
149
|
+
if (hasUnkeyed) return true;
|
|
150
|
+
return keys.size > 1;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
//#region src/auto-reply/reply/directive-parsing.ts
|
|
155
|
+
function skipDirectiveArgPrefix(raw) {
|
|
156
|
+
let i = 0;
|
|
157
|
+
const len = raw.length;
|
|
158
|
+
while (i < len && /\s/.test(raw[i])) i += 1;
|
|
159
|
+
if (raw[i] === ":") {
|
|
160
|
+
i += 1;
|
|
161
|
+
while (i < len && /\s/.test(raw[i])) i += 1;
|
|
162
|
+
}
|
|
163
|
+
return i;
|
|
164
|
+
}
|
|
165
|
+
function takeDirectiveToken(raw, startIndex) {
|
|
166
|
+
let i = startIndex;
|
|
167
|
+
const len = raw.length;
|
|
168
|
+
while (i < len && /\s/.test(raw[i])) i += 1;
|
|
169
|
+
if (i >= len) return {
|
|
170
|
+
token: null,
|
|
171
|
+
nextIndex: i
|
|
172
|
+
};
|
|
173
|
+
const start = i;
|
|
174
|
+
while (i < len && !/\s/.test(raw[i])) i += 1;
|
|
175
|
+
if (start === i) return {
|
|
176
|
+
token: null,
|
|
177
|
+
nextIndex: i
|
|
178
|
+
};
|
|
179
|
+
const token = raw.slice(start, i);
|
|
180
|
+
while (i < len && /\s/.test(raw[i])) i += 1;
|
|
181
|
+
return {
|
|
182
|
+
token,
|
|
183
|
+
nextIndex: i
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//#endregion
|
|
188
|
+
//#region src/auto-reply/reply/queue/normalize.ts
|
|
189
|
+
function normalizeQueueMode(raw) {
|
|
190
|
+
if (!raw) return;
|
|
191
|
+
const cleaned = raw.trim().toLowerCase();
|
|
192
|
+
if (cleaned === "queue" || cleaned === "queued") return "steer";
|
|
193
|
+
if (cleaned === "interrupt" || cleaned === "interrupts" || cleaned === "abort") return "interrupt";
|
|
194
|
+
if (cleaned === "steer" || cleaned === "steering") return "steer";
|
|
195
|
+
if (cleaned === "followup" || cleaned === "follow-ups" || cleaned === "followups") return "followup";
|
|
196
|
+
if (cleaned === "collect" || cleaned === "coalesce") return "collect";
|
|
197
|
+
if (cleaned === "steer+backlog" || cleaned === "steer-backlog" || cleaned === "steer_backlog") return "steer-backlog";
|
|
198
|
+
}
|
|
199
|
+
function normalizeQueueDropPolicy(raw) {
|
|
200
|
+
if (!raw) return;
|
|
201
|
+
const cleaned = raw.trim().toLowerCase();
|
|
202
|
+
if (cleaned === "old" || cleaned === "oldest") return "old";
|
|
203
|
+
if (cleaned === "new" || cleaned === "newest") return "new";
|
|
204
|
+
if (cleaned === "summarize" || cleaned === "summary") return "summarize";
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/auto-reply/reply/queue/directive.ts
|
|
209
|
+
function parseQueueDebounce(raw) {
|
|
210
|
+
if (!raw) return;
|
|
211
|
+
try {
|
|
212
|
+
const parsed = parseDurationMs(raw.trim(), { defaultUnit: "ms" });
|
|
213
|
+
if (!parsed || parsed < 0) return;
|
|
214
|
+
return Math.round(parsed);
|
|
215
|
+
} catch {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function parseQueueCap(raw) {
|
|
220
|
+
if (!raw) return;
|
|
221
|
+
const num = Number(raw);
|
|
222
|
+
if (!Number.isFinite(num)) return;
|
|
223
|
+
const cap = Math.floor(num);
|
|
224
|
+
if (cap < 1) return;
|
|
225
|
+
return cap;
|
|
226
|
+
}
|
|
227
|
+
function parseQueueDirectiveArgs(raw) {
|
|
228
|
+
const len = raw.length;
|
|
229
|
+
let i = skipDirectiveArgPrefix(raw);
|
|
230
|
+
let consumed = i;
|
|
231
|
+
let queueMode;
|
|
232
|
+
let queueReset = false;
|
|
233
|
+
let rawMode;
|
|
234
|
+
let debounceMs;
|
|
235
|
+
let cap;
|
|
236
|
+
let dropPolicy;
|
|
237
|
+
let rawDebounce;
|
|
238
|
+
let rawCap;
|
|
239
|
+
let rawDrop;
|
|
240
|
+
let hasOptions = false;
|
|
241
|
+
const takeToken = () => {
|
|
242
|
+
const res = takeDirectiveToken(raw, i);
|
|
243
|
+
i = res.nextIndex;
|
|
244
|
+
return res.token;
|
|
245
|
+
};
|
|
246
|
+
while (i < len) {
|
|
247
|
+
const token = takeToken();
|
|
248
|
+
if (!token) break;
|
|
249
|
+
const lowered = token.trim().toLowerCase();
|
|
250
|
+
if (lowered === "default" || lowered === "reset" || lowered === "clear") {
|
|
251
|
+
queueReset = true;
|
|
252
|
+
consumed = i;
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
if (lowered.startsWith("debounce:") || lowered.startsWith("debounce=")) {
|
|
256
|
+
rawDebounce = token.split(/[:=]/)[1] ?? "";
|
|
257
|
+
debounceMs = parseQueueDebounce(rawDebounce);
|
|
258
|
+
hasOptions = true;
|
|
259
|
+
consumed = i;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (lowered.startsWith("cap:") || lowered.startsWith("cap=")) {
|
|
263
|
+
rawCap = token.split(/[:=]/)[1] ?? "";
|
|
264
|
+
cap = parseQueueCap(rawCap);
|
|
265
|
+
hasOptions = true;
|
|
266
|
+
consumed = i;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (lowered.startsWith("drop:") || lowered.startsWith("drop=")) {
|
|
270
|
+
rawDrop = token.split(/[:=]/)[1] ?? "";
|
|
271
|
+
dropPolicy = normalizeQueueDropPolicy(rawDrop);
|
|
272
|
+
hasOptions = true;
|
|
273
|
+
consumed = i;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const mode = normalizeQueueMode(token);
|
|
277
|
+
if (mode) {
|
|
278
|
+
queueMode = mode;
|
|
279
|
+
rawMode = token;
|
|
280
|
+
consumed = i;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
consumed,
|
|
287
|
+
queueMode,
|
|
288
|
+
queueReset,
|
|
289
|
+
rawMode,
|
|
290
|
+
debounceMs,
|
|
291
|
+
cap,
|
|
292
|
+
dropPolicy,
|
|
293
|
+
rawDebounce,
|
|
294
|
+
rawCap,
|
|
295
|
+
rawDrop,
|
|
296
|
+
hasOptions
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
function extractQueueDirective(body) {
|
|
300
|
+
if (!body) return {
|
|
301
|
+
cleaned: "",
|
|
302
|
+
hasDirective: false,
|
|
303
|
+
queueReset: false,
|
|
304
|
+
hasOptions: false
|
|
305
|
+
};
|
|
306
|
+
const match = /(?:^|\s)\/queue(?=$|\s|:)/i.exec(body);
|
|
307
|
+
if (!match) return {
|
|
308
|
+
cleaned: body.trim(),
|
|
309
|
+
hasDirective: false,
|
|
310
|
+
queueReset: false,
|
|
311
|
+
hasOptions: false
|
|
312
|
+
};
|
|
313
|
+
const start = match.index + match[0].indexOf("/queue");
|
|
314
|
+
const argsStart = start + 6;
|
|
315
|
+
const parsed = parseQueueDirectiveArgs(body.slice(argsStart));
|
|
316
|
+
return {
|
|
317
|
+
cleaned: `${body.slice(0, start)} ${body.slice(argsStart + parsed.consumed)}`.replace(/\s+/g, " ").trim(),
|
|
318
|
+
queueMode: parsed.queueMode,
|
|
319
|
+
queueReset: parsed.queueReset,
|
|
320
|
+
rawMode: parsed.rawMode,
|
|
321
|
+
debounceMs: parsed.debounceMs,
|
|
322
|
+
cap: parsed.cap,
|
|
323
|
+
dropPolicy: parsed.dropPolicy,
|
|
324
|
+
rawDebounce: parsed.rawDebounce,
|
|
325
|
+
rawCap: parsed.rawCap,
|
|
326
|
+
rawDrop: parsed.rawDrop,
|
|
327
|
+
hasDirective: true,
|
|
328
|
+
hasOptions: parsed.hasOptions
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region src/infra/diagnostic-events.ts
|
|
334
|
+
function getDiagnosticEventsState() {
|
|
335
|
+
const globalStore = globalThis;
|
|
336
|
+
if (!globalStore.__remoteclawDiagnosticEventsState) globalStore.__remoteclawDiagnosticEventsState = {
|
|
337
|
+
seq: 0,
|
|
338
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
339
|
+
dispatchDepth: 0
|
|
340
|
+
};
|
|
341
|
+
return globalStore.__remoteclawDiagnosticEventsState;
|
|
342
|
+
}
|
|
343
|
+
function isDiagnosticsEnabled(config) {
|
|
344
|
+
return config?.diagnostics?.enabled === true;
|
|
345
|
+
}
|
|
346
|
+
function emitDiagnosticEvent(event) {
|
|
347
|
+
const state = getDiagnosticEventsState();
|
|
348
|
+
if (state.dispatchDepth > 100) {
|
|
349
|
+
console.error(`[diagnostic-events] recursion guard tripped at depth=${state.dispatchDepth}, dropping type=${event.type}`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const enriched = {
|
|
353
|
+
...event,
|
|
354
|
+
seq: state.seq += 1,
|
|
355
|
+
ts: Date.now()
|
|
356
|
+
};
|
|
357
|
+
state.dispatchDepth += 1;
|
|
358
|
+
for (const listener of state.listeners) try {
|
|
359
|
+
listener(enriched);
|
|
360
|
+
} catch (err) {
|
|
361
|
+
const errorMessage = err instanceof Error ? err.stack ?? err.message : typeof err === "string" ? err : String(err);
|
|
362
|
+
console.error(`[diagnostic-events] listener error type=${enriched.type} seq=${enriched.seq}: ${errorMessage}`);
|
|
363
|
+
}
|
|
364
|
+
state.dispatchDepth -= 1;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/logging/diagnostic-session-state.ts
|
|
369
|
+
const diagnosticSessionStates = /* @__PURE__ */ new Map();
|
|
370
|
+
const SESSION_STATE_TTL_MS = 1800 * 1e3;
|
|
371
|
+
const SESSION_STATE_PRUNE_INTERVAL_MS = 60 * 1e3;
|
|
372
|
+
const SESSION_STATE_MAX_ENTRIES = 2e3;
|
|
373
|
+
let lastSessionPruneAt = 0;
|
|
374
|
+
function pruneDiagnosticSessionStates(now = Date.now(), force = false) {
|
|
375
|
+
const shouldPruneForSize = diagnosticSessionStates.size > SESSION_STATE_MAX_ENTRIES;
|
|
376
|
+
if (!force && !shouldPruneForSize && now - lastSessionPruneAt < SESSION_STATE_PRUNE_INTERVAL_MS) return;
|
|
377
|
+
lastSessionPruneAt = now;
|
|
378
|
+
for (const [key, state] of diagnosticSessionStates.entries()) {
|
|
379
|
+
const ageMs = now - state.lastActivity;
|
|
380
|
+
if (state.state === "idle" && state.queueDepth <= 0 && ageMs > SESSION_STATE_TTL_MS) diagnosticSessionStates.delete(key);
|
|
381
|
+
}
|
|
382
|
+
if (diagnosticSessionStates.size <= SESSION_STATE_MAX_ENTRIES) return;
|
|
383
|
+
const excess = diagnosticSessionStates.size - SESSION_STATE_MAX_ENTRIES;
|
|
384
|
+
const ordered = Array.from(diagnosticSessionStates.entries()).toSorted((a, b) => a[1].lastActivity - b[1].lastActivity);
|
|
385
|
+
for (let i = 0; i < excess; i += 1) {
|
|
386
|
+
const key = ordered[i]?.[0];
|
|
387
|
+
if (!key) break;
|
|
388
|
+
diagnosticSessionStates.delete(key);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function resolveSessionKey({ sessionKey, sessionId }) {
|
|
392
|
+
return sessionKey ?? sessionId ?? "unknown";
|
|
393
|
+
}
|
|
394
|
+
function findStateBySessionId(sessionId) {
|
|
395
|
+
for (const state of diagnosticSessionStates.values()) if (state.sessionId === sessionId) return state;
|
|
396
|
+
}
|
|
397
|
+
function getDiagnosticSessionState(ref) {
|
|
398
|
+
pruneDiagnosticSessionStates();
|
|
399
|
+
const key = resolveSessionKey(ref);
|
|
400
|
+
const existing = diagnosticSessionStates.get(key) ?? (ref.sessionId && findStateBySessionId(ref.sessionId));
|
|
401
|
+
if (existing) {
|
|
402
|
+
if (ref.sessionId) existing.sessionId = ref.sessionId;
|
|
403
|
+
if (ref.sessionKey) existing.sessionKey = ref.sessionKey;
|
|
404
|
+
return existing;
|
|
405
|
+
}
|
|
406
|
+
const created = {
|
|
407
|
+
sessionId: ref.sessionId,
|
|
408
|
+
sessionKey: ref.sessionKey,
|
|
409
|
+
lastActivity: Date.now(),
|
|
410
|
+
state: "idle",
|
|
411
|
+
queueDepth: 0
|
|
412
|
+
};
|
|
413
|
+
diagnosticSessionStates.set(key, created);
|
|
414
|
+
pruneDiagnosticSessionStates(Date.now(), true);
|
|
415
|
+
return created;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region src/logging/diagnostic.ts
|
|
420
|
+
const diag = createSubsystemLogger("diagnostic");
|
|
421
|
+
const webhookStats = {
|
|
422
|
+
received: 0,
|
|
423
|
+
processed: 0,
|
|
424
|
+
errors: 0,
|
|
425
|
+
lastReceived: 0
|
|
426
|
+
};
|
|
427
|
+
let lastActivityAt = 0;
|
|
428
|
+
function markActivity() {
|
|
429
|
+
lastActivityAt = Date.now();
|
|
430
|
+
}
|
|
431
|
+
function logWebhookReceived(params) {
|
|
432
|
+
webhookStats.received += 1;
|
|
433
|
+
webhookStats.lastReceived = Date.now();
|
|
434
|
+
if (diag.isEnabled("debug")) diag.debug(`webhook received: channel=${params.channel} type=${params.updateType ?? "unknown"} chatId=${params.chatId ?? "unknown"} total=${webhookStats.received}`);
|
|
435
|
+
emitDiagnosticEvent({
|
|
436
|
+
type: "webhook.received",
|
|
437
|
+
channel: params.channel,
|
|
438
|
+
updateType: params.updateType,
|
|
439
|
+
chatId: params.chatId
|
|
440
|
+
});
|
|
441
|
+
markActivity();
|
|
442
|
+
}
|
|
443
|
+
function logWebhookProcessed(params) {
|
|
444
|
+
webhookStats.processed += 1;
|
|
445
|
+
if (diag.isEnabled("debug")) diag.debug(`webhook processed: channel=${params.channel} type=${params.updateType ?? "unknown"} chatId=${params.chatId ?? "unknown"} duration=${params.durationMs ?? 0}ms processed=${webhookStats.processed}`);
|
|
446
|
+
emitDiagnosticEvent({
|
|
447
|
+
type: "webhook.processed",
|
|
448
|
+
channel: params.channel,
|
|
449
|
+
updateType: params.updateType,
|
|
450
|
+
chatId: params.chatId,
|
|
451
|
+
durationMs: params.durationMs
|
|
452
|
+
});
|
|
453
|
+
markActivity();
|
|
454
|
+
}
|
|
455
|
+
function logWebhookError(params) {
|
|
456
|
+
webhookStats.errors += 1;
|
|
457
|
+
diag.error(`webhook error: channel=${params.channel} type=${params.updateType ?? "unknown"} chatId=${params.chatId ?? "unknown"} error="${params.error}" errors=${webhookStats.errors}`);
|
|
458
|
+
emitDiagnosticEvent({
|
|
459
|
+
type: "webhook.error",
|
|
460
|
+
channel: params.channel,
|
|
461
|
+
updateType: params.updateType,
|
|
462
|
+
chatId: params.chatId,
|
|
463
|
+
error: params.error
|
|
464
|
+
});
|
|
465
|
+
markActivity();
|
|
466
|
+
}
|
|
467
|
+
function logMessageQueued(params) {
|
|
468
|
+
const state = getDiagnosticSessionState(params);
|
|
469
|
+
state.queueDepth += 1;
|
|
470
|
+
state.lastActivity = Date.now();
|
|
471
|
+
if (diag.isEnabled("debug")) diag.debug(`message queued: sessionId=${state.sessionId ?? "unknown"} sessionKey=${state.sessionKey ?? "unknown"} source=${params.source} queueDepth=${state.queueDepth} sessionState=${state.state}`);
|
|
472
|
+
emitDiagnosticEvent({
|
|
473
|
+
type: "message.queued",
|
|
474
|
+
sessionId: state.sessionId,
|
|
475
|
+
sessionKey: state.sessionKey,
|
|
476
|
+
channel: params.channel,
|
|
477
|
+
source: params.source,
|
|
478
|
+
queueDepth: state.queueDepth
|
|
479
|
+
});
|
|
480
|
+
markActivity();
|
|
481
|
+
}
|
|
482
|
+
function logMessageProcessed(params) {
|
|
483
|
+
if (params.outcome === "error" ? diag.isEnabled("error") : diag.isEnabled("debug")) {
|
|
484
|
+
const payload = `message processed: channel=${params.channel} chatId=${params.chatId ?? "unknown"} messageId=${params.messageId ?? "unknown"} sessionId=${params.sessionId ?? "unknown"} sessionKey=${params.sessionKey ?? "unknown"} outcome=${params.outcome} duration=${params.durationMs ?? 0}ms${params.reason ? ` reason=${params.reason}` : ""}${params.error ? ` error="${params.error}"` : ""}`;
|
|
485
|
+
if (params.outcome === "error") diag.error(payload);
|
|
486
|
+
else diag.debug(payload);
|
|
487
|
+
}
|
|
488
|
+
emitDiagnosticEvent({
|
|
489
|
+
type: "message.processed",
|
|
490
|
+
channel: params.channel,
|
|
491
|
+
chatId: params.chatId,
|
|
492
|
+
messageId: params.messageId,
|
|
493
|
+
sessionId: params.sessionId,
|
|
494
|
+
sessionKey: params.sessionKey,
|
|
495
|
+
durationMs: params.durationMs,
|
|
496
|
+
outcome: params.outcome,
|
|
497
|
+
reason: params.reason,
|
|
498
|
+
error: params.error
|
|
499
|
+
});
|
|
500
|
+
markActivity();
|
|
501
|
+
}
|
|
502
|
+
function logSessionStateChange(params) {
|
|
503
|
+
const state = getDiagnosticSessionState(params);
|
|
504
|
+
const isProbeSession = state.sessionId?.startsWith("probe-") ?? false;
|
|
505
|
+
const prevState = state.state;
|
|
506
|
+
state.state = params.state;
|
|
507
|
+
state.lastActivity = Date.now();
|
|
508
|
+
if (params.state === "idle") state.queueDepth = Math.max(0, state.queueDepth - 1);
|
|
509
|
+
if (!isProbeSession && diag.isEnabled("debug")) diag.debug(`session state: sessionId=${state.sessionId ?? "unknown"} sessionKey=${state.sessionKey ?? "unknown"} prev=${prevState} new=${params.state} reason="${params.reason ?? ""}" queueDepth=${state.queueDepth}`);
|
|
510
|
+
emitDiagnosticEvent({
|
|
511
|
+
type: "session.state",
|
|
512
|
+
sessionId: state.sessionId,
|
|
513
|
+
sessionKey: state.sessionKey,
|
|
514
|
+
prevState,
|
|
515
|
+
state: params.state,
|
|
516
|
+
reason: params.reason,
|
|
517
|
+
queueDepth: state.queueDepth
|
|
518
|
+
});
|
|
519
|
+
markActivity();
|
|
520
|
+
}
|
|
521
|
+
function logSessionStuck(params) {
|
|
522
|
+
const state = getDiagnosticSessionState(params);
|
|
523
|
+
diag.warn(`stuck session: sessionId=${state.sessionId ?? "unknown"} sessionKey=${state.sessionKey ?? "unknown"} state=${params.state} age=${Math.round(params.ageMs / 1e3)}s queueDepth=${state.queueDepth}`);
|
|
524
|
+
emitDiagnosticEvent({
|
|
525
|
+
type: "session.stuck",
|
|
526
|
+
sessionId: state.sessionId,
|
|
527
|
+
sessionKey: state.sessionKey,
|
|
528
|
+
state: params.state,
|
|
529
|
+
ageMs: params.ageMs,
|
|
530
|
+
queueDepth: state.queueDepth
|
|
531
|
+
});
|
|
532
|
+
markActivity();
|
|
533
|
+
}
|
|
534
|
+
function logLaneDequeue(lane, waitMs, queueSize) {
|
|
535
|
+
diag.debug(`lane dequeue: lane=${lane} waitMs=${waitMs} queueSize=${queueSize}`);
|
|
536
|
+
emitDiagnosticEvent({
|
|
537
|
+
type: "queue.lane.dequeue",
|
|
538
|
+
lane,
|
|
539
|
+
queueSize,
|
|
540
|
+
waitMs
|
|
541
|
+
});
|
|
542
|
+
markActivity();
|
|
543
|
+
}
|
|
544
|
+
let heartbeatInterval = null;
|
|
545
|
+
function startDiagnosticHeartbeat() {
|
|
546
|
+
if (heartbeatInterval) return;
|
|
547
|
+
heartbeatInterval = setInterval(() => {
|
|
548
|
+
const now = Date.now();
|
|
549
|
+
pruneDiagnosticSessionStates(now, true);
|
|
550
|
+
const activeCount = Array.from(diagnosticSessionStates.values()).filter((s) => s.state === "processing").length;
|
|
551
|
+
const waitingCount = Array.from(diagnosticSessionStates.values()).filter((s) => s.state === "waiting").length;
|
|
552
|
+
const totalQueued = Array.from(diagnosticSessionStates.values()).reduce((sum, s) => sum + s.queueDepth, 0);
|
|
553
|
+
if (!(lastActivityAt > 0 || webhookStats.received > 0 || activeCount > 0 || waitingCount > 0 || totalQueued > 0)) return;
|
|
554
|
+
if (now - lastActivityAt > 12e4 && activeCount === 0 && waitingCount === 0) return;
|
|
555
|
+
diag.debug(`heartbeat: webhooks=${webhookStats.received}/${webhookStats.processed}/${webhookStats.errors} active=${activeCount} waiting=${waitingCount} queued=${totalQueued}`);
|
|
556
|
+
emitDiagnosticEvent({
|
|
557
|
+
type: "diagnostic.heartbeat",
|
|
558
|
+
webhooks: {
|
|
559
|
+
received: webhookStats.received,
|
|
560
|
+
processed: webhookStats.processed,
|
|
561
|
+
errors: webhookStats.errors
|
|
562
|
+
},
|
|
563
|
+
active: activeCount,
|
|
564
|
+
waiting: waitingCount,
|
|
565
|
+
queued: totalQueued
|
|
566
|
+
});
|
|
567
|
+
for (const [, state] of diagnosticSessionStates) {
|
|
568
|
+
const ageMs = now - state.lastActivity;
|
|
569
|
+
if (state.state === "processing" && ageMs > 12e4) logSessionStuck({
|
|
570
|
+
sessionId: state.sessionId,
|
|
571
|
+
sessionKey: state.sessionKey,
|
|
572
|
+
state: state.state,
|
|
573
|
+
ageMs
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}, 3e4);
|
|
577
|
+
heartbeatInterval.unref?.();
|
|
578
|
+
}
|
|
579
|
+
function stopDiagnosticHeartbeat() {
|
|
580
|
+
if (heartbeatInterval) {
|
|
581
|
+
clearInterval(heartbeatInterval);
|
|
582
|
+
heartbeatInterval = null;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
//#endregion
|
|
587
|
+
//#region src/process/command-queue.ts
|
|
588
|
+
/**
|
|
589
|
+
* Dedicated error type thrown when a queued command is rejected because
|
|
590
|
+
* its lane was cleared. Callers that fire-and-forget enqueued tasks can
|
|
591
|
+
* catch (or ignore) this specific type to avoid unhandled-rejection noise.
|
|
592
|
+
*/
|
|
593
|
+
var CommandLaneClearedError = class extends Error {
|
|
594
|
+
constructor(lane) {
|
|
595
|
+
super(lane ? `Command lane "${lane}" cleared` : "Command lane cleared");
|
|
596
|
+
this.name = "CommandLaneClearedError";
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
const lanes = /* @__PURE__ */ new Map();
|
|
600
|
+
let nextTaskId = 1;
|
|
601
|
+
function getLaneState(lane) {
|
|
602
|
+
const existing = lanes.get(lane);
|
|
603
|
+
if (existing) return existing;
|
|
604
|
+
const created = {
|
|
605
|
+
lane,
|
|
606
|
+
queue: [],
|
|
607
|
+
activeTaskIds: /* @__PURE__ */ new Set(),
|
|
608
|
+
maxConcurrent: 1,
|
|
609
|
+
draining: false,
|
|
610
|
+
generation: 0
|
|
611
|
+
};
|
|
612
|
+
lanes.set(lane, created);
|
|
613
|
+
return created;
|
|
614
|
+
}
|
|
615
|
+
function completeTask(state, taskId, taskGeneration) {
|
|
616
|
+
if (taskGeneration !== state.generation) return false;
|
|
617
|
+
state.activeTaskIds.delete(taskId);
|
|
618
|
+
return true;
|
|
619
|
+
}
|
|
620
|
+
function drainLane(lane) {
|
|
621
|
+
const state = getLaneState(lane);
|
|
622
|
+
if (state.draining) return;
|
|
623
|
+
state.draining = true;
|
|
624
|
+
const pump = () => {
|
|
625
|
+
while (state.activeTaskIds.size < state.maxConcurrent && state.queue.length > 0) {
|
|
626
|
+
const entry = state.queue.shift();
|
|
627
|
+
const waitedMs = Date.now() - entry.enqueuedAt;
|
|
628
|
+
if (waitedMs >= entry.warnAfterMs) {
|
|
629
|
+
entry.onWait?.(waitedMs, state.queue.length);
|
|
630
|
+
diag.warn(`lane wait exceeded: lane=${lane} waitedMs=${waitedMs} queueAhead=${state.queue.length}`);
|
|
631
|
+
}
|
|
632
|
+
logLaneDequeue(lane, waitedMs, state.queue.length);
|
|
633
|
+
const taskId = nextTaskId++;
|
|
634
|
+
const taskGeneration = state.generation;
|
|
635
|
+
state.activeTaskIds.add(taskId);
|
|
636
|
+
(async () => {
|
|
637
|
+
const startTime = Date.now();
|
|
638
|
+
try {
|
|
639
|
+
const result = await entry.task();
|
|
640
|
+
if (completeTask(state, taskId, taskGeneration)) {
|
|
641
|
+
diag.debug(`lane task done: lane=${lane} durationMs=${Date.now() - startTime} active=${state.activeTaskIds.size} queued=${state.queue.length}`);
|
|
642
|
+
pump();
|
|
643
|
+
}
|
|
644
|
+
entry.resolve(result);
|
|
645
|
+
} catch (err) {
|
|
646
|
+
const completedCurrentGeneration = completeTask(state, taskId, taskGeneration);
|
|
647
|
+
if (!(lane.startsWith("auth-probe:") || lane.startsWith("session:probe-"))) diag.error(`lane task error: lane=${lane} durationMs=${Date.now() - startTime} error="${String(err)}"`);
|
|
648
|
+
if (completedCurrentGeneration) pump();
|
|
649
|
+
entry.reject(err);
|
|
650
|
+
}
|
|
651
|
+
})();
|
|
652
|
+
}
|
|
653
|
+
state.draining = false;
|
|
654
|
+
};
|
|
655
|
+
pump();
|
|
656
|
+
}
|
|
657
|
+
function setCommandLaneConcurrency(lane, maxConcurrent) {
|
|
658
|
+
const cleaned = lane.trim() || CommandLane.Main;
|
|
659
|
+
const state = getLaneState(cleaned);
|
|
660
|
+
state.maxConcurrent = Math.max(1, Math.floor(maxConcurrent));
|
|
661
|
+
drainLane(cleaned);
|
|
662
|
+
}
|
|
663
|
+
function getQueueSize(lane = CommandLane.Main) {
|
|
664
|
+
const resolved = lane.trim() || CommandLane.Main;
|
|
665
|
+
const state = lanes.get(resolved);
|
|
666
|
+
if (!state) return 0;
|
|
667
|
+
return state.queue.length + state.activeTaskIds.size;
|
|
668
|
+
}
|
|
669
|
+
function getTotalQueueSize() {
|
|
670
|
+
let total = 0;
|
|
671
|
+
for (const s of lanes.values()) total += s.queue.length + s.activeTaskIds.size;
|
|
672
|
+
return total;
|
|
673
|
+
}
|
|
674
|
+
function clearCommandLane(lane = CommandLane.Main) {
|
|
675
|
+
const cleaned = lane.trim() || CommandLane.Main;
|
|
676
|
+
const state = lanes.get(cleaned);
|
|
677
|
+
if (!state) return 0;
|
|
678
|
+
const removed = state.queue.length;
|
|
679
|
+
const pending = state.queue.splice(0);
|
|
680
|
+
for (const entry of pending) entry.reject(new CommandLaneClearedError(cleaned));
|
|
681
|
+
return removed;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Reset all lane runtime state to idle. Used after SIGUSR1 in-process
|
|
685
|
+
* restarts where interrupted tasks' finally blocks may not run, leaving
|
|
686
|
+
* stale active task IDs that permanently block new work from draining.
|
|
687
|
+
*
|
|
688
|
+
* Bumps lane generation and clears execution counters so stale completions
|
|
689
|
+
* from old in-flight tasks are ignored. Queued entries are intentionally
|
|
690
|
+
* preserved — they represent pending user work that should still execute
|
|
691
|
+
* after restart.
|
|
692
|
+
*
|
|
693
|
+
* After resetting, drains any lanes that still have queued entries so
|
|
694
|
+
* preserved work is pumped immediately rather than waiting for a future
|
|
695
|
+
* `enqueueCommandInLane()` call (which may never come).
|
|
696
|
+
*/
|
|
697
|
+
function resetAllLanes() {
|
|
698
|
+
const lanesToDrain = [];
|
|
699
|
+
for (const state of lanes.values()) {
|
|
700
|
+
state.generation += 1;
|
|
701
|
+
state.activeTaskIds.clear();
|
|
702
|
+
state.draining = false;
|
|
703
|
+
if (state.queue.length > 0) lanesToDrain.push(state.lane);
|
|
704
|
+
}
|
|
705
|
+
for (const lane of lanesToDrain) drainLane(lane);
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Returns the total number of actively executing tasks across all lanes
|
|
709
|
+
* (excludes queued-but-not-started entries).
|
|
710
|
+
*/
|
|
711
|
+
function getActiveTaskCount() {
|
|
712
|
+
let total = 0;
|
|
713
|
+
for (const s of lanes.values()) total += s.activeTaskIds.size;
|
|
714
|
+
return total;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Wait for all currently active tasks across all lanes to finish.
|
|
718
|
+
* Polls at a short interval; resolves when no tasks are active or
|
|
719
|
+
* when `timeoutMs` elapses (whichever comes first).
|
|
720
|
+
*
|
|
721
|
+
* New tasks enqueued after this call are ignored — only tasks that are
|
|
722
|
+
* already executing are waited on.
|
|
723
|
+
*/
|
|
724
|
+
function waitForActiveTasks(timeoutMs) {
|
|
725
|
+
const POLL_INTERVAL_MS = 50;
|
|
726
|
+
const deadline = Date.now() + timeoutMs;
|
|
727
|
+
const activeAtStart = /* @__PURE__ */ new Set();
|
|
728
|
+
for (const state of lanes.values()) for (const taskId of state.activeTaskIds) activeAtStart.add(taskId);
|
|
729
|
+
return new Promise((resolve) => {
|
|
730
|
+
const check = () => {
|
|
731
|
+
if (activeAtStart.size === 0) {
|
|
732
|
+
resolve({ drained: true });
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
let hasPending = false;
|
|
736
|
+
for (const state of lanes.values()) {
|
|
737
|
+
for (const taskId of state.activeTaskIds) if (activeAtStart.has(taskId)) {
|
|
738
|
+
hasPending = true;
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
if (hasPending) break;
|
|
742
|
+
}
|
|
743
|
+
if (!hasPending) {
|
|
744
|
+
resolve({ drained: true });
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (Date.now() >= deadline) {
|
|
748
|
+
resolve({ drained: false });
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
setTimeout(check, POLL_INTERVAL_MS);
|
|
752
|
+
};
|
|
753
|
+
check();
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/auto-reply/reply/queue/state.ts
|
|
759
|
+
const DEFAULT_QUEUE_DEBOUNCE_MS = 1e3;
|
|
760
|
+
const DEFAULT_QUEUE_CAP = 20;
|
|
761
|
+
const DEFAULT_QUEUE_DROP = "summarize";
|
|
762
|
+
const FOLLOWUP_QUEUES = /* @__PURE__ */ new Map();
|
|
763
|
+
function getExistingFollowupQueue(key) {
|
|
764
|
+
const cleaned = key.trim();
|
|
765
|
+
if (!cleaned) return;
|
|
766
|
+
return FOLLOWUP_QUEUES.get(cleaned);
|
|
767
|
+
}
|
|
768
|
+
function getFollowupQueue(key, settings) {
|
|
769
|
+
const existing = FOLLOWUP_QUEUES.get(key);
|
|
770
|
+
if (existing) {
|
|
771
|
+
applyQueueRuntimeSettings({
|
|
772
|
+
target: existing,
|
|
773
|
+
settings
|
|
774
|
+
});
|
|
775
|
+
return existing;
|
|
776
|
+
}
|
|
777
|
+
const created = {
|
|
778
|
+
items: [],
|
|
779
|
+
draining: false,
|
|
780
|
+
lastEnqueuedAt: 0,
|
|
781
|
+
mode: settings.mode,
|
|
782
|
+
debounceMs: typeof settings.debounceMs === "number" ? Math.max(0, settings.debounceMs) : DEFAULT_QUEUE_DEBOUNCE_MS,
|
|
783
|
+
cap: typeof settings.cap === "number" && settings.cap > 0 ? Math.floor(settings.cap) : DEFAULT_QUEUE_CAP,
|
|
784
|
+
dropPolicy: settings.dropPolicy ?? DEFAULT_QUEUE_DROP,
|
|
785
|
+
droppedCount: 0,
|
|
786
|
+
summaryLines: []
|
|
787
|
+
};
|
|
788
|
+
applyQueueRuntimeSettings({
|
|
789
|
+
target: created,
|
|
790
|
+
settings
|
|
791
|
+
});
|
|
792
|
+
FOLLOWUP_QUEUES.set(key, created);
|
|
793
|
+
return created;
|
|
794
|
+
}
|
|
795
|
+
function clearFollowupQueue(key) {
|
|
796
|
+
const cleaned = key.trim();
|
|
797
|
+
const queue = getExistingFollowupQueue(cleaned);
|
|
798
|
+
if (!queue) return 0;
|
|
799
|
+
const cleared = queue.items.length + queue.droppedCount;
|
|
800
|
+
queue.items.length = 0;
|
|
801
|
+
queue.droppedCount = 0;
|
|
802
|
+
queue.summaryLines = [];
|
|
803
|
+
queue.lastRun = void 0;
|
|
804
|
+
queue.lastEnqueuedAt = 0;
|
|
805
|
+
FOLLOWUP_QUEUES.delete(cleaned);
|
|
806
|
+
return cleared;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region src/auto-reply/reply/queue/cleanup.ts
|
|
811
|
+
function clearSessionQueues(keys) {
|
|
812
|
+
const seen = /* @__PURE__ */ new Set();
|
|
813
|
+
let followupCleared = 0;
|
|
814
|
+
let laneCleared = 0;
|
|
815
|
+
const clearedKeys = [];
|
|
816
|
+
for (const key of keys) {
|
|
817
|
+
const cleaned = key?.trim();
|
|
818
|
+
if (!cleaned || seen.has(cleaned)) continue;
|
|
819
|
+
seen.add(cleaned);
|
|
820
|
+
clearedKeys.push(cleaned);
|
|
821
|
+
followupCleared += clearFollowupQueue(cleaned);
|
|
822
|
+
laneCleared += clearCommandLane("default");
|
|
823
|
+
}
|
|
824
|
+
return {
|
|
825
|
+
followupCleared,
|
|
826
|
+
laneCleared,
|
|
827
|
+
keys: clearedKeys
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
//#endregion
|
|
832
|
+
//#region src/line/flex-templates/common.ts
|
|
833
|
+
function attachFooterText(bubble, footer) {
|
|
834
|
+
bubble.footer = {
|
|
835
|
+
type: "box",
|
|
836
|
+
layout: "vertical",
|
|
837
|
+
contents: [{
|
|
838
|
+
type: "text",
|
|
839
|
+
text: footer,
|
|
840
|
+
size: "xs",
|
|
841
|
+
color: "#AAAAAA",
|
|
842
|
+
wrap: true,
|
|
843
|
+
align: "center"
|
|
844
|
+
}],
|
|
845
|
+
paddingAll: "lg",
|
|
846
|
+
backgroundColor: "#FAFAFA"
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/line/flex-templates/schedule-cards.ts
|
|
852
|
+
function buildTitleSubtitleHeader(params) {
|
|
853
|
+
const { title, subtitle } = params;
|
|
854
|
+
const headerContents = [{
|
|
855
|
+
type: "text",
|
|
856
|
+
text: title,
|
|
857
|
+
weight: "bold",
|
|
858
|
+
size: "xl",
|
|
859
|
+
color: "#111111",
|
|
860
|
+
wrap: true
|
|
861
|
+
}];
|
|
862
|
+
if (subtitle) headerContents.push({
|
|
863
|
+
type: "text",
|
|
864
|
+
text: subtitle,
|
|
865
|
+
size: "sm",
|
|
866
|
+
color: "#888888",
|
|
867
|
+
margin: "sm",
|
|
868
|
+
wrap: true
|
|
869
|
+
});
|
|
870
|
+
return headerContents;
|
|
871
|
+
}
|
|
872
|
+
function buildCardHeaderSections(headerContents) {
|
|
873
|
+
return [{
|
|
874
|
+
type: "box",
|
|
875
|
+
layout: "vertical",
|
|
876
|
+
contents: headerContents,
|
|
877
|
+
paddingBottom: "lg"
|
|
878
|
+
}, {
|
|
879
|
+
type: "separator",
|
|
880
|
+
color: "#EEEEEE"
|
|
881
|
+
}];
|
|
882
|
+
}
|
|
883
|
+
function createMegaBubbleWithFooter(params) {
|
|
884
|
+
const bubble = {
|
|
885
|
+
type: "bubble",
|
|
886
|
+
size: "mega",
|
|
887
|
+
body: {
|
|
888
|
+
type: "box",
|
|
889
|
+
layout: "vertical",
|
|
890
|
+
contents: params.bodyContents,
|
|
891
|
+
paddingAll: "xl",
|
|
892
|
+
backgroundColor: "#FFFFFF"
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
if (params.footer) attachFooterText(bubble, params.footer);
|
|
896
|
+
return bubble;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Create a receipt/summary card (for orders, transactions, data tables)
|
|
900
|
+
*
|
|
901
|
+
* Editorial design: Clean table layout with alternating row backgrounds,
|
|
902
|
+
* prominent total section, and clear visual hierarchy.
|
|
903
|
+
*/
|
|
904
|
+
function createReceiptCard(params) {
|
|
905
|
+
const { title, subtitle, items, total, footer } = params;
|
|
906
|
+
const itemRows = items.slice(0, 12).map((item, index) => ({
|
|
907
|
+
type: "box",
|
|
908
|
+
layout: "horizontal",
|
|
909
|
+
contents: [{
|
|
910
|
+
type: "text",
|
|
911
|
+
text: item.name,
|
|
912
|
+
size: "sm",
|
|
913
|
+
color: item.highlight ? "#111111" : "#666666",
|
|
914
|
+
weight: item.highlight ? "bold" : "regular",
|
|
915
|
+
flex: 3,
|
|
916
|
+
wrap: true
|
|
917
|
+
}, {
|
|
918
|
+
type: "text",
|
|
919
|
+
text: item.value,
|
|
920
|
+
size: "sm",
|
|
921
|
+
color: item.highlight ? "#06C755" : "#333333",
|
|
922
|
+
weight: item.highlight ? "bold" : "regular",
|
|
923
|
+
flex: 2,
|
|
924
|
+
align: "end",
|
|
925
|
+
wrap: true
|
|
926
|
+
}],
|
|
927
|
+
paddingAll: "md",
|
|
928
|
+
backgroundColor: index % 2 === 0 ? "#FFFFFF" : "#FAFAFA"
|
|
929
|
+
}));
|
|
930
|
+
const bodyContents = [...buildCardHeaderSections(buildTitleSubtitleHeader({
|
|
931
|
+
title,
|
|
932
|
+
subtitle
|
|
933
|
+
})), {
|
|
934
|
+
type: "box",
|
|
935
|
+
layout: "vertical",
|
|
936
|
+
contents: itemRows,
|
|
937
|
+
margin: "md",
|
|
938
|
+
cornerRadius: "md",
|
|
939
|
+
borderWidth: "light",
|
|
940
|
+
borderColor: "#EEEEEE"
|
|
941
|
+
}];
|
|
942
|
+
if (total) bodyContents.push({
|
|
943
|
+
type: "box",
|
|
944
|
+
layout: "horizontal",
|
|
945
|
+
contents: [{
|
|
946
|
+
type: "text",
|
|
947
|
+
text: total.label,
|
|
948
|
+
size: "lg",
|
|
949
|
+
weight: "bold",
|
|
950
|
+
color: "#111111",
|
|
951
|
+
flex: 2
|
|
952
|
+
}, {
|
|
953
|
+
type: "text",
|
|
954
|
+
text: total.value,
|
|
955
|
+
size: "xl",
|
|
956
|
+
weight: "bold",
|
|
957
|
+
color: "#06C755",
|
|
958
|
+
flex: 2,
|
|
959
|
+
align: "end"
|
|
960
|
+
}],
|
|
961
|
+
margin: "xl",
|
|
962
|
+
paddingAll: "lg",
|
|
963
|
+
backgroundColor: "#F0FDF4",
|
|
964
|
+
cornerRadius: "lg"
|
|
965
|
+
});
|
|
966
|
+
return createMegaBubbleWithFooter({
|
|
967
|
+
bodyContents,
|
|
968
|
+
footer
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Create a calendar event card (for meetings, appointments, reminders)
|
|
973
|
+
*
|
|
974
|
+
* Editorial design: Date as hero, strong typographic hierarchy,
|
|
975
|
+
* color-blocked zones, full text wrapping for readability.
|
|
976
|
+
*/
|
|
977
|
+
function createEventCard(params) {
|
|
978
|
+
const { title, date, time, location, description, calendar, isAllDay, action } = params;
|
|
979
|
+
const dateBlock = {
|
|
980
|
+
type: "box",
|
|
981
|
+
layout: "vertical",
|
|
982
|
+
contents: [{
|
|
983
|
+
type: "text",
|
|
984
|
+
text: date.toUpperCase(),
|
|
985
|
+
size: "sm",
|
|
986
|
+
weight: "bold",
|
|
987
|
+
color: "#06C755",
|
|
988
|
+
wrap: true
|
|
989
|
+
}, {
|
|
990
|
+
type: "text",
|
|
991
|
+
text: isAllDay ? "ALL DAY" : time ?? "",
|
|
992
|
+
size: "xxl",
|
|
993
|
+
weight: "bold",
|
|
994
|
+
color: "#111111",
|
|
995
|
+
wrap: true,
|
|
996
|
+
margin: "xs"
|
|
997
|
+
}],
|
|
998
|
+
paddingBottom: "lg",
|
|
999
|
+
borderWidth: "none"
|
|
1000
|
+
};
|
|
1001
|
+
if (!time && !isAllDay) dateBlock.contents = [{
|
|
1002
|
+
type: "text",
|
|
1003
|
+
text: date,
|
|
1004
|
+
size: "xl",
|
|
1005
|
+
weight: "bold",
|
|
1006
|
+
color: "#111111",
|
|
1007
|
+
wrap: true
|
|
1008
|
+
}];
|
|
1009
|
+
const bodyContents = [dateBlock, {
|
|
1010
|
+
type: "box",
|
|
1011
|
+
layout: "horizontal",
|
|
1012
|
+
contents: [{
|
|
1013
|
+
type: "box",
|
|
1014
|
+
layout: "vertical",
|
|
1015
|
+
contents: [],
|
|
1016
|
+
width: "4px",
|
|
1017
|
+
backgroundColor: "#06C755",
|
|
1018
|
+
cornerRadius: "2px"
|
|
1019
|
+
}, {
|
|
1020
|
+
type: "box",
|
|
1021
|
+
layout: "vertical",
|
|
1022
|
+
contents: [{
|
|
1023
|
+
type: "text",
|
|
1024
|
+
text: title,
|
|
1025
|
+
size: "lg",
|
|
1026
|
+
weight: "bold",
|
|
1027
|
+
color: "#1a1a1a",
|
|
1028
|
+
wrap: true
|
|
1029
|
+
}, ...calendar ? [{
|
|
1030
|
+
type: "text",
|
|
1031
|
+
text: calendar,
|
|
1032
|
+
size: "xs",
|
|
1033
|
+
color: "#888888",
|
|
1034
|
+
margin: "sm",
|
|
1035
|
+
wrap: true
|
|
1036
|
+
}] : []],
|
|
1037
|
+
flex: 1,
|
|
1038
|
+
paddingStart: "lg"
|
|
1039
|
+
}],
|
|
1040
|
+
paddingTop: "lg",
|
|
1041
|
+
paddingBottom: "lg",
|
|
1042
|
+
borderWidth: "light",
|
|
1043
|
+
borderColor: "#EEEEEE"
|
|
1044
|
+
}];
|
|
1045
|
+
if (location || description) {
|
|
1046
|
+
const detailItems = [];
|
|
1047
|
+
if (location) detailItems.push({
|
|
1048
|
+
type: "box",
|
|
1049
|
+
layout: "horizontal",
|
|
1050
|
+
contents: [{
|
|
1051
|
+
type: "text",
|
|
1052
|
+
text: "📍",
|
|
1053
|
+
size: "sm",
|
|
1054
|
+
flex: 0
|
|
1055
|
+
}, {
|
|
1056
|
+
type: "text",
|
|
1057
|
+
text: location,
|
|
1058
|
+
size: "sm",
|
|
1059
|
+
color: "#444444",
|
|
1060
|
+
margin: "md",
|
|
1061
|
+
flex: 1,
|
|
1062
|
+
wrap: true
|
|
1063
|
+
}],
|
|
1064
|
+
alignItems: "flex-start"
|
|
1065
|
+
});
|
|
1066
|
+
if (description) detailItems.push({
|
|
1067
|
+
type: "text",
|
|
1068
|
+
text: description,
|
|
1069
|
+
size: "sm",
|
|
1070
|
+
color: "#666666",
|
|
1071
|
+
wrap: true,
|
|
1072
|
+
margin: location ? "lg" : "none"
|
|
1073
|
+
});
|
|
1074
|
+
bodyContents.push({
|
|
1075
|
+
type: "box",
|
|
1076
|
+
layout: "vertical",
|
|
1077
|
+
contents: detailItems,
|
|
1078
|
+
margin: "lg",
|
|
1079
|
+
paddingAll: "lg",
|
|
1080
|
+
backgroundColor: "#F8F9FA",
|
|
1081
|
+
cornerRadius: "lg"
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
return {
|
|
1085
|
+
type: "bubble",
|
|
1086
|
+
size: "mega",
|
|
1087
|
+
body: {
|
|
1088
|
+
type: "box",
|
|
1089
|
+
layout: "vertical",
|
|
1090
|
+
contents: bodyContents,
|
|
1091
|
+
paddingAll: "xl",
|
|
1092
|
+
backgroundColor: "#FFFFFF",
|
|
1093
|
+
action
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Create a calendar agenda card showing multiple events
|
|
1099
|
+
*
|
|
1100
|
+
* Editorial timeline design: Time-focused left column with event details
|
|
1101
|
+
* on the right. Visual accent bars indicate event priority/recency.
|
|
1102
|
+
*/
|
|
1103
|
+
function createAgendaCard(params) {
|
|
1104
|
+
const { title, subtitle, events, footer } = params;
|
|
1105
|
+
const headerContents = buildTitleSubtitleHeader({
|
|
1106
|
+
title,
|
|
1107
|
+
subtitle
|
|
1108
|
+
});
|
|
1109
|
+
const eventItems = events.slice(0, 6).map((event, index) => {
|
|
1110
|
+
const isActive = event.isNow || index === 0;
|
|
1111
|
+
const accentColor = isActive ? "#06C755" : "#E5E5E5";
|
|
1112
|
+
const timeColumn = {
|
|
1113
|
+
type: "box",
|
|
1114
|
+
layout: "vertical",
|
|
1115
|
+
contents: [{
|
|
1116
|
+
type: "text",
|
|
1117
|
+
text: event.time ?? "—",
|
|
1118
|
+
size: "sm",
|
|
1119
|
+
weight: isActive ? "bold" : "regular",
|
|
1120
|
+
color: isActive ? "#06C755" : "#666666",
|
|
1121
|
+
align: "end",
|
|
1122
|
+
wrap: true
|
|
1123
|
+
}],
|
|
1124
|
+
width: "65px",
|
|
1125
|
+
justifyContent: "flex-start"
|
|
1126
|
+
};
|
|
1127
|
+
const dotColumn = {
|
|
1128
|
+
type: "box",
|
|
1129
|
+
layout: "vertical",
|
|
1130
|
+
contents: [{
|
|
1131
|
+
type: "box",
|
|
1132
|
+
layout: "vertical",
|
|
1133
|
+
contents: [],
|
|
1134
|
+
width: "10px",
|
|
1135
|
+
height: "10px",
|
|
1136
|
+
backgroundColor: accentColor,
|
|
1137
|
+
cornerRadius: "5px"
|
|
1138
|
+
}],
|
|
1139
|
+
width: "24px",
|
|
1140
|
+
alignItems: "center",
|
|
1141
|
+
justifyContent: "flex-start",
|
|
1142
|
+
paddingTop: "xs"
|
|
1143
|
+
};
|
|
1144
|
+
const detailContents = [{
|
|
1145
|
+
type: "text",
|
|
1146
|
+
text: event.title,
|
|
1147
|
+
size: "md",
|
|
1148
|
+
weight: "bold",
|
|
1149
|
+
color: "#1a1a1a",
|
|
1150
|
+
wrap: true
|
|
1151
|
+
}];
|
|
1152
|
+
const secondaryParts = [];
|
|
1153
|
+
if (event.location) secondaryParts.push(event.location);
|
|
1154
|
+
if (event.calendar) secondaryParts.push(event.calendar);
|
|
1155
|
+
if (secondaryParts.length > 0) detailContents.push({
|
|
1156
|
+
type: "text",
|
|
1157
|
+
text: secondaryParts.join(" · "),
|
|
1158
|
+
size: "xs",
|
|
1159
|
+
color: "#888888",
|
|
1160
|
+
wrap: true,
|
|
1161
|
+
margin: "xs"
|
|
1162
|
+
});
|
|
1163
|
+
return {
|
|
1164
|
+
type: "box",
|
|
1165
|
+
layout: "horizontal",
|
|
1166
|
+
contents: [
|
|
1167
|
+
timeColumn,
|
|
1168
|
+
dotColumn,
|
|
1169
|
+
{
|
|
1170
|
+
type: "box",
|
|
1171
|
+
layout: "vertical",
|
|
1172
|
+
contents: detailContents,
|
|
1173
|
+
flex: 1
|
|
1174
|
+
}
|
|
1175
|
+
],
|
|
1176
|
+
margin: index > 0 ? "xl" : void 0,
|
|
1177
|
+
alignItems: "flex-start"
|
|
1178
|
+
};
|
|
1179
|
+
});
|
|
1180
|
+
return createMegaBubbleWithFooter({
|
|
1181
|
+
bodyContents: [...buildCardHeaderSections(headerContents), {
|
|
1182
|
+
type: "box",
|
|
1183
|
+
layout: "vertical",
|
|
1184
|
+
contents: eventItems,
|
|
1185
|
+
paddingTop: "xl"
|
|
1186
|
+
}],
|
|
1187
|
+
footer
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
//#endregion
|
|
1192
|
+
//#region src/line/flex-templates/media-control-cards.ts
|
|
1193
|
+
/**
|
|
1194
|
+
* Create a media player card for Sonos, Spotify, Apple Music, etc.
|
|
1195
|
+
*
|
|
1196
|
+
* Editorial design: Album art hero with gradient overlay for text,
|
|
1197
|
+
* prominent now-playing indicator, refined playback controls.
|
|
1198
|
+
*/
|
|
1199
|
+
function createMediaPlayerCard(params) {
|
|
1200
|
+
const { title, subtitle, source, imageUrl, isPlaying, progress, controls, extraActions } = params;
|
|
1201
|
+
const trackInfo = [{
|
|
1202
|
+
type: "text",
|
|
1203
|
+
text: title,
|
|
1204
|
+
weight: "bold",
|
|
1205
|
+
size: "xl",
|
|
1206
|
+
color: "#111111",
|
|
1207
|
+
wrap: true
|
|
1208
|
+
}];
|
|
1209
|
+
if (subtitle) trackInfo.push({
|
|
1210
|
+
type: "text",
|
|
1211
|
+
text: subtitle,
|
|
1212
|
+
size: "md",
|
|
1213
|
+
color: "#666666",
|
|
1214
|
+
wrap: true,
|
|
1215
|
+
margin: "sm"
|
|
1216
|
+
});
|
|
1217
|
+
const statusItems = [];
|
|
1218
|
+
if (isPlaying !== void 0) statusItems.push({
|
|
1219
|
+
type: "box",
|
|
1220
|
+
layout: "horizontal",
|
|
1221
|
+
contents: [{
|
|
1222
|
+
type: "box",
|
|
1223
|
+
layout: "vertical",
|
|
1224
|
+
contents: [],
|
|
1225
|
+
width: "8px",
|
|
1226
|
+
height: "8px",
|
|
1227
|
+
backgroundColor: isPlaying ? "#06C755" : "#CCCCCC",
|
|
1228
|
+
cornerRadius: "4px"
|
|
1229
|
+
}, {
|
|
1230
|
+
type: "text",
|
|
1231
|
+
text: isPlaying ? "Now Playing" : "Paused",
|
|
1232
|
+
size: "xs",
|
|
1233
|
+
color: isPlaying ? "#06C755" : "#888888",
|
|
1234
|
+
weight: "bold",
|
|
1235
|
+
margin: "sm"
|
|
1236
|
+
}],
|
|
1237
|
+
alignItems: "center"
|
|
1238
|
+
});
|
|
1239
|
+
if (source) statusItems.push({
|
|
1240
|
+
type: "text",
|
|
1241
|
+
text: source,
|
|
1242
|
+
size: "xs",
|
|
1243
|
+
color: "#AAAAAA",
|
|
1244
|
+
margin: statusItems.length > 0 ? "lg" : void 0
|
|
1245
|
+
});
|
|
1246
|
+
if (progress) statusItems.push({
|
|
1247
|
+
type: "text",
|
|
1248
|
+
text: progress,
|
|
1249
|
+
size: "xs",
|
|
1250
|
+
color: "#888888",
|
|
1251
|
+
align: "end",
|
|
1252
|
+
flex: 1
|
|
1253
|
+
});
|
|
1254
|
+
const bodyContents = [{
|
|
1255
|
+
type: "box",
|
|
1256
|
+
layout: "vertical",
|
|
1257
|
+
contents: trackInfo
|
|
1258
|
+
}];
|
|
1259
|
+
if (statusItems.length > 0) bodyContents.push({
|
|
1260
|
+
type: "box",
|
|
1261
|
+
layout: "horizontal",
|
|
1262
|
+
contents: statusItems,
|
|
1263
|
+
margin: "lg",
|
|
1264
|
+
alignItems: "center"
|
|
1265
|
+
});
|
|
1266
|
+
const bubble = {
|
|
1267
|
+
type: "bubble",
|
|
1268
|
+
size: "mega",
|
|
1269
|
+
body: {
|
|
1270
|
+
type: "box",
|
|
1271
|
+
layout: "vertical",
|
|
1272
|
+
contents: bodyContents,
|
|
1273
|
+
paddingAll: "xl",
|
|
1274
|
+
backgroundColor: "#FFFFFF"
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
1277
|
+
if (imageUrl) bubble.hero = {
|
|
1278
|
+
type: "image",
|
|
1279
|
+
url: imageUrl,
|
|
1280
|
+
size: "full",
|
|
1281
|
+
aspectRatio: "1:1",
|
|
1282
|
+
aspectMode: "cover"
|
|
1283
|
+
};
|
|
1284
|
+
if (controls || extraActions?.length) {
|
|
1285
|
+
const footerContents = [];
|
|
1286
|
+
if (controls) {
|
|
1287
|
+
const controlButtons = [];
|
|
1288
|
+
if (controls.previous) controlButtons.push({
|
|
1289
|
+
type: "button",
|
|
1290
|
+
action: {
|
|
1291
|
+
type: "postback",
|
|
1292
|
+
label: "⏮",
|
|
1293
|
+
data: controls.previous.data
|
|
1294
|
+
},
|
|
1295
|
+
style: "secondary",
|
|
1296
|
+
flex: 1,
|
|
1297
|
+
height: "sm"
|
|
1298
|
+
});
|
|
1299
|
+
if (controls.play) controlButtons.push({
|
|
1300
|
+
type: "button",
|
|
1301
|
+
action: {
|
|
1302
|
+
type: "postback",
|
|
1303
|
+
label: "▶",
|
|
1304
|
+
data: controls.play.data
|
|
1305
|
+
},
|
|
1306
|
+
style: isPlaying ? "secondary" : "primary",
|
|
1307
|
+
flex: 1,
|
|
1308
|
+
height: "sm",
|
|
1309
|
+
margin: controls.previous ? "md" : void 0
|
|
1310
|
+
});
|
|
1311
|
+
if (controls.pause) controlButtons.push({
|
|
1312
|
+
type: "button",
|
|
1313
|
+
action: {
|
|
1314
|
+
type: "postback",
|
|
1315
|
+
label: "⏸",
|
|
1316
|
+
data: controls.pause.data
|
|
1317
|
+
},
|
|
1318
|
+
style: isPlaying ? "primary" : "secondary",
|
|
1319
|
+
flex: 1,
|
|
1320
|
+
height: "sm",
|
|
1321
|
+
margin: controlButtons.length > 0 ? "md" : void 0
|
|
1322
|
+
});
|
|
1323
|
+
if (controls.next) controlButtons.push({
|
|
1324
|
+
type: "button",
|
|
1325
|
+
action: {
|
|
1326
|
+
type: "postback",
|
|
1327
|
+
label: "⏭",
|
|
1328
|
+
data: controls.next.data
|
|
1329
|
+
},
|
|
1330
|
+
style: "secondary",
|
|
1331
|
+
flex: 1,
|
|
1332
|
+
height: "sm",
|
|
1333
|
+
margin: controlButtons.length > 0 ? "md" : void 0
|
|
1334
|
+
});
|
|
1335
|
+
if (controlButtons.length > 0) footerContents.push({
|
|
1336
|
+
type: "box",
|
|
1337
|
+
layout: "horizontal",
|
|
1338
|
+
contents: controlButtons
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
if (extraActions?.length) footerContents.push({
|
|
1342
|
+
type: "box",
|
|
1343
|
+
layout: "horizontal",
|
|
1344
|
+
contents: extraActions.slice(0, 2).map((action, index) => ({
|
|
1345
|
+
type: "button",
|
|
1346
|
+
action: {
|
|
1347
|
+
type: "postback",
|
|
1348
|
+
label: action.label.slice(0, 15),
|
|
1349
|
+
data: action.data
|
|
1350
|
+
},
|
|
1351
|
+
style: "secondary",
|
|
1352
|
+
flex: 1,
|
|
1353
|
+
height: "sm",
|
|
1354
|
+
margin: index > 0 ? "md" : void 0
|
|
1355
|
+
})),
|
|
1356
|
+
margin: "md"
|
|
1357
|
+
});
|
|
1358
|
+
if (footerContents.length > 0) bubble.footer = {
|
|
1359
|
+
type: "box",
|
|
1360
|
+
layout: "vertical",
|
|
1361
|
+
contents: footerContents,
|
|
1362
|
+
paddingAll: "lg",
|
|
1363
|
+
backgroundColor: "#FAFAFA"
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
return bubble;
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Create an Apple TV remote card with a D-pad and control rows.
|
|
1370
|
+
*/
|
|
1371
|
+
function createAppleTvRemoteCard(params) {
|
|
1372
|
+
const { deviceName, status, actionData } = params;
|
|
1373
|
+
const headerContents = [{
|
|
1374
|
+
type: "text",
|
|
1375
|
+
text: deviceName,
|
|
1376
|
+
weight: "bold",
|
|
1377
|
+
size: "xl",
|
|
1378
|
+
color: "#111111",
|
|
1379
|
+
wrap: true
|
|
1380
|
+
}];
|
|
1381
|
+
if (status) headerContents.push({
|
|
1382
|
+
type: "text",
|
|
1383
|
+
text: status,
|
|
1384
|
+
size: "sm",
|
|
1385
|
+
color: "#666666",
|
|
1386
|
+
wrap: true,
|
|
1387
|
+
margin: "sm"
|
|
1388
|
+
});
|
|
1389
|
+
const makeButton = (label, data, style = "secondary") => ({
|
|
1390
|
+
type: "button",
|
|
1391
|
+
action: {
|
|
1392
|
+
type: "postback",
|
|
1393
|
+
label,
|
|
1394
|
+
data
|
|
1395
|
+
},
|
|
1396
|
+
style,
|
|
1397
|
+
height: "sm",
|
|
1398
|
+
flex: 1
|
|
1399
|
+
});
|
|
1400
|
+
const dpadRows = [
|
|
1401
|
+
{
|
|
1402
|
+
type: "box",
|
|
1403
|
+
layout: "horizontal",
|
|
1404
|
+
contents: [
|
|
1405
|
+
{ type: "filler" },
|
|
1406
|
+
makeButton("↑", actionData.up),
|
|
1407
|
+
{ type: "filler" }
|
|
1408
|
+
]
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
type: "box",
|
|
1412
|
+
layout: "horizontal",
|
|
1413
|
+
contents: [
|
|
1414
|
+
makeButton("←", actionData.left),
|
|
1415
|
+
makeButton("OK", actionData.select, "primary"),
|
|
1416
|
+
makeButton("→", actionData.right)
|
|
1417
|
+
],
|
|
1418
|
+
margin: "md"
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
type: "box",
|
|
1422
|
+
layout: "horizontal",
|
|
1423
|
+
contents: [
|
|
1424
|
+
{ type: "filler" },
|
|
1425
|
+
makeButton("↓", actionData.down),
|
|
1426
|
+
{ type: "filler" }
|
|
1427
|
+
],
|
|
1428
|
+
margin: "md"
|
|
1429
|
+
}
|
|
1430
|
+
];
|
|
1431
|
+
const menuRow = {
|
|
1432
|
+
type: "box",
|
|
1433
|
+
layout: "horizontal",
|
|
1434
|
+
contents: [makeButton("Menu", actionData.menu), makeButton("Home", actionData.home)],
|
|
1435
|
+
margin: "lg"
|
|
1436
|
+
};
|
|
1437
|
+
const playbackRow = {
|
|
1438
|
+
type: "box",
|
|
1439
|
+
layout: "horizontal",
|
|
1440
|
+
contents: [makeButton("Play", actionData.play), makeButton("Pause", actionData.pause)],
|
|
1441
|
+
margin: "md"
|
|
1442
|
+
};
|
|
1443
|
+
const volumeRow = {
|
|
1444
|
+
type: "box",
|
|
1445
|
+
layout: "horizontal",
|
|
1446
|
+
contents: [
|
|
1447
|
+
makeButton("Vol +", actionData.volumeUp),
|
|
1448
|
+
makeButton("Mute", actionData.mute),
|
|
1449
|
+
makeButton("Vol -", actionData.volumeDown)
|
|
1450
|
+
],
|
|
1451
|
+
margin: "md"
|
|
1452
|
+
};
|
|
1453
|
+
return {
|
|
1454
|
+
type: "bubble",
|
|
1455
|
+
size: "mega",
|
|
1456
|
+
body: {
|
|
1457
|
+
type: "box",
|
|
1458
|
+
layout: "vertical",
|
|
1459
|
+
contents: [
|
|
1460
|
+
{
|
|
1461
|
+
type: "box",
|
|
1462
|
+
layout: "vertical",
|
|
1463
|
+
contents: headerContents
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
type: "separator",
|
|
1467
|
+
margin: "lg",
|
|
1468
|
+
color: "#EEEEEE"
|
|
1469
|
+
},
|
|
1470
|
+
...dpadRows,
|
|
1471
|
+
menuRow,
|
|
1472
|
+
playbackRow,
|
|
1473
|
+
volumeRow
|
|
1474
|
+
],
|
|
1475
|
+
paddingAll: "xl",
|
|
1476
|
+
backgroundColor: "#FFFFFF"
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Create a device control card for Apple TV, smart home devices, etc.
|
|
1482
|
+
*
|
|
1483
|
+
* Editorial design: Device-focused header with status indicator,
|
|
1484
|
+
* clean control grid with clear visual hierarchy.
|
|
1485
|
+
*/
|
|
1486
|
+
function createDeviceControlCard(params) {
|
|
1487
|
+
const { deviceName, deviceType, status, isOnline, imageUrl, controls } = params;
|
|
1488
|
+
const headerContents = [{
|
|
1489
|
+
type: "box",
|
|
1490
|
+
layout: "horizontal",
|
|
1491
|
+
contents: [{
|
|
1492
|
+
type: "box",
|
|
1493
|
+
layout: "vertical",
|
|
1494
|
+
contents: [],
|
|
1495
|
+
width: "10px",
|
|
1496
|
+
height: "10px",
|
|
1497
|
+
backgroundColor: isOnline !== false ? "#06C755" : "#FF5555",
|
|
1498
|
+
cornerRadius: "5px"
|
|
1499
|
+
}, {
|
|
1500
|
+
type: "text",
|
|
1501
|
+
text: deviceName,
|
|
1502
|
+
weight: "bold",
|
|
1503
|
+
size: "xl",
|
|
1504
|
+
color: "#111111",
|
|
1505
|
+
wrap: true,
|
|
1506
|
+
flex: 1,
|
|
1507
|
+
margin: "md"
|
|
1508
|
+
}],
|
|
1509
|
+
alignItems: "center"
|
|
1510
|
+
}];
|
|
1511
|
+
if (deviceType) headerContents.push({
|
|
1512
|
+
type: "text",
|
|
1513
|
+
text: deviceType,
|
|
1514
|
+
size: "sm",
|
|
1515
|
+
color: "#888888",
|
|
1516
|
+
margin: "sm"
|
|
1517
|
+
});
|
|
1518
|
+
if (status) headerContents.push({
|
|
1519
|
+
type: "box",
|
|
1520
|
+
layout: "vertical",
|
|
1521
|
+
contents: [{
|
|
1522
|
+
type: "text",
|
|
1523
|
+
text: status,
|
|
1524
|
+
size: "sm",
|
|
1525
|
+
color: "#444444",
|
|
1526
|
+
wrap: true
|
|
1527
|
+
}],
|
|
1528
|
+
margin: "lg",
|
|
1529
|
+
paddingAll: "md",
|
|
1530
|
+
backgroundColor: "#F8F9FA",
|
|
1531
|
+
cornerRadius: "md"
|
|
1532
|
+
});
|
|
1533
|
+
const bubble = {
|
|
1534
|
+
type: "bubble",
|
|
1535
|
+
size: "mega",
|
|
1536
|
+
body: {
|
|
1537
|
+
type: "box",
|
|
1538
|
+
layout: "vertical",
|
|
1539
|
+
contents: headerContents,
|
|
1540
|
+
paddingAll: "xl",
|
|
1541
|
+
backgroundColor: "#FFFFFF"
|
|
1542
|
+
}
|
|
1543
|
+
};
|
|
1544
|
+
if (imageUrl) bubble.hero = {
|
|
1545
|
+
type: "image",
|
|
1546
|
+
url: imageUrl,
|
|
1547
|
+
size: "full",
|
|
1548
|
+
aspectRatio: "16:9",
|
|
1549
|
+
aspectMode: "cover"
|
|
1550
|
+
};
|
|
1551
|
+
if (controls.length > 0) {
|
|
1552
|
+
const rows = [];
|
|
1553
|
+
const limitedControls = controls.slice(0, 6);
|
|
1554
|
+
for (let i = 0; i < limitedControls.length; i += 2) {
|
|
1555
|
+
const rowButtons = [];
|
|
1556
|
+
for (let j = i; j < Math.min(i + 2, limitedControls.length); j++) {
|
|
1557
|
+
const ctrl = limitedControls[j];
|
|
1558
|
+
const buttonLabel = ctrl.icon ? `${ctrl.icon} ${ctrl.label}` : ctrl.label;
|
|
1559
|
+
rowButtons.push({
|
|
1560
|
+
type: "button",
|
|
1561
|
+
action: {
|
|
1562
|
+
type: "postback",
|
|
1563
|
+
label: buttonLabel.slice(0, 18),
|
|
1564
|
+
data: ctrl.data
|
|
1565
|
+
},
|
|
1566
|
+
style: ctrl.style ?? "secondary",
|
|
1567
|
+
flex: 1,
|
|
1568
|
+
height: "sm",
|
|
1569
|
+
margin: j > i ? "md" : void 0
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
if (rowButtons.length === 1) rowButtons.push({ type: "filler" });
|
|
1573
|
+
rows.push({
|
|
1574
|
+
type: "box",
|
|
1575
|
+
layout: "horizontal",
|
|
1576
|
+
contents: rowButtons,
|
|
1577
|
+
margin: i > 0 ? "md" : void 0
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
bubble.footer = {
|
|
1581
|
+
type: "box",
|
|
1582
|
+
layout: "vertical",
|
|
1583
|
+
contents: rows,
|
|
1584
|
+
paddingAll: "lg",
|
|
1585
|
+
backgroundColor: "#FAFAFA"
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
return bubble;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
//#endregion
|
|
1592
|
+
//#region src/auto-reply/reply/line-directives.ts
|
|
1593
|
+
/**
|
|
1594
|
+
* Parse LINE-specific directives from text and extract them into ReplyPayload fields.
|
|
1595
|
+
*
|
|
1596
|
+
* Supported directives:
|
|
1597
|
+
* - [[quick_replies: option1, option2, option3]]
|
|
1598
|
+
* - [[location: title | address | latitude | longitude]]
|
|
1599
|
+
* - [[confirm: question | yes_label | no_label]]
|
|
1600
|
+
* - [[buttons: title | text | btn1:data1, btn2:data2]]
|
|
1601
|
+
* - [[media_player: title | artist | source | imageUrl | playing/paused]]
|
|
1602
|
+
* - [[event: title | date | time | location | description]]
|
|
1603
|
+
* - [[agenda: title | event1_title:event1_time, event2_title:event2_time, ...]]
|
|
1604
|
+
* - [[device: name | type | status | ctrl1:data1, ctrl2:data2]]
|
|
1605
|
+
* - [[appletv_remote: name | status]]
|
|
1606
|
+
*
|
|
1607
|
+
* Returns the modified payload with directives removed from text and fields populated.
|
|
1608
|
+
*/
|
|
1609
|
+
function parseLineDirectives(payload) {
|
|
1610
|
+
let text = payload.text;
|
|
1611
|
+
if (!text) return payload;
|
|
1612
|
+
const result = { ...payload };
|
|
1613
|
+
const lineData = { ...result.channelData?.line };
|
|
1614
|
+
const toSlug = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "device";
|
|
1615
|
+
const lineActionData = (action, extras) => {
|
|
1616
|
+
const base = [`line.action=${encodeURIComponent(action)}`];
|
|
1617
|
+
if (extras) for (const [key, value] of Object.entries(extras)) base.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
1618
|
+
return base.join("&");
|
|
1619
|
+
};
|
|
1620
|
+
const quickRepliesMatch = text.match(/\[\[quick_replies:\s*([^\]]+)\]\]/i);
|
|
1621
|
+
if (quickRepliesMatch) {
|
|
1622
|
+
const options = quickRepliesMatch[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
1623
|
+
if (options.length > 0) lineData.quickReplies = [...lineData.quickReplies || [], ...options];
|
|
1624
|
+
text = text.replace(quickRepliesMatch[0], "").trim();
|
|
1625
|
+
}
|
|
1626
|
+
const locationMatch = text.match(/\[\[location:\s*([^\]]+)\]\]/i);
|
|
1627
|
+
if (locationMatch && !lineData.location) {
|
|
1628
|
+
const parts = locationMatch[1].split("|").map((s) => s.trim());
|
|
1629
|
+
if (parts.length >= 4) {
|
|
1630
|
+
const [title, address, latStr, lonStr] = parts;
|
|
1631
|
+
const latitude = parseFloat(latStr);
|
|
1632
|
+
const longitude = parseFloat(lonStr);
|
|
1633
|
+
if (!isNaN(latitude) && !isNaN(longitude)) lineData.location = {
|
|
1634
|
+
title: title || "Location",
|
|
1635
|
+
address: address || "",
|
|
1636
|
+
latitude,
|
|
1637
|
+
longitude
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
text = text.replace(locationMatch[0], "").trim();
|
|
1641
|
+
}
|
|
1642
|
+
const confirmMatch = text.match(/\[\[confirm:\s*([^\]]+)\]\]/i);
|
|
1643
|
+
if (confirmMatch && !lineData.templateMessage) {
|
|
1644
|
+
const parts = confirmMatch[1].split("|").map((s) => s.trim());
|
|
1645
|
+
if (parts.length >= 3) {
|
|
1646
|
+
const [question, yesPart, noPart] = parts;
|
|
1647
|
+
const [yesLabel, yesData] = yesPart.includes(":") ? yesPart.split(":").map((s) => s.trim()) : [yesPart, yesPart.toLowerCase()];
|
|
1648
|
+
const [noLabel, noData] = noPart.includes(":") ? noPart.split(":").map((s) => s.trim()) : [noPart, noPart.toLowerCase()];
|
|
1649
|
+
lineData.templateMessage = {
|
|
1650
|
+
type: "confirm",
|
|
1651
|
+
text: question,
|
|
1652
|
+
confirmLabel: yesLabel,
|
|
1653
|
+
confirmData: yesData,
|
|
1654
|
+
cancelLabel: noLabel,
|
|
1655
|
+
cancelData: noData,
|
|
1656
|
+
altText: question
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
text = text.replace(confirmMatch[0], "").trim();
|
|
1660
|
+
}
|
|
1661
|
+
const buttonsMatch = text.match(/\[\[buttons:\s*([^\]]+)\]\]/i);
|
|
1662
|
+
if (buttonsMatch && !lineData.templateMessage) {
|
|
1663
|
+
const parts = buttonsMatch[1].split("|").map((s) => s.trim());
|
|
1664
|
+
if (parts.length >= 3) {
|
|
1665
|
+
const [title, bodyText, actionsStr] = parts;
|
|
1666
|
+
const actions = actionsStr.split(",").map((actionStr) => {
|
|
1667
|
+
const trimmed = actionStr.trim();
|
|
1668
|
+
const colonIndex = (() => {
|
|
1669
|
+
const index = trimmed.indexOf(":");
|
|
1670
|
+
if (index === -1) return -1;
|
|
1671
|
+
const lower = trimmed.toLowerCase();
|
|
1672
|
+
if (lower.startsWith("http://") || lower.startsWith("https://")) return -1;
|
|
1673
|
+
return index;
|
|
1674
|
+
})();
|
|
1675
|
+
let label;
|
|
1676
|
+
let data;
|
|
1677
|
+
if (colonIndex === -1) {
|
|
1678
|
+
label = trimmed;
|
|
1679
|
+
data = trimmed;
|
|
1680
|
+
} else {
|
|
1681
|
+
label = trimmed.slice(0, colonIndex).trim();
|
|
1682
|
+
data = trimmed.slice(colonIndex + 1).trim();
|
|
1683
|
+
}
|
|
1684
|
+
if (data.startsWith("http://") || data.startsWith("https://")) return {
|
|
1685
|
+
type: "uri",
|
|
1686
|
+
label,
|
|
1687
|
+
uri: data
|
|
1688
|
+
};
|
|
1689
|
+
if (data.includes("=")) return {
|
|
1690
|
+
type: "postback",
|
|
1691
|
+
label,
|
|
1692
|
+
data
|
|
1693
|
+
};
|
|
1694
|
+
return {
|
|
1695
|
+
type: "message",
|
|
1696
|
+
label,
|
|
1697
|
+
data: data || label
|
|
1698
|
+
};
|
|
1699
|
+
});
|
|
1700
|
+
if (actions.length > 0) lineData.templateMessage = {
|
|
1701
|
+
type: "buttons",
|
|
1702
|
+
title,
|
|
1703
|
+
text: bodyText,
|
|
1704
|
+
actions: actions.slice(0, 4),
|
|
1705
|
+
altText: `${title}: ${bodyText}`
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
text = text.replace(buttonsMatch[0], "").trim();
|
|
1709
|
+
}
|
|
1710
|
+
const mediaPlayerMatch = text.match(/\[\[media_player:\s*([^\]]+)\]\]/i);
|
|
1711
|
+
if (mediaPlayerMatch && !lineData.flexMessage) {
|
|
1712
|
+
const parts = mediaPlayerMatch[1].split("|").map((s) => s.trim());
|
|
1713
|
+
if (parts.length >= 1) {
|
|
1714
|
+
const [title, artist, source, imageUrl, statusStr] = parts;
|
|
1715
|
+
const isPlaying = statusStr?.toLowerCase() === "playing";
|
|
1716
|
+
const validImageUrl = imageUrl?.startsWith("https://") ? imageUrl : void 0;
|
|
1717
|
+
const deviceKey = toSlug(source || title || "media");
|
|
1718
|
+
const card = createMediaPlayerCard({
|
|
1719
|
+
title: title || "Unknown Track",
|
|
1720
|
+
subtitle: artist || void 0,
|
|
1721
|
+
source: source || void 0,
|
|
1722
|
+
imageUrl: validImageUrl,
|
|
1723
|
+
isPlaying: statusStr ? isPlaying : void 0,
|
|
1724
|
+
controls: {
|
|
1725
|
+
previous: { data: lineActionData("previous", { "line.device": deviceKey }) },
|
|
1726
|
+
play: { data: lineActionData("play", { "line.device": deviceKey }) },
|
|
1727
|
+
pause: { data: lineActionData("pause", { "line.device": deviceKey }) },
|
|
1728
|
+
next: { data: lineActionData("next", { "line.device": deviceKey }) }
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
lineData.flexMessage = {
|
|
1732
|
+
altText: `🎵 ${title}${artist ? ` - ${artist}` : ""}`,
|
|
1733
|
+
contents: card
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
text = text.replace(mediaPlayerMatch[0], "").trim();
|
|
1737
|
+
}
|
|
1738
|
+
const eventMatch = text.match(/\[\[event:\s*([^\]]+)\]\]/i);
|
|
1739
|
+
if (eventMatch && !lineData.flexMessage) {
|
|
1740
|
+
const parts = eventMatch[1].split("|").map((s) => s.trim());
|
|
1741
|
+
if (parts.length >= 2) {
|
|
1742
|
+
const [title, date, time, location, description] = parts;
|
|
1743
|
+
const card = createEventCard({
|
|
1744
|
+
title: title || "Event",
|
|
1745
|
+
date: date || "TBD",
|
|
1746
|
+
time: time || void 0,
|
|
1747
|
+
location: location || void 0,
|
|
1748
|
+
description: description || void 0
|
|
1749
|
+
});
|
|
1750
|
+
lineData.flexMessage = {
|
|
1751
|
+
altText: `📅 ${title} - ${date}${time ? ` ${time}` : ""}`,
|
|
1752
|
+
contents: card
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
text = text.replace(eventMatch[0], "").trim();
|
|
1756
|
+
}
|
|
1757
|
+
const appleTvMatch = text.match(/\[\[appletv_remote:\s*([^\]]+)\]\]/i);
|
|
1758
|
+
if (appleTvMatch && !lineData.flexMessage) {
|
|
1759
|
+
const parts = appleTvMatch[1].split("|").map((s) => s.trim());
|
|
1760
|
+
if (parts.length >= 1) {
|
|
1761
|
+
const [deviceName, status] = parts;
|
|
1762
|
+
const deviceKey = toSlug(deviceName || "apple_tv");
|
|
1763
|
+
const card = createAppleTvRemoteCard({
|
|
1764
|
+
deviceName: deviceName || "Apple TV",
|
|
1765
|
+
status: status || void 0,
|
|
1766
|
+
actionData: {
|
|
1767
|
+
up: lineActionData("up", { "line.device": deviceKey }),
|
|
1768
|
+
down: lineActionData("down", { "line.device": deviceKey }),
|
|
1769
|
+
left: lineActionData("left", { "line.device": deviceKey }),
|
|
1770
|
+
right: lineActionData("right", { "line.device": deviceKey }),
|
|
1771
|
+
select: lineActionData("select", { "line.device": deviceKey }),
|
|
1772
|
+
menu: lineActionData("menu", { "line.device": deviceKey }),
|
|
1773
|
+
home: lineActionData("home", { "line.device": deviceKey }),
|
|
1774
|
+
play: lineActionData("play", { "line.device": deviceKey }),
|
|
1775
|
+
pause: lineActionData("pause", { "line.device": deviceKey }),
|
|
1776
|
+
volumeUp: lineActionData("volume_up", { "line.device": deviceKey }),
|
|
1777
|
+
volumeDown: lineActionData("volume_down", { "line.device": deviceKey }),
|
|
1778
|
+
mute: lineActionData("mute", { "line.device": deviceKey })
|
|
1779
|
+
}
|
|
1780
|
+
});
|
|
1781
|
+
lineData.flexMessage = {
|
|
1782
|
+
altText: `📺 ${deviceName || "Apple TV"} Remote`,
|
|
1783
|
+
contents: card
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
text = text.replace(appleTvMatch[0], "").trim();
|
|
1787
|
+
}
|
|
1788
|
+
const agendaMatch = text.match(/\[\[agenda:\s*([^\]]+)\]\]/i);
|
|
1789
|
+
if (agendaMatch && !lineData.flexMessage) {
|
|
1790
|
+
const parts = agendaMatch[1].split("|").map((s) => s.trim());
|
|
1791
|
+
if (parts.length >= 2) {
|
|
1792
|
+
const [title, eventsStr] = parts;
|
|
1793
|
+
const events = eventsStr.split(",").map((eventStr) => {
|
|
1794
|
+
const trimmed = eventStr.trim();
|
|
1795
|
+
const colonIdx = trimmed.lastIndexOf(":");
|
|
1796
|
+
if (colonIdx > 0) return {
|
|
1797
|
+
title: trimmed.slice(0, colonIdx).trim(),
|
|
1798
|
+
time: trimmed.slice(colonIdx + 1).trim()
|
|
1799
|
+
};
|
|
1800
|
+
return { title: trimmed };
|
|
1801
|
+
});
|
|
1802
|
+
const card = createAgendaCard({
|
|
1803
|
+
title: title || "Agenda",
|
|
1804
|
+
events
|
|
1805
|
+
});
|
|
1806
|
+
lineData.flexMessage = {
|
|
1807
|
+
altText: `📋 ${title} (${events.length} events)`,
|
|
1808
|
+
contents: card
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
text = text.replace(agendaMatch[0], "").trim();
|
|
1812
|
+
}
|
|
1813
|
+
const deviceMatch = text.match(/\[\[device:\s*([^\]]+)\]\]/i);
|
|
1814
|
+
if (deviceMatch && !lineData.flexMessage) {
|
|
1815
|
+
const parts = deviceMatch[1].split("|").map((s) => s.trim());
|
|
1816
|
+
if (parts.length >= 1) {
|
|
1817
|
+
const [deviceName, deviceType, status, controlsStr] = parts;
|
|
1818
|
+
const deviceKey = toSlug(deviceName || "device");
|
|
1819
|
+
const controls = controlsStr ? controlsStr.split(",").map((ctrlStr) => {
|
|
1820
|
+
const [label, data] = ctrlStr.split(":").map((s) => s.trim());
|
|
1821
|
+
return {
|
|
1822
|
+
label,
|
|
1823
|
+
data: lineActionData(data || label.toLowerCase().replace(/\s+/g, "_"), { "line.device": deviceKey })
|
|
1824
|
+
};
|
|
1825
|
+
}) : [];
|
|
1826
|
+
const card = createDeviceControlCard({
|
|
1827
|
+
deviceName: deviceName || "Device",
|
|
1828
|
+
deviceType: deviceType || void 0,
|
|
1829
|
+
status: status || void 0,
|
|
1830
|
+
controls
|
|
1831
|
+
});
|
|
1832
|
+
lineData.flexMessage = {
|
|
1833
|
+
altText: `📱 ${deviceName}${status ? `: ${status}` : ""}`,
|
|
1834
|
+
contents: card
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
text = text.replace(deviceMatch[0], "").trim();
|
|
1838
|
+
}
|
|
1839
|
+
text = text.replace(/\n{3,}/g, "\n\n").trim();
|
|
1840
|
+
result.text = text || void 0;
|
|
1841
|
+
if (Object.keys(lineData).length > 0) result.channelData = {
|
|
1842
|
+
...result.channelData,
|
|
1843
|
+
line: lineData
|
|
1844
|
+
};
|
|
1845
|
+
return result;
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Check if text contains any LINE directives
|
|
1849
|
+
*/
|
|
1850
|
+
function hasLineDirectives(text) {
|
|
1851
|
+
return /\[\[(quick_replies|location|confirm|buttons|media_player|event|agenda|device|appletv_remote):/i.test(text);
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
//#endregion
|
|
1855
|
+
//#region src/auto-reply/reply/normalize-reply.ts
|
|
1856
|
+
function normalizeReplyPayload(payload, opts = {}) {
|
|
1857
|
+
const hasMedia = Boolean(payload.mediaUrl || (payload.mediaUrls?.length ?? 0) > 0);
|
|
1858
|
+
const hasChannelData = Boolean(payload.channelData && Object.keys(payload.channelData).length > 0);
|
|
1859
|
+
const trimmed = payload.text?.trim() ?? "";
|
|
1860
|
+
if (!trimmed && !hasMedia && !hasChannelData) {
|
|
1861
|
+
opts.onSkip?.("empty");
|
|
1862
|
+
return null;
|
|
1863
|
+
}
|
|
1864
|
+
const silentToken = opts.silentToken ?? SILENT_REPLY_TOKEN;
|
|
1865
|
+
let text = payload.text ?? void 0;
|
|
1866
|
+
if (text && isSilentReplyText(text, silentToken)) {
|
|
1867
|
+
if (!hasMedia && !hasChannelData) {
|
|
1868
|
+
opts.onSkip?.("silent");
|
|
1869
|
+
return null;
|
|
1870
|
+
}
|
|
1871
|
+
text = "";
|
|
1872
|
+
}
|
|
1873
|
+
if (text && !trimmed) text = "";
|
|
1874
|
+
if (text) text = sanitizeUserFacingText(text, { errorContext: Boolean(payload.isError) });
|
|
1875
|
+
if (!text?.trim() && !hasMedia && !hasChannelData) {
|
|
1876
|
+
opts.onSkip?.("empty");
|
|
1877
|
+
return null;
|
|
1878
|
+
}
|
|
1879
|
+
let enrichedPayload = {
|
|
1880
|
+
...payload,
|
|
1881
|
+
text
|
|
1882
|
+
};
|
|
1883
|
+
if (text && hasLineDirectives(text)) {
|
|
1884
|
+
enrichedPayload = parseLineDirectives(enrichedPayload);
|
|
1885
|
+
text = enrichedPayload.text;
|
|
1886
|
+
}
|
|
1887
|
+
const effectivePrefix = opts.responsePrefixContext ? resolveResponsePrefixTemplate(opts.responsePrefix, opts.responsePrefixContext) : opts.responsePrefix;
|
|
1888
|
+
if (effectivePrefix && text && !text.startsWith(effectivePrefix)) text = `${effectivePrefix} ${text}`;
|
|
1889
|
+
return {
|
|
1890
|
+
...enrichedPayload,
|
|
1891
|
+
text
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
//#endregion
|
|
1896
|
+
//#region src/auto-reply/reply/route-reply.ts
|
|
1897
|
+
/**
|
|
1898
|
+
* Provider-agnostic reply router.
|
|
1899
|
+
*
|
|
1900
|
+
* Routes replies to the originating channel based on OriginatingChannel/OriginatingTo
|
|
1901
|
+
* instead of using the session's lastChannel. This ensures replies go back to the
|
|
1902
|
+
* provider where the message originated, even when the main session is shared
|
|
1903
|
+
* across multiple providers.
|
|
1904
|
+
*/
|
|
1905
|
+
/**
|
|
1906
|
+
* Routes a reply payload to the specified channel.
|
|
1907
|
+
*
|
|
1908
|
+
* This function provides a unified interface for sending messages to any
|
|
1909
|
+
* supported provider. It's used by the followup queue to route replies
|
|
1910
|
+
* back to the originating channel when OriginatingChannel/OriginatingTo
|
|
1911
|
+
* are set.
|
|
1912
|
+
*/
|
|
1913
|
+
async function routeReply(params) {
|
|
1914
|
+
const { payload, channel, to, accountId, threadId, cfg, abortSignal } = params;
|
|
1915
|
+
if (shouldSuppressReasoningPayload(payload)) return { ok: true };
|
|
1916
|
+
const normalizedChannel = normalizeMessageChannel(channel);
|
|
1917
|
+
const resolvedAgentId = params.sessionKey ? resolveSessionAgentId({
|
|
1918
|
+
sessionKey: params.sessionKey,
|
|
1919
|
+
config: cfg
|
|
1920
|
+
}) : void 0;
|
|
1921
|
+
const normalized = normalizeReplyPayload(payload, { responsePrefix: params.sessionKey ? resolveEffectiveMessagesConfig(cfg, resolvedAgentId ?? resolveSessionAgentId({ config: cfg }), {
|
|
1922
|
+
channel: normalizedChannel,
|
|
1923
|
+
accountId
|
|
1924
|
+
}).responsePrefix : cfg.messages?.responsePrefix === "auto" ? void 0 : cfg.messages?.responsePrefix });
|
|
1925
|
+
if (!normalized) return { ok: true };
|
|
1926
|
+
let text = normalized.text ?? "";
|
|
1927
|
+
let mediaUrls = (normalized.mediaUrls?.filter(Boolean) ?? []).length ? normalized.mediaUrls?.filter(Boolean) : normalized.mediaUrl ? [normalized.mediaUrl] : [];
|
|
1928
|
+
const replyToId = normalized.replyToId;
|
|
1929
|
+
if (!text.trim() && mediaUrls.length === 0) return { ok: true };
|
|
1930
|
+
if (channel === INTERNAL_MESSAGE_CHANNEL) return {
|
|
1931
|
+
ok: false,
|
|
1932
|
+
error: "Webchat routing not supported for queued replies"
|
|
1933
|
+
};
|
|
1934
|
+
const channelId = normalizeChannelId$1(channel) ?? null;
|
|
1935
|
+
if (!channelId) return {
|
|
1936
|
+
ok: false,
|
|
1937
|
+
error: `Unknown channel: ${String(channel)}`
|
|
1938
|
+
};
|
|
1939
|
+
if (abortSignal?.aborted) return {
|
|
1940
|
+
ok: false,
|
|
1941
|
+
error: "Reply routing aborted"
|
|
1942
|
+
};
|
|
1943
|
+
const resolvedReplyToId = replyToId ?? (channelId === "slack" && threadId != null && threadId !== "" ? String(threadId) : void 0);
|
|
1944
|
+
const resolvedThreadId = channelId === "slack" ? null : threadId ?? null;
|
|
1945
|
+
try {
|
|
1946
|
+
const { deliverOutboundPayloads } = await import("./deliver-912khjLK.js").then((n) => n.n);
|
|
1947
|
+
return {
|
|
1948
|
+
ok: true,
|
|
1949
|
+
messageId: (await deliverOutboundPayloads({
|
|
1950
|
+
cfg,
|
|
1951
|
+
channel: channelId,
|
|
1952
|
+
to,
|
|
1953
|
+
accountId: accountId ?? void 0,
|
|
1954
|
+
payloads: [normalized],
|
|
1955
|
+
replyToId: resolvedReplyToId ?? null,
|
|
1956
|
+
threadId: resolvedThreadId,
|
|
1957
|
+
agentId: resolvedAgentId,
|
|
1958
|
+
abortSignal,
|
|
1959
|
+
mirror: params.mirror !== false && params.sessionKey ? {
|
|
1960
|
+
sessionKey: params.sessionKey,
|
|
1961
|
+
agentId: resolvedAgentId,
|
|
1962
|
+
text,
|
|
1963
|
+
mediaUrls
|
|
1964
|
+
} : void 0
|
|
1965
|
+
})).at(-1)?.messageId
|
|
1966
|
+
};
|
|
1967
|
+
} catch (err) {
|
|
1968
|
+
return {
|
|
1969
|
+
ok: false,
|
|
1970
|
+
error: `Failed to route reply to ${channel}: ${err instanceof Error ? err.message : String(err)}`
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Checks if a channel type is routable via routeReply.
|
|
1976
|
+
*
|
|
1977
|
+
* Some channels (webchat) require special handling and cannot be routed through
|
|
1978
|
+
* this generic interface.
|
|
1979
|
+
*/
|
|
1980
|
+
function isRoutableChannel(channel) {
|
|
1981
|
+
if (!channel || channel === INTERNAL_MESSAGE_CHANNEL) return false;
|
|
1982
|
+
return normalizeChannelId$1(channel) !== null;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
//#endregion
|
|
1986
|
+
//#region src/auto-reply/reply/queue/drain.ts
|
|
1987
|
+
function resolveOriginRoutingMetadata(items) {
|
|
1988
|
+
return {
|
|
1989
|
+
originatingChannel: items.find((item) => item.originatingChannel)?.originatingChannel,
|
|
1990
|
+
originatingTo: items.find((item) => item.originatingTo)?.originatingTo,
|
|
1991
|
+
originatingAccountId: items.find((item) => item.originatingAccountId)?.originatingAccountId,
|
|
1992
|
+
originatingThreadId: items.find((item) => item.originatingThreadId != null && item.originatingThreadId !== "")?.originatingThreadId
|
|
1993
|
+
};
|
|
1994
|
+
}
|
|
1995
|
+
function resolveCrossChannelKey(item) {
|
|
1996
|
+
const { originatingChannel: channel, originatingTo: to, originatingAccountId: accountId } = item;
|
|
1997
|
+
const threadId = item.originatingThreadId;
|
|
1998
|
+
if (!channel && !to && !accountId && (threadId == null || threadId === "")) return {};
|
|
1999
|
+
if (!isRoutableChannel(channel) || !to) return { cross: true };
|
|
2000
|
+
return { key: [
|
|
2001
|
+
channel,
|
|
2002
|
+
to,
|
|
2003
|
+
accountId || "",
|
|
2004
|
+
threadId != null && threadId !== "" ? String(threadId) : ""
|
|
2005
|
+
].join("|") };
|
|
2006
|
+
}
|
|
2007
|
+
function scheduleFollowupDrain(key, runFollowup) {
|
|
2008
|
+
const queue = beginQueueDrain(FOLLOWUP_QUEUES, key);
|
|
2009
|
+
if (!queue) return;
|
|
2010
|
+
(async () => {
|
|
2011
|
+
try {
|
|
2012
|
+
const collectState = { forceIndividualCollect: false };
|
|
2013
|
+
while (queue.items.length > 0 || queue.droppedCount > 0) {
|
|
2014
|
+
await waitForQueueDebounce(queue);
|
|
2015
|
+
if (queue.mode === "collect") {
|
|
2016
|
+
const collectDrainResult = await drainCollectQueueStep({
|
|
2017
|
+
collectState,
|
|
2018
|
+
isCrossChannel: hasCrossChannelItems(queue.items, resolveCrossChannelKey),
|
|
2019
|
+
items: queue.items,
|
|
2020
|
+
run: runFollowup
|
|
2021
|
+
});
|
|
2022
|
+
if (collectDrainResult === "empty") break;
|
|
2023
|
+
if (collectDrainResult === "drained") continue;
|
|
2024
|
+
const items = queue.items.slice();
|
|
2025
|
+
const summary = previewQueueSummaryPrompt({
|
|
2026
|
+
state: queue,
|
|
2027
|
+
noun: "message"
|
|
2028
|
+
});
|
|
2029
|
+
const run = items.at(-1)?.run ?? queue.lastRun;
|
|
2030
|
+
if (!run) break;
|
|
2031
|
+
const routing = resolveOriginRoutingMetadata(items);
|
|
2032
|
+
await runFollowup({
|
|
2033
|
+
prompt: buildCollectPrompt({
|
|
2034
|
+
title: "[Queued messages while agent was busy]",
|
|
2035
|
+
items,
|
|
2036
|
+
summary,
|
|
2037
|
+
renderItem: (item, idx) => `---\nQueued #${idx + 1}\n${item.prompt}`.trim()
|
|
2038
|
+
}),
|
|
2039
|
+
run,
|
|
2040
|
+
enqueuedAt: Date.now(),
|
|
2041
|
+
...routing
|
|
2042
|
+
});
|
|
2043
|
+
queue.items.splice(0, items.length);
|
|
2044
|
+
if (summary) clearQueueSummaryState(queue);
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
const summaryPrompt = previewQueueSummaryPrompt({
|
|
2048
|
+
state: queue,
|
|
2049
|
+
noun: "message"
|
|
2050
|
+
});
|
|
2051
|
+
if (summaryPrompt) {
|
|
2052
|
+
const run = queue.lastRun;
|
|
2053
|
+
if (!run) break;
|
|
2054
|
+
if (!await drainNextQueueItem(queue.items, async (item) => {
|
|
2055
|
+
await runFollowup({
|
|
2056
|
+
prompt: summaryPrompt,
|
|
2057
|
+
run,
|
|
2058
|
+
enqueuedAt: Date.now(),
|
|
2059
|
+
originatingChannel: item.originatingChannel,
|
|
2060
|
+
originatingTo: item.originatingTo,
|
|
2061
|
+
originatingAccountId: item.originatingAccountId,
|
|
2062
|
+
originatingThreadId: item.originatingThreadId
|
|
2063
|
+
});
|
|
2064
|
+
})) break;
|
|
2065
|
+
clearQueueSummaryState(queue);
|
|
2066
|
+
continue;
|
|
2067
|
+
}
|
|
2068
|
+
if (!await drainNextQueueItem(queue.items, runFollowup)) break;
|
|
2069
|
+
}
|
|
2070
|
+
} catch (err) {
|
|
2071
|
+
queue.lastEnqueuedAt = Date.now();
|
|
2072
|
+
defaultRuntime.error?.(`followup queue drain failed for ${key}: ${String(err)}`);
|
|
2073
|
+
} finally {
|
|
2074
|
+
queue.draining = false;
|
|
2075
|
+
if (queue.items.length === 0 && queue.droppedCount === 0) FOLLOWUP_QUEUES.delete(key);
|
|
2076
|
+
else scheduleFollowupDrain(key, runFollowup);
|
|
2077
|
+
}
|
|
2078
|
+
})();
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
//#endregion
|
|
2082
|
+
//#region src/auto-reply/reply/queue/enqueue.ts
|
|
2083
|
+
function isRunAlreadyQueued(run, items, allowPromptFallback = false) {
|
|
2084
|
+
const hasSameRouting = (item) => item.originatingChannel === run.originatingChannel && item.originatingTo === run.originatingTo && item.originatingAccountId === run.originatingAccountId && item.originatingThreadId === run.originatingThreadId;
|
|
2085
|
+
const messageId = run.messageId?.trim();
|
|
2086
|
+
if (messageId) return items.some((item) => item.messageId?.trim() === messageId && hasSameRouting(item));
|
|
2087
|
+
if (!allowPromptFallback) return false;
|
|
2088
|
+
return items.some((item) => item.prompt === run.prompt && hasSameRouting(item));
|
|
2089
|
+
}
|
|
2090
|
+
function enqueueFollowupRun(key, run, settings, dedupeMode = "message-id") {
|
|
2091
|
+
const queue = getFollowupQueue(key, settings);
|
|
2092
|
+
const dedupe = dedupeMode === "none" ? void 0 : (item, items) => isRunAlreadyQueued(item, items, dedupeMode === "prompt");
|
|
2093
|
+
if (shouldSkipQueueItem({
|
|
2094
|
+
item: run,
|
|
2095
|
+
items: queue.items,
|
|
2096
|
+
dedupe
|
|
2097
|
+
})) return false;
|
|
2098
|
+
queue.lastEnqueuedAt = Date.now();
|
|
2099
|
+
queue.lastRun = run.run;
|
|
2100
|
+
if (!applyQueueDropPolicy({
|
|
2101
|
+
queue,
|
|
2102
|
+
summarize: (item) => item.summaryLine?.trim() || item.prompt.trim()
|
|
2103
|
+
})) return false;
|
|
2104
|
+
queue.items.push(run);
|
|
2105
|
+
return true;
|
|
2106
|
+
}
|
|
2107
|
+
function getFollowupQueueDepth(key) {
|
|
2108
|
+
const queue = getExistingFollowupQueue(key);
|
|
2109
|
+
if (!queue) return 0;
|
|
2110
|
+
return queue.items.length;
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
//#endregion
|
|
2114
|
+
//#region src/auto-reply/reply/queue/settings.ts
|
|
2115
|
+
function defaultQueueModeForChannel(_channel) {
|
|
2116
|
+
return "collect";
|
|
2117
|
+
}
|
|
2118
|
+
/** Resolve per-channel debounce override from debounceMsByChannel map. */
|
|
2119
|
+
function resolveChannelDebounce(byChannel, channelKey) {
|
|
2120
|
+
if (!channelKey || !byChannel) return;
|
|
2121
|
+
const value = byChannel[channelKey];
|
|
2122
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : void 0;
|
|
2123
|
+
}
|
|
2124
|
+
function resolvePluginDebounce(channelKey) {
|
|
2125
|
+
if (!channelKey) return;
|
|
2126
|
+
const value = getChannelPlugin(channelKey)?.defaults?.queue?.debounceMs;
|
|
2127
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : void 0;
|
|
2128
|
+
}
|
|
2129
|
+
function resolveQueueSettings(params) {
|
|
2130
|
+
const channelKey = params.channel?.trim().toLowerCase();
|
|
2131
|
+
const queueCfg = params.cfg.messages?.queue;
|
|
2132
|
+
const providerModeRaw = channelKey && queueCfg?.byChannel ? queueCfg.byChannel[channelKey] : void 0;
|
|
2133
|
+
const resolvedMode = params.inlineMode ?? normalizeQueueMode(params.sessionEntry?.queueMode) ?? normalizeQueueMode(providerModeRaw) ?? normalizeQueueMode(queueCfg?.mode) ?? defaultQueueModeForChannel(channelKey);
|
|
2134
|
+
const debounceRaw = params.inlineOptions?.debounceMs ?? params.sessionEntry?.queueDebounceMs ?? resolveChannelDebounce(queueCfg?.debounceMsByChannel, channelKey) ?? resolvePluginDebounce(channelKey) ?? queueCfg?.debounceMs ?? DEFAULT_QUEUE_DEBOUNCE_MS;
|
|
2135
|
+
const capRaw = params.inlineOptions?.cap ?? params.sessionEntry?.queueCap ?? queueCfg?.cap ?? DEFAULT_QUEUE_CAP;
|
|
2136
|
+
const dropRaw = params.inlineOptions?.dropPolicy ?? params.sessionEntry?.queueDrop ?? normalizeQueueDropPolicy(queueCfg?.drop) ?? DEFAULT_QUEUE_DROP;
|
|
2137
|
+
return {
|
|
2138
|
+
mode: resolvedMode,
|
|
2139
|
+
debounceMs: typeof debounceRaw === "number" ? Math.max(0, debounceRaw) : void 0,
|
|
2140
|
+
cap: typeof capRaw === "number" ? Math.max(1, Math.floor(capRaw)) : void 0,
|
|
2141
|
+
dropPolicy: dropRaw
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2145
|
+
//#endregion
|
|
2146
|
+
//#region src/infra/outbound/session-binding-service.ts
|
|
2147
|
+
function normalizeConversationRef(ref) {
|
|
2148
|
+
return {
|
|
2149
|
+
channel: ref.channel.trim().toLowerCase(),
|
|
2150
|
+
accountId: normalizeAccountId(ref.accountId),
|
|
2151
|
+
conversationId: ref.conversationId.trim(),
|
|
2152
|
+
parentConversationId: ref.parentConversationId?.trim() || void 0
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
function toAdapterKey(params) {
|
|
2156
|
+
return `${params.channel.trim().toLowerCase()}:${normalizeAccountId(params.accountId)}`;
|
|
2157
|
+
}
|
|
2158
|
+
const ADAPTERS_BY_CHANNEL_ACCOUNT = /* @__PURE__ */ new Map();
|
|
2159
|
+
function registerSessionBindingAdapter(adapter) {
|
|
2160
|
+
const key = toAdapterKey({
|
|
2161
|
+
channel: adapter.channel,
|
|
2162
|
+
accountId: adapter.accountId
|
|
2163
|
+
});
|
|
2164
|
+
ADAPTERS_BY_CHANNEL_ACCOUNT.set(key, {
|
|
2165
|
+
...adapter,
|
|
2166
|
+
channel: adapter.channel.trim().toLowerCase(),
|
|
2167
|
+
accountId: normalizeAccountId(adapter.accountId)
|
|
2168
|
+
});
|
|
2169
|
+
}
|
|
2170
|
+
function unregisterSessionBindingAdapter(params) {
|
|
2171
|
+
ADAPTERS_BY_CHANNEL_ACCOUNT.delete(toAdapterKey(params));
|
|
2172
|
+
}
|
|
2173
|
+
function resolveAdapterForConversation(ref) {
|
|
2174
|
+
const normalized = normalizeConversationRef(ref);
|
|
2175
|
+
const key = toAdapterKey({
|
|
2176
|
+
channel: normalized.channel,
|
|
2177
|
+
accountId: normalized.accountId
|
|
2178
|
+
});
|
|
2179
|
+
return ADAPTERS_BY_CHANNEL_ACCOUNT.get(key) ?? null;
|
|
2180
|
+
}
|
|
2181
|
+
function dedupeBindings(records) {
|
|
2182
|
+
const byId = /* @__PURE__ */ new Map();
|
|
2183
|
+
for (const record of records) {
|
|
2184
|
+
if (!record?.bindingId) continue;
|
|
2185
|
+
byId.set(record.bindingId, record);
|
|
2186
|
+
}
|
|
2187
|
+
return [...byId.values()];
|
|
2188
|
+
}
|
|
2189
|
+
function createDefaultSessionBindingService() {
|
|
2190
|
+
return {
|
|
2191
|
+
bind: async (input) => {
|
|
2192
|
+
const normalizedConversation = normalizeConversationRef(input.conversation);
|
|
2193
|
+
const adapter = resolveAdapterForConversation(normalizedConversation);
|
|
2194
|
+
if (!adapter?.bind) throw new Error(`Session binding adapter unavailable for ${normalizedConversation.channel}:${normalizedConversation.accountId}`);
|
|
2195
|
+
const bound = await adapter.bind({
|
|
2196
|
+
...input,
|
|
2197
|
+
conversation: normalizedConversation
|
|
2198
|
+
});
|
|
2199
|
+
if (!bound) throw new Error("Session binding adapter failed to bind target conversation");
|
|
2200
|
+
return bound;
|
|
2201
|
+
},
|
|
2202
|
+
listBySession: (targetSessionKey) => {
|
|
2203
|
+
const key = targetSessionKey.trim();
|
|
2204
|
+
if (!key) return [];
|
|
2205
|
+
const results = [];
|
|
2206
|
+
for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) {
|
|
2207
|
+
const entries = adapter.listBySession(key);
|
|
2208
|
+
if (entries.length > 0) results.push(...entries);
|
|
2209
|
+
}
|
|
2210
|
+
return dedupeBindings(results);
|
|
2211
|
+
},
|
|
2212
|
+
resolveByConversation: (ref) => {
|
|
2213
|
+
const normalized = normalizeConversationRef(ref);
|
|
2214
|
+
if (!normalized.channel || !normalized.conversationId) return null;
|
|
2215
|
+
const adapter = resolveAdapterForConversation(normalized);
|
|
2216
|
+
if (!adapter) return null;
|
|
2217
|
+
return adapter.resolveByConversation(normalized);
|
|
2218
|
+
},
|
|
2219
|
+
touch: (bindingId, at) => {
|
|
2220
|
+
const normalizedBindingId = bindingId.trim();
|
|
2221
|
+
if (!normalizedBindingId) return;
|
|
2222
|
+
for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) adapter.touch?.(normalizedBindingId, at);
|
|
2223
|
+
},
|
|
2224
|
+
unbind: async (input) => {
|
|
2225
|
+
const removed = [];
|
|
2226
|
+
for (const adapter of ADAPTERS_BY_CHANNEL_ACCOUNT.values()) {
|
|
2227
|
+
if (!adapter.unbind) continue;
|
|
2228
|
+
const entries = await adapter.unbind(input);
|
|
2229
|
+
if (entries.length > 0) removed.push(...entries);
|
|
2230
|
+
}
|
|
2231
|
+
return dedupeBindings(removed);
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
const DEFAULT_SESSION_BINDING_SERVICE = createDefaultSessionBindingService();
|
|
2236
|
+
function getSessionBindingService() {
|
|
2237
|
+
return DEFAULT_SESSION_BINDING_SERVICE;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
//#endregion
|
|
2241
|
+
//#region src/infra/outbound/bound-delivery-router.ts
|
|
2242
|
+
function isActiveBinding(record) {
|
|
2243
|
+
return record.status === "active";
|
|
2244
|
+
}
|
|
2245
|
+
function resolveBindingForRequester(requester, bindings) {
|
|
2246
|
+
const matchingChannelAccount = bindings.filter((entry) => entry.conversation.channel === requester.channel && entry.conversation.accountId === requester.accountId);
|
|
2247
|
+
if (matchingChannelAccount.length === 0) return null;
|
|
2248
|
+
const exactConversation = matchingChannelAccount.find((entry) => entry.conversation.conversationId === requester.conversationId);
|
|
2249
|
+
if (exactConversation) return exactConversation;
|
|
2250
|
+
if (matchingChannelAccount.length === 1) return matchingChannelAccount[0] ?? null;
|
|
2251
|
+
return null;
|
|
2252
|
+
}
|
|
2253
|
+
function createBoundDeliveryRouter(service = getSessionBindingService()) {
|
|
2254
|
+
return { resolveDestination: (input) => {
|
|
2255
|
+
const targetSessionKey = input.targetSessionKey.trim();
|
|
2256
|
+
if (!targetSessionKey) return {
|
|
2257
|
+
binding: null,
|
|
2258
|
+
mode: "fallback",
|
|
2259
|
+
reason: "missing-target-session"
|
|
2260
|
+
};
|
|
2261
|
+
const activeBindings = service.listBySession(targetSessionKey).filter(isActiveBinding);
|
|
2262
|
+
if (activeBindings.length === 0) return {
|
|
2263
|
+
binding: null,
|
|
2264
|
+
mode: "fallback",
|
|
2265
|
+
reason: "no-active-binding"
|
|
2266
|
+
};
|
|
2267
|
+
if (!input.requester) {
|
|
2268
|
+
if (activeBindings.length === 1) return {
|
|
2269
|
+
binding: activeBindings[0] ?? null,
|
|
2270
|
+
mode: "bound",
|
|
2271
|
+
reason: "single-active-binding"
|
|
2272
|
+
};
|
|
2273
|
+
return {
|
|
2274
|
+
binding: null,
|
|
2275
|
+
mode: "fallback",
|
|
2276
|
+
reason: "ambiguous-without-requester"
|
|
2277
|
+
};
|
|
2278
|
+
}
|
|
2279
|
+
const requester = {
|
|
2280
|
+
channel: input.requester.channel.trim().toLowerCase(),
|
|
2281
|
+
accountId: input.requester.accountId.trim(),
|
|
2282
|
+
conversationId: input.requester.conversationId.trim(),
|
|
2283
|
+
parentConversationId: input.requester.parentConversationId?.trim() || void 0
|
|
2284
|
+
};
|
|
2285
|
+
if (!requester.channel || !requester.conversationId) return {
|
|
2286
|
+
binding: null,
|
|
2287
|
+
mode: "fallback",
|
|
2288
|
+
reason: "invalid-requester"
|
|
2289
|
+
};
|
|
2290
|
+
const fromRequester = resolveBindingForRequester(requester, activeBindings);
|
|
2291
|
+
if (fromRequester) return {
|
|
2292
|
+
binding: fromRequester,
|
|
2293
|
+
mode: "bound",
|
|
2294
|
+
reason: "requester-match"
|
|
2295
|
+
};
|
|
2296
|
+
if (activeBindings.length === 1 && !input.failClosed) return {
|
|
2297
|
+
binding: activeBindings[0] ?? null,
|
|
2298
|
+
mode: "bound",
|
|
2299
|
+
reason: "single-active-binding-fallback"
|
|
2300
|
+
};
|
|
2301
|
+
return {
|
|
2302
|
+
binding: null,
|
|
2303
|
+
mode: "fallback",
|
|
2304
|
+
reason: "no-requester-match"
|
|
2305
|
+
};
|
|
2306
|
+
} };
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
//#endregion
|
|
2310
|
+
//#region src/shared/chat-content.ts
|
|
2311
|
+
function extractTextFromChatContent(content, opts) {
|
|
2312
|
+
const normalize = opts?.normalizeText ?? ((text) => text.replace(/\s+/g, " ").trim());
|
|
2313
|
+
const joinWith = opts?.joinWith ?? " ";
|
|
2314
|
+
if (typeof content === "string") {
|
|
2315
|
+
const normalized = normalize(opts?.sanitizeText ? opts.sanitizeText(content) : content);
|
|
2316
|
+
return normalized ? normalized : null;
|
|
2317
|
+
}
|
|
2318
|
+
if (!Array.isArray(content)) return null;
|
|
2319
|
+
const chunks = [];
|
|
2320
|
+
for (const block of content) {
|
|
2321
|
+
if (!block || typeof block !== "object") continue;
|
|
2322
|
+
if (block.type !== "text") continue;
|
|
2323
|
+
const text = block.text;
|
|
2324
|
+
if (typeof text !== "string") continue;
|
|
2325
|
+
const value = opts?.sanitizeText ? opts.sanitizeText(text) : text;
|
|
2326
|
+
if (value.trim()) chunks.push(value);
|
|
2327
|
+
}
|
|
2328
|
+
const joined = normalize(chunks.join(joinWith));
|
|
2329
|
+
return joined ? joined : null;
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
//#endregion
|
|
2333
|
+
//#region src/agents/announce-idempotency.ts
|
|
2334
|
+
function buildAnnounceIdFromChildRun(params) {
|
|
2335
|
+
return `v1:${params.childSessionKey}:${params.childRunId}`;
|
|
2336
|
+
}
|
|
2337
|
+
function buildAnnounceIdempotencyKey(announceId) {
|
|
2338
|
+
return `announce:${announceId}`;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
//#endregion
|
|
2342
|
+
//#region src/agents/subagent-depth.ts
|
|
2343
|
+
function normalizeSpawnDepth(value) {
|
|
2344
|
+
if (typeof value === "number") return Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
2345
|
+
if (typeof value === "string") {
|
|
2346
|
+
const trimmed = value.trim();
|
|
2347
|
+
if (!trimmed) return;
|
|
2348
|
+
const numeric = Number(trimmed);
|
|
2349
|
+
return Number.isInteger(numeric) && numeric >= 0 ? numeric : void 0;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
function normalizeSessionKey(value) {
|
|
2353
|
+
if (typeof value !== "string") return;
|
|
2354
|
+
return value.trim() || void 0;
|
|
2355
|
+
}
|
|
2356
|
+
function readSessionStore(storePath) {
|
|
2357
|
+
try {
|
|
2358
|
+
const raw = fs.readFileSync(storePath, "utf-8");
|
|
2359
|
+
const parsed = JSON5.parse(raw);
|
|
2360
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
2361
|
+
} catch {}
|
|
2362
|
+
return {};
|
|
2363
|
+
}
|
|
2364
|
+
function buildKeyCandidates(rawKey, cfg) {
|
|
2365
|
+
if (!cfg) return [rawKey];
|
|
2366
|
+
if (rawKey === "global" || rawKey === "unknown") return [rawKey];
|
|
2367
|
+
if (parseAgentSessionKey(rawKey)) return [rawKey];
|
|
2368
|
+
const prefixed = `agent:${resolveDefaultAgentId(cfg)}:${rawKey}`;
|
|
2369
|
+
return prefixed === rawKey ? [rawKey] : [rawKey, prefixed];
|
|
2370
|
+
}
|
|
2371
|
+
function findEntryBySessionId(store, sessionId) {
|
|
2372
|
+
const normalizedSessionId = normalizeSessionKey(sessionId);
|
|
2373
|
+
if (!normalizedSessionId) return;
|
|
2374
|
+
for (const entry of Object.values(store)) {
|
|
2375
|
+
const candidateSessionId = normalizeSessionKey(entry?.sessionId);
|
|
2376
|
+
if (candidateSessionId && candidateSessionId === normalizedSessionId) return entry;
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
function resolveEntryForSessionKey(params) {
|
|
2380
|
+
const candidates = buildKeyCandidates(params.sessionKey, params.cfg);
|
|
2381
|
+
if (params.store) {
|
|
2382
|
+
for (const key of candidates) {
|
|
2383
|
+
const entry = params.store[key];
|
|
2384
|
+
if (entry) return entry;
|
|
2385
|
+
}
|
|
2386
|
+
return findEntryBySessionId(params.store, params.sessionKey);
|
|
2387
|
+
}
|
|
2388
|
+
if (!params.cfg) return;
|
|
2389
|
+
for (const key of candidates) {
|
|
2390
|
+
const parsed = parseAgentSessionKey(key);
|
|
2391
|
+
if (!parsed?.agentId) continue;
|
|
2392
|
+
const storePath = resolveStorePath(params.cfg.session?.store, { agentId: parsed.agentId });
|
|
2393
|
+
let store = params.cache.get(storePath);
|
|
2394
|
+
if (!store) {
|
|
2395
|
+
store = readSessionStore(storePath);
|
|
2396
|
+
params.cache.set(storePath, store);
|
|
2397
|
+
}
|
|
2398
|
+
const entry = store[key] ?? findEntryBySessionId(store, params.sessionKey);
|
|
2399
|
+
if (entry) return entry;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
function getSubagentDepthFromSessionStore(sessionKey, opts) {
|
|
2403
|
+
const raw = (sessionKey ?? "").trim();
|
|
2404
|
+
const fallbackDepth = getSubagentDepth(raw);
|
|
2405
|
+
if (!raw) return fallbackDepth;
|
|
2406
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2407
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2408
|
+
const depthFromStore = (key) => {
|
|
2409
|
+
const normalizedKey = normalizeSessionKey(key);
|
|
2410
|
+
if (!normalizedKey) return;
|
|
2411
|
+
if (visited.has(normalizedKey)) return;
|
|
2412
|
+
visited.add(normalizedKey);
|
|
2413
|
+
const entry = resolveEntryForSessionKey({
|
|
2414
|
+
sessionKey: normalizedKey,
|
|
2415
|
+
cfg: opts?.cfg,
|
|
2416
|
+
store: opts?.store,
|
|
2417
|
+
cache
|
|
2418
|
+
});
|
|
2419
|
+
const storedDepth = normalizeSpawnDepth(entry?.spawnDepth);
|
|
2420
|
+
if (storedDepth !== void 0) return storedDepth;
|
|
2421
|
+
const spawnedBy = normalizeSessionKey(entry?.spawnedBy);
|
|
2422
|
+
if (!spawnedBy) return;
|
|
2423
|
+
const parentDepth = depthFromStore(spawnedBy);
|
|
2424
|
+
if (parentDepth !== void 0) return parentDepth + 1;
|
|
2425
|
+
return getSubagentDepth(spawnedBy) + 1;
|
|
2426
|
+
};
|
|
2427
|
+
return depthFromStore(raw) ?? fallbackDepth;
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
//#endregion
|
|
2431
|
+
//#region src/agents/tools/sessions-resolution.ts
|
|
2432
|
+
function resolveMainSessionAlias(cfg) {
|
|
2433
|
+
const mainKey = normalizeMainKey(cfg.session?.mainKey);
|
|
2434
|
+
const scope = cfg.session?.scope ?? "per-sender";
|
|
2435
|
+
return {
|
|
2436
|
+
mainKey,
|
|
2437
|
+
alias: scope === "global" ? "global" : mainKey,
|
|
2438
|
+
scope
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
function resolveDisplaySessionKey(params) {
|
|
2442
|
+
if (params.key === params.alias) return "main";
|
|
2443
|
+
if (params.key === params.mainKey) return "main";
|
|
2444
|
+
return params.key;
|
|
2445
|
+
}
|
|
2446
|
+
function resolveInternalSessionKey(params) {
|
|
2447
|
+
if (params.key === "main") return params.alias;
|
|
2448
|
+
return params.key;
|
|
2449
|
+
}
|
|
2450
|
+
async function listSpawnedSessionKeys(params) {
|
|
2451
|
+
const limit = typeof params.limit === "number" && Number.isFinite(params.limit) ? Math.max(1, Math.floor(params.limit)) : 500;
|
|
2452
|
+
try {
|
|
2453
|
+
const list = await callGateway({
|
|
2454
|
+
method: "sessions.list",
|
|
2455
|
+
params: {
|
|
2456
|
+
includeGlobal: false,
|
|
2457
|
+
includeUnknown: false,
|
|
2458
|
+
limit,
|
|
2459
|
+
spawnedBy: params.requesterSessionKey
|
|
2460
|
+
}
|
|
2461
|
+
});
|
|
2462
|
+
const keys = (Array.isArray(list?.sessions) ? list.sessions : []).map((entry) => typeof entry?.key === "string" ? entry.key : "").map((value) => value.trim()).filter(Boolean);
|
|
2463
|
+
return new Set(keys);
|
|
2464
|
+
} catch {
|
|
2465
|
+
return /* @__PURE__ */ new Set();
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
async function isRequesterSpawnedSessionVisible(params) {
|
|
2469
|
+
if (params.requesterSessionKey === params.targetSessionKey) return true;
|
|
2470
|
+
return (await listSpawnedSessionKeys({
|
|
2471
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
2472
|
+
limit: params.limit
|
|
2473
|
+
})).has(params.targetSessionKey);
|
|
2474
|
+
}
|
|
2475
|
+
function shouldVerifyRequesterSpawnedSessionVisibility(params) {
|
|
2476
|
+
return params.restrictToSpawned && !params.resolvedViaSessionId && params.requesterSessionKey !== params.targetSessionKey;
|
|
2477
|
+
}
|
|
2478
|
+
async function isResolvedSessionVisibleToRequester(params) {
|
|
2479
|
+
if (!shouldVerifyRequesterSpawnedSessionVisibility({
|
|
2480
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
2481
|
+
targetSessionKey: params.targetSessionKey,
|
|
2482
|
+
restrictToSpawned: params.restrictToSpawned,
|
|
2483
|
+
resolvedViaSessionId: params.resolvedViaSessionId
|
|
2484
|
+
})) return true;
|
|
2485
|
+
return await isRequesterSpawnedSessionVisible({
|
|
2486
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
2487
|
+
targetSessionKey: params.targetSessionKey,
|
|
2488
|
+
limit: params.limit
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
const SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2492
|
+
function looksLikeSessionId(value) {
|
|
2493
|
+
return SESSION_ID_RE.test(value.trim());
|
|
2494
|
+
}
|
|
2495
|
+
function looksLikeSessionKey(value) {
|
|
2496
|
+
const raw = value.trim();
|
|
2497
|
+
if (!raw) return false;
|
|
2498
|
+
if (raw === "main" || raw === "global" || raw === "unknown") return true;
|
|
2499
|
+
if (isAcpSessionKey(raw)) return true;
|
|
2500
|
+
if (raw.startsWith("agent:")) return true;
|
|
2501
|
+
if (raw.startsWith("cron:") || raw.startsWith("hook:")) return true;
|
|
2502
|
+
if (raw.startsWith("node-") || raw.startsWith("node:")) return true;
|
|
2503
|
+
if (raw.includes(":group:") || raw.includes(":channel:")) return true;
|
|
2504
|
+
return false;
|
|
2505
|
+
}
|
|
2506
|
+
function shouldResolveSessionIdInput(value) {
|
|
2507
|
+
return looksLikeSessionId(value) || !looksLikeSessionKey(value);
|
|
2508
|
+
}
|
|
2509
|
+
async function resolveSessionKeyFromSessionId(params) {
|
|
2510
|
+
try {
|
|
2511
|
+
const result = await callGateway({
|
|
2512
|
+
method: "sessions.resolve",
|
|
2513
|
+
params: {
|
|
2514
|
+
sessionId: params.sessionId,
|
|
2515
|
+
spawnedBy: params.restrictToSpawned ? params.requesterInternalKey : void 0,
|
|
2516
|
+
includeGlobal: !params.restrictToSpawned,
|
|
2517
|
+
includeUnknown: !params.restrictToSpawned
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
2520
|
+
const key = typeof result?.key === "string" ? result.key.trim() : "";
|
|
2521
|
+
if (!key) throw new Error(`Session not found: ${params.sessionId} (use the full sessionKey from sessions_list)`);
|
|
2522
|
+
return {
|
|
2523
|
+
ok: true,
|
|
2524
|
+
key,
|
|
2525
|
+
displayKey: resolveDisplaySessionKey({
|
|
2526
|
+
key,
|
|
2527
|
+
alias: params.alias,
|
|
2528
|
+
mainKey: params.mainKey
|
|
2529
|
+
}),
|
|
2530
|
+
resolvedViaSessionId: true
|
|
2531
|
+
};
|
|
2532
|
+
} catch (err) {
|
|
2533
|
+
if (params.restrictToSpawned) return {
|
|
2534
|
+
ok: false,
|
|
2535
|
+
status: "forbidden",
|
|
2536
|
+
error: `Session not visible from this sandboxed agent session: ${params.sessionId}`
|
|
2537
|
+
};
|
|
2538
|
+
return {
|
|
2539
|
+
ok: false,
|
|
2540
|
+
status: "error",
|
|
2541
|
+
error: (err instanceof Error ? err.message : String(err)) || `Session not found: ${params.sessionId} (use the full sessionKey from sessions_list)`
|
|
2542
|
+
};
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
async function resolveSessionKeyFromKey(params) {
|
|
2546
|
+
try {
|
|
2547
|
+
const result = await callGateway({
|
|
2548
|
+
method: "sessions.resolve",
|
|
2549
|
+
params: {
|
|
2550
|
+
key: params.key,
|
|
2551
|
+
spawnedBy: params.restrictToSpawned ? params.requesterInternalKey : void 0
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2554
|
+
const key = typeof result?.key === "string" ? result.key.trim() : "";
|
|
2555
|
+
if (!key) return null;
|
|
2556
|
+
return {
|
|
2557
|
+
ok: true,
|
|
2558
|
+
key,
|
|
2559
|
+
displayKey: resolveDisplaySessionKey({
|
|
2560
|
+
key,
|
|
2561
|
+
alias: params.alias,
|
|
2562
|
+
mainKey: params.mainKey
|
|
2563
|
+
}),
|
|
2564
|
+
resolvedViaSessionId: false
|
|
2565
|
+
};
|
|
2566
|
+
} catch {
|
|
2567
|
+
return null;
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
async function resolveSessionReference(params) {
|
|
2571
|
+
const raw = params.sessionKey.trim();
|
|
2572
|
+
if (shouldResolveSessionIdInput(raw)) {
|
|
2573
|
+
const resolvedByKey = await resolveSessionKeyFromKey({
|
|
2574
|
+
key: raw,
|
|
2575
|
+
alias: params.alias,
|
|
2576
|
+
mainKey: params.mainKey,
|
|
2577
|
+
requesterInternalKey: params.requesterInternalKey,
|
|
2578
|
+
restrictToSpawned: params.restrictToSpawned
|
|
2579
|
+
});
|
|
2580
|
+
if (resolvedByKey) return resolvedByKey;
|
|
2581
|
+
return await resolveSessionKeyFromSessionId({
|
|
2582
|
+
sessionId: raw,
|
|
2583
|
+
alias: params.alias,
|
|
2584
|
+
mainKey: params.mainKey,
|
|
2585
|
+
requesterInternalKey: params.requesterInternalKey,
|
|
2586
|
+
restrictToSpawned: params.restrictToSpawned
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
const resolvedKey = resolveInternalSessionKey({
|
|
2590
|
+
key: raw,
|
|
2591
|
+
alias: params.alias,
|
|
2592
|
+
mainKey: params.mainKey
|
|
2593
|
+
});
|
|
2594
|
+
return {
|
|
2595
|
+
ok: true,
|
|
2596
|
+
key: resolvedKey,
|
|
2597
|
+
displayKey: resolveDisplaySessionKey({
|
|
2598
|
+
key: resolvedKey,
|
|
2599
|
+
alias: params.alias,
|
|
2600
|
+
mainKey: params.mainKey
|
|
2601
|
+
}),
|
|
2602
|
+
resolvedViaSessionId: false
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
//#endregion
|
|
2607
|
+
//#region src/agents/tools/sessions-access.ts
|
|
2608
|
+
function resolveSessionToolsVisibility(cfg) {
|
|
2609
|
+
const raw = cfg.tools?.sessions?.visibility;
|
|
2610
|
+
const value = typeof raw === "string" ? raw.trim().toLowerCase() : "";
|
|
2611
|
+
if (value === "self" || value === "tree" || value === "agent" || value === "all") return value;
|
|
2612
|
+
return "tree";
|
|
2613
|
+
}
|
|
2614
|
+
function resolveEffectiveSessionToolsVisibility(params) {
|
|
2615
|
+
const visibility = resolveSessionToolsVisibility(params.cfg);
|
|
2616
|
+
if (!params.sandboxed) return visibility;
|
|
2617
|
+
if ((params.cfg.agents?.defaults?.sandbox?.sessionToolsVisibility ?? "spawned") === "spawned" && visibility !== "tree") return "tree";
|
|
2618
|
+
return visibility;
|
|
2619
|
+
}
|
|
2620
|
+
function resolveSandboxSessionToolsVisibility(cfg) {
|
|
2621
|
+
return cfg.agents?.defaults?.sandbox?.sessionToolsVisibility ?? "spawned";
|
|
2622
|
+
}
|
|
2623
|
+
function resolveSandboxedSessionToolContext(params) {
|
|
2624
|
+
const { mainKey, alias } = resolveMainSessionAlias(params.cfg);
|
|
2625
|
+
const visibility = resolveSandboxSessionToolsVisibility(params.cfg);
|
|
2626
|
+
const requesterInternalKey = typeof params.agentSessionKey === "string" && params.agentSessionKey.trim() ? resolveInternalSessionKey({
|
|
2627
|
+
key: params.agentSessionKey,
|
|
2628
|
+
alias,
|
|
2629
|
+
mainKey
|
|
2630
|
+
}) : void 0;
|
|
2631
|
+
return {
|
|
2632
|
+
mainKey,
|
|
2633
|
+
alias,
|
|
2634
|
+
visibility,
|
|
2635
|
+
requesterInternalKey,
|
|
2636
|
+
effectiveRequesterKey: requesterInternalKey ?? alias,
|
|
2637
|
+
restrictToSpawned: params.sandboxed === true && visibility === "spawned" && !!requesterInternalKey && !isSubagentSessionKey(requesterInternalKey)
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
function createAgentToAgentPolicy(cfg) {
|
|
2641
|
+
const routingA2A = cfg.tools?.agentToAgent;
|
|
2642
|
+
const enabled = routingA2A?.enabled === true;
|
|
2643
|
+
const allowPatterns = Array.isArray(routingA2A?.allow) ? routingA2A.allow : [];
|
|
2644
|
+
const matchesAllow = (agentId) => {
|
|
2645
|
+
if (allowPatterns.length === 0) return true;
|
|
2646
|
+
return allowPatterns.some((pattern) => {
|
|
2647
|
+
const raw = String(pattern ?? "").trim();
|
|
2648
|
+
if (!raw) return false;
|
|
2649
|
+
if (raw === "*") return true;
|
|
2650
|
+
if (!raw.includes("*")) return raw === agentId;
|
|
2651
|
+
const escaped = raw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2652
|
+
return new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`, "i").test(agentId);
|
|
2653
|
+
});
|
|
2654
|
+
};
|
|
2655
|
+
const isAllowed = (requesterAgentId, targetAgentId) => {
|
|
2656
|
+
if (requesterAgentId === targetAgentId) return true;
|
|
2657
|
+
if (!enabled) return false;
|
|
2658
|
+
return matchesAllow(requesterAgentId) && matchesAllow(targetAgentId);
|
|
2659
|
+
};
|
|
2660
|
+
return {
|
|
2661
|
+
enabled,
|
|
2662
|
+
matchesAllow,
|
|
2663
|
+
isAllowed
|
|
2664
|
+
};
|
|
2665
|
+
}
|
|
2666
|
+
function actionPrefix(action) {
|
|
2667
|
+
if (action === "history") return "Session history";
|
|
2668
|
+
if (action === "send") return "Session send";
|
|
2669
|
+
return "Session list";
|
|
2670
|
+
}
|
|
2671
|
+
function a2aDisabledMessage(action) {
|
|
2672
|
+
if (action === "history") return "Agent-to-agent history is disabled. Set tools.agentToAgent.enabled=true to allow cross-agent access.";
|
|
2673
|
+
if (action === "send") return "Agent-to-agent messaging is disabled. Set tools.agentToAgent.enabled=true to allow cross-agent sends.";
|
|
2674
|
+
return "Agent-to-agent listing is disabled. Set tools.agentToAgent.enabled=true to allow cross-agent visibility.";
|
|
2675
|
+
}
|
|
2676
|
+
function a2aDeniedMessage(action) {
|
|
2677
|
+
if (action === "history") return "Agent-to-agent history denied by tools.agentToAgent.allow.";
|
|
2678
|
+
if (action === "send") return "Agent-to-agent messaging denied by tools.agentToAgent.allow.";
|
|
2679
|
+
return "Agent-to-agent listing denied by tools.agentToAgent.allow.";
|
|
2680
|
+
}
|
|
2681
|
+
function crossVisibilityMessage(action) {
|
|
2682
|
+
if (action === "history") return "Session history visibility is restricted. Set tools.sessions.visibility=all to allow cross-agent access.";
|
|
2683
|
+
if (action === "send") return "Session send visibility is restricted. Set tools.sessions.visibility=all to allow cross-agent access.";
|
|
2684
|
+
return "Session list visibility is restricted. Set tools.sessions.visibility=all to allow cross-agent access.";
|
|
2685
|
+
}
|
|
2686
|
+
function selfVisibilityMessage(action) {
|
|
2687
|
+
return `${actionPrefix(action)} visibility is restricted to the current session (tools.sessions.visibility=self).`;
|
|
2688
|
+
}
|
|
2689
|
+
function treeVisibilityMessage(action) {
|
|
2690
|
+
return `${actionPrefix(action)} visibility is restricted to the current session tree (tools.sessions.visibility=tree).`;
|
|
2691
|
+
}
|
|
2692
|
+
async function createSessionVisibilityGuard(params) {
|
|
2693
|
+
const requesterAgentId = resolveAgentIdFromSessionKey(params.requesterSessionKey);
|
|
2694
|
+
const spawnedKeys = params.visibility === "tree" ? await listSpawnedSessionKeys({ requesterSessionKey: params.requesterSessionKey }) : null;
|
|
2695
|
+
const check = (targetSessionKey) => {
|
|
2696
|
+
const targetAgentId = resolveAgentIdFromSessionKey(targetSessionKey);
|
|
2697
|
+
if (targetAgentId !== requesterAgentId) {
|
|
2698
|
+
if (params.visibility !== "all") return {
|
|
2699
|
+
allowed: false,
|
|
2700
|
+
status: "forbidden",
|
|
2701
|
+
error: crossVisibilityMessage(params.action)
|
|
2702
|
+
};
|
|
2703
|
+
if (!params.a2aPolicy.enabled) return {
|
|
2704
|
+
allowed: false,
|
|
2705
|
+
status: "forbidden",
|
|
2706
|
+
error: a2aDisabledMessage(params.action)
|
|
2707
|
+
};
|
|
2708
|
+
if (!params.a2aPolicy.isAllowed(requesterAgentId, targetAgentId)) return {
|
|
2709
|
+
allowed: false,
|
|
2710
|
+
status: "forbidden",
|
|
2711
|
+
error: a2aDeniedMessage(params.action)
|
|
2712
|
+
};
|
|
2713
|
+
return { allowed: true };
|
|
2714
|
+
}
|
|
2715
|
+
if (params.visibility === "self" && targetSessionKey !== params.requesterSessionKey) return {
|
|
2716
|
+
allowed: false,
|
|
2717
|
+
status: "forbidden",
|
|
2718
|
+
error: selfVisibilityMessage(params.action)
|
|
2719
|
+
};
|
|
2720
|
+
if (params.visibility === "tree" && targetSessionKey !== params.requesterSessionKey && !spawnedKeys?.has(targetSessionKey)) return {
|
|
2721
|
+
allowed: false,
|
|
2722
|
+
status: "forbidden",
|
|
2723
|
+
error: treeVisibilityMessage(params.action)
|
|
2724
|
+
};
|
|
2725
|
+
return { allowed: true };
|
|
2726
|
+
};
|
|
2727
|
+
return { check };
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
//#endregion
|
|
2731
|
+
//#region src/shared/text/code-regions.ts
|
|
2732
|
+
function findCodeRegions(text) {
|
|
2733
|
+
const regions = [];
|
|
2734
|
+
for (const match of text.matchAll(/(^|\n)(```|~~~)[^\n]*\n[\s\S]*?(?:\n\2(?:\n|$)|$)/g)) {
|
|
2735
|
+
const start = (match.index ?? 0) + match[1].length;
|
|
2736
|
+
regions.push({
|
|
2737
|
+
start,
|
|
2738
|
+
end: start + match[0].length - match[1].length
|
|
2739
|
+
});
|
|
2740
|
+
}
|
|
2741
|
+
for (const match of text.matchAll(/`+[^`]+`+/g)) {
|
|
2742
|
+
const start = match.index ?? 0;
|
|
2743
|
+
const end = start + match[0].length;
|
|
2744
|
+
if (!regions.some((r) => start >= r.start && end <= r.end)) regions.push({
|
|
2745
|
+
start,
|
|
2746
|
+
end
|
|
2747
|
+
});
|
|
2748
|
+
}
|
|
2749
|
+
regions.sort((a, b) => a.start - b.start);
|
|
2750
|
+
return regions;
|
|
2751
|
+
}
|
|
2752
|
+
function isInsideCode(pos, regions) {
|
|
2753
|
+
return regions.some((r) => pos >= r.start && pos < r.end);
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
//#endregion
|
|
2757
|
+
//#region src/shared/text/reasoning-tags.ts
|
|
2758
|
+
const QUICK_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking|final)\b/i;
|
|
2759
|
+
const FINAL_TAG_RE = /<\s*\/?\s*final\b[^<>]*>/gi;
|
|
2760
|
+
const THINKING_TAG_RE = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\b[^<>]*>/gi;
|
|
2761
|
+
function applyTrim(value, mode) {
|
|
2762
|
+
if (mode === "none") return value;
|
|
2763
|
+
if (mode === "start") return value.trimStart();
|
|
2764
|
+
return value.trim();
|
|
2765
|
+
}
|
|
2766
|
+
function stripReasoningTagsFromText(text, options) {
|
|
2767
|
+
if (!text) return text;
|
|
2768
|
+
if (!QUICK_TAG_RE.test(text)) return text;
|
|
2769
|
+
const mode = options?.mode ?? "strict";
|
|
2770
|
+
const trimMode = options?.trim ?? "both";
|
|
2771
|
+
let cleaned = text;
|
|
2772
|
+
if (FINAL_TAG_RE.test(cleaned)) {
|
|
2773
|
+
FINAL_TAG_RE.lastIndex = 0;
|
|
2774
|
+
const finalMatches = [];
|
|
2775
|
+
const preCodeRegions = findCodeRegions(cleaned);
|
|
2776
|
+
for (const match of cleaned.matchAll(FINAL_TAG_RE)) {
|
|
2777
|
+
const start = match.index ?? 0;
|
|
2778
|
+
finalMatches.push({
|
|
2779
|
+
start,
|
|
2780
|
+
length: match[0].length,
|
|
2781
|
+
inCode: isInsideCode(start, preCodeRegions)
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
for (let i = finalMatches.length - 1; i >= 0; i--) {
|
|
2785
|
+
const m = finalMatches[i];
|
|
2786
|
+
if (!m.inCode) cleaned = cleaned.slice(0, m.start) + cleaned.slice(m.start + m.length);
|
|
2787
|
+
}
|
|
2788
|
+
} else FINAL_TAG_RE.lastIndex = 0;
|
|
2789
|
+
const codeRegions = findCodeRegions(cleaned);
|
|
2790
|
+
THINKING_TAG_RE.lastIndex = 0;
|
|
2791
|
+
let result = "";
|
|
2792
|
+
let lastIndex = 0;
|
|
2793
|
+
let inThinking = false;
|
|
2794
|
+
for (const match of cleaned.matchAll(THINKING_TAG_RE)) {
|
|
2795
|
+
const idx = match.index ?? 0;
|
|
2796
|
+
const isClose = match[1] === "/";
|
|
2797
|
+
if (isInsideCode(idx, codeRegions)) continue;
|
|
2798
|
+
if (!inThinking) {
|
|
2799
|
+
result += cleaned.slice(lastIndex, idx);
|
|
2800
|
+
if (!isClose) inThinking = true;
|
|
2801
|
+
} else if (isClose) inThinking = false;
|
|
2802
|
+
lastIndex = idx + match[0].length;
|
|
2803
|
+
}
|
|
2804
|
+
if (!inThinking || mode === "preserve") result += cleaned.slice(lastIndex);
|
|
2805
|
+
return applyTrim(result, trimMode);
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
//#endregion
|
|
2809
|
+
//#region src/agents/agent-utils.ts
|
|
2810
|
+
/**
|
|
2811
|
+
* Strip malformed Minimax tool invocations that leak into text content.
|
|
2812
|
+
* Minimax sometimes embeds tool calls as XML in text blocks instead of
|
|
2813
|
+
* proper structured tool calls. This removes:
|
|
2814
|
+
* - <invoke name="...">...</invoke> blocks
|
|
2815
|
+
* - </minimax:tool_call> closing tags
|
|
2816
|
+
*/
|
|
2817
|
+
function stripMinimaxToolCallXml(text) {
|
|
2818
|
+
if (!text) return text;
|
|
2819
|
+
if (!/minimax:tool_call/i.test(text)) return text;
|
|
2820
|
+
let cleaned = text.replace(/<invoke\b[^>]*>[\s\S]*?<\/invoke>/gi, "");
|
|
2821
|
+
cleaned = cleaned.replace(/<\/?minimax:tool_call>/gi, "");
|
|
2822
|
+
return cleaned;
|
|
2823
|
+
}
|
|
2824
|
+
/**
|
|
2825
|
+
* Strip downgraded tool call text representations that leak into text content.
|
|
2826
|
+
* When replaying history to Gemini, tool calls without `thought_signature` are
|
|
2827
|
+
* downgraded to text blocks like `[Tool Call: name (ID: ...)]`. These should
|
|
2828
|
+
* not be shown to users.
|
|
2829
|
+
*/
|
|
2830
|
+
function stripDowngradedToolCallText(text) {
|
|
2831
|
+
if (!text) return text;
|
|
2832
|
+
if (!/\[Tool (?:Call|Result)/i.test(text) && !/\[Historical context/i.test(text)) return text;
|
|
2833
|
+
const consumeJsonish = (input, start, options) => {
|
|
2834
|
+
const { allowLeadingNewlines = false } = options ?? {};
|
|
2835
|
+
let index = start;
|
|
2836
|
+
while (index < input.length) {
|
|
2837
|
+
const ch = input[index];
|
|
2838
|
+
if (ch === " " || ch === " ") {
|
|
2839
|
+
index += 1;
|
|
2840
|
+
continue;
|
|
2841
|
+
}
|
|
2842
|
+
if (allowLeadingNewlines && (ch === "\n" || ch === "\r")) {
|
|
2843
|
+
index += 1;
|
|
2844
|
+
continue;
|
|
2845
|
+
}
|
|
2846
|
+
break;
|
|
2847
|
+
}
|
|
2848
|
+
if (index >= input.length) return null;
|
|
2849
|
+
const startChar = input[index];
|
|
2850
|
+
if (startChar === "{" || startChar === "[") {
|
|
2851
|
+
let depth = 0;
|
|
2852
|
+
let inString = false;
|
|
2853
|
+
let escape = false;
|
|
2854
|
+
for (let i = index; i < input.length; i += 1) {
|
|
2855
|
+
const ch = input[i];
|
|
2856
|
+
if (inString) {
|
|
2857
|
+
if (escape) escape = false;
|
|
2858
|
+
else if (ch === "\\") escape = true;
|
|
2859
|
+
else if (ch === "\"") inString = false;
|
|
2860
|
+
continue;
|
|
2861
|
+
}
|
|
2862
|
+
if (ch === "\"") {
|
|
2863
|
+
inString = true;
|
|
2864
|
+
continue;
|
|
2865
|
+
}
|
|
2866
|
+
if (ch === "{" || ch === "[") {
|
|
2867
|
+
depth += 1;
|
|
2868
|
+
continue;
|
|
2869
|
+
}
|
|
2870
|
+
if (ch === "}" || ch === "]") {
|
|
2871
|
+
depth -= 1;
|
|
2872
|
+
if (depth === 0) return i + 1;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
return null;
|
|
2876
|
+
}
|
|
2877
|
+
if (startChar === "\"") {
|
|
2878
|
+
let escape = false;
|
|
2879
|
+
for (let i = index + 1; i < input.length; i += 1) {
|
|
2880
|
+
const ch = input[i];
|
|
2881
|
+
if (escape) {
|
|
2882
|
+
escape = false;
|
|
2883
|
+
continue;
|
|
2884
|
+
}
|
|
2885
|
+
if (ch === "\\") {
|
|
2886
|
+
escape = true;
|
|
2887
|
+
continue;
|
|
2888
|
+
}
|
|
2889
|
+
if (ch === "\"") return i + 1;
|
|
2890
|
+
}
|
|
2891
|
+
return null;
|
|
2892
|
+
}
|
|
2893
|
+
let end = index;
|
|
2894
|
+
while (end < input.length && input[end] !== "\n" && input[end] !== "\r") end += 1;
|
|
2895
|
+
return end;
|
|
2896
|
+
};
|
|
2897
|
+
const stripToolCalls = (input) => {
|
|
2898
|
+
const markerRe = /\[Tool Call:[^\]]*\]/gi;
|
|
2899
|
+
let result = "";
|
|
2900
|
+
let cursor = 0;
|
|
2901
|
+
for (const match of input.matchAll(markerRe)) {
|
|
2902
|
+
const start = match.index ?? 0;
|
|
2903
|
+
if (start < cursor) continue;
|
|
2904
|
+
result += input.slice(cursor, start);
|
|
2905
|
+
let index = start + match[0].length;
|
|
2906
|
+
while (index < input.length && (input[index] === " " || input[index] === " ")) index += 1;
|
|
2907
|
+
if (input[index] === "\r") {
|
|
2908
|
+
index += 1;
|
|
2909
|
+
if (input[index] === "\n") index += 1;
|
|
2910
|
+
} else if (input[index] === "\n") index += 1;
|
|
2911
|
+
while (index < input.length && (input[index] === " " || input[index] === " ")) index += 1;
|
|
2912
|
+
if (input.slice(index, index + 9).toLowerCase() === "arguments") {
|
|
2913
|
+
index += 9;
|
|
2914
|
+
if (input[index] === ":") index += 1;
|
|
2915
|
+
if (input[index] === " ") index += 1;
|
|
2916
|
+
const end = consumeJsonish(input, index, { allowLeadingNewlines: true });
|
|
2917
|
+
if (end !== null) index = end;
|
|
2918
|
+
}
|
|
2919
|
+
if ((input[index] === "\n" || input[index] === "\r") && (result.endsWith("\n") || result.endsWith("\r") || result.length === 0)) {
|
|
2920
|
+
if (input[index] === "\r") index += 1;
|
|
2921
|
+
if (input[index] === "\n") index += 1;
|
|
2922
|
+
}
|
|
2923
|
+
cursor = index;
|
|
2924
|
+
}
|
|
2925
|
+
result += input.slice(cursor);
|
|
2926
|
+
return result;
|
|
2927
|
+
};
|
|
2928
|
+
let cleaned = stripToolCalls(text);
|
|
2929
|
+
cleaned = cleaned.replace(/\[Tool Result for ID[^\]]*\]\n?[\s\S]*?(?=\n*\[Tool |\n*$)/gi, "");
|
|
2930
|
+
cleaned = cleaned.replace(/\[Historical context:[^\]]*\]\n?/gi, "");
|
|
2931
|
+
return cleaned.trim();
|
|
2932
|
+
}
|
|
2933
|
+
/**
|
|
2934
|
+
* Strip thinking tags and their content from text.
|
|
2935
|
+
* This is a safety net for cases where the model outputs <think> tags
|
|
2936
|
+
* that slip through other filtering mechanisms.
|
|
2937
|
+
*/
|
|
2938
|
+
function stripThinkingTagsFromText(text) {
|
|
2939
|
+
return stripReasoningTagsFromText(text, {
|
|
2940
|
+
mode: "strict",
|
|
2941
|
+
trim: "both"
|
|
2942
|
+
});
|
|
2943
|
+
}
|
|
2944
|
+
function formatReasoningMessage(text) {
|
|
2945
|
+
const trimmed = text.trim();
|
|
2946
|
+
if (!trimmed) return "";
|
|
2947
|
+
return `Reasoning:\n${trimmed.split("\n").map((line) => line ? `_${line}_` : line).join("\n")}`;
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
//#endregion
|
|
2951
|
+
//#region src/agents/tools/sessions-helpers.ts
|
|
2952
|
+
function normalizeKey(value) {
|
|
2953
|
+
const trimmed = value?.trim();
|
|
2954
|
+
return trimmed ? trimmed : void 0;
|
|
2955
|
+
}
|
|
2956
|
+
function classifySessionKind(params) {
|
|
2957
|
+
const key = params.key;
|
|
2958
|
+
if (key === params.alias || key === params.mainKey) return "main";
|
|
2959
|
+
if (key.startsWith("cron:")) return "cron";
|
|
2960
|
+
if (key.startsWith("hook:")) return "hook";
|
|
2961
|
+
if (key.startsWith("node-") || key.startsWith("node:")) return "node";
|
|
2962
|
+
if (params.gatewayKind === "group") return "group";
|
|
2963
|
+
if (key.includes(":group:") || key.includes(":channel:")) return "group";
|
|
2964
|
+
return "other";
|
|
2965
|
+
}
|
|
2966
|
+
function deriveChannel(params) {
|
|
2967
|
+
if (params.kind === "cron" || params.kind === "hook" || params.kind === "node") return "internal";
|
|
2968
|
+
const channel = normalizeKey(params.channel ?? void 0);
|
|
2969
|
+
if (channel) return channel;
|
|
2970
|
+
const lastChannel = normalizeKey(params.lastChannel ?? void 0);
|
|
2971
|
+
if (lastChannel) return lastChannel;
|
|
2972
|
+
const parts = params.key.split(":").filter(Boolean);
|
|
2973
|
+
if (parts.length >= 3 && (parts[1] === "group" || parts[1] === "channel")) return parts[0];
|
|
2974
|
+
return "unknown";
|
|
2975
|
+
}
|
|
2976
|
+
function stripToolMessages(messages) {
|
|
2977
|
+
return messages.filter((msg) => {
|
|
2978
|
+
if (!msg || typeof msg !== "object") return true;
|
|
2979
|
+
const role = msg.role;
|
|
2980
|
+
return role !== "toolResult" && role !== "tool";
|
|
2981
|
+
});
|
|
2982
|
+
}
|
|
2983
|
+
/**
|
|
2984
|
+
* Sanitize text content to strip tool call markers and thinking tags.
|
|
2985
|
+
* This ensures user-facing text doesn't leak internal tool representations.
|
|
2986
|
+
*/
|
|
2987
|
+
function sanitizeTextContent(text) {
|
|
2988
|
+
if (!text) return text;
|
|
2989
|
+
return stripThinkingTagsFromText(stripDowngradedToolCallText(stripMinimaxToolCallXml(text)));
|
|
2990
|
+
}
|
|
2991
|
+
function extractAssistantText(message) {
|
|
2992
|
+
if (!message || typeof message !== "object") return;
|
|
2993
|
+
if (message.role !== "assistant") return;
|
|
2994
|
+
const content = message.content;
|
|
2995
|
+
if (!Array.isArray(content)) return;
|
|
2996
|
+
const joined = extractTextFromChatContent(content, {
|
|
2997
|
+
sanitizeText: sanitizeTextContent,
|
|
2998
|
+
joinWith: "",
|
|
2999
|
+
normalizeText: (text) => text.trim()
|
|
3000
|
+
}) ?? "";
|
|
3001
|
+
const stopReason = message.stopReason;
|
|
3002
|
+
const errorMessage = message.errorMessage;
|
|
3003
|
+
const errorContext = stopReason === "error" || typeof errorMessage === "string" && Boolean(errorMessage.trim());
|
|
3004
|
+
return joined ? sanitizeUserFacingText(joined, { errorContext }) : void 0;
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
//#endregion
|
|
3008
|
+
//#region src/agents/tools/agent-step.ts
|
|
3009
|
+
async function readLatestAssistantReply(params) {
|
|
3010
|
+
const history = await callGateway({
|
|
3011
|
+
method: "chat.history",
|
|
3012
|
+
params: {
|
|
3013
|
+
sessionKey: params.sessionKey,
|
|
3014
|
+
limit: params.limit ?? 50
|
|
3015
|
+
}
|
|
3016
|
+
});
|
|
3017
|
+
const filtered = stripToolMessages(Array.isArray(history?.messages) ? history.messages : []);
|
|
3018
|
+
for (let i = filtered.length - 1; i >= 0; i -= 1) {
|
|
3019
|
+
const candidate = filtered[i];
|
|
3020
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
3021
|
+
if (candidate.role !== "assistant") continue;
|
|
3022
|
+
const text = extractAssistantText(candidate);
|
|
3023
|
+
if (!text?.trim()) continue;
|
|
3024
|
+
return text;
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
async function runAgentStep(params) {
|
|
3028
|
+
const stepIdem = crypto.randomUUID();
|
|
3029
|
+
const response = await callGateway({
|
|
3030
|
+
method: "agent",
|
|
3031
|
+
params: {
|
|
3032
|
+
message: params.message,
|
|
3033
|
+
sessionKey: params.sessionKey,
|
|
3034
|
+
idempotencyKey: stepIdem,
|
|
3035
|
+
deliver: false,
|
|
3036
|
+
channel: params.channel ?? INTERNAL_MESSAGE_CHANNEL,
|
|
3037
|
+
lane: params.lane ?? AGENT_LANE_NESTED,
|
|
3038
|
+
extraSystemPrompt: params.extraSystemPrompt,
|
|
3039
|
+
inputProvenance: {
|
|
3040
|
+
kind: "inter_session",
|
|
3041
|
+
sourceSessionKey: params.sourceSessionKey,
|
|
3042
|
+
sourceChannel: params.sourceChannel,
|
|
3043
|
+
sourceTool: params.sourceTool ?? "sessions_send"
|
|
3044
|
+
}
|
|
3045
|
+
},
|
|
3046
|
+
timeoutMs: 1e4
|
|
3047
|
+
});
|
|
3048
|
+
const resolvedRunId = (typeof response?.runId === "string" && response.runId ? response.runId : "") || stepIdem;
|
|
3049
|
+
const stepWaitMs = Math.min(params.timeoutMs, 6e4);
|
|
3050
|
+
if ((await callGateway({
|
|
3051
|
+
method: "agent.wait",
|
|
3052
|
+
params: {
|
|
3053
|
+
runId: resolvedRunId,
|
|
3054
|
+
timeoutMs: stepWaitMs
|
|
3055
|
+
},
|
|
3056
|
+
timeoutMs: stepWaitMs + 2e3
|
|
3057
|
+
}))?.status !== "ok") return;
|
|
3058
|
+
return await readLatestAssistantReply({ sessionKey: params.sessionKey });
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
//#endregion
|
|
3062
|
+
//#region src/agents/tools/sessions-send-helpers.ts
|
|
3063
|
+
const ANNOUNCE_SKIP_TOKEN = "ANNOUNCE_SKIP";
|
|
3064
|
+
const REPLY_SKIP_TOKEN = "REPLY_SKIP";
|
|
3065
|
+
const DEFAULT_PING_PONG_TURNS = 5;
|
|
3066
|
+
const MAX_PING_PONG_TURNS = 5;
|
|
3067
|
+
function resolveAnnounceTargetFromKey(sessionKey) {
|
|
3068
|
+
const rawParts = sessionKey.split(":").filter(Boolean);
|
|
3069
|
+
const parts = rawParts.length >= 3 && rawParts[0] === "agent" ? rawParts.slice(2) : rawParts;
|
|
3070
|
+
if (parts.length < 3) return null;
|
|
3071
|
+
const [channelRaw, kind, ...rest] = parts;
|
|
3072
|
+
if (kind !== "group" && kind !== "channel") return null;
|
|
3073
|
+
let threadId;
|
|
3074
|
+
const restJoined = rest.join(":");
|
|
3075
|
+
const topicMatch = restJoined.match(/:topic:(\d+)$/);
|
|
3076
|
+
const threadMatch = restJoined.match(/:thread:(\d+)$/);
|
|
3077
|
+
const match = topicMatch || threadMatch;
|
|
3078
|
+
if (match) threadId = match[1];
|
|
3079
|
+
const id = match ? restJoined.replace(/:(topic|thread):\d+$/, "") : restJoined.trim();
|
|
3080
|
+
if (!id) return null;
|
|
3081
|
+
if (!channelRaw) return null;
|
|
3082
|
+
const normalizedChannel = normalizeChannelId$1(channelRaw) ?? normalizeChannelId(channelRaw);
|
|
3083
|
+
const channel = normalizedChannel ?? channelRaw.toLowerCase();
|
|
3084
|
+
const kindTarget = (() => {
|
|
3085
|
+
if (!normalizedChannel) return id;
|
|
3086
|
+
if (normalizedChannel === "discord" || normalizedChannel === "slack") return `channel:${id}`;
|
|
3087
|
+
return kind === "channel" ? `channel:${id}` : `group:${id}`;
|
|
3088
|
+
})();
|
|
3089
|
+
return {
|
|
3090
|
+
channel,
|
|
3091
|
+
to: (normalizedChannel ? getChannelPlugin(normalizedChannel)?.messaging?.normalizeTarget?.(kindTarget) : void 0) ?? kindTarget,
|
|
3092
|
+
threadId
|
|
3093
|
+
};
|
|
3094
|
+
}
|
|
3095
|
+
function buildAgentToAgentMessageContext(params) {
|
|
3096
|
+
return [
|
|
3097
|
+
"Agent-to-agent message context:",
|
|
3098
|
+
params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
|
|
3099
|
+
params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
|
|
3100
|
+
`Agent 2 (target) session: ${params.targetSessionKey}.`
|
|
3101
|
+
].filter(Boolean).join("\n");
|
|
3102
|
+
}
|
|
3103
|
+
function buildAgentToAgentReplyContext(params) {
|
|
3104
|
+
return [
|
|
3105
|
+
"Agent-to-agent reply step:",
|
|
3106
|
+
`Current agent: ${params.currentRole === "requester" ? "Agent 1 (requester)" : "Agent 2 (target)"}.`,
|
|
3107
|
+
`Turn ${params.turn} of ${params.maxTurns}.`,
|
|
3108
|
+
params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
|
|
3109
|
+
params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
|
|
3110
|
+
`Agent 2 (target) session: ${params.targetSessionKey}.`,
|
|
3111
|
+
params.targetChannel ? `Agent 2 (target) channel: ${params.targetChannel}.` : void 0,
|
|
3112
|
+
`If you want to stop the ping-pong, reply exactly "${REPLY_SKIP_TOKEN}".`
|
|
3113
|
+
].filter(Boolean).join("\n");
|
|
3114
|
+
}
|
|
3115
|
+
function buildAgentToAgentAnnounceContext(params) {
|
|
3116
|
+
return [
|
|
3117
|
+
"Agent-to-agent announce step:",
|
|
3118
|
+
params.requesterSessionKey ? `Agent 1 (requester) session: ${params.requesterSessionKey}.` : void 0,
|
|
3119
|
+
params.requesterChannel ? `Agent 1 (requester) channel: ${params.requesterChannel}.` : void 0,
|
|
3120
|
+
`Agent 2 (target) session: ${params.targetSessionKey}.`,
|
|
3121
|
+
params.targetChannel ? `Agent 2 (target) channel: ${params.targetChannel}.` : void 0,
|
|
3122
|
+
`Original request: ${params.originalMessage}`,
|
|
3123
|
+
params.roundOneReply ? `Round 1 reply: ${params.roundOneReply}` : "Round 1 reply: (not available).",
|
|
3124
|
+
params.latestReply ? `Latest reply: ${params.latestReply}` : "Latest reply: (not available).",
|
|
3125
|
+
`If you want to remain silent, reply exactly "${ANNOUNCE_SKIP_TOKEN}".`,
|
|
3126
|
+
"Any other reply will be posted to the target channel.",
|
|
3127
|
+
"After this reply, the agent-to-agent conversation is over."
|
|
3128
|
+
].filter(Boolean).join("\n");
|
|
3129
|
+
}
|
|
3130
|
+
function isAnnounceSkip(text) {
|
|
3131
|
+
return (text ?? "").trim() === ANNOUNCE_SKIP_TOKEN;
|
|
3132
|
+
}
|
|
3133
|
+
function isReplySkip(text) {
|
|
3134
|
+
return (text ?? "").trim() === REPLY_SKIP_TOKEN;
|
|
3135
|
+
}
|
|
3136
|
+
function resolvePingPongTurns(cfg) {
|
|
3137
|
+
const raw = cfg?.session?.agentToAgent?.maxPingPongTurns;
|
|
3138
|
+
const fallback = DEFAULT_PING_PONG_TURNS;
|
|
3139
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
|
|
3140
|
+
const rounded = Math.floor(raw);
|
|
3141
|
+
return Math.max(0, Math.min(MAX_PING_PONG_TURNS, rounded));
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
//#endregion
|
|
3145
|
+
//#region src/agents/subagent-announce.ts
|
|
3146
|
+
const FAST_TEST_MODE = process.env.REMOTECLAW_TEST_FAST === "1";
|
|
3147
|
+
const FAST_TEST_RETRY_INTERVAL_MS = 8;
|
|
3148
|
+
const FAST_TEST_REPLY_CHANGE_WAIT_MS = 20;
|
|
3149
|
+
const DEFAULT_SUBAGENT_ANNOUNCE_TIMEOUT_MS = 6e4;
|
|
3150
|
+
const MAX_TIMER_SAFE_TIMEOUT_MS = 2147e6;
|
|
3151
|
+
const DIRECT_ANNOUNCE_TRANSIENT_RETRY_DELAYS_MS = FAST_TEST_MODE ? [
|
|
3152
|
+
8,
|
|
3153
|
+
16,
|
|
3154
|
+
32
|
|
3155
|
+
] : [
|
|
3156
|
+
5e3,
|
|
3157
|
+
1e4,
|
|
3158
|
+
2e4
|
|
3159
|
+
];
|
|
3160
|
+
function resolveSubagentAnnounceTimeoutMs(cfg) {
|
|
3161
|
+
const configured = cfg.agents?.defaults?.subagents?.announceTimeoutMs;
|
|
3162
|
+
if (typeof configured !== "number" || !Number.isFinite(configured)) return DEFAULT_SUBAGENT_ANNOUNCE_TIMEOUT_MS;
|
|
3163
|
+
return Math.min(Math.max(1, Math.floor(configured)), MAX_TIMER_SAFE_TIMEOUT_MS);
|
|
3164
|
+
}
|
|
3165
|
+
function buildCompletionDeliveryMessage(params) {
|
|
3166
|
+
const findingsText = params.findings.trim();
|
|
3167
|
+
if (isAnnounceSkip(findingsText)) return "";
|
|
3168
|
+
const hasFindings = findingsText.length > 0 && findingsText !== "(no output)";
|
|
3169
|
+
const header = (() => {
|
|
3170
|
+
if (params.outcome?.status === "error") return params.spawnMode === "session" ? `❌ Subagent ${params.subagentName} failed this task (session remains active)` : `❌ Subagent ${params.subagentName} failed`;
|
|
3171
|
+
if (params.outcome?.status === "timeout") return params.spawnMode === "session" ? `⏱️ Subagent ${params.subagentName} timed out on this task (session remains active)` : `⏱️ Subagent ${params.subagentName} timed out`;
|
|
3172
|
+
return params.spawnMode === "session" ? `✅ Subagent ${params.subagentName} completed this task (session remains active)` : `✅ Subagent ${params.subagentName} finished`;
|
|
3173
|
+
})();
|
|
3174
|
+
if (!hasFindings) return header;
|
|
3175
|
+
return `${header}\n\n${findingsText}`;
|
|
3176
|
+
}
|
|
3177
|
+
function summarizeDeliveryError(error) {
|
|
3178
|
+
if (error instanceof Error) return error.message || "error";
|
|
3179
|
+
if (typeof error === "string") return error;
|
|
3180
|
+
if (error === void 0 || error === null) return "unknown error";
|
|
3181
|
+
try {
|
|
3182
|
+
return JSON.stringify(error);
|
|
3183
|
+
} catch {
|
|
3184
|
+
return "error";
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
const TRANSIENT_ANNOUNCE_DELIVERY_ERROR_PATTERNS = [
|
|
3188
|
+
/\berrorcode=unavailable\b/i,
|
|
3189
|
+
/\bstatus\s*[:=]\s*"?unavailable\b/i,
|
|
3190
|
+
/\bUNAVAILABLE\b/,
|
|
3191
|
+
/no active .* listener/i,
|
|
3192
|
+
/gateway not connected/i,
|
|
3193
|
+
/gateway closed \(1006/i,
|
|
3194
|
+
/gateway timeout/i,
|
|
3195
|
+
/\b(econnreset|econnrefused|etimedout|enotfound|ehostunreach|network error)\b/i
|
|
3196
|
+
];
|
|
3197
|
+
const PERMANENT_ANNOUNCE_DELIVERY_ERROR_PATTERNS = [
|
|
3198
|
+
/unsupported channel/i,
|
|
3199
|
+
/unknown channel/i,
|
|
3200
|
+
/chat not found/i,
|
|
3201
|
+
/user not found/i,
|
|
3202
|
+
/bot was blocked by the user/i,
|
|
3203
|
+
/forbidden: bot was kicked/i,
|
|
3204
|
+
/recipient is not a valid/i,
|
|
3205
|
+
/outbound not configured for channel/i
|
|
3206
|
+
];
|
|
3207
|
+
function isTransientAnnounceDeliveryError(error) {
|
|
3208
|
+
const message = summarizeDeliveryError(error);
|
|
3209
|
+
if (!message) return false;
|
|
3210
|
+
if (PERMANENT_ANNOUNCE_DELIVERY_ERROR_PATTERNS.some((re) => re.test(message))) return false;
|
|
3211
|
+
return TRANSIENT_ANNOUNCE_DELIVERY_ERROR_PATTERNS.some((re) => re.test(message));
|
|
3212
|
+
}
|
|
3213
|
+
async function waitForAnnounceRetryDelay(ms, signal) {
|
|
3214
|
+
if (ms <= 0) return;
|
|
3215
|
+
if (!signal) {
|
|
3216
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
3217
|
+
return;
|
|
3218
|
+
}
|
|
3219
|
+
if (signal.aborted) return;
|
|
3220
|
+
await new Promise((resolve) => {
|
|
3221
|
+
const timer = setTimeout(() => {
|
|
3222
|
+
signal.removeEventListener("abort", onAbort);
|
|
3223
|
+
resolve();
|
|
3224
|
+
}, ms);
|
|
3225
|
+
const onAbort = () => {
|
|
3226
|
+
clearTimeout(timer);
|
|
3227
|
+
signal.removeEventListener("abort", onAbort);
|
|
3228
|
+
resolve();
|
|
3229
|
+
};
|
|
3230
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3231
|
+
});
|
|
3232
|
+
}
|
|
3233
|
+
async function runAnnounceDeliveryWithRetry(params) {
|
|
3234
|
+
let retryIndex = 0;
|
|
3235
|
+
for (;;) {
|
|
3236
|
+
if (params.signal?.aborted) throw new Error("announce delivery aborted");
|
|
3237
|
+
try {
|
|
3238
|
+
return await params.run();
|
|
3239
|
+
} catch (err) {
|
|
3240
|
+
const delayMs = DIRECT_ANNOUNCE_TRANSIENT_RETRY_DELAYS_MS[retryIndex];
|
|
3241
|
+
if (delayMs == null || !isTransientAnnounceDeliveryError(err) || params.signal?.aborted) throw err;
|
|
3242
|
+
const nextAttempt = retryIndex + 2;
|
|
3243
|
+
const maxAttempts = DIRECT_ANNOUNCE_TRANSIENT_RETRY_DELAYS_MS.length + 1;
|
|
3244
|
+
defaultRuntime.log(`[warn] Subagent announce ${params.operation} transient failure, retrying ${nextAttempt}/${maxAttempts} in ${Math.round(delayMs / 1e3)}s: ${summarizeDeliveryError(err)}`);
|
|
3245
|
+
retryIndex += 1;
|
|
3246
|
+
await waitForAnnounceRetryDelay(delayMs, params.signal);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
function extractToolResultText(content) {
|
|
3251
|
+
if (typeof content === "string") return sanitizeTextContent(content);
|
|
3252
|
+
if (content && typeof content === "object" && !Array.isArray(content)) {
|
|
3253
|
+
const obj = content;
|
|
3254
|
+
if (typeof obj.text === "string") return sanitizeTextContent(obj.text);
|
|
3255
|
+
if (typeof obj.output === "string") return sanitizeTextContent(obj.output);
|
|
3256
|
+
if (typeof obj.content === "string") return sanitizeTextContent(obj.content);
|
|
3257
|
+
if (typeof obj.result === "string") return sanitizeTextContent(obj.result);
|
|
3258
|
+
if (typeof obj.error === "string") return sanitizeTextContent(obj.error);
|
|
3259
|
+
if (typeof obj.summary === "string") return sanitizeTextContent(obj.summary);
|
|
3260
|
+
}
|
|
3261
|
+
if (!Array.isArray(content)) return "";
|
|
3262
|
+
return extractTextFromChatContent(content, {
|
|
3263
|
+
sanitizeText: sanitizeTextContent,
|
|
3264
|
+
normalizeText: (text) => text,
|
|
3265
|
+
joinWith: "\n"
|
|
3266
|
+
})?.trim() ?? "";
|
|
3267
|
+
}
|
|
3268
|
+
function extractInlineTextContent(content) {
|
|
3269
|
+
if (!Array.isArray(content)) return "";
|
|
3270
|
+
return extractTextFromChatContent(content, {
|
|
3271
|
+
sanitizeText: sanitizeTextContent,
|
|
3272
|
+
normalizeText: (text) => text.trim(),
|
|
3273
|
+
joinWith: ""
|
|
3274
|
+
}) ?? "";
|
|
3275
|
+
}
|
|
3276
|
+
function extractSubagentOutputText(message) {
|
|
3277
|
+
if (!message || typeof message !== "object") return "";
|
|
3278
|
+
const role = message.role;
|
|
3279
|
+
const content = message.content;
|
|
3280
|
+
if (role === "assistant") {
|
|
3281
|
+
const assistantText = extractAssistantText(message);
|
|
3282
|
+
if (assistantText) return assistantText;
|
|
3283
|
+
if (typeof content === "string") return sanitizeTextContent(content);
|
|
3284
|
+
if (Array.isArray(content)) return extractInlineTextContent(content);
|
|
3285
|
+
return "";
|
|
3286
|
+
}
|
|
3287
|
+
if (role === "toolResult" || role === "tool") return extractToolResultText(message.content);
|
|
3288
|
+
if (role == null) {
|
|
3289
|
+
if (typeof content === "string") return sanitizeTextContent(content);
|
|
3290
|
+
if (Array.isArray(content)) return extractInlineTextContent(content);
|
|
3291
|
+
}
|
|
3292
|
+
return "";
|
|
3293
|
+
}
|
|
3294
|
+
async function readLatestSubagentOutput(sessionKey) {
|
|
3295
|
+
try {
|
|
3296
|
+
const latestAssistant = await readLatestAssistantReply({
|
|
3297
|
+
sessionKey,
|
|
3298
|
+
limit: 50
|
|
3299
|
+
});
|
|
3300
|
+
if (latestAssistant?.trim()) return latestAssistant;
|
|
3301
|
+
} catch {}
|
|
3302
|
+
const history = await callGateway({
|
|
3303
|
+
method: "chat.history",
|
|
3304
|
+
params: {
|
|
3305
|
+
sessionKey,
|
|
3306
|
+
limit: 50
|
|
3307
|
+
}
|
|
3308
|
+
});
|
|
3309
|
+
const messages = Array.isArray(history?.messages) ? history.messages : [];
|
|
3310
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
3311
|
+
const msg = messages[i];
|
|
3312
|
+
const text = extractSubagentOutputText(msg);
|
|
3313
|
+
if (text) return text;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
async function readLatestSubagentOutputWithRetry(params) {
|
|
3317
|
+
const RETRY_INTERVAL_MS = FAST_TEST_MODE ? FAST_TEST_RETRY_INTERVAL_MS : 100;
|
|
3318
|
+
const deadline = Date.now() + Math.max(0, Math.min(params.maxWaitMs, 15e3));
|
|
3319
|
+
let result;
|
|
3320
|
+
while (Date.now() < deadline) {
|
|
3321
|
+
result = await readLatestSubagentOutput(params.sessionKey);
|
|
3322
|
+
if (result?.trim()) return result;
|
|
3323
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS));
|
|
3324
|
+
}
|
|
3325
|
+
return result;
|
|
3326
|
+
}
|
|
3327
|
+
async function waitForSubagentOutputChange(params) {
|
|
3328
|
+
const baseline = params.baselineReply.trim();
|
|
3329
|
+
if (!baseline) return params.baselineReply;
|
|
3330
|
+
const RETRY_INTERVAL_MS = FAST_TEST_MODE ? FAST_TEST_RETRY_INTERVAL_MS : 100;
|
|
3331
|
+
const deadline = Date.now() + Math.max(0, Math.min(params.maxWaitMs, 5e3));
|
|
3332
|
+
let latest = params.baselineReply;
|
|
3333
|
+
while (Date.now() < deadline) {
|
|
3334
|
+
const next = await readLatestSubagentOutput(params.sessionKey);
|
|
3335
|
+
if (next?.trim()) {
|
|
3336
|
+
latest = next;
|
|
3337
|
+
if (next.trim() !== baseline) return next;
|
|
3338
|
+
}
|
|
3339
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_INTERVAL_MS));
|
|
3340
|
+
}
|
|
3341
|
+
return latest;
|
|
3342
|
+
}
|
|
3343
|
+
function formatDurationShort(valueMs) {
|
|
3344
|
+
if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) return "n/a";
|
|
3345
|
+
const totalSeconds = Math.round(valueMs / 1e3);
|
|
3346
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
3347
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
3348
|
+
const seconds = totalSeconds % 60;
|
|
3349
|
+
if (hours > 0) return `${hours}h${minutes}m`;
|
|
3350
|
+
if (minutes > 0) return `${minutes}m${seconds}s`;
|
|
3351
|
+
return `${seconds}s`;
|
|
3352
|
+
}
|
|
3353
|
+
function formatTokenCount(value) {
|
|
3354
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return "0";
|
|
3355
|
+
if (value >= 1e6) return `${(value / 1e6).toFixed(1)}m`;
|
|
3356
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
|
|
3357
|
+
return String(Math.round(value));
|
|
3358
|
+
}
|
|
3359
|
+
async function buildCompactAnnounceStatsLine(params) {
|
|
3360
|
+
const cfg = loadConfig();
|
|
3361
|
+
const agentId = resolveAgentIdFromSessionKey(params.sessionKey);
|
|
3362
|
+
const storePath = resolveStorePath(cfg.session?.store, { agentId });
|
|
3363
|
+
let entry = loadSessionStore(storePath)[params.sessionKey];
|
|
3364
|
+
const tokenWaitAttempts = FAST_TEST_MODE ? 1 : 3;
|
|
3365
|
+
for (let attempt = 0; attempt < tokenWaitAttempts; attempt += 1) {
|
|
3366
|
+
if (typeof entry?.inputTokens === "number" || typeof entry?.outputTokens === "number" || typeof entry?.totalTokens === "number") break;
|
|
3367
|
+
if (!FAST_TEST_MODE) await new Promise((resolve) => setTimeout(resolve, 150));
|
|
3368
|
+
entry = loadSessionStore(storePath)[params.sessionKey];
|
|
3369
|
+
}
|
|
3370
|
+
const input = typeof entry?.inputTokens === "number" ? entry.inputTokens : 0;
|
|
3371
|
+
const output = typeof entry?.outputTokens === "number" ? entry.outputTokens : 0;
|
|
3372
|
+
const ioTotal = input + output;
|
|
3373
|
+
const promptCache = typeof entry?.totalTokens === "number" ? entry.totalTokens : void 0;
|
|
3374
|
+
const parts = [`runtime ${formatDurationShort(typeof params.startedAt === "number" && typeof params.endedAt === "number" ? Math.max(0, params.endedAt - params.startedAt) : void 0)}`, `tokens ${formatTokenCount(ioTotal)} (in ${formatTokenCount(input)} / out ${formatTokenCount(output)})`];
|
|
3375
|
+
if (typeof promptCache === "number" && promptCache > ioTotal) parts.push(`prompt/cache ${formatTokenCount(promptCache)}`);
|
|
3376
|
+
return `Stats: ${parts.join(" • ")}`;
|
|
3377
|
+
}
|
|
3378
|
+
function resolveAnnounceOrigin(entry, requesterOrigin) {
|
|
3379
|
+
const normalizedRequester = normalizeDeliveryContext(requesterOrigin);
|
|
3380
|
+
const normalizedEntry = deliveryContextFromSession(entry);
|
|
3381
|
+
if (normalizedRequester?.channel && isInternalMessageChannel(normalizedRequester.channel)) return mergeDeliveryContext({
|
|
3382
|
+
accountId: normalizedRequester.accountId,
|
|
3383
|
+
threadId: normalizedRequester.threadId
|
|
3384
|
+
}, normalizedEntry);
|
|
3385
|
+
return mergeDeliveryContext(normalizedRequester, normalizedRequester?.to && normalizedRequester.threadId == null && normalizedEntry?.threadId != null ? (() => {
|
|
3386
|
+
const { threadId: _ignore, ...rest } = normalizedEntry;
|
|
3387
|
+
return rest;
|
|
3388
|
+
})() : normalizedEntry);
|
|
3389
|
+
}
|
|
3390
|
+
async function resolveSubagentCompletionOrigin(params) {
|
|
3391
|
+
const requesterOrigin = normalizeDeliveryContext(params.requesterOrigin);
|
|
3392
|
+
const requesterConversation = (() => {
|
|
3393
|
+
const channel = requesterOrigin?.channel?.trim().toLowerCase();
|
|
3394
|
+
const to = requesterOrigin?.to?.trim();
|
|
3395
|
+
const accountId = normalizeAccountId(requesterOrigin?.accountId);
|
|
3396
|
+
const conversationId = (requesterOrigin?.threadId != null && requesterOrigin.threadId !== "" ? String(requesterOrigin.threadId).trim() : void 0) || (to?.startsWith("channel:") ? to.slice(8) : "");
|
|
3397
|
+
if (!channel || !conversationId) return;
|
|
3398
|
+
return {
|
|
3399
|
+
channel,
|
|
3400
|
+
accountId,
|
|
3401
|
+
conversationId
|
|
3402
|
+
};
|
|
3403
|
+
})();
|
|
3404
|
+
const route = createBoundDeliveryRouter().resolveDestination({
|
|
3405
|
+
eventKind: "task_completion",
|
|
3406
|
+
targetSessionKey: params.childSessionKey,
|
|
3407
|
+
requester: requesterConversation,
|
|
3408
|
+
failClosed: false
|
|
3409
|
+
});
|
|
3410
|
+
if (route.mode === "bound" && route.binding) return {
|
|
3411
|
+
origin: mergeDeliveryContext({
|
|
3412
|
+
channel: route.binding.conversation.channel,
|
|
3413
|
+
accountId: route.binding.conversation.accountId,
|
|
3414
|
+
to: `channel:${route.binding.conversation.conversationId}`,
|
|
3415
|
+
threadId: route.binding.conversation.conversationId
|
|
3416
|
+
}, requesterOrigin),
|
|
3417
|
+
routeMode: "bound"
|
|
3418
|
+
};
|
|
3419
|
+
const hookRunner = getGlobalHookRunner();
|
|
3420
|
+
if (!hookRunner?.hasHooks("subagent_delivery_target")) return {
|
|
3421
|
+
origin: requesterOrigin,
|
|
3422
|
+
routeMode: "fallback"
|
|
3423
|
+
};
|
|
3424
|
+
try {
|
|
3425
|
+
const hookOrigin = normalizeDeliveryContext((await hookRunner.runSubagentDeliveryTarget({
|
|
3426
|
+
childSessionKey: params.childSessionKey,
|
|
3427
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
3428
|
+
requesterOrigin,
|
|
3429
|
+
childRunId: params.childRunId,
|
|
3430
|
+
spawnMode: params.spawnMode,
|
|
3431
|
+
expectsCompletionMessage: params.expectsCompletionMessage
|
|
3432
|
+
}, {
|
|
3433
|
+
runId: params.childRunId,
|
|
3434
|
+
childSessionKey: params.childSessionKey,
|
|
3435
|
+
requesterSessionKey: params.requesterSessionKey
|
|
3436
|
+
}))?.origin);
|
|
3437
|
+
if (!hookOrigin) return {
|
|
3438
|
+
origin: requesterOrigin,
|
|
3439
|
+
routeMode: "fallback"
|
|
3440
|
+
};
|
|
3441
|
+
if (hookOrigin.channel && !isDeliverableMessageChannel(hookOrigin.channel)) return {
|
|
3442
|
+
origin: requesterOrigin,
|
|
3443
|
+
routeMode: "fallback"
|
|
3444
|
+
};
|
|
3445
|
+
return {
|
|
3446
|
+
origin: mergeDeliveryContext(hookOrigin, requesterOrigin),
|
|
3447
|
+
routeMode: "hook"
|
|
3448
|
+
};
|
|
3449
|
+
} catch {
|
|
3450
|
+
return {
|
|
3451
|
+
origin: requesterOrigin,
|
|
3452
|
+
routeMode: "fallback"
|
|
3453
|
+
};
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
function resolveRequesterStoreKey(cfg, requesterSessionKey) {
|
|
3457
|
+
const raw = (requesterSessionKey ?? "").trim();
|
|
3458
|
+
if (!raw) return raw;
|
|
3459
|
+
if (raw === "global" || raw === "unknown") return raw;
|
|
3460
|
+
if (raw.startsWith("agent:")) return raw;
|
|
3461
|
+
const mainKey = normalizeMainKey(cfg.session?.mainKey);
|
|
3462
|
+
if (raw === "main" || raw === mainKey) return resolveMainSessionKey(cfg);
|
|
3463
|
+
return `agent:${resolveAgentIdFromSessionKey(raw)}:${raw}`;
|
|
3464
|
+
}
|
|
3465
|
+
function loadRequesterSessionEntry(requesterSessionKey) {
|
|
3466
|
+
const cfg = loadConfig();
|
|
3467
|
+
const canonicalKey = resolveRequesterStoreKey(cfg, requesterSessionKey);
|
|
3468
|
+
const agentId = resolveAgentIdFromSessionKey(canonicalKey);
|
|
3469
|
+
return {
|
|
3470
|
+
cfg,
|
|
3471
|
+
entry: loadSessionStore(resolveStorePath(cfg.session?.store, { agentId }))[canonicalKey],
|
|
3472
|
+
canonicalKey
|
|
3473
|
+
};
|
|
3474
|
+
}
|
|
3475
|
+
async function maybeQueueSubagentAnnounce(params) {
|
|
3476
|
+
if (params.signal?.aborted) return "none";
|
|
3477
|
+
const { cfg, entry } = loadRequesterSessionEntry(params.requesterSessionKey);
|
|
3478
|
+
resolveRequesterStoreKey(cfg, params.requesterSessionKey);
|
|
3479
|
+
if (!entry?.sessionId) return "none";
|
|
3480
|
+
const queueSettings = resolveQueueSettings({
|
|
3481
|
+
cfg,
|
|
3482
|
+
channel: entry?.channel ?? entry?.lastChannel,
|
|
3483
|
+
sessionEntry: entry
|
|
3484
|
+
});
|
|
3485
|
+
queueSettings.mode === "followup" || queueSettings.mode === "collect" || queueSettings.mode === "steer-backlog" || queueSettings.mode;
|
|
3486
|
+
return "none";
|
|
3487
|
+
}
|
|
3488
|
+
function queueOutcomeToDeliveryResult(outcome) {
|
|
3489
|
+
if (outcome === "steered") return {
|
|
3490
|
+
delivered: true,
|
|
3491
|
+
path: "steered"
|
|
3492
|
+
};
|
|
3493
|
+
if (outcome === "queued") return {
|
|
3494
|
+
delivered: true,
|
|
3495
|
+
path: "queued"
|
|
3496
|
+
};
|
|
3497
|
+
return {
|
|
3498
|
+
delivered: false,
|
|
3499
|
+
path: "none"
|
|
3500
|
+
};
|
|
3501
|
+
}
|
|
3502
|
+
async function sendSubagentAnnounceDirectly(params) {
|
|
3503
|
+
if (params.signal?.aborted) return {
|
|
3504
|
+
delivered: false,
|
|
3505
|
+
path: "none"
|
|
3506
|
+
};
|
|
3507
|
+
const cfg = loadConfig();
|
|
3508
|
+
const announceTimeoutMs = resolveSubagentAnnounceTimeoutMs(cfg);
|
|
3509
|
+
const canonicalRequesterSessionKey = resolveRequesterStoreKey(cfg, params.targetRequesterSessionKey);
|
|
3510
|
+
try {
|
|
3511
|
+
const completionDirectOrigin = normalizeDeliveryContext(params.completionDirectOrigin);
|
|
3512
|
+
const completionChannelRaw = typeof completionDirectOrigin?.channel === "string" ? completionDirectOrigin.channel.trim() : "";
|
|
3513
|
+
const completionChannel = completionChannelRaw && isDeliverableMessageChannel(completionChannelRaw) ? completionChannelRaw : "";
|
|
3514
|
+
const completionTo = typeof completionDirectOrigin?.to === "string" ? completionDirectOrigin.to.trim() : "";
|
|
3515
|
+
const hasCompletionDirectTarget = !params.requesterIsSubagent && Boolean(completionChannel) && Boolean(completionTo);
|
|
3516
|
+
if (params.expectsCompletionMessage && hasCompletionDirectTarget && params.completionMessage?.trim()) {
|
|
3517
|
+
const forceBoundSessionDirectDelivery = params.spawnMode === "session" && (params.completionRouteMode === "bound" || params.completionRouteMode === "hook");
|
|
3518
|
+
let shouldSendCompletionDirectly = true;
|
|
3519
|
+
if (!forceBoundSessionDirectDelivery) {
|
|
3520
|
+
let activeDescendantRuns = 0;
|
|
3521
|
+
try {
|
|
3522
|
+
const { countActiveDescendantRuns } = await Promise.resolve().then(() => subagent_registry_exports);
|
|
3523
|
+
activeDescendantRuns = Math.max(0, countActiveDescendantRuns(canonicalRequesterSessionKey));
|
|
3524
|
+
} catch {}
|
|
3525
|
+
if (activeDescendantRuns > 0) shouldSendCompletionDirectly = false;
|
|
3526
|
+
}
|
|
3527
|
+
if (shouldSendCompletionDirectly) {
|
|
3528
|
+
const completionThreadId = completionDirectOrigin?.threadId != null && completionDirectOrigin.threadId !== "" ? String(completionDirectOrigin.threadId) : void 0;
|
|
3529
|
+
if (params.signal?.aborted) return {
|
|
3530
|
+
delivered: false,
|
|
3531
|
+
path: "none"
|
|
3532
|
+
};
|
|
3533
|
+
await runAnnounceDeliveryWithRetry({
|
|
3534
|
+
operation: "completion direct send",
|
|
3535
|
+
signal: params.signal,
|
|
3536
|
+
run: async () => await callGateway({
|
|
3537
|
+
method: "send",
|
|
3538
|
+
params: {
|
|
3539
|
+
channel: completionChannel,
|
|
3540
|
+
to: completionTo,
|
|
3541
|
+
accountId: completionDirectOrigin?.accountId,
|
|
3542
|
+
threadId: completionThreadId,
|
|
3543
|
+
sessionKey: canonicalRequesterSessionKey,
|
|
3544
|
+
message: params.completionMessage,
|
|
3545
|
+
idempotencyKey: params.directIdempotencyKey
|
|
3546
|
+
},
|
|
3547
|
+
timeoutMs: announceTimeoutMs
|
|
3548
|
+
})
|
|
3549
|
+
});
|
|
3550
|
+
return {
|
|
3551
|
+
delivered: true,
|
|
3552
|
+
path: "direct"
|
|
3553
|
+
};
|
|
3554
|
+
}
|
|
3555
|
+
}
|
|
3556
|
+
const directOrigin = normalizeDeliveryContext(params.directOrigin);
|
|
3557
|
+
const directChannelRaw = typeof directOrigin?.channel === "string" ? directOrigin.channel.trim() : "";
|
|
3558
|
+
const directChannel = directChannelRaw && isDeliverableMessageChannel(directChannelRaw) ? directChannelRaw : "";
|
|
3559
|
+
const directTo = typeof directOrigin?.to === "string" ? directOrigin.to.trim() : "";
|
|
3560
|
+
const hasDeliverableDirectTarget = !params.requesterIsSubagent && Boolean(directChannel) && Boolean(directTo);
|
|
3561
|
+
const shouldDeliverExternally = !params.requesterIsSubagent && (!params.expectsCompletionMessage || hasDeliverableDirectTarget);
|
|
3562
|
+
const threadId = directOrigin?.threadId != null && directOrigin.threadId !== "" ? String(directOrigin.threadId) : void 0;
|
|
3563
|
+
if (params.signal?.aborted) return {
|
|
3564
|
+
delivered: false,
|
|
3565
|
+
path: "none"
|
|
3566
|
+
};
|
|
3567
|
+
await runAnnounceDeliveryWithRetry({
|
|
3568
|
+
operation: "direct announce agent call",
|
|
3569
|
+
signal: params.signal,
|
|
3570
|
+
run: async () => await callGateway({
|
|
3571
|
+
method: "agent",
|
|
3572
|
+
params: {
|
|
3573
|
+
sessionKey: canonicalRequesterSessionKey,
|
|
3574
|
+
message: params.triggerMessage,
|
|
3575
|
+
deliver: shouldDeliverExternally,
|
|
3576
|
+
bestEffortDeliver: params.bestEffortDeliver,
|
|
3577
|
+
channel: shouldDeliverExternally ? directChannel : void 0,
|
|
3578
|
+
accountId: shouldDeliverExternally ? directOrigin?.accountId : void 0,
|
|
3579
|
+
to: shouldDeliverExternally ? directTo : void 0,
|
|
3580
|
+
threadId: shouldDeliverExternally ? threadId : void 0,
|
|
3581
|
+
idempotencyKey: params.directIdempotencyKey
|
|
3582
|
+
},
|
|
3583
|
+
expectFinal: true,
|
|
3584
|
+
timeoutMs: announceTimeoutMs
|
|
3585
|
+
})
|
|
3586
|
+
});
|
|
3587
|
+
return {
|
|
3588
|
+
delivered: true,
|
|
3589
|
+
path: "direct"
|
|
3590
|
+
};
|
|
3591
|
+
} catch (err) {
|
|
3592
|
+
return {
|
|
3593
|
+
delivered: false,
|
|
3594
|
+
path: "direct",
|
|
3595
|
+
error: summarizeDeliveryError(err)
|
|
3596
|
+
};
|
|
3597
|
+
}
|
|
3598
|
+
}
|
|
3599
|
+
async function deliverSubagentAnnouncement(params) {
|
|
3600
|
+
if (params.signal?.aborted) return {
|
|
3601
|
+
delivered: false,
|
|
3602
|
+
path: "none"
|
|
3603
|
+
};
|
|
3604
|
+
if (!params.expectsCompletionMessage) {
|
|
3605
|
+
const queued = queueOutcomeToDeliveryResult(await maybeQueueSubagentAnnounce({
|
|
3606
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
3607
|
+
announceId: params.announceId,
|
|
3608
|
+
triggerMessage: params.triggerMessage,
|
|
3609
|
+
summaryLine: params.summaryLine,
|
|
3610
|
+
requesterOrigin: params.requesterOrigin,
|
|
3611
|
+
signal: params.signal
|
|
3612
|
+
}));
|
|
3613
|
+
if (queued.delivered) return queued;
|
|
3614
|
+
}
|
|
3615
|
+
const direct = await sendSubagentAnnounceDirectly({
|
|
3616
|
+
targetRequesterSessionKey: params.targetRequesterSessionKey,
|
|
3617
|
+
triggerMessage: params.triggerMessage,
|
|
3618
|
+
completionMessage: params.completionMessage,
|
|
3619
|
+
directIdempotencyKey: params.directIdempotencyKey,
|
|
3620
|
+
completionDirectOrigin: params.completionDirectOrigin,
|
|
3621
|
+
completionRouteMode: params.completionRouteMode,
|
|
3622
|
+
spawnMode: params.spawnMode,
|
|
3623
|
+
directOrigin: params.directOrigin,
|
|
3624
|
+
requesterIsSubagent: params.requesterIsSubagent,
|
|
3625
|
+
expectsCompletionMessage: params.expectsCompletionMessage,
|
|
3626
|
+
signal: params.signal,
|
|
3627
|
+
bestEffortDeliver: params.bestEffortDeliver
|
|
3628
|
+
});
|
|
3629
|
+
if (direct.delivered || !params.expectsCompletionMessage) return direct;
|
|
3630
|
+
const queueOutcome = await maybeQueueSubagentAnnounce({
|
|
3631
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
3632
|
+
announceId: params.announceId,
|
|
3633
|
+
triggerMessage: params.triggerMessage,
|
|
3634
|
+
summaryLine: params.summaryLine,
|
|
3635
|
+
requesterOrigin: params.requesterOrigin,
|
|
3636
|
+
signal: params.signal
|
|
3637
|
+
});
|
|
3638
|
+
if (queueOutcome === "steered" || queueOutcome === "queued") return queueOutcomeToDeliveryResult(queueOutcome);
|
|
3639
|
+
return direct;
|
|
3640
|
+
}
|
|
3641
|
+
function loadSessionEntryByKey(sessionKey) {
|
|
3642
|
+
const cfg = loadConfig();
|
|
3643
|
+
const agentId = resolveAgentIdFromSessionKey(sessionKey);
|
|
3644
|
+
return loadSessionStore(resolveStorePath(cfg.session?.store, { agentId }))[sessionKey];
|
|
3645
|
+
}
|
|
3646
|
+
function buildSubagentSystemPrompt(params) {
|
|
3647
|
+
const taskText = typeof params.task === "string" && params.task.trim() ? params.task.replace(/\s+/g, " ").trim() : "{{TASK_DESCRIPTION}}";
|
|
3648
|
+
const childDepth = typeof params.childDepth === "number" ? params.childDepth : 1;
|
|
3649
|
+
const canSpawn = childDepth < (typeof params.maxSpawnDepth === "number" ? params.maxSpawnDepth : DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH);
|
|
3650
|
+
const parentLabel = childDepth >= 2 ? "parent orchestrator" : "main agent";
|
|
3651
|
+
const lines = [
|
|
3652
|
+
"# Subagent Context",
|
|
3653
|
+
"",
|
|
3654
|
+
`You are a **subagent** spawned by the ${parentLabel} for a specific task.`,
|
|
3655
|
+
"",
|
|
3656
|
+
"## Your Role",
|
|
3657
|
+
`- You were created to handle: ${taskText}`,
|
|
3658
|
+
"- Complete this task. That's your entire purpose.",
|
|
3659
|
+
`- You are NOT the ${parentLabel}. Don't try to be.`,
|
|
3660
|
+
"",
|
|
3661
|
+
"## Rules",
|
|
3662
|
+
"1. **Stay focused** - Do your assigned task, nothing else",
|
|
3663
|
+
`2. **Complete the task** - Your final message will be automatically reported to the ${parentLabel}`,
|
|
3664
|
+
"3. **Don't initiate** - No heartbeats, no proactive actions, no side quests",
|
|
3665
|
+
"4. **Be ephemeral** - You may be terminated after task completion. That's fine.",
|
|
3666
|
+
"5. **Trust push-based completion** - Descendant results are auto-announced back to you; do not busy-poll for status.",
|
|
3667
|
+
"6. **Recover from compacted/truncated tool output** - If you see `[compacted: tool output removed to free context]` or `[truncated: output exceeded context limit]`, assume prior output was reduced. Re-read only what you need using smaller chunks (`read` with offset/limit, or targeted `rg`/`head`/`tail`) instead of full-file `cat`.",
|
|
3668
|
+
"",
|
|
3669
|
+
"## Output Format",
|
|
3670
|
+
"When complete, your final response should include:",
|
|
3671
|
+
`- What you accomplished or found`,
|
|
3672
|
+
`- Any relevant details the ${parentLabel} should know`,
|
|
3673
|
+
"- Keep it concise but informative",
|
|
3674
|
+
"",
|
|
3675
|
+
"## What You DON'T Do",
|
|
3676
|
+
`- NO user conversations (that's ${parentLabel}'s job)`,
|
|
3677
|
+
"- NO external messages (email, tweets, etc.) unless explicitly tasked with a specific recipient/channel",
|
|
3678
|
+
"- NO cron jobs or persistent state",
|
|
3679
|
+
`- NO pretending to be the ${parentLabel}`,
|
|
3680
|
+
`- Only use the \`message\` tool when explicitly instructed to contact a specific external recipient; otherwise return plain text and let the ${parentLabel} deliver it`,
|
|
3681
|
+
""
|
|
3682
|
+
];
|
|
3683
|
+
if (canSpawn) lines.push("## Sub-Agent Spawning", "You CAN spawn your own sub-agents for parallel or complex work using `sessions_spawn`.", "Use the `subagents` tool to steer, kill, or do an on-demand status check for your spawned sub-agents.", "Your sub-agents will announce their results back to you automatically (not to the main agent).", "Default workflow: spawn work, continue orchestrating, and wait for auto-announced completions.", "Do NOT repeatedly poll `subagents list` in a loop unless you are actively debugging or intervening.", "Coordinate their work and synthesize results before reporting back.", "");
|
|
3684
|
+
else if (childDepth >= 2) lines.push("## Sub-Agent Spawning", "You are a leaf worker and CANNOT spawn further sub-agents. Focus on your assigned task.", "");
|
|
3685
|
+
lines.push("## Session Context", ...[
|
|
3686
|
+
params.label ? `- Label: ${params.label}` : void 0,
|
|
3687
|
+
params.requesterSessionKey ? `- Requester session: ${params.requesterSessionKey}.` : void 0,
|
|
3688
|
+
params.requesterOrigin?.channel ? `- Requester channel: ${params.requesterOrigin.channel}.` : void 0,
|
|
3689
|
+
`- Your session: ${params.childSessionKey}.`
|
|
3690
|
+
].filter((line) => line !== void 0), "");
|
|
3691
|
+
return lines.join("\n");
|
|
3692
|
+
}
|
|
3693
|
+
function buildAnnounceReplyInstruction(params) {
|
|
3694
|
+
if (params.remainingActiveSubagentRuns > 0) {
|
|
3695
|
+
const activeRunsLabel = params.remainingActiveSubagentRuns === 1 ? "run" : "runs";
|
|
3696
|
+
return `There are still ${params.remainingActiveSubagentRuns} active subagent ${activeRunsLabel} for this session. If they are part of the same workflow, wait for the remaining results before sending a user update. If they are unrelated, respond normally using only the result above.`;
|
|
3697
|
+
}
|
|
3698
|
+
if (params.requesterIsSubagent) return `Convert this completion into a concise internal orchestration update for your parent agent in your own words. Keep this internal context private (don't mention system/log/stats/session details or announce type). If this result is duplicate or no update is needed, reply ONLY: ${SILENT_REPLY_TOKEN}.`;
|
|
3699
|
+
if (params.expectsCompletionMessage) return `A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type).`;
|
|
3700
|
+
return `A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type), and do not copy the system message verbatim. Reply ONLY: ${SILENT_REPLY_TOKEN} if this exact result was already delivered to the user in this same turn.`;
|
|
3701
|
+
}
|
|
3702
|
+
async function runSubagentAnnounceFlow(params) {
|
|
3703
|
+
let didAnnounce = false;
|
|
3704
|
+
const expectsCompletionMessage = params.expectsCompletionMessage === true;
|
|
3705
|
+
let shouldDeleteChildSession = params.cleanup === "delete";
|
|
3706
|
+
try {
|
|
3707
|
+
let targetRequesterSessionKey = params.requesterSessionKey;
|
|
3708
|
+
let targetRequesterOrigin = normalizeDeliveryContext(params.requesterOrigin);
|
|
3709
|
+
const childSessionId = (() => {
|
|
3710
|
+
const entry = loadSessionEntryByKey(params.childSessionKey);
|
|
3711
|
+
return typeof entry?.sessionId === "string" && entry.sessionId.trim() ? entry.sessionId.trim() : void 0;
|
|
3712
|
+
})();
|
|
3713
|
+
const settleTimeoutMs = Math.min(Math.max(params.timeoutMs, 1), 12e4);
|
|
3714
|
+
let reply = params.roundOneReply;
|
|
3715
|
+
let outcome = params.outcome;
|
|
3716
|
+
if (!reply && params.waitForCompletion !== false) {
|
|
3717
|
+
const waitMs = settleTimeoutMs;
|
|
3718
|
+
const wait = await callGateway({
|
|
3719
|
+
method: "agent.wait",
|
|
3720
|
+
params: {
|
|
3721
|
+
runId: params.childRunId,
|
|
3722
|
+
timeoutMs: waitMs
|
|
3723
|
+
},
|
|
3724
|
+
timeoutMs: waitMs + 2e3
|
|
3725
|
+
});
|
|
3726
|
+
const waitError = typeof wait?.error === "string" ? wait.error : void 0;
|
|
3727
|
+
if (wait?.status === "timeout") outcome = { status: "timeout" };
|
|
3728
|
+
else if (wait?.status === "error") outcome = {
|
|
3729
|
+
status: "error",
|
|
3730
|
+
error: waitError
|
|
3731
|
+
};
|
|
3732
|
+
else if (wait?.status === "ok") outcome = { status: "ok" };
|
|
3733
|
+
if (typeof wait?.startedAt === "number" && !params.startedAt) params.startedAt = wait.startedAt;
|
|
3734
|
+
if (typeof wait?.endedAt === "number" && !params.endedAt) params.endedAt = wait.endedAt;
|
|
3735
|
+
if (wait?.status === "timeout") {
|
|
3736
|
+
if (!outcome) outcome = { status: "timeout" };
|
|
3737
|
+
}
|
|
3738
|
+
reply = await readLatestSubagentOutput(params.childSessionKey);
|
|
3739
|
+
}
|
|
3740
|
+
if (!reply) reply = await readLatestSubagentOutput(params.childSessionKey);
|
|
3741
|
+
if (!reply?.trim()) reply = await readLatestSubagentOutputWithRetry({
|
|
3742
|
+
sessionKey: params.childSessionKey,
|
|
3743
|
+
maxWaitMs: params.timeoutMs
|
|
3744
|
+
});
|
|
3745
|
+
if (isAnnounceSkip(reply)) return true;
|
|
3746
|
+
if (!outcome) outcome = { status: "unknown" };
|
|
3747
|
+
let requesterDepth = getSubagentDepthFromSessionStore(targetRequesterSessionKey);
|
|
3748
|
+
let activeChildDescendantRuns = 0;
|
|
3749
|
+
try {
|
|
3750
|
+
const { countActiveDescendantRuns } = await Promise.resolve().then(() => subagent_registry_exports);
|
|
3751
|
+
activeChildDescendantRuns = Math.max(0, countActiveDescendantRuns(params.childSessionKey));
|
|
3752
|
+
} catch {}
|
|
3753
|
+
if (activeChildDescendantRuns > 0) {
|
|
3754
|
+
shouldDeleteChildSession = false;
|
|
3755
|
+
return false;
|
|
3756
|
+
}
|
|
3757
|
+
if (requesterDepth >= 1 && reply?.trim()) {
|
|
3758
|
+
const minReplyChangeWaitMs = FAST_TEST_MODE ? FAST_TEST_REPLY_CHANGE_WAIT_MS : 250;
|
|
3759
|
+
reply = await waitForSubagentOutputChange({
|
|
3760
|
+
sessionKey: params.childSessionKey,
|
|
3761
|
+
baselineReply: reply,
|
|
3762
|
+
maxWaitMs: Math.max(minReplyChangeWaitMs, Math.min(params.timeoutMs, 2e3))
|
|
3763
|
+
});
|
|
3764
|
+
}
|
|
3765
|
+
const statusLabel = outcome.status === "ok" ? "completed successfully" : outcome.status === "timeout" ? "timed out" : outcome.status === "error" ? `failed: ${outcome.error || "unknown error"}` : "finished with unknown status";
|
|
3766
|
+
const announceType = params.announceType ?? "subagent task";
|
|
3767
|
+
const taskLabel = params.label || params.task || "task";
|
|
3768
|
+
const subagentName = resolveAgentIdFromSessionKey(params.childSessionKey);
|
|
3769
|
+
const announceSessionId = childSessionId || "unknown";
|
|
3770
|
+
const findings = reply || "(no output)";
|
|
3771
|
+
let completionMessage = "";
|
|
3772
|
+
let triggerMessage = "";
|
|
3773
|
+
let requesterIsSubagent = requesterDepth >= 1;
|
|
3774
|
+
if (requesterIsSubagent) {
|
|
3775
|
+
const { isSubagentSessionRunActive, resolveRequesterForChildSession } = await Promise.resolve().then(() => subagent_registry_exports);
|
|
3776
|
+
if (!isSubagentSessionRunActive(targetRequesterSessionKey)) {
|
|
3777
|
+
const parentSessionEntry = loadSessionEntryByKey(targetRequesterSessionKey);
|
|
3778
|
+
if (!(parentSessionEntry && typeof parentSessionEntry.sessionId === "string" && parentSessionEntry.sessionId.trim())) {
|
|
3779
|
+
const fallback = resolveRequesterForChildSession(targetRequesterSessionKey);
|
|
3780
|
+
if (!fallback?.requesterSessionKey) {
|
|
3781
|
+
shouldDeleteChildSession = false;
|
|
3782
|
+
return false;
|
|
3783
|
+
}
|
|
3784
|
+
targetRequesterSessionKey = fallback.requesterSessionKey;
|
|
3785
|
+
targetRequesterOrigin = normalizeDeliveryContext(fallback.requesterOrigin) ?? targetRequesterOrigin;
|
|
3786
|
+
requesterDepth = getSubagentDepthFromSessionStore(targetRequesterSessionKey);
|
|
3787
|
+
requesterIsSubagent = requesterDepth >= 1;
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
let remainingActiveSubagentRuns = 0;
|
|
3792
|
+
try {
|
|
3793
|
+
const { countActiveDescendantRuns } = await Promise.resolve().then(() => subagent_registry_exports);
|
|
3794
|
+
remainingActiveSubagentRuns = Math.max(0, countActiveDescendantRuns(targetRequesterSessionKey));
|
|
3795
|
+
} catch {}
|
|
3796
|
+
const replyInstruction = buildAnnounceReplyInstruction({
|
|
3797
|
+
remainingActiveSubagentRuns,
|
|
3798
|
+
requesterIsSubagent,
|
|
3799
|
+
announceType,
|
|
3800
|
+
expectsCompletionMessage
|
|
3801
|
+
});
|
|
3802
|
+
const statsLine = await buildCompactAnnounceStatsLine({
|
|
3803
|
+
sessionKey: params.childSessionKey,
|
|
3804
|
+
startedAt: params.startedAt,
|
|
3805
|
+
endedAt: params.endedAt
|
|
3806
|
+
});
|
|
3807
|
+
completionMessage = buildCompletionDeliveryMessage({
|
|
3808
|
+
findings,
|
|
3809
|
+
subagentName,
|
|
3810
|
+
spawnMode: params.spawnMode,
|
|
3811
|
+
outcome
|
|
3812
|
+
});
|
|
3813
|
+
triggerMessage = [
|
|
3814
|
+
[
|
|
3815
|
+
`[System Message] [sessionId: ${announceSessionId}] A ${announceType} "${taskLabel}" just ${statusLabel}.`,
|
|
3816
|
+
"",
|
|
3817
|
+
"Result:",
|
|
3818
|
+
findings,
|
|
3819
|
+
"",
|
|
3820
|
+
statsLine
|
|
3821
|
+
].join("\n"),
|
|
3822
|
+
"",
|
|
3823
|
+
replyInstruction
|
|
3824
|
+
].join("\n");
|
|
3825
|
+
const announceId = buildAnnounceIdFromChildRun({
|
|
3826
|
+
childSessionKey: params.childSessionKey,
|
|
3827
|
+
childRunId: params.childRunId
|
|
3828
|
+
});
|
|
3829
|
+
let directOrigin = targetRequesterOrigin;
|
|
3830
|
+
if (!requesterIsSubagent) {
|
|
3831
|
+
const { entry } = loadRequesterSessionEntry(targetRequesterSessionKey);
|
|
3832
|
+
directOrigin = resolveAnnounceOrigin(entry, targetRequesterOrigin);
|
|
3833
|
+
}
|
|
3834
|
+
const completionResolution = expectsCompletionMessage && !requesterIsSubagent ? await resolveSubagentCompletionOrigin({
|
|
3835
|
+
childSessionKey: params.childSessionKey,
|
|
3836
|
+
requesterSessionKey: targetRequesterSessionKey,
|
|
3837
|
+
requesterOrigin: directOrigin,
|
|
3838
|
+
childRunId: params.childRunId,
|
|
3839
|
+
spawnMode: params.spawnMode,
|
|
3840
|
+
expectsCompletionMessage
|
|
3841
|
+
}) : {
|
|
3842
|
+
origin: targetRequesterOrigin,
|
|
3843
|
+
routeMode: "fallback"
|
|
3844
|
+
};
|
|
3845
|
+
const completionDirectOrigin = completionResolution.origin;
|
|
3846
|
+
const directIdempotencyKey = buildAnnounceIdempotencyKey(announceId);
|
|
3847
|
+
const delivery = await deliverSubagentAnnouncement({
|
|
3848
|
+
requesterSessionKey: targetRequesterSessionKey,
|
|
3849
|
+
announceId,
|
|
3850
|
+
triggerMessage,
|
|
3851
|
+
completionMessage,
|
|
3852
|
+
summaryLine: taskLabel,
|
|
3853
|
+
requesterOrigin: expectsCompletionMessage && !requesterIsSubagent ? completionDirectOrigin : targetRequesterOrigin,
|
|
3854
|
+
completionDirectOrigin,
|
|
3855
|
+
directOrigin,
|
|
3856
|
+
targetRequesterSessionKey,
|
|
3857
|
+
requesterIsSubagent,
|
|
3858
|
+
expectsCompletionMessage,
|
|
3859
|
+
bestEffortDeliver: params.bestEffortDeliver,
|
|
3860
|
+
completionRouteMode: completionResolution.routeMode,
|
|
3861
|
+
spawnMode: params.spawnMode,
|
|
3862
|
+
directIdempotencyKey,
|
|
3863
|
+
signal: params.signal
|
|
3864
|
+
});
|
|
3865
|
+
didAnnounce = delivery.delivered;
|
|
3866
|
+
if (!delivery.delivered && delivery.path === "direct" && delivery.error) defaultRuntime.error?.(`Subagent completion direct announce failed for run ${params.childRunId}: ${delivery.error}`);
|
|
3867
|
+
} catch (err) {
|
|
3868
|
+
defaultRuntime.error?.(`Subagent announce failed: ${String(err)}`);
|
|
3869
|
+
} finally {
|
|
3870
|
+
if (params.label) try {
|
|
3871
|
+
await callGateway({
|
|
3872
|
+
method: "sessions.patch",
|
|
3873
|
+
params: {
|
|
3874
|
+
key: params.childSessionKey,
|
|
3875
|
+
label: params.label
|
|
3876
|
+
},
|
|
3877
|
+
timeoutMs: 1e4
|
|
3878
|
+
});
|
|
3879
|
+
} catch {}
|
|
3880
|
+
if (shouldDeleteChildSession) try {
|
|
3881
|
+
await callGateway({
|
|
3882
|
+
method: "sessions.delete",
|
|
3883
|
+
params: {
|
|
3884
|
+
key: params.childSessionKey,
|
|
3885
|
+
deleteTranscript: true,
|
|
3886
|
+
emitLifecycleHooks: false
|
|
3887
|
+
},
|
|
3888
|
+
timeoutMs: 1e4
|
|
3889
|
+
});
|
|
3890
|
+
} catch {}
|
|
3891
|
+
}
|
|
3892
|
+
return didAnnounce;
|
|
3893
|
+
}
|
|
3894
|
+
|
|
3895
|
+
//#endregion
|
|
3896
|
+
//#region src/agents/subagent-lifecycle-events.ts
|
|
3897
|
+
const SUBAGENT_TARGET_KIND_SUBAGENT = "subagent";
|
|
3898
|
+
const SUBAGENT_ENDED_REASON_COMPLETE = "subagent-complete";
|
|
3899
|
+
const SUBAGENT_ENDED_REASON_ERROR = "subagent-error";
|
|
3900
|
+
const SUBAGENT_ENDED_REASON_KILLED = "subagent-killed";
|
|
3901
|
+
const SUBAGENT_ENDED_OUTCOME_OK = "ok";
|
|
3902
|
+
const SUBAGENT_ENDED_OUTCOME_ERROR = "error";
|
|
3903
|
+
const SUBAGENT_ENDED_OUTCOME_TIMEOUT = "timeout";
|
|
3904
|
+
const SUBAGENT_ENDED_OUTCOME_KILLED = "killed";
|
|
3905
|
+
|
|
3906
|
+
//#endregion
|
|
3907
|
+
//#region src/agents/subagent-registry-cleanup.ts
|
|
3908
|
+
function resolveCleanupCompletionReason(entry) {
|
|
3909
|
+
return entry.endedReason ?? SUBAGENT_ENDED_REASON_COMPLETE;
|
|
3910
|
+
}
|
|
3911
|
+
function resolveEndedAgoMs(entry, now) {
|
|
3912
|
+
return typeof entry.endedAt === "number" ? now - entry.endedAt : 0;
|
|
3913
|
+
}
|
|
3914
|
+
function resolveDeferredCleanupDecision(params) {
|
|
3915
|
+
const endedAgo = resolveEndedAgoMs(params.entry, params.now);
|
|
3916
|
+
if (params.entry.expectsCompletionMessage === true && params.activeDescendantRuns > 0) {
|
|
3917
|
+
if (endedAgo > params.announceExpiryMs) return {
|
|
3918
|
+
kind: "give-up",
|
|
3919
|
+
reason: "expiry"
|
|
3920
|
+
};
|
|
3921
|
+
return {
|
|
3922
|
+
kind: "defer-descendants",
|
|
3923
|
+
delayMs: params.deferDescendantDelayMs
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
const retryCount = (params.entry.announceRetryCount ?? 0) + 1;
|
|
3927
|
+
if (retryCount >= params.maxAnnounceRetryCount || endedAgo > params.announceExpiryMs) return {
|
|
3928
|
+
kind: "give-up",
|
|
3929
|
+
reason: retryCount >= params.maxAnnounceRetryCount ? "retry-limit" : "expiry",
|
|
3930
|
+
retryCount
|
|
3931
|
+
};
|
|
3932
|
+
return {
|
|
3933
|
+
kind: "retry",
|
|
3934
|
+
retryCount,
|
|
3935
|
+
resumeDelayMs: params.entry.expectsCompletionMessage === true ? params.resolveAnnounceRetryDelayMs(retryCount) : void 0
|
|
3936
|
+
};
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3939
|
+
//#endregion
|
|
3940
|
+
//#region src/agents/subagent-registry-completion.ts
|
|
3941
|
+
function runOutcomesEqual(a, b) {
|
|
3942
|
+
if (!a && !b) return true;
|
|
3943
|
+
if (!a || !b) return false;
|
|
3944
|
+
if (a.status !== b.status) return false;
|
|
3945
|
+
if (a.status === "error" && b.status === "error") return (a.error ?? "") === (b.error ?? "");
|
|
3946
|
+
return true;
|
|
3947
|
+
}
|
|
3948
|
+
function resolveLifecycleOutcomeFromRunOutcome(outcome) {
|
|
3949
|
+
if (outcome?.status === "error") return SUBAGENT_ENDED_OUTCOME_ERROR;
|
|
3950
|
+
if (outcome?.status === "timeout") return SUBAGENT_ENDED_OUTCOME_TIMEOUT;
|
|
3951
|
+
return SUBAGENT_ENDED_OUTCOME_OK;
|
|
3952
|
+
}
|
|
3953
|
+
async function emitSubagentEndedHookOnce(params) {
|
|
3954
|
+
const runId = params.entry.runId.trim();
|
|
3955
|
+
if (!runId) return false;
|
|
3956
|
+
if (params.entry.endedHookEmittedAt) return false;
|
|
3957
|
+
if (params.inFlightRunIds.has(runId)) return false;
|
|
3958
|
+
params.inFlightRunIds.add(runId);
|
|
3959
|
+
try {
|
|
3960
|
+
const hookRunner = getGlobalHookRunner();
|
|
3961
|
+
if (hookRunner?.hasHooks("subagent_ended")) await hookRunner.runSubagentEnded({
|
|
3962
|
+
targetSessionKey: params.entry.childSessionKey,
|
|
3963
|
+
targetKind: SUBAGENT_TARGET_KIND_SUBAGENT,
|
|
3964
|
+
reason: params.reason,
|
|
3965
|
+
sendFarewell: params.sendFarewell,
|
|
3966
|
+
accountId: params.accountId,
|
|
3967
|
+
runId: params.entry.runId,
|
|
3968
|
+
endedAt: params.entry.endedAt,
|
|
3969
|
+
outcome: params.outcome,
|
|
3970
|
+
error: params.error
|
|
3971
|
+
}, {
|
|
3972
|
+
runId: params.entry.runId,
|
|
3973
|
+
childSessionKey: params.entry.childSessionKey,
|
|
3974
|
+
requesterSessionKey: params.entry.requesterSessionKey
|
|
3975
|
+
});
|
|
3976
|
+
params.entry.endedHookEmittedAt = Date.now();
|
|
3977
|
+
params.persist();
|
|
3978
|
+
return true;
|
|
3979
|
+
} catch {
|
|
3980
|
+
return false;
|
|
3981
|
+
} finally {
|
|
3982
|
+
params.inFlightRunIds.delete(runId);
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
|
|
3986
|
+
//#endregion
|
|
3987
|
+
//#region src/agents/subagent-registry-queries.ts
|
|
3988
|
+
function findRunIdsByChildSessionKeyFromRuns(runs, childSessionKey) {
|
|
3989
|
+
const key = childSessionKey.trim();
|
|
3990
|
+
if (!key) return [];
|
|
3991
|
+
const runIds = [];
|
|
3992
|
+
for (const [runId, entry] of runs.entries()) if (entry.childSessionKey === key) runIds.push(runId);
|
|
3993
|
+
return runIds;
|
|
3994
|
+
}
|
|
3995
|
+
function listRunsForRequesterFromRuns(runs, requesterSessionKey) {
|
|
3996
|
+
const key = requesterSessionKey.trim();
|
|
3997
|
+
if (!key) return [];
|
|
3998
|
+
return [...runs.values()].filter((entry) => entry.requesterSessionKey === key);
|
|
3999
|
+
}
|
|
4000
|
+
function resolveRequesterForChildSessionFromRuns(runs, childSessionKey) {
|
|
4001
|
+
const key = childSessionKey.trim();
|
|
4002
|
+
if (!key) return null;
|
|
4003
|
+
let best;
|
|
4004
|
+
for (const entry of runs.values()) {
|
|
4005
|
+
if (entry.childSessionKey !== key) continue;
|
|
4006
|
+
if (!best || entry.createdAt > best.createdAt) best = entry;
|
|
4007
|
+
}
|
|
4008
|
+
if (!best) return null;
|
|
4009
|
+
return {
|
|
4010
|
+
requesterSessionKey: best.requesterSessionKey,
|
|
4011
|
+
requesterOrigin: best.requesterOrigin
|
|
4012
|
+
};
|
|
4013
|
+
}
|
|
4014
|
+
function countActiveRunsForSessionFromRuns(runs, requesterSessionKey) {
|
|
4015
|
+
const key = requesterSessionKey.trim();
|
|
4016
|
+
if (!key) return 0;
|
|
4017
|
+
let count = 0;
|
|
4018
|
+
for (const entry of runs.values()) {
|
|
4019
|
+
if (entry.requesterSessionKey !== key) continue;
|
|
4020
|
+
if (typeof entry.endedAt === "number") continue;
|
|
4021
|
+
count += 1;
|
|
4022
|
+
}
|
|
4023
|
+
return count;
|
|
4024
|
+
}
|
|
4025
|
+
function countActiveDescendantRunsFromRuns(runs, rootSessionKey) {
|
|
4026
|
+
const root = rootSessionKey.trim();
|
|
4027
|
+
if (!root) return 0;
|
|
4028
|
+
const pending = [root];
|
|
4029
|
+
const visited = new Set([root]);
|
|
4030
|
+
let count = 0;
|
|
4031
|
+
while (pending.length > 0) {
|
|
4032
|
+
const requester = pending.shift();
|
|
4033
|
+
if (!requester) continue;
|
|
4034
|
+
for (const entry of runs.values()) {
|
|
4035
|
+
if (entry.requesterSessionKey !== requester) continue;
|
|
4036
|
+
if (typeof entry.endedAt !== "number") count += 1;
|
|
4037
|
+
const childKey = entry.childSessionKey.trim();
|
|
4038
|
+
if (!childKey || visited.has(childKey)) continue;
|
|
4039
|
+
visited.add(childKey);
|
|
4040
|
+
pending.push(childKey);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
return count;
|
|
4044
|
+
}
|
|
4045
|
+
function listDescendantRunsForRequesterFromRuns(runs, rootSessionKey) {
|
|
4046
|
+
const root = rootSessionKey.trim();
|
|
4047
|
+
if (!root) return [];
|
|
4048
|
+
const pending = [root];
|
|
4049
|
+
const visited = new Set([root]);
|
|
4050
|
+
const descendants = [];
|
|
4051
|
+
while (pending.length > 0) {
|
|
4052
|
+
const requester = pending.shift();
|
|
4053
|
+
if (!requester) continue;
|
|
4054
|
+
for (const entry of runs.values()) {
|
|
4055
|
+
if (entry.requesterSessionKey !== requester) continue;
|
|
4056
|
+
descendants.push(entry);
|
|
4057
|
+
const childKey = entry.childSessionKey.trim();
|
|
4058
|
+
if (!childKey || visited.has(childKey)) continue;
|
|
4059
|
+
visited.add(childKey);
|
|
4060
|
+
pending.push(childKey);
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
return descendants;
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
//#endregion
|
|
4067
|
+
//#region src/agents/subagent-registry.store.ts
|
|
4068
|
+
const REGISTRY_VERSION = 2;
|
|
4069
|
+
function resolveSubagentStateDir(env = process.env) {
|
|
4070
|
+
if (env.REMOTECLAW_STATE_DIR?.trim()) return resolveStateDir(env);
|
|
4071
|
+
if (env.VITEST || env.NODE_ENV === "test") return path.join(os.tmpdir(), "remoteclaw-test-state", String(process.pid));
|
|
4072
|
+
return resolveStateDir(env);
|
|
4073
|
+
}
|
|
4074
|
+
function resolveSubagentRegistryPath() {
|
|
4075
|
+
return path.join(resolveSubagentStateDir(process.env), "subagents", "runs.json");
|
|
4076
|
+
}
|
|
4077
|
+
function loadSubagentRegistryFromDisk() {
|
|
4078
|
+
const raw = loadJsonFile(resolveSubagentRegistryPath());
|
|
4079
|
+
if (!raw || typeof raw !== "object") return /* @__PURE__ */ new Map();
|
|
4080
|
+
const record = raw;
|
|
4081
|
+
if (record.version !== 1 && record.version !== 2) return /* @__PURE__ */ new Map();
|
|
4082
|
+
const runsRaw = record.runs;
|
|
4083
|
+
if (!runsRaw || typeof runsRaw !== "object") return /* @__PURE__ */ new Map();
|
|
4084
|
+
const out = /* @__PURE__ */ new Map();
|
|
4085
|
+
const isLegacy = record.version === 1;
|
|
4086
|
+
let migrated = false;
|
|
4087
|
+
for (const [runId, entry] of Object.entries(runsRaw)) {
|
|
4088
|
+
if (!entry || typeof entry !== "object") continue;
|
|
4089
|
+
const typed = entry;
|
|
4090
|
+
if (!typed.runId || typeof typed.runId !== "string") continue;
|
|
4091
|
+
const legacyCompletedAt = isLegacy && typeof typed.announceCompletedAt === "number" ? typed.announceCompletedAt : void 0;
|
|
4092
|
+
const cleanupCompletedAt = typeof typed.cleanupCompletedAt === "number" ? typed.cleanupCompletedAt : legacyCompletedAt;
|
|
4093
|
+
const cleanupHandled = typeof typed.cleanupHandled === "boolean" ? typed.cleanupHandled : isLegacy ? Boolean(typed.announceHandled ?? cleanupCompletedAt) : void 0;
|
|
4094
|
+
const requesterOrigin = normalizeDeliveryContext(typed.requesterOrigin ?? {
|
|
4095
|
+
channel: typeof typed.requesterChannel === "string" ? typed.requesterChannel : void 0,
|
|
4096
|
+
accountId: typeof typed.requesterAccountId === "string" ? typed.requesterAccountId : void 0
|
|
4097
|
+
});
|
|
4098
|
+
const { announceCompletedAt: _announceCompletedAt, announceHandled: _announceHandled, requesterChannel: _channel, requesterAccountId: _accountId, ...rest } = typed;
|
|
4099
|
+
out.set(runId, {
|
|
4100
|
+
...rest,
|
|
4101
|
+
requesterOrigin,
|
|
4102
|
+
cleanupCompletedAt,
|
|
4103
|
+
cleanupHandled,
|
|
4104
|
+
spawnMode: typed.spawnMode === "session" ? "session" : "run"
|
|
4105
|
+
});
|
|
4106
|
+
if (isLegacy) migrated = true;
|
|
4107
|
+
}
|
|
4108
|
+
if (migrated) try {
|
|
4109
|
+
saveSubagentRegistryToDisk(out);
|
|
4110
|
+
} catch {}
|
|
4111
|
+
return out;
|
|
4112
|
+
}
|
|
4113
|
+
function saveSubagentRegistryToDisk(runs) {
|
|
4114
|
+
const pathname = resolveSubagentRegistryPath();
|
|
4115
|
+
const serialized = {};
|
|
4116
|
+
for (const [runId, entry] of runs.entries()) serialized[runId] = entry;
|
|
4117
|
+
saveJsonFile(pathname, {
|
|
4118
|
+
version: REGISTRY_VERSION,
|
|
4119
|
+
runs: serialized
|
|
4120
|
+
});
|
|
4121
|
+
}
|
|
4122
|
+
|
|
4123
|
+
//#endregion
|
|
4124
|
+
//#region src/agents/subagent-registry-state.ts
|
|
4125
|
+
function persistSubagentRunsToDisk(runs) {
|
|
4126
|
+
try {
|
|
4127
|
+
saveSubagentRegistryToDisk(runs);
|
|
4128
|
+
} catch {}
|
|
4129
|
+
}
|
|
4130
|
+
function restoreSubagentRunsFromDisk(params) {
|
|
4131
|
+
const restored = loadSubagentRegistryFromDisk();
|
|
4132
|
+
if (restored.size === 0) return 0;
|
|
4133
|
+
let added = 0;
|
|
4134
|
+
for (const [runId, entry] of restored.entries()) {
|
|
4135
|
+
if (!runId || !entry) continue;
|
|
4136
|
+
if (params.mergeOnly && params.runs.has(runId)) continue;
|
|
4137
|
+
params.runs.set(runId, entry);
|
|
4138
|
+
added += 1;
|
|
4139
|
+
}
|
|
4140
|
+
return added;
|
|
4141
|
+
}
|
|
4142
|
+
function getSubagentRunsSnapshotForRead(inMemoryRuns) {
|
|
4143
|
+
const merged = /* @__PURE__ */ new Map();
|
|
4144
|
+
if (!(process.env.VITEST || false)) try {
|
|
4145
|
+
for (const [runId, entry] of loadSubagentRegistryFromDisk().entries()) merged.set(runId, entry);
|
|
4146
|
+
} catch {}
|
|
4147
|
+
for (const [runId, entry] of inMemoryRuns.entries()) merged.set(runId, entry);
|
|
4148
|
+
return merged;
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
//#endregion
|
|
4152
|
+
//#region src/agents/timeout.ts
|
|
4153
|
+
const DEFAULT_AGENT_TIMEOUT_SECONDS = 600;
|
|
4154
|
+
const MAX_SAFE_TIMEOUT_MS = 2147e6;
|
|
4155
|
+
const normalizeNumber = (value) => typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : void 0;
|
|
4156
|
+
function resolveAgentTimeoutSeconds(cfg) {
|
|
4157
|
+
const seconds = normalizeNumber(cfg?.agents?.defaults?.timeoutSeconds) ?? DEFAULT_AGENT_TIMEOUT_SECONDS;
|
|
4158
|
+
return Math.max(seconds, 1);
|
|
4159
|
+
}
|
|
4160
|
+
function resolveAgentTimeoutMs(opts) {
|
|
4161
|
+
const minMs = Math.max(normalizeNumber(opts.minMs) ?? 1, 1);
|
|
4162
|
+
const clampTimeoutMs = (valueMs) => Math.min(Math.max(valueMs, minMs), MAX_SAFE_TIMEOUT_MS);
|
|
4163
|
+
const defaultMs = clampTimeoutMs(resolveAgentTimeoutSeconds(opts.cfg) * 1e3);
|
|
4164
|
+
const NO_TIMEOUT_MS = MAX_SAFE_TIMEOUT_MS;
|
|
4165
|
+
const overrideMs = normalizeNumber(opts.overrideMs);
|
|
4166
|
+
if (overrideMs !== void 0) {
|
|
4167
|
+
if (overrideMs === 0) return NO_TIMEOUT_MS;
|
|
4168
|
+
if (overrideMs < 0) return defaultMs;
|
|
4169
|
+
return clampTimeoutMs(overrideMs);
|
|
4170
|
+
}
|
|
4171
|
+
const overrideSeconds = normalizeNumber(opts.overrideSeconds);
|
|
4172
|
+
if (overrideSeconds !== void 0) {
|
|
4173
|
+
if (overrideSeconds === 0) return NO_TIMEOUT_MS;
|
|
4174
|
+
if (overrideSeconds < 0) return defaultMs;
|
|
4175
|
+
return clampTimeoutMs(overrideSeconds * 1e3);
|
|
4176
|
+
}
|
|
4177
|
+
return defaultMs;
|
|
4178
|
+
}
|
|
4179
|
+
|
|
4180
|
+
//#endregion
|
|
4181
|
+
//#region src/agents/subagent-registry.ts
|
|
4182
|
+
var subagent_registry_exports = /* @__PURE__ */ __exportAll({
|
|
4183
|
+
clearSubagentRunSteerRestart: () => clearSubagentRunSteerRestart,
|
|
4184
|
+
countActiveDescendantRuns: () => countActiveDescendantRuns,
|
|
4185
|
+
countActiveRunsForSession: () => countActiveRunsForSession,
|
|
4186
|
+
initSubagentRegistry: () => initSubagentRegistry,
|
|
4187
|
+
isSubagentSessionRunActive: () => isSubagentSessionRunActive,
|
|
4188
|
+
listDescendantRunsForRequester: () => listDescendantRunsForRequester,
|
|
4189
|
+
listSubagentRunsForRequester: () => listSubagentRunsForRequester,
|
|
4190
|
+
markSubagentRunForSteerRestart: () => markSubagentRunForSteerRestart,
|
|
4191
|
+
markSubagentRunTerminated: () => markSubagentRunTerminated,
|
|
4192
|
+
registerSubagentRun: () => registerSubagentRun,
|
|
4193
|
+
replaceSubagentRunAfterSteer: () => replaceSubagentRunAfterSteer,
|
|
4194
|
+
resolveRequesterForChildSession: () => resolveRequesterForChildSession
|
|
4195
|
+
});
|
|
4196
|
+
const subagentRuns = /* @__PURE__ */ new Map();
|
|
4197
|
+
let sweeper = null;
|
|
4198
|
+
let listenerStarted = false;
|
|
4199
|
+
let listenerStop = null;
|
|
4200
|
+
var restoreAttempted = false;
|
|
4201
|
+
const SUBAGENT_ANNOUNCE_TIMEOUT_MS = 12e4;
|
|
4202
|
+
const MIN_ANNOUNCE_RETRY_DELAY_MS = 1e3;
|
|
4203
|
+
const MAX_ANNOUNCE_RETRY_DELAY_MS = 8e3;
|
|
4204
|
+
/**
|
|
4205
|
+
* Maximum number of announce delivery attempts before giving up.
|
|
4206
|
+
* Prevents infinite retry loops when `runSubagentAnnounceFlow` repeatedly
|
|
4207
|
+
* returns `false` due to stale state or transient conditions (#18264).
|
|
4208
|
+
*/
|
|
4209
|
+
const MAX_ANNOUNCE_RETRY_COUNT = 3;
|
|
4210
|
+
/**
|
|
4211
|
+
* Announce entries older than this are force-expired even if delivery never
|
|
4212
|
+
* succeeded. Guards against stale registry entries surviving gateway restarts.
|
|
4213
|
+
*/
|
|
4214
|
+
const ANNOUNCE_EXPIRY_MS = 5 * 6e4;
|
|
4215
|
+
function resolveAnnounceRetryDelayMs(retryCount) {
|
|
4216
|
+
const boundedRetryCount = Math.max(0, Math.min(retryCount, 10));
|
|
4217
|
+
const baseDelay = MIN_ANNOUNCE_RETRY_DELAY_MS * 2 ** Math.max(0, boundedRetryCount - 1);
|
|
4218
|
+
return Math.min(baseDelay, MAX_ANNOUNCE_RETRY_DELAY_MS);
|
|
4219
|
+
}
|
|
4220
|
+
function logAnnounceGiveUp(entry, reason) {
|
|
4221
|
+
const retryCount = entry.announceRetryCount ?? 0;
|
|
4222
|
+
const endedAgoMs = typeof entry.endedAt === "number" ? Math.max(0, Date.now() - entry.endedAt) : void 0;
|
|
4223
|
+
const endedAgoLabel = endedAgoMs != null ? `${Math.round(endedAgoMs / 1e3)}s` : "n/a";
|
|
4224
|
+
defaultRuntime.log(`[warn] Subagent announce give up (${reason}) run=${entry.runId} child=${entry.childSessionKey} requester=${entry.requesterSessionKey} retries=${retryCount} endedAgo=${endedAgoLabel}`);
|
|
4225
|
+
}
|
|
4226
|
+
function persistSubagentRuns() {
|
|
4227
|
+
persistSubagentRunsToDisk(subagentRuns);
|
|
4228
|
+
}
|
|
4229
|
+
function findSessionEntryByKey(store, sessionKey) {
|
|
4230
|
+
const direct = store[sessionKey];
|
|
4231
|
+
if (direct) return direct;
|
|
4232
|
+
const normalized = sessionKey.toLowerCase();
|
|
4233
|
+
for (const [key, entry] of Object.entries(store)) if (key.toLowerCase() === normalized) return entry;
|
|
4234
|
+
}
|
|
4235
|
+
function resolveSubagentRunOrphanReason(params) {
|
|
4236
|
+
const childSessionKey = params.entry.childSessionKey?.trim();
|
|
4237
|
+
if (!childSessionKey) return "missing-session-entry";
|
|
4238
|
+
try {
|
|
4239
|
+
const cfg = loadConfig();
|
|
4240
|
+
const agentId = resolveAgentIdFromSessionKey(childSessionKey);
|
|
4241
|
+
const storePath = resolveStorePath(cfg.session?.store, { agentId });
|
|
4242
|
+
let store = params.storeCache?.get(storePath);
|
|
4243
|
+
if (!store) {
|
|
4244
|
+
store = loadSessionStore(storePath);
|
|
4245
|
+
params.storeCache?.set(storePath, store);
|
|
4246
|
+
}
|
|
4247
|
+
const sessionEntry = findSessionEntryByKey(store, childSessionKey);
|
|
4248
|
+
if (!sessionEntry) return "missing-session-entry";
|
|
4249
|
+
if (typeof sessionEntry.sessionId !== "string" || !sessionEntry.sessionId.trim()) return "missing-session-id";
|
|
4250
|
+
return null;
|
|
4251
|
+
} catch {
|
|
4252
|
+
return null;
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
function reconcileOrphanedRun(params) {
|
|
4256
|
+
const now = Date.now();
|
|
4257
|
+
let changed = false;
|
|
4258
|
+
if (typeof params.entry.endedAt !== "number") {
|
|
4259
|
+
params.entry.endedAt = now;
|
|
4260
|
+
changed = true;
|
|
4261
|
+
}
|
|
4262
|
+
const orphanOutcome = {
|
|
4263
|
+
status: "error",
|
|
4264
|
+
error: `orphaned subagent run (${params.reason})`
|
|
4265
|
+
};
|
|
4266
|
+
if (!runOutcomesEqual(params.entry.outcome, orphanOutcome)) {
|
|
4267
|
+
params.entry.outcome = orphanOutcome;
|
|
4268
|
+
changed = true;
|
|
4269
|
+
}
|
|
4270
|
+
if (params.entry.endedReason !== SUBAGENT_ENDED_REASON_ERROR) {
|
|
4271
|
+
params.entry.endedReason = SUBAGENT_ENDED_REASON_ERROR;
|
|
4272
|
+
changed = true;
|
|
4273
|
+
}
|
|
4274
|
+
if (params.entry.cleanupHandled !== true) {
|
|
4275
|
+
params.entry.cleanupHandled = true;
|
|
4276
|
+
changed = true;
|
|
4277
|
+
}
|
|
4278
|
+
if (typeof params.entry.cleanupCompletedAt !== "number") {
|
|
4279
|
+
params.entry.cleanupCompletedAt = now;
|
|
4280
|
+
changed = true;
|
|
4281
|
+
}
|
|
4282
|
+
const removed = subagentRuns.delete(params.runId);
|
|
4283
|
+
resumedRuns.delete(params.runId);
|
|
4284
|
+
if (!removed && !changed) return false;
|
|
4285
|
+
defaultRuntime.log(`[warn] Subagent orphan run pruned source=${params.source} run=${params.runId} child=${params.entry.childSessionKey} reason=${params.reason}`);
|
|
4286
|
+
return true;
|
|
4287
|
+
}
|
|
4288
|
+
function reconcileOrphanedRestoredRuns() {
|
|
4289
|
+
const storeCache = /* @__PURE__ */ new Map();
|
|
4290
|
+
let changed = false;
|
|
4291
|
+
for (const [runId, entry] of subagentRuns.entries()) {
|
|
4292
|
+
const orphanReason = resolveSubagentRunOrphanReason({
|
|
4293
|
+
entry,
|
|
4294
|
+
storeCache
|
|
4295
|
+
});
|
|
4296
|
+
if (!orphanReason) continue;
|
|
4297
|
+
if (reconcileOrphanedRun({
|
|
4298
|
+
runId,
|
|
4299
|
+
entry,
|
|
4300
|
+
reason: orphanReason,
|
|
4301
|
+
source: "restore"
|
|
4302
|
+
})) changed = true;
|
|
4303
|
+
}
|
|
4304
|
+
return changed;
|
|
4305
|
+
}
|
|
4306
|
+
const resumedRuns = /* @__PURE__ */ new Set();
|
|
4307
|
+
const endedHookInFlightRunIds = /* @__PURE__ */ new Set();
|
|
4308
|
+
function suppressAnnounceForSteerRestart(entry) {
|
|
4309
|
+
return entry?.suppressAnnounceReason === "steer-restart";
|
|
4310
|
+
}
|
|
4311
|
+
function shouldKeepThreadBindingAfterRun(params) {
|
|
4312
|
+
if (params.reason === SUBAGENT_ENDED_REASON_KILLED) return false;
|
|
4313
|
+
return params.entry.spawnMode === "session";
|
|
4314
|
+
}
|
|
4315
|
+
function shouldEmitEndedHookForRun(params) {
|
|
4316
|
+
return !shouldKeepThreadBindingAfterRun(params);
|
|
4317
|
+
}
|
|
4318
|
+
async function emitSubagentEndedHookForRun(params) {
|
|
4319
|
+
const reason = params.reason ?? params.entry.endedReason ?? SUBAGENT_ENDED_REASON_COMPLETE;
|
|
4320
|
+
const outcome = resolveLifecycleOutcomeFromRunOutcome(params.entry.outcome);
|
|
4321
|
+
const error = params.entry.outcome?.status === "error" ? params.entry.outcome.error : void 0;
|
|
4322
|
+
await emitSubagentEndedHookOnce({
|
|
4323
|
+
entry: params.entry,
|
|
4324
|
+
reason,
|
|
4325
|
+
sendFarewell: params.sendFarewell,
|
|
4326
|
+
accountId: params.accountId ?? params.entry.requesterOrigin?.accountId,
|
|
4327
|
+
outcome,
|
|
4328
|
+
error,
|
|
4329
|
+
inFlightRunIds: endedHookInFlightRunIds,
|
|
4330
|
+
persist: persistSubagentRuns
|
|
4331
|
+
});
|
|
4332
|
+
}
|
|
4333
|
+
async function completeSubagentRun(params) {
|
|
4334
|
+
const entry = subagentRuns.get(params.runId);
|
|
4335
|
+
if (!entry) return;
|
|
4336
|
+
let mutated = false;
|
|
4337
|
+
const endedAt = typeof params.endedAt === "number" ? params.endedAt : Date.now();
|
|
4338
|
+
if (entry.endedAt !== endedAt) {
|
|
4339
|
+
entry.endedAt = endedAt;
|
|
4340
|
+
mutated = true;
|
|
4341
|
+
}
|
|
4342
|
+
if (!runOutcomesEqual(entry.outcome, params.outcome)) {
|
|
4343
|
+
entry.outcome = params.outcome;
|
|
4344
|
+
mutated = true;
|
|
4345
|
+
}
|
|
4346
|
+
if (entry.endedReason !== params.reason) {
|
|
4347
|
+
entry.endedReason = params.reason;
|
|
4348
|
+
mutated = true;
|
|
4349
|
+
}
|
|
4350
|
+
if (mutated) persistSubagentRuns();
|
|
4351
|
+
const suppressedForSteerRestart = suppressAnnounceForSteerRestart(entry);
|
|
4352
|
+
const shouldEmitEndedHook = !suppressedForSteerRestart && shouldEmitEndedHookForRun({
|
|
4353
|
+
entry,
|
|
4354
|
+
reason: params.reason
|
|
4355
|
+
});
|
|
4356
|
+
if (!(shouldEmitEndedHook && params.triggerCleanup && entry.expectsCompletionMessage === true && !suppressedForSteerRestart) && shouldEmitEndedHook) await emitSubagentEndedHookForRun({
|
|
4357
|
+
entry,
|
|
4358
|
+
reason: params.reason,
|
|
4359
|
+
sendFarewell: params.sendFarewell,
|
|
4360
|
+
accountId: params.accountId
|
|
4361
|
+
});
|
|
4362
|
+
if (!params.triggerCleanup) return;
|
|
4363
|
+
if (suppressedForSteerRestart) return;
|
|
4364
|
+
startSubagentAnnounceCleanupFlow(params.runId, entry);
|
|
4365
|
+
}
|
|
4366
|
+
function startSubagentAnnounceCleanupFlow(runId, entry) {
|
|
4367
|
+
if (!beginSubagentCleanup(runId)) return false;
|
|
4368
|
+
const requesterOrigin = normalizeDeliveryContext(entry.requesterOrigin);
|
|
4369
|
+
runSubagentAnnounceFlow({
|
|
4370
|
+
childSessionKey: entry.childSessionKey,
|
|
4371
|
+
childRunId: entry.runId,
|
|
4372
|
+
requesterSessionKey: entry.requesterSessionKey,
|
|
4373
|
+
requesterOrigin,
|
|
4374
|
+
requesterDisplayKey: entry.requesterDisplayKey,
|
|
4375
|
+
task: entry.task,
|
|
4376
|
+
timeoutMs: SUBAGENT_ANNOUNCE_TIMEOUT_MS,
|
|
4377
|
+
cleanup: entry.cleanup,
|
|
4378
|
+
waitForCompletion: false,
|
|
4379
|
+
startedAt: entry.startedAt,
|
|
4380
|
+
endedAt: entry.endedAt,
|
|
4381
|
+
label: entry.label,
|
|
4382
|
+
outcome: entry.outcome,
|
|
4383
|
+
spawnMode: entry.spawnMode,
|
|
4384
|
+
expectsCompletionMessage: entry.expectsCompletionMessage
|
|
4385
|
+
}).then((didAnnounce) => {
|
|
4386
|
+
finalizeSubagentCleanup(runId, entry.cleanup, didAnnounce);
|
|
4387
|
+
});
|
|
4388
|
+
return true;
|
|
4389
|
+
}
|
|
4390
|
+
function resumeSubagentRun(runId) {
|
|
4391
|
+
if (!runId || resumedRuns.has(runId)) return;
|
|
4392
|
+
const entry = subagentRuns.get(runId);
|
|
4393
|
+
if (!entry) return;
|
|
4394
|
+
const orphanReason = resolveSubagentRunOrphanReason({ entry });
|
|
4395
|
+
if (orphanReason) {
|
|
4396
|
+
if (reconcileOrphanedRun({
|
|
4397
|
+
runId,
|
|
4398
|
+
entry,
|
|
4399
|
+
reason: orphanReason,
|
|
4400
|
+
source: "resume"
|
|
4401
|
+
})) persistSubagentRuns();
|
|
4402
|
+
return;
|
|
4403
|
+
}
|
|
4404
|
+
if (entry.cleanupCompletedAt) return;
|
|
4405
|
+
if ((entry.announceRetryCount ?? 0) >= MAX_ANNOUNCE_RETRY_COUNT) {
|
|
4406
|
+
logAnnounceGiveUp(entry, "retry-limit");
|
|
4407
|
+
entry.cleanupCompletedAt = Date.now();
|
|
4408
|
+
persistSubagentRuns();
|
|
4409
|
+
return;
|
|
4410
|
+
}
|
|
4411
|
+
if (typeof entry.endedAt === "number" && Date.now() - entry.endedAt > ANNOUNCE_EXPIRY_MS) {
|
|
4412
|
+
logAnnounceGiveUp(entry, "expiry");
|
|
4413
|
+
entry.cleanupCompletedAt = Date.now();
|
|
4414
|
+
persistSubagentRuns();
|
|
4415
|
+
return;
|
|
4416
|
+
}
|
|
4417
|
+
const now = Date.now();
|
|
4418
|
+
const delayMs = resolveAnnounceRetryDelayMs(entry.announceRetryCount ?? 0);
|
|
4419
|
+
const earliestRetryAt = (entry.lastAnnounceRetryAt ?? 0) + delayMs;
|
|
4420
|
+
if (entry.expectsCompletionMessage === true && entry.lastAnnounceRetryAt && now < earliestRetryAt) {
|
|
4421
|
+
const waitMs = Math.max(1, earliestRetryAt - now);
|
|
4422
|
+
setTimeout(() => {
|
|
4423
|
+
resumeSubagentRun(runId);
|
|
4424
|
+
}, waitMs).unref?.();
|
|
4425
|
+
resumedRuns.add(runId);
|
|
4426
|
+
return;
|
|
4427
|
+
}
|
|
4428
|
+
if (typeof entry.endedAt === "number" && entry.endedAt > 0) {
|
|
4429
|
+
if (suppressAnnounceForSteerRestart(entry)) {
|
|
4430
|
+
resumedRuns.add(runId);
|
|
4431
|
+
return;
|
|
4432
|
+
}
|
|
4433
|
+
if (!startSubagentAnnounceCleanupFlow(runId, entry)) return;
|
|
4434
|
+
resumedRuns.add(runId);
|
|
4435
|
+
return;
|
|
4436
|
+
}
|
|
4437
|
+
waitForSubagentCompletion(runId, resolveSubagentWaitTimeoutMs(loadConfig(), entry.runTimeoutSeconds));
|
|
4438
|
+
resumedRuns.add(runId);
|
|
4439
|
+
}
|
|
4440
|
+
function restoreSubagentRunsOnce() {
|
|
4441
|
+
if (restoreAttempted) return;
|
|
4442
|
+
restoreAttempted = true;
|
|
4443
|
+
try {
|
|
4444
|
+
if (restoreSubagentRunsFromDisk({
|
|
4445
|
+
runs: subagentRuns,
|
|
4446
|
+
mergeOnly: true
|
|
4447
|
+
}) === 0) return;
|
|
4448
|
+
if (reconcileOrphanedRestoredRuns()) persistSubagentRuns();
|
|
4449
|
+
if (subagentRuns.size === 0) return;
|
|
4450
|
+
ensureListener();
|
|
4451
|
+
if ([...subagentRuns.values()].some((entry) => entry.archiveAtMs)) startSweeper();
|
|
4452
|
+
for (const runId of subagentRuns.keys()) resumeSubagentRun(runId);
|
|
4453
|
+
} catch {}
|
|
4454
|
+
}
|
|
4455
|
+
function resolveArchiveAfterMs(cfg) {
|
|
4456
|
+
const minutes = (cfg ?? loadConfig()).agents?.defaults?.subagents?.archiveAfterMinutes ?? 60;
|
|
4457
|
+
if (!Number.isFinite(minutes) || minutes <= 0) return;
|
|
4458
|
+
return Math.max(1, Math.floor(minutes)) * 6e4;
|
|
4459
|
+
}
|
|
4460
|
+
function resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds) {
|
|
4461
|
+
return resolveAgentTimeoutMs({
|
|
4462
|
+
cfg,
|
|
4463
|
+
overrideSeconds: runTimeoutSeconds ?? 0
|
|
4464
|
+
});
|
|
4465
|
+
}
|
|
4466
|
+
function startSweeper() {
|
|
4467
|
+
if (sweeper) return;
|
|
4468
|
+
sweeper = setInterval(() => {
|
|
4469
|
+
sweepSubagentRuns();
|
|
4470
|
+
}, 6e4);
|
|
4471
|
+
sweeper.unref?.();
|
|
4472
|
+
}
|
|
4473
|
+
function stopSweeper() {
|
|
4474
|
+
if (!sweeper) return;
|
|
4475
|
+
clearInterval(sweeper);
|
|
4476
|
+
sweeper = null;
|
|
4477
|
+
}
|
|
4478
|
+
async function sweepSubagentRuns() {
|
|
4479
|
+
const now = Date.now();
|
|
4480
|
+
let mutated = false;
|
|
4481
|
+
for (const [runId, entry] of subagentRuns.entries()) {
|
|
4482
|
+
if (!entry.archiveAtMs || entry.archiveAtMs > now) continue;
|
|
4483
|
+
subagentRuns.delete(runId);
|
|
4484
|
+
mutated = true;
|
|
4485
|
+
try {
|
|
4486
|
+
await callGateway({
|
|
4487
|
+
method: "sessions.delete",
|
|
4488
|
+
params: {
|
|
4489
|
+
key: entry.childSessionKey,
|
|
4490
|
+
deleteTranscript: true,
|
|
4491
|
+
emitLifecycleHooks: false
|
|
4492
|
+
},
|
|
4493
|
+
timeoutMs: 1e4
|
|
4494
|
+
});
|
|
4495
|
+
} catch {}
|
|
4496
|
+
}
|
|
4497
|
+
if (mutated) persistSubagentRuns();
|
|
4498
|
+
if (subagentRuns.size === 0) stopSweeper();
|
|
4499
|
+
}
|
|
4500
|
+
function ensureListener() {
|
|
4501
|
+
if (listenerStarted) return;
|
|
4502
|
+
listenerStarted = true;
|
|
4503
|
+
listenerStop = onAgentEvent((evt) => {
|
|
4504
|
+
(async () => {
|
|
4505
|
+
if (!evt || evt.stream !== "lifecycle") return;
|
|
4506
|
+
const entry = subagentRuns.get(evt.runId);
|
|
4507
|
+
if (!entry) return;
|
|
4508
|
+
const phase = evt.data?.phase;
|
|
4509
|
+
if (phase === "start") {
|
|
4510
|
+
const startedAt = typeof evt.data?.startedAt === "number" ? evt.data.startedAt : void 0;
|
|
4511
|
+
if (startedAt) {
|
|
4512
|
+
entry.startedAt = startedAt;
|
|
4513
|
+
persistSubagentRuns();
|
|
4514
|
+
}
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4517
|
+
if (phase !== "end" && phase !== "error") return;
|
|
4518
|
+
const endedAt = typeof evt.data?.endedAt === "number" ? evt.data.endedAt : Date.now();
|
|
4519
|
+
const error = typeof evt.data?.error === "string" ? evt.data.error : void 0;
|
|
4520
|
+
const outcome = phase === "error" ? {
|
|
4521
|
+
status: "error",
|
|
4522
|
+
error
|
|
4523
|
+
} : evt.data?.aborted ? { status: "timeout" } : { status: "ok" };
|
|
4524
|
+
await completeSubagentRun({
|
|
4525
|
+
runId: evt.runId,
|
|
4526
|
+
endedAt,
|
|
4527
|
+
outcome,
|
|
4528
|
+
reason: phase === "error" ? SUBAGENT_ENDED_REASON_ERROR : SUBAGENT_ENDED_REASON_COMPLETE,
|
|
4529
|
+
sendFarewell: true,
|
|
4530
|
+
accountId: entry.requesterOrigin?.accountId,
|
|
4531
|
+
triggerCleanup: true
|
|
4532
|
+
});
|
|
4533
|
+
})();
|
|
4534
|
+
});
|
|
4535
|
+
}
|
|
4536
|
+
async function finalizeSubagentCleanup(runId, cleanup, didAnnounce) {
|
|
4537
|
+
const entry = subagentRuns.get(runId);
|
|
4538
|
+
if (!entry) return;
|
|
4539
|
+
if (didAnnounce) {
|
|
4540
|
+
await emitCompletionEndedHookIfNeeded(entry, resolveCleanupCompletionReason(entry));
|
|
4541
|
+
completeCleanupBookkeeping({
|
|
4542
|
+
runId,
|
|
4543
|
+
entry,
|
|
4544
|
+
cleanup,
|
|
4545
|
+
completedAt: Date.now()
|
|
4546
|
+
});
|
|
4547
|
+
return;
|
|
4548
|
+
}
|
|
4549
|
+
const now = Date.now();
|
|
4550
|
+
const deferredDecision = resolveDeferredCleanupDecision({
|
|
4551
|
+
entry,
|
|
4552
|
+
now,
|
|
4553
|
+
activeDescendantRuns: Math.max(0, countActiveDescendantRuns(entry.childSessionKey)),
|
|
4554
|
+
announceExpiryMs: ANNOUNCE_EXPIRY_MS,
|
|
4555
|
+
maxAnnounceRetryCount: MAX_ANNOUNCE_RETRY_COUNT,
|
|
4556
|
+
deferDescendantDelayMs: MIN_ANNOUNCE_RETRY_DELAY_MS,
|
|
4557
|
+
resolveAnnounceRetryDelayMs
|
|
4558
|
+
});
|
|
4559
|
+
if (deferredDecision.kind === "defer-descendants") {
|
|
4560
|
+
entry.lastAnnounceRetryAt = now;
|
|
4561
|
+
entry.cleanupHandled = false;
|
|
4562
|
+
resumedRuns.delete(runId);
|
|
4563
|
+
persistSubagentRuns();
|
|
4564
|
+
setTimeout(() => {
|
|
4565
|
+
resumeSubagentRun(runId);
|
|
4566
|
+
}, deferredDecision.delayMs).unref?.();
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
4569
|
+
if (deferredDecision.retryCount != null) {
|
|
4570
|
+
entry.announceRetryCount = deferredDecision.retryCount;
|
|
4571
|
+
entry.lastAnnounceRetryAt = now;
|
|
4572
|
+
}
|
|
4573
|
+
if (deferredDecision.kind === "give-up") {
|
|
4574
|
+
await emitCompletionEndedHookIfNeeded(entry, resolveCleanupCompletionReason(entry));
|
|
4575
|
+
logAnnounceGiveUp(entry, deferredDecision.reason);
|
|
4576
|
+
completeCleanupBookkeeping({
|
|
4577
|
+
runId,
|
|
4578
|
+
entry,
|
|
4579
|
+
cleanup: "keep",
|
|
4580
|
+
completedAt: now
|
|
4581
|
+
});
|
|
4582
|
+
return;
|
|
4583
|
+
}
|
|
4584
|
+
entry.cleanupHandled = false;
|
|
4585
|
+
resumedRuns.delete(runId);
|
|
4586
|
+
persistSubagentRuns();
|
|
4587
|
+
if (deferredDecision.resumeDelayMs == null) return;
|
|
4588
|
+
setTimeout(() => {
|
|
4589
|
+
resumeSubagentRun(runId);
|
|
4590
|
+
}, deferredDecision.resumeDelayMs).unref?.();
|
|
4591
|
+
}
|
|
4592
|
+
async function emitCompletionEndedHookIfNeeded(entry, reason) {
|
|
4593
|
+
if (entry.expectsCompletionMessage === true && shouldEmitEndedHookForRun({
|
|
4594
|
+
entry,
|
|
4595
|
+
reason
|
|
4596
|
+
})) await emitSubagentEndedHookForRun({
|
|
4597
|
+
entry,
|
|
4598
|
+
reason,
|
|
4599
|
+
sendFarewell: true
|
|
4600
|
+
});
|
|
4601
|
+
}
|
|
4602
|
+
function completeCleanupBookkeeping(params) {
|
|
4603
|
+
if (params.cleanup === "delete") {
|
|
4604
|
+
subagentRuns.delete(params.runId);
|
|
4605
|
+
persistSubagentRuns();
|
|
4606
|
+
retryDeferredCompletedAnnounces(params.runId);
|
|
4607
|
+
return;
|
|
4608
|
+
}
|
|
4609
|
+
params.entry.cleanupCompletedAt = params.completedAt;
|
|
4610
|
+
persistSubagentRuns();
|
|
4611
|
+
retryDeferredCompletedAnnounces(params.runId);
|
|
4612
|
+
}
|
|
4613
|
+
function retryDeferredCompletedAnnounces(excludeRunId) {
|
|
4614
|
+
const now = Date.now();
|
|
4615
|
+
for (const [runId, entry] of subagentRuns.entries()) {
|
|
4616
|
+
if (excludeRunId && runId === excludeRunId) continue;
|
|
4617
|
+
if (typeof entry.endedAt !== "number") continue;
|
|
4618
|
+
if (entry.cleanupCompletedAt || entry.cleanupHandled) continue;
|
|
4619
|
+
if (suppressAnnounceForSteerRestart(entry)) continue;
|
|
4620
|
+
if (now - (entry.endedAt ?? now) > ANNOUNCE_EXPIRY_MS) {
|
|
4621
|
+
logAnnounceGiveUp(entry, "expiry");
|
|
4622
|
+
entry.cleanupCompletedAt = now;
|
|
4623
|
+
persistSubagentRuns();
|
|
4624
|
+
continue;
|
|
4625
|
+
}
|
|
4626
|
+
resumedRuns.delete(runId);
|
|
4627
|
+
resumeSubagentRun(runId);
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
function beginSubagentCleanup(runId) {
|
|
4631
|
+
const entry = subagentRuns.get(runId);
|
|
4632
|
+
if (!entry) return false;
|
|
4633
|
+
if (entry.cleanupCompletedAt) return false;
|
|
4634
|
+
if (entry.cleanupHandled) return false;
|
|
4635
|
+
entry.cleanupHandled = true;
|
|
4636
|
+
persistSubagentRuns();
|
|
4637
|
+
return true;
|
|
4638
|
+
}
|
|
4639
|
+
function markSubagentRunForSteerRestart(runId) {
|
|
4640
|
+
const key = runId.trim();
|
|
4641
|
+
if (!key) return false;
|
|
4642
|
+
const entry = subagentRuns.get(key);
|
|
4643
|
+
if (!entry) return false;
|
|
4644
|
+
if (entry.suppressAnnounceReason === "steer-restart") return true;
|
|
4645
|
+
entry.suppressAnnounceReason = "steer-restart";
|
|
4646
|
+
persistSubagentRuns();
|
|
4647
|
+
return true;
|
|
4648
|
+
}
|
|
4649
|
+
function clearSubagentRunSteerRestart(runId) {
|
|
4650
|
+
const key = runId.trim();
|
|
4651
|
+
if (!key) return false;
|
|
4652
|
+
const entry = subagentRuns.get(key);
|
|
4653
|
+
if (!entry) return false;
|
|
4654
|
+
if (entry.suppressAnnounceReason !== "steer-restart") return true;
|
|
4655
|
+
entry.suppressAnnounceReason = void 0;
|
|
4656
|
+
persistSubagentRuns();
|
|
4657
|
+
resumedRuns.delete(key);
|
|
4658
|
+
if (typeof entry.endedAt === "number" && !entry.cleanupCompletedAt) resumeSubagentRun(key);
|
|
4659
|
+
return true;
|
|
4660
|
+
}
|
|
4661
|
+
function replaceSubagentRunAfterSteer(params) {
|
|
4662
|
+
const previousRunId = params.previousRunId.trim();
|
|
4663
|
+
const nextRunId = params.nextRunId.trim();
|
|
4664
|
+
if (!previousRunId || !nextRunId) return false;
|
|
4665
|
+
const source = subagentRuns.get(previousRunId) ?? params.fallback;
|
|
4666
|
+
if (!source) return false;
|
|
4667
|
+
if (previousRunId !== nextRunId) {
|
|
4668
|
+
subagentRuns.delete(previousRunId);
|
|
4669
|
+
resumedRuns.delete(previousRunId);
|
|
4670
|
+
}
|
|
4671
|
+
const now = Date.now();
|
|
4672
|
+
const cfg = loadConfig();
|
|
4673
|
+
const archiveAfterMs = resolveArchiveAfterMs(cfg);
|
|
4674
|
+
const spawnMode = source.spawnMode === "session" ? "session" : "run";
|
|
4675
|
+
const archiveAtMs = spawnMode === "session" ? void 0 : archiveAfterMs ? now + archiveAfterMs : void 0;
|
|
4676
|
+
const runTimeoutSeconds = params.runTimeoutSeconds ?? source.runTimeoutSeconds ?? 0;
|
|
4677
|
+
const waitTimeoutMs = resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds);
|
|
4678
|
+
const next = {
|
|
4679
|
+
...source,
|
|
4680
|
+
runId: nextRunId,
|
|
4681
|
+
startedAt: now,
|
|
4682
|
+
endedAt: void 0,
|
|
4683
|
+
endedReason: void 0,
|
|
4684
|
+
endedHookEmittedAt: void 0,
|
|
4685
|
+
outcome: void 0,
|
|
4686
|
+
cleanupCompletedAt: void 0,
|
|
4687
|
+
cleanupHandled: false,
|
|
4688
|
+
suppressAnnounceReason: void 0,
|
|
4689
|
+
announceRetryCount: void 0,
|
|
4690
|
+
lastAnnounceRetryAt: void 0,
|
|
4691
|
+
spawnMode,
|
|
4692
|
+
archiveAtMs,
|
|
4693
|
+
runTimeoutSeconds
|
|
4694
|
+
};
|
|
4695
|
+
subagentRuns.set(nextRunId, next);
|
|
4696
|
+
ensureListener();
|
|
4697
|
+
persistSubagentRuns();
|
|
4698
|
+
if (archiveAtMs) startSweeper();
|
|
4699
|
+
waitForSubagentCompletion(nextRunId, waitTimeoutMs);
|
|
4700
|
+
return true;
|
|
4701
|
+
}
|
|
4702
|
+
function registerSubagentRun(params) {
|
|
4703
|
+
const now = Date.now();
|
|
4704
|
+
const cfg = loadConfig();
|
|
4705
|
+
const archiveAfterMs = resolveArchiveAfterMs(cfg);
|
|
4706
|
+
const spawnMode = params.spawnMode === "session" ? "session" : "run";
|
|
4707
|
+
const archiveAtMs = spawnMode === "session" ? void 0 : archiveAfterMs ? now + archiveAfterMs : void 0;
|
|
4708
|
+
const runTimeoutSeconds = params.runTimeoutSeconds ?? 0;
|
|
4709
|
+
const waitTimeoutMs = resolveSubagentWaitTimeoutMs(cfg, runTimeoutSeconds);
|
|
4710
|
+
const requesterOrigin = normalizeDeliveryContext(params.requesterOrigin);
|
|
4711
|
+
subagentRuns.set(params.runId, {
|
|
4712
|
+
runId: params.runId,
|
|
4713
|
+
childSessionKey: params.childSessionKey,
|
|
4714
|
+
requesterSessionKey: params.requesterSessionKey,
|
|
4715
|
+
requesterOrigin,
|
|
4716
|
+
requesterDisplayKey: params.requesterDisplayKey,
|
|
4717
|
+
task: params.task,
|
|
4718
|
+
cleanup: params.cleanup,
|
|
4719
|
+
expectsCompletionMessage: params.expectsCompletionMessage,
|
|
4720
|
+
spawnMode,
|
|
4721
|
+
label: params.label,
|
|
4722
|
+
model: params.model,
|
|
4723
|
+
runTimeoutSeconds,
|
|
4724
|
+
createdAt: now,
|
|
4725
|
+
startedAt: now,
|
|
4726
|
+
archiveAtMs,
|
|
4727
|
+
cleanupHandled: false
|
|
4728
|
+
});
|
|
4729
|
+
ensureListener();
|
|
4730
|
+
persistSubagentRuns();
|
|
4731
|
+
if (archiveAtMs) startSweeper();
|
|
4732
|
+
waitForSubagentCompletion(params.runId, waitTimeoutMs);
|
|
4733
|
+
}
|
|
4734
|
+
async function waitForSubagentCompletion(runId, waitTimeoutMs) {
|
|
4735
|
+
try {
|
|
4736
|
+
const timeoutMs = Math.max(1, Math.floor(waitTimeoutMs));
|
|
4737
|
+
const wait = await callGateway({
|
|
4738
|
+
method: "agent.wait",
|
|
4739
|
+
params: {
|
|
4740
|
+
runId,
|
|
4741
|
+
timeoutMs
|
|
4742
|
+
},
|
|
4743
|
+
timeoutMs: timeoutMs + 1e4
|
|
4744
|
+
});
|
|
4745
|
+
if (wait?.status !== "ok" && wait?.status !== "error" && wait?.status !== "timeout") return;
|
|
4746
|
+
const entry = subagentRuns.get(runId);
|
|
4747
|
+
if (!entry) return;
|
|
4748
|
+
let mutated = false;
|
|
4749
|
+
if (typeof wait.startedAt === "number") {
|
|
4750
|
+
entry.startedAt = wait.startedAt;
|
|
4751
|
+
mutated = true;
|
|
4752
|
+
}
|
|
4753
|
+
if (typeof wait.endedAt === "number") {
|
|
4754
|
+
entry.endedAt = wait.endedAt;
|
|
4755
|
+
mutated = true;
|
|
4756
|
+
}
|
|
4757
|
+
if (!entry.endedAt) {
|
|
4758
|
+
entry.endedAt = Date.now();
|
|
4759
|
+
mutated = true;
|
|
4760
|
+
}
|
|
4761
|
+
const waitError = typeof wait.error === "string" ? wait.error : void 0;
|
|
4762
|
+
const outcome = wait.status === "error" ? {
|
|
4763
|
+
status: "error",
|
|
4764
|
+
error: waitError
|
|
4765
|
+
} : wait.status === "timeout" ? { status: "timeout" } : { status: "ok" };
|
|
4766
|
+
if (!runOutcomesEqual(entry.outcome, outcome)) {
|
|
4767
|
+
entry.outcome = outcome;
|
|
4768
|
+
mutated = true;
|
|
4769
|
+
}
|
|
4770
|
+
if (mutated) persistSubagentRuns();
|
|
4771
|
+
await completeSubagentRun({
|
|
4772
|
+
runId,
|
|
4773
|
+
endedAt: entry.endedAt,
|
|
4774
|
+
outcome,
|
|
4775
|
+
reason: wait.status === "error" ? SUBAGENT_ENDED_REASON_ERROR : SUBAGENT_ENDED_REASON_COMPLETE,
|
|
4776
|
+
sendFarewell: true,
|
|
4777
|
+
accountId: entry.requesterOrigin?.accountId,
|
|
4778
|
+
triggerCleanup: true
|
|
4779
|
+
});
|
|
4780
|
+
} catch {}
|
|
4781
|
+
}
|
|
4782
|
+
function findRunIdsByChildSessionKey(childSessionKey) {
|
|
4783
|
+
return findRunIdsByChildSessionKeyFromRuns(subagentRuns, childSessionKey);
|
|
4784
|
+
}
|
|
4785
|
+
function resolveRequesterForChildSession(childSessionKey) {
|
|
4786
|
+
const resolved = resolveRequesterForChildSessionFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), childSessionKey);
|
|
4787
|
+
if (!resolved) return null;
|
|
4788
|
+
return {
|
|
4789
|
+
requesterSessionKey: resolved.requesterSessionKey,
|
|
4790
|
+
requesterOrigin: normalizeDeliveryContext(resolved.requesterOrigin)
|
|
4791
|
+
};
|
|
4792
|
+
}
|
|
4793
|
+
function isSubagentSessionRunActive(childSessionKey) {
|
|
4794
|
+
const runIds = findRunIdsByChildSessionKey(childSessionKey);
|
|
4795
|
+
for (const runId of runIds) {
|
|
4796
|
+
const entry = subagentRuns.get(runId);
|
|
4797
|
+
if (!entry) continue;
|
|
4798
|
+
if (typeof entry.endedAt !== "number") return true;
|
|
4799
|
+
}
|
|
4800
|
+
return false;
|
|
4801
|
+
}
|
|
4802
|
+
function markSubagentRunTerminated(params) {
|
|
4803
|
+
const runIds = /* @__PURE__ */ new Set();
|
|
4804
|
+
if (typeof params.runId === "string" && params.runId.trim()) runIds.add(params.runId.trim());
|
|
4805
|
+
if (typeof params.childSessionKey === "string" && params.childSessionKey.trim()) for (const runId of findRunIdsByChildSessionKey(params.childSessionKey)) runIds.add(runId);
|
|
4806
|
+
if (runIds.size === 0) return 0;
|
|
4807
|
+
const now = Date.now();
|
|
4808
|
+
const reason = params.reason?.trim() || "killed";
|
|
4809
|
+
let updated = 0;
|
|
4810
|
+
const entriesByChildSessionKey = /* @__PURE__ */ new Map();
|
|
4811
|
+
for (const runId of runIds) {
|
|
4812
|
+
const entry = subagentRuns.get(runId);
|
|
4813
|
+
if (!entry) continue;
|
|
4814
|
+
if (typeof entry.endedAt === "number") continue;
|
|
4815
|
+
entry.endedAt = now;
|
|
4816
|
+
entry.outcome = {
|
|
4817
|
+
status: "error",
|
|
4818
|
+
error: reason
|
|
4819
|
+
};
|
|
4820
|
+
entry.endedReason = SUBAGENT_ENDED_REASON_KILLED;
|
|
4821
|
+
entry.cleanupHandled = true;
|
|
4822
|
+
entry.cleanupCompletedAt = now;
|
|
4823
|
+
entry.suppressAnnounceReason = "killed";
|
|
4824
|
+
if (!entriesByChildSessionKey.has(entry.childSessionKey)) entriesByChildSessionKey.set(entry.childSessionKey, entry);
|
|
4825
|
+
updated += 1;
|
|
4826
|
+
}
|
|
4827
|
+
if (updated > 0) {
|
|
4828
|
+
persistSubagentRuns();
|
|
4829
|
+
for (const entry of entriesByChildSessionKey.values()) emitSubagentEndedHookOnce({
|
|
4830
|
+
entry,
|
|
4831
|
+
reason: SUBAGENT_ENDED_REASON_KILLED,
|
|
4832
|
+
sendFarewell: true,
|
|
4833
|
+
outcome: SUBAGENT_ENDED_OUTCOME_KILLED,
|
|
4834
|
+
error: reason,
|
|
4835
|
+
inFlightRunIds: endedHookInFlightRunIds,
|
|
4836
|
+
persist: persistSubagentRuns
|
|
4837
|
+
}).catch(() => {});
|
|
4838
|
+
}
|
|
4839
|
+
return updated;
|
|
4840
|
+
}
|
|
4841
|
+
function listSubagentRunsForRequester(requesterSessionKey) {
|
|
4842
|
+
return listRunsForRequesterFromRuns(subagentRuns, requesterSessionKey);
|
|
4843
|
+
}
|
|
4844
|
+
function countActiveRunsForSession(requesterSessionKey) {
|
|
4845
|
+
return countActiveRunsForSessionFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), requesterSessionKey);
|
|
4846
|
+
}
|
|
4847
|
+
function countActiveDescendantRuns(rootSessionKey) {
|
|
4848
|
+
return countActiveDescendantRunsFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), rootSessionKey);
|
|
4849
|
+
}
|
|
4850
|
+
function listDescendantRunsForRequester(rootSessionKey) {
|
|
4851
|
+
return listDescendantRunsForRequesterFromRuns(getSubagentRunsSnapshotForRead(subagentRuns), rootSessionKey);
|
|
4852
|
+
}
|
|
4853
|
+
function initSubagentRegistry() {
|
|
4854
|
+
restoreSubagentRunsOnce();
|
|
4855
|
+
}
|
|
4856
|
+
|
|
4857
|
+
//#endregion
|
|
4858
|
+
export { normalizeReplyPayload as $, stripReasoningTagsFromText as A, resolveMainSessionAlias as B, runAgentStep as C, sanitizeTextContent as D, extractAssistantText as E, resolveEffectiveSessionToolsVisibility as F, registerSessionBindingAdapter as G, shouldResolveSessionIdInput as H, resolveSandboxedSessionToolContext as I, enqueueFollowupRun as J, unregisterSessionBindingAdapter as K, isResolvedSessionVisibleToRequester as L, isInsideCode as M, createAgentToAgentPolicy as N, stripToolMessages as O, createSessionVisibilityGuard as P, routeReply as Q, resolveDisplaySessionKey as R, readLatestAssistantReply as S, deriveChannel as T, getSubagentDepthFromSessionStore as U, resolveSessionReference as V, extractTextFromChatContent as W, scheduleFollowupDrain as X, getFollowupQueueDepth as Y, isRoutableChannel as Z, buildAgentToAgentReplyContext as _, emitDiagnosticEvent as _t, listDescendantRunsForRequester as a, getTotalQueueSize as at, resolveAnnounceTargetFromKey as b, markSubagentRunTerminated as c, waitForActiveTasks as ct, subagent_registry_exports as d, logSessionStateChange as dt, createReceiptCard as et, resolveAgentTimeoutMs as f, logWebhookError as ft, buildAgentToAgentMessageContext as g, stopDiagnosticHeartbeat as gt, buildAgentToAgentAnnounceContext as h, startDiagnosticHeartbeat as ht, initSubagentRegistry as i, getQueueSize as it, findCodeRegions as j, formatReasoningMessage as k, registerSubagentRun as l, logMessageProcessed as lt, runSubagentAnnounceFlow as m, logWebhookReceived as mt, countActiveDescendantRuns as n, clearCommandLane as nt, listSubagentRunsForRequester as o, resetAllLanes as ot, buildSubagentSystemPrompt as p, logWebhookProcessed as pt, resolveQueueSettings as q, countActiveRunsForSession as r, getActiveTaskCount as rt, markSubagentRunForSteerRestart as s, setCommandLaneConcurrency as st, clearSubagentRunSteerRestart as t, clearSessionQueues as tt, replaceSubagentRunAfterSteer as u, logMessageQueued as ut, isAnnounceSkip as v, isDiagnosticsEnabled as vt, classifySessionKind as w, resolvePingPongTurns as x, isReplySkip as y, extractQueueDirective as yt, resolveInternalSessionKey as z };
|