mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-11 17:43:56 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
|
|
@ -0,0 +1,147 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js";
|
||||
import { TELEGRAM_FORUM_SERVICE_FIELDS } from "./forum-service-message.js";
|
||||
|
||||
describe("buildTelegramMessageContext implicitMention forum service messages", () => {
|
||||
/**
|
||||
* Build a group message context where the user sends a message inside a
|
||||
* forum topic that has `reply_to_message` pointing to a message from the
|
||||
* bot. Callers control whether the reply target looks like a forum service
|
||||
* message (carries `forum_topic_created` etc.) or a real bot reply.
|
||||
*/
|
||||
async function buildGroupReplyCtx(params: {
|
||||
replyToMessageText?: string;
|
||||
replyToMessageCaption?: string;
|
||||
replyFromIsBot?: boolean;
|
||||
replyFromId?: number;
|
||||
/** Extra fields on reply_to_message (e.g. forum_topic_created). */
|
||||
replyToMessageExtra?: Record<string, unknown>;
|
||||
}) {
|
||||
const BOT_ID = 7; // matches test harness primaryCtx.me.id
|
||||
return await buildTelegramMessageContextForTest({
|
||||
message: {
|
||||
message_id: 100,
|
||||
chat: { id: -1001234567890, type: "supergroup", title: "Forum Group" },
|
||||
date: 1700000000,
|
||||
text: "hello everyone",
|
||||
from: { id: 42, first_name: "Alice" },
|
||||
reply_to_message: {
|
||||
message_id: 1,
|
||||
text: params.replyToMessageText ?? undefined,
|
||||
...(params.replyToMessageCaption != null
|
||||
? { caption: params.replyToMessageCaption }
|
||||
: {}),
|
||||
from: {
|
||||
id: params.replyFromId ?? BOT_ID,
|
||||
first_name: "OpenClaw",
|
||||
is_bot: params.replyFromIsBot ?? true,
|
||||
},
|
||||
...params.replyToMessageExtra,
|
||||
},
|
||||
},
|
||||
resolveGroupActivation: () => true,
|
||||
resolveGroupRequireMention: () => true,
|
||||
resolveTelegramGroupConfig: () => ({
|
||||
groupConfig: { requireMention: true },
|
||||
topicConfig: undefined,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
it("does NOT trigger implicitMention for forum_topic_created service message", async () => {
|
||||
// Bot auto-generated "Topic created" message carries forum_topic_created.
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyFromIsBot: true,
|
||||
replyToMessageExtra: {
|
||||
forum_topic_created: { name: "New Topic", icon_color: 0x6fb9f0 },
|
||||
},
|
||||
});
|
||||
|
||||
// With requireMention and no explicit @mention, the message should be
|
||||
// skipped (null) because implicitMention should NOT fire.
|
||||
expect(ctx).toBeNull();
|
||||
});
|
||||
|
||||
it.each(TELEGRAM_FORUM_SERVICE_FIELDS)(
|
||||
"does NOT trigger implicitMention for %s service message",
|
||||
async (field) => {
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyFromIsBot: true,
|
||||
replyToMessageExtra: { [field]: {} },
|
||||
});
|
||||
|
||||
expect(ctx).toBeNull();
|
||||
},
|
||||
);
|
||||
|
||||
it("does NOT trigger implicitMention for forum_topic_closed service message", async () => {
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyFromIsBot: true,
|
||||
replyToMessageExtra: { forum_topic_closed: {} },
|
||||
});
|
||||
|
||||
expect(ctx).toBeNull();
|
||||
});
|
||||
|
||||
it("does NOT trigger implicitMention for general_forum_topic_hidden service message", async () => {
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyFromIsBot: true,
|
||||
replyToMessageExtra: { general_forum_topic_hidden: {} },
|
||||
});
|
||||
|
||||
expect(ctx).toBeNull();
|
||||
});
|
||||
|
||||
it("DOES trigger implicitMention for real bot replies (non-empty text)", async () => {
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: "Here is my answer",
|
||||
replyFromIsBot: true,
|
||||
});
|
||||
|
||||
// Real bot reply → implicitMention fires → message is NOT skipped.
|
||||
expect(ctx).not.toBeNull();
|
||||
expect(ctx?.ctxPayload?.WasMentioned).toBe(true);
|
||||
});
|
||||
|
||||
it("DOES trigger implicitMention for bot media messages with caption", async () => {
|
||||
// Media messages from the bot have caption but no text — they should
|
||||
// still count as real bot replies, not service messages.
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyToMessageCaption: "Check out this image",
|
||||
replyFromIsBot: true,
|
||||
});
|
||||
|
||||
expect(ctx).not.toBeNull();
|
||||
expect(ctx?.ctxPayload?.WasMentioned).toBe(true);
|
||||
});
|
||||
|
||||
it("DOES trigger implicitMention for bot sticker/voice (no text, no caption, no service field)", async () => {
|
||||
// Stickers, voice notes, and captionless photos have neither text nor
|
||||
// caption, but they are NOT service messages — they are legitimate bot
|
||||
// replies that should trigger implicitMention.
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: undefined,
|
||||
replyFromIsBot: true,
|
||||
// No forum_topic_* fields → not a service message
|
||||
});
|
||||
|
||||
expect(ctx).not.toBeNull();
|
||||
expect(ctx?.ctxPayload?.WasMentioned).toBe(true);
|
||||
});
|
||||
|
||||
it("does NOT trigger implicitMention when reply is from a different user", async () => {
|
||||
const ctx = await buildGroupReplyCtx({
|
||||
replyToMessageText: "some message",
|
||||
replyFromIsBot: false,
|
||||
replyFromId: 999,
|
||||
});
|
||||
|
||||
// Different user's message → not an implicit mention → skipped.
|
||||
expect(ctx).toBeNull();
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue