fix: prioritize ctx.channelId over prompt for turn gate

- Add channelIdFromCtx parameter to deriveDecisionInputFromPrompt
- Priority: ctx.channelId > conv.chat_id > conv.channel_id
- This fixes turn gate not working because channelId was empty/wrong
- Update all 3 call sites to pass ctx.channelId
This commit is contained in:
zhi
2026-02-28 19:49:09 +00:00
parent db3df0688b
commit 532d829ca5

View File

@@ -82,6 +82,7 @@ function extractUntrustedConversationInfo(text: string): Record<string, unknown>
function deriveDecisionInputFromPrompt(
prompt: string,
messageProvider?: string,
channelIdFromCtx?: string,
): {
channel: string;
channelId?: string;
@@ -91,11 +92,17 @@ function deriveDecisionInputFromPrompt(
} {
const conv = extractUntrustedConversationInfo(prompt) || {};
const channel = (messageProvider || "").toLowerCase();
const channelId =
(typeof conv.channel_id === "string" && conv.channel_id) ||
(typeof conv.chat_id === "string" && conv.chat_id.startsWith("channel:")
? conv.chat_id.slice("channel:".length)
: undefined);
// Priority: ctx.channelId > conv.chat_id > conv.channel_id
let channelId = channelIdFromCtx;
if (!channelId) {
channelId =
(typeof conv.chat_id === "string" && conv.chat_id.startsWith("channel:")
? conv.chat_id.slice("channel:".length)
: typeof conv.channel_id === "string" && conv.channel_id) ||
undefined;
}
const senderId =
(typeof conv.sender_id === "string" && conv.sender_id) ||
(typeof conv.sender === "string" && conv.sender) ||
@@ -576,7 +583,7 @@ export default {
);
}
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider);
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider, ctx.channelId);
// 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;
@@ -712,7 +719,7 @@ export default {
if (rec) sessionDecision.delete(key);
const prompt = ((event as Record<string, unknown>).prompt as string) || "";
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider);
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider, ctx.channelId);
const decision = evaluateDecision({
config: live,
@@ -747,7 +754,7 @@ export default {
// Resolve end symbols from config/policy for dynamic instruction
const prompt = ((event as Record<string, unknown>).prompt as string) || "";
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider);
const derived = deriveDecisionInputFromPrompt(prompt, ctx.messageProvider, ctx.channelId);
const policy = resolvePolicy(live, derived.channelId, policyState.channelPolicies);
const isGroupChat = derived.conv.is_group_chat === true || derived.conv.is_group_chat === "true";
const instruction = buildEndMarkerInstruction(policy.endSymbols, isGroupChat);