@openclaw/slack 2026.8.1-beta.3 → 2026.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/account-configured-sUohAxZr.js +33 -0
- package/dist/account-inspect-C3sePHWa.js +87 -0
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-BlzxuYle.js → accounts-Dm_H77gH.js} +7 -10
- package/dist/{accounts.runtime-CbabBL8x.js → accounts.runtime-DRuEK6mL.js} +1 -1
- package/dist/{action-runtime-D6jg2CQd.js → action-runtime-B0kRJ69h.js} +90 -75
- package/dist/action-runtime.runtime-IuA14rev.js +2 -0
- package/dist/{actions-DFk0ANVB.js → actions-BOxiu2Vy.js} +278 -102
- package/dist/api.js +15 -15
- package/dist/{approval-handler.runtime-BNvAoKdK.js → approval-handler.runtime-l5_2JLqi.js} +58 -180
- package/dist/{channel-CA5w7qDF.js → channel-BguxhhNG.js} +97 -154
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-CZWv55Wu.js → channel-type-ChkODKBW.js} +3 -3
- package/dist/{channel.setup-CpyYsEXH.js → channel.setup-BJohRJha.js} +54 -68
- package/dist/{config-schema-CN3XZRX5.js → config-schema-B9GwoRlE.js} +24 -15
- package/dist/configured-state.js +34 -0
- package/dist/{conversation-binding-route-DFVLUdYF.js → conversation-binding-route-Vee8Dgbf.js} +2 -2
- package/dist/{directory-config-BGYyuzWh.js → directory-config-Bmw4ykSy.js} +5 -4
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-DjUJQLbq.js → directory-live-BOILcXPo.js} +2 -2
- package/dist/{doctor-contract-BAy7-EUQ.js → doctor-contract-BNjw9bxb.js} +5 -4
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{group-policy-DyfB_ZIE.js → group-policy-BYH74y50.js} +643 -774
- package/dist/{message-tool-api-CqMr5Rmc.js → message-tool-api-BsZbsulu.js} +23 -5
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-Chrecrb9.js → monitor-B72wWXWg.js} +3 -3
- package/dist/{outbound-adapter-DuRqAQXK.js → outbound-adapter-CPgYQ-BM.js} +94 -69
- package/dist/{pipeline.runtime-Bbfd5VFW.js → pipeline.runtime-CcdujV99.js} +357 -544
- package/dist/{policy-BKXSxrIS.js → policy-CUpBeOt9.js} +7 -4
- package/dist/{probe-BVA65leh.js → probe-gj5yQgN2.js} +209 -21
- package/dist/{provider-CUUiwsg2.js → provider-DW9YC_no.js} +301 -179
- package/dist/{relay-source-mhpMMRG-.js → relay-source-BLMdBrAw.js} +6 -4
- package/dist/{replies-SnWyXcsL.js → replies-DLjQ8RYU.js} +25 -10
- package/dist/{resolve-channels-BSpqC8jU.js → resolve-channels-Bv6IiGZ4.js} +4 -3
- package/dist/{resolve-users-Dvz9pDe0.js → resolve-users-BXw2pA7y.js} +4 -3
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-BSk4GZvZ.js → scopes-B9HRguDe.js} +1 -1
- package/dist/{send-CtnOxKCc.js → send-GUz4_v2E.js} +58 -42
- package/dist/send-results-eeOu_HYm.js +23 -0
- package/dist/{send.runtime-kYctMHSd.js → send.runtime-rScD-UJi.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-BPFfp6So.js → setup-surface-Cc3P-z35.js} +6 -6
- package/dist/{shared-DJBaslN7.js → shared-CQGVZ_8a.js} +28 -8
- package/dist/{slash-dispatch.runtime-Cf2FTrnf.js → slash-dispatch.runtime-C2015r6s.js} +3 -3
- package/dist/{target-parsing-BnMD2ZqZ.js → target-parsing-PbxGDbr9.js} +11 -6
- package/dist/{targets-Cx5W_n3W.js → targets-7FexXJ62.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 +0 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/bolt/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/bolt/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/bolt/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/bolt/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/bolt/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/bolt/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/README.md +2 -0
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/package.json +1 -1
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/package.json +16 -10
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/README.md +2 -0
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/package.json +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/socket-mode/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/socket-mode/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/socket-mode/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/socket-mode/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/socket-mode/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/socket-mode/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/socket-mode/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/socket-mode/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/socket-mode/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/v8.d.ts +20 -23
- 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 +0 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/web-api/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/web-api/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/web-api/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/web-api/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/web-api/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/web-api/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/typebox/build/format/date.d.mts +1 -1
- package/node_modules/typebox/build/format/date.mjs +1 -1
- package/node_modules/typebox/build/format/date_time.d.mts +2 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -3
- package/node_modules/typebox/build/format/email.d.mts +1 -1
- package/node_modules/typebox/build/format/email.mjs +2 -2
- package/node_modules/typebox/build/format/hostname.mjs +2 -10
- package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_email.mjs +3 -3
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
- package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
- package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
- package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +41 -0
- package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
- package/node_modules/typebox/build/format/idna/index.mjs +2 -0
- package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
- package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
- package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
- package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
- package/node_modules/typebox/build/format/ipv4.mjs +2 -32
- package/node_modules/typebox/build/format/ipv6.mjs +2 -61
- package/node_modules/typebox/build/format/iri.d.mts +2 -2
- package/node_modules/typebox/build/format/iri.mjs +26 -8
- package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
- package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
- package/node_modules/typebox/build/format/regex.d.mts +1 -2
- package/node_modules/typebox/build/format/regex.mjs +2 -6
- package/node_modules/typebox/build/format/time.d.mts +2 -2
- package/node_modules/typebox/build/format/time.mjs +19 -14
- package/node_modules/typebox/build/format/uri.d.mts +1 -1
- package/node_modules/typebox/build/format/uri.mjs +3 -130
- package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
- package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
- package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
- package/node_modules/typebox/build/format/uri_template.mjs +4 -5
- package/node_modules/typebox/build/format/url.d.mts +3 -3
- package/node_modules/typebox/build/format/url.mjs +4 -5
- package/node_modules/typebox/build/guard/emit.d.mts +3 -1
- package/node_modules/typebox/build/guard/emit.mjs +12 -5
- package/node_modules/typebox/build/guard/guard.d.mts +8 -2
- package/node_modules/typebox/build/guard/guard.mjs +25 -4
- package/node_modules/typebox/build/guard/string.d.mts +2 -2
- package/node_modules/typebox/build/guard/string.mjs +7 -7
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
- package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
- package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
- package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
- package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
- package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
- package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
- package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/types/index.mjs +0 -2
- package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
- package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
- package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
- package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
- package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
- package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
- package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
- package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
- package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
- package/node_modules/typebox/build/type/script/parser.mjs +27 -23
- package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
- package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
- package/node_modules/typebox/package.json +27 -27
- package/node_modules/typebox/readme.md +79 -82
- package/node_modules/ws/lib/permessage-deflate.js +3 -1
- package/node_modules/ws/package.json +1 -1
- package/openclaw.plugin.json +14 -6
- package/package.json +9 -7
- package/dist/account-configured-BwfXBo_F.js +0 -14
- package/dist/account-inspect-YJvFBbCR.js +0 -89
- package/dist/action-runtime.runtime-JtoOK9l5.js +0 -2
- package/dist/actions.runtime-CYLsYRai.js +0 -2
- package/dist/runtime-api-DBi7xc_g.js +0 -10
- package/dist/slack-client-kind-BXyOOICI.js +0 -94
- package/node_modules/@slack/bolt/node_modules/negotiator/HISTORY.md +0 -114
- package/node_modules/typebox/build/format/_idna.d.mts +0 -2
- package/node_modules/typebox/build/format/_idna.mjs +0 -246
- package/node_modules/typebox/build/format/_puny.d.mts +0 -1
- package/node_modules/typebox/build/format/_puny.mjs +0 -77
- package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
- package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
- package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
- package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { n as resolveSlackConversationBindingRoute, r as resolveSlackReplyToMode, t as normalizeSlackRouteBindingConfig } from "./conversation-binding-route-
|
|
2
|
-
import { n as formatSlackTarget } from "./target-parsing-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { n as resolveSlackConversationBindingRoute, r as resolveSlackReplyToMode, t as normalizeSlackRouteBindingConfig } from "./conversation-binding-route-Vee8Dgbf.js";
|
|
2
|
+
import { n as formatSlackTarget } from "./target-parsing-PbxGDbr9.js";
|
|
3
|
+
import { I as countSlackTextUtf8Bytes, L as truncateSlackText, M as SLACK_TEXT_LIMIT, Q as normalizeSlackOutboundText, R as truncateSlackTextByUtf8Bytes, T as buildSlackBlocksFallbackText, U as SLACK_SESSION_LINK_ACTION_ID, a as qualifySlackConversationId, b as hasSlackNativeDataBlock, et as escapeSlackMrkdwn, k as SLACK_EDIT_TEXT_MAX_BYTES, m as resolveSlackReplyRenderPlan, o as qualifySlackRoutePeerId, s as resolveSlackEnterpriseMainDmSessionKey } from "./group-policy-BYH74y50.js";
|
|
4
|
+
import { C as normalizeAllowListLower, E as resolveSlackAllowListMatch, o as formatSlackError, w as normalizeSlackAllowOwnerEntry } from "./probe-gj5yQgN2.js";
|
|
5
5
|
import { n as resolveSlackStreamingMode, t as resolveSlackNativeStreaming } from "./streaming-compat-B-e0mqM0.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { c as
|
|
9
|
-
import {
|
|
10
|
-
import { n as
|
|
11
|
-
import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as emitSlackMessageSentHooks, t as createSlackReplyDeliveryPlan } from "./replies-SnWyXcsL.js";
|
|
6
|
+
import { D as resolveSlackMessageText$1, E as resolveSlackBlocksText, O as buildSlackEditTextPayload, S as formatSlackFileReferenceList, T as isSlackUnfurlAttachment, a as editSlackRenderedMessage, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, v as logVerbose$1, w as hasSlackTableBlock, x as formatSlackFileReference } from "./actions-BOxiu2Vy.js";
|
|
7
|
+
import { c as hasSlackThreadFailureNotice, d as recordSlackThreadFailureNotice, f as recordSlackThreadParticipation, l as hasSlackThreadParticipation, m as buildSlackNativeDataDeliveryPlan, o as clearSlackThreadFailureNotice, r as sendMessageSlack, u as hasSlackThreadParticipationWithPersistence } from "./send-GUz4_v2E.js";
|
|
8
|
+
import { C as resolveStorePath, E as stripSlackMentionsForCommandDetection, S as resolveChannelResetConfig, _ as resolveSlackChatType, b as readSessionUpdatedAt, c as resolveSlackThreadTargets, d as authorizeSlackBotRoomMessage, f as resolveSlackCommandIngress, g as normalizeSlackChannelType, l as trackSlackDraftMessage, o as authorizeSlackDirectMessage, p as resolveSlackEffectiveAllowFrom, r as resolveSlackRoomContextHints, s as resolveSlackThreadContext, u as resolveConversationLabel$1, v as buildSlackAssistantThreadMetadata, w as updateLastRoute, x as resolveChannelContextVisibilityMode, y as parseSlackAssistantThreadMetadata } from "./provider-DW9YC_no.js";
|
|
9
|
+
import { n as resolveSlackChannelConfig } from "./policy-CUpBeOt9.js";
|
|
10
|
+
import { a as resolveDeliveredSlackReplyThreadTs, c as emitSlackMessageSentHooks, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as sanitizeSlackMonitorReplyPayload, t as createSlackReplyDeliveryPlan } from "./replies-DLjQ8RYU.js";
|
|
12
11
|
import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
13
12
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
|
|
14
|
-
import {
|
|
13
|
+
import { createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createDraftStreamLoop, createFinalizableDraftStreamControlsForState, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
|
|
15
14
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
16
15
|
import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
16
|
+
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
17
|
+
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
18
|
+
import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement, isReplyPayloadNonTerminalToolErrorWarning, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
17
19
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
18
|
-
import { createHash } from "node:crypto";
|
|
19
20
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
20
21
|
import { ensureConfiguredBindingRouteReady } from "openclaw/plugin-sdk/conversation-runtime";
|
|
22
|
+
import { resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
21
23
|
import fs from "node:fs/promises";
|
|
22
24
|
import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
23
25
|
import { formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
24
|
-
import { buildTtsSupplementMediaPayload, getReplyPayloadTtsSupplement, isReplyPayloadNonTerminalToolErrorWarning, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
25
26
|
import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
|
|
26
27
|
import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
|
|
27
28
|
import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
28
29
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
29
30
|
import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
30
|
-
import { resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
31
31
|
import { asDateTimestampMs, asFiniteNumberInRange, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
|
|
32
32
|
import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
|
|
33
33
|
import { buildChannelInboundEventContext, buildMentionRegexes, classifyChannelInboundEvent, dispatchChannelInboundTurn, formatInboundEnvelope, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, readAgentRunTerminalOutcome, recordDroppedChannelInboundHistory, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundReplyDispatchCounts, resolveInboundSupplementalSenderAllowed, resolveUnmentionedGroupInboundPolicy, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
|
|
34
34
|
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
35
35
|
import { resolveGatewayPublicOrigin } from "openclaw/plugin-sdk/config-contracts";
|
|
36
36
|
import { buildControlUiSessionPath } from "openclaw/plugin-sdk/session-discussion";
|
|
37
|
-
import {
|
|
37
|
+
import { createStatusReactionController, logAckFailure, logTypingFailure, resolveAckReaction, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
38
38
|
import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
|
|
39
39
|
import { isAbortRequestText } from "openclaw/plugin-sdk/command-primitives-runtime";
|
|
40
40
|
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
|
|
@@ -384,12 +384,12 @@ function createSlackDraftStream(params) {
|
|
|
384
384
|
const send = params.send ?? sendMessageSlack;
|
|
385
385
|
const edit = params.edit ?? editSlackMessage;
|
|
386
386
|
const remove = params.remove ?? deleteSlackMessage;
|
|
387
|
-
let
|
|
388
|
-
let streamChannelId;
|
|
387
|
+
let streamMessage;
|
|
389
388
|
let untrackConversationBoundary;
|
|
390
389
|
let lastVisibleUpdate;
|
|
391
390
|
let lastSentKey = "";
|
|
392
|
-
const
|
|
391
|
+
const pendingCleanupMessages = [];
|
|
392
|
+
let cleanupTail = Promise.resolve();
|
|
393
393
|
const finalizedMessageIds = /* @__PURE__ */ new Set();
|
|
394
394
|
const streamState = {
|
|
395
395
|
stopped: false,
|
|
@@ -411,8 +411,8 @@ function createSlackDraftStream(params) {
|
|
|
411
411
|
if (sentKey === lastSentKey) return;
|
|
412
412
|
lastSentKey = sentKey;
|
|
413
413
|
try {
|
|
414
|
-
if (
|
|
415
|
-
await edit(
|
|
414
|
+
if (streamMessage) {
|
|
415
|
+
await edit(streamMessage.channelId, streamMessage.messageId, trimmed, {
|
|
416
416
|
cfg: params.cfg,
|
|
417
417
|
token: params.token,
|
|
418
418
|
accountId: params.accountId,
|
|
@@ -444,27 +444,29 @@ function createSlackDraftStream(params) {
|
|
|
444
444
|
...params.metadata ? { metadata: params.metadata } : {},
|
|
445
445
|
...blocks ? { blocks } : {}
|
|
446
446
|
});
|
|
447
|
-
|
|
448
|
-
streamMessageId = sent.messageId || streamMessageId;
|
|
449
|
-
if (!streamChannelId || !streamMessageId) {
|
|
447
|
+
if (!sent.channelId || !sent.messageId) {
|
|
450
448
|
stopTrackingConversationBoundary();
|
|
451
449
|
streamState.stopped = true;
|
|
452
450
|
params.warn?.("slack stream preview stopped (missing identifiers from sendMessage)");
|
|
453
451
|
return;
|
|
454
452
|
}
|
|
453
|
+
streamMessage = {
|
|
454
|
+
channelId: sent.channelId,
|
|
455
|
+
messageId: sent.messageId
|
|
456
|
+
};
|
|
455
457
|
lastVisibleUpdate = {
|
|
456
458
|
text: trimmed,
|
|
457
459
|
...blocks ? { blocks } : {}
|
|
458
460
|
};
|
|
459
|
-
if (pendingBoundary && params.conversationChannelId ===
|
|
461
|
+
if (pendingBoundary && params.conversationChannelId === streamMessage.channelId) pendingBoundary.setMessageTs(streamMessage.messageId);
|
|
460
462
|
else {
|
|
461
463
|
stopTrackingConversationBoundary();
|
|
462
464
|
untrackConversationBoundary = trackSlackDraftMessage({
|
|
463
465
|
accountId: params.accountId,
|
|
464
466
|
teamId: params.eventScope?.teamId,
|
|
465
|
-
channelId:
|
|
467
|
+
channelId: streamMessage.channelId,
|
|
466
468
|
threadTs,
|
|
467
|
-
messageTs:
|
|
469
|
+
messageTs: streamMessage.messageId,
|
|
468
470
|
onInterveningMessage: forceNewMessage
|
|
469
471
|
}).stop;
|
|
470
472
|
}
|
|
@@ -476,6 +478,7 @@ function createSlackDraftStream(params) {
|
|
|
476
478
|
};
|
|
477
479
|
const { loop, update, discardPending, seal } = createFinalizableDraftStreamControlsForState({
|
|
478
480
|
throttleMs,
|
|
481
|
+
coalesceInFlight: true,
|
|
479
482
|
state: streamState,
|
|
480
483
|
sendOrEditStreamMessage,
|
|
481
484
|
emptyValue: "",
|
|
@@ -485,60 +488,58 @@ function createSlackDraftStream(params) {
|
|
|
485
488
|
untrackConversationBoundary?.();
|
|
486
489
|
untrackConversationBoundary = void 0;
|
|
487
490
|
};
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
491
|
+
const dropDetachedMessages = () => {
|
|
492
|
+
cleanupTail = cleanupTail.then(async () => {
|
|
493
|
+
for (let index = 0; index < pendingCleanupMessages.length;) {
|
|
494
|
+
const message = pendingCleanupMessages[index];
|
|
495
|
+
if (!message) return;
|
|
496
|
+
try {
|
|
497
|
+
await remove(message.channelId, message.messageId, {
|
|
498
|
+
token: params.token,
|
|
499
|
+
accountId: params.accountId,
|
|
500
|
+
...params.eventScope ? { client: params.eventScope.client } : {}
|
|
501
|
+
});
|
|
502
|
+
pendingCleanupMessages.splice(index, 1);
|
|
503
|
+
} catch (err) {
|
|
504
|
+
params.warn?.(`slack stream preview cleanup failed: ${formatSlackError(err)}`);
|
|
505
|
+
index += 1;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
return cleanupTail;
|
|
498
510
|
};
|
|
499
511
|
const clear = async () => {
|
|
500
512
|
stopTrackingConversationBoundary();
|
|
501
513
|
await discardPending();
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
514
|
+
if (streamMessage) {
|
|
515
|
+
pendingCleanupMessages.push(streamMessage);
|
|
516
|
+
streamMessage = void 0;
|
|
517
|
+
}
|
|
506
518
|
lastVisibleUpdate = void 0;
|
|
507
519
|
lastSentKey = "";
|
|
508
|
-
|
|
509
|
-
await removeMessage(channelId, messageId);
|
|
520
|
+
await dropDetachedMessages();
|
|
510
521
|
};
|
|
511
522
|
const forceNewMessage = () => {
|
|
512
523
|
stopTrackingConversationBoundary();
|
|
513
524
|
streamState.stopped = false;
|
|
514
525
|
streamState.final = false;
|
|
515
|
-
if (
|
|
516
|
-
|
|
517
|
-
messageId: streamMessageId
|
|
518
|
-
});
|
|
519
|
-
streamMessageId = void 0;
|
|
520
|
-
streamChannelId = void 0;
|
|
526
|
+
if (streamMessage && !finalizedMessageIds.has(streamMessage.messageId)) pendingCleanupMessages.push(streamMessage);
|
|
527
|
+
streamMessage = void 0;
|
|
521
528
|
lastVisibleUpdate = void 0;
|
|
522
529
|
lastSentKey = "";
|
|
523
530
|
loop.resetPending();
|
|
524
531
|
};
|
|
525
|
-
const dropDetachedMessages = async () => {
|
|
526
|
-
let message;
|
|
527
|
-
while ((message = detachedMessages.shift()) !== void 0) {
|
|
528
|
-
const { channelId, messageId } = message;
|
|
529
|
-
await removeMessage(channelId, messageId);
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
532
|
const discardPendingAndStopTracking = async () => {
|
|
533
533
|
stopTrackingConversationBoundary();
|
|
534
534
|
await discardPending();
|
|
535
535
|
};
|
|
536
536
|
const finalizeMessage = async (messageId, editFinal) => {
|
|
537
|
-
const
|
|
537
|
+
const currentMessage = streamMessage;
|
|
538
538
|
const previousUpdate = lastVisibleUpdate;
|
|
539
|
-
if (!
|
|
539
|
+
if (!currentMessage || currentMessage.messageId !== messageId || !previousUpdate) return false;
|
|
540
|
+
const { channelId } = currentMessage;
|
|
540
541
|
await editFinal();
|
|
541
|
-
if (
|
|
542
|
+
if (streamMessage?.channelId === channelId && streamMessage.messageId === messageId) {
|
|
542
543
|
finalizedMessageIds.add(messageId);
|
|
543
544
|
stopTrackingConversationBoundary();
|
|
544
545
|
return true;
|
|
@@ -566,69 +567,16 @@ function createSlackDraftStream(params) {
|
|
|
566
567
|
forceNewMessage,
|
|
567
568
|
dropDetachedMessages,
|
|
568
569
|
finalizeMessage,
|
|
569
|
-
messageId: () =>
|
|
570
|
-
channelId: () =>
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
//#endregion
|
|
574
|
-
//#region extensions/slack/src/stream-mode.ts
|
|
575
|
-
function resolveSlackStreamingConfig(params) {
|
|
576
|
-
return {
|
|
577
|
-
mode: resolveSlackStreamingMode(params),
|
|
578
|
-
nativeStreaming: resolveSlackNativeStreaming(params)
|
|
579
|
-
};
|
|
580
|
-
}
|
|
581
|
-
function applyAppendOnlyStreamUpdate(params) {
|
|
582
|
-
const incoming = params.incoming.trimEnd();
|
|
583
|
-
if (!incoming) return {
|
|
584
|
-
rendered: params.rendered,
|
|
585
|
-
source: params.source,
|
|
586
|
-
changed: false
|
|
587
|
-
};
|
|
588
|
-
if (!params.rendered) return {
|
|
589
|
-
rendered: incoming,
|
|
590
|
-
source: incoming,
|
|
591
|
-
changed: true
|
|
592
|
-
};
|
|
593
|
-
if (incoming === params.source) return {
|
|
594
|
-
rendered: params.rendered,
|
|
595
|
-
source: params.source,
|
|
596
|
-
changed: false
|
|
597
|
-
};
|
|
598
|
-
if (incoming.startsWith(params.rendered)) return {
|
|
599
|
-
rendered: incoming,
|
|
600
|
-
source: incoming,
|
|
601
|
-
changed: incoming !== params.rendered
|
|
602
|
-
};
|
|
603
|
-
if (incoming.startsWith(params.source)) {
|
|
604
|
-
const delta = incoming.slice(params.source.length);
|
|
605
|
-
return {
|
|
606
|
-
rendered: `${params.rendered}${delta}`,
|
|
607
|
-
source: incoming,
|
|
608
|
-
changed: delta.length > 0
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
if (params.source.startsWith(incoming)) return {
|
|
612
|
-
rendered: params.rendered,
|
|
613
|
-
source: params.source,
|
|
614
|
-
changed: false
|
|
615
|
-
};
|
|
616
|
-
const separator = params.separator ?? (params.rendered.endsWith("\n") ? "" : "\n");
|
|
617
|
-
return {
|
|
618
|
-
rendered: `${params.rendered}${separator}${incoming}`,
|
|
619
|
-
source: incoming,
|
|
620
|
-
changed: true
|
|
570
|
+
messageId: () => streamMessage?.messageId,
|
|
571
|
+
channelId: () => streamMessage?.channelId
|
|
621
572
|
};
|
|
622
573
|
}
|
|
623
574
|
//#endregion
|
|
624
575
|
//#region extensions/slack/src/progress-blocks.ts
|
|
625
576
|
const SLACK_PROGRESS_FIELD_MAX = 1800;
|
|
626
577
|
const DEFAULT_SLACK_PROGRESS_DETAIL_MAX_CHARS = 120;
|
|
627
|
-
const DEFAULT_SLACK_PROGRESS_TASK_DETAIL_MAX_CHARS = 48;
|
|
628
578
|
const SLACK_PROGRESS_CHUNK_TEXT_MAX = 256;
|
|
629
579
|
const SLACK_PROGRESS_TASK_TITLE_MAX = 120;
|
|
630
|
-
const SLACK_PROGRESS_PLAN_FALLBACK_TITLE = "Thinking";
|
|
631
|
-
const SLACK_PROGRESS_LINE_DELTA_RE = /(?:^|\s)\+(\d+)\s+[−-](\d+)(?=\s|$)/u;
|
|
632
580
|
function buildSessionSources(url) {
|
|
633
581
|
return [{
|
|
634
582
|
type: "url_source",
|
|
@@ -636,12 +584,6 @@ function buildSessionSources(url) {
|
|
|
636
584
|
text: "Open in OpenClaw"
|
|
637
585
|
}];
|
|
638
586
|
}
|
|
639
|
-
function field(text) {
|
|
640
|
-
return {
|
|
641
|
-
type: "mrkdwn",
|
|
642
|
-
text: truncateSlackText(text, SLACK_PROGRESS_FIELD_MAX)
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
587
|
function resolveMaxLineChars(value, fallback) {
|
|
646
588
|
return value && value > 0 ? Math.floor(value) : fallback;
|
|
647
589
|
}
|
|
@@ -660,141 +602,58 @@ function compactTitle(value) {
|
|
|
660
602
|
function compactChunkText(value) {
|
|
661
603
|
return truncateSlackText(value.replace(/\s+/g, " ").trim(), SLACK_PROGRESS_CHUNK_TEXT_MAX);
|
|
662
604
|
}
|
|
663
|
-
function lineDetailParts(line) {
|
|
664
|
-
return [line.detail, line.status && line.status !== "completed" && !line.detail?.includes(line.status) ? line.status : void 0].map((part) => part?.trim()).filter((part) => Boolean(part));
|
|
665
|
-
}
|
|
666
|
-
function legacyLineTitle(line) {
|
|
667
|
-
return `${line.icon ?? "•"} *${escapeSlackMrkdwn(line.label)}*`;
|
|
668
|
-
}
|
|
669
605
|
function isAuthoredProgressLine(line) {
|
|
670
606
|
return line.id === "reasoning" || line.id?.startsWith("commentary:") === true;
|
|
671
607
|
}
|
|
672
|
-
function
|
|
673
|
-
const
|
|
674
|
-
if (
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
function lineTaskTitle(line) {
|
|
679
|
-
const label = (line.kind === "command-output" ? line.toolName : void 0) || line.label.replace(/\s+/g, " ").trim() || line.toolName || line.kind || "Update";
|
|
680
|
-
const fallback = line.text.replace(/\s+/g, " ").trim();
|
|
681
|
-
if (fallback && fallback !== label) return compactTitle(lineDetailParts(line).length > 0 || line.status ? label : fallback);
|
|
682
|
-
return compactTitle(label);
|
|
683
|
-
}
|
|
684
|
-
function lineTaskDetails(line, maxLineChars) {
|
|
685
|
-
const detail = line.detail?.replace(SLACK_PROGRESS_LINE_DELTA_RE, "").replace(/\s+·\s*$/u, "").trim();
|
|
686
|
-
return detail && detail !== line.status?.trim() ? compactDetail(detail, maxLineChars) : void 0;
|
|
687
|
-
}
|
|
688
|
-
function lineTaskOutput(line) {
|
|
689
|
-
const match = line.detail ? SLACK_PROGRESS_LINE_DELTA_RE.exec(line.detail) : null;
|
|
690
|
-
if (match) return `+${match[1]} −${match[2]}`;
|
|
691
|
-
const status = line.status?.replace(/\s+/g, " ").trim();
|
|
692
|
-
return status && lineTaskStatus(line) === "error" ? status : void 0;
|
|
693
|
-
}
|
|
694
|
-
function lineTaskStatus(line) {
|
|
695
|
-
const normalized = line.status?.replace(/\s+/g, " ").trim().toLowerCase();
|
|
696
|
-
if (!normalized) return "in_progress";
|
|
697
|
-
if (normalized === "complete" || normalized === "completed" || normalized === "done" || normalized === "ok" || normalized === "success" || normalized === "succeeded" || normalized === "successful" || normalized === "exit 0") return "complete";
|
|
698
|
-
if (normalized === "error" || normalized === "failed" || normalized === "failure" || normalized.startsWith("exit ")) return normalized === "exit 0" ? "complete" : "error";
|
|
699
|
-
return "in_progress";
|
|
700
|
-
}
|
|
701
|
-
function slugTaskIdPart(value) {
|
|
702
|
-
return value?.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "task";
|
|
703
|
-
}
|
|
704
|
-
function stableTaskIdPart(value, slugValue = value) {
|
|
705
|
-
const suffix = createHash("sha256").update(value).digest("hex").slice(0, 8);
|
|
706
|
-
return `${slugTaskIdPart(slugValue).slice(0, 48)}_${suffix}`;
|
|
707
|
-
}
|
|
708
|
-
function resolveLineTaskIdentity(line) {
|
|
709
|
-
if (line.id?.trim()) return {
|
|
710
|
-
id: stableTaskIdPart(line.id),
|
|
711
|
-
contentDerived: false
|
|
608
|
+
function resolveProgressAttention(lines) {
|
|
609
|
+
const approval = lines.findLast((line) => line.kind === "approval" && line.status === "requested");
|
|
610
|
+
if (approval) return {
|
|
611
|
+
id: "openclaw_attention",
|
|
612
|
+
title: compactTitle(`Approval required: ${approval.detail || approval.label}`),
|
|
613
|
+
status: "pending"
|
|
712
614
|
};
|
|
615
|
+
const failure = lines.findLast((line) => {
|
|
616
|
+
const status = line.status?.trim().toLowerCase();
|
|
617
|
+
return status === "error" || status === "failed" || status === "failure" || status?.startsWith("exit ") && status !== "exit 0";
|
|
618
|
+
});
|
|
619
|
+
if (!failure) return;
|
|
713
620
|
return {
|
|
714
|
-
id:
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
].join("
|
|
720
|
-
|
|
621
|
+
id: "openclaw_attention",
|
|
622
|
+
title: compactTitle([...new Set([
|
|
623
|
+
failure.label,
|
|
624
|
+
failure.detail,
|
|
625
|
+
failure.status
|
|
626
|
+
].filter(Boolean))].join(" — ")),
|
|
627
|
+
status: "error"
|
|
721
628
|
};
|
|
722
629
|
}
|
|
723
|
-
function
|
|
724
|
-
|
|
630
|
+
function buildSlackProgressStreamChunks(params) {
|
|
631
|
+
const title = compactChunkText(params.title?.trim() || params.label?.trim() || "Working");
|
|
632
|
+
if (!params.title && !params.label && !params.lines.length && !params.plan?.length && !params.sessionUrl) return;
|
|
633
|
+
const tasks = params.plan?.length ? params.plan.slice(-50).map((entry, index) => ({
|
|
725
634
|
id: `plan_step_${index + 1}`,
|
|
726
635
|
title: compactTitle(entry.step),
|
|
727
636
|
status: entry.status === "completed" ? "complete" : entry.status
|
|
728
|
-
}))
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}
|
|
741
|
-
const details = lineTaskDetails(line, maxLineChars);
|
|
742
|
-
const output = lineTaskOutput(line);
|
|
743
|
-
const task = {
|
|
744
|
-
id,
|
|
745
|
-
title: lineTaskTitle(line),
|
|
746
|
-
status: lineTaskStatus(line)
|
|
747
|
-
};
|
|
748
|
-
if (details) task.details = details;
|
|
749
|
-
if (output) task.output = output;
|
|
750
|
-
return task;
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
function resolvePlanTitle(params) {
|
|
754
|
-
return compactChunkText(params.title?.trim() || params.label?.trim() || (params.tasks.at(-1)?.details ? `${params.tasks.at(-1)?.title} — ${params.tasks.at(-1)?.details}` : params.tasks.at(-1)?.title) || SLACK_PROGRESS_PLAN_FALLBACK_TITLE);
|
|
755
|
-
}
|
|
756
|
-
function buildSlackProgressStreamChunks(params) {
|
|
757
|
-
const tasks = buildPlanTasks({
|
|
758
|
-
lines: params.lines,
|
|
759
|
-
plan: params.plan,
|
|
760
|
-
maxLineChars: params.maxLineChars
|
|
761
|
-
});
|
|
762
|
-
if (tasks.length === 0) {
|
|
763
|
-
const title = params.title?.trim() || params.label?.trim();
|
|
764
|
-
if (!title) return;
|
|
765
|
-
if (!params.sessionUrl && !params.diffStat) return [{
|
|
766
|
-
type: "plan_update",
|
|
767
|
-
title: compactChunkText(title)
|
|
768
|
-
}];
|
|
769
|
-
return [{
|
|
770
|
-
type: "plan_update",
|
|
771
|
-
title: compactChunkText(title)
|
|
772
|
-
}, {
|
|
773
|
-
type: "task_update",
|
|
774
|
-
id: "openclaw_summary",
|
|
775
|
-
title: "Completed",
|
|
776
|
-
status: "complete",
|
|
777
|
-
...formatTaskDiffOutput(params.diffStat) ? { output: formatTaskDiffOutput(params.diffStat) } : {},
|
|
778
|
-
...params.sessionUrl ? { sources: buildSessionSources(params.sessionUrl) } : {}
|
|
779
|
-
}];
|
|
780
|
-
}
|
|
781
|
-
const title = resolvePlanTitle({
|
|
782
|
-
label: params.label,
|
|
783
|
-
title: params.title,
|
|
784
|
-
tasks
|
|
785
|
-
});
|
|
637
|
+
})) : [{
|
|
638
|
+
id: "openclaw_summary",
|
|
639
|
+
title: compactTitle(title),
|
|
640
|
+
status: "in_progress"
|
|
641
|
+
}];
|
|
642
|
+
let attention = resolveProgressAttention(params.lines);
|
|
643
|
+
if (params.finalInProgressStatus === "error" && !tasks.some((task) => task.status === "in_progress")) attention = {
|
|
644
|
+
id: "openclaw_attention",
|
|
645
|
+
title: attention?.status === "error" ? attention.title : "Failed",
|
|
646
|
+
status: "error"
|
|
647
|
+
};
|
|
648
|
+
if (attention && !(params.finalInProgressStatus && attention.status === "pending")) tasks.push(attention);
|
|
786
649
|
const finalTaskIndex = tasks.length - 1;
|
|
787
|
-
const diffOutput = formatTaskDiffOutput(params.diffStat);
|
|
788
650
|
const taskChunks = tasks.map((task, index) => {
|
|
789
651
|
const chunk = {
|
|
790
652
|
type: "task_update",
|
|
791
653
|
id: task.id,
|
|
792
654
|
title: task.title,
|
|
793
|
-
status: task.status === "in_progress" ? params.finalInProgressStatus ??
|
|
655
|
+
status: task.status === "in_progress" ? params.finalInProgressStatus ?? task.status : task.status
|
|
794
656
|
};
|
|
795
|
-
if (task.details) chunk.details = task.details;
|
|
796
|
-
if (task.output) chunk.output = task.output;
|
|
797
|
-
if (index === finalTaskIndex && diffOutput) chunk.output = [task.output, diffOutput].filter(Boolean).join(" · ");
|
|
798
657
|
if (index === finalTaskIndex && params.sessionUrl) chunk.sources = buildSessionSources(params.sessionUrl);
|
|
799
658
|
return chunk;
|
|
800
659
|
});
|
|
@@ -803,113 +662,50 @@ function buildSlackProgressStreamChunks(params) {
|
|
|
803
662
|
title
|
|
804
663
|
}, ...taskChunks];
|
|
805
664
|
}
|
|
806
|
-
function formatDiffStat(diffStat) {
|
|
807
|
-
if (!diffStat || diffStat.files === 0 && diffStat.added === 0 && diffStat.removed === 0) return;
|
|
808
|
-
return [
|
|
809
|
-
`📝 ${diffStat.files} files`,
|
|
810
|
-
...diffStat.added > 0 ? [`+${diffStat.added}`] : [],
|
|
811
|
-
...diffStat.removed > 0 ? [`−${diffStat.removed}`] : []
|
|
812
|
-
].join(" ");
|
|
813
|
-
}
|
|
814
|
-
function formatTaskDiffOutput(diffStat) {
|
|
815
|
-
return diffStat && (diffStat.added > 0 || diffStat.removed > 0) ? `+${diffStat.added} −${diffStat.removed}` : void 0;
|
|
816
|
-
}
|
|
817
|
-
function buildActivityText(lines, maxLineChars) {
|
|
818
|
-
const rendered = [];
|
|
819
|
-
let length = 0;
|
|
820
|
-
for (const line of lines.slice(-50).toReversed()) {
|
|
821
|
-
const row = `${legacyLineTitle(line)} — ${legacyLineDetail(line, maxLineChars)}`;
|
|
822
|
-
const nextLength = length + row.length + (rendered.length > 0 ? 1 : 0);
|
|
823
|
-
if (nextLength > SLACK_PROGRESS_FIELD_MAX) break;
|
|
824
|
-
rendered.push(row);
|
|
825
|
-
length = nextLength;
|
|
826
|
-
}
|
|
827
|
-
return rendered.toReversed().join("\n");
|
|
828
|
-
}
|
|
829
665
|
function buildSlackProgressCardBlocks(params) {
|
|
830
666
|
const maxLineChars = resolveMaxLineChars(params.maxLineChars, DEFAULT_SLACK_PROGRESS_DETAIL_MAX_CHARS);
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const narration = params.narration?.replace(/\s+/g, " ").trim();
|
|
836
|
-
const activityText = buildActivityText(params.lines, maxLineChars);
|
|
837
|
-
const diffStat = formatDiffStat(params.diffStat);
|
|
838
|
-
const workingFooter = [
|
|
839
|
-
...params.toolCalls && params.toolCalls > 0 ? [`🛠️ ${params.toolCalls} tools`] : [],
|
|
840
|
-
...diffStat ? [diffStat] : [],
|
|
841
|
-
...params.elapsedSeconds && params.elapsedSeconds > 0 ? [`⏱ ${params.elapsedSeconds}s`] : []
|
|
842
|
-
].join(" · ");
|
|
843
|
-
const footer = params.state === "working" ? workingFooter : diffStat;
|
|
844
|
-
return [
|
|
845
|
-
{
|
|
846
|
-
type: "section",
|
|
847
|
-
text: field(`${params.state === "working" ? "🔄" : params.state === "success" ? "✅" : "❌"} *${escapeSlackMrkdwn(params.title.trim() || "Working")}*`)
|
|
848
|
-
},
|
|
849
|
-
...narration ? [{
|
|
850
|
-
type: "section",
|
|
851
|
-
text: field(`_${escapeSlackMrkdwn(narration)}_`)
|
|
852
|
-
}] : [],
|
|
853
|
-
...planLines.length > 0 ? [{
|
|
854
|
-
type: "section",
|
|
855
|
-
text: field(planLines.map((line) => escapeSlackMrkdwn(line)).join("\n"))
|
|
856
|
-
}] : [],
|
|
857
|
-
...activityText ? [{
|
|
858
|
-
type: "section",
|
|
859
|
-
text: field(activityText)
|
|
860
|
-
}] : [],
|
|
861
|
-
...footer ? [{
|
|
862
|
-
type: "context",
|
|
863
|
-
elements: [field(footer)]
|
|
864
|
-
}] : [],
|
|
865
|
-
...params.state !== "working" && params.sessionUrl ? [{
|
|
866
|
-
type: "actions",
|
|
867
|
-
elements: [{
|
|
868
|
-
type: "button",
|
|
869
|
-
action_id: SLACK_SESSION_LINK_ACTION_ID,
|
|
870
|
-
text: {
|
|
871
|
-
type: "plain_text",
|
|
872
|
-
text: "Open in OpenClaw"
|
|
873
|
-
},
|
|
874
|
-
url: params.sessionUrl
|
|
875
|
-
}]
|
|
876
|
-
}] : []
|
|
877
|
-
].slice(0, 50);
|
|
878
|
-
}
|
|
879
|
-
const EMPTY_SLACK_NATIVE_STREAM_SNAPSHOT = { tasks: /* @__PURE__ */ new Map() };
|
|
880
|
-
const SLACK_TASK_FIELD_SEPARATOR = " · ";
|
|
881
|
-
function resolveTaskFieldDelta(previous, incoming) {
|
|
882
|
-
if (!incoming) return {
|
|
883
|
-
field: previous,
|
|
884
|
-
delta: void 0
|
|
885
|
-
};
|
|
886
|
-
if (previous?.rendered.includes(incoming)) return {
|
|
887
|
-
field: {
|
|
888
|
-
rendered: previous.rendered,
|
|
889
|
-
source: incoming
|
|
890
|
-
},
|
|
891
|
-
delta: void 0
|
|
667
|
+
const statusLabels = {
|
|
668
|
+
completed: "Completed",
|
|
669
|
+
in_progress: "In progress",
|
|
670
|
+
pending: "Pending"
|
|
892
671
|
};
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
672
|
+
const planLines = (params.plan ?? []).slice(-50).map((entry) => `${statusLabels[entry.status]}: ${compactDetail(entry.step, maxLineChars)}`);
|
|
673
|
+
const narration = params.narration?.replace(/\s+/g, " ").trim();
|
|
674
|
+
const authoredText = params.lines.filter(isAuthoredProgressLine).map((line) => line.text.trim()).filter((text, index, values) => text && text !== narration && values.indexOf(text) === index).map((text) => normalizeSlackOutboundText(compactDetail(text, maxLineChars))).join("\n");
|
|
675
|
+
const attention = resolveProgressAttention(params.lines);
|
|
676
|
+
const blocks = [
|
|
677
|
+
`${params.state === "success" ? "Completed: " : params.state === "error" ? "Failed: " : ""}*${escapeSlackMrkdwn(params.title.trim() || "Working")}*`,
|
|
678
|
+
narration ? `_${escapeSlackMrkdwn(narration)}_` : "",
|
|
679
|
+
planLines.map((line) => escapeSlackMrkdwn(line)).join("\n"),
|
|
680
|
+
authoredText,
|
|
681
|
+
attention && !(params.state !== "working" && attention.status === "pending") ? escapeSlackMrkdwn(attention.title) : ""
|
|
682
|
+
].filter(Boolean).map((text) => ({
|
|
683
|
+
type: "section",
|
|
684
|
+
text: {
|
|
685
|
+
type: "mrkdwn",
|
|
686
|
+
text: truncateSlackText(text, SLACK_PROGRESS_FIELD_MAX)
|
|
687
|
+
}
|
|
688
|
+
}));
|
|
689
|
+
if (params.state !== "working" && params.sessionUrl) blocks.push({
|
|
690
|
+
type: "actions",
|
|
691
|
+
elements: [{
|
|
692
|
+
type: "button",
|
|
693
|
+
action_id: SLACK_SESSION_LINK_ACTION_ID,
|
|
694
|
+
text: {
|
|
695
|
+
type: "plain_text",
|
|
696
|
+
text: "Open in OpenClaw"
|
|
697
|
+
},
|
|
698
|
+
url: params.sessionUrl
|
|
699
|
+
}]
|
|
898
700
|
});
|
|
899
|
-
|
|
900
|
-
return {
|
|
901
|
-
field: {
|
|
902
|
-
rendered: next.rendered,
|
|
903
|
-
source: next.source
|
|
904
|
-
},
|
|
905
|
-
delta
|
|
906
|
-
};
|
|
701
|
+
return blocks.slice(0, 50);
|
|
907
702
|
}
|
|
703
|
+
const EMPTY_SLACK_NATIVE_STREAM_SNAPSHOT = { tasks: /* @__PURE__ */ new Map() };
|
|
908
704
|
/**
|
|
909
705
|
* Turns a full task snapshot into the delta Slack must receive. Native streams
|
|
910
706
|
* key rows by persistent id with no removal chunk: unchanged rows are omitted,
|
|
911
|
-
* changed
|
|
912
|
-
* (plan shrinks,
|
|
707
|
+
* changed titles/statuses replace in place, and rows that dropped out
|
|
708
|
+
* (plan shrinks, summary <-> plan source switches) get a final complete
|
|
913
709
|
* update or they linger in_progress forever.
|
|
914
710
|
*/
|
|
915
711
|
function reconcileSlackNativeTaskChunks(params) {
|
|
@@ -930,26 +726,20 @@ function reconcileSlackNativeTaskChunks(params) {
|
|
|
930
726
|
}
|
|
931
727
|
const previousRow = params.previous.tasks.get(chunk.id);
|
|
932
728
|
const status = chunk.status;
|
|
933
|
-
const details = resolveTaskFieldDelta(previousRow?.details, chunk.details);
|
|
934
|
-
const output = resolveTaskFieldDelta(previousRow?.output, chunk.output);
|
|
935
729
|
const sourcesChanged = Boolean(chunk.sources) && !previousRow?.sourcesSent;
|
|
936
730
|
const row = {
|
|
937
731
|
title: chunk.title,
|
|
938
732
|
status
|
|
939
733
|
};
|
|
940
|
-
if (details.field) row.details = details.field;
|
|
941
|
-
if (output.field) row.output = output.field;
|
|
942
734
|
if (sourcesChanged || previousRow?.sourcesSent) row.sourcesSent = true;
|
|
943
735
|
nextTasks.set(chunk.id, row);
|
|
944
|
-
if (!(!previousRow || previousRow.title !== chunk.title || previousRow.status !== status ||
|
|
736
|
+
if (!(!previousRow || previousRow.title !== chunk.title || previousRow.status !== status || sourcesChanged)) continue;
|
|
945
737
|
const update = {
|
|
946
738
|
type: "task_update",
|
|
947
739
|
id: chunk.id,
|
|
948
740
|
title: chunk.title,
|
|
949
741
|
status
|
|
950
742
|
};
|
|
951
|
-
if (details.delta) update.details = details.delta;
|
|
952
|
-
if (output.delta) update.output = output.delta;
|
|
953
743
|
if (sourcesChanged) update.sources = chunk.sources;
|
|
954
744
|
emitted.push(update);
|
|
955
745
|
}
|
|
@@ -978,40 +768,63 @@ function reconcileSlackNativeTaskChunks(params) {
|
|
|
978
768
|
}
|
|
979
769
|
};
|
|
980
770
|
}
|
|
981
|
-
function buildSlackProgressStreamCompletionChunks(params) {
|
|
982
|
-
return buildSlackProgressStreamChunks({
|
|
983
|
-
...params,
|
|
984
|
-
completeInProgress: true
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
771
|
//#endregion
|
|
988
|
-
//#region extensions/slack/src/
|
|
989
|
-
function
|
|
990
|
-
return
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
772
|
+
//#region extensions/slack/src/stream-mode.ts
|
|
773
|
+
function resolveSlackStreamingConfig(params) {
|
|
774
|
+
return {
|
|
775
|
+
mode: resolveSlackStreamingMode(params),
|
|
776
|
+
nativeStreaming: resolveSlackNativeStreaming(params)
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
function applyAppendOnlyStreamUpdate(params) {
|
|
780
|
+
const incoming = params.incoming.trimEnd();
|
|
781
|
+
if (!incoming) return {
|
|
782
|
+
rendered: params.rendered,
|
|
783
|
+
source: params.source,
|
|
784
|
+
changed: false
|
|
785
|
+
};
|
|
786
|
+
if (!params.rendered) return {
|
|
787
|
+
rendered: incoming,
|
|
788
|
+
source: incoming,
|
|
789
|
+
changed: true
|
|
790
|
+
};
|
|
791
|
+
if (incoming === params.source) return {
|
|
792
|
+
rendered: params.rendered,
|
|
793
|
+
source: params.source,
|
|
794
|
+
changed: false
|
|
795
|
+
};
|
|
796
|
+
if (incoming.startsWith(params.rendered)) return {
|
|
797
|
+
rendered: incoming,
|
|
798
|
+
source: incoming,
|
|
799
|
+
changed: incoming !== params.rendered
|
|
800
|
+
};
|
|
801
|
+
if (incoming.startsWith(params.source)) {
|
|
802
|
+
const delta = incoming.slice(params.source.length);
|
|
994
803
|
return {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
label: reasoning ? "Reasoning" : "Update",
|
|
999
|
-
prefix: false
|
|
804
|
+
rendered: `${params.rendered}${delta}`,
|
|
805
|
+
source: incoming,
|
|
806
|
+
changed: delta.length > 0
|
|
1000
807
|
};
|
|
1001
|
-
}
|
|
808
|
+
}
|
|
809
|
+
if (params.source.startsWith(incoming)) return {
|
|
810
|
+
rendered: params.rendered,
|
|
811
|
+
source: params.source,
|
|
812
|
+
changed: false
|
|
813
|
+
};
|
|
814
|
+
const separator = params.separator ?? (params.rendered.endsWith("\n") ? "" : "\n");
|
|
815
|
+
return {
|
|
816
|
+
rendered: `${params.rendered}${separator}${incoming}`,
|
|
817
|
+
source: incoming,
|
|
818
|
+
changed: true
|
|
819
|
+
};
|
|
1002
820
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
821
|
+
//#endregion
|
|
822
|
+
//#region extensions/slack/src/monitor/message-handler/dispatch-progress-render.ts
|
|
823
|
+
function resolveStructuredProgressLines(lines) {
|
|
824
|
+
return lines.filter((line) => typeof line !== "string");
|
|
1005
825
|
}
|
|
1006
826
|
function resolveNativeProgressLines(snapshot) {
|
|
1007
|
-
|
|
1008
|
-
if (snapshot.plan?.length || !snapshot.planExplanation) return lines;
|
|
1009
|
-
const explanationLine = buildChannelProgressDraftLine({
|
|
1010
|
-
event: "plan",
|
|
1011
|
-
phase: "update",
|
|
1012
|
-
explanation: snapshot.planExplanation
|
|
1013
|
-
});
|
|
1014
|
-
return explanationLine ? [...lines, explanationLine] : lines;
|
|
827
|
+
return resolveStructuredProgressLines(snapshot.lines).filter((line) => line.id !== "reasoning" && line.id?.startsWith("commentary:") !== true);
|
|
1015
828
|
}
|
|
1016
829
|
function resolveNativeProgressNarration(snapshot) {
|
|
1017
830
|
const paragraphs = resolveStructuredProgressLines(snapshot.lines).filter((line) => line.id === "reasoning" || line.id?.startsWith("commentary:") === true).map((line) => line.text.trim()).filter((text, index, values) => Boolean(text) && values.indexOf(text) === index);
|
|
@@ -1020,14 +833,6 @@ function resolveNativeProgressNarration(snapshot) {
|
|
|
1020
833
|
function combineProgressHeadlineAndExplanation(headline, explanation) {
|
|
1021
834
|
return headline && explanation && headline !== explanation ? `${headline} — ${explanation}` : headline ?? explanation;
|
|
1022
835
|
}
|
|
1023
|
-
function buildNativeProgressChunks(params) {
|
|
1024
|
-
return buildSlackProgressStreamChunks({
|
|
1025
|
-
title: params.title,
|
|
1026
|
-
lines: resolveNativeProgressLines(params.snapshot),
|
|
1027
|
-
plan: resolveNativeProgressPlan(params.snapshot),
|
|
1028
|
-
maxLineChars: params.maxLineChars
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
836
|
//#endregion
|
|
1032
837
|
//#region extensions/slack/src/monitor/message-handler/preview-finalize.ts
|
|
1033
838
|
function buildExpectedSlackEditText(params) {
|
|
@@ -1065,7 +870,8 @@ function blocksMatch(expected, actual) {
|
|
|
1065
870
|
const fallbackBlocks = fallbackPlan.fallbackMessages.flatMap((message) => message.blocks ?? []);
|
|
1066
871
|
if (JSON.stringify(fallbackBlocks) === JSON.stringify(actual)) return true;
|
|
1067
872
|
const fallbackText = fallbackPlan.fallbackMessages.map((message) => message.text).filter(Boolean).join("\n\n");
|
|
1068
|
-
|
|
873
|
+
const actualText = buildSlackBlocksFallbackText(actual);
|
|
874
|
+
return normalizeSlackOutboundText(actualText) === normalizeSlackOutboundText(fallbackText);
|
|
1069
875
|
} catch {
|
|
1070
876
|
return false;
|
|
1071
877
|
}
|
|
@@ -1156,6 +962,7 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1156
962
|
return url.toString();
|
|
1157
963
|
};
|
|
1158
964
|
const resolveText = (snapshot) => latestFallbackText || formatChannelProgressDraftText({
|
|
965
|
+
presentation: "summary",
|
|
1159
966
|
entry: account.config,
|
|
1160
967
|
lines: [...snapshot.lines],
|
|
1161
968
|
seed: params.progressSeed,
|
|
@@ -1172,11 +979,7 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1172
979
|
plan: snapshot.plan,
|
|
1173
980
|
lines: resolveStructuredProgressLines(snapshot.lines),
|
|
1174
981
|
maxLineChars: params.maxLineChars,
|
|
1175
|
-
|
|
1176
|
-
...state === "working" ? {
|
|
1177
|
-
toolCalls: params.progressWorkCounter.toolCalls,
|
|
1178
|
-
elapsedSeconds: params.progressWorkCounter.elapsedSeconds
|
|
1179
|
-
} : { sessionUrl: resolveSessionUrl() }
|
|
982
|
+
...state !== "working" ? { sessionUrl: resolveSessionUrl() } : {}
|
|
1180
983
|
});
|
|
1181
984
|
};
|
|
1182
985
|
const finalize = async (status, snapshot = params.getSnapshot(), fallbackText = resolveText(snapshot)) => {
|
|
@@ -1336,7 +1139,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1336
1139
|
log: logVerbose,
|
|
1337
1140
|
warn: logVerbose
|
|
1338
1141
|
}) : void 0;
|
|
1339
|
-
let
|
|
1142
|
+
let hasStreamedAnswer = false;
|
|
1340
1143
|
const isProgressMode = slackStreaming.mode === "progress";
|
|
1341
1144
|
const useNativeProgressStreaming = useStreaming && slackStreaming.mode === "progress";
|
|
1342
1145
|
const progressDraftActive = Boolean(draftStream) || useNativeProgressStreaming;
|
|
@@ -1362,7 +1165,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1362
1165
|
nativeStreamOrder = run.catch(() => void 0);
|
|
1363
1166
|
return run;
|
|
1364
1167
|
};
|
|
1365
|
-
const progressWorkCounter = createChannelProgressWorkCounter();
|
|
1366
1168
|
const progressSeed = `${account.accountId}:${message.channel}`;
|
|
1367
1169
|
const slackProgressStyle = resolveSlackProgressStyle(account.config);
|
|
1368
1170
|
const useDraftProgressCard = Boolean(draftStream) && isProgressMode && slackProgressStyle === "card";
|
|
@@ -1378,7 +1180,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1378
1180
|
},
|
|
1379
1181
|
draftStream,
|
|
1380
1182
|
enabled: useDraftProgressCard,
|
|
1381
|
-
progressWorkCounter,
|
|
1382
1183
|
progressSeed,
|
|
1383
1184
|
explicitTitle: explicitProgressTitle,
|
|
1384
1185
|
maxLineChars: progressDraftMaxLineChars,
|
|
@@ -1398,12 +1199,17 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1398
1199
|
if (isError) nativeProgressTerminalStatus = "error";
|
|
1399
1200
|
if (!session || nativeProgressCompletionSent) return;
|
|
1400
1201
|
const chunks = buildNativeProgressCompletionChunks(isError ? "error" : "complete");
|
|
1401
|
-
|
|
1202
|
+
const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(progressDraft.getSnapshot()));
|
|
1203
|
+
if (!chunks?.length && !narrationUpdate.delta) return;
|
|
1402
1204
|
try {
|
|
1403
1205
|
await appendSlackStream({
|
|
1404
1206
|
session,
|
|
1405
1207
|
chunks
|
|
1406
1208
|
});
|
|
1209
|
+
if (narrationUpdate.next.changed) {
|
|
1210
|
+
nativeNarrationRenderedText = narrationUpdate.next.rendered;
|
|
1211
|
+
nativeNarrationSourceText = narrationUpdate.next.source;
|
|
1212
|
+
}
|
|
1407
1213
|
nativeProgressCompletionSent = true;
|
|
1408
1214
|
delivery.observedReplyDelivery ||= session.delivered;
|
|
1409
1215
|
} catch (err) {
|
|
@@ -1412,11 +1218,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1412
1218
|
}
|
|
1413
1219
|
};
|
|
1414
1220
|
const resolveNativeProgressTitle = (snapshot) => combineProgressHeadlineAndExplanation(explicitProgressTitle ?? snapshot.statusHeadline, snapshot.planExplanation);
|
|
1415
|
-
const buildNativeProgressChunks$1 = (snapshot) => buildNativeProgressChunks({
|
|
1416
|
-
snapshot,
|
|
1417
|
-
title: resolveNativeProgressTitle(snapshot),
|
|
1418
|
-
maxLineChars: progressDraftMaxLineChars
|
|
1419
|
-
});
|
|
1420
1221
|
const normalizeProgressText = (text) => text?.replace(/\s+/gu, " ").trim() ?? "";
|
|
1421
1222
|
const isRenderedAsProgressTitle = (text) => {
|
|
1422
1223
|
const candidate = normalizeProgressText(text);
|
|
@@ -1435,17 +1236,18 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1435
1236
|
delta: next.changed ? next.rendered.slice(nativeNarrationRenderedText.length) : ""
|
|
1436
1237
|
};
|
|
1437
1238
|
};
|
|
1438
|
-
const updateNativeProgressStream = () => withNativeStreamOrder(updateNativeProgressStreamNow);
|
|
1439
1239
|
const updateNativeProgressStreamNow = async () => {
|
|
1440
1240
|
const snapshot = progressDraft.getSnapshot();
|
|
1441
|
-
const progressLines = resolveNativeProgressLines(snapshot);
|
|
1442
1241
|
const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(snapshot));
|
|
1443
|
-
|
|
1444
|
-
if (!useNativeProgressStreaming || delivery.streamFailed || progressLines.length === 0 && !snapshot.plan?.length && !snapshot.statusHeadline && !explicitProgressTitle && !hasRetirableNativeTasks && !narrationUpdate.delta) return false;
|
|
1242
|
+
if (!useNativeProgressStreaming || delivery.streamFailed || nativeUpdatesStopped) return false;
|
|
1445
1243
|
if (!await nativeTransport.waitForStart()) return false;
|
|
1446
1244
|
const reconciled = reconcileSlackNativeTaskChunks({
|
|
1447
1245
|
previous: nativeStreamSnapshot,
|
|
1448
|
-
chunks:
|
|
1246
|
+
chunks: buildSlackProgressStreamChunks({
|
|
1247
|
+
title: resolveNativeProgressTitle(snapshot) ?? "Working",
|
|
1248
|
+
lines: resolveNativeProgressLines(snapshot),
|
|
1249
|
+
plan: snapshot.plan
|
|
1250
|
+
})
|
|
1449
1251
|
});
|
|
1450
1252
|
const chunks = reconciled.chunks;
|
|
1451
1253
|
if (!chunks?.length && !narrationUpdate.delta) return false;
|
|
@@ -1469,6 +1271,21 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1469
1271
|
return false;
|
|
1470
1272
|
}
|
|
1471
1273
|
};
|
|
1274
|
+
let nativeUpdatesStopped = false;
|
|
1275
|
+
const nativeUpdates = createDraftStreamLoop({
|
|
1276
|
+
throttleMs: 1e3,
|
|
1277
|
+
coalesceInFlight: true,
|
|
1278
|
+
emptyValue: false,
|
|
1279
|
+
isEmpty: (pending) => !pending,
|
|
1280
|
+
isStopped: () => nativeUpdatesStopped,
|
|
1281
|
+
sendOrEditStreamMessage: () => withNativeStreamOrder(updateNativeProgressStreamNow),
|
|
1282
|
+
onBackgroundFlushError: (err) => runtime.error?.(danger(`slack-stream: progress update failed: ${formatSlackError(err)}`))
|
|
1283
|
+
});
|
|
1284
|
+
const cancelNativeUpdates = async () => {
|
|
1285
|
+
nativeUpdatesStopped = true;
|
|
1286
|
+
nativeUpdates.stop();
|
|
1287
|
+
await nativeUpdates.waitForInFlight();
|
|
1288
|
+
};
|
|
1472
1289
|
const appendNativeNarration = (payload, kind) => withNativeStreamOrder(() => appendNativeNarrationNow(payload, kind));
|
|
1473
1290
|
const appendNativeNarrationNow = async (payload, kind) => {
|
|
1474
1291
|
if (isRenderedAsProgressTitle(payload.text)) return false;
|
|
@@ -1488,24 +1305,28 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1488
1305
|
return true;
|
|
1489
1306
|
};
|
|
1490
1307
|
const resetProgressTurnState = () => {
|
|
1491
|
-
progressWorkCounter.reset();
|
|
1492
1308
|
nativeNarrationRenderedText = "";
|
|
1493
1309
|
nativeNarrationSourceText = "";
|
|
1494
1310
|
};
|
|
1495
1311
|
const progressDraft = createChannelProgressDraftCompositor({
|
|
1312
|
+
presentation: isProgressMode ? "summary" : void 0,
|
|
1496
1313
|
entry: account.config,
|
|
1497
1314
|
mode: slackStreaming.mode,
|
|
1498
1315
|
active: progressDraftActive,
|
|
1499
1316
|
seed: progressSeed,
|
|
1500
1317
|
formatLine: formatSlackProgressDraftLine,
|
|
1501
1318
|
reasoningLinePrefix: "🧠 ",
|
|
1502
|
-
commentaryLinePrefix: "",
|
|
1503
1319
|
reasoningGate: previewToolProgressEnabled,
|
|
1504
|
-
commentaryItalics: true,
|
|
1505
|
-
buildProgressEventLine: (input, options) => input.event === "tool" || input.event === "item" || input.event === "command-output" ? buildChannelProgressDraftLineForEntry(account.config, input, options) : buildChannelProgressDraftLine(input, options),
|
|
1506
1320
|
updateOnLineChange: useNativeProgressStreaming || useDraftProgressCard,
|
|
1507
1321
|
update: async (previewText, options) => {
|
|
1508
|
-
if (useNativeProgressStreaming)
|
|
1322
|
+
if (useNativeProgressStreaming) {
|
|
1323
|
+
const priorSnapshot = nativeStreamSnapshot;
|
|
1324
|
+
const priorNarration = nativeNarrationRenderedText;
|
|
1325
|
+
nativeUpdates.update(true);
|
|
1326
|
+
if (options?.flush) await nativeUpdates.flush();
|
|
1327
|
+
else await nativeUpdates.waitForInFlight();
|
|
1328
|
+
return priorSnapshot !== nativeStreamSnapshot || priorNarration !== nativeNarrationRenderedText;
|
|
1329
|
+
}
|
|
1509
1330
|
if (!draftStream) return false;
|
|
1510
1331
|
const snapshot = progressDraft.getSnapshot();
|
|
1511
1332
|
progressCard.setFallbackText(previewText);
|
|
@@ -1513,13 +1334,16 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1513
1334
|
text: previewText,
|
|
1514
1335
|
blocks: progressCard.resolvePresentation(snapshot, "working")
|
|
1515
1336
|
} : previewText);
|
|
1516
|
-
hasStreamedMessage = true;
|
|
1517
1337
|
if (options?.flush) await draftStream.flush();
|
|
1518
1338
|
return Boolean(draftStream.messageId() && draftStream.channelId());
|
|
1519
1339
|
}
|
|
1520
1340
|
});
|
|
1521
1341
|
const commentaryProgressEnabled = progressDraft.commentaryProgressEnabled;
|
|
1522
|
-
const deliverNativeFinal = (payload, kind) =>
|
|
1342
|
+
const deliverNativeFinal = async (payload, kind) => {
|
|
1343
|
+
progressDraft.markFinalReplyStarted();
|
|
1344
|
+
await cancelNativeUpdates();
|
|
1345
|
+
await withNativeStreamOrder(() => deliverNativeFinalNow(payload, kind));
|
|
1346
|
+
};
|
|
1523
1347
|
const deliverNativeFinalNow = async (payload, kind) => {
|
|
1524
1348
|
progressDraft.markFinalReplyStarted();
|
|
1525
1349
|
const streamReady = await nativeTransport.waitForStart();
|
|
@@ -1544,20 +1368,23 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1544
1368
|
const snapshot = progressDraft.getSnapshot();
|
|
1545
1369
|
const lines = resolveNativeProgressLines(snapshot);
|
|
1546
1370
|
const sessionUrl = progressCard.resolveSessionUrl();
|
|
1371
|
+
const narrationUpdate = resolveNarrationUpdate(resolveNativeProgressNarration(snapshot));
|
|
1547
1372
|
const hasRetirableNativeTasks = [...nativeStreamSnapshot.tasks.values()].some((task) => task.status !== "complete" && task.status !== "error");
|
|
1548
|
-
if (lines.length === 0 && !snapshot.plan?.length && !hasRetirableNativeTasks && !
|
|
1549
|
-
|
|
1373
|
+
if (lines.length === 0 && !snapshot.plan?.length && !hasRetirableNativeTasks && !narrationUpdate.delta && !sessionUrl) return;
|
|
1374
|
+
const completion = reconcileSlackNativeTaskChunks({
|
|
1550
1375
|
previous: nativeStreamSnapshot,
|
|
1551
|
-
chunks:
|
|
1376
|
+
chunks: buildSlackProgressStreamChunks({
|
|
1552
1377
|
title: resolveNativeProgressTitle(snapshot) ?? (lines.length === 0 && !snapshot.plan?.length ? "Working" : void 0),
|
|
1553
1378
|
lines,
|
|
1554
|
-
plan:
|
|
1555
|
-
maxLineChars: progressDraftMaxLineChars,
|
|
1379
|
+
plan: snapshot.plan,
|
|
1556
1380
|
finalInProgressStatus,
|
|
1557
|
-
diffStat: snapshot.diffStat,
|
|
1558
1381
|
sessionUrl
|
|
1559
1382
|
})
|
|
1560
1383
|
}).chunks;
|
|
1384
|
+
return narrationUpdate.delta ? [{
|
|
1385
|
+
type: "markdown_text",
|
|
1386
|
+
text: narrationUpdate.delta
|
|
1387
|
+
}, ...completion ?? []] : completion;
|
|
1561
1388
|
};
|
|
1562
1389
|
const finishNativeProgressTurn = async (completionChunks) => {
|
|
1563
1390
|
if (delivery.nativeProgressStreamStartPromise) await delivery.nativeProgressStreamStartPromise.catch(() => null);
|
|
@@ -1595,10 +1422,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1595
1422
|
narration: explanation,
|
|
1596
1423
|
plan: steps
|
|
1597
1424
|
});
|
|
1598
|
-
if (text)
|
|
1599
|
-
draftStream.update(text);
|
|
1600
|
-
hasStreamedMessage = true;
|
|
1601
|
-
}
|
|
1425
|
+
if (text) draftStream.update(text);
|
|
1602
1426
|
return false;
|
|
1603
1427
|
};
|
|
1604
1428
|
const pushPreviewProgress = async (line, options) => {
|
|
@@ -1613,7 +1437,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1613
1437
|
return await progressDraft.pushToolProgress(line, options);
|
|
1614
1438
|
};
|
|
1615
1439
|
const updateDraftFromPartial = (text) => {
|
|
1616
|
-
const trimmed = text
|
|
1440
|
+
const trimmed = text && sanitizeAssistantVisibleText(text).trimEnd();
|
|
1617
1441
|
if (!trimmed) return false;
|
|
1618
1442
|
if (slackStreaming.mode === "block") {
|
|
1619
1443
|
previewToolProgressSuppressed = true;
|
|
@@ -1627,14 +1451,14 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1627
1451
|
appendSourceText = next.source;
|
|
1628
1452
|
if (!next.changed) return false;
|
|
1629
1453
|
draftStream?.update(next.rendered);
|
|
1630
|
-
|
|
1454
|
+
hasStreamedAnswer = true;
|
|
1631
1455
|
return false;
|
|
1632
1456
|
}
|
|
1633
1457
|
if (isProgressMode) return false;
|
|
1634
1458
|
previewToolProgressSuppressed = true;
|
|
1635
1459
|
progressDraft.suppress();
|
|
1636
1460
|
draftStream?.update(trimmed);
|
|
1637
|
-
|
|
1461
|
+
hasStreamedAnswer = true;
|
|
1638
1462
|
return false;
|
|
1639
1463
|
};
|
|
1640
1464
|
const pushReasoningProgress = async (payload) => {
|
|
@@ -1654,7 +1478,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1654
1478
|
return await progressDraft.pushReasoningProgress(payload.text, { snapshot: payload.isReasoningSnapshot === true });
|
|
1655
1479
|
};
|
|
1656
1480
|
const resetDraftDeliveryState = () => {
|
|
1657
|
-
|
|
1481
|
+
hasStreamedAnswer = false;
|
|
1658
1482
|
appendRenderedText = "";
|
|
1659
1483
|
appendSourceText = "";
|
|
1660
1484
|
};
|
|
@@ -1663,6 +1487,10 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1663
1487
|
progressDraft.reset();
|
|
1664
1488
|
};
|
|
1665
1489
|
const beginNewProgressTurn = async (options) => {
|
|
1490
|
+
if (useNativeProgressStreaming) {
|
|
1491
|
+
if (!nativeUpdatesStopped && options?.force !== true) return false;
|
|
1492
|
+
await cancelNativeUpdates();
|
|
1493
|
+
}
|
|
1666
1494
|
const priorSnapshot = progressDraft.getSnapshot();
|
|
1667
1495
|
const priorFallbackText = progressCard.resolveText(priorSnapshot);
|
|
1668
1496
|
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent ? buildNativeProgressCompletionChunks(nativeProgressTerminalStatus) : void 0;
|
|
@@ -1677,6 +1505,8 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1677
1505
|
nativeStreamSnapshot = EMPTY_SLACK_NATIVE_STREAM_SNAPSHOT;
|
|
1678
1506
|
nativeProgressCompletionSent = false;
|
|
1679
1507
|
nativeProgressTerminalStatus = "complete";
|
|
1508
|
+
nativeUpdatesStopped = false;
|
|
1509
|
+
nativeUpdates.resetThrottleWindow();
|
|
1680
1510
|
progressCard.reset();
|
|
1681
1511
|
resetPreviewDeliveryState();
|
|
1682
1512
|
delivery.resetDeliveryTracker();
|
|
@@ -1687,7 +1517,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1687
1517
|
await beginNewProgressTurn();
|
|
1688
1518
|
return;
|
|
1689
1519
|
}
|
|
1690
|
-
if (
|
|
1520
|
+
if (hasStreamedAnswer) draftStream?.forceNewMessage();
|
|
1691
1521
|
resetDraftDeliveryState();
|
|
1692
1522
|
resetDraftProgressState();
|
|
1693
1523
|
};
|
|
@@ -1700,7 +1530,14 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1700
1530
|
resetDraftDeliveryState();
|
|
1701
1531
|
resetDraftProgressState();
|
|
1702
1532
|
};
|
|
1703
|
-
const onQueuedFollowupSettled = !useDraftProgressCard ? void 0 : async () => {
|
|
1533
|
+
const onQueuedFollowupSettled = !useDraftProgressCard && !useNativeProgressStreaming ? void 0 : async () => {
|
|
1534
|
+
if (useNativeProgressStreaming) {
|
|
1535
|
+
progressDraft.markFinalReplyStarted();
|
|
1536
|
+
await cancelNativeUpdates();
|
|
1537
|
+
await finishNativeProgressTurn(nativeProgressCompletionSent ? void 0 : buildNativeProgressCompletionChunks(nativeProgressTerminalStatus));
|
|
1538
|
+
progressDraft.markFinalReplyDelivered();
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1704
1541
|
if (!progressCard.hasTerminalized) await draftStream?.clear();
|
|
1705
1542
|
await dropDetachedProgressCards();
|
|
1706
1543
|
};
|
|
@@ -1714,7 +1551,10 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1714
1551
|
suppressDefaultToolProgressMessages,
|
|
1715
1552
|
progressDraft,
|
|
1716
1553
|
commentaryProgressEnabled,
|
|
1717
|
-
|
|
1554
|
+
async cancel() {
|
|
1555
|
+
progressDraft.cancel();
|
|
1556
|
+
await cancelNativeUpdates();
|
|
1557
|
+
},
|
|
1718
1558
|
get nativeProgressCompletionSent() {
|
|
1719
1559
|
return nativeProgressCompletionSent;
|
|
1720
1560
|
},
|
|
@@ -1742,41 +1582,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1742
1582
|
};
|
|
1743
1583
|
}
|
|
1744
1584
|
//#endregion
|
|
1745
|
-
//#region extensions/slack/src/threading.ts
|
|
1746
|
-
function resolveSlackThreadContext(params) {
|
|
1747
|
-
const incomingThreadTs = params.message.thread_ts;
|
|
1748
|
-
const eventTs = params.message.event_ts;
|
|
1749
|
-
const messageTs = params.message.ts ?? eventTs;
|
|
1750
|
-
const hasThreadTs = typeof incomingThreadTs === "string" && incomingThreadTs.length > 0;
|
|
1751
|
-
const isThreadReply = hasThreadTs && (incomingThreadTs !== messageTs || Boolean(params.message.parent_user_id));
|
|
1752
|
-
const replyToId = isThreadReply ? incomingThreadTs : void 0;
|
|
1753
|
-
const isAssistantDmThreadRoot = hasThreadTs && !isThreadReply && params.isDirectMessage === true;
|
|
1754
|
-
return {
|
|
1755
|
-
incomingThreadTs,
|
|
1756
|
-
messageTs,
|
|
1757
|
-
isThreadReply,
|
|
1758
|
-
replyToId,
|
|
1759
|
-
messageThreadId: isThreadReply || isAssistantDmThreadRoot ? incomingThreadTs : params.replyToMode === "all" ? messageTs : void 0
|
|
1760
|
-
};
|
|
1761
|
-
}
|
|
1762
|
-
/**
|
|
1763
|
-
* Resolves Slack thread targeting for replies and status indicators.
|
|
1764
|
-
*
|
|
1765
|
-
* @returns replyThreadTs - Thread timestamp for reply messages
|
|
1766
|
-
* @returns statusThreadTs - Thread timestamp for status indicators (typing, etc.)
|
|
1767
|
-
* @returns isThreadReply - true if this is a genuine user reply in a thread,
|
|
1768
|
-
* false if thread_ts comes from a bot status message (e.g. typing indicator)
|
|
1769
|
-
*/
|
|
1770
|
-
function resolveSlackThreadTargets(params) {
|
|
1771
|
-
const { incomingThreadTs, messageTs, isThreadReply } = resolveSlackThreadContext(params);
|
|
1772
|
-
const replyThreadTs = isThreadReply ? incomingThreadTs : params.replyToMode === "all" ? messageTs : void 0;
|
|
1773
|
-
return {
|
|
1774
|
-
replyThreadTs,
|
|
1775
|
-
statusThreadTs: replyThreadTs,
|
|
1776
|
-
isThreadReply
|
|
1777
|
-
};
|
|
1778
|
-
}
|
|
1779
|
-
//#endregion
|
|
1780
1585
|
//#region extensions/slack/src/monitor/message-handler/dispatch-setup.ts
|
|
1781
1586
|
async function createSlackDispatchSetup(prepared) {
|
|
1782
1587
|
const { ctx, account, message, route } = prepared;
|
|
@@ -1854,24 +1659,17 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1854
1659
|
await reactSlackMessage(message.channel, reactionMessageTs ?? "", emoji, {
|
|
1855
1660
|
token: ctx.botToken,
|
|
1856
1661
|
client: slackClient
|
|
1857
|
-
}).catch((err) => {
|
|
1858
|
-
if (formatErrorMessage(err).includes("already_reacted")) return;
|
|
1859
|
-
throw err;
|
|
1860
1662
|
});
|
|
1861
1663
|
},
|
|
1862
1664
|
removeReaction: async (emoji) => {
|
|
1863
1665
|
await removeSlackReaction(message.channel, reactionMessageTs ?? "", emoji, {
|
|
1864
1666
|
token: ctx.botToken,
|
|
1865
1667
|
client: slackClient
|
|
1866
|
-
}).catch((err) => {
|
|
1867
|
-
if (formatErrorMessage(err).includes("no_reaction")) return;
|
|
1868
|
-
throw err;
|
|
1869
1668
|
});
|
|
1870
1669
|
}
|
|
1871
1670
|
},
|
|
1872
1671
|
initialEmoji: prepared.ackReactionValue || "eyes",
|
|
1873
|
-
|
|
1874
|
-
timing: DEFAULT_TIMING,
|
|
1672
|
+
presentation: "acknowledgement",
|
|
1875
1673
|
onError: (err) => {
|
|
1876
1674
|
logAckFailure({
|
|
1877
1675
|
log: logVerbose,
|
|
@@ -1898,10 +1696,7 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1898
1696
|
agentId: route.agentId,
|
|
1899
1697
|
channel: "slack",
|
|
1900
1698
|
accountId: route.accountId,
|
|
1901
|
-
transformReplyPayload:
|
|
1902
|
-
if (payload.isReasoning === true) return null;
|
|
1903
|
-
return payload;
|
|
1904
|
-
},
|
|
1699
|
+
transformReplyPayload: sanitizeSlackMonitorReplyPayload,
|
|
1905
1700
|
typing: {
|
|
1906
1701
|
start: async () => {
|
|
1907
1702
|
if (!threadStatusGate.hasVisibleOutput()) {
|
|
@@ -2187,7 +1982,6 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2187
1982
|
}
|
|
2188
1983
|
};
|
|
2189
1984
|
const deliverNormally = async (params) => {
|
|
2190
|
-
if (params.payload.isReasoning === true) return;
|
|
2191
1985
|
const replyThreadTs = resolveDeliveryThreadTs(params);
|
|
2192
1986
|
const deliveryReplyThreadTs = replyDeliveryMode === "off" && !forcedReplyThreadTs && !isThreadReply ? void 0 : replyThreadTs;
|
|
2193
1987
|
if (deliveryTracker.hasDelivered({
|
|
@@ -2250,7 +2044,6 @@ function createSlackStreamingDeliveryRuntime(setup) {
|
|
|
2250
2044
|
return !state.streamFailed && !reply.hasMedia && renderPlan.mode !== "split" && !plannedBlocks?.length && !readSlackReplyBlocks(payload)?.length && reply.hasText && (!options?.maxTextBytes || countSlackTextUtf8Bytes(reply.trimmedText) <= options.maxTextBytes);
|
|
2251
2045
|
};
|
|
2252
2046
|
const deliverWithStreaming = async (params) => {
|
|
2253
|
-
if (params.payload.isReasoning === true) return;
|
|
2254
2047
|
const reply = resolveSendableOutboundReplyParts(params.payload);
|
|
2255
2048
|
if (!isStreamingEligible(params.payload)) {
|
|
2256
2049
|
await deliverNormally({
|
|
@@ -2452,7 +2245,6 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2452
2245
|
return payload;
|
|
2453
2246
|
};
|
|
2454
2247
|
const deliverSlackPayload = async (payload, info) => {
|
|
2455
|
-
if (payload.isReasoning === true) return { visibleReplySent: false };
|
|
2456
2248
|
if (info.kind === "final" && slackStreaming.mode === "progress" && progress.isProgressMode) {
|
|
2457
2249
|
if (progress.useNativeProgressStreaming) {
|
|
2458
2250
|
await progress.deliverNativeFinal(payload, info.kind);
|
|
@@ -2503,7 +2295,11 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2503
2295
|
const slackBlocks = replyRenderPlan.mode === "single" ? replyRenderPlan.blocks : replyRenderPlan.blockPart?.blocks;
|
|
2504
2296
|
const requiresSeparateFallbackDelivery = replyRenderPlan.mode === "split";
|
|
2505
2297
|
const trimmedFinalText = replyRenderPlan.mode === "single" ? replyRenderPlan.text.trim() : replyRenderPlan.fallbackText.trim();
|
|
2506
|
-
const previewFinalText = replyRenderPlan.mode === "single" && replyRenderPlan.textIsSlackMrkdwn ? trimmedFinalText : normalizeSlackOutboundText((replySourceText ?? "").trim()
|
|
2298
|
+
const previewFinalText = replyRenderPlan.mode === "single" && replyRenderPlan.textIsSlackMrkdwn ? trimmedFinalText : normalizeSlackOutboundText((replySourceText ?? "").trim(), { tableMode: resolveMarkdownTableMode({
|
|
2299
|
+
cfg,
|
|
2300
|
+
channel: "slack",
|
|
2301
|
+
accountId: account.accountId
|
|
2302
|
+
}) });
|
|
2507
2303
|
const previewFinalTextFitsEdit = countSlackTextUtf8Bytes(previewFinalText) <= SLACK_EDIT_TEXT_MAX_BYTES;
|
|
2508
2304
|
const shouldRestoreTtsSupplementTextForPreviewFallback = Boolean(ttsSupplement) && ttsSupplement?.visibleTextAlreadyDelivered !== true && Boolean(draftStream) && !draftPreviewCommitted.value && !delivery.observedFinalReplyDelivery && previewStreamingEnabled && !payload.text?.trim();
|
|
2509
2305
|
let ttsPreviewFinalization;
|
|
@@ -2619,6 +2415,7 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2619
2415
|
sessionKey: route.sessionKey
|
|
2620
2416
|
},
|
|
2621
2417
|
ctxPayload: prepared.ctxPayload,
|
|
2418
|
+
dispatchReplyFromConfig: ctx.dispatchReplyFromConfig,
|
|
2622
2419
|
dispatcherOptions: {
|
|
2623
2420
|
...replyPipeline,
|
|
2624
2421
|
transformReplyPayload: (payload) => {
|
|
@@ -2673,7 +2470,6 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2673
2470
|
} : void 0,
|
|
2674
2471
|
onToolStart: async (payload) => {
|
|
2675
2472
|
if (statusReactionsEnabled) await statusReactions.setTool(payload.name);
|
|
2676
|
-
if (payload.phase === "start") progress.progressWorkCounter.noteToolCall(payload.name);
|
|
2677
2473
|
return await progress.progressDraft.pushToolEvent(payload);
|
|
2678
2474
|
},
|
|
2679
2475
|
onItemEvent: async (payload) => {
|
|
@@ -2715,7 +2511,7 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2715
2511
|
} catch (err) {
|
|
2716
2512
|
dispatchError = err;
|
|
2717
2513
|
} finally {
|
|
2718
|
-
progress.
|
|
2514
|
+
await progress.cancel();
|
|
2719
2515
|
if (!progress.useDraftProgressCard) await draftStream?.discardPending();
|
|
2720
2516
|
}
|
|
2721
2517
|
let streamFallbackDelivered = false;
|
|
@@ -2748,13 +2544,15 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2748
2544
|
if (pendingFailureNotice && anyReplyDelivered) recordSlackThreadFailureNotice(pendingFailureNotice);
|
|
2749
2545
|
if (dispatchError || agentRunFailed) await progress.finalizeDraftProgressCard("error");
|
|
2750
2546
|
await progress.dropDetachedProgressCards();
|
|
2751
|
-
if (statusReactionsEnabled)
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2547
|
+
if (statusReactionsEnabled) {
|
|
2548
|
+
if (dispatchError || agentRunFailed) {
|
|
2549
|
+
await statusReactions.setError();
|
|
2550
|
+
statusReactions.restoreInitial();
|
|
2551
|
+
} else if (anyReplyDelivered) {
|
|
2552
|
+
await statusReactions.setDone();
|
|
2553
|
+
statusReactions.restoreInitial();
|
|
2554
|
+
} else await statusReactions.restoreInitial();
|
|
2555
|
+
}
|
|
2758
2556
|
const participationThreadTs = delivery.usedReplyThreadTs ?? statusThreadTs;
|
|
2759
2557
|
if (anyReplyDelivered && participationThreadTs) recordSlackThreadParticipation(account.accountId, message.channel, participationThreadTs, {
|
|
2760
2558
|
agentId: route.agentId,
|
|
@@ -2813,7 +2611,7 @@ function normalizeSlackAppContextEntities(value) {
|
|
|
2813
2611
|
//#endregion
|
|
2814
2612
|
//#region extensions/slack/src/monitor/thread.ts
|
|
2815
2613
|
const THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
|
|
2816
|
-
const THREAD_STARTER_CACHE_TTL_MS =
|
|
2614
|
+
const THREAD_STARTER_CACHE_TTL_MS = 216e5;
|
|
2817
2615
|
const THREAD_STARTER_CACHE_MAX = 2e3;
|
|
2818
2616
|
function evictThreadStarterCache() {
|
|
2819
2617
|
const now = asDateTimestampMs(Date.now());
|
|
@@ -3008,7 +2806,24 @@ async function discardSlackPreflightMedia(media) {
|
|
|
3008
2806
|
const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
|
|
3009
2807
|
const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
|
|
3010
2808
|
const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
|
|
3011
|
-
const
|
|
2809
|
+
const MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS = 2e3;
|
|
2810
|
+
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-BOxiu2Vy.js").then((n) => n._));
|
|
2811
|
+
function formatSlackUnavailableMedia(params) {
|
|
2812
|
+
let fileReferences = params.files?.map((file) => `${formatSlackFileReference(file)} unavailable (${file.reason})`).join(", ");
|
|
2813
|
+
if (fileReferences && fileReferences.length > MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS) fileReferences = `${truncateUtf16Safe(fileReferences, MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS)}; … (file references truncated)`;
|
|
2814
|
+
const fileBlock = fileReferences ? `[Slack file: ${fileReferences}]` : void 0;
|
|
2815
|
+
const body = [params.body, fileBlock].filter(Boolean).join("\n");
|
|
2816
|
+
if (params.unavailableMediaCount === 0) return body;
|
|
2817
|
+
const notice = `[slack ${params.unavailableMediaCount > 1 ? `${params.unavailableMediaCount} attachments` : "attachment"} unavailable]`;
|
|
2818
|
+
return params.prependUnavailable ? [
|
|
2819
|
+
notice,
|
|
2820
|
+
fileBlock,
|
|
2821
|
+
params.body
|
|
2822
|
+
].filter(Boolean).join("\n") : formatInboundMediaUnavailableText({
|
|
2823
|
+
body,
|
|
2824
|
+
notice
|
|
2825
|
+
});
|
|
2826
|
+
}
|
|
3012
2827
|
function collectUniqueSlackMentionIds$1(texts) {
|
|
3013
2828
|
const seen = /* @__PURE__ */ new Set();
|
|
3014
2829
|
const mentionIds = [];
|
|
@@ -3046,8 +2861,9 @@ async function resolveSlackMessageContent(params) {
|
|
|
3046
2861
|
isThreadReply: params.isThreadReply,
|
|
3047
2862
|
threadStarter: params.threadStarter
|
|
3048
2863
|
});
|
|
3049
|
-
const
|
|
2864
|
+
const attachmentContent = ownFiles?.length || params.message.attachments?.length ? await loadSlackMediaModule$1().then(({ resolveSlackAttachmentContent }) => resolveSlackAttachmentContent({
|
|
3050
2865
|
files: ownFiles,
|
|
2866
|
+
attachments: params.message.attachments,
|
|
3051
2867
|
client: params.client,
|
|
3052
2868
|
token: params.botToken,
|
|
3053
2869
|
maxBytes: params.mediaMaxBytes,
|
|
@@ -3055,30 +2871,9 @@ async function resolveSlackMessageContent(params) {
|
|
|
3055
2871
|
totalTimeoutMs: params.mediaTotalTimeoutMs,
|
|
3056
2872
|
abortSignal: params.abortSignal,
|
|
3057
2873
|
preloadedMedia: params.preloadedMedia
|
|
3058
|
-
})) :
|
|
3059
|
-
const
|
|
3060
|
-
|
|
3061
|
-
client: params.client,
|
|
3062
|
-
token: params.botToken,
|
|
3063
|
-
maxBytes: params.mediaMaxBytes,
|
|
3064
|
-
readIdleTimeoutMs: params.mediaReadIdleTimeoutMs,
|
|
3065
|
-
totalTimeoutMs: params.mediaTotalTimeoutMs,
|
|
3066
|
-
abortSignal: params.abortSignal
|
|
3067
|
-
})) : Promise.resolve(null);
|
|
3068
|
-
const [media, attachmentContent] = await Promise.all([mediaPromise, attachmentContentPromise]);
|
|
3069
|
-
const mergedMedia = [...media ?? [], ...attachmentContent?.media ?? []];
|
|
3070
|
-
const effectiveDirectMedia = mergedMedia.length > 0 ? mergedMedia : null;
|
|
3071
|
-
const mediaPlaceholder = effectiveDirectMedia ? effectiveDirectMedia.map((item) => item.placeholder).join(" ") : void 0;
|
|
3072
|
-
const fallbackFileIds = /* @__PURE__ */ new Set();
|
|
3073
|
-
const fallbackFiles = [...ownFiles ?? [], ...attachmentContent?.files ?? []].filter((file) => {
|
|
3074
|
-
const fileId = normalizeOptionalString(file.id);
|
|
3075
|
-
if (!fileId) return true;
|
|
3076
|
-
if (fallbackFileIds.has(fileId)) return false;
|
|
3077
|
-
fallbackFileIds.add(fileId);
|
|
3078
|
-
return true;
|
|
3079
|
-
});
|
|
3080
|
-
const fileOnlyFallback = !mediaPlaceholder && fallbackFiles.length > 0 ? fallbackFiles.slice(0, 8).map((file) => formatSlackFileReference(file)).join(", ") : void 0;
|
|
3081
|
-
const fileOnlyPlaceholder = fileOnlyFallback ? `[Slack file: ${fileOnlyFallback}]` : void 0;
|
|
2874
|
+
})) : null;
|
|
2875
|
+
const effectiveDirectMedia = attachmentContent?.media.length ? attachmentContent.media : null;
|
|
2876
|
+
const mediaPlaceholder = effectiveDirectMedia?.map((item) => item.placeholder).join(" ");
|
|
3082
2877
|
let botAttachmentText;
|
|
3083
2878
|
if (params.isBotMessage && !attachmentContent?.text) {
|
|
3084
2879
|
const botAttachmentTextParts = [];
|
|
@@ -3102,7 +2897,8 @@ async function resolveSlackMessageContent(params) {
|
|
|
3102
2897
|
if (skippedLookups > 0) logVerbose(`slack: skipping ${skippedLookups} mention lookup(s) beyond per-message cap (${SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE})`);
|
|
3103
2898
|
const { results } = await runTasksWithConcurrency({
|
|
3104
2899
|
tasks: lookupIds.map((userId) => async () => {
|
|
3105
|
-
const
|
|
2900
|
+
const user = await resolveUserName(userId);
|
|
2901
|
+
const renderedName = normalizeOptionalString(user?.name);
|
|
3106
2902
|
return {
|
|
3107
2903
|
userId,
|
|
3108
2904
|
rendered: renderedName ? `<@${userId}> (${renderedName})` : null
|
|
@@ -3115,23 +2911,20 @@ async function resolveSlackMessageContent(params) {
|
|
|
3115
2911
|
renderedMentions.set(result.userId, result.rendered);
|
|
3116
2912
|
}
|
|
3117
2913
|
}
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
body: rawBody,
|
|
3128
|
-
notice: `[slack ${unavailableImageCount > 1 ? `${unavailableImageCount} forwarded images` : "forwarded image"} unavailable]`
|
|
2914
|
+
const rawBody = formatSlackUnavailableMedia({
|
|
2915
|
+
body: [
|
|
2916
|
+
renderSlackUserMentions(textParts[0], renderedMentions),
|
|
2917
|
+
renderSlackUserMentions(textParts[1], renderedMentions),
|
|
2918
|
+
renderSlackUserMentions(textParts[2], renderedMentions),
|
|
2919
|
+
mediaPlaceholder
|
|
2920
|
+
].filter(Boolean).join("\n") || "",
|
|
2921
|
+
files: attachmentContent?.files,
|
|
2922
|
+
unavailableMediaCount: attachmentContent?.unavailableMediaCount ?? 0
|
|
3129
2923
|
});
|
|
3130
|
-
|
|
3131
|
-
return {
|
|
2924
|
+
return rawBody ? {
|
|
3132
2925
|
rawBody,
|
|
3133
2926
|
effectiveDirectMedia
|
|
3134
|
-
};
|
|
2927
|
+
} : null;
|
|
3135
2928
|
}
|
|
3136
2929
|
//#endregion
|
|
3137
2930
|
//#region extensions/slack/src/monitor/message-handler/prepare-dm-history.ts
|
|
@@ -3208,7 +3001,8 @@ async function resolveSlackDmHistoryContext(params) {
|
|
|
3208
3001
|
//#endregion
|
|
3209
3002
|
//#region extensions/slack/src/monitor/message-handler/prepare-routing.ts
|
|
3210
3003
|
function resolveSlackBaseConversationId(params) {
|
|
3211
|
-
|
|
3004
|
+
const raw = params.isDirectMessage ? `user:${params.message.user ?? "unknown"}` : params.message.channel;
|
|
3005
|
+
return qualifySlackConversationId(raw, params.eventScope);
|
|
3212
3006
|
}
|
|
3213
3007
|
function resolveSlackInitialAgentRoute(params) {
|
|
3214
3008
|
const route = resolveAgentRoute({
|
|
@@ -3359,7 +3153,7 @@ function formatSlackThreadLabelSnippet(text) {
|
|
|
3359
3153
|
}
|
|
3360
3154
|
//#endregion
|
|
3361
3155
|
//#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
|
|
3362
|
-
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-
|
|
3156
|
+
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-BOxiu2Vy.js").then((n) => n._));
|
|
3363
3157
|
const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
|
|
3364
3158
|
function resolveSlackThreadSessionFreshness(params) {
|
|
3365
3159
|
return params.ctx.channelRuntime?.session?.resolveEntryResetFreshness?.({
|
|
@@ -3471,14 +3265,24 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3471
3265
|
const snippet = formatSlackThreadLabelSnippet(starter.text);
|
|
3472
3266
|
threadLabel = `Slack thread ${params.roomLabel}${snippet ? `: ${snippet}` : ""}`;
|
|
3473
3267
|
if (shouldSeedInitialThreadContext && !params.effectiveDirectMedia && starter.files && starter.files.length > 0) {
|
|
3474
|
-
const {
|
|
3475
|
-
|
|
3268
|
+
const { resolveSlackAttachmentContent } = await loadSlackMediaModule();
|
|
3269
|
+
const attachmentContent = await resolveSlackAttachmentContent({
|
|
3476
3270
|
files: starter.files,
|
|
3477
3271
|
client: params.eventScope?.client ?? params.ctx.app.client,
|
|
3478
3272
|
token: params.ctx.botToken,
|
|
3479
3273
|
maxBytes: params.ctx.mediaMaxBytes
|
|
3480
3274
|
});
|
|
3481
|
-
|
|
3275
|
+
threadStarterMedia = attachmentContent?.media.length ? attachmentContent.media : null;
|
|
3276
|
+
if (attachmentContent) threadStarterBody = formatSlackUnavailableMedia({
|
|
3277
|
+
body: threadStarterBody,
|
|
3278
|
+
files: attachmentContent.files,
|
|
3279
|
+
unavailableMediaCount: attachmentContent.unavailableMediaCount,
|
|
3280
|
+
prependUnavailable: true
|
|
3281
|
+
});
|
|
3282
|
+
if (threadStarterMedia) {
|
|
3283
|
+
const starterPlaceholders = threadStarterMedia.map((item) => item.placeholder).join(", ");
|
|
3284
|
+
logVerbose(`slack: hydrated thread starter file ${starterPlaceholders} from root message`);
|
|
3285
|
+
}
|
|
3482
3286
|
}
|
|
3483
3287
|
} else threadLabel = `Slack thread ${params.roomLabel}`;
|
|
3484
3288
|
const includeBotStarterAsRootContext = shouldIncludeBotThreadStarterContext({
|
|
@@ -3498,14 +3302,20 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3498
3302
|
const threadInitialHistoryLimit = params.account.config?.thread?.initialHistoryLimit ?? 20;
|
|
3499
3303
|
if (threadInitialHistoryLimit > 0 && shouldLoadInitialThreadHistory) {
|
|
3500
3304
|
const currentBotRootTs = starter?.ts ?? params.threadTs;
|
|
3305
|
+
const threadHistory = await resolveSlackThreadHistory({
|
|
3306
|
+
channelId: params.message.channel,
|
|
3307
|
+
threadTs: params.threadTs,
|
|
3308
|
+
client: params.eventScope?.client ?? params.ctx.app.client,
|
|
3309
|
+
currentMessageTs: params.message.ts,
|
|
3310
|
+
limit: threadInitialHistoryLimit
|
|
3311
|
+
});
|
|
3312
|
+
const enrichedStarter = starter && threadStarterBody && threadStarterBody !== starter.text ? {
|
|
3313
|
+
...starter,
|
|
3314
|
+
text: threadStarterBody,
|
|
3315
|
+
ts: currentBotRootTs
|
|
3316
|
+
} : null;
|
|
3501
3317
|
const threadHistoryWithBotRoot = ensureSlackThreadHistoryHasBotRoot({
|
|
3502
|
-
history:
|
|
3503
|
-
channelId: params.message.channel,
|
|
3504
|
-
threadTs: params.threadTs,
|
|
3505
|
-
client: params.eventScope?.client ?? params.ctx.app.client,
|
|
3506
|
-
currentMessageTs: params.message.ts,
|
|
3507
|
-
limit: threadInitialHistoryLimit
|
|
3508
|
-
}),
|
|
3318
|
+
history: enrichedStarter && !threadHistory.some((entry) => entry.ts === currentBotRootTs) ? [enrichedStarter, ...threadHistory.length >= threadInitialHistoryLimit ? threadHistory.slice(1) : threadHistory] : threadHistory,
|
|
3509
3319
|
includeBotStarterAsRootContext,
|
|
3510
3320
|
threadStarter: starter ? {
|
|
3511
3321
|
...starter,
|
|
@@ -3564,7 +3374,7 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3564
3374
|
});
|
|
3565
3375
|
const role = isCurrentBot || isOtherBot || Boolean(historyMsg.botId) ? "assistant" : "user";
|
|
3566
3376
|
const msgSenderName = isCurrentBot ? "Bot (this assistant)" : msgUser?.name ?? (historyMsg.botId ? `Bot (${historyMsg.botId})` : "Unknown");
|
|
3567
|
-
const msgWithId = `${historyMsg.text}\n[slack message id: ${historyMsg.ts ?? "unknown"} channel: ${params.message.channel}]`;
|
|
3377
|
+
const msgWithId = `${historyMsg.ts === currentBotRootTs && threadStarterBody ? threadStarterBody : historyMsg.text}\n[slack message id: ${historyMsg.ts ?? "unknown"} channel: ${params.message.channel}]`;
|
|
3568
3378
|
historyParts.push(formatInboundEnvelope({
|
|
3569
3379
|
channel: "Slack",
|
|
3570
3380
|
from: `${msgSenderName} (${role})`,
|
|
@@ -3591,7 +3401,7 @@ async function resolveSlackThreadContextData(params) {
|
|
|
3591
3401
|
//#endregion
|
|
3592
3402
|
//#region extensions/slack/src/monitor/message-handler/subteam-mentions.ts
|
|
3593
3403
|
const SUBTEAM_MENTION_RE = /<!subteam\^([A-Z0-9]+)(?:\|[^>]*)?>/gi;
|
|
3594
|
-
const SUBTEAM_MEMBER_CACHE_TTL_MS =
|
|
3404
|
+
const SUBTEAM_MEMBER_CACHE_TTL_MS = 3e5;
|
|
3595
3405
|
const subteamMemberCache = /* @__PURE__ */ new WeakMap();
|
|
3596
3406
|
function normalizeSlackId(value) {
|
|
3597
3407
|
return typeof value === "string" && value.trim() ? value.trim().toUpperCase() : void 0;
|
|
@@ -3662,7 +3472,7 @@ const SLACK_USER_MENTION_RE = /<@([^>|]+)(?:\|[^>]+)?>/g;
|
|
|
3662
3472
|
const SLACK_SUBTEAM_MENTION_RE = /<!subteam\^([^>|]+)(?:\|[^>]+)?>/g;
|
|
3663
3473
|
const SLACK_SUBTEAM_MENTION_MARKER = "<!subteam^";
|
|
3664
3474
|
const SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS = 4;
|
|
3665
|
-
const SLACK_HISTORY_MEDIA_MAX_BYTES =
|
|
3475
|
+
const SLACK_HISTORY_MEDIA_MAX_BYTES = 10485760;
|
|
3666
3476
|
const SLACK_HISTORY_MEDIA_IDLE_TIMEOUT_MS = 1e3;
|
|
3667
3477
|
const SLACK_HISTORY_MEDIA_TOTAL_TIMEOUT_MS = 3e3;
|
|
3668
3478
|
const SLACK_CHANNEL_ACCESS_DOCS_URL = "https://docs.openclaw.ai/channels/slack#access-control-and-routing";
|
|
@@ -3796,7 +3606,7 @@ function buildSlackHistoryMediaCandidateMessage(message) {
|
|
|
3796
3606
|
async function resolveSlackHistoryMediaForPendingRecord(params) {
|
|
3797
3607
|
const mediaMessage = buildSlackHistoryMediaCandidateMessage(params.message);
|
|
3798
3608
|
if (!mediaMessage) return [];
|
|
3799
|
-
|
|
3609
|
+
const content = await resolveSlackMessageContent({
|
|
3800
3610
|
message: mediaMessage,
|
|
3801
3611
|
isThreadReply: params.isThreadReply,
|
|
3802
3612
|
threadStarter: params.threadStarter,
|
|
@@ -3806,7 +3616,8 @@ async function resolveSlackHistoryMediaForPendingRecord(params) {
|
|
|
3806
3616
|
mediaMaxBytes: Math.min(params.ctx.mediaMaxBytes, SLACK_HISTORY_MEDIA_MAX_BYTES),
|
|
3807
3617
|
mediaReadIdleTimeoutMs: SLACK_HISTORY_MEDIA_IDLE_TIMEOUT_MS,
|
|
3808
3618
|
mediaTotalTimeoutMs: SLACK_HISTORY_MEDIA_TOTAL_TIMEOUT_MS
|
|
3809
|
-
})
|
|
3619
|
+
});
|
|
3620
|
+
return await toInboundMediaFactsWithMetadata(content?.effectiveDirectMedia, {
|
|
3810
3621
|
kind: "image",
|
|
3811
3622
|
messageId: params.message.ts
|
|
3812
3623
|
});
|
|
@@ -3929,7 +3740,8 @@ async function authorizeSlackInboundMessage(params) {
|
|
|
3929
3740
|
if (conversation.isRoom && ctx.groupPolicy === "allowlist" && params.explicitBotMention && !isBotMessage && message.user) {
|
|
3930
3741
|
let subject = "This OpenClaw bot";
|
|
3931
3742
|
if (ctx.botUserId) try {
|
|
3932
|
-
const
|
|
3743
|
+
const botIdentity = await ctx.resolveUserName(ctx.botUserId, params.eventScope);
|
|
3744
|
+
const botName = normalizeOptionalString(botIdentity?.name);
|
|
3933
3745
|
if (botName) subject = escapeSlackMrkdwn(botName);
|
|
3934
3746
|
} catch (error) {
|
|
3935
3747
|
logVerbose(`slack allowlist denial bot-name lookup failed: ${formatSlackError(error)}`);
|
|
@@ -4022,7 +3834,8 @@ async function prepareSlackMessage(params) {
|
|
|
4022
3834
|
const resolveSenderName = async () => {
|
|
4023
3835
|
if (resolvedSenderName) return resolvedSenderName;
|
|
4024
3836
|
if (message.user) {
|
|
4025
|
-
const
|
|
3837
|
+
const sender = await ctx.resolveUserName(message.user, opts.eventScope);
|
|
3838
|
+
const normalized = normalizeOptionalString(sender?.name);
|
|
4026
3839
|
if (normalized) {
|
|
4027
3840
|
resolvedSenderName = normalized;
|
|
4028
3841
|
return resolvedSenderName;
|