Skip to content

Commit 6016e22

Browse files
committed
refactor(discord): compose native command routes
1 parent 547436b commit 6016e22

File tree

3 files changed

+87
-23
lines changed

3 files changed

+87
-23
lines changed

src/discord/monitor/native-command.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ import {
8585
import { buildDiscordNativeCommandContext } from "./native-command-context.js";
8686
import { resolveDiscordNativeCommandSessionTargets } from "./native-command-session-targets.js";
8787
import {
88-
buildDiscordRoutePeer,
89-
resolveDiscordConversationRoute,
88+
resolveDiscordBoundConversationRoute,
9089
resolveDiscordEffectiveRoute,
9190
} from "./route-resolution.js";
9291
import { resolveDiscordSenderIdentity } from "./sender-identity.js";
@@ -451,25 +450,19 @@ async function resolveDiscordModelPickerRoute(params: {
451450
threadParentId = parentInfo.id;
452451
}
453452

454-
const route = resolveDiscordConversationRoute({
453+
const threadBinding = isThreadChannel
454+
? params.threadBindings.getByThreadId(rawChannelId)
455+
: undefined;
456+
return resolveDiscordBoundConversationRoute({
455457
cfg,
456458
accountId,
457459
guildId: interaction.guild?.id ?? undefined,
458460
memberRoleIds,
459-
peer: buildDiscordRoutePeer({
460-
isDirectMessage,
461-
isGroupDm,
462-
directUserId: interaction.user?.id ?? rawChannelId,
463-
conversationId: rawChannelId,
464-
}),
461+
isDirectMessage,
462+
isGroupDm,
463+
directUserId: interaction.user?.id ?? rawChannelId,
464+
conversationId: rawChannelId,
465465
parentConversationId: threadParentId,
466-
});
467-
468-
const threadBinding = isThreadChannel
469-
? params.threadBindings.getByThreadId(rawChannelId)
470-
: undefined;
471-
return resolveDiscordEffectiveRoute({
472-
route,
473466
boundSessionKey: threadBinding?.targetSessionKey,
474467
});
475468
}
@@ -1605,18 +1598,18 @@ async function dispatchDiscordCommandInteraction(params: {
16051598
const isGuild = Boolean(interaction.guild);
16061599
const channelId = rawChannelId || "unknown";
16071600
const interactionId = interaction.rawData.id;
1608-
const route = resolveDiscordConversationRoute({
1601+
const route = resolveDiscordBoundConversationRoute({
16091602
cfg,
16101603
accountId,
16111604
guildId: interaction.guild?.id ?? undefined,
16121605
memberRoleIds,
1613-
peer: buildDiscordRoutePeer({
1614-
isDirectMessage,
1615-
isGroupDm,
1616-
directUserId: user.id,
1617-
conversationId: channelId,
1618-
}),
1606+
isDirectMessage,
1607+
isGroupDm,
1608+
directUserId: user.id,
1609+
conversationId: channelId,
16191610
parentConversationId: threadParentId,
1611+
// Configured ACP routes apply after raw route resolution, so do not pass
1612+
// bound/configured overrides here.
16201613
});
16211614
const threadBinding = isThreadChannel ? threadBindings.getByThreadId(rawChannelId) : undefined;
16221615
const configuredRoute =

src/discord/monitor/route-resolution.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
22
import type { OpenClawConfig } from "../../config/config.js";
33
import type { ResolvedAgentRoute } from "../../routing/resolve-route.js";
44
import {
5+
resolveDiscordBoundConversationRoute,
56
buildDiscordRoutePeer,
67
resolveDiscordConversationRoute,
78
resolveDiscordEffectiveRoute,
@@ -104,4 +105,39 @@ describe("discord route resolution helpers", () => {
104105
matchedBy: "binding.peer",
105106
});
106107
});
108+
109+
it("composes route building with effective-route overrides", () => {
110+
const cfg: OpenClawConfig = {
111+
agents: {
112+
list: [{ id: "worker" }],
113+
},
114+
bindings: [
115+
{
116+
agentId: "worker",
117+
match: {
118+
channel: "discord",
119+
accountId: "default",
120+
peer: { kind: "direct", id: "user-1" },
121+
},
122+
},
123+
],
124+
};
125+
126+
expect(
127+
resolveDiscordBoundConversationRoute({
128+
cfg,
129+
accountId: "default",
130+
isDirectMessage: true,
131+
isGroupDm: false,
132+
directUserId: "user-1",
133+
conversationId: "dm-1",
134+
boundSessionKey: "agent:worker:discord:direct:user-1",
135+
matchedBy: "binding.channel",
136+
}),
137+
).toMatchObject({
138+
agentId: "worker",
139+
sessionKey: "agent:worker:discord:direct:user-1",
140+
matchedBy: "binding.channel",
141+
});
142+
});
107143
});

src/discord/monitor/route-resolution.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,41 @@ export function resolveDiscordConversationRoute(params: {
4141
});
4242
}
4343

44+
export function resolveDiscordBoundConversationRoute(params: {
45+
cfg: OpenClawConfig;
46+
accountId?: string | null;
47+
guildId?: string | null;
48+
memberRoleIds?: string[];
49+
isDirectMessage: boolean;
50+
isGroupDm: boolean;
51+
directUserId?: string | null;
52+
conversationId: string;
53+
parentConversationId?: string | null;
54+
boundSessionKey?: string | null;
55+
configuredRoute?: { route: ResolvedAgentRoute } | null;
56+
matchedBy?: ResolvedAgentRoute["matchedBy"];
57+
}): ResolvedAgentRoute {
58+
const route = resolveDiscordConversationRoute({
59+
cfg: params.cfg,
60+
accountId: params.accountId,
61+
guildId: params.guildId,
62+
memberRoleIds: params.memberRoleIds,
63+
peer: buildDiscordRoutePeer({
64+
isDirectMessage: params.isDirectMessage,
65+
isGroupDm: params.isGroupDm,
66+
directUserId: params.directUserId,
67+
conversationId: params.conversationId,
68+
}),
69+
parentConversationId: params.parentConversationId,
70+
});
71+
return resolveDiscordEffectiveRoute({
72+
route,
73+
boundSessionKey: params.boundSessionKey,
74+
configuredRoute: params.configuredRoute,
75+
matchedBy: params.matchedBy,
76+
});
77+
}
78+
4479
export function resolveDiscordEffectiveRoute(params: {
4580
route: ResolvedAgentRoute;
4681
boundSessionKey?: string | null;

0 commit comments

Comments
 (0)