mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 04:20:34 +00:00
matrix-js: improve thread context and auto-threading
This commit is contained in:
@@ -370,6 +370,12 @@ export type ChannelThreadingToolContext = {
|
||||
currentChannelProvider?: ChannelId;
|
||||
currentThreadTs?: string;
|
||||
currentMessageId?: string | number;
|
||||
/**
|
||||
* Optional direct-chat participant identifier for channels whose outbound
|
||||
* tool targets can address either the backing conversation id or the direct
|
||||
* participant id.
|
||||
*/
|
||||
currentDirectUserId?: string;
|
||||
replyToMode?: "off" | "first" | "all";
|
||||
hasRepliedRef?: { value: boolean };
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { matrixPlugin } from "../../../extensions/matrix-js/src/channel.js";
|
||||
import { setMatrixRuntime } from "../../../extensions/matrix-js/src/runtime.js";
|
||||
import { slackPlugin } from "../../../extensions/slack/src/channel.js";
|
||||
import { setSlackRuntime } from "../../../extensions/slack/src/runtime.js";
|
||||
import { telegramPlugin } from "../../../extensions/telegram/src/channel.js";
|
||||
import { setTelegramRuntime } from "../../../extensions/telegram/src/runtime.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||
import { createPluginRuntime } from "../../plugins/runtime/index.js";
|
||||
import { createTestRegistry } from "../../test-utils/channel-plugins.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
executeSendAction: vi.fn(),
|
||||
recordSessionMetaFromInbound: vi.fn(async () => ({ ok: true })),
|
||||
@@ -34,6 +45,15 @@ let resetMessageActionRunnerTestRegistry: MessageActionRunnerTestHelpersModule["
|
||||
let slackConfig: MessageActionRunnerTestHelpersModule["slackConfig"];
|
||||
let telegramConfig: MessageActionRunnerTestHelpersModule["telegramConfig"];
|
||||
|
||||
const matrixConfig = {
|
||||
channels: {
|
||||
"matrix-js": {
|
||||
homeserver: "https://matrix.example.org",
|
||||
accessToken: "matrix-test",
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
async function runThreadingAction(params: {
|
||||
cfg: MessageActionRunnerTestHelpersModule["slackConfig"];
|
||||
actionParams: Record<string, unknown>;
|
||||
@@ -65,7 +85,25 @@ const defaultTelegramToolContext = {
|
||||
currentThreadTs: "42",
|
||||
} as const;
|
||||
|
||||
const defaultMatrixToolContext = {
|
||||
currentChannelId: "room:!room:example.org",
|
||||
currentThreadTs: "$thread",
|
||||
} as const;
|
||||
|
||||
const defaultMatrixDmToolContext = {
|
||||
currentChannelId: "room:!dm:example.org",
|
||||
currentThreadTs: "$thread",
|
||||
currentDirectUserId: "@alice:example.org",
|
||||
} as const;
|
||||
|
||||
describe("runMessageAction threading auto-injection", () => {
|
||||
beforeAll(() => {
|
||||
const runtime = createPluginRuntime();
|
||||
setMatrixRuntime(runtime);
|
||||
setSlackRuntime(runtime);
|
||||
setTelegramRuntime(runtime);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
({ runMessageAction } = await import("./message-action-runner.js"));
|
||||
@@ -76,6 +114,25 @@ describe("runMessageAction threading auto-injection", () => {
|
||||
telegramConfig,
|
||||
} = await import("./message-action-runner.test-helpers.js"));
|
||||
installMessageActionRunnerTestRegistry();
|
||||
setActivePluginRegistry(
|
||||
createTestRegistry([
|
||||
{
|
||||
pluginId: "matrix-js",
|
||||
source: "test",
|
||||
plugin: matrixPlugin,
|
||||
},
|
||||
{
|
||||
pluginId: "slack",
|
||||
source: "test",
|
||||
plugin: slackPlugin,
|
||||
},
|
||||
{
|
||||
pluginId: "telegram",
|
||||
source: "test",
|
||||
plugin: telegramPlugin,
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -188,4 +245,96 @@ describe("runMessageAction threading auto-injection", () => {
|
||||
expect(call?.replyToId).toBe("777");
|
||||
expect(call?.ctx?.params?.replyTo).toBe("777");
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "injects threadId for bare room id",
|
||||
target: "!room:example.org",
|
||||
expectedThreadId: "$thread",
|
||||
},
|
||||
{
|
||||
name: "injects threadId for room target prefix",
|
||||
target: "room:!room:example.org",
|
||||
expectedThreadId: "$thread",
|
||||
},
|
||||
{
|
||||
name: "injects threadId for matrix room target",
|
||||
target: "matrix:room:!room:example.org",
|
||||
expectedThreadId: "$thread",
|
||||
},
|
||||
{
|
||||
name: "skips threadId when target room differs",
|
||||
target: "!other:example.org",
|
||||
expectedThreadId: undefined,
|
||||
},
|
||||
] as const)("matrix auto-threading: $name", async (testCase) => {
|
||||
mockHandledSendAction();
|
||||
|
||||
const call = await runThreadingAction({
|
||||
cfg: matrixConfig,
|
||||
actionParams: {
|
||||
channel: "matrix-js",
|
||||
target: testCase.target,
|
||||
message: "hi",
|
||||
},
|
||||
toolContext: defaultMatrixToolContext,
|
||||
});
|
||||
|
||||
expect(call?.ctx?.params?.threadId).toBe(testCase.expectedThreadId);
|
||||
if (testCase.expectedThreadId !== undefined) {
|
||||
expect(call?.threadId).toBe(testCase.expectedThreadId);
|
||||
}
|
||||
});
|
||||
|
||||
it("uses explicit matrix threadId when provided", async () => {
|
||||
mockHandledSendAction();
|
||||
|
||||
const call = await runThreadingAction({
|
||||
cfg: matrixConfig,
|
||||
actionParams: {
|
||||
channel: "matrix-js",
|
||||
target: "room:!room:example.org",
|
||||
message: "hi",
|
||||
threadId: "$explicit",
|
||||
},
|
||||
toolContext: defaultMatrixToolContext,
|
||||
});
|
||||
|
||||
expect(call?.threadId).toBe("$explicit");
|
||||
expect(call?.ctx?.params?.threadId).toBe("$explicit");
|
||||
});
|
||||
|
||||
it("injects threadId for matching Matrix dm user target", async () => {
|
||||
mockHandledSendAction();
|
||||
|
||||
const call = await runThreadingAction({
|
||||
cfg: matrixConfig,
|
||||
actionParams: {
|
||||
channel: "matrix-js",
|
||||
target: "user:@alice:example.org",
|
||||
message: "hi",
|
||||
},
|
||||
toolContext: defaultMatrixDmToolContext,
|
||||
});
|
||||
|
||||
expect(call?.threadId).toBe("$thread");
|
||||
expect(call?.ctx?.params?.threadId).toBe("$thread");
|
||||
});
|
||||
|
||||
it("skips threadId for different Matrix dm user target", async () => {
|
||||
mockHandledSendAction();
|
||||
|
||||
const call = await runThreadingAction({
|
||||
cfg: matrixConfig,
|
||||
actionParams: {
|
||||
channel: "matrix-js",
|
||||
target: "user:@bob:example.org",
|
||||
message: "hi",
|
||||
},
|
||||
toolContext: defaultMatrixDmToolContext,
|
||||
});
|
||||
|
||||
expect(call?.threadId).toBeUndefined();
|
||||
expect(call?.ctx?.params?.threadId).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user