Commit 63bbd9e3 by CaIon

feat: add endpoint type selection to channel testing functionality

parent f92d7834
...@@ -23,6 +23,7 @@ var defaultEndpointInfoMap = map[constant.EndpointType]EndpointInfo{ ...@@ -23,6 +23,7 @@ var defaultEndpointInfoMap = map[constant.EndpointType]EndpointInfo{
constant.EndpointTypeGemini: {Path: "/v1beta/models/{model}:generateContent", Method: "POST"}, constant.EndpointTypeGemini: {Path: "/v1beta/models/{model}:generateContent", Method: "POST"},
constant.EndpointTypeJinaRerank: {Path: "/rerank", Method: "POST"}, constant.EndpointTypeJinaRerank: {Path: "/rerank", Method: "POST"},
constant.EndpointTypeImageGeneration: {Path: "/v1/images/generations", Method: "POST"}, constant.EndpointTypeImageGeneration: {Path: "/v1/images/generations", Method: "POST"},
constant.EndpointTypeEmbeddings: {Path: "/v1/embeddings", Method: "POST"},
} }
// GetDefaultEndpointInfo 返回指定端点类型的默认信息以及是否存在 // GetDefaultEndpointInfo 返回指定端点类型的默认信息以及是否存在
......
...@@ -9,6 +9,7 @@ const ( ...@@ -9,6 +9,7 @@ const (
EndpointTypeGemini EndpointType = "gemini" EndpointTypeGemini EndpointType = "gemini"
EndpointTypeJinaRerank EndpointType = "jina-rerank" EndpointTypeJinaRerank EndpointType = "jina-rerank"
EndpointTypeImageGeneration EndpointType = "image-generation" EndpointTypeImageGeneration EndpointType = "image-generation"
EndpointTypeEmbeddings EndpointType = "embeddings"
//EndpointTypeMidjourney EndpointType = "midjourney-proxy" //EndpointTypeMidjourney EndpointType = "midjourney-proxy"
//EndpointTypeSuno EndpointType = "suno-proxy" //EndpointTypeSuno EndpointType = "suno-proxy"
//EndpointTypeKling EndpointType = "kling" //EndpointTypeKling EndpointType = "kling"
......
...@@ -25,6 +25,7 @@ import { ...@@ -25,6 +25,7 @@ import {
Table, Table,
Tag, Tag,
Typography, Typography,
Select,
} from '@douyinfe/semi-ui'; } from '@douyinfe/semi-ui';
import { IconSearch } from '@douyinfe/semi-icons'; import { IconSearch } from '@douyinfe/semi-icons';
import { copy, showError, showInfo, showSuccess } from '../../../../helpers'; import { copy, showError, showInfo, showSuccess } from '../../../../helpers';
...@@ -45,6 +46,8 @@ const ModelTestModal = ({ ...@@ -45,6 +46,8 @@ const ModelTestModal = ({
testChannel, testChannel,
modelTablePage, modelTablePage,
setModelTablePage, setModelTablePage,
selectedEndpointType,
setSelectedEndpointType,
allSelectingRef, allSelectingRef,
isMobile, isMobile,
t, t,
...@@ -59,6 +62,17 @@ const ModelTestModal = ({ ...@@ -59,6 +62,17 @@ const ModelTestModal = ({
) )
: []; : [];
const endpointTypeOptions = [
{ value: '', label: t('自动检测') },
{ value: 'openai', label: 'OpenAI (/v1/chat/completions)' },
{ value: 'openai-response', label: 'OpenAI Response (/v1/responses)' },
{ value: 'anthropic', label: 'Anthropic (/v1/messages)' },
{ value: 'gemini', label: 'Gemini (/v1beta/models/{model}:generateContent)' },
{ value: 'jina-rerank', label: 'Jina Rerank (/rerank)' },
{ value: 'image-generation', label: t('图像生成') + ' (/v1/images/generations)' },
{ value: 'embeddings', label: 'Embeddings (/v1/embeddings)' },
];
const handleCopySelected = () => { const handleCopySelected = () => {
if (selectedModelKeys.length === 0) { if (selectedModelKeys.length === 0) {
showError(t('请先选择模型!')); showError(t('请先选择模型!'));
...@@ -152,7 +166,7 @@ const ModelTestModal = ({ ...@@ -152,7 +166,7 @@ const ModelTestModal = ({
return ( return (
<Button <Button
type='tertiary' type='tertiary'
onClick={() => testChannel(currentTestChannel, record.model)} onClick={() => testChannel(currentTestChannel, record.model, selectedEndpointType)}
loading={isTesting} loading={isTesting}
size='small' size='small'
> >
...@@ -228,6 +242,18 @@ const ModelTestModal = ({ ...@@ -228,6 +242,18 @@ const ModelTestModal = ({
> >
{hasChannel && ( {hasChannel && (
<div className='model-test-scroll'> <div className='model-test-scroll'>
{/* 端点类型选择器 */}
<div className='flex items-center gap-2 w-full mb-2'>
<Typography.Text strong>{t('端点类型')}:</Typography.Text>
<Select
value={selectedEndpointType}
onChange={setSelectedEndpointType}
optionList={endpointTypeOptions}
className='!w-full'
placeholder={t('选择端点类型')}
/>
</div>
{/* 搜索与操作按钮 */} {/* 搜索与操作按钮 */}
<div className='flex items-center justify-end gap-2 w-full mb-2'> <div className='flex items-center justify-end gap-2 w-full mb-2'>
<Input <Input
......
...@@ -80,6 +80,7 @@ export const useChannelsData = () => { ...@@ -80,6 +80,7 @@ export const useChannelsData = () => {
const [selectedModelKeys, setSelectedModelKeys] = useState([]); const [selectedModelKeys, setSelectedModelKeys] = useState([]);
const [isBatchTesting, setIsBatchTesting] = useState(false); const [isBatchTesting, setIsBatchTesting] = useState(false);
const [modelTablePage, setModelTablePage] = useState(1); const [modelTablePage, setModelTablePage] = useState(1);
const [selectedEndpointType, setSelectedEndpointType] = useState('');
// 使用 ref 来避免闭包问题,类似旧版实现 // 使用 ref 来避免闭包问题,类似旧版实现
const shouldStopBatchTestingRef = useRef(false); const shouldStopBatchTestingRef = useRef(false);
...@@ -691,7 +692,7 @@ export const useChannelsData = () => { ...@@ -691,7 +692,7 @@ export const useChannelsData = () => {
}; };
// Test channel - 单个模型测试,参考旧版实现 // Test channel - 单个模型测试,参考旧版实现
const testChannel = async (record, model) => { const testChannel = async (record, model, endpointType = '') => {
const testKey = `${record.id}-${model}`; const testKey = `${record.id}-${model}`;
// 检查是否应该停止批量测试 // 检查是否应该停止批量测试
...@@ -703,7 +704,11 @@ export const useChannelsData = () => { ...@@ -703,7 +704,11 @@ export const useChannelsData = () => {
setTestingModels(prev => new Set([...prev, model])); setTestingModels(prev => new Set([...prev, model]));
try { try {
const res = await API.get(`/api/channel/test/${record.id}?model=${model}`); let url = `/api/channel/test/${record.id}?model=${model}`;
if (endpointType) {
url += `&endpoint_type=${endpointType}`;
}
const res = await API.get(url);
// 检查是否在请求期间被停止 // 检查是否在请求期间被停止
if (shouldStopBatchTestingRef.current && isBatchTesting) { if (shouldStopBatchTestingRef.current && isBatchTesting) {
...@@ -820,7 +825,7 @@ export const useChannelsData = () => { ...@@ -820,7 +825,7 @@ export const useChannelsData = () => {
.replace('${total}', models.length) .replace('${total}', models.length)
); );
const batchPromises = batch.map(model => testChannel(currentTestChannel, model)); const batchPromises = batch.map(model => testChannel(currentTestChannel, model, selectedEndpointType));
const batchResults = await Promise.allSettled(batchPromises); const batchResults = await Promise.allSettled(batchPromises);
results.push(...batchResults); results.push(...batchResults);
...@@ -902,6 +907,7 @@ export const useChannelsData = () => { ...@@ -902,6 +907,7 @@ export const useChannelsData = () => {
setTestingModels(new Set()); setTestingModels(new Set());
setSelectedModelKeys([]); setSelectedModelKeys([]);
setModelTablePage(1); setModelTablePage(1);
setSelectedEndpointType('');
// 可选择性保留测试结果,这里不清空以便用户查看 // 可选择性保留测试结果,这里不清空以便用户查看
}; };
...@@ -989,6 +995,8 @@ export const useChannelsData = () => { ...@@ -989,6 +995,8 @@ export const useChannelsData = () => {
isBatchTesting, isBatchTesting,
modelTablePage, modelTablePage,
setModelTablePage, setModelTablePage,
selectedEndpointType,
setSelectedEndpointType,
allSelectingRef, allSelectingRef,
// Multi-key management states // Multi-key management states
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment