fix(mattermost): suppress draft progress chatter

This commit is contained in:
Vincent Koc
2026-05-03 19:11:13 -07:00
parent 7e296aef4b
commit be438cf887
3 changed files with 44 additions and 0 deletions

View File

@@ -62,6 +62,7 @@ Docs: https://docs.openclaw.ai
- Discord/Slack/Mattermost: align draft preview tool-progress config help with the runtime behavior that hides interim tool updates when `streaming.preview.toolProgress` is false. Thanks @vincentkoc.
- Feishu: use the shared channel progress formatter for streaming-card tool status lines, including raw command/detail output and message-tool filtering. Thanks @vincentkoc.
- Mattermost: use the shared progress draft formatter for tool status previews, including raw command/detail output when `agents.defaults.toolProgressDetail: "raw"` is enabled. Thanks @vincentkoc.
- Mattermost: suppress standalone default tool-progress messages while draft previews are active, including when draft tool lines are disabled. Thanks @vincentkoc.
- OpenAI Codex: honor `auth.order.openai-codex` when starting app-server clients without an explicit auth profile, so status/model probes and implicit startup use the configured Codex account instead of falling back to the default profile. Thanks @vincentkoc.
- OpenAI Codex: let SSRF-guarded provider requests inherit OpenClaw's undici IPv4/IPv6 fallback policy, so ChatGPT-backed Codex runs recover on IPv4-working hosts when DNS still returns unreachable IPv6 addresses. Fixes #76857. Thanks @jplavoiemtl and @SymbolStar.
- Gateway/systemd: preserve operator-added secrets in the Gateway env file across re-stage while clearing OpenClaw-managed keys (such as `OPENCLAW_GATEWAY_TOKEN`) so a fresh staging value is never shadowed by a stale env-file copy; operator secrets are also retained when the state-dir `.env` is empty. Fixes #76860. Thanks @hclsys.

View File

@@ -17,6 +17,7 @@ import {
resolveMattermostThreadSessionContext,
shouldFinalizeMattermostPreviewAfterDispatch,
shouldClearMattermostDraftPreview,
shouldSuppressMattermostDefaultToolProgressMessages,
shouldUpdateMattermostDraftToolProgress,
type MattermostMentionGateInput,
type MattermostRequireMentionResolverInput,
@@ -314,6 +315,37 @@ describe("shouldUpdateMattermostDraftToolProgress", () => {
});
});
describe("shouldSuppressMattermostDefaultToolProgressMessages", () => {
type MattermostConfig = NonNullable<NonNullable<OpenClawConfig["channels"]>["mattermost"]>;
function resolveSuppressDefaultProgress(mattermostConfig: MattermostConfig) {
const account = resolveMattermostAccount({
cfg: {
channels: {
mattermost: mattermostConfig,
},
},
accountId: "default",
allowUnresolvedSecretRef: true,
});
return shouldSuppressMattermostDefaultToolProgressMessages(account);
}
it("suppresses standalone progress messages while draft previews are active", () => {
expect(resolveSuppressDefaultProgress({ enabled: true })).toBe(true);
});
it("keeps standalone progress messages available when draft streaming is off", () => {
expect(
resolveSuppressDefaultProgress({
streaming: {
mode: "off",
},
}),
).toBe(false);
});
});
describe("shouldClearMattermostDraftPreview", () => {
it("deletes the preview after successful normal final delivery", () => {
expect(

View File

@@ -127,6 +127,12 @@ export function shouldUpdateMattermostDraftToolProgress(
);
}
export function shouldSuppressMattermostDefaultToolProgressMessages(
account: Pick<ResolvedMattermostAccount, "streamingMode">,
): boolean {
return account.streamingMode !== "off";
}
type MediaKind = "image" | "audio" | "video" | "document" | "unknown";
type MattermostReaction = {
@@ -1648,6 +1654,8 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
});
const draftPreviewEnabled = account.streamingMode !== "off";
const draftToolProgressEnabled = shouldUpdateMattermostDraftToolProgress(account);
const suppressDefaultToolProgressMessages =
shouldSuppressMattermostDefaultToolProgressMessages(account);
const draftStream = draftPreviewEnabled
? createMattermostDraftStream({
client,
@@ -1844,6 +1852,9 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
replyOptions: {
...replyOptions,
disableBlockStreaming: true,
...(suppressDefaultToolProgressMessages
? { suppressDefaultToolProgressMessages: true }
: {}),
onModelSelected,
onPartialReply: (payload) => {
if (account.streamingMode !== "progress") {