🔌 feat(api): extend endpoint type support & expose in pricing UI
* backend
- constant/endpoint_type.go
• Add EndpointTypeMidjourney, EndpointTypeSuno, EndpointTypeKling, EndpointTypeJimeng.
- common/endpoint_type.go
• Map Midjourney / MidjourneyPlus, SunoAPI, Kling, Jimeng channel types to the new endpoint types.
* frontend
- ModelPricing.js
• Add “Supported Endpoint Type” column.
• Implement renderSupportedEndpoints with `stringToColor` for consistent tag colors.
These changes allow `/api/pricing` and model lists to return accurate
`supported_endpoint_types` covering all non-OpenAI providers and display
them clearly in the UI.
No breaking changes.
This commit is contained in:
@@ -8,6 +8,14 @@ func GetEndpointTypesByChannelType(channelType int, modelName string) []constant
|
|||||||
switch channelType {
|
switch channelType {
|
||||||
case constant.ChannelTypeJina:
|
case constant.ChannelTypeJina:
|
||||||
endpointTypes = []constant.EndpointType{constant.EndpointTypeJinaRerank}
|
endpointTypes = []constant.EndpointType{constant.EndpointTypeJinaRerank}
|
||||||
|
case constant.ChannelTypeMidjourney, constant.ChannelTypeMidjourneyPlus:
|
||||||
|
endpointTypes = []constant.EndpointType{constant.EndpointTypeMidjourney}
|
||||||
|
case constant.ChannelTypeSunoAPI:
|
||||||
|
endpointTypes = []constant.EndpointType{constant.EndpointTypeSuno}
|
||||||
|
case constant.ChannelTypeKling:
|
||||||
|
endpointTypes = []constant.EndpointType{constant.EndpointTypeKling}
|
||||||
|
case constant.ChannelTypeJimeng:
|
||||||
|
endpointTypes = []constant.EndpointType{constant.EndpointTypeJimeng}
|
||||||
case constant.ChannelTypeAws:
|
case constant.ChannelTypeAws:
|
||||||
fallthrough
|
fallthrough
|
||||||
case constant.ChannelTypeAnthropic:
|
case constant.ChannelTypeAnthropic:
|
||||||
|
|||||||
@@ -8,4 +8,8 @@ const (
|
|||||||
EndpointTypeAnthropic EndpointType = "anthropic"
|
EndpointTypeAnthropic EndpointType = "anthropic"
|
||||||
EndpointTypeGemini EndpointType = "gemini"
|
EndpointTypeGemini EndpointType = "gemini"
|
||||||
EndpointTypeJinaRerank EndpointType = "jina-rerank"
|
EndpointTypeJinaRerank EndpointType = "jina-rerank"
|
||||||
|
EndpointTypeMidjourney EndpointType = "midjourney-proxy"
|
||||||
|
EndpointTypeSuno EndpointType = "suno-proxy"
|
||||||
|
EndpointTypeKling EndpointType = "kling"
|
||||||
|
EndpointTypeJimeng EndpointType = "jimeng"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useContext, useEffect, useRef, useMemo, useState } from 'react';
|
import React, { useContext, useEffect, useRef, useMemo, useState } from 'react';
|
||||||
import { API, copy, showError, showInfo, showSuccess, getModelCategories, renderModelTag } from '../../helpers';
|
import { API, copy, showError, showInfo, showSuccess, getModelCategories, renderModelTag, stringToColor } from '../../helpers';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -106,6 +106,26 @@ const ModelPricing = () => {
|
|||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderSupportedEndpoints(endpoints) {
|
||||||
|
if (!endpoints || endpoints.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Space wrap>
|
||||||
|
{endpoints.map((endpoint, idx) => (
|
||||||
|
<Tag
|
||||||
|
key={endpoint}
|
||||||
|
color={stringToColor(endpoint)}
|
||||||
|
size='large'
|
||||||
|
shape='circle'
|
||||||
|
>
|
||||||
|
{endpoint}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: t('可用性'),
|
title: t('可用性'),
|
||||||
@@ -120,6 +140,13 @@ const ModelPricing = () => {
|
|||||||
},
|
},
|
||||||
defaultSortOrder: 'descend',
|
defaultSortOrder: 'descend',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('可用端点类型'),
|
||||||
|
dataIndex: 'supported_endpoint_types',
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return renderSupportedEndpoints(text);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('模型名称'),
|
title: t('模型名称'),
|
||||||
dataIndex: 'model_name',
|
dataIndex: 'model_name',
|
||||||
@@ -499,7 +526,7 @@ const ModelPricing = () => {
|
|||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<AlertCircle size={14} className="mr-1.5 flex-shrink-0" />
|
<AlertCircle size={14} className="mr-1.5 flex-shrink-0" />
|
||||||
<span className="truncate">
|
<span className="truncate">
|
||||||
{t('未登录,使用默认分组倍率')}: {groupRatio['default']}
|
{t('未登录,使用默认分组倍率:')}{groupRatio['default']}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1750,5 +1750,7 @@
|
|||||||
"批量创建时会在名称后自动添加随机后缀": "When creating in batches, a random suffix will be automatically added to the name",
|
"批量创建时会在名称后自动添加随机后缀": "When creating in batches, a random suffix will be automatically added to the name",
|
||||||
"额度必须大于0": "Quota must be greater than 0",
|
"额度必须大于0": "Quota must be greater than 0",
|
||||||
"生成数量必须大于0": "Generation quantity must be greater than 0",
|
"生成数量必须大于0": "Generation quantity must be greater than 0",
|
||||||
"创建后可在编辑渠道时获取上游模型列表": "After creation, you can get the upstream model list when editing the channel"
|
"创建后可在编辑渠道时获取上游模型列表": "After creation, you can get the upstream model list when editing the channel",
|
||||||
|
"可用端点类型": "Supported endpoint types",
|
||||||
|
"未登录,使用默认分组倍率:": "Not logged in, using default group ratio: "
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user