diff --git a/plugin/index.ts b/plugin/index.ts index 2c2f727..a1d5bc8 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -8,6 +8,7 @@ type DiscordControlAction = "channel-private-create" | "channel-private-update" type DecisionRecord = { decision: Decision; createdAt: number; + needsRestore?: boolean; }; type PolicyState = { @@ -168,7 +169,7 @@ function shouldDebugLog(cfg: DebugConfig, channelId?: string): boolean { if (!cfg.enableDebugLogs) return false; const allow = Array.isArray(cfg.debugLogChannelIds) ? cfg.debugLogChannelIds : []; if (allow.length === 0) return true; - if (!channelId) return false; + if (!channelId) return true; // 允许打印,方便排查 channelId 为空的场景 return allow.includes(channelId); } @@ -363,8 +364,18 @@ export default { ensurePolicyStateLoaded(api, live); const prompt = ((event as Record).prompt as string) || ""; + + if (live.enableDebugLogs) { + api.logger.info( + `whispergate: DEBUG_BEFORE_MODEL_RESOLVE ctx=${JSON.stringify({ sessionKey: ctx.sessionKey, messageProvider: ctx.messageProvider, agentId: ctx.agentId })} ` + + `promptPreview=${prompt.slice(0, 300)}`, + ); + } + const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider); - if (live.discordOnly !== false && derived.channel !== "discord") return; + // Only proceed if: discord channel AND prompt contains untrusted metadata + const hasConvMarker = prompt.includes("Conversation info (untrusted metadata):"); + if (live.discordOnly !== false && (!hasConvMarker || derived.channel !== "discord")) return; let rec = sessionDecision.get(key); if (!rec || Date.now() - rec.createdAt > DECISION_TTL_MS) { @@ -392,7 +403,36 @@ export default { } } - if (!rec.decision.shouldUseNoReply) return; + if (!rec.decision.shouldUseNoReply) { + // 如果之前有 no-reply 执行过,现在不需要了,清除 override 恢复原模型 + if (rec.needsRestore) { + sessionDecision.delete(key); + return { + providerOverride: undefined, + modelOverride: undefined, + }; + } + return; + } + + // 标记这次执行了 no-reply,下次需要恢复模型 + rec.needsRestore = true; + sessionDecision.set(key, rec); + + // 无论是否有缓存,只要 debug flag 开启就打印决策详情 + if (live.enableDebugLogs) { + const prompt = ((event as Record).prompt as string) || ""; + const hasConvMarker = prompt.includes("Conversation info (untrusted metadata):"); + api.logger.info( + `whispergate: DEBUG_NO_REPLY_TRIGGER session=${key} ` + + `channel=${derived.channel} channelId=${derived.channelId ?? ""} senderId=${derived.senderId ?? ""} ` + + `convSenderId=${String((derived.conv as Record).sender_id ?? "")} ` + + `convSender=${String((derived.conv as Record).sender ?? "")} ` + + `decision=${rec.decision.reason} ` + + `shouldNoReply=${rec.decision.shouldUseNoReply} shouldInject=${rec.decision.shouldInjectEndMarkerPrompt} ` + + `hasConvMarker=${hasConvMarker} promptLen=${prompt.length}`, + ); + } api.logger.info( `whispergate: override model for session=${key}, provider=${live.noReplyProvider}, model=${live.noReplyModel}, reason=${rec.decision.reason}`,