* docs(slack): drop retired socketMode transport tuning
channels.slack.socketMode is rejected by Slack config validation, pinned by
the 'rejects retired Socket Mode ping/pong transport tuning' schema test, and
the client pong timeout is now a hardcoded 15s constant. The page still told
operators to configure it.
* fix(slack): migrate retired socketMode with doctor instead of hand-editing
The retired object fails schema validation at root and account scope, so the
docs previously left manual removal as the only recovery. Slack already owns
legacyConfigRules and normalizeCompatibilityConfig, so the strip belongs there.
* test(slack): narrow the doctor contract config record for check-test-types
normalizeCompatibilityConfig returns a possibly-absent channel entry, so the
socketMode assertions need expectDefined before indexing.
* docs(slack): describe socketMode retirement by observed behavior
openclaw config validate reports a config carrying the retired object as valid,
so the earlier 'validation rejects it / fails to load' wording was wrong. The
observable facts are that it is not read and that doctor --fix removes it.
* revert(slack): drop the duplicate socketMode doctor migration
Core already strips channels.slack.socketMode at root and account scope in
legacy-config-migrations.runtime.retired.ts via visitChannelEntries, so the
plugin-side rule was duplicate policy. Keeps this PR to the docs correction.
* docs(slack): state what doctor actually cleans up for socketMode
Doctor flags retired layout knobs with a general notice, and --fix removes the
three named fields and drops the object only once empty, so an unknown key
inside it survives.
Prevent stale top-level buttons arguments from silently sending text-only Telegram messages. Point model guidance and docs to typed presentation actions, and reject retired input before delivery.
Separate durable ClickClack room identity from replaceable exact-session attachments. Session archive, reset, deletion, and recreation retain the existing room and history while rotating local routing authority and preserving fail-closed exact-incarnation grants.
Pin ambiguous room recovery to the originating account and credential, and retain prior attachments when persistence fails.
Closes#119300
Co-authored-by: Chisel <chisel@psiclawops.dev>
Recover Telegram forum reaction topics from provider-observed message context before authorization, and drop unknown topics instead of routing them to General. Serialize each forum message with its reaction update to avoid cache races. Thanks @vovapetry.
Three gates my own changes broke:
- docs/channels/telegram.md needed a blank line before </Note>; I formatted the
TypeScript but never ran the docs formatter over the pages I edited.
- The mock harness matched a literal with a regex, which oxlint's prefer-includes
rejects.
- Widening resolveChannelPreviewStreamMode's defaultMode to StreamingMode and
adding rendersRollingLinesNatively changes the exported plugin-SDK surface, so
the API baseline hash had to be regenerated.
ClawSweeper's accepted-migration path requires operator-facing docs for the
default change: state what an existing install sees after upgrading and the
one-line setting that restores streamed answer text.
A status headline replaced the rolling tool lines instead of sitting above
them, so a default Discord draft showed one preamble sentence for an entire
tool-heavy turn. Operators reached for `/verbose` to see any activity, which
delivers durable per-tool-call messages and floods the channel.
- Render the headline above the lines; both stay visible in one message.
- Shorten the start gate from 5s to 1.5s. The gate only creates the draft
when the timer fires and finalize cancels it, so quick answers still post
no draft while a 3s tool turn stops being silent.
- Drop Discord's label-gated tool-progress default so
resolveChannelStreamingPreviewToolProgress is the single owner. An explicit
`toolProgress: false` still silences the lines.
- Resolve that toggle against a "progress" mode guess when `streaming.mode`
is unset, so the progress-draft channels stop ignoring an explicit
`progress.toolProgress` opt-out.
Telegram now defaults to `streaming.mode: "progress"` like Discord; set
`"partial"` to keep streamed answer text. Its renderer draws work lines from
the compositor's structured lines, so `rendersRollingLinesNatively` keeps
them out of the composed text rather than printing every line twice.
* fix(msteams): honor group conversation allowlists
Fixes#95737. Preserve opaque Teams conversation identities, the documented group fallback, personal-DM isolation, and display-name spoof protection.
Based on the original contributor fix in #95764.
Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>
* test(msteams): isolate conversation allowlist regression proof
Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>
---------
Co-authored-by: 周鹤0668001310 <zhou.he3@xydigit.com>
* refactor(memory-core): remove orphaned shadow trials
* refactor(qqbot): migrate direct voice upload formats
Release note: QQBot configs using voiceDirectUploadFormats now migrate through openclaw doctor --fix to audioFormatPolicy.uploadDirectFormats at root and account scope. Existing nested uploadDirectFormats values win conflicts, and runtime reads only the nested policy.
* refactor(feishu): migrate tools base alias
Release note: Feishu configs using tools.base now migrate through openclaw doctor --fix to tools.bitable at root and account scope. Existing bitable values win conflicts, and runtime accepts only the canonical key.
* refactor(extensions): remove dead runtime state
* chore(config): refresh bundled channel metadata
* refactor(codex): keep realtime fallback type private
* test(ci): align QA compatibility scenario count
* refactor(slack): retire inline interactive directives
Release note: Slack configs using channels.slack.capabilities.interactiveReplies, including per-account settings, are removed by openclaw doctor --fix. Slack-only [[slack_buttons:...]] and [[slack_select:...]] markup is no longer parsed; emit typed presentation buttons and selects instead.
* docs: refresh Slack docs map