Files
openclaw/src/config/config.telegram-topic-agentid.test.ts
Evgeny Zislis 58bc9a241b feat(telegram): add per-topic agent routing for forum groups [AI-assisted]
This feature allows different topics within a Telegram forum supergroup to route
to different agents, each with isolated workspace, memory, and sessions.

Key changes:
- Add agentId field to TelegramTopicConfig type for per-topic routing
- Add zod validation for agentId in topic config schema
- Implement routing logic to re-derive session key with topic's agent
- Add debug logging for topic agent overrides
- Add unit tests for routing behavior (forum topics + DM topics)
- Add config validation tests
- Document feature in docs/channels/telegram.md

This builds on the approach from PR #31513 by @Sid-Qin with additional fixes
for security (preserved account fail-closed guard) and test coverage.

Closes #31473
2026-03-04 09:35:53 +05:30

136 lines
3.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { OpenClawSchema } from "./zod-schema.js";
describe("telegram topic agentId schema", () => {
it("accepts valid agentId in forum group topic config", () => {
const res = OpenClawSchema.safeParse({
channels: {
telegram: {
groups: {
"-1001234567890": {
topics: {
"42": {
agentId: "main",
},
},
},
},
},
},
});
expect(res.success).toBe(true);
if (!res.success) {
console.error(res.error.format());
return;
}
expect(res.data.channels?.telegram?.groups?.["-1001234567890"]?.topics?.["42"]?.agentId).toBe(
"main",
);
});
it("accepts valid agentId in DM topic config", () => {
const res = OpenClawSchema.safeParse({
channels: {
telegram: {
direct: {
"123456789": {
topics: {
"99": {
agentId: "support",
systemPrompt: "You are support",
},
},
},
},
},
},
});
expect(res.success).toBe(true);
if (!res.success) {
console.error(res.error.format());
return;
}
expect(res.data.channels?.telegram?.direct?.["123456789"]?.topics?.["99"]?.agentId).toBe(
"support",
);
});
it("accepts empty config without agentId (backward compatible)", () => {
const res = OpenClawSchema.safeParse({
channels: {
telegram: {
groups: {
"-1001234567890": {
topics: {
"42": {
systemPrompt: "Be helpful",
},
},
},
},
},
},
});
expect(res.success).toBe(true);
if (!res.success) {
console.error(res.error.format());
return;
}
expect(res.data.channels?.telegram?.groups?.["-1001234567890"]?.topics?.["42"]).toEqual({
systemPrompt: "Be helpful",
});
});
it("accepts multiple topics with different agentIds", () => {
const res = OpenClawSchema.safeParse({
channels: {
telegram: {
groups: {
"-1001234567890": {
topics: {
"1": { agentId: "main" },
"3": { agentId: "zu" },
"5": { agentId: "q" },
},
},
},
},
},
});
expect(res.success).toBe(true);
if (!res.success) {
console.error(res.error.format());
return;
}
const topics = res.data.channels?.telegram?.groups?.["-1001234567890"]?.topics;
expect(topics?.["1"]?.agentId).toBe("main");
expect(topics?.["3"]?.agentId).toBe("zu");
expect(topics?.["5"]?.agentId).toBe("q");
});
it("rejects unknown fields in topic config (strict schema)", () => {
const res = OpenClawSchema.safeParse({
channels: {
telegram: {
groups: {
"-1001234567890": {
topics: {
"42": {
agentId: "main",
unknownField: "should fail",
},
},
},
},
},
},
});
expect(res.success).toBe(false);
});
});