Merge pull request #159 from Hureru/feat/account-level-proxy

feat(proxy): account-level proxy URL override
This commit is contained in:
Cita
2026-03-21 13:14:08 +08:00
committed by GitHub
20 changed files with 960 additions and 615 deletions
@@ -7,7 +7,7 @@ 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 { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { resolveChannelProxyUrl, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { type DownstreamFormat } from '../../transformers/shared/normalized.js';
import {
buildClaudeCountTokensUpstreamRequest,
@@ -204,6 +204,7 @@ export async function handleChatSurfaceRequest(
runtime: endpointRequest.runtime,
};
};
const channelProxyUrl = resolveChannelProxyUrl(selected.site, selected.account.extraConfig);
const dispatchRequest = (
compatibilityRequest: BuiltEndpointRequest,
targetUrl?: string,
@@ -216,7 +217,7 @@ export async function handleChatSurfaceRequest(
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, channelProxyUrl),
})
);
const endpointStrategy = downstreamTransformer.compatibility.createEndpointStrategy({
@@ -912,7 +913,7 @@ export async function handleClaudeCountTokensSurfaceRequest(
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, resolveChannelProxyUrl(selected.site, selected.account.extraConfig)),
});
if (upstream.status === 401 && oauth) {
@@ -932,7 +933,7 @@ export async function handleClaudeCountTokensSurfaceRequest(
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, resolveChannelProxyUrl(selected.site, selected.account.extraConfig)),
});
} catch {
// Fall through to the regular upstream error handling below.
@@ -9,7 +9,7 @@ import { isModelAllowedByPolicyOrAllowedRoutes } from '../../services/downstream
import { tokenRouter } from '../../services/tokenRouter.js';
import { buildOauthProviderHeaders } from '../../services/oauth/service.js';
import { getOauthInfoFromExtraConfig } from '../../services/oauth/oauthAccount.js';
import { withSiteProxyRequestInit } from '../../services/siteProxy.js';
import { resolveChannelProxyUrl, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { refreshModelsAndRebuildRoutes } from '../../services/modelService.js';
import { getDownstreamRoutingPolicy } from '../../routes/proxy/downstreamPolicy.js';
import { executeEndpointFlow, type BuiltEndpointRequest } from '../../routes/proxy/endpointFlow.js';
@@ -470,6 +470,7 @@ export async function geminiProxyRoute(app: FastifyInstance) {
selected.tokenValue,
query,
);
const channelProxyUrl = resolveChannelProxyUrl(selected.site, selected.account.extraConfig);
const upstream = isInternalGemini
? await dispatchRuntimeRequest({
siteUrl: selected.site.url,
@@ -489,11 +490,11 @@ export async function geminiProxyRoute(app: FastifyInstance) {
: (isStreamAction ? 'streamGenerateContent' : 'generateContent'),
},
},
buildInit: async (requestUrl, requestForFetch) => withSiteProxyRequestInit(requestUrl, {
buildInit: async (_requestUrl, requestForFetch) => withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, channelProxyUrl),
})
: await fetch(targetUrl, {
method: 'POST',
@@ -741,16 +742,17 @@ export async function geminiProxyRoute(app: FastifyInstance) {
runtime: endpointRequest.runtime,
};
};
const channelProxyUrl = resolveChannelProxyUrl(selected.site, selected.account.extraConfig);
const dispatchRequest = (compatibilityRequest: BuiltEndpointRequest, targetUrl?: string) => (
dispatchRuntimeRequest({
siteUrl: selected.site.url,
targetUrl,
request: compatibilityRequest,
buildInit: async (requestUrl, requestForFetch) => withSiteProxyRequestInit(requestUrl, {
buildInit: async (_requestUrl, requestForFetch) => withSiteRecordProxyRequestInit(selected.site, {
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, channelProxyUrl),
})
);
const endpointStrategy = createChatEndpointStrategy({
@@ -7,7 +7,7 @@ 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 { withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { resolveChannelProxyUrl, withSiteRecordProxyRequestInit } from '../../services/siteProxy.js';
import { openAiResponsesTransformer } from '../../transformers/openai/responses/index.js';
import {
buildUpstreamEndpointRequest,
@@ -304,6 +304,7 @@ export async function handleOpenAiResponsesSurfaceRequest(
runtime: endpointRequest.runtime,
};
};
const channelProxyUrl = resolveChannelProxyUrl(selected.site, selected.account.extraConfig);
const dispatchRequest = (compatibilityRequest: BuiltEndpointRequest, targetUrl?: string) => (
dispatchRuntimeRequest({
siteUrl: selected.site.url,
@@ -313,7 +314,7 @@ export async function handleOpenAiResponsesSurfaceRequest(
method: 'POST',
headers: requestForFetch.headers,
body: JSON.stringify(requestForFetch.body),
}),
}, channelProxyUrl),
})
);
const endpointStrategy = openAiResponsesTransformer.compatibility.createEndpointStrategy({