fix(mattermost): share progress draft labels

This commit is contained in:
Vincent Koc
2026-05-03 18:48:00 -07:00
parent 56b83230df
commit 90c0edcb61
3 changed files with 29 additions and 7 deletions

View File

@@ -54,6 +54,7 @@ Docs: https://docs.openclaw.ai
- Agents/messaging: deliver distinct final commentary after same-target `message` tool sends while still deduping text/media already sent by the tool, so short closing remarks are no longer silently dropped. Fixes #76915. Thanks @hclsys.
- Agents/messaging: preserve string thread IDs when matching message-tool reply dedupe routes, avoiding precision loss on numeric-looking topic IDs before channel plugin comparison. Thanks @vincentkoc.
- Channels/streaming: honor `agents.defaults.toolProgressDetail: "raw"` in Slack, Discord, Telegram, Matrix, and Microsoft Teams progress drafts, so tool-start lines include raw command/detail output when debugging. 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.
- 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

@@ -243,11 +243,17 @@ describe("createMattermostDraftStream", () => {
});
describe("buildMattermostToolStatusText", () => {
it("renders a status with the tool name", () => {
expect(buildMattermostToolStatusText({ name: "read" })).toBe("Running `read`…");
it("renders a status with the shared tool label", () => {
expect(buildMattermostToolStatusText({ name: "read" })).toBe("📖 Read");
});
it("falls back to a generic running tool status", () => {
expect(buildMattermostToolStatusText({ name: "exec" })).toBe("Running `exec`…");
it("honors raw exec detail mode", () => {
expect(
buildMattermostToolStatusText({
name: "exec",
args: { command: "pnpm test -- --watch=false" },
detailMode: "raw",
}),
).toBe("🛠️ Exec: run tests, `pnpm test -- --watch=false`");
});
});

View File

@@ -1,4 +1,5 @@
import { createFinalizableDraftLifecycle } from "openclaw/plugin-sdk/channel-lifecycle";
import { formatChannelProgressDraftLine } from "openclaw/plugin-sdk/channel-streaming";
import {
createMattermostPost,
deleteMattermostPost,
@@ -31,9 +32,23 @@ function normalizeMattermostDraftText(text: string, maxChars: number): string {
return `${trimmed.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
}
export function buildMattermostToolStatusText(params: { name?: string; phase?: string }): string {
const tool = params.name?.trim() ? ` \`${params.name.trim()}\`` : " tool";
return `Running${tool}`;
export function buildMattermostToolStatusText(params: {
name?: string;
phase?: string;
args?: Record<string, unknown>;
detailMode?: "explain" | "raw";
}): string {
return (
formatChannelProgressDraftLine(
{
event: "tool",
name: params.name,
phase: params.phase,
args: params.args,
},
params.detailMode ? { detailMode: params.detailMode } : undefined,
) ?? "Running tool..."
);
}
export function createMattermostDraftStream(params: {