fix(webchat): filter NO_REPLY token from streaming and final replies (#16286)

The webchat channel sent NO_REPLY as visible text to clients instead
of suppressing it. Other channels (Telegram, Discord) already filter
this token via the reply dispatcher, but the webchat streaming path
bypassed this check.

Fixes #16269
This commit is contained in:
Robby
2026-02-14 18:26:19 +01:00
committed by GitHub
parent 68b00a5388
commit baa3bf270b
2 changed files with 95 additions and 7 deletions

View File

@@ -1,4 +1,5 @@
import { normalizeVerboseLevel } from "../auto-reply/thinking.js";
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
import { loadConfig } from "../config/config.js";
import { type AgentEventPayload, getAgentRunContext } from "../infra/agent-events.js";
import { resolveHeartbeatVisibility } from "../infra/heartbeat-visibility.js";
@@ -228,6 +229,9 @@ export function createAgentEventHandler({
toolEventRecipients,
}: AgentEventHandlerOptions) {
const emitChatDelta = (sessionKey: string, clientRunId: string, seq: number, text: string) => {
if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) {
return;
}
chatRunState.buffers.set(clientRunId, text);
const now = Date.now();
const last = chatRunState.deltaSentAt.get(clientRunId) ?? 0;
@@ -261,6 +265,7 @@ export function createAgentEventHandler({
error?: unknown,
) => {
const text = chatRunState.buffers.get(clientRunId)?.trim() ?? "";
const shouldSuppressSilent = isSilentReplyText(text, SILENT_REPLY_TOKEN);
chatRunState.buffers.delete(clientRunId);
chatRunState.deltaSentAt.delete(clientRunId);
if (jobState === "done") {
@@ -269,13 +274,14 @@ export function createAgentEventHandler({
sessionKey,
seq,
state: "final" as const,
message: text
? {
role: "assistant",
content: [{ type: "text", text }],
timestamp: Date.now(),
}
: undefined,
message:
text && !shouldSuppressSilent
? {
role: "assistant",
content: [{ type: "text", text }],
timestamp: Date.now(),
}
: undefined,
};
// Suppress webchat broadcast for heartbeat runs when showOk is false
if (!shouldSuppressHeartbeatBroadcast(clientRunId)) {