mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 23:08:28 +00:00
refactor(discord): compose native command routes
This commit is contained in:
@@ -85,8 +85,7 @@ import {
|
|||||||
import { buildDiscordNativeCommandContext } from "./native-command-context.js";
|
import { buildDiscordNativeCommandContext } from "./native-command-context.js";
|
||||||
import { resolveDiscordNativeCommandSessionTargets } from "./native-command-session-targets.js";
|
import { resolveDiscordNativeCommandSessionTargets } from "./native-command-session-targets.js";
|
||||||
import {
|
import {
|
||||||
buildDiscordRoutePeer,
|
resolveDiscordBoundConversationRoute,
|
||||||
resolveDiscordConversationRoute,
|
|
||||||
resolveDiscordEffectiveRoute,
|
resolveDiscordEffectiveRoute,
|
||||||
} from "./route-resolution.js";
|
} from "./route-resolution.js";
|
||||||
import { resolveDiscordSenderIdentity } from "./sender-identity.js";
|
import { resolveDiscordSenderIdentity } from "./sender-identity.js";
|
||||||
@@ -451,25 +450,19 @@ async function resolveDiscordModelPickerRoute(params: {
|
|||||||
threadParentId = parentInfo.id;
|
threadParentId = parentInfo.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = resolveDiscordConversationRoute({
|
const threadBinding = isThreadChannel
|
||||||
|
? params.threadBindings.getByThreadId(rawChannelId)
|
||||||
|
: undefined;
|
||||||
|
return resolveDiscordBoundConversationRoute({
|
||||||
cfg,
|
cfg,
|
||||||
accountId,
|
accountId,
|
||||||
guildId: interaction.guild?.id ?? undefined,
|
guildId: interaction.guild?.id ?? undefined,
|
||||||
memberRoleIds,
|
memberRoleIds,
|
||||||
peer: buildDiscordRoutePeer({
|
isDirectMessage,
|
||||||
isDirectMessage,
|
isGroupDm,
|
||||||
isGroupDm,
|
directUserId: interaction.user?.id ?? rawChannelId,
|
||||||
directUserId: interaction.user?.id ?? rawChannelId,
|
conversationId: rawChannelId,
|
||||||
conversationId: rawChannelId,
|
|
||||||
}),
|
|
||||||
parentConversationId: threadParentId,
|
parentConversationId: threadParentId,
|
||||||
});
|
|
||||||
|
|
||||||
const threadBinding = isThreadChannel
|
|
||||||
? params.threadBindings.getByThreadId(rawChannelId)
|
|
||||||
: undefined;
|
|
||||||
return resolveDiscordEffectiveRoute({
|
|
||||||
route,
|
|
||||||
boundSessionKey: threadBinding?.targetSessionKey,
|
boundSessionKey: threadBinding?.targetSessionKey,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1605,18 +1598,18 @@ async function dispatchDiscordCommandInteraction(params: {
|
|||||||
const isGuild = Boolean(interaction.guild);
|
const isGuild = Boolean(interaction.guild);
|
||||||
const channelId = rawChannelId || "unknown";
|
const channelId = rawChannelId || "unknown";
|
||||||
const interactionId = interaction.rawData.id;
|
const interactionId = interaction.rawData.id;
|
||||||
const route = resolveDiscordConversationRoute({
|
const route = resolveDiscordBoundConversationRoute({
|
||||||
cfg,
|
cfg,
|
||||||
accountId,
|
accountId,
|
||||||
guildId: interaction.guild?.id ?? undefined,
|
guildId: interaction.guild?.id ?? undefined,
|
||||||
memberRoleIds,
|
memberRoleIds,
|
||||||
peer: buildDiscordRoutePeer({
|
isDirectMessage,
|
||||||
isDirectMessage,
|
isGroupDm,
|
||||||
isGroupDm,
|
directUserId: user.id,
|
||||||
directUserId: user.id,
|
conversationId: channelId,
|
||||||
conversationId: channelId,
|
|
||||||
}),
|
|
||||||
parentConversationId: threadParentId,
|
parentConversationId: threadParentId,
|
||||||
|
// Configured ACP routes apply after raw route resolution, so do not pass
|
||||||
|
// bound/configured overrides here.
|
||||||
});
|
});
|
||||||
const threadBinding = isThreadChannel ? threadBindings.getByThreadId(rawChannelId) : undefined;
|
const threadBinding = isThreadChannel ? threadBindings.getByThreadId(rawChannelId) : undefined;
|
||||||
const configuredRoute =
|
const configuredRoute =
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
|||||||
import type { OpenClawConfig } from "../../config/config.js";
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
import type { ResolvedAgentRoute } from "../../routing/resolve-route.js";
|
import type { ResolvedAgentRoute } from "../../routing/resolve-route.js";
|
||||||
import {
|
import {
|
||||||
|
resolveDiscordBoundConversationRoute,
|
||||||
buildDiscordRoutePeer,
|
buildDiscordRoutePeer,
|
||||||
resolveDiscordConversationRoute,
|
resolveDiscordConversationRoute,
|
||||||
resolveDiscordEffectiveRoute,
|
resolveDiscordEffectiveRoute,
|
||||||
@@ -104,4 +105,39 @@ describe("discord route resolution helpers", () => {
|
|||||||
matchedBy: "binding.peer",
|
matchedBy: "binding.peer",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("composes route building with effective-route overrides", () => {
|
||||||
|
const cfg: OpenClawConfig = {
|
||||||
|
agents: {
|
||||||
|
list: [{ id: "worker" }],
|
||||||
|
},
|
||||||
|
bindings: [
|
||||||
|
{
|
||||||
|
agentId: "worker",
|
||||||
|
match: {
|
||||||
|
channel: "discord",
|
||||||
|
accountId: "default",
|
||||||
|
peer: { kind: "direct", id: "user-1" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
resolveDiscordBoundConversationRoute({
|
||||||
|
cfg,
|
||||||
|
accountId: "default",
|
||||||
|
isDirectMessage: true,
|
||||||
|
isGroupDm: false,
|
||||||
|
directUserId: "user-1",
|
||||||
|
conversationId: "dm-1",
|
||||||
|
boundSessionKey: "agent:worker:discord:direct:user-1",
|
||||||
|
matchedBy: "binding.channel",
|
||||||
|
}),
|
||||||
|
).toMatchObject({
|
||||||
|
agentId: "worker",
|
||||||
|
sessionKey: "agent:worker:discord:direct:user-1",
|
||||||
|
matchedBy: "binding.channel",
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,6 +41,41 @@ export function resolveDiscordConversationRoute(params: {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveDiscordBoundConversationRoute(params: {
|
||||||
|
cfg: OpenClawConfig;
|
||||||
|
accountId?: string | null;
|
||||||
|
guildId?: string | null;
|
||||||
|
memberRoleIds?: string[];
|
||||||
|
isDirectMessage: boolean;
|
||||||
|
isGroupDm: boolean;
|
||||||
|
directUserId?: string | null;
|
||||||
|
conversationId: string;
|
||||||
|
parentConversationId?: string | null;
|
||||||
|
boundSessionKey?: string | null;
|
||||||
|
configuredRoute?: { route: ResolvedAgentRoute } | null;
|
||||||
|
matchedBy?: ResolvedAgentRoute["matchedBy"];
|
||||||
|
}): ResolvedAgentRoute {
|
||||||
|
const route = resolveDiscordConversationRoute({
|
||||||
|
cfg: params.cfg,
|
||||||
|
accountId: params.accountId,
|
||||||
|
guildId: params.guildId,
|
||||||
|
memberRoleIds: params.memberRoleIds,
|
||||||
|
peer: buildDiscordRoutePeer({
|
||||||
|
isDirectMessage: params.isDirectMessage,
|
||||||
|
isGroupDm: params.isGroupDm,
|
||||||
|
directUserId: params.directUserId,
|
||||||
|
conversationId: params.conversationId,
|
||||||
|
}),
|
||||||
|
parentConversationId: params.parentConversationId,
|
||||||
|
});
|
||||||
|
return resolveDiscordEffectiveRoute({
|
||||||
|
route,
|
||||||
|
boundSessionKey: params.boundSessionKey,
|
||||||
|
configuredRoute: params.configuredRoute,
|
||||||
|
matchedBy: params.matchedBy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveDiscordEffectiveRoute(params: {
|
export function resolveDiscordEffectiveRoute(params: {
|
||||||
route: ResolvedAgentRoute;
|
route: ResolvedAgentRoute;
|
||||||
boundSessionKey?: string | null;
|
boundSessionKey?: string | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user