Files
OmniRoute/open-sse/services/defaultReasoningEffort.ts
Diego Rodrigues de Sa e Souza b28331307e feat: per-model default reasoning_effort + no-think none on OpenAI path (#6879) (#7631)
Validated in merge-train 2026-07-18 @ 9084b408b: 12198/12201 pass; single red = earlyStreamKeepalive timer test, confirmed load-flake (6/6 green isolated on release tip AND the merged tree; no boarded PR touches keepalive)
2026-07-18 03:07:37 -03:00

43 lines
1.9 KiB
TypeScript

// Per-model default reasoning effort (#6879, "Ask 1"). Many models think by
// default with no client-visible way to turn it off (measured:
// gemini-flash-lite-latest burns ~277 reasoning tokens on a plain request with
// no reasoning params). ModelSpec.defaultReasoningEffort lets an operator
// configure a strip-by-default (or steer-by-default) value fleet-wide without
// patching every client.
//
// Semantics: applied ONLY when the request carries no reasoning field of any
// shape (`reasoning_effort`, `reasoning`, `thinking`) — an explicit client
// value, including one forwarded verbatim through a combo leg, always wins
// and this is a no-op. Models without a configured default are untouched
// (regression-safe). Wired at the OpenAI-format dispatch chokepoint in
// chatCore.ts, after model resolution, so the *upstream* model's default is
// used even when a combo/route substituted it.
import { getModelSpec } from "@/shared/constants/modelSpecs.ts";
/** True when `body` already expresses a reasoning-effort choice, in any known shape. */
function hasExplicitReasoningField(body: Record<string, unknown>): boolean {
return (
body.reasoning_effort !== undefined ||
body.reasoning !== undefined ||
body.thinking !== undefined
);
}
/**
* Inject the resolved model's `defaultReasoningEffort` as `reasoning_effort` when the
* request has no reasoning field. Returns `body` unchanged (same reference) when there
* is nothing to inject, so callers can chain it without extra guards.
*/
export function applyDefaultReasoningEffort<T extends Record<string, unknown>>(
body: T,
modelId: string
): T {
if (!body || typeof body !== "object") return body;
if (hasExplicitReasoningField(body)) return body;
const defaultEffort = getModelSpec(modelId)?.defaultReasoningEffort;
if (!defaultEffort) return body;
return { ...body, reasoning_effort: defaultEffort };
}