2026-03-19 23:52:17 +08:00
|
|
|
const DEFAULT_MODEL_TEST_MESSAGE = 'Hello! This is a test message.'
|
|
|
|
|
|
2026-03-20 00:24:56 +08:00
|
|
|
/** Pool-managed provider runs concurrent checks; single-key provider does not. */
|
|
|
|
|
export const POOL_TEST_CONCURRENCY = 5
|
|
|
|
|
export const SINGLE_TEST_CONCURRENCY = 1
|
|
|
|
|
|
2026-05-03 17:32:41 +08:00
|
|
|
export function buildDefaultModelTestRequestBody(modelName: string, apiFormat?: string | null): string {
|
|
|
|
|
if (apiFormat?.trim().toLowerCase().endsWith(':embedding')) {
|
|
|
|
|
return JSON.stringify({
|
|
|
|
|
model: modelName,
|
|
|
|
|
input: 'This is a test embedding input.',
|
|
|
|
|
}, null, 2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (apiFormat?.trim().toLowerCase().endsWith(':rerank')) {
|
|
|
|
|
return JSON.stringify({
|
|
|
|
|
model: modelName,
|
|
|
|
|
query: 'This is a test rerank query.',
|
|
|
|
|
documents: [
|
|
|
|
|
'This document is relevant to the test query.',
|
|
|
|
|
'This document is unrelated.',
|
|
|
|
|
],
|
|
|
|
|
top_n: 1,
|
|
|
|
|
return_documents: true,
|
|
|
|
|
}, null, 2)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 23:52:17 +08:00
|
|
|
return JSON.stringify({
|
|
|
|
|
model: modelName,
|
|
|
|
|
messages: [
|
|
|
|
|
{
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: DEFAULT_MODEL_TEST_MESSAGE,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
max_tokens: 30,
|
|
|
|
|
temperature: 0.7,
|
|
|
|
|
stream: true,
|
|
|
|
|
}, null, 2)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 00:24:56 +08:00
|
|
|
export function buildDefaultModelTestRequestHeaders(): string {
|
|
|
|
|
return JSON.stringify({}, null, 2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseModelTestJsonObjectDraft(
|
2026-03-19 23:52:17 +08:00
|
|
|
draft: string,
|
2026-03-20 00:24:56 +08:00
|
|
|
options: {
|
|
|
|
|
emptyValue: Record<string, unknown> | null
|
|
|
|
|
emptyError: string | null
|
|
|
|
|
invalidTypeError: string
|
|
|
|
|
},
|
2026-03-19 23:52:17 +08:00
|
|
|
): { value: Record<string, unknown> | null; error: string | null } {
|
|
|
|
|
const normalized = draft.trim()
|
|
|
|
|
if (!normalized) {
|
|
|
|
|
return {
|
2026-03-20 00:24:56 +08:00
|
|
|
value: options.emptyValue,
|
|
|
|
|
error: options.emptyError,
|
2026-03-19 23:52:17 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const parsed = JSON.parse(normalized)
|
|
|
|
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
|
|
|
return {
|
|
|
|
|
value: null,
|
2026-03-20 00:24:56 +08:00
|
|
|
error: options.invalidTypeError,
|
2026-03-19 23:52:17 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
value: parsed as Record<string, unknown>,
|
|
|
|
|
error: null,
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return {
|
|
|
|
|
value: null,
|
|
|
|
|
error: error instanceof Error ? error.message : '无效的 JSON',
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-20 00:24:56 +08:00
|
|
|
|
|
|
|
|
export function parseModelTestRequestBodyDraft(
|
|
|
|
|
draft: string,
|
|
|
|
|
): { value: Record<string, unknown> | null; error: string | null } {
|
|
|
|
|
return parseModelTestJsonObjectDraft(draft, {
|
|
|
|
|
emptyValue: null,
|
|
|
|
|
emptyError: '测试请求体不能为空',
|
|
|
|
|
invalidTypeError: '测试请求体必须是 JSON 对象',
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function parseModelTestRequestHeadersDraft(
|
|
|
|
|
draft: string,
|
|
|
|
|
): { value: Record<string, unknown> | null; error: string | null } {
|
|
|
|
|
return parseModelTestJsonObjectDraft(draft, {
|
|
|
|
|
emptyValue: {},
|
|
|
|
|
emptyError: null,
|
|
|
|
|
invalidTypeError: '测试请求头必须是 JSON 对象',
|
|
|
|
|
})
|
|
|
|
|
}
|