feat: wire multi-agent config and routing

Co-authored-by: Mark Pors <1078320+pors@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-01-09 12:44:23 +00:00
parent 81beda0772
commit 7b81d97ec2
189 changed files with 4340 additions and 2903 deletions

View File

@@ -875,7 +875,7 @@ describe("web auto-reply", () => {
for (const fmt of formats) {
// Force a small cap to ensure compression is exercised for every format.
setLoadConfigMock(() => ({ agent: { mediaMaxMb: 1 } }));
setLoadConfigMock(() => ({ agents: { defaults: { mediaMaxMb: 1 } } }));
const sendMedia = vi.fn();
const reply = vi.fn().mockResolvedValue(undefined);
const sendComposing = vi.fn();
@@ -940,7 +940,7 @@ describe("web auto-reply", () => {
);
it("honors mediaMaxMb from config", async () => {
setLoadConfigMock(() => ({ agent: { mediaMaxMb: 1 } }));
setLoadConfigMock(() => ({ agents: { defaults: { mediaMaxMb: 1 } } }));
const sendMedia = vi.fn();
const reply = vi.fn().mockResolvedValue(undefined);
const sendComposing = vi.fn();
@@ -1182,21 +1182,26 @@ describe("web auto-reply", () => {
allowFrom: ["*"],
groups: { "*": { requireMention: true } },
},
routing: {
messages: {
groupChat: { mentionPatterns: ["@global"] },
agents: {
work: { mentionPatterns: ["@workbot"] },
},
bindings: [
},
agents: {
list: [
{
agentId: "work",
match: {
provider: "whatsapp",
peer: { kind: "group", id: "123@g.us" },
},
id: "work",
groupChat: { mentionPatterns: ["@workbot"] },
},
],
},
bindings: [
{
agentId: "work",
match: {
provider: "whatsapp",
peer: { kind: "group", id: "123@g.us" },
},
},
],
}));
let capturedOnMessage:
@@ -1260,7 +1265,7 @@ describe("web auto-reply", () => {
allowFrom: ["*"],
groups: { "*": { requireMention: false } },
},
routing: { groupChat: { mentionPatterns: ["@clawd"] } },
messages: { groupChat: { mentionPatterns: ["@clawd"] } },
}));
let capturedOnMessage:
@@ -1309,7 +1314,7 @@ describe("web auto-reply", () => {
allowFrom: ["*"],
groups: { "999@g.us": { requireMention: false } },
},
routing: { groupChat: { mentionPatterns: ["@clawd"] } },
messages: { groupChat: { mentionPatterns: ["@clawd"] } },
}));
let capturedOnMessage:
@@ -1363,7 +1368,7 @@ describe("web auto-reply", () => {
"123@g.us": { requireMention: false },
},
},
routing: { groupChat: { mentionPatterns: ["@clawd"] } },
messages: { groupChat: { mentionPatterns: ["@clawd"] } },
}));
let capturedOnMessage:
@@ -1419,7 +1424,7 @@ describe("web auto-reply", () => {
});
setLoadConfigMock(() => ({
routing: {
messages: {
groupChat: { mentionPatterns: ["@clawd"] },
},
session: { store: storePath },
@@ -1498,7 +1503,7 @@ describe("web auto-reply", () => {
allowFrom: ["+999"],
groups: { "*": { requireMention: true } },
},
routing: {
messages: {
groupChat: {
mentionPatterns: ["\\bclawd\\b"],
},

View File

@@ -341,7 +341,7 @@ export async function runWebHeartbeatOnce(opts: {
const replyResult = await replyResolver(
{
Body: resolveHeartbeatPrompt(cfg.agent?.heartbeat?.prompt),
Body: resolveHeartbeatPrompt(cfg.agents?.defaults?.heartbeat?.prompt),
From: to,
To: to,
MessageSid: sessionId ?? sessionSnapshot.entry?.sessionId,
@@ -377,7 +377,8 @@ export async function runWebHeartbeatOnce(opts: {
);
const ackMaxChars = Math.max(
0,
cfg.agent?.heartbeat?.ackMaxChars ?? DEFAULT_HEARTBEAT_ACK_MAX_CHARS,
cfg.agents?.defaults?.heartbeat?.ackMaxChars ??
DEFAULT_HEARTBEAT_ACK_MAX_CHARS,
);
const stripped = stripHeartbeatToken(replyPayload.text, {
mode: "heartbeat",
@@ -786,7 +787,7 @@ export async function monitorWebProvider(
groups: account.groups,
},
} satisfies ReturnType<typeof loadConfig>;
const configuredMaxMb = cfg.agent?.mediaMaxMb;
const configuredMaxMb = cfg.agents?.defaults?.mediaMaxMb;
const maxMediaBytes =
typeof configuredMaxMb === "number" && configuredMaxMb > 0
? configuredMaxMb * 1024 * 1024
@@ -800,7 +801,7 @@ export async function monitorWebProvider(
buildMentionConfig(cfg, agentId);
const baseMentionConfig = resolveMentionConfig();
const groupHistoryLimit =
cfg.routing?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT;
cfg.messages?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT;
const groupHistories = new Map<
string,
Array<{ sender: string; body: string; timestamp?: number }>

View File

@@ -1081,7 +1081,7 @@ describe("web monitor inbox", () => {
// Reset mock for other tests
mockLoadConfig.mockReturnValue({
routing: {
whatsapp: {
allowFrom: ["*"],
},
messages: {