fix(gateway): strip directive tags from non-streaming webchat broadcasts

Closes #23053

The streaming path already strips [[reply_to_current]] and other
directive tags via stripInlineDirectiveTagsForDisplay, but the
non-streaming broadcastChatFinal path and the chat.inject path
sent raw message content to webchat clients, causing tags to
appear in rendered messages after streaming completes.
This commit is contained in:
SidQin-cyber
2026-02-22 13:34:42 +08:00
committed by Peter Steinberger
parent c56ab39da5
commit e6490732cd

View File

@@ -527,6 +527,25 @@ function nextChatSeq(context: { agentRunSeq: Map<string, number> }, runId: strin
return next;
}
function stripMessageDirectiveTags(
message: Record<string, unknown> | undefined,
): Record<string, unknown> | undefined {
if (!message) {
return message;
}
const content = message.content;
if (!Array.isArray(content)) {
return message;
}
const cleaned = content.map((part: Record<string, unknown>) => {
if (part.type === "text" && typeof part.text === "string") {
return { ...part, text: stripInlineDirectiveTagsForDisplay(part.text).text };
}
return part;
});
return { ...message, content: cleaned };
}
function broadcastChatFinal(params: {
context: Pick<GatewayRequestContext, "broadcast" | "nodeSendToSession" | "agentRunSeq">;
runId: string;
@@ -539,7 +558,7 @@ function broadcastChatFinal(params: {
sessionKey: params.sessionKey,
seq,
state: "final" as const,
message: params.message,
message: stripMessageDirectiveTags(params.message),
};
params.context.broadcast("chat", payload);
params.context.nodeSendToSession(params.sessionKey, "chat", payload);
@@ -1070,7 +1089,7 @@ export const chatHandlers: GatewayRequestHandlers = {
sessionKey: rawSessionKey,
seq: 0,
state: "final" as const,
message: appended.message,
message: stripMessageDirectiveTags(appended.message),
};
context.broadcast("chat", chatPayload);
context.nodeSendToSession(rawSessionKey, "chat", chatPayload);