mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 22:11:37 +00:00
* feat(mattermost): add opt-in DM threading via dmReplyToMode Resolves #93203. Mattermost direct messages are hardcoded non-threaded: resolveMattermostReplyToMode returns "off" for direct chats before consulting config, and the reply-root / effective-reply resolvers short-circuit for direct chats. So every DM accretes into one ever-growing session with unbounded per-session token usage, with no way to isolate each DM topic the way groups/channels (and Slack) can. Add channels.mattermost.dmReplyToMode (same enum as replyToMode), default "off" so existing flat-DM deployments are unchanged. When set to "first"/"all", a DM @mention starts an independent, thread-scoped session: - resolveMattermostReplyToMode: direct chats return config.dmReplyToMode ?? "off". - resolveMattermostEffectiveReplyToId: direct early-return gated on replyToMode "off" (the value already reflects dmReplyToMode for direct chats). - resolveMattermostReplyRootId: direct early-return gated on the absence of a thread root (a DM carries one only when DM threading is enabled). - New DM threads start fresh (no parent-session inheritance) so each topic is isolated; a threaded DM keeps its own history key while a flat DM root keeps none. Default-off preserves the documented flat-DM contract, so this changes no existing behavior. Adds unit coverage and documents the opt-in. The only open question is the knob shape (dmReplyToMode enum vs a boolean dmThreading) — happy to adjust. Refs #65729. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(mattermost): register dmReplyToMode in config schema dmReplyToMode was wired into the account config type and reply resolution but never added to MattermostConfigSchema, so setting it in openclaw.json failed config validation ("must not have additional properties: dmReplyToMode") and the gateway refused to start — the knob could not actually be enabled. Register it in the schema, regenerate the bundled channel config metadata and doc baseline, and add a config-schema test. * fix(mattermost): thread direct reply transport when dmReplyToMode is on resolveReplyTransport nulled the direct reply root/thread id unconditionally, so routed replies and message-tool follow-ups in an opted-in DM thread were still sent flat even when the effective replyToMode was first/all. Keep direct transport flat only when the mode is off (the historical contract) and preserve the thread root otherwise, matching the monitor-level DM threading gates. Adds channel.test.ts coverage for resolveReplyTransport. * fix(mattermost): use per-chat reply mode overrides * fix(mattermost): bound direct thread history * chore(config): refresh docs baseline --------- Co-authored-by: leon <leon@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>