refactor(chatCore): extrai prepareUpstreamBody (1ª sub-fatia do executeProviderRequest, #3501) (#4730)

chatCore #3501: extract prepareUpstreamBody (first sub-slice of executeProviderRequest) to leaf (upstreamBody.ts). Clean cherry-pick post-#4721. 7/7 new leaf tests, full 301/301 chatcore suite, typecheck/cycles/file-size green. Completes the 6-PR chatCore decomposition stack into release/v3.8.35.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-23 07:21:13 -03:00
committed by GitHub
parent 48dea489c1
commit 5f4e9e73a4
3 changed files with 253 additions and 87 deletions

View File

@@ -106,7 +106,6 @@ import {
COOLDOWN_MS,
HTTP_STATUS,
FETCH_BODY_TIMEOUT_MS,
MAX_TOOLS_LIMIT,
PROVIDER_MAX_TOKENS,
SSE_HEARTBEAT_INTERVAL_MS,
STREAM_IDLE_TIMEOUT_MS,
@@ -145,6 +144,7 @@ import {
} from "./chatCore/attemptLogging.ts";
import { stageTrace } from "./chatCore/stageTrace.ts";
import { attachCompressionUsageReceiptAfterAnalytics as attachCompressionUsageReceiptAfterAnalyticsFor } from "./chatCore/compressionUsageReceipt.ts";
import { prepareUpstreamBody } from "./chatCore/upstreamBody.ts";
import {
getCallLogPipelineCaptureStreamChunks,
@@ -185,14 +185,7 @@ import { getProviderCredentials, extractSessionAffinityKey } from "@/sse/service
import { deleteSessionAccountAffinity } from "@/lib/db/sessionAccountAffinity";
import { getCacheControlSettings } from "@/lib/cacheControlSettings";
import { guardrailRegistry, resolveDisabledGuardrails } from "@/lib/guardrails";
import {
applyConfiguredPayloadRules,
resolvePayloadRuleProtocols,
} from "../services/payloadRules.ts";
import {
shouldPreserveCacheControl,
providerSupportsCaching,
} from "../utils/cacheControlPolicy.ts";
import { shouldPreserveCacheControl } from "../utils/cacheControlPolicy.ts";
import { getCachedSettings } from "@/lib/db/readCache";
import { applyCodexGlobalFastServiceTier } from "@/lib/providers/codexFastTier";
import { buildUpstreamHeadersForExecute as buildUpstreamHeadersForExecuteFor } from "./chatCore/upstreamExecuteHeaders.ts";
@@ -204,7 +197,6 @@ import {
import { cacheReasoningFromAssistantMessage } from "../services/reasoningCache.ts";
import { sanitizeOpenAITool } from "../services/toolSchemaSanitizer.ts";
import {
getEffectiveToolLimit,
setDetectedToolLimit,
parseToolLimitFromError,
shouldDetectLimit,
@@ -2109,86 +2101,17 @@ export async function handleChatCore({
connectionId,
credentials: executionCredentials,
});
let bodyToSend =
translatedBody.model === modelToCall
? translatedBody
: { ...translatedBody, model: modelToCall };
const payloadRuleModel =
typeof bodyToSend.model === "string" && bodyToSend.model.length > 0
? bodyToSend.model
: modelToCall;
const payloadRuleProtocols = resolvePayloadRuleProtocols({
// Upstream body preparation extracted to chatCore/upstreamBody.ts (#3501 — first internal
// sub-slice of executeProviderRequest); produces the body sent upstream (payload rules +
// tool-limit truncation + qwen oauth user backfill + prompt_cache_key injection).
let bodyToSend = await prepareUpstreamBody({
translatedBody,
modelToCall,
provider,
targetFormat,
credentials,
log,
});
const payloadRuleResult = await applyConfiguredPayloadRules(
bodyToSend,
payloadRuleModel,
payloadRuleProtocols
);
bodyToSend = payloadRuleResult.payload;
if (payloadRuleResult.applied.length > 0) {
const appliedSummary = payloadRuleResult.applied
.map((rule) => {
if (rule.type === "filter") return `${rule.type}:${rule.path}`;
const serializedValue = JSON.stringify(rule.value);
const safeValue =
typeof serializedValue === "string" && serializedValue.length > 80
? `${serializedValue.slice(0, 77)}...`
: serializedValue;
return `${rule.type}:${rule.path}=${safeValue}`;
})
.join(", ");
log?.debug?.(
"PAYLOAD_RULES",
`Applied ${payloadRuleResult.applied.length} rule(s) for ${payloadRuleModel} (${payloadRuleProtocols.join(", ")}): ${appliedSummary}`
);
}
const effectiveToolLimit = getEffectiveToolLimit(provider);
if (
effectiveToolLimit < MAX_TOOLS_LIMIT &&
Array.isArray(bodyToSend.tools) &&
bodyToSend.tools.length > effectiveToolLimit
) {
const truncatedTools = bodyToSend.tools.slice(0, effectiveToolLimit);
bodyToSend = { ...bodyToSend, tools: truncatedTools };
log?.debug?.(
"TOOL_LIMIT",
`Truncated ${bodyToSend.tools.length} tools to ${effectiveToolLimit} for ${provider}`
);
}
// Qwen OAuth rejects requests without a non-empty `user` field.
// Some minimal OpenAI-compatible clients omit it, so we backfill a
// stable default only for OAuth mode (API key mode is unaffected).
const hasValidQwenUser =
typeof bodyToSend.user === "string" && bodyToSend.user.trim().length > 0;
const isQwenOAuthRequest =
provider === "qwen" &&
!credentials?.apiKey &&
typeof credentials?.accessToken === "string" &&
credentials.accessToken.trim().length > 0;
if (isQwenOAuthRequest && !hasValidQwenUser) {
bodyToSend = { ...bodyToSend, user: "omniroute-qwen-oauth" };
log?.debug?.("QWEN", "Injected fallback user for OAuth request");
}
// Inject prompt_cache_key only for providers that support it
if (
targetFormat === FORMATS.OPENAI &&
providerSupportsCaching(provider) &&
!bodyToSend.prompt_cache_key &&
Array.isArray(bodyToSend.messages) &&
!["nvidia", "codex", "xai"].includes(provider)
) {
const { generatePromptCacheKey } = await import("@/lib/promptCache");
const cacheKey = generatePromptCacheKey(bodyToSend.messages);
if (cacheKey) {
bodyToSend = { ...bodyToSend, prompt_cache_key: cacheKey };
}
}
updatePendingScope(pendingScope, {
providerRequest: bodyToSend,

View File

@@ -0,0 +1,141 @@
/**
* chatCore upstream body preparation (Quality Gate v2 / Fase 9 — chatCore god-file decomposition,
* #3501 — first internal sub-slice of executeProviderRequest).
*
* Extracted from handleChatCore's execute() closure: prepares the body actually sent upstream for a
* given target model. Pins the model id, applies the configured payload rules, truncates the tool
* list to the provider's effective limit, backfills a default `user` for Qwen OAuth requests, and
* injects an OpenAI `prompt_cache_key` for caching-capable providers. Pure with respect to handler
* state (returns a fresh body, only logs as a side effect); behaviour is byte-identical to the
* previous inline block. Split into small private steps so each stays under the complexity cap.
*/
import {
applyConfiguredPayloadRules,
resolvePayloadRuleProtocols,
} from "../../services/payloadRules.ts";
import { getEffectiveToolLimit } from "../../services/toolLimitDetector.ts";
import { providerSupportsCaching } from "../../utils/cacheControlPolicy.ts";
import { MAX_TOOLS_LIMIT } from "../../config/constants.ts";
import { FORMATS } from "../../translator/formats.ts";
type LoggerLike = { debug?: (...args: unknown[]) => void } | null | undefined;
type Body = Record<string, unknown>;
type CredentialsLike = { apiKey?: unknown; accessToken?: unknown } | null | undefined;
function buildAppliedRulesSummary(
applied: Array<{ type: string; path: string; value?: unknown }>
): string {
return applied
.map((rule) => {
if (rule.type === "filter") return `${rule.type}:${rule.path}`;
const serializedValue = JSON.stringify(rule.value);
const safeValue =
typeof serializedValue === "string" && serializedValue.length > 80
? `${serializedValue.slice(0, 77)}...`
: serializedValue;
return `${rule.type}:${rule.path}=${safeValue}`;
})
.join(", ");
}
function truncateToolList(bodyToSend: Body, provider: string | null | undefined, log?: LoggerLike): Body {
const effectiveToolLimit = getEffectiveToolLimit(provider);
if (
effectiveToolLimit < MAX_TOOLS_LIMIT &&
Array.isArray(bodyToSend.tools) &&
bodyToSend.tools.length > effectiveToolLimit
) {
const truncatedTools = bodyToSend.tools.slice(0, effectiveToolLimit);
bodyToSend = { ...bodyToSend, tools: truncatedTools };
log?.debug?.(
"TOOL_LIMIT",
`Truncated ${(bodyToSend.tools as unknown[]).length} tools to ${effectiveToolLimit} for ${provider}`
);
}
return bodyToSend;
}
// Qwen OAuth rejects requests without a non-empty `user` field. Some minimal OpenAI-compatible
// clients omit it, so we backfill a stable default only for OAuth mode (API key mode is unaffected).
function backfillQwenOAuthUser(
bodyToSend: Body,
provider: string | null | undefined,
credentials: CredentialsLike,
log?: LoggerLike
): Body {
const hasValidQwenUser =
typeof bodyToSend.user === "string" && bodyToSend.user.trim().length > 0;
const isQwenOAuthRequest =
provider === "qwen" &&
!credentials?.apiKey &&
typeof credentials?.accessToken === "string" &&
credentials.accessToken.trim().length > 0;
if (isQwenOAuthRequest && !hasValidQwenUser) {
bodyToSend = { ...bodyToSend, user: "omniroute-qwen-oauth" };
log?.debug?.("QWEN", "Injected fallback user for OAuth request");
}
return bodyToSend;
}
// Inject prompt_cache_key only for providers that support it.
async function injectPromptCacheKey(
bodyToSend: Body,
provider: string | null | undefined,
targetFormat: string
): Promise<Body> {
if (
targetFormat === FORMATS.OPENAI &&
providerSupportsCaching(provider) &&
!bodyToSend.prompt_cache_key &&
Array.isArray(bodyToSend.messages) &&
!["nvidia", "codex", "xai"].includes(provider)
) {
const { generatePromptCacheKey } = await import("@/lib/promptCache");
const cacheKey = generatePromptCacheKey(bodyToSend.messages);
if (cacheKey) {
bodyToSend = { ...bodyToSend, prompt_cache_key: cacheKey };
}
}
return bodyToSend;
}
export async function prepareUpstreamBody(opts: {
translatedBody: Body;
modelToCall: string;
provider: string | null | undefined;
targetFormat: string;
credentials: CredentialsLike;
log?: LoggerLike;
}): Promise<Body> {
const { translatedBody, modelToCall, provider, targetFormat, credentials, log } = opts;
let bodyToSend: Body =
translatedBody.model === modelToCall
? translatedBody
: { ...translatedBody, model: modelToCall };
const payloadRuleModel =
typeof bodyToSend.model === "string" && bodyToSend.model.length > 0
? bodyToSend.model
: modelToCall;
const payloadRuleProtocols = resolvePayloadRuleProtocols({ provider, targetFormat });
const payloadRuleResult = await applyConfiguredPayloadRules(
bodyToSend,
payloadRuleModel,
payloadRuleProtocols
);
bodyToSend = payloadRuleResult.payload;
if (payloadRuleResult.applied.length > 0) {
log?.debug?.(
"PAYLOAD_RULES",
`Applied ${payloadRuleResult.applied.length} rule(s) for ${payloadRuleModel} (${payloadRuleProtocols.join(", ")}): ${buildAppliedRulesSummary(payloadRuleResult.applied)}`
);
}
bodyToSend = truncateToolList(bodyToSend, provider, log);
bodyToSend = backfillQwenOAuthUser(bodyToSend, provider, credentials, log);
bodyToSend = await injectPromptCacheKey(bodyToSend, provider, targetFormat);
return bodyToSend;
}

View File

@@ -0,0 +1,102 @@
// tests/unit/chatcore-upstream-body.test.ts
// Characterization of prepareUpstreamBody — the first internal sub-slice of executeProviderRequest
// (chatCore god-file decomposition, #3501). Uses a fresh temp DB (no payload rules / no detected
// tool limits → defaults). Locks: target-model pinning, the Qwen OAuth user backfill (and its
// guards), and the prompt_cache_key gating (excluded providers + non-OPENAI format never inject).
import { test, before, after } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const testDataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omni-upstream-body-test-"));
process.env.DATA_DIR = testDataDir;
const coreDb = await import("../../src/lib/db/core.ts");
const { prepareUpstreamBody } = await import("../../open-sse/handlers/chatCore/upstreamBody.ts");
before(async () => {
await coreDb.ensureDbInitialized();
});
after(() => {
coreDb.resetDbInstance();
fs.rmSync(testDataDir, { recursive: true, force: true });
});
test("pins the target model when it differs from the translated body model", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "model-a", messages: [] },
modelToCall: "model-b",
provider: "some-provider",
targetFormat: "claude",
credentials: null,
});
assert.equal(out.model, "model-b");
});
test("leaves the model untouched when it already matches", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "model-a", messages: [] },
modelToCall: "model-a",
provider: "some-provider",
targetFormat: "claude",
credentials: null,
});
assert.equal(out.model, "model-a");
});
test("backfills the Qwen OAuth user when missing", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "qwen-max", messages: [] },
modelToCall: "qwen-max",
provider: "qwen",
targetFormat: "claude",
credentials: { accessToken: "tok-123" },
});
assert.equal(out.user, "omniroute-qwen-oauth");
});
test("does not backfill the Qwen user when an apiKey is present (API-key mode)", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "qwen-max", messages: [] },
modelToCall: "qwen-max",
provider: "qwen",
targetFormat: "claude",
credentials: { apiKey: "k", accessToken: "tok-123" },
});
assert.equal(out.user, undefined);
});
test("does not backfill the Qwen user when one is already set", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "qwen-max", messages: [], user: "real-user" },
modelToCall: "qwen-max",
provider: "qwen",
targetFormat: "claude",
credentials: { accessToken: "tok-123" },
});
assert.equal(out.user, "real-user");
});
test("never injects prompt_cache_key for an excluded provider (codex)", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "gpt-5-codex", messages: [{ role: "user", content: "hi" }] },
modelToCall: "gpt-5-codex",
provider: "codex",
targetFormat: "openai",
credentials: null,
});
assert.equal(out.prompt_cache_key, undefined);
});
test("never injects prompt_cache_key when the target format is not OpenAI", async () => {
const out = await prepareUpstreamBody({
translatedBody: { model: "claude-x", messages: [{ role: "user", content: "hi" }] },
modelToCall: "claude-x",
provider: "claude",
targetFormat: "claude",
credentials: null,
});
assert.equal(out.prompt_cache_key, undefined);
});