mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
Discord: implement role-based agent routing in resolveAgentRoute
This commit is contained in:
@@ -43,6 +43,7 @@ export type ResolvedAgentRoute = {
|
||||
matchedBy:
|
||||
| "binding.peer"
|
||||
| "binding.peer.parent"
|
||||
| "binding.guild+roles"
|
||||
| "binding.guild"
|
||||
| "binding.team"
|
||||
| "binding.account"
|
||||
@@ -67,12 +68,8 @@ function normalizeAccountId(value: string | undefined | null): string {
|
||||
|
||||
function matchesAccountId(match: string | undefined, actual: string): boolean {
|
||||
const trimmed = (match ?? "").trim();
|
||||
if (!trimmed) {
|
||||
return actual === DEFAULT_ACCOUNT_ID;
|
||||
}
|
||||
if (trimmed === "*") {
|
||||
return true;
|
||||
}
|
||||
if (!trimmed) return actual === DEFAULT_ACCOUNT_ID;
|
||||
if (trimmed === "*") return true;
|
||||
return trimmed === actual;
|
||||
}
|
||||
|
||||
@@ -106,18 +103,12 @@ function listAgents(cfg: OpenClawConfig) {
|
||||
|
||||
function pickFirstExistingAgentId(cfg: OpenClawConfig, agentId: string): string {
|
||||
const trimmed = (agentId ?? "").trim();
|
||||
if (!trimmed) {
|
||||
return sanitizeAgentId(resolveDefaultAgentId(cfg));
|
||||
}
|
||||
if (!trimmed) return sanitizeAgentId(resolveDefaultAgentId(cfg));
|
||||
const normalized = normalizeAgentId(trimmed);
|
||||
const agents = listAgents(cfg);
|
||||
if (agents.length === 0) {
|
||||
return sanitizeAgentId(trimmed);
|
||||
}
|
||||
if (agents.length === 0) return sanitizeAgentId(trimmed);
|
||||
const match = agents.find((agent) => normalizeAgentId(agent.id) === normalized);
|
||||
if (match?.id?.trim()) {
|
||||
return sanitizeAgentId(match.id.trim());
|
||||
}
|
||||
if (match?.id?.trim()) return sanitizeAgentId(match.id.trim());
|
||||
return sanitizeAgentId(resolveDefaultAgentId(cfg));
|
||||
}
|
||||
|
||||
@@ -126,9 +117,7 @@ function matchesChannel(
|
||||
channel: string,
|
||||
): boolean {
|
||||
const key = normalizeToken(match?.channel);
|
||||
if (!key) {
|
||||
return false;
|
||||
}
|
||||
if (!key) return false;
|
||||
return key === channel;
|
||||
}
|
||||
|
||||
@@ -143,9 +132,7 @@ function matchesPeer(
|
||||
// Backward compat: normalize "dm" to "direct" in config match rules
|
||||
const kind = normalizeChatType(m.kind);
|
||||
const id = normalizeId(m.id);
|
||||
if (!kind || !id) {
|
||||
return false;
|
||||
}
|
||||
if (!kind || !id) return false;
|
||||
return kind === peer.kind && id === peer.id;
|
||||
}
|
||||
|
||||
@@ -154,17 +141,13 @@ function matchesGuild(
|
||||
guildId: string,
|
||||
): boolean {
|
||||
const id = normalizeId(match?.guildId);
|
||||
if (!id) {
|
||||
return false;
|
||||
}
|
||||
if (!id) return false;
|
||||
return id === guildId;
|
||||
}
|
||||
|
||||
function matchesTeam(match: { teamId?: string | undefined } | undefined, teamId: string): boolean {
|
||||
const id = normalizeId(match?.teamId);
|
||||
if (!id) {
|
||||
return false;
|
||||
}
|
||||
if (!id) return false;
|
||||
return id === teamId;
|
||||
}
|
||||
|
||||
@@ -176,12 +159,8 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
||||
const teamId = normalizeId(input.teamId);
|
||||
|
||||
const bindings = listBindings(input.cfg).filter((binding) => {
|
||||
if (!binding || typeof binding !== "object") {
|
||||
return false;
|
||||
}
|
||||
if (!matchesChannel(binding.match, channel)) {
|
||||
return false;
|
||||
}
|
||||
if (!binding || typeof binding !== "object") return false;
|
||||
if (!matchesChannel(binding.match, channel)) return false;
|
||||
return matchesAccountId(binding.match?.accountId, accountId);
|
||||
});
|
||||
|
||||
@@ -214,9 +193,14 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
||||
|
||||
if (peer) {
|
||||
const peerMatch = bindings.find((b) => matchesPeer(b.match, peer));
|
||||
if (peerMatch) {
|
||||
return choose(peerMatch.agentId, "binding.peer");
|
||||
}
|
||||
if (peerMatch) return choose(peerMatch.agentId, "binding.peer");
|
||||
}
|
||||
|
||||
if (guildId && memberRoleIds.length > 0) {
|
||||
const guildRolesMatch = bindings.find(
|
||||
(b) => matchesGuild(b.match, guildId) && matchesRoles(b.match, memberRoleIds),
|
||||
);
|
||||
if (guildRolesMatch) return choose(guildRolesMatch.agentId, "binding.guild+roles");
|
||||
}
|
||||
|
||||
// Thread parent inheritance: if peer (thread) didn't match, check parent peer binding
|
||||
@@ -239,26 +223,20 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
||||
|
||||
if (teamId) {
|
||||
const teamMatch = bindings.find((b) => matchesTeam(b.match, teamId));
|
||||
if (teamMatch) {
|
||||
return choose(teamMatch.agentId, "binding.team");
|
||||
}
|
||||
if (teamMatch) return choose(teamMatch.agentId, "binding.team");
|
||||
}
|
||||
|
||||
const accountMatch = bindings.find(
|
||||
(b) =>
|
||||
b.match?.accountId?.trim() !== "*" && !b.match?.peer && !b.match?.guildId && !b.match?.teamId,
|
||||
);
|
||||
if (accountMatch) {
|
||||
return choose(accountMatch.agentId, "binding.account");
|
||||
}
|
||||
if (accountMatch) return choose(accountMatch.agentId, "binding.account");
|
||||
|
||||
const anyAccountMatch = bindings.find(
|
||||
(b) =>
|
||||
b.match?.accountId?.trim() === "*" && !b.match?.peer && !b.match?.guildId && !b.match?.teamId,
|
||||
);
|
||||
if (anyAccountMatch) {
|
||||
return choose(anyAccountMatch.agentId, "binding.channel");
|
||||
}
|
||||
if (anyAccountMatch) return choose(anyAccountMatch.agentId, "binding.channel");
|
||||
|
||||
return choose(resolveDefaultAgentId(input.cfg), "default");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user