activeclaw 2026.2.12 → 2026.2.13
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 +37 -0
- package/dist/{accounts-DbzMEfKN.js → accounts-DCDeFTra.js} +2 -2
- package/dist/{accounts-DimKrt7j.js → accounts-DeqIQjo1.js} +2 -2
- package/dist/{acp-cli-Cs1ai4XO.js → acp-cli-CeYI4XRd.js} +15 -16
- package/dist/{acp-cli-oV2dodPg.js → acp-cli-rNbGXICg.js} +14 -15
- package/dist/{agent-BndgzkUe.js → agent-BvNJF5QL.js} +19 -16
- package/dist/{agent-DZvDwqnd.js → agent-CyMxTyrG.js} +20 -17
- package/dist/{agent-scope-rXQ7WARN.js → agent-scope-BIEhVP4_.js} +1 -1
- package/dist/{agent-scope---6LLHj0.js → agent-scope-CQCus0rI.js} +2 -2
- package/dist/{agent-scope-RCSw6gHy.js → agent-scope-CsRbLH4l.js} +3 -3
- package/dist/{agent-scope-CN8DM4Xb.js → agent-scope-DPIFau3f.js} +1 -1
- package/dist/{audio-preflight-SZRntkxo.js → audio-preflight-BU8W7uxc.js} +10 -10
- package/dist/{audio-preflight-ClVNINDs.js → audio-preflight-CGsumMzb.js} +10 -10
- package/dist/{audio-preflight-txAP3v-C.js → audio-preflight-SLmkJI6-.js} +22 -22
- package/dist/{audio-preflight-BP6s-UPp.js → audio-preflight-jZc5mFCZ.js} +23 -23
- package/dist/{audit-CQzrm61N.js → audit-Dmww_503.js} +70 -18
- package/dist/{audit-DMH3CSXY.js → audit-wPu26VMb.js} +72 -20
- package/dist/{tailscale-DU6DgqVy.js → auth-9x3lqfIY.js} +208 -3
- package/dist/{tailscale-DHfcfRCx.js → auth-CQNl_IaI.js} +190 -3
- package/dist/{auth-health-BB3e3OmN.js → auth-health-C4L4FGBA.js} +1 -1
- package/dist/{auth-health-zZ9dnQGC.js → auth-health-j6epgQbq.js} +1 -1
- package/dist/{auth-profiles-CcJ3hrog.js → auth-profiles-ByNs3eEm.js} +60 -22
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +19 -16
- package/dist/bundled/session-memory/handler.js +16 -15
- package/dist/{call-Yxns4CVq.js → call-DVYCIV8m.js} +5 -5
- package/dist/{call-C9az806y.js → call-SolyGS1r.js} +4 -4
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-options-CjXPwMWu.js → channel-options-BwC2yQcR.js} +4 -4
- package/dist/{channel-options-CX4iYQfR.js → channel-options-Cq9BVDkP.js} +7 -7
- package/dist/{channel-selection-BoQ7GurB.js → channel-selection-D4D6ImhN.js} +2 -2
- package/dist/{channel-selection-C78IwbD-.js → channel-selection-MZAHm4U8.js} +2 -2
- package/dist/{channels-cli-DUHsmX3q.js → channels-cli-9Dsk9Qm7.js} +53 -51
- package/dist/{channels-cli-BXMQPB4x.js → channels-cli-BJUppQll.js} +52 -50
- package/dist/{channels-status-issues-Ca9--azp.js → channels-status-issues-D7GSV1GS.js} +1 -1
- package/dist/{channels-status-issues-CbULFg2X.js → channels-status-issues-DDAWeT-6.js} +1 -1
- package/dist/{chrome-svgmQ8T_.js → chrome-BfB6JdKF.js} +2 -1
- package/dist/{chrome-juQxt0zf.js → chrome-Cvr-57lg.js} +4 -3
- package/dist/{chrome-BCPPeLQ6.js → chrome-DL0avO8n.js} +2 -1
- package/dist/{chrome-yIKmOzCO.js → chrome-foEwx3lN.js} +5 -4
- package/dist/{clack-prompter-Dmvcu3gn.js → clack-prompter-Bz3Mmcl-.js} +5 -5
- package/dist/{clack-prompter-DuBVnTKy.js → clack-prompter-ChCGXfyt.js} +4 -4
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-FdxAcu_y.js → cli-ZR9ugUBX.js} +42 -40
- package/dist/{cli-By331Q9f.js → cli-miPe4Ujz.js} +42 -40
- package/dist/{client-B0_GiCjB.js → client-BrYfyoDK.js} +52 -3
- package/dist/{client-D7wrC1Ug.js → client-CTwXnRl7.js} +53 -4
- package/dist/{command-format-ayFsmwwz.js → command-format-Bxe0mWee.js} +1 -1
- package/dist/{command-options-BSDiKuyX.js → command-options-BvgxzPbK.js} +4 -4
- package/dist/{commands-BG25qku5.js → commands-BX_OIIVR.js} +4 -4
- package/dist/{completion-cli-C4zxjkC1.js → completion-cli-CR77-jyv.js} +3 -3
- package/dist/{completion-cli-DECEgBWR.js → completion-cli-DnjpxAag.js} +29 -29
- package/dist/{config-B7sno9eI.js → config-Bdhomfei.js} +15 -6
- package/dist/{config-BuF7vm-v.js → config-BvMsmctM.js} +13 -4
- package/dist/{config-D50SQVar.js → config-QYrbd7x7.js} +13 -4
- package/dist/{config-DH9TLUNc.js → config-aFQssWKX.js} +15 -6
- package/dist/{config-guard-DPxxY1iw.js → config-guard-CljaSxJd.js} +39 -39
- package/dist/{configure-BZQ9uSVX.js → configure-BXLiucXo.js} +19 -19
- package/dist/{configure-Cg5IKSUy.js → configure-BYPqXzGZ.js} +19 -19
- package/dist/control-auth-8Cf4WXpR.js +54 -0
- package/dist/control-auth-DBCu3qyv.js +54 -0
- package/dist/{control-service-CBlMVTRu.js → control-service-B5KnPqGP.js} +11 -5
- package/dist/{control-service-B2er20Ke.js → control-service-DKnttEus.js} +10 -4
- package/dist/{cron-cli-B2Zwhy_r.js → cron-cli-D7BRjDv2.js} +17 -17
- package/dist/{cron-cli-EaRUVd0p.js → cron-cli-z1zk_FXQ.js} +16 -16
- package/dist/{daemon-cli-CVNzObIF.js → daemon-cli-BDkU2ocb.js} +18 -18
- package/dist/{daemon-cli-DF6Rxjy6.js → daemon-cli-cNSF93-v.js} +19 -19
- package/dist/{daemon-runtime-BHF5NjQ7.js → daemon-runtime-B0tg_LsX.js} +2 -2
- package/dist/{daemon-runtime-B05PME1z.js → daemon-runtime-Bsjeut6m.js} +3 -3
- package/dist/{deliver-DzcxEcza.js → deliver-CIU9Npgs.js} +306 -12
- package/dist/{deliver-COf5XFo_.js → deliver-DYYCo1G7.js} +302 -8
- package/dist/{deliver-B1jsU2r7.js → deliver-LsxKETro.js} +306 -12
- package/dist/{deliver-CLwC284e.js → deliver-xUU3mGHo.js} +302 -8
- package/dist/{deps-Cva7QM_t.js → deps-QSwGcoNZ.js} +2 -2
- package/dist/{deps-B6602Wid.js → deps-lAAA2zYI.js} +2 -2
- package/dist/{devices-cli-DPg_4aW8.js → devices-cli-BG3-2oqt.js} +13 -13
- package/dist/{devices-cli-D8K3hZR5.js → devices-cli-VIQtOvt_.js} +13 -13
- package/dist/{directory-cli-OGBSVKAZ.js → directory-cli-BCJwjVC0.js} +15 -15
- package/dist/{directory-cli-Bn47fFX7.js → directory-cli-jYzZ02gk.js} +14 -14
- package/dist/{dispatcher-BHsNwFe-.js → dispatcher-DY51b-Zc.js} +2 -2
- package/dist/{dns-cli-DmTHXgwU.js → dns-cli-DHIiMJjS.js} +11 -11
- package/dist/{dns-cli-kk2rysJh.js → dns-cli-pZlv87Ib.js} +11 -11
- package/dist/{docs-cli-CB77CeM4.js → docs-cli-2JDiwfzP.js} +7 -7
- package/dist/{docs-cli-DUcyw0X0.js → docs-cli-BhkYqoIQ.js} +6 -6
- package/dist/{doctor-DwqdkfPa.js → doctor-Bf8EhNtA.js} +33 -33
- package/dist/{doctor-BZfxDGUg.js → doctor-sYG5V4Co.js} +32 -32
- package/dist/entry.js +36 -14
- package/dist/{env-DE9xvYOL.js → env-ONzUVAG2.js} +1 -1
- package/dist/{exec-4WHuOniw.js → exec-B8lXct-k.js} +31 -13
- package/dist/{exec-B8JKbXKW.js → exec-CACT5OAW.js} +1 -1
- package/dist/{exec-D12IZYtJ.js → exec-CJFFoM7H.js} +31 -13
- package/dist/{exec-DXtR2fhb.js → exec-YIosokWE.js} +1 -1
- package/dist/{exec-approvals-cli-GizapOX5.js → exec-approvals-cli-7LH0lwhO.js} +19 -19
- package/dist/{exec-approvals-cli-BWO0Rs-a.js → exec-approvals-cli-apGnQbpj.js} +19 -19
- package/dist/extensionAPI.js +1108 -661
- package/dist/{fetch-CqZP8jwB.js → fetch-DmiOpALK.js} +5 -3
- package/dist/{fetch-timeout-B2KlHXi3.js → fetch-timeout-BEtUjM1S.js} +5 -3
- package/dist/{fetch-timeout-ohY5QmsW.js → fetch-timeout-DEoXG_SF.js} +5 -3
- package/dist/{fetch-timeout-4UKsdtE1.js → fetch-timeout-DTK9vxex.js} +5 -3
- package/dist/{gateway-cli-Bbd1Xbsc.js → gateway-cli-DUdYxlZS.js} +315 -103
- package/dist/{gateway-cli-PR1S0BTe.js → gateway-cli-DbvWmE-9.js} +314 -102
- package/dist/{gateway-rpc-8gue7Qjt.js → gateway-rpc-BByb2Snz.js} +3 -3
- package/dist/{gateway-rpc-DjuxyOm-.js → gateway-rpc-wXSCUZXj.js} +3 -3
- package/dist/{github-copilot-auth-B3chCDfc.js → github-copilot-auth-D7ewvpMd.js} +16 -8
- package/dist/{github-copilot-auth-Cm2SB8Qf.js → github-copilot-auth-DDispnyz.js} +16 -8
- package/dist/{github-copilot-token-SLWintYd.js → github-copilot-token-Cfs0Wxr8.js} +1 -1
- package/dist/{gmail-setup-utils-Cgh0ptgA.js → gmail-setup-utils-Cfns8TQx.js} +3 -3
- package/dist/{gmail-setup-utils-WDyf1gTU.js → gmail-setup-utils-DJb-_5kO.js} +4 -4
- package/dist/{health-format-C0C_Apce.js → health-format-KGPokKJH.js} +68 -28
- package/dist/{health-format-gLMfE2wf.js → health-format-LZDxu3rv.js} +67 -27
- package/dist/{help-format-5iAL_46a.js → help-format-C48TXngO.js} +1 -1
- package/dist/{help-format-DUy1KRxq.js → help-format-R5fLToDw.js} +1 -1
- package/dist/{hooks-cli-CEN1h1ya.js → hooks-cli-CT8JCRkH.js} +46 -44
- package/dist/{hooks-cli-DrchIqSi.js → hooks-cli-S1MKumJO.js} +47 -45
- package/dist/{hooks-status-Cgy6AtQk.js → hooks-status-Cw0xD8Lt.js} +3 -3
- package/dist/{hooks-status--xVLpAXz.js → hooks-status-D9MhwHRp.js} +3 -3
- package/dist/{image-Dkawt9Kg.js → image-Brk1sJbw.js} +4 -4
- package/dist/{image-DI9s9eEx.js → image-C4Nn2p3e.js} +5 -5
- package/dist/{image-LxFvu0wL.js → image-DgtfXMcX.js} +5 -5
- package/dist/{image-B4mDPdyz.js → image-RKwc3fsL.js} +4 -4
- package/dist/index.js +83 -83
- package/dist/{installs-NS0VMPN7.js → installs-CrLcWYHe.js} +4 -4
- package/dist/{installs-DA-eSN1B.js → installs-DscWb9b9.js} +5 -5
- package/dist/{links-CV4oki2u.js → links-B8LAzWwg.js} +1 -1
- package/dist/{links-7M-j83As.js → links-Eax1UO3w.js} +1 -1
- package/dist/llm-slug-generator.js +15 -15
- package/dist/{loader-Caow9TPA.js → loader-KjT074JR.js} +1105 -762
- package/dist/{logging-CeHn2itV.js → logging-BAyPwvdH.js} +1 -1
- package/dist/{logging-D0MyqUlV.js → logging-CRq4h04P.js} +2 -2
- package/dist/{login-qr-Xx8yJrSc.js → login-qr-B6ZgAuIf.js} +5 -5
- package/dist/{login-qr-CoskdtvN.js → login-qr-Bua-p0nG.js} +2 -2
- package/dist/{login-qr-CAk9D-FM.js → login-qr-CuvemJj4.js} +6 -6
- package/dist/{login-qr-kUyMWXV1.js → login-qr-Djr1JfIf.js} +2 -2
- package/dist/{logs-cli-B476pzJS.js → logs-cli-9IAV7rWY.js} +15 -15
- package/dist/{logs-cli-BQRUI_PO.js → logs-cli-EiKzUFPa.js} +14 -14
- package/dist/{manager-CBApH7eR.js → manager-BIMh_eSm.js} +5 -5
- package/dist/{manager-CyJH6WMg.js → manager-CwinWQoz.js} +5 -5
- package/dist/{manager-DScY_ZTT.js → manager-DkqF1GiK.js} +7 -7
- package/dist/{manager-DseK7RWj.js → manager-T1XfGchB.js} +8 -8
- package/dist/{manifest-registry-DFckk-L8.js → manifest-registry-CQhdnDBZ.js} +2 -2
- package/dist/{manifest-registry-BTgLN_W2.js → manifest-registry-u0okVSkU.js} +2 -2
- package/dist/{message-channel-0717wOz-.js → message-channel-BLi2a6Yw.js} +1 -1
- package/dist/{message-channel-BlgPSDAh.js → message-channel-C_MmebBt.js} +1 -1
- package/dist/{model-auth-CbqRVYRp.js → model-auth-CabXIF6O.js} +57 -19
- package/dist/{model-selection-unMJyUIE.js → model-selection-BLuqsGVB.js} +59 -21
- package/dist/{model-selection-B9Y7dKQd.js → model-selection-C1GmkTAV.js} +57 -19
- package/dist/{models-cli-B1cLGcRz.js → models-cli-9jmDv-h3.js} +50 -48
- package/dist/{models-cli-D7sChCi6.js → models-cli-zS9rtWz8.js} +48 -46
- package/dist/{node-cli-ic2C1xs2.js → node-cli-CrpTxTTs.js} +26 -24
- package/dist/{node-cli-CS3KwBh1.js → node-cli-wemUMCg-.js} +25 -23
- package/dist/{node-service-D_Cdq1JI.js → node-service-C8DTHTMg.js} +2 -2
- package/dist/{node-service-_vgO5xR-.js → node-service-WQuEKz6W.js} +1 -1
- package/dist/{nodes-cli-CipcvVMc.js → nodes-cli-BaU2SIFw.js} +16 -16
- package/dist/{nodes-cli-B1meaW7S.js → nodes-cli-Dx23D72n.js} +16 -16
- package/dist/{nodes-screen-N-4_0VIu.js → nodes-screen-C0IuBqUL.js} +1 -1
- package/dist/{note-CAM9PbSJ.js → note-BhRSeNeu.js} +2 -2
- package/dist/{note-Ci08TSbV.js → note-hhtubr2j.js} +1 -1
- package/dist/{onboard-channels-DMcOT0dj.js → onboard-channels-C501x8GI.js} +8 -8
- package/dist/{onboard-channels-CsT3E4bT.js → onboard-channels-Dxzroasd.js} +8 -8
- package/dist/{onboard-skills-DoxkpnEU.js → onboard-skills-DV0Qzvjj.js} +19 -19
- package/dist/{onboard-skills-D-BrCoRN.js → onboard-skills-rlBHcu3Q.js} +18 -18
- package/dist/{onboarding-B92952fz.js → onboarding-CN-EDLjd.js} +34 -34
- package/dist/{pairing-cli-BDUJ5VoX.js → pairing-cli-CDHG4xuI.js} +15 -15
- package/dist/{pairing-cli-0wbU1u8d.js → pairing-cli-CQP34Dlx.js} +14 -14
- package/dist/{pairing-labels-3o3QO3Qn.js → pairing-labels-B6CN0SNH.js} +1 -1
- package/dist/{pairing-labels-Bin1K7_f.js → pairing-labels-CgNHnjzT.js} +1 -1
- package/dist/{pairing-store-CL4rJ7m7.js → pairing-store-CmlRVqOz.js} +2 -2
- package/dist/{pairing-store-fIWI3pXG.js → pairing-store-Dp5_JGnG.js} +3 -3
- package/dist/{path-env-CXWUFfFv.js → path-env-CLvYNwtL.js} +1 -1
- package/dist/{path-env-C5FR_Eay.js → path-env-CaYUVIML.js} +2 -2
- package/dist/{paths-DwKNqk_S.js → paths-B0a4ywSO.js} +30 -5
- package/dist/{paths-RITJT4UY.js → paths-B49s6UZQ.js} +30 -5
- package/dist/{paths-CB2fqqbX.js → paths-D0O87MfH.js} +30 -5
- package/dist/{paths-IivnSNkP.js → paths-DLINmNFQ.js} +31 -6
- package/dist/{pi-embedded-DhYItk8O.js → pi-embedded-Ctrt2kz0.js} +1109 -662
- package/dist/{pi-embedded-helpers-CmftU5Zj.js → pi-embedded-helpers-CMKLjW6X.js} +8 -5
- package/dist/{pi-embedded-helpers-CfXnSIFx.js → pi-embedded-helpers-CUzTc1v6.js} +170 -19
- package/dist/{pi-embedded-helpers-Uan-3N1T.js → pi-embedded-helpers-DfwkwPYD.js} +7 -4
- package/dist/{pi-embedded-helpers-Bri9tk9g.js → pi-embedded-helpers-WDwx99UA.js} +170 -19
- package/dist/{pi-tools.policy-CJFi1sny.js → pi-tools.policy-BpsROZbz.js} +4 -4
- package/dist/{plugin-auto-enable-BY4CqJbD.js → plugin-auto-enable-Bqhc3w5n.js} +5 -5
- package/dist/{plugin-auto-enable-DbQrtQjL.js → plugin-auto-enable-PW76g_PJ.js} +5 -5
- package/dist/plugin-sdk/agents/pi-embedded-runner/run/params.d.ts +2 -0
- package/dist/plugin-sdk/agents/pi-embedded-runner/run/types.d.ts +2 -0
- package/dist/plugin-sdk/agents/pi-embedded-runner/types.d.ts +15 -0
- package/dist/plugin-sdk/agents/pi-embedded-subscribe.handlers.tools.d.ts +1 -1
- package/dist/plugin-sdk/agents/pi-embedded-subscribe.handlers.types.d.ts +2 -0
- package/dist/plugin-sdk/agents/pi-embedded-subscribe.types.d.ts +2 -0
- package/dist/plugin-sdk/agents/session-tool-result-guard-wrapper.d.ts +2 -0
- package/dist/plugin-sdk/agents/session-tool-result-guard.d.ts +4 -0
- package/dist/plugin-sdk/agents/tools/agent-step.d.ts +3 -0
- package/dist/plugin-sdk/agents/usage.d.ts +1 -0
- package/dist/plugin-sdk/auto-reply/reply/reply-reference.d.ts +1 -1
- package/dist/plugin-sdk/auto-reply/reply/session-run-accounting.d.ts +11 -0
- package/dist/plugin-sdk/auto-reply/reply/session-usage.d.ts +8 -0
- package/dist/plugin-sdk/browser/control-auth.d.ts +13 -0
- package/dist/plugin-sdk/channels/plugins/onboarding/signal.d.ts +1 -0
- package/dist/plugin-sdk/cli/prompt.d.ts +1 -0
- package/dist/plugin-sdk/commands/agent/types.d.ts +2 -0
- package/dist/plugin-sdk/config/sessions/paths.d.ts +7 -2
- package/dist/plugin-sdk/config/types.agents.d.ts +2 -0
- package/dist/plugin-sdk/config/types.discord.d.ts +5 -0
- package/dist/plugin-sdk/config/types.gateway.d.ts +15 -0
- package/dist/plugin-sdk/config/types.hooks.d.ts +15 -0
- package/dist/plugin-sdk/config/zod-schema.agents.d.ts +1 -0
- package/dist/plugin-sdk/config/zod-schema.d.ts +11 -0
- package/dist/plugin-sdk/config/zod-schema.providers-core.d.ts +9 -0
- package/dist/plugin-sdk/config/zod-schema.providers.d.ts +4 -0
- package/dist/plugin-sdk/discord/monitor/allow-list.d.ts +15 -0
- package/dist/plugin-sdk/discord/send.types.d.ts +3 -0
- package/dist/plugin-sdk/gateway/auth.d.ts +36 -0
- package/dist/plugin-sdk/gateway/protocol/schema/agent.d.ts +6 -0
- package/dist/plugin-sdk/gateway/session-utils.fs.d.ts +3 -1
- package/dist/plugin-sdk/index.js +295 -99
- package/dist/plugin-sdk/infra/binaries.d.ts +3 -0
- package/dist/plugin-sdk/infra/heartbeat-runner.d.ts +1 -0
- package/dist/plugin-sdk/infra/net/fetch-guard.d.ts +1 -0
- package/dist/plugin-sdk/infra/net/ssrf.d.ts +1 -0
- package/dist/plugin-sdk/infra/tailscale.d.ts +34 -0
- package/dist/plugin-sdk/infra/tmp-openclaw-dir.d.ts +10 -0
- package/dist/plugin-sdk/logging/logger.d.ts +1 -1
- package/dist/plugin-sdk/media/input-files.d.ts +5 -0
- package/dist/plugin-sdk/routing/resolve-route.d.ts +3 -1
- package/dist/plugin-sdk/security/external-content.d.ts +1 -1
- 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/signal/monitor/event-handler.types.d.ts +8 -0
- package/dist/plugin-sdk/signal/monitor/mentions.d.ts +2 -0
- package/dist/{plugins-3GyCj5KL.js → plugins-4Hqd1WGf.js} +3 -3
- package/dist/{plugins-BL9lIXSA.js → plugins-X7d_tfTE.js} +4 -4
- package/dist/{plugins-cli-Ce7VsvZh.js → plugins-cli-Bgku3EGj.js} +253 -46
- package/dist/{plugins-cli-e9gUebMd.js → plugins-cli-CVToH3if.js} +254 -47
- package/dist/{ports-DupIRXQ0.js → ports-qkt29rdC.js} +2 -2
- package/dist/{program-u22vbFpH.js → program-Cf7lkBur.js} +82 -82
- package/dist/{progress-g9R--HZD.js → progress-C9kngsTD.js} +1 -1
- package/dist/{progress-Da1ehW-x.js → progress-DWqhRakV.js} +1 -1
- package/dist/{prompt-style-Dc0C5HC9.js → prompt-style-BFH5D5LN.js} +1 -1
- package/dist/{prompt-style-lmJDcgtA.js → prompt-style-CIbmaxSa.js} +1 -1
- package/dist/{pw-ai-C43wv1ZF.js → pw-ai-8mdv3h-d.js} +7 -6
- package/dist/{pw-ai-DTZVjndL.js → pw-ai-CM1IsSgZ.js} +5 -5
- package/dist/{pw-ai-zVebjrSG.js → pw-ai-FGoRVblI.js} +3 -3
- package/dist/{pw-ai-CWrnJ98b.js → pw-ai-sS1fRKW_.js} +3 -3
- package/dist/{qmd-manager-NPD5Yh_4.js → qmd-manager-C67Fc8aN.js} +4 -4
- package/dist/{qmd-manager-ozZ933qc.js → qmd-manager-CXVbfg99.js} +7 -7
- package/dist/{qmd-manager-DBCZ1sio.js → qmd-manager-RMRE8Tqt.js} +6 -6
- package/dist/{qmd-manager-a9Bt0405.js → qmd-manager-pyc_MTIe.js} +4 -4
- package/dist/{register.subclis-BpX3ulH1.js → register.subclis-C02e4zuJ.js} +28 -28
- package/dist/{reply-m467_fOC.js → reply-DICXkh_C.js} +911 -568
- package/dist/{routes-82Ywfho6.js → routes-CmOI1hIH.js} +29 -11
- package/dist/{routes-BqxA3ZYr.js → routes-DewK5tq2.js} +29 -12
- package/dist/{rpc-DcGBG-Fp.js → rpc-DHr30euf.js} +3 -3
- package/dist/{rpc-CfdBHlnp.js → rpc-T300F8zI.js} +3 -3
- package/dist/{run-main-aolvSfj3.js → run-main-C5wpthq1.js} +84 -84
- package/dist/{runner-C1G8RFWl.js → runner-CY0nmVme.js} +9 -9
- package/dist/{runner-BCBs8JKA.js → runner-Cfm5nTMc.js} +6 -6
- package/dist/{runner-CInKPsiP.js → runner-D_dujMod.js} +8 -8
- package/dist/{runner-Cwfn-VOM.js → runner-DrGYLH5K.js} +6 -6
- package/dist/{sandbox-B0K9e6Fw.js → sandbox-BKYnhYQH.js} +23 -15
- package/dist/{sandbox-BW8Xnkw1.js → sandbox-Bhjnh1Xg.js} +21 -13
- package/dist/{sandbox-cli-mKCs2J0i.js → sandbox-cli-DBsAjZJN.js} +20 -20
- package/dist/{sandbox-cli-BD5LkZ0B.js → sandbox-cli-rV9LtFeu.js} +19 -19
- package/dist/{security-cli-kgI4soGy.js → security-cli-BIwJM_rs.js} +27 -27
- package/dist/{security-cli-kz8TiyqU.js → security-cli-BRjny8Yu.js} +26 -26
- package/dist/{server-context-fX4xiYRh.js → server-context-BGpGs3qd.js} +7 -7
- package/dist/{server-context-Lb-eUZG_.js → server-context-Cl0U0vE3.js} +5 -5
- package/dist/{server-node-events-Dx18uVrH.js → server-node-events-CBfTbiTA.js} +45 -43
- package/dist/{server-node-events-KqZMN30F.js → server-node-events-QCvh8EgI.js} +45 -43
- package/dist/{service-DZMXgMra.js → service--nPk7DvT.js} +3 -3
- package/dist/{service-DNcIZ5Kp.js → service-99RDXwX4.js} +2 -2
- package/dist/{service-audit-0WLGnoNT.js → service-audit-DnLmRGQt.js} +4 -4
- package/dist/{service-audit-uhZSlxeb.js → service-audit-ckBaRCVC.js} +3 -3
- package/dist/{session-cost-usage-HU4OeRgw.js → session-cost-usage-D7HuoSSD.js} +10 -8
- package/dist/{session-cost-usage-CL8gnHRN.js → session-cost-usage-D9hHANWI.js} +10 -8
- package/dist/{shared-j4Qtr475.js → shared-Bs4vduG4.js} +3 -3
- package/dist/{shared-BBw6F-YC.js → shared-CEY5IkwG.js} +2 -2
- package/dist/{shared-DOZs2SoH.js → shared-DRohONn_.js} +3 -3
- package/dist/{shared-CtP9K-o2.js → shared-ICqOZibV.js} +3 -3
- package/dist/{skill-scanner-C_fQzVDu.js → skill-scanner-rHMtUHtP.js} +1 -1
- package/dist/{skills-BvPUNjxo.js → skills-DRjfSQT3.js} +128 -4
- package/dist/{skills-aFOsriMP.js → skills-DprQj9X2.js} +129 -5
- package/dist/{skills-cli-oWaTJzZd.js → skills-cli-9WO-C55s.js} +12 -12
- package/dist/{skills-cli-E6shXpdd.js → skills-cli-B9eej-EW.js} +13 -13
- package/dist/{skills-status-D4vbIMnz.js → skills-status-5U3P3YfJ.js} +3 -3
- package/dist/{skills-status-DJDaA2Ur.js → skills-status-TDIgVd1K.js} +2 -2
- package/dist/{sqlite-B7FPASCO.js → sqlite-BINzs1U0.js} +2 -2
- package/dist/{sqlite-B4Z1_Ioc.js → sqlite-D4w5TejA.js} +2 -2
- package/dist/{sqlite-BkYnxkQO.js → sqlite-DRRHmlug.js} +2 -2
- package/dist/{sqlite-EuQPVXvn.js → sqlite-F6PGkEm1.js} +2 -2
- package/dist/{status-B2Yr-2J5.js → status-BKGkKC_v.js} +3 -3
- package/dist/{status-DW7m5xUN.js → status-CiHtHdaa.js} +4 -4
- package/dist/{status-CxhnUa5J.js → status-DDWoOpeB.js} +33 -33
- package/dist/{subsystem-Bv7dGhES.js → subsystem-BoExtIHo.js} +32 -13
- package/dist/{system-cli-0JXhJNWm.js → system-cli-B6lr60Io.js} +14 -14
- package/dist/{system-cli-D-0OaMtH.js → system-cli-CprW9G3h.js} +14 -14
- package/dist/{systemd-CNTodvCO.js → systemd-C0VZriGM.js} +2 -2
- package/dist/{systemd-CUJJHgHa.js → systemd-DrmBtJ5T.js} +3 -3
- package/dist/{systemd-hints-cmHtrXUl.js → systemd-hints-DZtXiVHa.js} +1 -1
- package/dist/{systemd-linger-CArPbmvv.js → systemd-linger-NC2kl1SC.js} +2 -2
- package/dist/{systemd-linger-XvT9Y9sb.js → systemd-linger-xdn3BdPh.js} +2 -2
- package/dist/{table-DzBBIqHO.js → table-B8dx3v4v.js} +2 -2
- package/dist/{table-oJQPTUL6.js → table-CwulTLQp.js} +1 -1
- package/dist/{tool-display-Na-EVL83.js → tool-display-CZRIDMRm.js} +1 -1
- package/dist/{tool-display-sHJa3kRs.js → tool-display-ClRud3pg.js} +2 -2
- package/dist/{tui-nGp8ltQK.js → tui-CVTQn-dC.js} +9 -9
- package/dist/{tui-Biw7aqPj.js → tui-Lu8FdrlK.js} +9 -9
- package/dist/{tui-cli-C9FEfG7C.js → tui-cli-BLpTj1X9.js} +25 -25
- package/dist/{tui-cli-Dxnu5JGl.js → tui-cli-BLx5kL2I.js} +25 -25
- package/dist/{tui-formatters-BiNTNGwg.js → tui-formatters-CNySEfJN.js} +5 -5
- package/dist/{tui-formatters-C_baVYUz.js → tui-formatters-DePhZK3J.js} +5 -5
- package/dist/{update-C4rsLj2F.js → update-DHVxMTpQ.js} +3 -3
- package/dist/{update-uwUWrKFu.js → update-DU1geolI.js} +3 -3
- package/dist/{update-cli-cNd_G9E6.js → update-cli-C0hUvJWK.js} +66 -66
- package/dist/{update-cli-CBXp-c4C.js → update-cli-Wb1GB3rL.js} +68 -68
- package/dist/{update-runner-BLsqC24J.js → update-runner--ixK4J3W.js} +10 -10
- package/dist/{update-runner-C_FDpmA3.js → update-runner-7Qa1T9y6.js} +9 -9
- package/dist/{utils-Dk86IbEs.js → utils-BLJAc3ZV.js} +1 -1
- package/dist/{utils-BHPdZE4h.js → utils-Cd9QdCHh.js} +1 -1
- package/dist/{webhooks-cli-BpBKXL7W.js → webhooks-cli-DgcMy7RG.js} +12 -12
- package/dist/{webhooks-cli-wNfhfKqm.js → webhooks-cli-aVzUcJY9.js} +11 -11
- package/dist/{widearea-dns-WVCWJTEb.js → widearea-dns-BaIgNEhY.js} +1 -1
- package/dist/{widearea-dns-BWYPcfby.js → widearea-dns-DzuRdwk5.js} +1 -1
- package/dist/{ws-log-Cafylho7.js → ws-log-CIXbLCka.js} +1 -1
- package/dist/{ws-log-DTUOUVgR.js → ws-log-DcQFZByi.js} +1 -1
- package/dist/{wsl-B-H6Z5wp.js → wsl-BUOkxKJu.js} +2 -2
- package/docs/automation/webhook.md +43 -2
- package/docs/channels/discord.md +29 -1
- package/docs/cli/plugins.md +20 -1
- package/docs/cli/security.md +1 -0
- package/docs/concepts/session-tool.md +1 -0
- package/docs/gateway/configuration-reference.md +11 -0
- package/docs/gateway/configuration.md +3 -0
- package/docs/gateway/openresponses-http-api.md +15 -0
- package/docs/gateway/security/index.md +3 -0
- package/docs/help/faq.md +9 -0
- package/docs/install/installer.md +20 -0
- package/docs/reference/transcript-hygiene.md +18 -0
- package/docs/tools/browser.md +6 -0
- package/extensions/diagnostics-otel/package.json +9 -9
- package/extensions/feishu/package.json +1 -1
- package/extensions/feishu/src/config-schema.ts +6 -0
- package/extensions/feishu/src/reply-dispatcher.test.ts +116 -0
- package/extensions/feishu/src/reply-dispatcher.ts +124 -67
- package/extensions/feishu/src/streaming-card.ts +223 -0
- package/extensions/feishu/src/targets.test.ts +16 -0
- package/extensions/feishu/src/targets.ts +1 -1
- package/extensions/irc/src/client.ts +1 -1
- package/extensions/minimax-portal-auth/index.ts +7 -5
- package/extensions/nostr/package.json +1 -1
- package/package.json +13 -13
- package/dist/auth-BcNHFK-i.js +0 -184
- package/dist/auth-jrfLXze7.js +0 -184
- /package/dist/{archive-DqNr5i8b.js → archive-beaSfAzA.js} +0 -0
- /package/dist/{brew-BIrWdDps.js → brew-BUIxHEkn.js} +0 -0
- /package/dist/{brew-6UyogeLe.js → brew-ROHf0-Xp.js} +0 -0
- /package/dist/{constants-DuoCkWRh.js → constants-BvQ6S8j5.js} +0 -0
- /package/dist/{errors-x4NYs-1P.js → errors-DjZBTJJ3.js} +0 -0
- /package/dist/{helpers-BDvtkJjw.js → helpers-HyeZXsnu.js} +0 -0
- /package/dist/{is-main-CE1eOBYb.js → is-main-BWoXGz7p.js} +0 -0
- /package/dist/{parse-Cjiudy6x.js → parse-Bw0oH-rT.js} +0 -0
- /package/dist/{parse-timeout-DFSPLxpY.js → parse-timeout-D1XX_zN_.js} +0 -0
- /package/dist/{prompts-BOz5176z.js → prompts-Bg96reub.js} +0 -0
- /package/dist/{redact-DuEEf1p1.js → redact-Br9GfacZ.js} +0 -0
- /package/dist/{skill-scanner-CprFkZib.js → skill-scanner-CucvxYhu.js} +0 -0
- /package/dist/{transcript-events-CZ8CG4ht.js → transcript-events-BtNd-j6q.js} +0 -0
|
@@ -265,6 +265,9 @@ tool calls. Reduce the blast radius by:
|
|
|
265
265
|
- Using a read-only or tool-disabled **reader agent** to summarize untrusted content,
|
|
266
266
|
then pass the summary to your main agent.
|
|
267
267
|
- Keeping `web_search` / `web_fetch` / `browser` off for tool-enabled agents unless needed.
|
|
268
|
+
- For OpenResponses URL inputs (`input_file` / `input_image`), set tight
|
|
269
|
+
`gateway.http.endpoints.responses.files.urlAllowlist` and
|
|
270
|
+
`gateway.http.endpoints.responses.images.urlAllowlist`, and keep `maxUrlParts` low.
|
|
268
271
|
- Enabling sandboxing and strict tool allowlists for any agent that touches untrusted input.
|
|
269
272
|
- Keeping secrets out of prompts; pass them via env/config on the gateway host instead.
|
|
270
273
|
|
package/docs/help/faq.md
CHANGED
|
@@ -546,6 +546,15 @@ For a hackable (git) install:
|
|
|
546
546
|
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git --verbose
|
|
547
547
|
```
|
|
548
548
|
|
|
549
|
+
Windows (PowerShell) equivalent:
|
|
550
|
+
|
|
551
|
+
```powershell
|
|
552
|
+
# install.ps1 has no dedicated -Verbose flag yet.
|
|
553
|
+
Set-PSDebug -Trace 1
|
|
554
|
+
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
|
555
|
+
Set-PSDebug -Trace 0
|
|
556
|
+
```
|
|
557
|
+
|
|
549
558
|
More options: [Installer flags](/install/installer).
|
|
550
559
|
|
|
551
560
|
### Windows install says git not found or openclaw not recognized
|
|
@@ -286,6 +286,14 @@ Designed for environments where you want everything under a local prefix (defaul
|
|
|
286
286
|
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -DryRun
|
|
287
287
|
```
|
|
288
288
|
</Tab>
|
|
289
|
+
<Tab title="Debug trace">
|
|
290
|
+
```powershell
|
|
291
|
+
# install.ps1 has no dedicated -Verbose flag yet.
|
|
292
|
+
Set-PSDebug -Trace 1
|
|
293
|
+
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
|
294
|
+
Set-PSDebug -Trace 0
|
|
295
|
+
```
|
|
296
|
+
</Tab>
|
|
289
297
|
</Tabs>
|
|
290
298
|
|
|
291
299
|
<AccordionGroup>
|
|
@@ -379,6 +387,18 @@ Use non-interactive flags/env vars for predictable runs.
|
|
|
379
387
|
Run `npm config get prefix`, append `\bin`, add that directory to user PATH, then reopen PowerShell.
|
|
380
388
|
</Accordion>
|
|
381
389
|
|
|
390
|
+
<Accordion title="Windows: how to get verbose installer output">
|
|
391
|
+
`install.ps1` does not currently expose a `-Verbose` switch.
|
|
392
|
+
Use PowerShell tracing for script-level diagnostics:
|
|
393
|
+
|
|
394
|
+
```powershell
|
|
395
|
+
Set-PSDebug -Trace 1
|
|
396
|
+
& ([scriptblock]::Create((iwr -useb https://openclaw.ai/install.ps1))) -NoOnboard
|
|
397
|
+
Set-PSDebug -Trace 0
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
</Accordion>
|
|
401
|
+
|
|
382
402
|
<Accordion title="openclaw not found after install">
|
|
383
403
|
Usually a PATH issue. See [Node.js troubleshooting](/install/node#troubleshooting).
|
|
384
404
|
</Accordion>
|
|
@@ -24,6 +24,7 @@ Scope includes:
|
|
|
24
24
|
- Turn validation / ordering
|
|
25
25
|
- Thought signature cleanup
|
|
26
26
|
- Image payload sanitization
|
|
27
|
+
- User-input provenance tagging (for inter-session routed prompts)
|
|
27
28
|
|
|
28
29
|
If you need transcript storage details, see:
|
|
29
30
|
|
|
@@ -72,6 +73,23 @@ Implementation:
|
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
76
|
+
## Global rule: inter-session input provenance
|
|
77
|
+
|
|
78
|
+
When an agent sends a prompt into another session via `sessions_send` (including
|
|
79
|
+
agent-to-agent reply/announce steps), OpenClaw persists the created user turn with:
|
|
80
|
+
|
|
81
|
+
- `message.provenance.kind = "inter_session"`
|
|
82
|
+
|
|
83
|
+
This metadata is written at transcript append time and does not change role
|
|
84
|
+
(`role: "user"` remains for provider compatibility). Transcript readers can use
|
|
85
|
+
this to avoid treating routed internal prompts as end-user-authored instructions.
|
|
86
|
+
|
|
87
|
+
During context rebuild, OpenClaw also prepends a short `[Inter-session message]`
|
|
88
|
+
marker to those user turns in-memory so the model can distinguish them from
|
|
89
|
+
external end-user instructions.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
75
93
|
## Provider matrix (current behavior)
|
|
76
94
|
|
|
77
95
|
**OpenAI / OpenAI Codex**
|
package/docs/tools/browser.md
CHANGED
|
@@ -192,6 +192,7 @@ Notes:
|
|
|
192
192
|
Key ideas:
|
|
193
193
|
|
|
194
194
|
- Browser control is loopback-only; access flows through the Gateway’s auth or node pairing.
|
|
195
|
+
- If browser control is enabled and no auth is configured, OpenClaw auto-generates `gateway.auth.token` on startup and persists it to config.
|
|
195
196
|
- Keep the Gateway and any node hosts on a private network (Tailscale); avoid public exposure.
|
|
196
197
|
- Treat remote CDP URLs/tokens as secrets; prefer env vars or a secrets manager.
|
|
197
198
|
|
|
@@ -315,6 +316,11 @@ For local integrations only, the Gateway exposes a small loopback HTTP API:
|
|
|
315
316
|
|
|
316
317
|
All endpoints accept `?profile=<name>`.
|
|
317
318
|
|
|
319
|
+
If gateway auth is configured, browser HTTP routes require auth too:
|
|
320
|
+
|
|
321
|
+
- `Authorization: Bearer <gateway token>`
|
|
322
|
+
- `x-openclaw-password: <gateway password>` or HTTP Basic auth with that password
|
|
323
|
+
|
|
318
324
|
### Playwright requirement
|
|
319
325
|
|
|
320
326
|
Some features (navigate/act/AI snapshot/role snapshot, element screenshots, PDF) require
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@opentelemetry/api": "^1.9.0",
|
|
8
|
-
"@opentelemetry/api-logs": "^0.
|
|
9
|
-
"@opentelemetry/exporter-logs-otlp-http": "^0.
|
|
10
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.
|
|
11
|
-
"@opentelemetry/exporter-trace-otlp-http": "^0.
|
|
12
|
-
"@opentelemetry/resources": "^2.5.
|
|
13
|
-
"@opentelemetry/sdk-logs": "^0.
|
|
14
|
-
"@opentelemetry/sdk-metrics": "^2.5.
|
|
15
|
-
"@opentelemetry/sdk-node": "^0.
|
|
16
|
-
"@opentelemetry/sdk-trace-base": "^2.5.
|
|
8
|
+
"@opentelemetry/api-logs": "^0.212.0",
|
|
9
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.212.0",
|
|
10
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.212.0",
|
|
11
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.212.0",
|
|
12
|
+
"@opentelemetry/resources": "^2.5.1",
|
|
13
|
+
"@opentelemetry/sdk-logs": "^0.212.0",
|
|
14
|
+
"@opentelemetry/sdk-metrics": "^2.5.1",
|
|
15
|
+
"@opentelemetry/sdk-node": "^0.212.0",
|
|
16
|
+
"@opentelemetry/sdk-trace-base": "^2.5.1",
|
|
17
17
|
"@opentelemetry/semantic-conventions": "^1.39.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@larksuiteoapi/node-sdk": "^1.
|
|
7
|
+
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
8
8
|
"@sinclair/typebox": "0.34.48",
|
|
9
9
|
"zod": "^4.3.6"
|
|
10
10
|
},
|
|
@@ -36,6 +36,10 @@ const MarkdownConfigSchema = z
|
|
|
36
36
|
// Message render mode: auto (default) = detect markdown, raw = plain text, card = always card
|
|
37
37
|
const RenderModeSchema = z.enum(["auto", "raw", "card"]).optional();
|
|
38
38
|
|
|
39
|
+
// Streaming card mode: when enabled, card replies use Feishu's Card Kit streaming API
|
|
40
|
+
// for incremental text display with a "Thinking..." placeholder
|
|
41
|
+
const StreamingModeSchema = z.boolean().optional();
|
|
42
|
+
|
|
39
43
|
const BlockStreamingCoalesceSchema = z
|
|
40
44
|
.object({
|
|
41
45
|
enabled: z.boolean().optional(),
|
|
@@ -142,6 +146,7 @@ export const FeishuAccountConfigSchema = z
|
|
|
142
146
|
mediaMaxMb: z.number().positive().optional(),
|
|
143
147
|
heartbeat: ChannelHeartbeatVisibilitySchema,
|
|
144
148
|
renderMode: RenderModeSchema,
|
|
149
|
+
streaming: StreamingModeSchema, // Enable streaming card mode (default: true)
|
|
145
150
|
tools: FeishuToolsConfigSchema,
|
|
146
151
|
})
|
|
147
152
|
.strict();
|
|
@@ -177,6 +182,7 @@ export const FeishuConfigSchema = z
|
|
|
177
182
|
mediaMaxMb: z.number().positive().optional(),
|
|
178
183
|
heartbeat: ChannelHeartbeatVisibilitySchema,
|
|
179
184
|
renderMode: RenderModeSchema, // raw = plain text (default), card = interactive card with markdown
|
|
185
|
+
streaming: StreamingModeSchema, // Enable streaming card mode (default: true)
|
|
180
186
|
tools: FeishuToolsConfigSchema,
|
|
181
187
|
// Dynamic agent creation for DM users
|
|
182
188
|
dynamicAgentCreation: DynamicAgentCreationSchema,
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
const resolveFeishuAccountMock = vi.hoisted(() => vi.fn());
|
|
4
|
+
const getFeishuRuntimeMock = vi.hoisted(() => vi.fn());
|
|
5
|
+
const sendMessageFeishuMock = vi.hoisted(() => vi.fn());
|
|
6
|
+
const sendMarkdownCardFeishuMock = vi.hoisted(() => vi.fn());
|
|
7
|
+
const createFeishuClientMock = vi.hoisted(() => vi.fn());
|
|
8
|
+
const resolveReceiveIdTypeMock = vi.hoisted(() => vi.fn());
|
|
9
|
+
const createReplyDispatcherWithTypingMock = vi.hoisted(() => vi.fn());
|
|
10
|
+
const streamingInstances = vi.hoisted(() => [] as any[]);
|
|
11
|
+
|
|
12
|
+
vi.mock("./accounts.js", () => ({ resolveFeishuAccount: resolveFeishuAccountMock }));
|
|
13
|
+
vi.mock("./runtime.js", () => ({ getFeishuRuntime: getFeishuRuntimeMock }));
|
|
14
|
+
vi.mock("./send.js", () => ({
|
|
15
|
+
sendMessageFeishu: sendMessageFeishuMock,
|
|
16
|
+
sendMarkdownCardFeishu: sendMarkdownCardFeishuMock,
|
|
17
|
+
}));
|
|
18
|
+
vi.mock("./client.js", () => ({ createFeishuClient: createFeishuClientMock }));
|
|
19
|
+
vi.mock("./targets.js", () => ({ resolveReceiveIdType: resolveReceiveIdTypeMock }));
|
|
20
|
+
vi.mock("./streaming-card.js", () => ({
|
|
21
|
+
FeishuStreamingSession: class {
|
|
22
|
+
active = false;
|
|
23
|
+
start = vi.fn(async () => {
|
|
24
|
+
this.active = true;
|
|
25
|
+
});
|
|
26
|
+
update = vi.fn(async () => {});
|
|
27
|
+
close = vi.fn(async () => {
|
|
28
|
+
this.active = false;
|
|
29
|
+
});
|
|
30
|
+
isActive = vi.fn(() => this.active);
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
streamingInstances.push(this);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
import { createFeishuReplyDispatcher } from "./reply-dispatcher.js";
|
|
39
|
+
|
|
40
|
+
describe("createFeishuReplyDispatcher streaming behavior", () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
vi.clearAllMocks();
|
|
43
|
+
streamingInstances.length = 0;
|
|
44
|
+
|
|
45
|
+
resolveFeishuAccountMock.mockReturnValue({
|
|
46
|
+
accountId: "main",
|
|
47
|
+
appId: "app_id",
|
|
48
|
+
appSecret: "app_secret",
|
|
49
|
+
domain: "feishu",
|
|
50
|
+
config: {
|
|
51
|
+
renderMode: "auto",
|
|
52
|
+
streaming: true,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
resolveReceiveIdTypeMock.mockReturnValue("chat_id");
|
|
57
|
+
createFeishuClientMock.mockReturnValue({});
|
|
58
|
+
|
|
59
|
+
createReplyDispatcherWithTypingMock.mockImplementation((opts) => ({
|
|
60
|
+
dispatcher: {},
|
|
61
|
+
replyOptions: {},
|
|
62
|
+
markDispatchIdle: vi.fn(),
|
|
63
|
+
_opts: opts,
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
getFeishuRuntimeMock.mockReturnValue({
|
|
67
|
+
channel: {
|
|
68
|
+
text: {
|
|
69
|
+
resolveTextChunkLimit: vi.fn(() => 4000),
|
|
70
|
+
resolveChunkMode: vi.fn(() => "line"),
|
|
71
|
+
resolveMarkdownTableMode: vi.fn(() => "preserve"),
|
|
72
|
+
convertMarkdownTables: vi.fn((text) => text),
|
|
73
|
+
chunkTextWithMode: vi.fn((text) => [text]),
|
|
74
|
+
},
|
|
75
|
+
reply: {
|
|
76
|
+
createReplyDispatcherWithTyping: createReplyDispatcherWithTypingMock,
|
|
77
|
+
resolveHumanDelayConfig: vi.fn(() => undefined),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("keeps auto mode plain text on non-streaming send path", async () => {
|
|
84
|
+
createFeishuReplyDispatcher({
|
|
85
|
+
cfg: {} as never,
|
|
86
|
+
agentId: "agent",
|
|
87
|
+
runtime: {} as never,
|
|
88
|
+
chatId: "oc_chat",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const options = createReplyDispatcherWithTypingMock.mock.calls[0]?.[0];
|
|
92
|
+
await options.deliver({ text: "plain text" }, { kind: "final" });
|
|
93
|
+
|
|
94
|
+
expect(streamingInstances).toHaveLength(0);
|
|
95
|
+
expect(sendMessageFeishuMock).toHaveBeenCalledTimes(1);
|
|
96
|
+
expect(sendMarkdownCardFeishuMock).not.toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("uses streaming session for auto mode markdown payloads", async () => {
|
|
100
|
+
createFeishuReplyDispatcher({
|
|
101
|
+
cfg: {} as never,
|
|
102
|
+
agentId: "agent",
|
|
103
|
+
runtime: { log: vi.fn(), error: vi.fn() } as never,
|
|
104
|
+
chatId: "oc_chat",
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const options = createReplyDispatcherWithTypingMock.mock.calls[0]?.[0];
|
|
108
|
+
await options.deliver({ text: "```ts\nconst x = 1\n```" }, { kind: "final" });
|
|
109
|
+
|
|
110
|
+
expect(streamingInstances).toHaveLength(1);
|
|
111
|
+
expect(streamingInstances[0].start).toHaveBeenCalledTimes(1);
|
|
112
|
+
expect(streamingInstances[0].close).toHaveBeenCalledTimes(1);
|
|
113
|
+
expect(sendMessageFeishuMock).not.toHaveBeenCalled();
|
|
114
|
+
expect(sendMarkdownCardFeishuMock).not.toHaveBeenCalled();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -3,29 +3,22 @@ import {
|
|
|
3
3
|
createTypingCallbacks,
|
|
4
4
|
logTypingFailure,
|
|
5
5
|
type ClawdbotConfig,
|
|
6
|
-
type RuntimeEnv,
|
|
7
6
|
type ReplyPayload,
|
|
7
|
+
type RuntimeEnv,
|
|
8
8
|
} from "openclaw/plugin-sdk";
|
|
9
9
|
import type { MentionTarget } from "./mention.js";
|
|
10
10
|
import { resolveFeishuAccount } from "./accounts.js";
|
|
11
|
+
import { createFeishuClient } from "./client.js";
|
|
12
|
+
import { buildMentionedCardContent } from "./mention.js";
|
|
11
13
|
import { getFeishuRuntime } from "./runtime.js";
|
|
12
|
-
import {
|
|
14
|
+
import { sendMarkdownCardFeishu, sendMessageFeishu } from "./send.js";
|
|
15
|
+
import { FeishuStreamingSession } from "./streaming-card.js";
|
|
16
|
+
import { resolveReceiveIdType } from "./targets.js";
|
|
13
17
|
import { addTypingIndicator, removeTypingIndicator, type TypingIndicatorState } from "./typing.js";
|
|
14
18
|
|
|
15
|
-
/**
|
|
16
|
-
* Detect if text contains markdown elements that benefit from card rendering.
|
|
17
|
-
* Used by auto render mode.
|
|
18
|
-
*/
|
|
19
|
+
/** Detect if text contains markdown elements that benefit from card rendering */
|
|
19
20
|
function shouldUseCard(text: string): boolean {
|
|
20
|
-
|
|
21
|
-
if (/```[\s\S]*?```/.test(text)) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
// Tables (at least header + separator row with |)
|
|
25
|
-
if (/\|.+\|[\r\n]+\|[-:| ]+\|/.test(text)) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
return false;
|
|
21
|
+
return /```[\s\S]*?```/.test(text) || /\|.+\|[\r\n]+\|[-:| ]+\|/.test(text);
|
|
29
22
|
}
|
|
30
23
|
|
|
31
24
|
export type CreateFeishuReplyDispatcherParams = {
|
|
@@ -34,35 +27,23 @@ export type CreateFeishuReplyDispatcherParams = {
|
|
|
34
27
|
runtime: RuntimeEnv;
|
|
35
28
|
chatId: string;
|
|
36
29
|
replyToMessageId?: string;
|
|
37
|
-
/** Mention targets, will be auto-included in replies */
|
|
38
30
|
mentionTargets?: MentionTarget[];
|
|
39
|
-
/** Account ID for multi-account support */
|
|
40
31
|
accountId?: string;
|
|
41
32
|
};
|
|
42
33
|
|
|
43
34
|
export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherParams) {
|
|
44
35
|
const core = getFeishuRuntime();
|
|
45
36
|
const { cfg, agentId, chatId, replyToMessageId, mentionTargets, accountId } = params;
|
|
46
|
-
|
|
47
|
-
// Resolve account for config access
|
|
48
37
|
const account = resolveFeishuAccount({ cfg, accountId });
|
|
38
|
+
const prefixContext = createReplyPrefixContext({ cfg, agentId });
|
|
49
39
|
|
|
50
|
-
const prefixContext = createReplyPrefixContext({
|
|
51
|
-
cfg,
|
|
52
|
-
agentId,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Feishu doesn't have a native typing indicator API.
|
|
56
|
-
// We use message reactions as a typing indicator substitute.
|
|
57
40
|
let typingState: TypingIndicatorState | null = null;
|
|
58
|
-
|
|
59
41
|
const typingCallbacks = createTypingCallbacks({
|
|
60
42
|
start: async () => {
|
|
61
43
|
if (!replyToMessageId) {
|
|
62
44
|
return;
|
|
63
45
|
}
|
|
64
46
|
typingState = await addTypingIndicator({ cfg, messageId: replyToMessageId, accountId });
|
|
65
|
-
params.runtime.log?.(`feishu[${account.accountId}]: added typing indicator reaction`);
|
|
66
47
|
},
|
|
67
48
|
stop: async () => {
|
|
68
49
|
if (!typingState) {
|
|
@@ -70,24 +51,21 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
|
|
|
70
51
|
}
|
|
71
52
|
await removeTypingIndicator({ cfg, state: typingState, accountId });
|
|
72
53
|
typingState = null;
|
|
73
|
-
params.runtime.log?.(`feishu[${account.accountId}]: removed typing indicator reaction`);
|
|
74
54
|
},
|
|
75
|
-
onStartError: (err) =>
|
|
55
|
+
onStartError: (err) =>
|
|
76
56
|
logTypingFailure({
|
|
77
57
|
log: (message) => params.runtime.log?.(message),
|
|
78
58
|
channel: "feishu",
|
|
79
59
|
action: "start",
|
|
80
60
|
error: err,
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
onStopError: (err) => {
|
|
61
|
+
}),
|
|
62
|
+
onStopError: (err) =>
|
|
84
63
|
logTypingFailure({
|
|
85
64
|
log: (message) => params.runtime.log?.(message),
|
|
86
65
|
channel: "feishu",
|
|
87
66
|
action: "stop",
|
|
88
67
|
error: err,
|
|
89
|
-
})
|
|
90
|
-
},
|
|
68
|
+
}),
|
|
91
69
|
});
|
|
92
70
|
|
|
93
71
|
const textChunkLimit = core.channel.text.resolveTextChunkLimit(cfg, "feishu", accountId, {
|
|
@@ -95,77 +73,139 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
|
|
|
95
73
|
});
|
|
96
74
|
const chunkMode = core.channel.text.resolveChunkMode(cfg, "feishu");
|
|
97
75
|
const tableMode = core.channel.text.resolveMarkdownTableMode({ cfg, channel: "feishu" });
|
|
76
|
+
const renderMode = account.config?.renderMode ?? "auto";
|
|
77
|
+
const streamingEnabled = account.config?.streaming !== false && renderMode !== "raw";
|
|
78
|
+
|
|
79
|
+
let streaming: FeishuStreamingSession | null = null;
|
|
80
|
+
let streamText = "";
|
|
81
|
+
let lastPartial = "";
|
|
82
|
+
let partialUpdateQueue: Promise<void> = Promise.resolve();
|
|
83
|
+
let streamingStartPromise: Promise<void> | null = null;
|
|
84
|
+
|
|
85
|
+
const startStreaming = () => {
|
|
86
|
+
if (!streamingEnabled || streamingStartPromise || streaming) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
streamingStartPromise = (async () => {
|
|
90
|
+
const creds =
|
|
91
|
+
account.appId && account.appSecret
|
|
92
|
+
? { appId: account.appId, appSecret: account.appSecret, domain: account.domain }
|
|
93
|
+
: null;
|
|
94
|
+
if (!creds) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
streaming = new FeishuStreamingSession(createFeishuClient(account), creds, (message) =>
|
|
99
|
+
params.runtime.log?.(`feishu[${account.accountId}] ${message}`),
|
|
100
|
+
);
|
|
101
|
+
try {
|
|
102
|
+
await streaming.start(chatId, resolveReceiveIdType(chatId));
|
|
103
|
+
} catch (error) {
|
|
104
|
+
params.runtime.error?.(`feishu: streaming start failed: ${String(error)}`);
|
|
105
|
+
streaming = null;
|
|
106
|
+
}
|
|
107
|
+
})();
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const closeStreaming = async () => {
|
|
111
|
+
if (streamingStartPromise) {
|
|
112
|
+
await streamingStartPromise;
|
|
113
|
+
}
|
|
114
|
+
await partialUpdateQueue;
|
|
115
|
+
if (streaming?.isActive()) {
|
|
116
|
+
let text = streamText;
|
|
117
|
+
if (mentionTargets?.length) {
|
|
118
|
+
text = buildMentionedCardContent(mentionTargets, text);
|
|
119
|
+
}
|
|
120
|
+
await streaming.close(text);
|
|
121
|
+
}
|
|
122
|
+
streaming = null;
|
|
123
|
+
streamingStartPromise = null;
|
|
124
|
+
streamText = "";
|
|
125
|
+
lastPartial = "";
|
|
126
|
+
};
|
|
98
127
|
|
|
99
128
|
const { dispatcher, replyOptions, markDispatchIdle } =
|
|
100
129
|
core.channel.reply.createReplyDispatcherWithTyping({
|
|
101
130
|
responsePrefix: prefixContext.responsePrefix,
|
|
102
131
|
responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,
|
|
103
132
|
humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, agentId),
|
|
104
|
-
onReplyStart:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
);
|
|
133
|
+
onReplyStart: () => {
|
|
134
|
+
if (streamingEnabled && renderMode === "card") {
|
|
135
|
+
startStreaming();
|
|
136
|
+
}
|
|
137
|
+
void typingCallbacks.onReplyStart?.();
|
|
138
|
+
},
|
|
139
|
+
deliver: async (payload: ReplyPayload, info) => {
|
|
109
140
|
const text = payload.text ?? "";
|
|
110
141
|
if (!text.trim()) {
|
|
111
|
-
params.runtime.log?.(`feishu[${account.accountId}] deliver: empty text, skipping`);
|
|
112
142
|
return;
|
|
113
143
|
}
|
|
114
144
|
|
|
115
|
-
// Check render mode: auto (default), raw, or card
|
|
116
|
-
const feishuCfg = account.config;
|
|
117
|
-
const renderMode = feishuCfg?.renderMode ?? "auto";
|
|
118
|
-
|
|
119
|
-
// Determine if we should use card for this message
|
|
120
145
|
const useCard = renderMode === "card" || (renderMode === "auto" && shouldUseCard(text));
|
|
121
146
|
|
|
122
|
-
|
|
123
|
-
|
|
147
|
+
if ((info?.kind === "block" || info?.kind === "final") && streamingEnabled && useCard) {
|
|
148
|
+
startStreaming();
|
|
149
|
+
if (streamingStartPromise) {
|
|
150
|
+
await streamingStartPromise;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (streaming?.isActive()) {
|
|
155
|
+
if (info?.kind === "final") {
|
|
156
|
+
streamText = text;
|
|
157
|
+
await closeStreaming();
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
124
161
|
|
|
162
|
+
let first = true;
|
|
125
163
|
if (useCard) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
131
|
-
for (const chunk of chunks) {
|
|
164
|
+
for (const chunk of core.channel.text.chunkTextWithMode(
|
|
165
|
+
text,
|
|
166
|
+
textChunkLimit,
|
|
167
|
+
chunkMode,
|
|
168
|
+
)) {
|
|
132
169
|
await sendMarkdownCardFeishu({
|
|
133
170
|
cfg,
|
|
134
171
|
to: chatId,
|
|
135
172
|
text: chunk,
|
|
136
173
|
replyToMessageId,
|
|
137
|
-
mentions:
|
|
174
|
+
mentions: first ? mentionTargets : undefined,
|
|
138
175
|
accountId,
|
|
139
176
|
});
|
|
140
|
-
|
|
177
|
+
first = false;
|
|
141
178
|
}
|
|
142
179
|
} else {
|
|
143
|
-
// Raw mode: send as plain text with table conversion
|
|
144
180
|
const converted = core.channel.text.convertMarkdownTables(text, tableMode);
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
181
|
+
for (const chunk of core.channel.text.chunkTextWithMode(
|
|
182
|
+
converted,
|
|
183
|
+
textChunkLimit,
|
|
184
|
+
chunkMode,
|
|
185
|
+
)) {
|
|
150
186
|
await sendMessageFeishu({
|
|
151
187
|
cfg,
|
|
152
188
|
to: chatId,
|
|
153
189
|
text: chunk,
|
|
154
190
|
replyToMessageId,
|
|
155
|
-
mentions:
|
|
191
|
+
mentions: first ? mentionTargets : undefined,
|
|
156
192
|
accountId,
|
|
157
193
|
});
|
|
158
|
-
|
|
194
|
+
first = false;
|
|
159
195
|
}
|
|
160
196
|
}
|
|
161
197
|
},
|
|
162
|
-
onError: (
|
|
198
|
+
onError: async (error, info) => {
|
|
163
199
|
params.runtime.error?.(
|
|
164
|
-
`feishu[${account.accountId}] ${info.kind} reply failed: ${String(
|
|
200
|
+
`feishu[${account.accountId}] ${info.kind} reply failed: ${String(error)}`,
|
|
165
201
|
);
|
|
202
|
+
await closeStreaming();
|
|
203
|
+
typingCallbacks.onIdle?.();
|
|
204
|
+
},
|
|
205
|
+
onIdle: async () => {
|
|
206
|
+
await closeStreaming();
|
|
166
207
|
typingCallbacks.onIdle?.();
|
|
167
208
|
},
|
|
168
|
-
onIdle: typingCallbacks.onIdle,
|
|
169
209
|
});
|
|
170
210
|
|
|
171
211
|
return {
|
|
@@ -173,6 +213,23 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
|
|
|
173
213
|
replyOptions: {
|
|
174
214
|
...replyOptions,
|
|
175
215
|
onModelSelected: prefixContext.onModelSelected,
|
|
216
|
+
onPartialReply: streamingEnabled
|
|
217
|
+
? (payload: ReplyPayload) => {
|
|
218
|
+
if (!payload.text || payload.text === lastPartial) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
lastPartial = payload.text;
|
|
222
|
+
streamText = payload.text;
|
|
223
|
+
partialUpdateQueue = partialUpdateQueue.then(async () => {
|
|
224
|
+
if (streamingStartPromise) {
|
|
225
|
+
await streamingStartPromise;
|
|
226
|
+
}
|
|
227
|
+
if (streaming?.isActive()) {
|
|
228
|
+
await streaming.update(streamText);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
: undefined,
|
|
176
233
|
},
|
|
177
234
|
markDispatchIdle,
|
|
178
235
|
};
|