fix(agents): validate tool-result MEDIA directives with shared parser

Co-authored-by: Ho Lim <166576253+HOYALIM@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-02-22 19:51:38 +01:00
parent 0c1f491a02
commit c3d11d56c3
4 changed files with 50 additions and 20 deletions

View File

@@ -1,6 +1,6 @@
import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js";
import { normalizeTargetForProvider } from "../infra/outbound/target-normalization.js";
import { MEDIA_TOKEN_RE } from "../media/parse.js";
import { splitMediaFromOutput } from "../media/parse.js";
import { truncateUtf16Safe } from "../utils.js";
import { collectTextContentBlocks } from "./content-blocks.js";
import { type MessagingToolSend } from "./pi-embedded-messaging.js";
@@ -203,7 +203,8 @@ export function extractToolResultMediaPaths(result: unknown): string[] {
return [];
}
// Extract MEDIA: paths from text content blocks.
// Extract MEDIA: paths from text content blocks using the shared parser so
// directive matching and validation stay in sync with outbound reply parsing.
const paths: string[] = [];
let hasImageContent = false;
for (const item of content) {
@@ -216,24 +217,9 @@ export function extractToolResultMediaPaths(result: unknown): string[] {
continue;
}
if (entry.type === "text" && typeof entry.text === "string") {
// Only parse lines that start with MEDIA: (after trimming) to avoid
// false-matching placeholders like <media:audio> or mid-line mentions.
// Mirrors the line-start guard in splitMediaFromOutput (media/parse.ts).
for (const line of entry.text.split("\n")) {
if (!line.trimStart().startsWith("MEDIA:")) {
continue;
}
MEDIA_TOKEN_RE.lastIndex = 0;
let match: RegExpExecArray | null;
while ((match = MEDIA_TOKEN_RE.exec(line)) !== null) {
const p = match[1]
?.replace(/^[`"'[{(]+/, "")
.replace(/[`"'\]})\\,]+$/, "")
.trim();
if (p && p.length <= 4096) {
paths.push(p);
}
}
const parsed = splitMediaFromOutput(entry.text);
if (parsed.mediaUrls?.length) {
paths.push(...parsed.mediaUrls);
}
}
}