@openclaw/slack 2026.9.6 → 2026.9.7
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/assets/icon.png +0 -0
- package/dist/.setup/{account-inspect-DP1Bcwj4.mjs → account-inspect-DWBXpER6.mjs} +1 -1
- package/dist/.setup/{accounts-BBHvg0pY.mjs → accounts-D_N9IqNA.mjs} +23 -1
- package/dist/.setup/{action-runtime-B01d85zt.mjs → action-runtime-DfWvuiZd.mjs} +26 -41
- package/dist/.setup/action-runtime.runtime-Ck4bAWOX.mjs +2 -0
- package/dist/.setup/{actions-DKCtBgCI.mjs → actions-Df0CzcDl.mjs} +88 -175
- package/dist/.setup/{approval-handler.runtime-DMszKn_7.mjs → approval-handler.runtime-Ed6Sw5VK.mjs} +37 -47
- package/dist/.setup/{approval-message-updates-Tb_qRokK.mjs → approval-message-updates-BadvtA7R.mjs} +1 -2
- package/dist/.setup/{channel-CErYZ5zw.mjs → channel-C7bgPSTE.mjs} +181 -273
- package/dist/.setup/channel-meta-C443t-lI.mjs +27 -0
- package/dist/.setup/{channel-type-Dxk8VJUb.mjs → channel-type-ClOttrZ5.mjs} +13 -21
- package/dist/.setup/{channel.setup-BVoUtdPn.mjs → channel.setup-Dh2jzAjN.mjs} +35 -42
- package/dist/.setup/{config-schema-CyL279e7.mjs → config-schema-BZCxmHKG.mjs} +24 -21
- package/dist/.setup/{directory-config-CQTSH45W.mjs → directory-config-BOUWH3hR.mjs} +7 -10
- package/dist/.setup/{directory-live-BCcj89QV.mjs → directory-live-B2O4B_Ho.mjs} +9 -21
- package/dist/.setup/doctor-contract-CRN1Z_c7.mjs +342 -0
- package/dist/.setup/{message-tool-api-C0PTFaNV.mjs → message-tool-api-Cu4lwlGy.mjs} +34 -48
- package/dist/.setup/{provider-C-jPaGt2.mjs → monitor-BPVfkumU.mjs} +2181 -2693
- package/dist/.setup/{outbound-adapter-A7Wdn8ZT.mjs → outbound-adapter-Bv48XUjq.mjs} +10 -21
- package/dist/.setup/{pipeline.runtime-BlPOexmJ.mjs → pipeline.runtime-B1H63Frf.mjs} +311 -457
- package/dist/.setup/{plugin-routes-C3X0eVaK.mjs → plugin-routes-B8tooDLj.mjs} +1 -1
- package/dist/.setup/{policy-BApW53pI.mjs → policy-D-jfM174.mjs} +5 -5
- package/dist/.setup/{probe-DiYIMPJo.mjs → probe-B2Y9qc_z.mjs} +101 -39
- package/dist/.setup/{registry-bbjH7IHX.mjs → registry-CIbMfuf8.mjs} +6 -2
- package/dist/.setup/{relay-source-DfOnjJTE.mjs → relay-source-BpKdjsll.mjs} +10 -12
- package/dist/.setup/{replies-BBAJxUOQ.mjs → replies-BAnUtr2f.mjs} +16 -76
- package/dist/.setup/{reply-blocks-Bm8kf6mK.mjs → reply-blocks-SE1kTE3I.mjs} +27 -154
- package/dist/.setup/{resolve-channels-BXbMBbJD.mjs → resolve-channels-XXBn8UU_.mjs} +4 -5
- package/dist/.setup/{resolve-users-65WqvIqD.mjs → resolve-users-DW0ngD03.mjs} +20 -22
- package/dist/.setup/{scopes-h3YB-mMs.mjs → scopes-CasuDvaa.mjs} +6 -17
- package/dist/.setup/{secret-contract-DxmvbxBF.mjs → secret-contract-BaZcu6P_.mjs} +15 -20
- package/dist/.setup/{secret-contract-api-D9UfYujm.mjs → secret-contract-api-Dp6290Vg.mjs} +1 -1
- package/dist/.setup/{security-audit-BypHqcq5.mjs → security-audit-BqDc-6VL.mjs} +1 -1
- package/dist/.setup/{send-Cp6omkOg.mjs → send-BOVLQi3n.mjs} +84 -171
- package/dist/.setup/{session-status-Cf7AvWOt.mjs → session-status-DscajIsd.mjs} +315 -238
- package/dist/.setup/{setup-plugin-api-dLPkL06L.mjs → setup-plugin-api-DTtbTKNk.mjs} +1 -1
- package/dist/.setup/{setup-surface-D3DLcCxu.mjs → setup-surface-Dn7QgWRE.mjs} +24 -56
- package/dist/.setup/{shared-CJ3arAFL.mjs → shared-qau-uDGl.mjs} +30 -56
- package/dist/.setup/{slash-dispatch.runtime-HFy_XvyO.mjs → slash-dispatch.runtime--AEzLVBF.mjs} +1 -1
- package/dist/.setup/{streaming-compat-B-e0mqM0.mjs → streaming-compat-C5Wut626.mjs} +31 -8
- package/dist/.setup/{target-parsing-DEsPjngB.mjs → target-parsing-FFE26kOV.mjs} +1 -7
- package/dist/.setup/{targets-Cku2KCvg.mjs → targets-C6LZQL1Q.mjs} +1 -1
- package/dist/.setup/{thread-ts-CukseRVL.mjs → thread-ts-Cvt7WD6B.mjs} +0 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/api.js +18 -17
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/http-routes-api.js +1 -1
- package/dist/index.js +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/runtime-api.js +11 -12
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/setup-entry.js +2 -2
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/child_process.d.ts +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +20 -8
- package/node_modules/@slack/bolt/node_modules/@types/node/ffi.d.ts +14 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/http2.d.ts +3 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/net.d.ts +16 -4
- package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/process.d.ts +1 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/quic.d.ts +39 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/stream/iter.d.ts +9 -12
- package/node_modules/@slack/bolt/node_modules/@types/node/test/reporters.d.ts +1 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/test.d.ts +72 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/tls.d.ts +14 -10
- package/node_modules/@slack/bolt/node_modules/@types/node/vm.d.ts +2 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/worker_threads.d.ts +4 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/child_process.d.ts +1 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +20 -8
- package/node_modules/@slack/web-api/node_modules/@types/node/ffi.d.ts +14 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/http2.d.ts +3 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/net.d.ts +16 -4
- package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/process.d.ts +1 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/quic.d.ts +39 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/stream/iter.d.ts +9 -12
- package/node_modules/@slack/web-api/node_modules/@types/node/test/reporters.d.ts +1 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/test.d.ts +72 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/tls.d.ts +14 -10
- package/node_modules/@slack/web-api/node_modules/@types/node/vm.d.ts +2 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/worker_threads.d.ts +4 -1
- package/node_modules/get-east-asian-width/index.js +8 -3
- package/node_modules/get-east-asian-width/lookup-data.js +1 -1
- package/node_modules/get-east-asian-width/lookup.js +4 -4
- package/node_modules/get-east-asian-width/package.json +1 -1
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/node_modules/undici/README.md +81 -25
- package/node_modules/undici/docs/docs/api/Agent.md +249 -42
- package/node_modules/undici/docs/docs/api/BalancedPool.md +246 -48
- package/node_modules/undici/docs/docs/api/CacheStorage.md +171 -13
- package/node_modules/undici/docs/docs/api/CacheStore.md +294 -98
- package/node_modules/undici/docs/docs/api/Client.md +407 -162
- package/node_modules/undici/docs/docs/api/ClientStats.md +80 -14
- package/node_modules/undici/docs/docs/api/Connector.md +118 -35
- package/node_modules/undici/docs/docs/api/ContentType.md +65 -25
- package/node_modules/undici/docs/docs/api/Cookies.md +122 -71
- package/node_modules/undici/docs/docs/api/Debug.md +34 -18
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +364 -164
- package/node_modules/undici/docs/docs/api/Dispatcher.md +490 -1055
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +105 -93
- package/node_modules/undici/docs/docs/api/Errors.md +503 -28
- package/node_modules/undici/docs/docs/api/EventSource.md +326 -13
- package/node_modules/undici/docs/docs/api/Fetch.md +681 -30
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +78 -96
- package/node_modules/undici/docs/docs/api/H2CClient.md +298 -176
- package/node_modules/undici/docs/docs/api/Interceptors.md +418 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +333 -314
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +272 -98
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +189 -26
- package/node_modules/undici/docs/docs/api/MockClient.md +151 -33
- package/node_modules/undici/docs/docs/api/MockErrors.md +56 -5
- package/node_modules/undici/docs/docs/api/MockPool.md +321 -258
- package/node_modules/undici/docs/docs/api/Pool.md +236 -41
- package/node_modules/undici/docs/docs/api/PoolStats.md +119 -13
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +179 -160
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +238 -55
- package/node_modules/undici/docs/docs/api/RetryAgent.md +113 -27
- package/node_modules/undici/docs/docs/api/RetryHandler.md +161 -79
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +166 -72
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +262 -517
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +177 -196
- package/node_modules/undici/docs/docs/api/Util.md +68 -11
- package/node_modules/undici/docs/docs/api/WebSocket.md +475 -80
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +100 -32
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +2 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +233 -0
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +9 -7
- package/node_modules/undici/docs/docs/best-practices/proxy.md +3 -1
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +10 -8
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +2 -0
- package/node_modules/undici/docs/docs/getting-started.md +281 -0
- package/node_modules/undici/docs/docs/index.md +784 -0
- package/node_modules/undici/docs/docs/site.json +125 -0
- package/node_modules/undici/docs/docs/type-map.json +79 -0
- package/node_modules/undici/index.js +4 -2
- package/node_modules/undici/lib/api/api-connect.js +13 -11
- package/node_modules/undici/lib/api/api-pipeline.js +26 -13
- package/node_modules/undici/lib/api/api-request.js +51 -21
- package/node_modules/undici/lib/api/api-stream.js +81 -20
- package/node_modules/undici/lib/api/api-upgrade.js +21 -11
- package/node_modules/undici/lib/api/readable.js +45 -9
- package/node_modules/undici/lib/cache/memory-cache-store.js +3 -3
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +3 -1
- package/node_modules/undici/lib/core/connect.js +46 -7
- package/node_modules/undici/lib/core/constants.js +1 -24
- package/node_modules/undici/lib/core/errors.js +22 -2
- package/node_modules/undici/lib/core/request.js +100 -18
- package/node_modules/undici/lib/core/symbols.js +4 -0
- package/node_modules/undici/lib/core/util.js +105 -48
- package/node_modules/undici/lib/dispatcher/agent.js +51 -32
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +23 -27
- package/node_modules/undici/lib/dispatcher/client-h1.js +86 -24
- package/node_modules/undici/lib/dispatcher/client-h2.js +1091 -361
- package/node_modules/undici/lib/dispatcher/client.js +109 -36
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +19 -6
- package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -5
- package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +110 -0
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +37 -8
- package/node_modules/undici/lib/dispatcher/h2c-client.js +4 -4
- package/node_modules/undici/lib/dispatcher/pool-base.js +28 -10
- package/node_modules/undici/lib/dispatcher/pool.js +30 -5
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +95 -19
- package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +32 -10
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +153 -63
- package/node_modules/undici/lib/global.js +37 -14
- package/node_modules/undici/lib/handler/cache-handler.js +49 -7
- package/node_modules/undici/lib/handler/cache-revalidation-handler.js +10 -0
- package/node_modules/undici/lib/handler/decorator-handler.js +8 -3
- package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
- package/node_modules/undici/lib/handler/redirect-handler.js +66 -66
- package/node_modules/undici/lib/handler/retry-handler.js +191 -50
- package/node_modules/undici/lib/interceptor/cache.js +75 -25
- package/node_modules/undici/lib/interceptor/decompress.js +5 -2
- package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
- package/node_modules/undici/lib/interceptor/dns.js +12 -1
- package/node_modules/undici/lib/interceptor/redirect.js +3 -3
- package/node_modules/undici/lib/llhttp/llhttp-wasm.js +1 -1
- package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +1 -1
- package/node_modules/undici/lib/mock/mock-agent.js +21 -9
- package/node_modules/undici/lib/mock/mock-call-history.js +1 -1
- package/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
- package/node_modules/undici/lib/mock/mock-utils.js +281 -47
- package/node_modules/undici/lib/mock/snapshot-agent.js +25 -7
- package/node_modules/undici/lib/mock/snapshot-recorder.js +38 -3
- package/node_modules/undici/lib/util/cache.js +92 -10
- package/node_modules/undici/lib/util/runtime-features.js +3 -34
- package/node_modules/undici/lib/web/cache/cache.js +6 -8
- package/node_modules/undici/lib/web/cookies/parse.js +150 -146
- package/node_modules/undici/lib/web/cookies/util.js +1 -1
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +20 -21
- package/node_modules/undici/lib/web/eventsource/util.js +32 -1
- package/node_modules/undici/lib/web/fetch/body.js +48 -10
- package/node_modules/undici/lib/web/fetch/constants.js +1 -1
- package/node_modules/undici/lib/web/fetch/formdata.js +21 -2
- package/node_modules/undici/lib/web/fetch/index.js +242 -223
- package/node_modules/undici/lib/web/fetch/request.js +35 -6
- package/node_modules/undici/lib/web/fetch/response.js +1 -3
- package/node_modules/undici/lib/web/fetch/util.js +10 -2
- package/node_modules/undici/lib/web/webidl/index.js +5 -7
- package/node_modules/undici/lib/web/websocket/frame.js +1 -7
- package/node_modules/undici/lib/web/websocket/receiver.js +1 -1
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +10 -10
- package/node_modules/undici/lib/web/websocket/websocket.js +25 -3
- package/node_modules/undici/package.json +10 -10
- package/node_modules/undici/types/agent.d.ts +0 -2
- package/node_modules/undici/types/client.d.ts +69 -24
- package/node_modules/undici/types/connector.d.ts +1 -0
- package/node_modules/undici/types/cookies.d.ts +1 -1
- package/node_modules/undici/types/dispatcher.d.ts +8 -30
- package/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
- package/node_modules/undici/types/errors.d.ts +10 -0
- package/node_modules/undici/types/fetch.d.ts +5 -1
- package/node_modules/undici/types/formdata.d.ts +0 -6
- package/node_modules/undici/types/h2c-client.d.ts +6 -6
- package/node_modules/undici/types/handlers.d.ts +2 -0
- package/node_modules/undici/types/header.d.ts +5 -0
- package/node_modules/undici/types/index.d.ts +3 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/mock-agent.d.ts +11 -10
- package/node_modules/undici/types/mock-interceptor.d.ts +5 -1
- package/node_modules/undici/types/pool.d.ts +0 -2
- package/node_modules/undici/types/proxy-agent.d.ts +9 -2
- package/node_modules/undici/types/round-robin-pool.d.ts +0 -2
- package/node_modules/undici/types/snapshot-agent.d.ts +4 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +4 -2
- package/node_modules/undici/types/webidl.d.ts +0 -1
- package/openclaw.plugin.json +31 -3
- package/package.json +7 -7
- package/dist/.setup/accounts.runtime-DN-PPocC.mjs +0 -2
- package/dist/.setup/action-runtime.runtime-C8R8CUan.mjs +0 -2
- package/dist/.setup/doctor-contract-CtMUqjvk.mjs +0 -186
- package/dist/.setup/monitor-_Sht7Dqy.mjs +0 -13
- package/dist/.setup/rolldown-runtime-D7D4PA-g.mjs +0 -13
- package/dist/.setup/send.runtime-B4caZU6T.mjs +0 -2
- package/dist/.setup/slash-commands.runtime-BpSH0b3q.mjs +0 -2
- package/dist/.setup/slash-skill-commands.runtime-Bi1JWZHY.mjs +0 -2
- package/node_modules/undici/lib/handler/unwrap-handler.js +0 -106
- package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
- package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/node_modules/undici/lib/util/promise.js +0 -28
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { n as resolveSlackChannelConfig } from "./policy-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
1
|
+
import { i as __reExport, n as resolveSlackStreamingMode, r as __exportAll, t as resolveSlackNativeStreaming } from "./streaming-compat-C5Wut626.mjs";
|
|
2
|
+
import { f as resolveSlackReplyToMode } from "./accounts-D_N9IqNA.mjs";
|
|
3
|
+
import { n as formatSlackTarget } from "./target-parsing-FFE26kOV.mjs";
|
|
4
|
+
import { A as countSlackTextUtf8Bytes, C as buildSlackBlocksFallbackText, E as SLACK_EDIT_TEXT_MAX_BYTES, H as SLACK_SESSION_LINK_ACTION_ID, M as truncateSlackTextByUtf8Bytes, Q as normalizeSlackOutboundText, c as qualifySlackRoutePeerId, j as truncateSlackText, k as SLACK_TEXT_LIMIT, lt as escapeSlackMrkdwn, v as hasSlackNativeDataBlock, w as buildSlackCompleteBlocksFallbackText } from "./session-status-DscajIsd.mjs";
|
|
5
|
+
import { D as normalizeSlackAllowOwnerEntry, j as resolveSlackUserAllowed, o as formatSlackError, v as readLruMapEntry, y as writeLruMapEntry } from "./probe-B2Y9qc_z.mjs";
|
|
6
|
+
import { a as prepareSlackReply, l as resolveSlackReplyRenderPlan, s as resolveSlackReplyBlocks } from "./reply-blocks-SE1kTE3I.mjs";
|
|
7
|
+
import { n as resolveSlackReplyThreadTs } from "./thread-ts-Cvt7WD6B.mjs";
|
|
8
|
+
import { C as hasSlackTableBlock, D as buildSlackEditTextPayload, E as resolveSlackMessageText$1, T as resolveSlackBlocksText, a as editSlackRenderedMessage, b as formatSlackFileReference, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, w as isSlackUnfurlAttachment, x as formatSlackFileReferenceList } from "./actions-Df0CzcDl.mjs";
|
|
9
|
+
import { c as hasSlackThreadParticipationWithPersistence, i as clearSlackThreadFailureNotice, l as recordSlackThreadFailureNotice, o as hasSlackThreadFailureNotice, p as buildSlackNativeDataDeliveryPlan, s as hasSlackThreadParticipation, t as sendMessageSlack, u as recordSlackThreadParticipation } from "./send-BOVLQi3n.mjs";
|
|
10
|
+
import { n as resolveSlackChannelConfig } from "./policy-D-jfM174.mjs";
|
|
11
|
+
import { C as resolveSlackChatType, E as stripSlackMentionsForCommandDetection, S as normalizeSlackChannelType, T as readSlackAssistantThreadContext, _ as appendSlackStream, b as stopSlackStream, c as resolveSlackRoutingContext, g as SlackStreamNotDeliveredError, h as resolveSlackEffectiveAllowFrom, i as resolveSlackRoomContextHints, l as registerSlackSessionRun, m as resolveSlackCommandIngress, p as authorizeSlackBotRoomMessage, r as trackSlackDraftMessage, s as authorizeSlackDirectMessage, u as resolveSlackThreadContext, v as markSlackStreamFallbackDelivered, w as buildSlackAssistantThreadMetadata, y as startSlackStream } from "./monitor-BPVfkumU.mjs";
|
|
12
|
+
import { a as emitSlackMessageSentHooks, i as sanitizeSlackMonitorReplyPayload, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-BAnUtr2f.mjs";
|
|
13
|
+
import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readNonBlankString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
13
14
|
import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
14
|
-
import { buildChannelProgressDraftLine, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressWorkCounter, createDraftStreamLoop, createFinalizableDraftLifecycle, createLivePreviewLifecycle, createMessageReceiptFromOutboundResults, formatChannelProgressDraftDiffStat,
|
|
15
|
+
import { buildChannelProgressDraftLine, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressWorkCounter, createDraftStreamLoop, createFinalizableDraftLifecycle, createLivePreviewLifecycle, createMessageReceiptFromOutboundResults, formatChannelProgressDraftDiffStat, formatPlanChecklistLines, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
|
|
15
16
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
16
17
|
import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
17
18
|
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
18
19
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
20
|
+
import { normalizeStringEntriesLower } from "openclaw/plugin-sdk/string-normalization-runtime";
|
|
21
|
+
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
19
22
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
20
23
|
import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement, isReplyPayloadNonTerminalToolErrorWarning, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
21
24
|
import { asDateTimestampMs, asFiniteNumberInRange, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit } from "openclaw/plugin-sdk/number-runtime";
|
|
22
25
|
import { hash } from "node:crypto";
|
|
23
|
-
import {
|
|
24
|
-
import { ensureConfiguredBindingRouteReady } from "openclaw/plugin-sdk/conversation-runtime";
|
|
26
|
+
import { ensureConfiguredBindingRouteReady, resolveConversationLabel } from "openclaw/plugin-sdk/conversation-runtime";
|
|
25
27
|
import { resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
26
28
|
import fs from "node:fs/promises";
|
|
27
29
|
import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
@@ -29,16 +31,18 @@ import { formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-run
|
|
|
29
31
|
import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
|
|
30
32
|
import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
|
|
31
33
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
34
|
+
import { getSessionEntry, readSessionUpdatedAt, resolveChannelResetConfig, resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
|
|
32
35
|
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
33
36
|
import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
34
37
|
import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
|
|
35
|
-
import { buildChannelInboundEventContext, buildMentionRegexes, classifyChannelInboundEvent, dispatchChannelInboundTurn, formatInboundEnvelope, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch,
|
|
38
|
+
import { buildChannelInboundEventContext, buildMentionRegexes, classifyChannelInboundEvent, dispatchChannelInboundTurn, formatInboundEnvelope, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, isGroupThreadRouteExclusive, matchesMentionWithExplicit, readAgentRunTerminalOutcome, resolveEnvelopeFormatOptions, resolveGroupThreadConfig, resolveGroupThreadMentionFacts, resolveInboundMentionDecision, resolveInboundReplyDispatchCounts, resolveUnmentionedGroupInboundPolicy, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
|
|
36
39
|
import { resolveGatewayPublicOrigin } from "openclaw/plugin-sdk/config-contracts";
|
|
37
40
|
import { buildControlUiSessionPath } from "openclaw/plugin-sdk/session-discussion";
|
|
38
41
|
import { createStatusReactionController, logAckFailure, logTypingFailure, resolveAckReaction, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
39
42
|
import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
|
|
40
43
|
import { isAbortRequestText } from "openclaw/plugin-sdk/command-primitives-runtime";
|
|
41
44
|
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
|
|
45
|
+
import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
42
46
|
import { DEFAULT_GROUP_HISTORY_LIMIT, buildHistoryContextFromEntries, buildInboundHistoryFromEntries } from "openclaw/plugin-sdk/reply-history";
|
|
43
47
|
import { createChannelPreflightAudio, formatAudioTranscriptForAgent } from "openclaw/plugin-sdk/media-understanding-runtime";
|
|
44
48
|
//#region extensions/slack/src/monitor/message-handler/timestamp.ts
|
|
@@ -55,9 +59,6 @@ function resolveSlackTimestampMs(ts) {
|
|
|
55
59
|
}
|
|
56
60
|
//#endregion
|
|
57
61
|
//#region extensions/slack/src/monitor/message-handler/dispatch-helpers.ts
|
|
58
|
-
function resolveSlackMessageTimestampMs(message) {
|
|
59
|
-
return resolveSlackTimestampMs(message.event_ts ?? message.ts);
|
|
60
|
-
}
|
|
61
62
|
function resolveSlackBotLoopProtection(prepared) {
|
|
62
63
|
const senderBotId = prepared.message.bot_id;
|
|
63
64
|
if (!senderBotId) return;
|
|
@@ -71,7 +72,7 @@ function resolveSlackBotLoopProtection(prepared) {
|
|
|
71
72
|
config: mergePairLoopGuardConfig(prepared.account.config.botLoopProtection, prepared.channelConfig?.botLoopProtection),
|
|
72
73
|
defaultsConfig: prepared.ctx.cfg.channels?.defaults?.botLoopProtection,
|
|
73
74
|
defaultEnabled: true,
|
|
74
|
-
nowMs:
|
|
75
|
+
nowMs: resolveSlackTimestampMs(prepared.message.event_ts ?? prepared.message.ts)
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
function isSlackStreamingEnabled(params) {
|
|
@@ -89,26 +90,14 @@ function resolveExplicitSlackProgressTitle(entry) {
|
|
|
89
90
|
const trimmed = label.trim();
|
|
90
91
|
return trimmed && trimmed.toLowerCase() !== "auto" ? trimmed : void 0;
|
|
91
92
|
}
|
|
92
|
-
function resolveSlackProgressStyle(entry) {
|
|
93
|
+
function resolveSlackProgressStyle(entry, hasReplyThread) {
|
|
93
94
|
const progress = entry?.streaming?.progress;
|
|
95
|
+
if (!hasReplyThread && !Object.entries(progress ?? {}).some(([key, value]) => key !== "nativeTaskCards" || value !== true)) return "none";
|
|
94
96
|
return progress?.style ?? (progress?.toolProgress === false ? "compact" : "card");
|
|
95
97
|
}
|
|
96
|
-
function resolveSlackNativeProgressTaskCards(entry) {
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
if (!streaming || typeof streaming !== "object" || Array.isArray(streaming)) return true;
|
|
100
|
-
const progressConfig = streaming.progress;
|
|
101
|
-
if (!progressConfig || typeof progressConfig !== "object" || Array.isArray(progressConfig)) return true;
|
|
102
|
-
return progressConfig.nativeTaskCards !== false;
|
|
103
|
-
}
|
|
104
|
-
function resolveSlackStreamingThreadHint(params) {
|
|
105
|
-
return resolveSlackThreadTs({
|
|
106
|
-
replyToMode: params.replyToMode,
|
|
107
|
-
incomingThreadTs: params.incomingThreadTs,
|
|
108
|
-
messageTs: params.messageTs,
|
|
109
|
-
hasReplied: false,
|
|
110
|
-
isThreadReply: params.isThreadReply
|
|
111
|
-
});
|
|
98
|
+
function resolveSlackNativeProgressTaskCards(entry, style) {
|
|
99
|
+
if (style !== "card") return false;
|
|
100
|
+
return entry?.streaming?.progress?.nativeTaskCards !== false;
|
|
112
101
|
}
|
|
113
102
|
const SLACK_STREAM_RECIPIENT_TEAM_CACHE_MAX = 2e3;
|
|
114
103
|
const slackStreamRecipientTeamCaches = /* @__PURE__ */ new WeakMap();
|
|
@@ -123,7 +112,7 @@ function buildSlackEventDeliveryKey(params, preparedReply = prepareSlackReply(pa
|
|
|
123
112
|
const reply = resolveSendableOutboundReplyParts(params.payload, { text: params.textOverride });
|
|
124
113
|
const renderPlan = preparedReply.resolvePreview(params.textOverride);
|
|
125
114
|
const plannedBlocks = renderPlan.mode === "single" ? renderPlan.blocks : renderPlan.blockPart?.blocks;
|
|
126
|
-
const slackBlocks =
|
|
115
|
+
const slackBlocks = resolveSlackReplyBlocks(params.payload) ?? plannedBlocks;
|
|
127
116
|
const renderedText = renderPlan.mode === "single" ? renderPlan.text : renderPlan.fallbackText;
|
|
128
117
|
if (!reply.hasContent && !slackBlocks?.length && !renderedText.trim()) return null;
|
|
129
118
|
return JSON.stringify({
|
|
@@ -135,27 +124,6 @@ function buildSlackEventDeliveryKey(params, preparedReply = prepareSlackReply(pa
|
|
|
135
124
|
blocks: slackBlocks ?? null
|
|
136
125
|
});
|
|
137
126
|
}
|
|
138
|
-
function readSlackStreamRecipientTeamCache(params) {
|
|
139
|
-
if (!params.fallbackTeamId || !params.userId) return;
|
|
140
|
-
const cacheKey = `${params.fallbackTeamId}:${params.userId}`;
|
|
141
|
-
const cache = getSlackStreamRecipientTeamCache(params.client);
|
|
142
|
-
const cached = cache.get(cacheKey);
|
|
143
|
-
if (!cached) return;
|
|
144
|
-
cache.delete(cacheKey);
|
|
145
|
-
cache.set(cacheKey, cached);
|
|
146
|
-
return cached;
|
|
147
|
-
}
|
|
148
|
-
function rememberSlackStreamRecipientTeam(params) {
|
|
149
|
-
if (!params.fallbackTeamId || !params.userId) return;
|
|
150
|
-
const cacheKey = `${params.fallbackTeamId}:${params.userId}`;
|
|
151
|
-
const cache = getSlackStreamRecipientTeamCache(params.client);
|
|
152
|
-
if (cache.has(cacheKey)) cache.delete(cacheKey);
|
|
153
|
-
cache.set(cacheKey, params.teamId);
|
|
154
|
-
if (cache.size > SLACK_STREAM_RECIPIENT_TEAM_CACHE_MAX) {
|
|
155
|
-
const oldest = cache.keys().next().value;
|
|
156
|
-
if (oldest) cache.delete(oldest);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
127
|
function createSlackEventDeliveryTracker() {
|
|
160
128
|
const deliveredKeys = /* @__PURE__ */ new Set();
|
|
161
129
|
return {
|
|
@@ -176,7 +144,9 @@ function shouldUseStreaming(params) {
|
|
|
176
144
|
return true;
|
|
177
145
|
}
|
|
178
146
|
async function resolveSlackStreamRecipientTeamId(params) {
|
|
179
|
-
const
|
|
147
|
+
const cacheKey = params.fallbackTeamId && params.userId ? `${params.fallbackTeamId}:${params.userId}` : void 0;
|
|
148
|
+
const cache = cacheKey ? getSlackStreamRecipientTeamCache(params.client) : void 0;
|
|
149
|
+
const cachedTeamId = cache && cacheKey ? readLruMapEntry(cache, cacheKey) : void 0;
|
|
180
150
|
if (cachedTeamId) return cachedTeamId;
|
|
181
151
|
if (params.userId) try {
|
|
182
152
|
const info = await params.client.users.info({
|
|
@@ -185,10 +155,7 @@ async function resolveSlackStreamRecipientTeamId(params) {
|
|
|
185
155
|
});
|
|
186
156
|
const teamId = info.user?.team_id ?? info.user?.profile?.team;
|
|
187
157
|
if (teamId) {
|
|
188
|
-
|
|
189
|
-
...params,
|
|
190
|
-
teamId
|
|
191
|
-
});
|
|
158
|
+
if (cache && cacheKey) writeLruMapEntry(cache, cacheKey, teamId, SLACK_STREAM_RECIPIENT_TEAM_CACHE_MAX);
|
|
192
159
|
return teamId;
|
|
193
160
|
}
|
|
194
161
|
} catch (err) {
|
|
@@ -217,6 +184,11 @@ function createSlackDraftStream(params) {
|
|
|
217
184
|
final: false
|
|
218
185
|
};
|
|
219
186
|
const normalizeUpdate = (update) => typeof update === "string" ? { text: update } : update;
|
|
187
|
+
const clearMessageId = () => {
|
|
188
|
+
streamMessage = void 0;
|
|
189
|
+
lastVisibleUpdate = void 0;
|
|
190
|
+
lastSentKey = "";
|
|
191
|
+
};
|
|
220
192
|
const sendOrEditStreamMessage = async (pending) => {
|
|
221
193
|
if (streamState.stopped) return;
|
|
222
194
|
const update = normalizeUpdate(pending);
|
|
@@ -316,11 +288,7 @@ function createSlackDraftStream(params) {
|
|
|
316
288
|
emptyValue: "",
|
|
317
289
|
isEmpty: (value) => !normalizeUpdate(value).text.trim(),
|
|
318
290
|
readMessageId: () => streamMessage,
|
|
319
|
-
clearMessageId
|
|
320
|
-
streamMessage = void 0;
|
|
321
|
-
lastVisibleUpdate = void 0;
|
|
322
|
-
lastSentKey = "";
|
|
323
|
-
},
|
|
291
|
+
clearMessageId,
|
|
324
292
|
isValidMessageId: (value) => typeof value === "object" && value !== null,
|
|
325
293
|
deleteMessage: async (message) => {
|
|
326
294
|
if (message.generation > cleanupGeneration) return false;
|
|
@@ -359,9 +327,7 @@ function createSlackDraftStream(params) {
|
|
|
359
327
|
await discardPendingAndStopTracking();
|
|
360
328
|
if (generation === streamGeneration) {
|
|
361
329
|
clearingMessage = streamMessage;
|
|
362
|
-
|
|
363
|
-
lastVisibleUpdate = void 0;
|
|
364
|
-
lastSentKey = "";
|
|
330
|
+
clearMessageId();
|
|
365
331
|
}
|
|
366
332
|
}
|
|
367
333
|
cleanupGeneration = generation;
|
|
@@ -384,9 +350,7 @@ function createSlackDraftStream(params) {
|
|
|
384
350
|
streamMessage.detachedByHuman = reason === "human";
|
|
385
351
|
lifecycle.retire(streamMessage, { defer: true });
|
|
386
352
|
}
|
|
387
|
-
|
|
388
|
-
lastVisibleUpdate = void 0;
|
|
389
|
-
lastSentKey = "";
|
|
353
|
+
clearMessageId();
|
|
390
354
|
loop.resetPending();
|
|
391
355
|
};
|
|
392
356
|
const finalizeMessage = async (messageId, editFinal) => {
|
|
@@ -487,12 +451,11 @@ const SLACK_PROGRESS_TASK_TITLE_MAX = 120;
|
|
|
487
451
|
const SLACK_PROGRESS_PLAN_FALLBACK_TITLE = "Thinking";
|
|
488
452
|
const SLACK_PROGRESS_LINE_DELTA_RE = /(?:^|\s)\+(\d+)\s+[−-](\d+)(?=\s|$)/u;
|
|
489
453
|
const SLACK_ATTENTION_TASK_PREFIX = "openclaw-attention-";
|
|
490
|
-
function buildSessionSources(
|
|
491
|
-
return
|
|
454
|
+
function buildSessionSources(links) {
|
|
455
|
+
return links.map((link) => ({
|
|
492
456
|
type: "url_source",
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
}];
|
|
457
|
+
...link
|
|
458
|
+
}));
|
|
496
459
|
}
|
|
497
460
|
function field(text) {
|
|
498
461
|
return {
|
|
@@ -648,12 +611,13 @@ function buildSlackProgressStreamChunks(params) {
|
|
|
648
611
|
});
|
|
649
612
|
}
|
|
650
613
|
const headline = params.title?.trim() || params.label?.trim();
|
|
614
|
+
const summaryTitle = params.finalInProgressStatus === "error" ? "Failed" : params.finalInProgressStatus === "complete" || !params.summaryRow ? "Completed" : "Working";
|
|
651
615
|
const newest = tasks.at(-1);
|
|
652
|
-
const title = compactChunkText(headline || (newest?.details ? `${newest.title} — ${newest.details}` : newest?.title) || (params.summaryRow ?
|
|
616
|
+
const title = compactChunkText(headline || (newest?.details ? `${newest.title} — ${newest.details}` : newest?.title) || (params.summaryRow ? summaryTitle : attention.at(-1)?.title) || SLACK_PROGRESS_PLAN_FALLBACK_TITLE);
|
|
653
617
|
const diffOutput = formatTaskDiffOutput(params.diffStat);
|
|
654
|
-
if (tasks.length === 0 && (params.summaryRow || params.
|
|
618
|
+
if (tasks.length === 0 && (params.summaryRow || params.sessionLinks?.length || diffOutput)) tasks.push({
|
|
655
619
|
id: "openclaw_summary",
|
|
656
|
-
title: params.summaryRow ? compactTitle(title) :
|
|
620
|
+
title: params.summaryRow ? compactTitle(title) : summaryTitle,
|
|
657
621
|
status: params.finalInProgressStatus ?? (params.summaryRow ? "in_progress" : "complete")
|
|
658
622
|
});
|
|
659
623
|
tasks.push(...attention);
|
|
@@ -675,7 +639,7 @@ function buildSlackProgressStreamChunks(params) {
|
|
|
675
639
|
if (task.details) chunk.details = task.details;
|
|
676
640
|
if (task.output) chunk.output = task.output;
|
|
677
641
|
if (index === finalTaskIndex && diffOutput) chunk.output = [task.output, diffOutput].filter(Boolean).join(" · ");
|
|
678
|
-
if (index === finalTaskIndex && params.
|
|
642
|
+
if (index === finalTaskIndex && params.sessionLinks?.length) chunk.sources = buildSessionSources(params.sessionLinks);
|
|
679
643
|
return chunk;
|
|
680
644
|
});
|
|
681
645
|
return [{
|
|
@@ -727,7 +691,7 @@ function buildSlackProgressCardBlocks(params) {
|
|
|
727
691
|
buildActivityText(params.lines.filter((line) => line.kind !== "approval" && lineTaskStatus(line) !== "error"), maxLineChars),
|
|
728
692
|
joinRecentProgressRows(attention)
|
|
729
693
|
];
|
|
730
|
-
const title = params.title
|
|
694
|
+
const title = params.title?.trim() || (params.state === "working" ? "Working" : params.state === "success" ? "Done" : "Failed");
|
|
731
695
|
const blocks = [
|
|
732
696
|
params.titleFormat === "plain" ? progressTextSection({
|
|
733
697
|
text: `${icon} ${title}`,
|
|
@@ -746,17 +710,17 @@ function buildSlackProgressCardBlocks(params) {
|
|
|
746
710
|
type: "context",
|
|
747
711
|
elements: [field(footer)]
|
|
748
712
|
});
|
|
749
|
-
if (params.state !== "working" && params.
|
|
713
|
+
if (params.state !== "working" && params.sessionLinks?.length) blocks.push({
|
|
750
714
|
type: "actions",
|
|
751
|
-
elements:
|
|
715
|
+
elements: params.sessionLinks.map((link, index) => ({
|
|
752
716
|
type: "button",
|
|
753
|
-
action_id: SLACK_SESSION_LINK_ACTION_ID
|
|
717
|
+
action_id: index === 0 ? SLACK_SESSION_LINK_ACTION_ID : `${SLACK_SESSION_LINK_ACTION_ID}:${index}`,
|
|
754
718
|
text: {
|
|
755
719
|
type: "plain_text",
|
|
756
|
-
text:
|
|
720
|
+
text: link.text
|
|
757
721
|
},
|
|
758
|
-
url:
|
|
759
|
-
}
|
|
722
|
+
url: link.url
|
|
723
|
+
}))
|
|
760
724
|
});
|
|
761
725
|
return blocks.slice(0, 50);
|
|
762
726
|
}
|
|
@@ -941,25 +905,20 @@ function blocksMatch(expected, actual) {
|
|
|
941
905
|
}
|
|
942
906
|
}
|
|
943
907
|
async function readSlackMessageAfterEditError(params) {
|
|
944
|
-
|
|
945
|
-
token: params.token,
|
|
946
|
-
channel: params.channelId,
|
|
947
|
-
ts: params.threadTs,
|
|
948
|
-
latest: params.messageId,
|
|
949
|
-
oldest: params.messageId,
|
|
950
|
-
inclusive: true,
|
|
951
|
-
limit: 1
|
|
952
|
-
})).messages ?? []).find((message) => message?.ts === params.messageId) ?? null;
|
|
953
|
-
const message = (await params.client.conversations.history({
|
|
908
|
+
const query = {
|
|
954
909
|
token: params.token,
|
|
955
910
|
channel: params.channelId,
|
|
956
911
|
latest: params.messageId,
|
|
957
912
|
oldest: params.messageId,
|
|
958
913
|
inclusive: true,
|
|
959
914
|
limit: 1
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
|
|
915
|
+
};
|
|
916
|
+
const result = params.threadTs ? await params.client.conversations.replies({
|
|
917
|
+
...query,
|
|
918
|
+
ts: params.threadTs
|
|
919
|
+
}) : await params.client.conversations.history(query);
|
|
920
|
+
const message = params.threadTs ? result.messages?.find((entry) => entry?.ts === params.messageId) : result.messages?.[0];
|
|
921
|
+
return message?.ts && message.ts === params.messageId ? message : null;
|
|
963
922
|
}
|
|
964
923
|
async function didSlackPreviewEditApplyAfterError(params) {
|
|
965
924
|
const readback = await readSlackMessageAfterEditError(params);
|
|
@@ -986,15 +945,7 @@ async function finalizeSlackPreviewEdit(params) {
|
|
|
986
945
|
});
|
|
987
946
|
} catch (err) {
|
|
988
947
|
try {
|
|
989
|
-
if (await didSlackPreviewEditApplyAfterError({
|
|
990
|
-
client: params.client,
|
|
991
|
-
token: params.token,
|
|
992
|
-
channelId: params.channelId,
|
|
993
|
-
messageId: params.messageId,
|
|
994
|
-
text: params.text,
|
|
995
|
-
blocks: params.blocks,
|
|
996
|
-
threadTs: params.threadTs
|
|
997
|
-
})) {
|
|
948
|
+
if (await didSlackPreviewEditApplyAfterError(params)) {
|
|
998
949
|
logVerbose(`slack: preview final edit response failed but readback matched message ${params.channelId}/${params.messageId}; suppressing duplicate fallback send`);
|
|
999
950
|
return;
|
|
1000
951
|
}
|
|
@@ -1006,37 +957,39 @@ async function finalizeSlackPreviewEdit(params) {
|
|
|
1006
957
|
}
|
|
1007
958
|
//#endregion
|
|
1008
959
|
//#region extensions/slack/src/monitor/message-handler/dispatch-progress-card.ts
|
|
960
|
+
const MAX_VISIBLE_WORK_LINKS = 5;
|
|
1009
961
|
function createSlackDraftProgressCardRuntime(params) {
|
|
1010
962
|
const { account, cfg, ctx, prepared, slackClient } = params.setup;
|
|
1011
|
-
let latestFallbackText = "";
|
|
1012
963
|
let finalStatus;
|
|
1013
|
-
const
|
|
1014
|
-
|
|
964
|
+
const visibleWorkSessions = /* @__PURE__ */ new Map();
|
|
965
|
+
const resolveSessionLinks = () => {
|
|
966
|
+
if (visibleWorkSessions.size > 0) return [...visibleWorkSessions.values()].slice(0, MAX_VISIBLE_WORK_LINKS).map((session, index) => {
|
|
967
|
+
const label = session.label?.replace(/\s+/g, " ").trim();
|
|
968
|
+
return {
|
|
969
|
+
url: session.url,
|
|
970
|
+
text: visibleWorkSessions.size === 1 ? "Open work session" : truncateSlackText(label ? `Open ${label}` : `Open work session ${index + 1}`, 75)
|
|
971
|
+
};
|
|
972
|
+
});
|
|
973
|
+
if (cfg.gateway?.controlUi?.enabled === false) return [];
|
|
1015
974
|
const publicOrigin = resolveGatewayPublicOrigin(cfg);
|
|
1016
|
-
if (!publicOrigin) return;
|
|
975
|
+
if (!publicOrigin) return [];
|
|
1017
976
|
const url = new URL(publicOrigin);
|
|
1018
977
|
const path = buildControlUiSessionPath({
|
|
1019
978
|
namespace: "chat",
|
|
1020
|
-
sessionKey: prepared.route.sessionKey,
|
|
979
|
+
sessionKey: prepared.ctxPayload.SessionKey ?? prepared.route.sessionKey,
|
|
1021
980
|
fallbackAgentId: prepared.route.agentId,
|
|
981
|
+
mainKey: cfg.session?.mainKey,
|
|
1022
982
|
basePath: cfg.gateway?.controlUi?.basePath
|
|
1023
983
|
});
|
|
1024
|
-
if (!path) return;
|
|
984
|
+
if (!path) return [];
|
|
1025
985
|
url.pathname = path;
|
|
1026
|
-
return
|
|
986
|
+
return [{
|
|
987
|
+
url: url.toString(),
|
|
988
|
+
text: "Open in OpenClaw"
|
|
989
|
+
}];
|
|
1027
990
|
};
|
|
1028
|
-
const resolveText = (snapshot) => latestFallbackText || formatChannelProgressDraftText({
|
|
1029
|
-
entry: account.config,
|
|
1030
|
-
lines: [...snapshot.lines],
|
|
1031
|
-
seed: params.progressSeed,
|
|
1032
|
-
formatLine: formatSlackProgressDraftLine,
|
|
1033
|
-
narration: snapshot.statusHeadline,
|
|
1034
|
-
narrationFormat: snapshot.statusHeadlineFormat,
|
|
1035
|
-
plan: snapshot.plan,
|
|
1036
|
-
diffStat: snapshot.diffStat
|
|
1037
|
-
});
|
|
1038
991
|
const resolvePresentation = (snapshot, state) => {
|
|
1039
|
-
const title = params.explicitTitle ?? snapshot.statusHeadline
|
|
992
|
+
const title = params.explicitTitle ?? snapshot.statusHeadline;
|
|
1040
993
|
const titleFormat = params.explicitTitle ? void 0 : snapshot.statusHeadlineFormat;
|
|
1041
994
|
const narration = params.explicitTitle ? snapshot.statusHeadlineFormat === "plain" || snapshot.planExplanationFormat === "plain" ? [...snapshot.statusHeadline && (snapshot.statusHeadline !== snapshot.planExplanation || snapshot.statusHeadlineFormat !== snapshot.planExplanationFormat) ? [{
|
|
1042
995
|
text: snapshot.statusHeadline,
|
|
@@ -1049,7 +1002,7 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1049
1002
|
format: snapshot.planExplanationFormat
|
|
1050
1003
|
}] : void 0;
|
|
1051
1004
|
const workCounter = state === "working" ? params.progressWorkCounter : void 0;
|
|
1052
|
-
const
|
|
1005
|
+
const sessionLinks = state === "working" ? [] : resolveSessionLinks();
|
|
1053
1006
|
return buildSlackProgressCardBlocks({
|
|
1054
1007
|
state,
|
|
1055
1008
|
title,
|
|
@@ -1061,10 +1014,10 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1061
1014
|
diffStat: snapshot.diffStat,
|
|
1062
1015
|
toolCalls: workCounter?.toolCalls,
|
|
1063
1016
|
elapsedSeconds: workCounter?.elapsedSeconds,
|
|
1064
|
-
|
|
1017
|
+
sessionLinks
|
|
1065
1018
|
});
|
|
1066
1019
|
};
|
|
1067
|
-
const finalize = async (status, snapshot = params.getSnapshot()
|
|
1020
|
+
const finalize = async (status, snapshot = params.getSnapshot()) => {
|
|
1068
1021
|
if (!params.draftStream || !params.enabled) return false;
|
|
1069
1022
|
await params.draftStream.dropDetachedMessages();
|
|
1070
1023
|
const terminalStatus = finalStatus === "error" || status === "error" ? "error" : "success";
|
|
@@ -1076,14 +1029,15 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1076
1029
|
await params.draftStream.seal();
|
|
1077
1030
|
try {
|
|
1078
1031
|
const finalized = await params.draftStream.finalizeMessage(messageId, async () => {
|
|
1032
|
+
const blocks = resolvePresentation(snapshot, terminalStatus);
|
|
1079
1033
|
await finalizeSlackPreviewEdit({
|
|
1080
1034
|
client: slackClient,
|
|
1081
1035
|
token: ctx.botToken,
|
|
1082
1036
|
accountId: account.accountId,
|
|
1083
1037
|
channelId,
|
|
1084
1038
|
messageId,
|
|
1085
|
-
text:
|
|
1086
|
-
blocks
|
|
1039
|
+
text: buildSlackCompleteBlocksFallbackText(blocks),
|
|
1040
|
+
blocks,
|
|
1087
1041
|
threadTs: params.getThreadTs()
|
|
1088
1042
|
});
|
|
1089
1043
|
});
|
|
@@ -1095,19 +1049,18 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1095
1049
|
}
|
|
1096
1050
|
};
|
|
1097
1051
|
return {
|
|
1098
|
-
|
|
1099
|
-
|
|
1052
|
+
resolveSessionLinks,
|
|
1053
|
+
onVisibleWorkSessions: (sessions) => {
|
|
1054
|
+
for (const session of sessions) if (!visibleWorkSessions.has(session.sessionKey)) visibleWorkSessions.set(session.sessionKey, session);
|
|
1055
|
+
},
|
|
1100
1056
|
resolvePresentation,
|
|
1101
1057
|
finalize,
|
|
1102
1058
|
get hasTerminalized() {
|
|
1103
1059
|
return finalStatus !== void 0;
|
|
1104
1060
|
},
|
|
1105
|
-
setFallbackText(text) {
|
|
1106
|
-
latestFallbackText = text;
|
|
1107
|
-
},
|
|
1108
1061
|
reset() {
|
|
1109
|
-
latestFallbackText = "";
|
|
1110
1062
|
finalStatus = void 0;
|
|
1063
|
+
visibleWorkSessions.clear();
|
|
1111
1064
|
}
|
|
1112
1065
|
};
|
|
1113
1066
|
}
|
|
@@ -1123,15 +1076,12 @@ function formatSlackProgressDraftLine(line) {
|
|
|
1123
1076
|
//#endregion
|
|
1124
1077
|
//#region extensions/slack/src/monitor/message-handler/dispatch-progress-native.ts
|
|
1125
1078
|
function createSlackNativeProgressTransport(params) {
|
|
1126
|
-
const {
|
|
1079
|
+
const { replyPlan } = params.setup;
|
|
1127
1080
|
const { delivery } = params;
|
|
1128
1081
|
const markDelivered = (threadTs) => {
|
|
1129
1082
|
if (!delivery.streamSession?.delivered) return false;
|
|
1130
1083
|
delivery.observedReplyDelivery = true;
|
|
1131
|
-
if (threadTs)
|
|
1132
|
-
delivery.usedReplyThreadTs ??= threadTs;
|
|
1133
|
-
delivery.rememberDeliveredThreadTs("block", threadTs);
|
|
1134
|
-
}
|
|
1084
|
+
if (threadTs) delivery.rememberDeliveredThreadTs("block", threadTs);
|
|
1135
1085
|
return true;
|
|
1136
1086
|
};
|
|
1137
1087
|
const waitForStart = async () => {
|
|
@@ -1152,30 +1102,15 @@ function createSlackNativeProgressTransport(params) {
|
|
|
1152
1102
|
return false;
|
|
1153
1103
|
}
|
|
1154
1104
|
delivery.nativeProgressStreamThreadTs = streamThreadTs;
|
|
1155
|
-
const startPromise = (
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
...update.text ? { text: update.text } : {},
|
|
1162
|
-
...update.chunks?.length ? { chunks: update.chunks } : {},
|
|
1163
|
-
taskDisplayMode: "plan",
|
|
1164
|
-
...slackIdentity ? { identity: slackIdentity } : {},
|
|
1165
|
-
teamId: await resolveSlackStreamRecipientTeamId({
|
|
1166
|
-
client: slackClient,
|
|
1167
|
-
token: ctx.botToken,
|
|
1168
|
-
userId: message.user,
|
|
1169
|
-
fallbackTeamId: slackStreamFallbackTeamId
|
|
1170
|
-
}),
|
|
1171
|
-
userId: message.user
|
|
1172
|
-
});
|
|
1173
|
-
delivery.streamSession = session;
|
|
1174
|
-
return session;
|
|
1175
|
-
})();
|
|
1105
|
+
const startPromise = delivery.startStream({
|
|
1106
|
+
threadTs: streamThreadTs,
|
|
1107
|
+
...update.text ? { text: update.text } : {},
|
|
1108
|
+
...update.chunks?.length ? { chunks: update.chunks } : {},
|
|
1109
|
+
taskDisplayMode: "plan"
|
|
1110
|
+
});
|
|
1176
1111
|
delivery.nativeProgressStreamStartPromise = startPromise;
|
|
1177
1112
|
try {
|
|
1178
|
-
|
|
1113
|
+
await startPromise;
|
|
1179
1114
|
const delivered = markDelivered(streamThreadTs);
|
|
1180
1115
|
return update.chunks?.length ? delivered : true;
|
|
1181
1116
|
} finally {
|
|
@@ -1203,7 +1138,7 @@ function createSlackNativeProgressTransport(params) {
|
|
|
1203
1138
|
//#region extensions/slack/src/monitor/message-handler/dispatch-progress.ts
|
|
1204
1139
|
function createSlackProgressRuntime(runtimeParams) {
|
|
1205
1140
|
const { setup, delivery } = runtimeParams;
|
|
1206
|
-
const { account, cfg, ctx, hasSlackCustomIdentity, message, prepared, replyPlan, runtime, slackClient, slackIdentity, slackMessageMetadata, slackStreaming, shouldUseDraftStream, useStreaming, previewStreamingEnabled } = setup;
|
|
1141
|
+
const { account, cfg, ctx, hasSlackCustomIdentity, message, prepared, replyPlan, runtime, slackClient, slackIdentity, slackMessageMetadata, slackStreaming, slackProgressStyle, quietProgress, shouldUseDraftStream, useStreaming, previewStreamingEnabled } = setup;
|
|
1207
1142
|
const draftStream = shouldUseDraftStream ? createSlackDraftStream({
|
|
1208
1143
|
target: prepared.replyTarget,
|
|
1209
1144
|
cfg,
|
|
@@ -1227,7 +1162,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1227
1162
|
const progressDraftActive = Boolean(draftStream) || useNativeProgressStreaming;
|
|
1228
1163
|
const previewToolProgressEnabled = progressDraftActive && resolveChannelStreamingPreviewToolProgress(account.config, slackStreaming.mode !== "progress", slackStreaming.mode);
|
|
1229
1164
|
let shouldYieldDraftProgress = () => false;
|
|
1230
|
-
const suppressDefaultToolProgressMessages = resolveChannelStreamingSuppressDefaultToolProgressMessages(account.config, {
|
|
1165
|
+
const suppressDefaultToolProgressMessages = quietProgress || resolveChannelStreamingSuppressDefaultToolProgressMessages(account.config, {
|
|
1231
1166
|
draftStreamActive: Boolean(draftStream) || useNativeProgressStreaming,
|
|
1232
1167
|
mode: slackStreaming.mode,
|
|
1233
1168
|
previewToolProgressEnabled,
|
|
@@ -1248,7 +1183,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1248
1183
|
};
|
|
1249
1184
|
const progressWorkCounter = createChannelProgressWorkCounter();
|
|
1250
1185
|
const progressSeed = `${account.accountId}:${message.channel}`;
|
|
1251
|
-
const slackProgressStyle = resolveSlackProgressStyle(account.config);
|
|
1252
1186
|
const preambleOnlyProgress = isProgressMode && slackProgressStyle === "compact" && !previewToolProgressEnabled;
|
|
1253
1187
|
const useDraftProgressCard = Boolean(draftStream) && isProgressMode && slackProgressStyle === "card";
|
|
1254
1188
|
const explicitProgressTitle = resolveExplicitSlackProgressTitle(account.config);
|
|
@@ -1264,7 +1198,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1264
1198
|
draftStream,
|
|
1265
1199
|
enabled: useDraftProgressCard,
|
|
1266
1200
|
progressWorkCounter: previewToolProgressEnabled ? progressWorkCounter : void 0,
|
|
1267
|
-
progressSeed,
|
|
1268
1201
|
explicitTitle: explicitProgressTitle,
|
|
1269
1202
|
maxLineChars: progressDraftMaxLineChars,
|
|
1270
1203
|
getSnapshot: () => progressDraft.getSnapshot(),
|
|
@@ -1373,8 +1306,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1373
1306
|
nativeUpdates.stop();
|
|
1374
1307
|
await nativeUpdates.waitForInFlight();
|
|
1375
1308
|
};
|
|
1376
|
-
const appendNativeNarration = (payload, kind) => withNativeStreamOrder(() =>
|
|
1377
|
-
const appendNativeNarrationNow = async (payload, kind) => {
|
|
1309
|
+
const appendNativeNarration = (payload, kind) => withNativeStreamOrder(async () => {
|
|
1378
1310
|
if (isRenderedAsProgressTitle(payload.text)) return { visibleReplySent: false };
|
|
1379
1311
|
const narrationUpdate = resolveNarrationUpdate(payload.text?.trimEnd());
|
|
1380
1312
|
if (!narrationUpdate.delta) return { visibleReplySent: false };
|
|
@@ -1390,7 +1322,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1390
1322
|
nativeNarrationSourceText = narrationUpdate.next.source;
|
|
1391
1323
|
}
|
|
1392
1324
|
return result;
|
|
1393
|
-
};
|
|
1325
|
+
});
|
|
1394
1326
|
const resetProgressTurnState = () => {
|
|
1395
1327
|
progressWorkCounter.reset();
|
|
1396
1328
|
nativeNarrationRenderedText = "";
|
|
@@ -1419,7 +1351,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1419
1351
|
const snapshot = options.snapshot;
|
|
1420
1352
|
const latestLine = snapshot.lines.at(-1);
|
|
1421
1353
|
if (preambleOnlyProgress && typeof latestLine === "object" && latestLine.complete === false) return false;
|
|
1422
|
-
progressCard.setFallbackText(previewText);
|
|
1423
1354
|
draftStream.update(preambleOnlyProgress ? {
|
|
1424
1355
|
text: previewText,
|
|
1425
1356
|
allowNewMessage: typeof latestLine !== "object" || latestLine.complete !== false,
|
|
@@ -1492,22 +1423,22 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1492
1423
|
const buildNativeProgressCompletionChunks = (finalInProgressStatus) => {
|
|
1493
1424
|
const snapshot = progressDraft.getSnapshot();
|
|
1494
1425
|
const lines = resolveNativeProgressLines(snapshot);
|
|
1495
|
-
const
|
|
1426
|
+
const sessionLinks = progressCard.resolveSessionLinks();
|
|
1496
1427
|
const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(snapshot));
|
|
1497
1428
|
const hasRetirableNativeTasks = [...nativeStreamSnapshot.tasks.values()].some((task) => task.status !== "complete" && task.status !== "error");
|
|
1498
|
-
if (lines.length === 0 && !snapshot.plan?.length && !hasRetirableNativeTasks && !snapshot.diffStat && !narrationUpdate.delta &&
|
|
1429
|
+
if (lines.length === 0 && !snapshot.plan?.length && !hasRetirableNativeTasks && !snapshot.diffStat && !narrationUpdate.delta && sessionLinks.length === 0) return;
|
|
1499
1430
|
const completion = reconcileSlackNativeTaskChunks({
|
|
1500
1431
|
previous: nativeStreamSnapshot,
|
|
1501
1432
|
finalStatus: finalInProgressStatus,
|
|
1502
1433
|
chunks: buildSlackProgressStreamChunks({
|
|
1503
|
-
title: resolveNativeProgressTitle(snapshot)
|
|
1434
|
+
title: resolveNativeProgressTitle(snapshot),
|
|
1504
1435
|
lines,
|
|
1505
1436
|
plan: snapshot.plan,
|
|
1506
1437
|
maxLineChars: progressDraftMaxLineChars,
|
|
1507
1438
|
summaryRow: !previewToolProgressEnabled,
|
|
1508
1439
|
finalInProgressStatus,
|
|
1509
1440
|
diffStat: snapshot.diffStat,
|
|
1510
|
-
|
|
1441
|
+
sessionLinks
|
|
1511
1442
|
})
|
|
1512
1443
|
}).chunks;
|
|
1513
1444
|
return narrationUpdate.delta ? [{
|
|
@@ -1578,12 +1509,11 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1578
1509
|
await cancelNativeUpdates();
|
|
1579
1510
|
}
|
|
1580
1511
|
const priorSnapshot = progressDraft.getSnapshot();
|
|
1581
|
-
const priorFallbackText = progressCard.resolveText(priorSnapshot);
|
|
1582
1512
|
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent ? buildNativeProgressCompletionChunks(nativeProgressTerminalStatus) : void 0;
|
|
1583
1513
|
if (!progressDraft.beginNewTurn(options)) return false;
|
|
1584
1514
|
if (useNativeProgressStreaming) await finishNativeProgressTurn(completionChunks);
|
|
1585
1515
|
else {
|
|
1586
|
-
await progressCard.finalize("success", priorSnapshot
|
|
1516
|
+
await progressCard.finalize("success", priorSnapshot);
|
|
1587
1517
|
await previewLifecycle.cleanup();
|
|
1588
1518
|
draftStream?.forceNewMessage();
|
|
1589
1519
|
await dropDetachedProgressCards();
|
|
@@ -1666,6 +1596,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1666
1596
|
deliverNativeFinal,
|
|
1667
1597
|
dropDetachedProgressCards,
|
|
1668
1598
|
finalizeDraftProgressCard: progressCard.finalize,
|
|
1599
|
+
onVisibleWorkSessions: progressCard.onVisibleWorkSessions,
|
|
1669
1600
|
onDraftBoundary,
|
|
1670
1601
|
onQueuedFollowupAdmitted,
|
|
1671
1602
|
onQueuedFollowupSettled,
|
|
@@ -1722,14 +1653,14 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1722
1653
|
ctx: prepared.ctxPayload
|
|
1723
1654
|
});
|
|
1724
1655
|
}
|
|
1725
|
-
const
|
|
1656
|
+
const threadContext = resolveSlackThreadContext({
|
|
1726
1657
|
message,
|
|
1727
1658
|
replyToMode: prepared.replyToMode
|
|
1728
1659
|
});
|
|
1729
1660
|
const forcedReplyThreadTs = prepared.forcedReplyThreadTs;
|
|
1730
1661
|
const slackMessageMetadata = prepared.slackMessageMetadata;
|
|
1731
|
-
const statusThreadTs = forcedReplyThreadTs ??
|
|
1732
|
-
const isThreadReply =
|
|
1662
|
+
const statusThreadTs = forcedReplyThreadTs ?? threadContext.messageThreadId;
|
|
1663
|
+
const isThreadReply = threadContext.isThreadReply;
|
|
1733
1664
|
const replyDeliveryMode = forcedReplyThreadTs ? "off" : prepared.replyToMode;
|
|
1734
1665
|
const sourceReplyDeliveryMode = resolveChannelMessageSourceReplyDeliveryMode({
|
|
1735
1666
|
cfg,
|
|
@@ -1790,8 +1721,12 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1790
1721
|
hasRepliedRef,
|
|
1791
1722
|
isThreadReply: Boolean(forcedReplyThreadTs) || isThreadReply
|
|
1792
1723
|
});
|
|
1724
|
+
const slackStreaming = resolveSlackStreamingConfig({ streaming: account.config.streaming });
|
|
1725
|
+
const streamThreadHint = forcedReplyThreadTs ?? replyPlan.peekThreadTs();
|
|
1726
|
+
const slackProgressStyle = resolveSlackProgressStyle(account.config, Boolean(streamThreadHint));
|
|
1727
|
+
const quietProgress = slackStreaming.mode === "progress" && slackProgressStyle === "none";
|
|
1793
1728
|
const typingTarget = statusThreadTs ? `${message.channel}/${statusThreadTs}` : message.channel;
|
|
1794
|
-
const typingReaction = ctx.typingReaction;
|
|
1729
|
+
const typingReaction = quietProgress && account.config.typingReaction === void 0 ? "hourglass_flowing_sand" : ctx.typingReaction;
|
|
1795
1730
|
const threadStatusGate = { hasVisibleOutput: () => false };
|
|
1796
1731
|
const { onModelSelected, ...replyPipeline } = createChannelMessageReplyPipeline({
|
|
1797
1732
|
cfg,
|
|
@@ -1866,23 +1801,16 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1866
1801
|
}
|
|
1867
1802
|
}
|
|
1868
1803
|
});
|
|
1869
|
-
const slackStreaming = resolveSlackStreamingConfig({ streaming: account.config.streaming });
|
|
1870
|
-
const streamThreadHint = forcedReplyThreadTs ?? resolveSlackStreamingThreadHint({
|
|
1871
|
-
replyToMode: replyDeliveryMode,
|
|
1872
|
-
incomingThreadTs,
|
|
1873
|
-
messageTs,
|
|
1874
|
-
isThreadReply
|
|
1875
|
-
});
|
|
1876
1804
|
const hookRunner = getGlobalHookRunner();
|
|
1877
1805
|
const modifyingHooksRegistered = (hookRunner?.hasHooks("reply_payload_sending") ?? false) || (hookRunner?.hasHooks("message_sending") ?? false);
|
|
1878
1806
|
const allowPreHookProviderStreaming = !prepared.ctxPayload.GroupThread && !modifyingHooksRegistered;
|
|
1879
|
-
const previewStreamingEnabled = allowPreHookProviderStreaming && !sourceRepliesAreToolOnly && slackStreaming.mode !== "off";
|
|
1807
|
+
const previewStreamingEnabled = allowPreHookProviderStreaming && !sourceRepliesAreToolOnly && !quietProgress && slackStreaming.mode !== "off";
|
|
1880
1808
|
const hasSlackCustomIdentity = Boolean(slackIdentity?.username || slackIdentity?.iconUrl || slackIdentity?.iconEmoji);
|
|
1881
1809
|
const useStreaming = shouldUseStreaming({
|
|
1882
1810
|
streamingEnabled: !prepared.ctxPayload.GroupThread && !sourceRepliesAreToolOnly && (allowPreHookProviderStreaming || slackStreaming.mode !== "progress") && isSlackStreamingEnabled({
|
|
1883
1811
|
mode: slackStreaming.mode,
|
|
1884
1812
|
nativeStreaming: slackStreaming.nativeStreaming,
|
|
1885
|
-
nativeProgressTaskCards: resolveSlackNativeProgressTaskCards(account.config)
|
|
1813
|
+
nativeProgressTaskCards: resolveSlackNativeProgressTaskCards(account.config, slackProgressStyle)
|
|
1886
1814
|
}),
|
|
1887
1815
|
threadTs: streamThreadHint
|
|
1888
1816
|
});
|
|
@@ -1906,13 +1834,10 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1906
1834
|
isThreadReply,
|
|
1907
1835
|
replyDeliveryMode,
|
|
1908
1836
|
sourceReplyDeliveryMode,
|
|
1909
|
-
sourceRepliesAreToolOnly,
|
|
1910
1837
|
suppressRoomEventTyping,
|
|
1911
1838
|
messageSentHookTarget,
|
|
1912
1839
|
messageSentHookContext,
|
|
1913
1840
|
messageSentDeliveryHookContext,
|
|
1914
|
-
incomingThreadTs,
|
|
1915
|
-
messageTs,
|
|
1916
1841
|
statusReactionsEnabled,
|
|
1917
1842
|
statusReactions,
|
|
1918
1843
|
hasRepliedRef,
|
|
@@ -1921,11 +1846,13 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1921
1846
|
onModelSelected,
|
|
1922
1847
|
replyPipeline,
|
|
1923
1848
|
slackStreaming,
|
|
1849
|
+
slackProgressStyle,
|
|
1850
|
+
quietProgress,
|
|
1924
1851
|
streamThreadHint,
|
|
1925
1852
|
previewStreamingEnabled,
|
|
1926
1853
|
hasSlackCustomIdentity,
|
|
1927
1854
|
shouldUseDraftStream,
|
|
1928
|
-
disableBlockStreaming: sourceRepliesAreToolOnly ? true : resolveSlackDisableBlockStreaming({
|
|
1855
|
+
disableBlockStreaming: sourceRepliesAreToolOnly || quietProgress ? true : resolveSlackDisableBlockStreaming({
|
|
1929
1856
|
useStreaming,
|
|
1930
1857
|
shouldUseDraftStream,
|
|
1931
1858
|
blockStreamingEnabled
|
|
@@ -1946,6 +1873,41 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
1946
1873
|
usedBlockReplyThreadTs: void 0,
|
|
1947
1874
|
observedReplyDelivery: false
|
|
1948
1875
|
};
|
|
1876
|
+
const startStream = async (params) => {
|
|
1877
|
+
const session = await startSlackStream({
|
|
1878
|
+
client: slackClient,
|
|
1879
|
+
clientOptions: slackClientOptions,
|
|
1880
|
+
channel: message.channel,
|
|
1881
|
+
...params,
|
|
1882
|
+
...slackIdentity ? { identity: slackIdentity } : {},
|
|
1883
|
+
teamId: await resolveSlackStreamRecipientTeamId({
|
|
1884
|
+
client: slackClient,
|
|
1885
|
+
token: ctx.botToken,
|
|
1886
|
+
userId: message.user,
|
|
1887
|
+
fallbackTeamId: slackStreamFallbackTeamId
|
|
1888
|
+
}),
|
|
1889
|
+
userId: message.user
|
|
1890
|
+
});
|
|
1891
|
+
state.streamSession = session;
|
|
1892
|
+
return session;
|
|
1893
|
+
};
|
|
1894
|
+
const deliverPreparedReply = (reply, replyThreadTs, deferMessageSentHooks = false) => deliverReplies({
|
|
1895
|
+
cfg: ctx.cfg,
|
|
1896
|
+
replies: [reply],
|
|
1897
|
+
target: prepared.replyTarget,
|
|
1898
|
+
token: ctx.botToken,
|
|
1899
|
+
accountId: account.accountId,
|
|
1900
|
+
runtime,
|
|
1901
|
+
textLimit: ctx.textLimit,
|
|
1902
|
+
mediaMaxBytes: ctx.mediaMaxBytes,
|
|
1903
|
+
replyThreadTs,
|
|
1904
|
+
replyToMode: replyDeliveryMode,
|
|
1905
|
+
...slackIdentity ? { identity: slackIdentity } : {},
|
|
1906
|
+
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {},
|
|
1907
|
+
...messageSentDeliveryHookContext,
|
|
1908
|
+
...deferMessageSentHooks ? { deferMessageSentHooks: true } : {},
|
|
1909
|
+
eventScope: prepared.eventScope
|
|
1910
|
+
});
|
|
1949
1911
|
const emitStreamedDelivery = (content, result) => {
|
|
1950
1912
|
emitSlackMessageSentHooks({
|
|
1951
1913
|
...messageSentHookContext,
|
|
@@ -1996,23 +1958,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
1996
1958
|
}
|
|
1997
1959
|
const fallbackText = fallbackError.pendingText.trim();
|
|
1998
1960
|
if (!fallbackText) return;
|
|
1999
|
-
const sent = await
|
|
2000
|
-
cfg: ctx.cfg,
|
|
2001
|
-
replies: [prepareSlackReply({ text: fallbackText })],
|
|
2002
|
-
target: prepared.replyTarget,
|
|
2003
|
-
token: ctx.botToken,
|
|
2004
|
-
accountId: account.accountId,
|
|
2005
|
-
runtime,
|
|
2006
|
-
textLimit: ctx.textLimit,
|
|
2007
|
-
mediaMaxBytes: ctx.mediaMaxBytes,
|
|
2008
|
-
replyThreadTs: session.threadTs,
|
|
2009
|
-
replyToMode: replyDeliveryMode,
|
|
2010
|
-
...slackIdentity ? { identity: slackIdentity } : {},
|
|
2011
|
-
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {},
|
|
2012
|
-
...messageSentDeliveryHookContext,
|
|
2013
|
-
deferMessageSentHooks: true,
|
|
2014
|
-
eventScope: prepared.eventScope
|
|
2015
|
-
});
|
|
1961
|
+
const sent = await deliverPreparedReply(prepareSlackReply({ text: fallbackText }), session.threadTs, true);
|
|
2016
1962
|
if (!sent?.receipt.platformMessageIds.length) return;
|
|
2017
1963
|
markSlackStreamFallbackDelivered(session);
|
|
2018
1964
|
if (!session.stopped) try {
|
|
@@ -2066,22 +2012,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2066
2012
|
logVerbose("slack: suppressed duplicate normal delivery within the same turn");
|
|
2067
2013
|
return { visibleReplySent: false };
|
|
2068
2014
|
}
|
|
2069
|
-
const sent = await
|
|
2070
|
-
cfg: ctx.cfg,
|
|
2071
|
-
replies: [preparedReply],
|
|
2072
|
-
target: prepared.replyTarget,
|
|
2073
|
-
token: ctx.botToken,
|
|
2074
|
-
accountId: account.accountId,
|
|
2075
|
-
runtime,
|
|
2076
|
-
textLimit: ctx.textLimit,
|
|
2077
|
-
mediaMaxBytes: ctx.mediaMaxBytes,
|
|
2078
|
-
replyThreadTs: deliveryReplyThreadTs,
|
|
2079
|
-
replyToMode: replyDeliveryMode,
|
|
2080
|
-
...slackIdentity ? { identity: slackIdentity } : {},
|
|
2081
|
-
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {},
|
|
2082
|
-
...messageSentDeliveryHookContext,
|
|
2083
|
-
eventScope: prepared.eventScope
|
|
2084
|
-
});
|
|
2015
|
+
const sent = await deliverPreparedReply(preparedReply, deliveryReplyThreadTs);
|
|
2085
2016
|
if (!sent?.receipt.platformMessageIds.length) return { visibleReplySent: false };
|
|
2086
2017
|
state.observedReplyDelivery = true;
|
|
2087
2018
|
const deliveredThreadTs = resolveSlackReplyThreadTs({
|
|
@@ -2104,7 +2035,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2104
2035
|
const reply = resolveSendableOutboundReplyParts(payload);
|
|
2105
2036
|
const renderPlan = resolveSlackReplyRenderPlan(payload);
|
|
2106
2037
|
const plannedBlocks = renderPlan.mode === "single" ? renderPlan.blocks : renderPlan.blockPart?.blocks;
|
|
2107
|
-
return !state.streamFailed && !reply.hasMedia && renderPlan.mode !== "split" && !renderPlan.textIsSlackPlainText && !plannedBlocks?.length && !
|
|
2038
|
+
return !state.streamFailed && !reply.hasMedia && renderPlan.mode !== "split" && !renderPlan.textIsSlackPlainText && !plannedBlocks?.length && !resolveSlackReplyBlocks(payload)?.length && reply.hasText && (!options?.maxTextBytes || countSlackTextUtf8Bytes(reply.trimmedText) <= options.maxTextBytes);
|
|
2108
2039
|
};
|
|
2109
2040
|
const deliverWithStreaming = async (params) => {
|
|
2110
2041
|
if (state.streamSession?.stoppedBySlack) return { visibleReplySent: false };
|
|
@@ -2144,26 +2075,12 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2144
2075
|
text: `${params.appendSeparator === false ? "" : "\n"}${text}`,
|
|
2145
2076
|
chunks: []
|
|
2146
2077
|
});
|
|
2147
|
-
else {
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
text,
|
|
2154
|
-
chunks: [],
|
|
2155
|
-
...params.taskDisplayMode ? { taskDisplayMode: params.taskDisplayMode } : {},
|
|
2156
|
-
...slackIdentity ? { identity: slackIdentity } : {},
|
|
2157
|
-
teamId: await resolveSlackStreamRecipientTeamId({
|
|
2158
|
-
client: slackClient,
|
|
2159
|
-
token: ctx.botToken,
|
|
2160
|
-
userId: message.user,
|
|
2161
|
-
fallbackTeamId: slackStreamFallbackTeamId
|
|
2162
|
-
}),
|
|
2163
|
-
userId: message.user
|
|
2164
|
-
});
|
|
2165
|
-
state.streamSession = session;
|
|
2166
|
-
}
|
|
2078
|
+
else session = await startStream({
|
|
2079
|
+
threadTs,
|
|
2080
|
+
text,
|
|
2081
|
+
chunks: [],
|
|
2082
|
+
...params.taskDisplayMode ? { taskDisplayMode: params.taskDisplayMode } : {}
|
|
2083
|
+
});
|
|
2167
2084
|
messageId = session.streamer.ts;
|
|
2168
2085
|
} catch (error) {
|
|
2169
2086
|
state.streamFailed = true;
|
|
@@ -2221,6 +2138,7 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2221
2138
|
isStreamingEligible,
|
|
2222
2139
|
markPreviewPayloadDelivered,
|
|
2223
2140
|
rememberDeliveredThreadTs,
|
|
2141
|
+
startStream,
|
|
2224
2142
|
resetDeliveryTracker: () => {
|
|
2225
2143
|
deliveryTracker = createSlackEventDeliveryTracker();
|
|
2226
2144
|
}
|
|
@@ -2324,14 +2242,7 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
|
|
|
2324
2242
|
})).deliveryResult ?? { visibleReplySent: false };
|
|
2325
2243
|
}
|
|
2326
2244
|
if (progress.useNativeProgressStreaming) {
|
|
2327
|
-
if (info.kind !== "final" && payload.isError !== true)
|
|
2328
|
-
if (!delivery.isStreamingEligible(payload)) return await delivery.deliverNormally({
|
|
2329
|
-
payload,
|
|
2330
|
-
kind: info.kind,
|
|
2331
|
-
forcedThreadTs: delivery.streamSession?.threadTs ?? delivery.nativeProgressStreamThreadTs
|
|
2332
|
-
});
|
|
2333
|
-
return await progress.appendNativeNarration(payload, info.kind);
|
|
2334
|
-
}
|
|
2245
|
+
if (info.kind !== "final" && payload.isError !== true && delivery.isStreamingEligible(payload)) return await progress.appendNativeNarration(payload, info.kind);
|
|
2335
2246
|
return await delivery.deliverNormally({
|
|
2336
2247
|
payload,
|
|
2337
2248
|
kind: info.kind,
|
|
@@ -2482,6 +2393,7 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
|
|
|
2482
2393
|
record: prepared.turn.record,
|
|
2483
2394
|
botLoopProtection: resolveSlackBotLoopProtection(prepared),
|
|
2484
2395
|
replyOptions: {
|
|
2396
|
+
onVisibleWorkSessions: progress.onVisibleWorkSessions,
|
|
2485
2397
|
groupThreadReplyFormatter: formatSlackGroupThreadReply,
|
|
2486
2398
|
queuedDeliveryCorrelations: [{ begin: beginSessionRun }],
|
|
2487
2399
|
...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
|
|
@@ -2501,9 +2413,7 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
|
|
|
2501
2413
|
} : void 0,
|
|
2502
2414
|
allowProgressCallbacksWhenSourceDeliverySuppressed: sourceReplyDeliveryMode === "message_tool_only" && statusReactionsEnabled ? true : void 0,
|
|
2503
2415
|
allowToolLifecycleWhenProgressHidden: statusReactionsEnabled ? true : void 0,
|
|
2504
|
-
onPartialReply: useStreaming
|
|
2505
|
-
return progress.updateDraftFromPartial(payload.text);
|
|
2506
|
-
},
|
|
2416
|
+
onPartialReply: !useStreaming && previewStreamingEnabled ? async (payload) => progress.updateDraftFromPartial(payload.text) : void 0,
|
|
2507
2417
|
onAssistantMessageStart: progress.onDraftBoundary ? async () => {
|
|
2508
2418
|
await progress.onDraftBoundary?.();
|
|
2509
2419
|
return false;
|
|
@@ -2586,7 +2496,7 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
|
|
|
2586
2496
|
}
|
|
2587
2497
|
if (shouldLogVerbose()) {
|
|
2588
2498
|
const finalCount = resolveInboundReplyDispatchCounts(settledDispatchResult).final;
|
|
2589
|
-
logVerbose(`slack: delivered ${finalCount}
|
|
2499
|
+
logVerbose(`slack: delivered ${finalCount} repl${finalCount === 1 ? "y" : "ies"} to ${prepared.replyTarget}`);
|
|
2590
2500
|
}
|
|
2591
2501
|
}
|
|
2592
2502
|
//#endregion
|
|
@@ -2646,12 +2556,9 @@ function formatSlackFilePlaceholder(files) {
|
|
|
2646
2556
|
return `[attached: ${formatSlackFileReferenceList(files)}]`;
|
|
2647
2557
|
}
|
|
2648
2558
|
function pushUniqueText(parts, value, options = {}) {
|
|
2649
|
-
const text = options.preserveWhitespace ?
|
|
2559
|
+
const text = options.preserveWhitespace ? readNonBlankString(value) : normalizeOptionalString(value);
|
|
2650
2560
|
if (text && !parts.includes(text)) parts.push(text);
|
|
2651
2561
|
}
|
|
2652
|
-
function resolveSlackBlocksFallbackText(blocks) {
|
|
2653
|
-
return resolveSlackBlocksText(blocks)?.text;
|
|
2654
|
-
}
|
|
2655
2562
|
function resolveSlackAttachmentFallbackText(attachments) {
|
|
2656
2563
|
if (!Array.isArray(attachments) || attachments.length === 0) return;
|
|
2657
2564
|
const parts = [];
|
|
@@ -2666,8 +2573,8 @@ function resolveSlackAttachmentFallbackText(attachments) {
|
|
|
2666
2573
|
pushUniqueText(parts, field.title);
|
|
2667
2574
|
pushUniqueText(parts, field.value);
|
|
2668
2575
|
}
|
|
2669
|
-
pushUniqueText(parts,
|
|
2670
|
-
pushUniqueText(parts,
|
|
2576
|
+
pushUniqueText(parts, resolveSlackBlocksText(fallbackBlocks(attachment.blocks))?.text, { preserveWhitespace: true });
|
|
2577
|
+
pushUniqueText(parts, resolveSlackBlocksText(fallbackBlocks(attachment.message_blocks))?.text, { preserveWhitespace: true });
|
|
2671
2578
|
}
|
|
2672
2579
|
return parts.length > 0 ? parts.join("\n") : void 0;
|
|
2673
2580
|
}
|
|
@@ -2721,7 +2628,7 @@ async function resolveSlackThreadStarter(params) {
|
|
|
2721
2628
|
}
|
|
2722
2629
|
return starter;
|
|
2723
2630
|
} catch (err) {
|
|
2724
|
-
logVerbose
|
|
2631
|
+
logVerbose(`slack thread starter fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
|
|
2725
2632
|
return null;
|
|
2726
2633
|
}
|
|
2727
2634
|
}
|
|
@@ -2771,7 +2678,7 @@ async function resolveSlackThreadHistory(params) {
|
|
|
2771
2678
|
}
|
|
2772
2679
|
} while (cursor && pagesFetched < SLACK_THREAD_HISTORY_MAX_PAGES);
|
|
2773
2680
|
if (cursor) {
|
|
2774
|
-
logVerbose
|
|
2681
|
+
logVerbose(`slack thread history capped channel=${params.channelId} ts=${params.threadTs} pages=${SLACK_THREAD_HISTORY_MAX_PAGES}`);
|
|
2775
2682
|
params.onOmission?.("Slack thread exceeds the three-page automatic history budget");
|
|
2776
2683
|
return [];
|
|
2777
2684
|
}
|
|
@@ -2786,7 +2693,7 @@ async function resolveSlackThreadHistory(params) {
|
|
|
2786
2693
|
} catch (err) {
|
|
2787
2694
|
params.assertCurrent?.();
|
|
2788
2695
|
params.onOmission?.(formatErrorMessage(err));
|
|
2789
|
-
logVerbose
|
|
2696
|
+
logVerbose(`slack thread history fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
|
|
2790
2697
|
return [];
|
|
2791
2698
|
}
|
|
2792
2699
|
}
|
|
@@ -2869,9 +2776,7 @@ async function resolveSlackPreflightAudioTranscript(params) {
|
|
|
2869
2776
|
mediaIndex
|
|
2870
2777
|
} : null;
|
|
2871
2778
|
}
|
|
2872
|
-
|
|
2873
|
-
await slackPreflightAudio.send(params);
|
|
2874
|
-
}
|
|
2779
|
+
const sendSlackPreflightAudioTranscriptEcho = slackPreflightAudio.send.bind(slackPreflightAudio);
|
|
2875
2780
|
async function discardSlackPreflightMedia(media) {
|
|
2876
2781
|
await Promise.allSettled((media ?? []).map((entry) => fs.rm(entry.path, { force: true })));
|
|
2877
2782
|
}
|
|
@@ -2881,7 +2786,7 @@ const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
|
|
|
2881
2786
|
const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
|
|
2882
2787
|
const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
|
|
2883
2788
|
const MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS = 2e3;
|
|
2884
|
-
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-
|
|
2789
|
+
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-Df0CzcDl.mjs").then((n) => n._));
|
|
2885
2790
|
function formatSlackUnavailableMedia(params) {
|
|
2886
2791
|
let fileReferences = params.files?.map((file) => `${formatSlackFileReference(file)} unavailable (${file.reason})`).join(", ");
|
|
2887
2792
|
if (fileReferences && fileReferences.length > MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS) fileReferences = `${truncateUtf16Safe(fileReferences, MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS)}; … (file references truncated)`;
|
|
@@ -2900,18 +2805,15 @@ function formatSlackUnavailableMedia(params) {
|
|
|
2900
2805
|
}
|
|
2901
2806
|
function collectUniqueSlackMentionIds$1(texts) {
|
|
2902
2807
|
const seen = /* @__PURE__ */ new Set();
|
|
2903
|
-
const mentionIds = [];
|
|
2904
2808
|
for (const text of texts) {
|
|
2905
2809
|
if (!text) continue;
|
|
2906
2810
|
SLACK_USER_MENTION_RE$1.lastIndex = 0;
|
|
2907
2811
|
for (const match of text.matchAll(SLACK_USER_MENTION_RE$1)) {
|
|
2908
2812
|
const userId = match[1];
|
|
2909
|
-
if (
|
|
2910
|
-
seen.add(userId);
|
|
2911
|
-
mentionIds.push(userId);
|
|
2813
|
+
if (userId) seen.add(userId);
|
|
2912
2814
|
}
|
|
2913
2815
|
}
|
|
2914
|
-
return
|
|
2816
|
+
return [...seen];
|
|
2915
2817
|
}
|
|
2916
2818
|
function renderSlackUserMentions(text, renderedMentions) {
|
|
2917
2819
|
if (!text || renderedMentions.size === 0) return text;
|
|
@@ -2922,8 +2824,7 @@ function renderSlackUserMentions(text, renderedMentions) {
|
|
|
2922
2824
|
}
|
|
2923
2825
|
function filterInheritedParentFiles(params) {
|
|
2924
2826
|
const { files, isThreadReply, threadStarter } = params;
|
|
2925
|
-
if (!isThreadReply || !files?.length) return files;
|
|
2926
|
-
if (!threadStarter?.files?.length) return files;
|
|
2827
|
+
if (!isThreadReply || !files?.length || !threadStarter?.files?.length) return files;
|
|
2927
2828
|
const starterFileIds = new Set(threadStarter.files.map((file) => file.id));
|
|
2928
2829
|
const filtered = files.filter((file) => !file.id || !starterFileIds.has(file.id));
|
|
2929
2830
|
if (filtered.length < files.length) logVerbose(`slack: filtered ${files.length - filtered.length} inherited parent file(s) from thread reply`);
|
|
@@ -2950,14 +2851,7 @@ async function resolveSlackMessageContent(params) {
|
|
|
2950
2851
|
const effectiveDirectMedia = attachmentContent?.media.length ? attachmentContent.media : null;
|
|
2951
2852
|
const mediaPlaceholder = effectiveDirectMedia?.map((item) => item.placeholder).join(" ");
|
|
2952
2853
|
let botAttachmentText;
|
|
2953
|
-
if (params.isBotMessage && !attachmentContent?.text)
|
|
2954
|
-
const botAttachmentTextParts = [];
|
|
2955
|
-
for (const attachment of params.message.attachments ?? []) {
|
|
2956
|
-
const text = normalizeOptionalString(attachment.text) ?? normalizeOptionalString(attachment.fallback);
|
|
2957
|
-
if (text) botAttachmentTextParts.push(text);
|
|
2958
|
-
}
|
|
2959
|
-
botAttachmentText = botAttachmentTextParts.length > 0 ? botAttachmentTextParts.join("\n") : void 0;
|
|
2960
|
-
}
|
|
2854
|
+
if (params.isBotMessage && !attachmentContent?.text) botAttachmentText = (params.message.attachments ?? []).map((attachment) => normalizeOptionalString(attachment.text) ?? normalizeOptionalString(attachment.fallback)).filter(Boolean).join("\n") || void 0;
|
|
2961
2855
|
const textParts = [
|
|
2962
2856
|
resolveSlackMessageText$1(params.message),
|
|
2963
2857
|
attachmentContent?.text,
|
|
@@ -2986,17 +2880,9 @@ async function resolveSlackMessageContent(params) {
|
|
|
2986
2880
|
renderedMentions.set(result.userId, result.rendered);
|
|
2987
2881
|
}
|
|
2988
2882
|
}
|
|
2989
|
-
const renderedMessageText = renderSlackUserMentions(textParts[0], renderedMentions);
|
|
2990
|
-
const renderedAttachmentText = renderSlackUserMentions(textParts[1], renderedMentions);
|
|
2991
|
-
const renderedBotAttachmentText = renderSlackUserMentions(textParts[2], renderedMentions);
|
|
2992
2883
|
const commandSourceText = renderSlackUserMentions(normalizeOptionalString(params.message.text), renderedMentions) ?? "";
|
|
2993
2884
|
const rawBody = formatSlackUnavailableMedia({
|
|
2994
|
-
body: [
|
|
2995
|
-
renderedMessageText,
|
|
2996
|
-
renderedAttachmentText,
|
|
2997
|
-
renderedBotAttachmentText,
|
|
2998
|
-
mediaPlaceholder
|
|
2999
|
-
].filter(Boolean).join("\n") || "",
|
|
2885
|
+
body: [...textParts.map((text) => renderSlackUserMentions(text, renderedMentions)), mediaPlaceholder].filter(Boolean).join("\n"),
|
|
3000
2886
|
files: attachmentContent?.files,
|
|
3001
2887
|
unavailableMediaCount: attachmentContent?.unavailableMediaCount ?? 0
|
|
3002
2888
|
});
|
|
@@ -3011,7 +2897,7 @@ async function resolveSlackMessageContent(params) {
|
|
|
3011
2897
|
//#endregion
|
|
3012
2898
|
//#region extensions/slack/src/monitor/message-handler/prepare-dm-history.ts
|
|
3013
2899
|
function resolveSlackDmHistoryLimit(params) {
|
|
3014
|
-
const override = params.userId
|
|
2900
|
+
const override = params.userId ? params.account.config.dms?.[params.userId]?.historyLimit : void 0;
|
|
3015
2901
|
return resolvePromptHistoryLimit(override ?? params.defaultLimit, 0);
|
|
3016
2902
|
}
|
|
3017
2903
|
async function resolveSlackDmHistoryContext(params) {
|
|
@@ -3088,52 +2974,6 @@ function isSlackThreadAuthorCurrentBot(params) {
|
|
|
3088
2974
|
if (identity.botId && author.botId && author.botId === identity.botId) return true;
|
|
3089
2975
|
return false;
|
|
3090
2976
|
}
|
|
3091
|
-
function resolveSlackThreadHistoryFilterPolicy(params) {
|
|
3092
|
-
if (params.retainCurrentBotHistory) return { currentBot: "all" };
|
|
3093
|
-
if (!params.includeBotStarterAsRootContext || !params.starterTs) return { currentBot: "omit" };
|
|
3094
|
-
return {
|
|
3095
|
-
currentBot: "root-only",
|
|
3096
|
-
rootTs: params.starterTs
|
|
3097
|
-
};
|
|
3098
|
-
}
|
|
3099
|
-
function applySlackThreadHistoryFilterPolicy(params) {
|
|
3100
|
-
const kept = [];
|
|
3101
|
-
let omittedCurrentBot = 0;
|
|
3102
|
-
for (const entry of params.history) {
|
|
3103
|
-
if (!isSlackThreadAuthorCurrentBot({
|
|
3104
|
-
identity: params.identity,
|
|
3105
|
-
author: entry
|
|
3106
|
-
})) {
|
|
3107
|
-
kept.push(entry);
|
|
3108
|
-
continue;
|
|
3109
|
-
}
|
|
3110
|
-
if (params.policy.currentBot === "all" || params.policy.currentBot === "root-only" && entry.ts === params.policy.rootTs) kept.push(entry);
|
|
3111
|
-
else omittedCurrentBot += 1;
|
|
3112
|
-
}
|
|
3113
|
-
return {
|
|
3114
|
-
kept,
|
|
3115
|
-
omittedCurrentBot
|
|
3116
|
-
};
|
|
3117
|
-
}
|
|
3118
|
-
function shouldIncludeBotThreadStarterContext(params) {
|
|
3119
|
-
if (!params.hasStarterText) return false;
|
|
3120
|
-
return params.starterIsCurrentBot && params.isNewThreadSession;
|
|
3121
|
-
}
|
|
3122
|
-
function ensureSlackThreadHistoryHasBotRoot(params) {
|
|
3123
|
-
if (!params.includeBotStarterAsRootContext || !params.threadStarter?.text) return params.history;
|
|
3124
|
-
if (params.history.some((entry) => entry.ts === params.threadStarter?.ts)) return params.history;
|
|
3125
|
-
return [params.threadStarter, ...params.history];
|
|
3126
|
-
}
|
|
3127
|
-
function formatSlackBotStarterThreadLabel(params) {
|
|
3128
|
-
const base = `Slack thread ${params.roomLabel}`;
|
|
3129
|
-
if (!params.starterText) return base;
|
|
3130
|
-
const snippet = formatSlackThreadLabelSnippet(params.starterText).trim();
|
|
3131
|
-
if (!snippet) return base;
|
|
3132
|
-
return `${base} (assistant root): ${snippet}`;
|
|
3133
|
-
}
|
|
3134
|
-
function formatSlackThreadLabelSnippet(text) {
|
|
3135
|
-
return truncateUtf16Safe(text.replace(/\s+/g, " "), 80);
|
|
3136
|
-
}
|
|
3137
2977
|
//#endregion
|
|
3138
2978
|
//#region extensions/slack/src/monitor/message-handler/prepare-room-history.ts
|
|
3139
2979
|
const SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS = 4;
|
|
@@ -3300,8 +3140,11 @@ async function resolveSlackHistoryMedia(params) {
|
|
|
3300
3140
|
}
|
|
3301
3141
|
//#endregion
|
|
3302
3142
|
//#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
|
|
3303
|
-
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-
|
|
3143
|
+
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-Df0CzcDl.mjs").then((n) => n._));
|
|
3304
3144
|
const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
|
|
3145
|
+
function formatSlackThreadLabelSnippet(text) {
|
|
3146
|
+
return truncateUtf16Safe(text.replace(/\s+/g, " "), 80);
|
|
3147
|
+
}
|
|
3305
3148
|
function resolveSlackThreadSessionFreshness(params) {
|
|
3306
3149
|
return params.ctx.channelRuntime?.session?.resolveEntryResetFreshness?.({
|
|
3307
3150
|
agentId: params.agentId,
|
|
@@ -3316,27 +3159,15 @@ function resolveSlackThreadSessionFreshness(params) {
|
|
|
3316
3159
|
});
|
|
3317
3160
|
}
|
|
3318
3161
|
async function resolveSlackThreadUserMap(params) {
|
|
3319
|
-
const uniqueUserIds = [];
|
|
3320
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3321
|
-
for (const item of params.messages) {
|
|
3322
|
-
if (!item.userId || seen.has(item.userId)) continue;
|
|
3323
|
-
seen.add(item.userId);
|
|
3324
|
-
uniqueUserIds.push(item.userId);
|
|
3325
|
-
}
|
|
3326
|
-
const userMap = /* @__PURE__ */ new Map();
|
|
3327
|
-
if (uniqueUserIds.length === 0) return userMap;
|
|
3162
|
+
const uniqueUserIds = [...new Set(params.messages.map((item) => item.userId).filter((id) => Boolean(id)))];
|
|
3328
3163
|
const { results } = await runTasksWithConcurrency({
|
|
3329
3164
|
tasks: uniqueUserIds.map((id) => async () => {
|
|
3330
3165
|
const user = await params.ctx.resolveUserName(id, params.eventScope);
|
|
3331
|
-
return user ?
|
|
3332
|
-
id,
|
|
3333
|
-
user
|
|
3334
|
-
} : null;
|
|
3166
|
+
return user ? [id, user] : null;
|
|
3335
3167
|
}),
|
|
3336
3168
|
limit: SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY
|
|
3337
3169
|
});
|
|
3338
|
-
|
|
3339
|
-
return userMap;
|
|
3170
|
+
return new Map(results.flatMap((result) => result ? [result] : []));
|
|
3340
3171
|
}
|
|
3341
3172
|
async function resolveSlackThreadContextData(params) {
|
|
3342
3173
|
const botIdentity = {
|
|
@@ -3375,10 +3206,7 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3375
3206
|
const starter = params.threadStarter;
|
|
3376
3207
|
const starterSenderName = params.allowNameMatching && params.allowFromLower.length > 0 && starter?.userId ? (await params.ctx.resolveUserName(starter.userId, params.eventScope))?.name : void 0;
|
|
3377
3208
|
params.assertHistoryCurrent?.();
|
|
3378
|
-
const starterIsCurrentBot = Boolean(starter && isCurrentBotAuthor(
|
|
3379
|
-
userId: starter.userId,
|
|
3380
|
-
botId: starter.botId
|
|
3381
|
-
}));
|
|
3209
|
+
const starterIsCurrentBot = Boolean(starter && isCurrentBotAuthor(starter));
|
|
3382
3210
|
const starterAllowed = !starter || !starterIsCurrentBot && resolveSlackUserAllowed({
|
|
3383
3211
|
allowList: params.allowFromLower,
|
|
3384
3212
|
teamId: params.eventScope?.teamId ?? params.ctx.teamId,
|
|
@@ -3420,18 +3248,12 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3420
3248
|
}
|
|
3421
3249
|
}
|
|
3422
3250
|
} else threadLabel = `Slack thread ${params.roomLabel}`;
|
|
3423
|
-
const includeBotStarterAsRootContext =
|
|
3424
|
-
starterIsCurrentBot,
|
|
3425
|
-
isNewThreadSession: shouldSeedInitialThreadContext,
|
|
3426
|
-
hasStarterText: Boolean(starter?.text)
|
|
3427
|
-
});
|
|
3251
|
+
const includeBotStarterAsRootContext = Boolean(starter?.text && starterIsCurrentBot && shouldSeedInitialThreadContext);
|
|
3428
3252
|
if (starter?.text && starterIsCurrentBot && !includeBotStarterAsRootContext) logVerbose("slack: omitted current-bot thread starter from context");
|
|
3429
3253
|
else if (starter?.text && !includeStarterContext && !starterIsCurrentBot) logVerbose(`slack: omitted thread starter from context (mode=${params.contextVisibilityMode}, sender_allowed=${starterAllowed ? "yes" : "no"})`);
|
|
3430
3254
|
else if (includeBotStarterAsRootContext) {
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
starterText: starter?.text
|
|
3434
|
-
});
|
|
3255
|
+
const snippet = formatSlackThreadLabelSnippet(starter?.text ?? "").trim();
|
|
3256
|
+
threadLabel = `Slack thread ${params.roomLabel}${snippet ? ` (assistant root): ${snippet}` : ""}`;
|
|
3435
3257
|
logVerbose("slack: retained current-bot thread starter as assistant root context");
|
|
3436
3258
|
}
|
|
3437
3259
|
const threadInitialHistoryLimit = Math.min(params.account.config?.thread?.initialHistoryLimit ?? 20, params.historyLimit ?? Number.POSITIVE_INFINITY);
|
|
@@ -3469,24 +3291,15 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3469
3291
|
text: threadStarterBody,
|
|
3470
3292
|
ts: currentBotRootTs
|
|
3471
3293
|
} : null;
|
|
3472
|
-
const
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
ts: currentBotRootTs
|
|
3478
|
-
} : null
|
|
3479
|
-
});
|
|
3294
|
+
const threadHistoryWithEnrichedRoot = enrichedStarter && !threadHistory.some((entry) => entry.ts === currentBotRootTs) ? [enrichedStarter, ...threadHistory.length >= threadInitialHistoryLimit ? threadHistory.slice(1) : threadHistory] : threadHistory;
|
|
3295
|
+
const threadHistoryWithBotRoot = includeBotStarterAsRootContext && starter && !threadHistoryWithEnrichedRoot.some((entry) => entry.ts === currentBotRootTs) ? [{
|
|
3296
|
+
...starter,
|
|
3297
|
+
ts: currentBotRootTs
|
|
3298
|
+
}, ...threadHistoryWithEnrichedRoot] : threadHistoryWithEnrichedRoot;
|
|
3480
3299
|
if (threadHistoryWithBotRoot.length > 0) {
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
includeBotStarterAsRootContext,
|
|
3485
|
-
starterTs: currentBotRootTs,
|
|
3486
|
-
retainCurrentBotHistory: params.isGroupDm && (isMissingThreadSession || isOutboundOnlyThreadSession)
|
|
3487
|
-
}),
|
|
3488
|
-
identity: botIdentity
|
|
3489
|
-
});
|
|
3300
|
+
const retainCurrentBotHistory = params.isGroupDm && (isMissingThreadSession || isOutboundOnlyThreadSession);
|
|
3301
|
+
const threadHistoryWithoutCurrentBot = threadHistoryWithBotRoot.filter((entry) => !isCurrentBotAuthor(entry) || retainCurrentBotHistory || includeBotStarterAsRootContext && entry.ts === currentBotRootTs);
|
|
3302
|
+
const omittedCurrentBotHistoryCount = threadHistoryWithBotRoot.length - threadHistoryWithoutCurrentBot.length;
|
|
3490
3303
|
const userMapForFilter = params.contextVisibilityMode !== "all" && params.allowNameMatching && params.allowFromLower.length > 0 ? await resolveSlackThreadUserMap({
|
|
3491
3304
|
ctx: params.ctx,
|
|
3492
3305
|
messages: threadHistoryWithoutCurrentBot,
|
|
@@ -3501,10 +3314,7 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3501
3314
|
mode: params.contextVisibilityMode,
|
|
3502
3315
|
kind: "thread",
|
|
3503
3316
|
isSenderAllowed: (historyMsg) => {
|
|
3504
|
-
if (isCurrentBotAuthor(
|
|
3505
|
-
userId: historyMsg.userId,
|
|
3506
|
-
botId: historyMsg.botId
|
|
3507
|
-
})) return true;
|
|
3317
|
+
if (isCurrentBotAuthor(historyMsg)) return true;
|
|
3508
3318
|
const msgUser = historyMsg.userId ? userMapForFilter.get(historyMsg.userId) : null;
|
|
3509
3319
|
return resolveSlackUserAllowed({
|
|
3510
3320
|
allowList: params.allowFromLower,
|
|
@@ -3525,10 +3335,7 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3525
3335
|
const historyParts = [];
|
|
3526
3336
|
for (const historyMsg of filteredThreadHistory) {
|
|
3527
3337
|
const msgUser = historyMsg.userId ? userMap.get(historyMsg.userId) : null;
|
|
3528
|
-
const isCurrentBot = isCurrentBotAuthor(
|
|
3529
|
-
userId: historyMsg.userId,
|
|
3530
|
-
botId: historyMsg.botId
|
|
3531
|
-
});
|
|
3338
|
+
const isCurrentBot = isCurrentBotAuthor(historyMsg);
|
|
3532
3339
|
const role = isCurrentBot || historyMsg.botId ? "assistant" : "user";
|
|
3533
3340
|
const msgSenderName = isCurrentBot ? "Bot (this assistant)" : msgUser?.name ?? (historyMsg.botId ? `Bot (${historyMsg.botId})` : "Unknown");
|
|
3534
3341
|
const msgWithId = `${historyMsg.ts === currentBotRootTs && threadStarterBody ? threadStarterBody : historyMsg.text}\n[slack message id: ${historyMsg.ts ?? "unknown"} channel: ${params.message.channel}]`;
|
|
@@ -3556,12 +3363,64 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3556
3363
|
};
|
|
3557
3364
|
}
|
|
3558
3365
|
//#endregion
|
|
3366
|
+
//#region src/channels/mention-gating.ts
|
|
3367
|
+
function resolveBotThreadMentionPolicy(params) {
|
|
3368
|
+
if (!params.isBotOwnedThread || params.requireMentionInBotThreads === void 0) return {
|
|
3369
|
+
requireMention: params.requireMention,
|
|
3370
|
+
implicitMentionKinds: params.implicitMentionKinds
|
|
3371
|
+
};
|
|
3372
|
+
return {
|
|
3373
|
+
requireMention: params.requireMentionInBotThreads,
|
|
3374
|
+
implicitMentionKinds: params.requireMentionInBotThreads ? params.implicitMentionKinds?.filter((kind) => kind === "native") : params.implicitMentionKinds
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3377
|
+
//#endregion
|
|
3378
|
+
//#region \0openclaw:bundled-sdk:openclaw/plugin-sdk/channel-mention-gating
|
|
3379
|
+
var channel_mention_gating_exports = /* @__PURE__ */ __exportAll({ resolveBotThreadMentionPolicy: () => resolveBotThreadMentionPolicy });
|
|
3380
|
+
import * as import_openclaw_plugin_sdk_channel_mention_gating from "openclaw/plugin-sdk/channel-mention-gating";
|
|
3381
|
+
__reExport(channel_mention_gating_exports, import_openclaw_plugin_sdk_channel_mention_gating);
|
|
3382
|
+
//#endregion
|
|
3383
|
+
//#region extensions/slack/src/monitor/message-handler/prepare-thread-mentions.ts
|
|
3384
|
+
async function resolveSlackThreadMentionPolicy(params) {
|
|
3385
|
+
const { ctx, account, message, conversation, thread } = params;
|
|
3386
|
+
const { isRoom, isDirectMessage, channelConfig } = conversation;
|
|
3387
|
+
let implicitMentionKinds = [];
|
|
3388
|
+
if (!isDirectMessage && message.thread_ts && !params.wasMentioned) {
|
|
3389
|
+
const replyToBotKinds = (0, channel_mention_gating_exports.implicitMentionKindWhen)("reply_to_bot", Boolean(ctx.botUserId && message.parent_user_id === ctx.botUserId));
|
|
3390
|
+
implicitMentionKinds = replyToBotKinds.length > 0 ? replyToBotKinds : (0, channel_mention_gating_exports.implicitMentionKindWhen)("bot_thread_participant", await hasSlackThreadParticipationWithPersistence({
|
|
3391
|
+
accountId: account.accountId,
|
|
3392
|
+
channelId: message.channel,
|
|
3393
|
+
threadTs: message.thread_ts,
|
|
3394
|
+
teamId: params.teamId
|
|
3395
|
+
}));
|
|
3396
|
+
}
|
|
3397
|
+
const requireMentionInBotThreads = channelConfig?.requireMentionInBotThreads ?? account.config.requireMentionInBotThreads;
|
|
3398
|
+
let isBotOwnedThread = false;
|
|
3399
|
+
if (isRoom && thread.isThreadReply && requireMentionInBotThreads !== void 0) {
|
|
3400
|
+
const parentUserId = normalizeOptionalString(message.parent_user_id);
|
|
3401
|
+
if (parentUserId) isBotOwnedThread = Boolean(ctx.botUserId && parentUserId === ctx.botUserId);
|
|
3402
|
+
else {
|
|
3403
|
+
const starter = await params.getThreadStarter();
|
|
3404
|
+
isBotOwnedThread = Boolean(starter && starter.ts === thread.threadTs && isSlackThreadAuthorCurrentBot({
|
|
3405
|
+
identity: ctx,
|
|
3406
|
+
author: starter
|
|
3407
|
+
}));
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
return resolveBotThreadMentionPolicy({
|
|
3411
|
+
isBotOwnedThread,
|
|
3412
|
+
requireMentionInBotThreads,
|
|
3413
|
+
requireMention: isRoom ? channelConfig?.requireMention ?? ctx.defaultRequireMention : false,
|
|
3414
|
+
implicitMentionKinds
|
|
3415
|
+
});
|
|
3416
|
+
}
|
|
3417
|
+
//#endregion
|
|
3559
3418
|
//#region extensions/slack/src/monitor/message-handler/subteam-mentions.ts
|
|
3560
3419
|
const SUBTEAM_MENTION_RE = /<!subteam\^([A-Z0-9]+)(?:\|[^>]*)?>/gi;
|
|
3561
3420
|
const SUBTEAM_MEMBER_CACHE_TTL_MS = 3e5;
|
|
3562
3421
|
const subteamMemberCache = /* @__PURE__ */ new WeakMap();
|
|
3563
3422
|
function normalizeSlackId(value) {
|
|
3564
|
-
return
|
|
3423
|
+
return normalizeOptionalString(value)?.toUpperCase();
|
|
3565
3424
|
}
|
|
3566
3425
|
function extractSlackSubteamMentionIds(text) {
|
|
3567
3426
|
if (!text) return [];
|
|
@@ -3594,7 +3453,7 @@ async function readSlackSubteamUsers(params) {
|
|
|
3594
3453
|
params.log?.(`slack: failed to resolve user-group mention ${params.subteamId}: ${response.error ?? "unknown_error"}`);
|
|
3595
3454
|
return /* @__PURE__ */ new Set();
|
|
3596
3455
|
}
|
|
3597
|
-
const users = new Set((response.users ?? []).map((userId) =>
|
|
3456
|
+
const users = new Set((response.users ?? []).map(normalizeSlackId).filter((userId) => userId !== void 0));
|
|
3598
3457
|
const expiresAt = resolveExpiresAtMsFromDurationMs(SUBTEAM_MEMBER_CACHE_TTL_MS, { nowMs: params.now });
|
|
3599
3458
|
if (expiresAt !== void 0) bySubteam.set(cacheKey, {
|
|
3600
3459
|
expiresAt,
|
|
@@ -3635,13 +3494,6 @@ function resolveSlackGroupSessionSubject(params) {
|
|
|
3635
3494
|
if (channelName && workspaceName) return `${workspaceName} #${channelName}`;
|
|
3636
3495
|
return `Slack Channel (Workspace ID: ${params.workspaceId}, Channel ID: ${params.channelId})`;
|
|
3637
3496
|
}
|
|
3638
|
-
function recordString(record, key) {
|
|
3639
|
-
return normalizeOptionalString(record?.[key]);
|
|
3640
|
-
}
|
|
3641
|
-
function recordNullableString(record, key) {
|
|
3642
|
-
const value = record?.[key];
|
|
3643
|
-
return value === null ? null : normalizeOptionalString(value);
|
|
3644
|
-
}
|
|
3645
3497
|
function mergeSlackAssistantThreadContext(primary, fallback) {
|
|
3646
3498
|
if (!primary) return fallback;
|
|
3647
3499
|
if (!fallback) return primary;
|
|
@@ -3661,16 +3513,16 @@ function resolveSlackMessageAssistantThreadContext(message) {
|
|
|
3661
3513
|
const thread = asOptionalRecord(message.assistant_thread);
|
|
3662
3514
|
if (!thread) return;
|
|
3663
3515
|
const context = asOptionalRecord(thread.context);
|
|
3664
|
-
const assistantChannelId =
|
|
3665
|
-
const threadTs =
|
|
3516
|
+
const assistantChannelId = normalizeOptionalString(thread.channel_id) ?? message.channel;
|
|
3517
|
+
const threadTs = normalizeOptionalString(thread.thread_ts) ?? message.thread_ts ?? message.ts;
|
|
3666
3518
|
if (!assistantChannelId || !threadTs) return;
|
|
3667
3519
|
return {
|
|
3668
3520
|
assistantChannelId,
|
|
3669
3521
|
threadTs,
|
|
3670
|
-
userId:
|
|
3671
|
-
channelId:
|
|
3672
|
-
teamId:
|
|
3673
|
-
enterpriseId:
|
|
3522
|
+
userId: normalizeOptionalString(thread.user_id) ?? message.user,
|
|
3523
|
+
channelId: normalizeOptionalString(context?.channel_id),
|
|
3524
|
+
teamId: normalizeOptionalString(context?.team_id),
|
|
3525
|
+
enterpriseId: context?.enterprise_id === null ? null : normalizeOptionalString(context?.enterprise_id)
|
|
3674
3526
|
};
|
|
3675
3527
|
}
|
|
3676
3528
|
async function restoreSlackAssistantThreadContextFromMetadata(params) {
|
|
@@ -3752,7 +3604,7 @@ async function resolveSlackConversationContext(params) {
|
|
|
3752
3604
|
const cfg = ctx.cfg;
|
|
3753
3605
|
let channelInfo = {};
|
|
3754
3606
|
let resolvedChannelType = normalizeSlackChannelType(message.channel_type, message.channel);
|
|
3755
|
-
if (resolvedChannelType !== "im" &&
|
|
3607
|
+
if (resolvedChannelType !== "im" && message.channel_type !== "im") {
|
|
3756
3608
|
channelInfo = await ctx.resolveChannelName(message.channel, params.eventScope);
|
|
3757
3609
|
resolvedChannelType = normalizeSlackChannelType(message.channel_type ?? channelInfo.type ?? ctx.recallSlackChannelType(message.channel, params.eventScope), message.channel);
|
|
3758
3610
|
}
|
|
@@ -3771,7 +3623,7 @@ async function resolveSlackConversationContext(params) {
|
|
|
3771
3623
|
defaultRequireMention: ctx.defaultRequireMention,
|
|
3772
3624
|
allowNameMatching: ctx.allowNameMatching
|
|
3773
3625
|
}) : null;
|
|
3774
|
-
const allowBotsSetting = channelConfig?.allowBots ?? account.config?.allowBots ?? cfg.channels?.slack?.allowBots ??
|
|
3626
|
+
const allowBotsSetting = channelConfig?.allowBots ?? account.config?.allowBots ?? cfg.channels?.slack?.allowBots ?? true;
|
|
3775
3627
|
return {
|
|
3776
3628
|
channelInfo,
|
|
3777
3629
|
channelName,
|
|
@@ -3789,7 +3641,7 @@ async function authorizeSlackInboundMessage(params) {
|
|
|
3789
3641
|
const { ctx, account, message, conversation, drop } = params;
|
|
3790
3642
|
const { isDirectMessage, channelName, resolvedChannelType, isBotMessage, allowBotsMode } = conversation;
|
|
3791
3643
|
if (isBotMessage) {
|
|
3792
|
-
if (message.user
|
|
3644
|
+
if (ctx.botUserId && message.user === ctx.botUserId || ctx.botId && message.bot_id === ctx.botId) return null;
|
|
3793
3645
|
if (allowBotsMode === "off") return drop("bot-disabled");
|
|
3794
3646
|
}
|
|
3795
3647
|
if (isDirectMessage && !message.user) return drop("missing-user");
|
|
@@ -3938,20 +3790,21 @@ async function prepareSlackMessage(params) {
|
|
|
3938
3790
|
eventScope: opts.eventScope
|
|
3939
3791
|
});
|
|
3940
3792
|
const channelRequireMention = channelConfig?.requireMention ?? ctx.defaultRequireMention ?? true;
|
|
3941
|
-
const
|
|
3793
|
+
const chatType = resolveSlackChatType(conversation.resolvedChannelType);
|
|
3942
3794
|
const restoredAssistantThreadContext = await restoredAssistantThreadContextPromise;
|
|
3943
3795
|
const assistantThreadContext = mergeSlackAssistantThreadContext(messageAssistantThreadContext, cachedAssistantThreadContext ?? restoredAssistantThreadContext);
|
|
3944
3796
|
const assistantThreadContextToCache = messageAssistantThreadContext || restoredAssistantThreadContext ? assistantThreadContext : void 0;
|
|
3945
3797
|
if (assistantThreadContextToCache) ctx.saveSlackAssistantThreadContext(assistantThreadContextToCache, opts.eventScope);
|
|
3946
|
-
const
|
|
3798
|
+
const canUseManagedView = isDirectMessage && !opts.eventScope && !assistantThreadContext;
|
|
3799
|
+
const hasAgentViewMessageSignal = canUseManagedView && isSlackAppContext(message.app_context);
|
|
3947
3800
|
if (hasAgentViewMessageSignal) await ctx.recordSlackAgentView();
|
|
3948
3801
|
const managedViewThreadTs = message.thread_ts;
|
|
3949
|
-
const isManagedViewRoot =
|
|
3802
|
+
const isManagedViewRoot = canUseManagedView && !message.parent_user_id && Boolean(managedViewThreadTs && message.ts && managedViewThreadTs === message.ts);
|
|
3950
3803
|
if (isManagedViewRoot && managedViewThreadTs) await ctx.recordSlackManagedViewThread(message.channel, managedViewThreadTs);
|
|
3951
|
-
const hasManagedViewThread =
|
|
3952
|
-
const isAgentViewMessage =
|
|
3804
|
+
const hasManagedViewThread = canUseManagedView && Boolean(managedViewThreadTs && await ctx.isSlackManagedViewThread(message.channel, managedViewThreadTs));
|
|
3805
|
+
const isAgentViewMessage = canUseManagedView && (hasAgentViewMessageSignal || isManagedViewRoot || hasManagedViewThread || await ctx.isSlackAgentView());
|
|
3953
3806
|
const agentViewThreadTs = isAgentViewMessage ? message.thread_ts ?? message.ts : void 0;
|
|
3954
|
-
const channelReplyToMode = channelConfig?.replyToMode ?? resolveSlackReplyToMode(account,
|
|
3807
|
+
const channelReplyToMode = channelConfig?.replyToMode ?? resolveSlackReplyToMode(account, chatType);
|
|
3955
3808
|
const willImplicitlyThreadReply = isRoom && !channelRequireMention && channelReplyToMode !== "off";
|
|
3956
3809
|
const seedTopLevelRoomThreadBySource = opts.source === "app_mention" || opts.wasMentioned === true || explicitlyMentioned || willImplicitlyThreadReply;
|
|
3957
3810
|
const resolveMessageRouting = (seedTopLevelRoomThread) => resolveSlackRoutingContext({
|
|
@@ -4034,16 +3887,6 @@ async function prepareSlackMessage(params) {
|
|
|
4034
3887
|
ok: true,
|
|
4035
3888
|
name: void 0
|
|
4036
3889
|
});
|
|
4037
|
-
let implicitMentionKinds = [];
|
|
4038
|
-
if (!isDirectMessage && message.thread_ts && !wasMentioned) {
|
|
4039
|
-
const replyToBotKinds = implicitMentionKindWhen("reply_to_bot", Boolean(ctx.botUserId && message.parent_user_id === ctx.botUserId));
|
|
4040
|
-
implicitMentionKinds = replyToBotKinds.length > 0 ? replyToBotKinds : implicitMentionKindWhen("bot_thread_participant", await hasSlackThreadParticipationWithPersistence({
|
|
4041
|
-
accountId: account.accountId,
|
|
4042
|
-
channelId: message.channel,
|
|
4043
|
-
threadTs: message.thread_ts,
|
|
4044
|
-
teamId: opts.eventScope?.teamId
|
|
4045
|
-
}));
|
|
4046
|
-
}
|
|
4047
3890
|
let threadStarterPromise;
|
|
4048
3891
|
const getThreadStarter = () => {
|
|
4049
3892
|
threadStarterPromise ??= isThreadReply && threadTs ? resolveSlackThreadStarter({
|
|
@@ -4079,7 +3922,18 @@ async function prepareSlackMessage(params) {
|
|
|
4079
3922
|
cfg,
|
|
4080
3923
|
surface: "slack"
|
|
4081
3924
|
});
|
|
4082
|
-
const
|
|
3925
|
+
const { requireMention: shouldRequireMention, implicitMentionKinds } = await resolveSlackThreadMentionPolicy({
|
|
3926
|
+
ctx,
|
|
3927
|
+
account,
|
|
3928
|
+
message,
|
|
3929
|
+
conversation,
|
|
3930
|
+
thread: routing,
|
|
3931
|
+
wasMentioned,
|
|
3932
|
+
teamId: opts.eventScope?.teamId,
|
|
3933
|
+
getThreadStarter
|
|
3934
|
+
});
|
|
3935
|
+
opts.abortSignal?.throwIfAborted();
|
|
3936
|
+
if (opts.isRuntimePolicyCurrent?.() === false) return drop("final-route-denied");
|
|
4083
3937
|
const implicitMentions = resolveChannelImplicitMentions({
|
|
4084
3938
|
cfg,
|
|
4085
3939
|
channel: "slack",
|
|
@@ -4095,6 +3949,7 @@ async function prepareSlackMessage(params) {
|
|
|
4095
3949
|
ctx,
|
|
4096
3950
|
teamId: opts.eventScope?.teamId ?? ctx.teamId,
|
|
4097
3951
|
senderId,
|
|
3952
|
+
senderAuthentication: message.user ? opts.senderAuthentication : void 0,
|
|
4098
3953
|
senderName: senderNameForAuth,
|
|
4099
3954
|
channelType: conversation.resolvedChannelType ?? "channel",
|
|
4100
3955
|
channelId: message.channel,
|
|
@@ -4128,7 +3983,7 @@ async function prepareSlackMessage(params) {
|
|
|
4128
3983
|
allowFromLower,
|
|
4129
3984
|
eventScope: opts.eventScope
|
|
4130
3985
|
})) return drop("unauthorized-bot");
|
|
4131
|
-
const threadContextAllowFromLower = isRoom ? channelUsersAllowlistConfigured ?
|
|
3986
|
+
const threadContextAllowFromLower = isRoom ? channelUsersAllowlistConfigured ? normalizeStringEntriesLower(channelConfig?.users) : [] : isDirectMessage ? allowFromLower : [];
|
|
4132
3987
|
const contextVisibilityMode = resolveChannelContextVisibilityMode({
|
|
4133
3988
|
cfg: ctx.cfg,
|
|
4134
3989
|
channel: "slack",
|
|
@@ -4245,7 +4100,6 @@ async function prepareSlackMessage(params) {
|
|
|
4245
4100
|
const ignoreOtherMentions = channelConfig?.ignoreOtherMentions ?? false;
|
|
4246
4101
|
if (isRoom && ignoreOtherMentions && Boolean(ctx.botUserId) && hasAnyMention && !wasMentioned) return drop("other-mention");
|
|
4247
4102
|
if (isRoom && shouldRequireMention && mentionDecision.shouldSkip) return drop("missing-mention");
|
|
4248
|
-
const chatType = resolveSlackChatType(conversation.resolvedChannelType);
|
|
4249
4103
|
const inboundEventKind = classifyChannelInboundEvent({
|
|
4250
4104
|
conversation: { kind: chatType },
|
|
4251
4105
|
unmentionedGroupPolicy: resolveUnmentionedGroupInboundPolicy({
|
|
@@ -4258,6 +4112,8 @@ async function prepareSlackMessage(params) {
|
|
|
4258
4112
|
});
|
|
4259
4113
|
const threadStarter = await getThreadStarter();
|
|
4260
4114
|
const resolvedMessageContent = await getMessageContent();
|
|
4115
|
+
opts.abortSignal?.throwIfAborted();
|
|
4116
|
+
if (opts.isRuntimePolicyCurrent?.() === false) return drop("final-route-denied");
|
|
4261
4117
|
if (!resolvedMessageContent) return drop("empty-content");
|
|
4262
4118
|
const { rawBody, effectiveDirectMedia, commandSourceText, mentionStripPatterns } = resolvedMessageContent;
|
|
4263
4119
|
const bodyForAgent = preflightAudioTranscript ? formatSlackAudioTranscriptForAgent({
|
|
@@ -4278,7 +4134,7 @@ async function prepareSlackMessage(params) {
|
|
|
4278
4134
|
}) === "message_tool_only";
|
|
4279
4135
|
const statusReactionsExplicitlyEnabled = cfg.messages?.statusReactions?.enabled === true;
|
|
4280
4136
|
const isRoomEvent = inboundEventKind === "room_event";
|
|
4281
|
-
const shouldAckReaction$1 =
|
|
4137
|
+
const shouldAckReaction$1 = Boolean(ackReaction && shouldAckReaction({
|
|
4282
4138
|
scope: cfg.messages?.ackReactionScope,
|
|
4283
4139
|
inboundEventKind,
|
|
4284
4140
|
isDirect: isDirectMessage,
|
|
@@ -4289,7 +4145,7 @@ async function prepareSlackMessage(params) {
|
|
|
4289
4145
|
shouldBypassMention
|
|
4290
4146
|
}));
|
|
4291
4147
|
const ackReactionMessageTs = message.ts;
|
|
4292
|
-
const shouldSendAckReaction = shouldAckReaction$1
|
|
4148
|
+
const shouldSendAckReaction = shouldAckReaction$1 && (!sourceRepliesAreToolOnly || effectiveWasMentioned || shouldBypassMention || isRoomEvent);
|
|
4293
4149
|
const statusReactionsWillHandle = Boolean(ackReactionMessageTs) && !isRoomEvent && statusReactionsExplicitlyEnabled && shouldSendAckReaction;
|
|
4294
4150
|
const ackReactionPromise = !statusReactionsWillHandle && shouldSendAckReaction && ackReactionMessageTs && ackReactionValue ? reactSlackMessage(message.channel, ackReactionMessageTs, ackReactionValue, {
|
|
4295
4151
|
token: ctx.botToken,
|
|
@@ -4417,20 +4273,18 @@ async function prepareSlackMessage(params) {
|
|
|
4417
4273
|
let { threadStarterBody, threadHistoryBody, shouldSeedInitialThreadContext } = threadContextData;
|
|
4418
4274
|
const threadScopedHistory = isThreadReply && ctx.threadHistoryScope === "thread";
|
|
4419
4275
|
let roomHistory = [];
|
|
4420
|
-
if (isRoomish && ctx.historyLimit > 0 && (!threadScopedHistory || !shouldSeedInitialThreadContext)) {
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
});
|
|
4433
|
-
}
|
|
4276
|
+
if (isRoomish && ctx.historyLimit > 0 && (!threadScopedHistory || !shouldSeedInitialThreadContext) && sessionEntry?.updatedAt !== 0) roomHistory = await resolveSlackRoomHistory({
|
|
4277
|
+
ctx,
|
|
4278
|
+
message,
|
|
4279
|
+
threadTs: threadScopedHistory ? threadTs : void 0,
|
|
4280
|
+
oldest: sessionEntry?.sessionStartedAt ? (sessionEntry.sessionStartedAt / 1e3).toFixed(6) : void 0,
|
|
4281
|
+
excludedMessageIds,
|
|
4282
|
+
allowFromLower: threadContextAllowFromLower,
|
|
4283
|
+
contextVisibilityMode,
|
|
4284
|
+
eventScope: opts.eventScope,
|
|
4285
|
+
assertCurrent: assertHistoryCurrent,
|
|
4286
|
+
abortSignal: opts.abortSignal
|
|
4287
|
+
});
|
|
4434
4288
|
const effectiveMedia = effectiveDirectMedia ?? threadStarterMedia;
|
|
4435
4289
|
let inboundMedia = await toInboundMediaFactsWithMetadata(effectiveMedia, { transcribed: (entry) => effectiveMedia === effectiveDirectMedia && entry === preflightAudioMedia });
|
|
4436
4290
|
opts.abortSignal?.throwIfAborted();
|