feat(proxy): pass account proxy through all proxy route handlers

Thread account-level proxyUrl from extraConfig into
resolveChannelProxyUrl for endpointFlow and the third parameter
of withSiteRecordProxyRequestInit for direct fetch calls across
chat, responses, completions, embeddings, images, search, and
videos proxy routes.
This commit is contained in:
Hureru
2026-03-16 01:06:16 +08:00
parent b43a4fd2ea
commit 6d2f1c4b81
7 changed files with 535 additions and 526 deletions
+4 -3
View File
@@ -8,7 +8,8 @@ import { isTokenExpiredError } from '../../services/alertRules.js';
import { shouldRetryProxyRequest } from '../../services/proxyRetryPolicy.js';
import { resolveProxyUsageWithSelfLogFallback } from '../../services/proxyUsageFallbackService.js';
import { mergeProxyUsage, parseProxyUsage } from '../../services/proxyUsageParser.js';
import { resolveProxyUrlForSite, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { resolveChannelProxyUrl, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { type DownstreamFormat } from '../../transformers/shared/normalized.js';
import {
buildUpstreamEndpointRequest,
@@ -168,7 +169,7 @@ async function handleChatProxyRequest(
method: 'POST',
headers: compatibilityRequest.headers,
body: JSON.stringify(compatibilityRequest.body),
}),
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)),
),
});
let startTime = Date.now();
@@ -176,7 +177,7 @@ async function handleChatProxyRequest(
try {
const endpointResult = await executeEndpointFlow({
siteUrl: selected.site.url,
proxyUrl: resolveProxyUrlForSite(selected.site),
proxyUrl: resolveChannelProxyUrl(selected.site, selected.account.extraConfig),
endpointCandidates,
buildRequest: (endpoint) => buildEndpointRequest(endpoint),
tryRecover: endpointStrategy.tryRecover,
+2 -1
View File
@@ -10,6 +10,7 @@ import { resolveProxyUsageWithSelfLogFallback } from '../../services/proxyUsageF
import { mergeProxyUsage, parseProxyUsage, pullSseDataEvents } from '../../services/proxyUsageParser.js';
import { ensureModelAllowedForDownstreamKey, getDownstreamRoutingPolicy, recordDownstreamCostUsage } from './downstreamPolicy.js';
import { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { composeProxyLogMessage } from './logPathMeta.js';
import { formatUtcSqlDateTime } from '../../services/localTimeService.js';
import { resolveProxyLogBilling } from './proxyBilling.js';
@@ -65,7 +66,7 @@ export async function completionsProxyRoute(app: FastifyInstance) {
'Authorization': `Bearer ${selected.tokenValue}`,
},
body: JSON.stringify(forwardBody),
}));
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)));
if (!upstream.ok) {
const errText = await upstream.text().catch(() => 'unknown error');
+2 -1
View File
@@ -10,6 +10,7 @@ import { resolveProxyUsageWithSelfLogFallback } from '../../services/proxyUsageF
import { parseProxyUsage } from '../../services/proxyUsageParser.js';
import { ensureModelAllowedForDownstreamKey, getDownstreamRoutingPolicy, recordDownstreamCostUsage } from './downstreamPolicy.js';
import { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { composeProxyLogMessage } from './logPathMeta.js';
import { formatUtcSqlDateTime } from '../../services/localTimeService.js';
import { resolveProxyLogBilling } from './proxyBilling.js';
@@ -62,7 +63,7 @@ export async function embeddingsProxyRoute(app: FastifyInstance) {
'Authorization': `Bearer ${selected.tokenValue}`,
},
body: JSON.stringify(forwardBody),
}));
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)));
const text = await upstream.text();
if (!upstream.ok) {
+5 -3
View File
@@ -9,6 +9,7 @@ import { estimateProxyCost } from '../../services/modelPricingService.js';
import { shouldRetryProxyRequest } from '../../services/proxyRetryPolicy.js';
import { ensureModelAllowedForDownstreamKey, getDownstreamRoutingPolicy, recordDownstreamCostUsage } from './downstreamPolicy.js';
import { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { composeProxyLogMessage } from './logPathMeta.js';
import { formatUtcSqlDateTime } from '../../services/localTimeService.js';
import { cloneFormDataWithOverrides, ensureMultipartBufferParser, parseMultipartFormData } from './multipart.js';
@@ -61,7 +62,7 @@ export async function imagesProxyRoute(app: FastifyInstance) {
'Authorization': `Bearer ${selected.tokenValue}`,
},
body: JSON.stringify(forwardBody),
}));
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)));
const text = await upstream.text();
if (!upstream.ok) {
@@ -159,6 +160,7 @@ export async function imagesProxyRoute(app: FastifyInstance) {
const startTime = Date.now();
try {
const accountProxy = getProxyUrlFromExtraConfig(selected.account.extraConfig);
const requestInit = multipartForm
? withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
@@ -168,7 +170,7 @@ export async function imagesProxyRoute(app: FastifyInstance) {
body: cloneFormDataWithOverrides(multipartForm, {
model: selected.actualModel || requestedModel,
}) as any,
})
}, accountProxy)
: withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
headers: {
@@ -179,7 +181,7 @@ export async function imagesProxyRoute(app: FastifyInstance) {
...(jsonBody || {}),
model: selected.actualModel || requestedModel,
}),
});
}, accountProxy);
const upstream = await fetch(targetUrl, requestInit);
const text = await upstream.text();
+4 -3
View File
@@ -8,7 +8,8 @@ import { isTokenExpiredError } from '../../services/alertRules.js';
import { shouldRetryProxyRequest } from '../../services/proxyRetryPolicy.js';
import { resolveProxyUsageWithSelfLogFallback } from '../../services/proxyUsageFallbackService.js';
import { mergeProxyUsage, parseProxyUsage } from '../../services/proxyUsageParser.js';
import { resolveProxyUrlForSite, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { resolveChannelProxyUrl, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { openAiResponsesTransformer } from '../../transformers/openai/responses/index.js';
import {
buildUpstreamEndpointRequest,
@@ -259,7 +260,7 @@ export async function responsesProxyRoute(app: FastifyInstance) {
method: 'POST',
headers: compatibilityRequest.headers,
body: JSON.stringify(compatibilityRequest.body),
}),
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)),
),
});
@@ -268,7 +269,7 @@ export async function responsesProxyRoute(app: FastifyInstance) {
try {
const endpointResult = await executeEndpointFlow({
siteUrl: selected.site.url,
proxyUrl: resolveProxyUrlForSite(selected.site),
proxyUrl: resolveChannelProxyUrl(selected.site, selected.account.extraConfig),
endpointCandidates,
buildRequest: (endpoint) => buildEndpointRequest(endpoint),
tryRecover: endpointStrategy.tryRecover,
+2 -1
View File
@@ -8,6 +8,7 @@ import { isTokenExpiredError } from '../../services/alertRules.js';
import { shouldRetryProxyRequest } from '../../services/proxyRetryPolicy.js';
import { ensureModelAllowedForDownstreamKey, getDownstreamRoutingPolicy, recordDownstreamCostUsage } from './downstreamPolicy.js';
import { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { composeProxyLogMessage } from './logPathMeta.js';
import { formatUtcSqlDateTime } from '../../services/localTimeService.js';
import { buildUpstreamUrl } from './upstreamUrl.js';
@@ -92,7 +93,7 @@ export async function searchProxyRoute(app: FastifyInstance) {
Authorization: `Bearer ${selected.tokenValue}`,
},
body: JSON.stringify(forwardBody),
}));
}, getProxyUrlFromExtraConfig(selected.account.extraConfig)));
const text = await upstream.text();
if (!upstream.ok) {
+4 -2
View File
@@ -8,6 +8,7 @@ import { estimateProxyCost } from '../../services/modelPricingService.js';
import { shouldRetryProxyRequest } from '../../services/proxyRetryPolicy.js';
import { ensureModelAllowedForDownstreamKey, getDownstreamRoutingPolicy, recordDownstreamCostUsage } from './downstreamPolicy.js';
import { withSiteProxyRequestInit, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { getProxyUrlFromExtraConfig } from '../../services/accountExtraConfig.js';
import { cloneFormDataWithOverrides, ensureMultipartBufferParser, parseMultipartFormData } from './multipart.js';
import { buildUpstreamUrl } from './upstreamUrl.js';
import {
@@ -75,6 +76,7 @@ export async function videosProxyRoute(app: FastifyInstance) {
const startTime = Date.now();
try {
const accountProxy = getProxyUrlFromExtraConfig(selected.account.extraConfig);
const requestInit = multipartForm
? withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
@@ -84,7 +86,7 @@ export async function videosProxyRoute(app: FastifyInstance) {
body: cloneFormDataWithOverrides(multipartForm, {
model: selected.actualModel || requestedModel,
}) as any,
})
}, accountProxy)
: withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
headers: {
@@ -95,7 +97,7 @@ export async function videosProxyRoute(app: FastifyInstance) {
...(jsonBody || {}),
model: selected.actualModel || requestedModel,
}),
});
}, accountProxy);
const upstream = await fetch(targetUrl, requestInit);
const text = await upstream.text();