fix(telegram): honor topic requireMention precedence

Telegram forum-topic requireMention config now takes precedence over persisted activation state, with focused regression coverage.\n\nFixes #49864.\nThanks @Panniantong.
This commit is contained in:
Pnant
2026-05-04 14:53:06 -07:00
committed by GitHub
parent d0cae0d950
commit a7b665cfed
3 changed files with 114 additions and 1 deletions

View File

@@ -76,6 +76,7 @@ Docs: https://docs.openclaw.ai
- active-memory: skip the memory sub-agent gracefully instead of logging a confusing allowlist error when no memory plugin (`memory-core` or `memory-lancedb`) is loaded, so active-memory with no memory backend no longer produces misleading "No callable tools remain" warnings in the gateway log. Fixes #77506. Thanks @hclsys.
- Memory/wiki: preserve representation from both corpora in `corpus=all` searches while backfilling unused result capacity, so memory hits are not starved by numerically higher wiki integer scores. Fixes #77337. Thanks @hclsys.
- Telegram: clean up tool-only draft previews after assistant message boundaries so transient `Surfacing...` tool-status bubbles do not linger when no matching final preview arrives. Thanks @BunsDev.
- Telegram: let explicit forum-topic `requireMention` settings override persisted `/activate` and `/deactivate` state, so per-topic mention gates work consistently. Fixes #49864. Thanks @Panniantong.
- Cron: surface failed isolated-run diagnostics in `cron show`, status, and run history when requested tools are unavailable, so blocked cron runs report the actual tool-policy failure instead of a misleading green result. Fixes #75763. Thanks @RyanSandoval.
- TUI/escape abort: track the in-flight runId after `chat.send` resolves so pressing Esc during the gap before the first gateway event aborts the run instead of repeatedly printing `no active run`. Fixes #1296. Thanks @Lukavyi and @romneyda.
- TUI/render: stop the long-token sanitizer from injecting literal spaces inside inline code spans, fenced code blocks, table borders, and bare hyphenated/dotted identifiers, so copied package names, entity IDs, and shell line-continuations stay byte-for-byte intact while narrow-terminal protection still chunks unidentifiable long prose tokens. Fixes #48432, #39505. Thanks @DocOellerson, @xeusoc, @CCcassiusdjs, @akramcodez, @brokemac79, @romneyda.

View File

@@ -0,0 +1,112 @@
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
import { beforeEach, describe, expect, it, vi } from "vitest";
const { defaultRouteConfig } = vi.hoisted(() => ({
defaultRouteConfig: {
agents: {
list: [{ id: "main", default: true }],
},
channels: { telegram: {} },
messages: { groupChat: { mentionPatterns: [] } },
},
}));
vi.mock("openclaw/plugin-sdk/runtime-config-snapshot", async () => {
const actual = await vi.importActual<
typeof import("openclaw/plugin-sdk/runtime-config-snapshot")
>("openclaw/plugin-sdk/runtime-config-snapshot");
return {
...actual,
getRuntimeConfig: vi.fn(() => defaultRouteConfig),
};
});
const { buildTelegramMessageContextForTest } =
await import("./bot-message-context.test-harness.js");
describe("buildTelegramMessageContext requireMention precedence", () => {
function buildForumMessage(threadId = 99) {
return {
message_id: 1,
chat: {
id: -1001234567890,
type: "supergroup" as const,
title: "Forum",
is_forum: true,
},
date: 1_700_000_000,
text: "hello everyone",
message_thread_id: threadId,
from: { id: 42, first_name: "Alice" },
};
}
beforeEach(() => {
vi.mocked(getRuntimeConfig).mockReturnValue(defaultRouteConfig as never);
});
it("lets explicit topic requireMention=false override group requireMention=true", async () => {
const ctx = await buildTelegramMessageContextForTest({
message: buildForumMessage(),
resolveGroupActivation: () => undefined,
resolveGroupRequireMention: () => true,
resolveTelegramGroupConfig: () => ({
groupConfig: { requireMention: true },
topicConfig: { requireMention: false },
}),
});
expect(ctx).not.toBeNull();
});
it("lets explicit topic requireMention=false override mention activation", async () => {
const resolveGroupActivation = vi.fn(() => true);
const ctx = await buildTelegramMessageContextForTest({
message: buildForumMessage(),
resolveGroupActivation,
resolveGroupRequireMention: () => true,
resolveTelegramGroupConfig: () => ({
groupConfig: { requireMention: true },
topicConfig: { requireMention: false },
}),
});
expect(ctx).not.toBeNull();
expect(resolveGroupActivation).toHaveBeenCalledWith(
expect.objectContaining({
chatId: -1001234567890,
messageThreadId: 99,
sessionKey: "agent:main:telegram:group:-1001234567890:topic:99",
}),
);
});
it("lets explicit topic requireMention=true override always activation", async () => {
const ctx = await buildTelegramMessageContextForTest({
message: buildForumMessage(),
resolveGroupActivation: () => false,
resolveGroupRequireMention: () => false,
resolveTelegramGroupConfig: () => ({
groupConfig: { requireMention: false },
topicConfig: { requireMention: true },
}),
});
expect(ctx).toBeNull();
});
it("keeps activation fallback when no topic requireMention is configured", async () => {
const ctx = await buildTelegramMessageContextForTest({
message: buildForumMessage(),
resolveGroupActivation: () => false,
resolveGroupRequireMention: () => true,
resolveTelegramGroupConfig: () => ({
groupConfig: { requireMention: true },
topicConfig: { agentId: "main" },
}),
});
expect(ctx).not.toBeNull();
});
});

View File

@@ -411,8 +411,8 @@ export const buildTelegramMessageContext = async ({
});
const baseRequireMention = resolveGroupRequireMention(chatId);
const requireMention = firstDefined(
activationOverride,
topicConfig?.requireMention,
activationOverride,
telegramGroupConfig?.requireMention,
baseRequireMention,
);