diff --git a/src/routing/resolve-route.ts b/src/routing/resolve-route.ts index 70917841a..a33049931 100644 --- a/src/routing/resolve-route.ts +++ b/src/routing/resolve-route.ts @@ -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"); }