Files
9router/open-sse/utils/streamErrorPatterns.js
luulam 2a37a4085e chore: normalize formatting (2-space → tabs) in stream-error-patterns files
Re-tab only — no logic changes. Follows the repo's tab-based formatting
for these files, matching the CommandCode executor/translator style.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-05 09:03:41 +07:00

48 lines
1.4 KiB
JavaScript

/**
* Config-driven in-stream error pattern matching.
* See docs/2026-08-04-stream-error-patterns-design.md.
*
* Settings shape: streamErrorPatterns: { [provider]: string[] }
* Pattern syntax per entry:
* - "plain text" → case-insensitive substring match
* - "/regex/flags" → RegExp match (flags after the last "/")
*/
export function parsePatterns(patterns) {
if (!Array.isArray(patterns)) return [];
const out = [];
for (const entry of patterns) {
if (typeof entry !== "string" || !entry.trim()) continue;
const raw = entry.trim();
const m = raw.match(/^\/(.*)\/([a-z]*)$/s);
if (m) {
try {
out.push({ regex: new RegExp(m[1], m[2]), raw });
} catch {
// invalid regex → skip; config errors must never break requests
}
continue;
}
out.push({ text: raw.toLowerCase(), raw });
}
return out;
}
export function matchStreamErrorPatterns(patterns, text) {
if (!Array.isArray(patterns) || patterns.length === 0) return null;
if (typeof text !== "string" || !text) return null;
const lower = text.toLowerCase();
for (const p of parsePatterns(patterns)) {
if (p.text && lower.includes(p.text)) return p.raw;
if (p.regex) {
p.regex.lastIndex = 0; // stateless even with /g
if (p.regex.test(text)) return p.raw;
}
}
return null;
}
export function streamStatusForContent(patterns, content) {
return matchStreamErrorPatterns(patterns, content) ? "error" : "success";
}