fix(discord): escape prose markdown without clobbering structured output
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import path from 'path';
|
||||
|
||||
import { normalizeAgentOutput } from '../agent-protocol.js';
|
||||
import { neutralizeStrayMarkdown, sanitizeForOutbound } from '../router.js';
|
||||
import type { OutboundAttachment } from '../types.js';
|
||||
|
||||
const LOCAL_MARKDOWN_LINK_RE = /\[[^\]\n]*\]\((\/[^)\n]+)\)/g;
|
||||
@@ -46,7 +47,17 @@ export function prepareDiscordOutbound(
|
||||
const structuredOutput =
|
||||
normalized.output?.visibility === 'public' ? normalized.output : null;
|
||||
const outboundText = structuredOutput?.text ?? normalized.result ?? text;
|
||||
const cleanText = sanitizeLocalMarkdownLinks(outboundText);
|
||||
// Redact/strip before escaping so secret patterns (which contain `_`) still
|
||||
// match, then escape stray Discord markdown in free-form agent prose so
|
||||
// emphasis markers (**bold**, ~~strike~~, …) render literally. Author-
|
||||
// controlled structured envelopes are intentional, so their text is left
|
||||
// untouched. Escaping runs before sanitizeLocalMarkdownLinks so the inline
|
||||
// code it deliberately produces is preserved.
|
||||
const safeText = sanitizeForOutbound(outboundText);
|
||||
const renderedText = structuredOutput
|
||||
? safeText
|
||||
: neutralizeStrayMarkdown(safeText);
|
||||
const cleanText = sanitizeLocalMarkdownLinks(renderedText);
|
||||
const attachments =
|
||||
optionAttachments && optionAttachments.length > 0
|
||||
? optionAttachments
|
||||
|
||||
@@ -15,7 +15,7 @@ import { CACHE_DIR } from '../config.js';
|
||||
import { getEnv } from '../env.js';
|
||||
import { logger } from '../logger.js';
|
||||
import { validateOutboundAttachments } from '../outbound-attachments.js';
|
||||
import { formatOutbound } from '../router.js';
|
||||
import { sanitizeForOutbound } from '../router.js';
|
||||
import { hasReviewerLease } from '../service-routing.js';
|
||||
import type {
|
||||
DeleteRecentMessagesByContentOptions,
|
||||
@@ -528,7 +528,9 @@ export class DiscordChannel implements Channel {
|
||||
for (const [name, id] of Object.entries(mentionMap)) {
|
||||
cleaned = cleaned.replace(new RegExp(`@${name}`, 'g'), `<@${id}>`);
|
||||
}
|
||||
cleaned = formatOutbound(cleaned);
|
||||
// Markdown escaping already happened in prepareDiscordOutbound (before
|
||||
// the deliberate link→inline-code step). Here we only strip/redact.
|
||||
cleaned = sanitizeForOutbound(cleaned);
|
||||
|
||||
// Discord has a 2000 character limit per message and 10 attachments per message
|
||||
const MAX_LENGTH = 2000;
|
||||
|
||||
Reference in New Issue
Block a user