Merge remote-tracking branch 'origin/pr/593'

This commit is contained in:
elky
2026-06-02 21:40:59 +08:00
56 changed files with 1605 additions and 42 deletions
@@ -32,7 +32,13 @@ describe('global model form embedding payload helpers', () => {
streaming: false,
embedding: true,
model_type: 'embedding',
api_formats: ['openai:embedding', 'gemini:embedding', 'jina:embedding', 'doubao:embedding'],
api_formats: [
'openai:embedding',
'gemini:embedding',
'jina:embedding',
'doubao:embedding',
'aliyun:multimodal_embedding',
],
},
})
})
@@ -6,6 +6,7 @@ export const EMBEDDING_API_FORMATS = [
'gemini:embedding',
'jina:embedding',
'doubao:embedding',
'aliyun:multimodal_embedding',
] as const
export const RERANK_API_FORMATS = [
@@ -16,6 +16,7 @@ describe('provider model form embedding helpers', () => {
{ supported_capabilities: null, config: { embedding: true } },
{ supported_capabilities: null, config: { model_type: 'embedding' } },
{ supported_capabilities: null, config: { api_formats: ['doubao:embedding'] } },
{ supported_capabilities: null, config: { api_formats: ['aliyun:multimodal_embedding'] } },
{ supports_embedding: true, effective_supports_embedding: null, config: {} },
{ supports_embedding: null, effective_supports_embedding: true, config: {} },
])('detects embedding metadata from %o', (model) => {
@@ -7,6 +7,11 @@ interface EmbeddingMetadataCarrier {
config?: Record<string, unknown> | null
}
function isEmbeddingApiFormat(format: unknown): boolean {
const value = String(format).trim().toLowerCase()
return value.endsWith(':embedding') || value === 'aliyun:multimodal_embedding'
}
export interface ProviderModelCreatePayloadInput {
globalModelId: string
providerModelName: string
@@ -45,7 +50,7 @@ export function modelSupportsEmbedding(model: EmbeddingMetadataCarrier | null |
return supportedCapabilities?.includes('embedding') === true
|| config.embedding === true
|| config.model_type === 'embedding'
|| (Array.isArray(config.api_formats) && config.api_formats.some((format) => String(format).endsWith(':embedding')))
|| (Array.isArray(config.api_formats) && config.api_formats.some(isEmbeddingApiFormat))
}
export function buildProviderModelCreatePayload(input: ProviderModelCreatePayloadInput): ModelCreate {
@@ -34,6 +34,21 @@ describe('buildDefaultModelTestRequestBody', () => {
expect(body.stream).toBeUndefined()
})
it('uses multimodal input and qwen3-vl defaults for Aliyun embedding tests', () => {
const body = JSON.parse(buildDefaultModelTestRequestBody('qwen3-vl-embedding', 'aliyun:multimodal_embedding'))
expect(body).toEqual({
model: 'qwen3-vl-embedding',
input: [
{ text: 'White running shoes, lightweight and breathable.' },
{ image: 'https://dashscope.oss-cn-beijing.aliyuncs.com/images/256_1.png' },
],
parameters: {
enable_fusion: true,
},
})
})
it.each([
'openai:rerank',
'jina:rerank',
@@ -151,6 +151,19 @@ export function buildDefaultModelTestRequestBody(
): string {
const normalizedApiFormat = normalizeApiFormatAlias(apiFormat ?? '')
if (normalizedApiFormat === 'aliyun:multimodal_embedding') {
return JSON.stringify({
model: modelName,
input: [
{ text: 'White running shoes, lightweight and breathable.' },
{ image: 'https://dashscope.oss-cn-beijing.aliyuncs.com/images/256_1.png' },
],
parameters: {
enable_fusion: true,
},
}, null, 2)
}
if (normalizedApiFormat.endsWith(':embedding')) {
return JSON.stringify({
model: modelName,
@@ -273,4 +286,4 @@ export function parseModelTestRequestHeadersDraft(
emptyError: null,
invalidTypeError: '测试请求头必须是 JSON 对象',
})
}
}
@@ -18,6 +18,7 @@ const ENDPOINT_SORT_ORDER = [
'jina:embedding',
'jina:rerank',
'doubao:embedding',
'aliyun:multimodal_embedding',
]
/**
@@ -34,6 +34,7 @@ export function useProviderFilters(
{ value: 'jina:embedding', label: 'Jina Embedding' },
{ value: 'jina:rerank', label: 'Jina Rerank' },
{ value: 'doubao:embedding', label: 'Doubao Embedding' },
{ value: 'aliyun:multimodal_embedding', label: 'Aliyun Multimodal Embedding' },
]
const modelFilters = computed<FilterOption[]>(() => {