mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 06:44:01 +02:00
fix(mattermost): dedupe repeated model picker selects
This commit is contained in:
@@ -3,6 +3,7 @@ import { describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../runtime-api.js";
|
||||
import { resolveMattermostAccount } from "./accounts.js";
|
||||
import {
|
||||
buildMattermostModelPickerSelectMessageSid,
|
||||
evaluateMattermostMentionGate,
|
||||
MattermostRetryableInboundError,
|
||||
processMattermostReplayGuardedPost,
|
||||
@@ -378,6 +379,41 @@ describe("processMattermostReplayGuardedPost", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildMattermostModelPickerSelectMessageSid", () => {
|
||||
it("stays stable for the same picker selection", () => {
|
||||
expect(
|
||||
buildMattermostModelPickerSelectMessageSid({
|
||||
postId: "post-1",
|
||||
provider: "OpenAI",
|
||||
model: " GPT-5 ",
|
||||
}),
|
||||
).toBe("interaction:post-1:select:openai/gpt-5");
|
||||
expect(
|
||||
buildMattermostModelPickerSelectMessageSid({
|
||||
postId: "post-1",
|
||||
provider: "openai",
|
||||
model: "gpt-5",
|
||||
}),
|
||||
).toBe("interaction:post-1:select:openai/gpt-5");
|
||||
});
|
||||
|
||||
it("keeps different model selections distinct", () => {
|
||||
expect(
|
||||
buildMattermostModelPickerSelectMessageSid({
|
||||
postId: "post-1",
|
||||
provider: "openai",
|
||||
model: "gpt-5",
|
||||
}),
|
||||
).not.toBe(
|
||||
buildMattermostModelPickerSelectMessageSid({
|
||||
postId: "post-1",
|
||||
provider: "openai",
|
||||
model: "gpt-4.1",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveMattermostReactionChannelId", () => {
|
||||
it("prefers broadcast channel_id when present", () => {
|
||||
expect(
|
||||
|
||||
@@ -139,6 +139,16 @@ export class MattermostRetryableInboundError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildMattermostModelPickerSelectMessageSid(params: {
|
||||
postId: string;
|
||||
provider: string;
|
||||
model: string;
|
||||
}): string {
|
||||
const provider = normalizeLowercaseStringOrEmpty(params.provider);
|
||||
const model = normalizeLowercaseStringOrEmpty(params.model);
|
||||
return `interaction:${params.postId}:select:${provider}/${model}`;
|
||||
}
|
||||
|
||||
function buildMattermostInboundReplayKeys(params: {
|
||||
accountId: string;
|
||||
messageIds: string[];
|
||||
@@ -698,6 +708,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
roomLabel: string;
|
||||
teamId?: string;
|
||||
postId: string;
|
||||
messageSid?: string;
|
||||
effectiveReplyToId?: string;
|
||||
deliverReplies?: boolean;
|
||||
}): Promise<string> => {
|
||||
@@ -731,7 +742,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
SenderId: params.senderId,
|
||||
Provider: "mattermost" as const,
|
||||
Surface: "mattermost" as const,
|
||||
MessageSid: `interaction:${params.postId}:${Date.now()}`,
|
||||
MessageSid: params.messageSid ?? `interaction:${params.postId}:${Date.now()}`,
|
||||
ReplyToId: params.effectiveReplyToId,
|
||||
MessageThreadId: params.effectiveReplyToId,
|
||||
Timestamp: Date.now(),
|
||||
@@ -1023,6 +1034,11 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
roomLabel,
|
||||
teamId,
|
||||
postId: params.payload.post_id,
|
||||
messageSid: buildMattermostModelPickerSelectMessageSid({
|
||||
postId: params.payload.post_id,
|
||||
provider: pickerState.provider,
|
||||
model: pickerState.model,
|
||||
}),
|
||||
effectiveReplyToId: threadContext.effectiveReplyToId,
|
||||
deliverReplies: true,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user