Files
OmniRoute/open-sse/config/providerFieldStrips.ts
Diego Rodrigues de Sa e Souza 92715c8f2c Release v3.8.46
Release v3.8.46. Full changelog: CHANGELOG.md → [3.8.46]. Contributor attribution in the CHANGELOG entries.
2026-07-07 13:14:06 -03:00

43 lines
1.7 KiB
TypeScript

// Fields that, when literally named in an upstream 400 body, are safe to strip and
// retry once (FCC NIM-style recovery). Mirrors the existing context_management 400
// fallback in base.ts, generalized to these OpenAI-compat / NIM reasoning fields.
// `context_management` (9router#1468): Claude Code sends it top-level; strict
// anthropic-compatible gateways 400 with "context_management: Extra inputs are not
// permitted". The dedicated base.ts fallback only fires when OmniRoute's own
// contextEditing feature is enabled, so a client-sent field passed through
// untouched when the feature is off — this generic strip covers that case.
export const KNOWN_OFFENDING_FIELDS: readonly string[] = [
"reasoning_budget",
"chat_template",
"reasoning_content",
"context_management",
];
/** Return the first known-offending field literally named in a 400 body, or null. */
export function findOffendingField(bodyText: string): string | null {
if (typeof bodyText !== "string" || !bodyText) return null;
for (const field of KNOWN_OFFENDING_FIELDS) {
if (bodyText.includes(field)) return field;
}
return null;
}
/** Immutably drop request fields Groq rejects with a 400. */
export function stripGroqUnsupportedFields<T extends Record<string, unknown>>(body: T): T {
if (!body || typeof body !== "object") return body;
const next: Record<string, unknown> = { ...body };
delete next.logprobs;
delete next.logit_bias;
delete next.top_logprobs;
if (Array.isArray(next.messages)) {
next.messages = next.messages.map((m) => {
if (m && typeof m === "object" && "name" in m) {
const { name: _name, ...rest } = m as Record<string, unknown>;
return rest;
}
return m;
});
}
return next as T;
}