fix: avoid messages fallback for generic file uploads

This commit is contained in:
ciat-777
2026-03-21 14:03:35 +08:00
parent 424e1e210b
commit 17a4281117
3 changed files with 30 additions and 13 deletions
@@ -60,6 +60,16 @@ describe('conversationFileCapabilities', () => {
document: 'inline_only', document: 'inline_only',
preservesRemoteDocumentUrl: false, preservesRemoteDocumentUrl: false,
}); });
expect(resolveConversationFileEndpointCapability({
sitePlatform: 'new-api',
endpoint: 'messages',
})).toMatchObject({
image: 'native',
audio: 'unsupported',
document: 'unsupported',
preservesRemoteDocumentUrl: false,
});
}); });
it('ranks document-capable endpoints ahead of lossy fallbacks', () => { it('ranks document-capable endpoints ahead of lossy fallbacks', () => {
@@ -74,6 +84,6 @@ describe('conversationFileCapabilities', () => {
}, },
}); });
expect(ranked).toEqual(['responses', 'messages', 'chat']); expect(ranked).toEqual(['responses', 'chat']);
}); });
}); });
@@ -218,7 +218,7 @@ export function resolveConversationFileEndpointCapability(input: {
return { return {
image: 'native', image: 'native',
audio: 'unsupported', audio: 'unsupported',
document: 'inline_only', document: 'unsupported',
preservesRemoteDocumentUrl: false, preservesRemoteDocumentUrl: false,
}; };
} }
@@ -241,27 +241,34 @@ export function rankConversationFileEndpoints(input: {
return [...input.requestedOrder]; return [...input.requestedOrder];
} }
const isDocumentCompatible = (endpoint: ConversationFileEndpoint) => {
const capability = resolveConversationFileEndpointCapability({
sitePlatform: input.sitePlatform,
endpoint,
});
if (capability.document === 'unsupported') return false;
if (input.summary.hasRemoteDocumentUrl && !capability.preservesRemoteDocumentUrl) return false;
return true;
};
const preferredDocumentOrder = input.preferMessagesForClaudeModel === true const preferredDocumentOrder = input.preferMessagesForClaudeModel === true
? ['messages', 'responses', 'chat'] ? ['messages', 'responses', 'chat']
: ['responses', 'messages', 'chat']; : ['responses', 'messages', 'chat'];
const supportedDocumentEndpoints = preferredDocumentOrder.filter((endpoint) => { const supportedDocumentEndpoints = preferredDocumentOrder.filter((endpoint) => {
if (!input.requestedOrder.includes(endpoint as ConversationFileEndpoint)) return false; if (!input.requestedOrder.includes(endpoint as ConversationFileEndpoint)) return false;
const capability = resolveConversationFileEndpointCapability({ return isDocumentCompatible(endpoint as ConversationFileEndpoint);
sitePlatform: input.sitePlatform,
endpoint: endpoint as ConversationFileEndpoint,
});
if (capability.document === 'unsupported') return false;
if (input.summary.hasRemoteDocumentUrl && !capability.preservesRemoteDocumentUrl) return false;
return true;
}) as ConversationFileEndpoint[]; }) as ConversationFileEndpoint[];
if (supportedDocumentEndpoints.length <= 0) { if (supportedDocumentEndpoints.length <= 0) {
return [...input.requestedOrder]; return [];
} }
return [ return [
...supportedDocumentEndpoints, ...supportedDocumentEndpoints,
...input.requestedOrder.filter((endpoint) => !supportedDocumentEndpoints.includes(endpoint)), ...input.requestedOrder.filter((endpoint) => (
!supportedDocumentEndpoints.includes(endpoint)
&& isDocumentCompatible(endpoint)
)),
]; ];
} }
@@ -193,7 +193,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
}, },
); );
expect(order).toEqual(['responses', 'messages', 'chat']); expect(order).toEqual(['responses', 'chat']);
}); });
it('remembers the last successful endpoint per site capability profile', async () => { it('remembers the last successful endpoint per site capability profile', async () => {
@@ -252,7 +252,7 @@ describe('resolveUpstreamEndpointCandidates', () => {
}, },
); );
expect(order).toEqual(['responses', 'messages', 'chat']); expect(order).toEqual(['responses']);
}); });
it('does not remember messages fallback success for generic /v1/responses requests', async () => { it('does not remember messages fallback success for generic /v1/responses requests', async () => {