mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 21:01:43 +03:00
fix: add discord routing debug logging (#16202) (thanks @jayleekr)
This commit is contained in:
@@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
- Sandbox: add `sandbox.browser.binds` to configure browser-container bind mounts separately from exec containers. (#16230) Thanks @seheepeak.
|
- Sandbox: add `sandbox.browser.binds` to configure browser-container bind mounts separately from exec containers. (#16230) Thanks @seheepeak.
|
||||||
|
- Discord: add debug logging for message routing decisions to improve `--debug` tracing. (#16202) Thanks @jayleekr.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { loadConfig } from "../../config/config.js";
|
|||||||
import { logVerbose, shouldLogVerbose } from "../../globals.js";
|
import { logVerbose, shouldLogVerbose } from "../../globals.js";
|
||||||
import { recordChannelActivity } from "../../infra/channel-activity.js";
|
import { recordChannelActivity } from "../../infra/channel-activity.js";
|
||||||
import { enqueueSystemEvent } from "../../infra/system-events.js";
|
import { enqueueSystemEvent } from "../../infra/system-events.js";
|
||||||
|
import { logDebug } from "../../logger.js";
|
||||||
import { getChildLogger } from "../../logging.js";
|
import { getChildLogger } from "../../logging.js";
|
||||||
import { buildPairingReply } from "../../pairing/pairing-messages.js";
|
import { buildPairingReply } from "../../pairing/pairing-messages.js";
|
||||||
import {
|
import {
|
||||||
@@ -104,6 +105,9 @@ export async function preflightDiscordMessage(
|
|||||||
const channelInfo = await resolveDiscordChannelInfo(params.client, message.channelId);
|
const channelInfo = await resolveDiscordChannelInfo(params.client, message.channelId);
|
||||||
const isDirectMessage = channelInfo?.type === ChannelType.DM;
|
const isDirectMessage = channelInfo?.type === ChannelType.DM;
|
||||||
const isGroupDm = channelInfo?.type === ChannelType.GroupDM;
|
const isGroupDm = channelInfo?.type === ChannelType.GroupDM;
|
||||||
|
logDebug(
|
||||||
|
`[discord-preflight] channelId=${message.channelId} guild_id=${params.data.guild_id} channelType=${channelInfo?.type} isGuild=${isGuildMessage} isDM=${isDirectMessage} isGroupDm=${isGroupDm}`,
|
||||||
|
);
|
||||||
|
|
||||||
if (isGroupDm && !params.groupDmEnabled) {
|
if (isGroupDm && !params.groupDmEnabled) {
|
||||||
logVerbose("discord: drop group dm (group dms disabled)");
|
logVerbose("discord: drop group dm (group dms disabled)");
|
||||||
@@ -262,12 +266,18 @@ export async function preflightDiscordMessage(
|
|||||||
guildEntries: params.guildEntries,
|
guildEntries: params.guildEntries,
|
||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
|
logDebug(
|
||||||
|
`[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${!!params.data.guild} guild_obj_id=${params.data.guild?.id} guildInfo=${!!guildInfo} guildEntries=${params.guildEntries ? Object.keys(params.guildEntries).join(",") : "none"}`,
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
isGuildMessage &&
|
isGuildMessage &&
|
||||||
params.guildEntries &&
|
params.guildEntries &&
|
||||||
Object.keys(params.guildEntries).length > 0 &&
|
Object.keys(params.guildEntries).length > 0 &&
|
||||||
!guildInfo
|
!guildInfo
|
||||||
) {
|
) {
|
||||||
|
logDebug(
|
||||||
|
`[discord-preflight] guild blocked: guild_id=${params.data.guild_id} guildEntries keys=${Object.keys(params.guildEntries).join(",")}`,
|
||||||
|
);
|
||||||
logVerbose(
|
logVerbose(
|
||||||
`Blocked discord guild ${params.data.guild_id ?? "unknown"} (not in discord.guilds)`,
|
`Blocked discord guild ${params.data.guild_id ?? "unknown"} (not in discord.guilds)`,
|
||||||
);
|
);
|
||||||
@@ -305,7 +315,16 @@ export async function preflightDiscordMessage(
|
|||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
const channelMatchMeta = formatAllowlistMatchMeta(channelConfig);
|
const channelMatchMeta = formatAllowlistMatchMeta(channelConfig);
|
||||||
|
if (shouldLogVerbose()) {
|
||||||
|
const channelConfigSummary = channelConfig
|
||||||
|
? `allowed=${channelConfig.allowed} enabled=${channelConfig.enabled ?? "unset"} requireMention=${channelConfig.requireMention ?? "unset"} matchKey=${channelConfig.matchKey ?? "none"} matchSource=${channelConfig.matchSource ?? "none"} users=${channelConfig.users?.length ?? 0} roles=${channelConfig.roles?.length ?? 0} skills=${channelConfig.skills?.length ?? 0}`
|
||||||
|
: "none";
|
||||||
|
logDebug(
|
||||||
|
`[discord-preflight] channelConfig=${channelConfigSummary} channelMatchMeta=${channelMatchMeta} channelId=${message.channelId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (isGuildMessage && channelConfig?.enabled === false) {
|
if (isGuildMessage && channelConfig?.enabled === false) {
|
||||||
|
logDebug(`[discord-preflight] drop: channel disabled`);
|
||||||
logVerbose(
|
logVerbose(
|
||||||
`Blocked discord channel ${message.channelId} (channel disabled, ${channelMatchMeta})`,
|
`Blocked discord channel ${message.channelId} (channel disabled, ${channelMatchMeta})`,
|
||||||
);
|
);
|
||||||
@@ -351,12 +370,14 @@ export async function preflightDiscordMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isGuildMessage && channelConfig?.allowed === false) {
|
if (isGuildMessage && channelConfig?.allowed === false) {
|
||||||
|
logDebug(`[discord-preflight] drop: channelConfig.allowed===false`);
|
||||||
logVerbose(
|
logVerbose(
|
||||||
`Blocked discord channel ${message.channelId} not in guild channel allowlist (${channelMatchMeta})`,
|
`Blocked discord channel ${message.channelId} not in guild channel allowlist (${channelMatchMeta})`,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (isGuildMessage) {
|
if (isGuildMessage) {
|
||||||
|
logDebug(`[discord-preflight] pass: channel allowed`);
|
||||||
logVerbose(`discord: allow channel ${message.channelId} (${channelMatchMeta})`);
|
logVerbose(`discord: allow channel ${message.channelId} (${channelMatchMeta})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,8 +540,12 @@ export async function preflightDiscordMessage(
|
|||||||
commandAuthorized,
|
commandAuthorized,
|
||||||
});
|
});
|
||||||
const effectiveWasMentioned = mentionGate.effectiveWasMentioned;
|
const effectiveWasMentioned = mentionGate.effectiveWasMentioned;
|
||||||
|
logDebug(
|
||||||
|
`[discord-preflight] shouldRequireMention=${shouldRequireMention} mentionGate.shouldSkip=${mentionGate.shouldSkip} wasMentioned=${wasMentioned}`,
|
||||||
|
);
|
||||||
if (isGuildMessage && shouldRequireMention) {
|
if (isGuildMessage && shouldRequireMention) {
|
||||||
if (botId && mentionGate.shouldSkip) {
|
if (botId && mentionGate.shouldSkip) {
|
||||||
|
logDebug(`[discord-preflight] drop: no-mention`);
|
||||||
logVerbose(`discord: drop guild message (mention required, botId=${botId})`);
|
logVerbose(`discord: drop guild message (mention required, botId=${botId})`);
|
||||||
logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
@@ -540,6 +565,7 @@ export async function preflightDiscordMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isGuildMessage && hasAccessRestrictions && !memberAllowed) {
|
if (isGuildMessage && hasAccessRestrictions && !memberAllowed) {
|
||||||
|
logDebug(`[discord-preflight] drop: member not allowed`);
|
||||||
logVerbose(`Blocked discord guild sender ${sender.id} (not in users/roles allowlist)`);
|
logVerbose(`Blocked discord guild sender ${sender.id} (not in users/roles allowlist)`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -552,6 +578,7 @@ export async function preflightDiscordMessage(
|
|||||||
});
|
});
|
||||||
const systemText = resolveDiscordSystemEvent(message, systemLocation);
|
const systemText = resolveDiscordSystemEvent(message, systemLocation);
|
||||||
if (systemText) {
|
if (systemText) {
|
||||||
|
logDebug(`[discord-preflight] drop: system event`);
|
||||||
enqueueSystemEvent(systemText, {
|
enqueueSystemEvent(systemText, {
|
||||||
sessionKey: route.sessionKey,
|
sessionKey: route.sessionKey,
|
||||||
contextKey: `discord:system:${message.channelId}:${message.id}`,
|
contextKey: `discord:system:${message.channelId}:${message.id}`,
|
||||||
@@ -560,10 +587,12 @@ export async function preflightDiscordMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!messageText) {
|
if (!messageText) {
|
||||||
|
logDebug(`[discord-preflight] drop: empty content`);
|
||||||
logVerbose(`discord: drop message ${message.id} (empty content)`);
|
logVerbose(`discord: drop message ${message.id} (empty content)`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logDebug(`[discord-preflight] success: route=${route.agentId} sessionKey=${route.sessionKey}`);
|
||||||
return {
|
return {
|
||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
discordConfig: params.discordConfig,
|
discordConfig: params.discordConfig,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import type { ChatType } from "../channels/chat-type.js";
|
|||||||
import type { OpenClawConfig } from "../config/config.js";
|
import type { OpenClawConfig } from "../config/config.js";
|
||||||
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||||
import { normalizeChatType } from "../channels/chat-type.js";
|
import { normalizeChatType } from "../channels/chat-type.js";
|
||||||
|
import { shouldLogVerbose } from "../globals.js";
|
||||||
|
import { logDebug } from "../logger.js";
|
||||||
import { listBindings } from "./bindings.js";
|
import { listBindings } from "./bindings.js";
|
||||||
import {
|
import {
|
||||||
buildAgentMainSessionKey,
|
buildAgentMainSessionKey,
|
||||||
@@ -322,6 +324,29 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldLogDebug = shouldLogVerbose();
|
||||||
|
const formatPeer = (value?: RoutePeer | null) =>
|
||||||
|
value?.kind && value?.id ? `${value.kind}:${value.id}` : "none";
|
||||||
|
const formatNormalizedPeer = (value: NormalizedPeerConstraint) => {
|
||||||
|
if (value.state === "none") {
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
if (value.state === "invalid") {
|
||||||
|
return "invalid";
|
||||||
|
}
|
||||||
|
return `${value.kind}:${value.id}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shouldLogDebug) {
|
||||||
|
logDebug(
|
||||||
|
`[routing] resolveAgentRoute: channel=${channel} accountId=${accountId} peer=${formatPeer(peer)} guildId=${guildId || "none"} teamId=${teamId || "none"} bindings=${bindings.length}`,
|
||||||
|
);
|
||||||
|
for (const entry of bindings) {
|
||||||
|
logDebug(
|
||||||
|
`[routing] binding: agentId=${entry.binding.agentId} accountPattern=${entry.match.accountPattern || "default"} peer=${formatNormalizedPeer(entry.match.peer)} guildId=${entry.match.guildId ?? "none"} teamId=${entry.match.teamId ?? "none"} roles=${entry.match.roles?.length ?? 0}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Thread parent inheritance: if peer (thread) didn't match, check parent peer binding
|
// Thread parent inheritance: if peer (thread) didn't match, check parent peer binding
|
||||||
const parentPeer = input.parentPeer
|
const parentPeer = input.parentPeer
|
||||||
? { kind: input.parentPeer.kind, id: normalizeId(input.parentPeer.id) }
|
? { kind: input.parentPeer.kind, id: normalizeId(input.parentPeer.id) }
|
||||||
@@ -397,6 +422,9 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
if (matched) {
|
if (matched) {
|
||||||
|
if (shouldLogDebug) {
|
||||||
|
logDebug(`[routing] match: matchedBy=${tier.matchedBy} agentId=${matched.binding.agentId}`);
|
||||||
|
}
|
||||||
return choose(matched.binding.agentId, tier.matchedBy);
|
return choose(matched.binding.agentId, tier.matchedBy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user