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);
});
it('uses responses -> messages -> chat for unknown platforms', async () => {
it('uses downstream-aligned endpoint priority for unknown platforms', async () => {
const openaiOrder = await resolveUpstreamEndpointCandidates(
{
...baseContext,
@@ -37,7 +37,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3',
'openai',
);
expect(openaiOrder).toEqual(['responses', 'messages', 'chat']);
expect(openaiOrder).toEqual(['chat', 'messages', 'responses']);
const claudeOrder = await resolveUpstreamEndpointCandidates(
{
@@ -47,7 +47,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3',
'claude',
);
expect(claudeOrder).toEqual(['responses', 'messages', 'chat']);
expect(claudeOrder).toEqual(['messages', 'chat', 'responses']);
const responsesOrder = await resolveUpstreamEndpointCandidates(
{
@@ -57,7 +57,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
'gpt-5.3',
'responses',
);
expect(responsesOrder).toEqual(['responses', 'messages', 'chat']);
expect(responsesOrder).toEqual(['responses', 'chat', 'messages']);
});
it('keeps explicit platform priority rules', async () => {
+19 -9
View File
@@ -381,9 +381,17 @@ function preferredEndpointOrder(downstreamFormat: EndpointPreference, sitePlatfo
return ['messages'];
}
// Unknown/generic upstreams: try the most expressive protocol first,
// then degrade to anthropic messages, and finally chat completions.
return ['responses', 'messages', 'chat'];
// Unknown/generic upstreams: prefer endpoint family that matches the
// downstream API surface, then degrade progressively.
if (downstreamFormat === 'responses') {
return ['responses', 'chat', 'messages'];
}
if (downstreamFormat === 'claude') {
return ['messages', 'chat', 'responses'];
}
return ['chat', 'messages', 'responses'];
}
export async function resolveUpstreamEndpointCandidates(
@@ -438,13 +446,15 @@ export async function resolveUpstreamEndpointCandidates(
if (supported.size === 0) return preferred;
const filtered = preferred.filter((endpoint) => supported.has(endpoint));
if (filtered.length === 0) return preferred;
const firstSupported = preferred.find((endpoint) => supported.has(endpoint));
if (!firstSupported) return preferred;
// Keep non-catalog endpoints as best-effort fallbacks because some
// upstreams expose incomplete/incorrect endpoint metadata.
const fallback = preferred.filter((endpoint) => !filtered.includes(endpoint));
return [...filtered, ...fallback];
// Catalog metadata can be incomplete/inaccurate, so only use it to pick
// the first attempt. Keep downstream-driven fallback order unchanged.
return [
firstSupported,
...preferred.filter((endpoint) => endpoint !== firstSupported),
];
} catch {
return preferred;
}