refactor: 更新未知平台的端点优先级逻辑

This commit is contained in:
ciat-777
2026-03-02 20:46:02 +08:00
parent 487bd23a02
commit 605c5e1959
2 changed files with 23 additions and 13 deletions
@@ -28,7 +28,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
fetchModelPricingCatalogMock.mockResolvedValue(null); fetchModelPricingCatalogMock.mockResolvedValue(null);
}); });
it('uses responses -> messages -> chat for unknown platforms', async () => { it('uses downstream-aligned endpoint priority for unknown platforms', async () => {
const openaiOrder = await resolveUpstreamEndpointCandidates( const openaiOrder = await resolveUpstreamEndpointCandidates(
{ {
...baseContext, ...baseContext,
@@ -37,7 +37,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3', 'gpt-5.3',
'openai', 'openai',
); );
expect(openaiOrder).toEqual(['responses', 'messages', 'chat']); expect(openaiOrder).toEqual(['chat', 'messages', 'responses']);
const claudeOrder = await resolveUpstreamEndpointCandidates( const claudeOrder = await resolveUpstreamEndpointCandidates(
{ {
@@ -47,7 +47,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3', 'gpt-5.3',
'claude', 'claude',
); );
expect(claudeOrder).toEqual(['responses', 'messages', 'chat']); expect(claudeOrder).toEqual(['messages', 'chat', 'responses']);
const responsesOrder = await resolveUpstreamEndpointCandidates( const responsesOrder = await resolveUpstreamEndpointCandidates(
{ {
@@ -57,7 +57,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3', 'gpt-5.3',
'responses', 'responses',
); );
expect(responsesOrder).toEqual(['responses', 'messages', 'chat']); expect(responsesOrder).toEqual(['responses', 'chat', 'messages']);
}); });
it('keeps explicit platform priority rules', async () => { it('keeps explicit platform priority rules', async () => {
+19 -9
View File
@@ -381,9 +381,17 @@ function preferredEndpointOrder(downstreamFormat: EndpointPreference, sitePlatfo
return ['messages']; return ['messages'];
} }
// Unknown/generic upstreams: try the most expressive protocol first, // Unknown/generic upstreams: prefer endpoint family that matches the
// then degrade to anthropic messages, and finally chat completions. // downstream API surface, then degrade progressively.
return ['responses', 'messages', 'chat']; if (downstreamFormat === 'responses') {
return ['responses', 'chat', 'messages'];
}
if (downstreamFormat === 'claude') {
return ['messages', 'chat', 'responses'];
}
return ['chat', 'messages', 'responses'];
} }
export async function resolveUpstreamEndpointCandidates( export async function resolveUpstreamEndpointCandidates(
@@ -438,13 +446,15 @@ export async function resolveUpstreamEndpointCandidates(
if (supported.size === 0) return preferred; if (supported.size === 0) return preferred;
const filtered = preferred.filter((endpoint) => supported.has(endpoint)); const firstSupported = preferred.find((endpoint) => supported.has(endpoint));
if (filtered.length === 0) return preferred; if (!firstSupported) return preferred;
// Keep non-catalog endpoints as best-effort fallbacks because some // Catalog metadata can be incomplete/inaccurate, so only use it to pick
// upstreams expose incomplete/incorrect endpoint metadata. // the first attempt. Keep downstream-driven fallback order unchanged.
const fallback = preferred.filter((endpoint) => !filtered.includes(endpoint)); return [
return [...filtered, ...fallback]; firstSupported,
...preferred.filter((endpoint) => endpoint !== firstSupported),
];
} catch { } catch {
return preferred; return preferred;
} }