@@ -5,9 +5,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var ModelList = []string{
|
var ModelList = []string{
|
||||||
"gemini-1.0-pro-latest", "gemini-1.0-pro-001", "gemini-1.5-pro-latest", "gemini-1.5-flash-latest", "gemini-ultra",
|
"gemini-1.5-pro-latest", "gemini-1.5-flash-latest", "gemini-ultra",
|
||||||
"gemini-1.0-pro-vision-latest", "gemini-1.0-pro-vision-001", "gemini-1.5-pro-exp-0827", "gemini-1.5-flash-exp-0827",
|
"gemini-1.5-pro-exp-0827", "gemini-1.5-flash-exp-0827",
|
||||||
"gemini-exp-1114",
|
"gemini-exp-1114", "gemini-exp-1206",
|
||||||
}
|
}
|
||||||
|
|
||||||
var ChannelName = "google gemini"
|
var ChannelName = "google gemini"
|
||||||
|
|||||||
@@ -176,7 +176,20 @@ func (a *Adaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycom
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Adaptor) GetModelList() []string {
|
func (a *Adaptor) GetModelList() []string {
|
||||||
return ModelList
|
var modelList []string
|
||||||
|
for i, s := range ModelList {
|
||||||
|
modelList = append(modelList, s)
|
||||||
|
ModelList[i] = s
|
||||||
|
}
|
||||||
|
for i, s := range claude.ModelList {
|
||||||
|
modelList = append(modelList, s)
|
||||||
|
claude.ModelList[i] = s
|
||||||
|
}
|
||||||
|
for i, s := range gemini.ModelList {
|
||||||
|
modelList = append(modelList, s)
|
||||||
|
gemini.ModelList[i] = s
|
||||||
|
}
|
||||||
|
return modelList
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Adaptor) GetChannelName() string {
|
func (a *Adaptor) GetChannelName() string {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package vertex
|
package vertex
|
||||||
|
|
||||||
var ModelList = []string{
|
var ModelList = []string{
|
||||||
"claude-3-sonnet-20240229",
|
//"claude-3-sonnet-20240229",
|
||||||
"claude-3-opus-20240229",
|
//"claude-3-opus-20240229",
|
||||||
"claude-3-haiku-20240307",
|
//"claude-3-haiku-20240307",
|
||||||
"claude-3-5-sonnet-20240620",
|
//"claude-3-5-sonnet-20240620",
|
||||||
|
|
||||||
//"gemini-1.5-pro-latest", "gemini-1.5-flash-latest",
|
//"gemini-1.5-pro-latest", "gemini-1.5-flash-latest",
|
||||||
"gemini-1.5-pro-001", "gemini-1.5-flash-001", "gemini-pro", "gemini-pro-vision",
|
//"gemini-1.5-pro-001", "gemini-1.5-flash-001", "gemini-pro", "gemini-pro-vision",
|
||||||
|
|
||||||
"meta/llama3-405b-instruct-maas",
|
"meta/llama3-405b-instruct-maas",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
import { ITEMS_PER_PAGE } from '../constants';
|
import { ITEMS_PER_PAGE } from '../constants';
|
||||||
import {
|
import {
|
||||||
renderAudioModelPrice,
|
renderAudioModelPrice,
|
||||||
renderModelPrice,
|
renderModelPrice, renderModelPriceSimple,
|
||||||
renderNumber,
|
renderNumber,
|
||||||
renderQuota,
|
renderQuota,
|
||||||
stringToColor
|
stringToColor
|
||||||
@@ -386,14 +386,11 @@ const LogsTable = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let content = renderModelPrice(
|
let content = renderModelPriceSimple(
|
||||||
// record.prompt_tokens,
|
other.model_ratio,
|
||||||
// record.completion_tokens,
|
other.model_price,
|
||||||
// other.model_ratio,
|
other.group_ratio,
|
||||||
// other.model_price,
|
);
|
||||||
// other.completion_ratio,
|
|
||||||
// other.group_ratio,
|
|
||||||
// );
|
|
||||||
return (
|
return (
|
||||||
<Paragraph
|
<Paragraph
|
||||||
ellipsis={{
|
ellipsis={{
|
||||||
@@ -401,7 +398,7 @@ const LogsTable = () => {
|
|||||||
}}
|
}}
|
||||||
style={{ maxWidth: 240 }}
|
style={{ maxWidth: 240 }}
|
||||||
>
|
>
|
||||||
调用消费
|
{content}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const PageLayout = () => {
|
|||||||
</Sider>
|
</Sider>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Content
|
<Content
|
||||||
style={{ overflowY: 'auto', padding: '24px' }}
|
style={{ overflowY: 'auto', padding: styleState.isChatPage? '0': '24px' }}
|
||||||
>
|
>
|
||||||
<App />
|
<App />
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
@@ -363,36 +363,18 @@ const PersonalSetting = () => {
|
|||||||
</Space>
|
</Space>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
footer={
|
|
||||||
<Descriptions row>
|
|
||||||
<Descriptions.Item itemKey='当前余额'>
|
|
||||||
{renderQuota(userState?.user?.quota)}
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item itemKey='历史消耗'>
|
|
||||||
{renderQuota(userState?.user?.used_quota)}
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item itemKey='请求次数'>
|
|
||||||
{userState.user?.request_count}
|
|
||||||
</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Typography.Title heading={6}>可用模型</Typography.Title>
|
<Descriptions row>
|
||||||
<div style={{marginTop: 10}}>
|
<Descriptions.Item itemKey='当前余额'>
|
||||||
<Space wrap>
|
{renderQuota(userState?.user?.quota)}
|
||||||
{models.map((model) => (
|
</Descriptions.Item>
|
||||||
<Tag
|
<Descriptions.Item itemKey='历史消耗'>
|
||||||
key={model}
|
{renderQuota(userState?.user?.used_quota)}
|
||||||
color='cyan'
|
</Descriptions.Item>
|
||||||
onClick={() => {
|
<Descriptions.Item itemKey='请求次数'>
|
||||||
copyText(model);
|
{userState.user?.request_count}
|
||||||
}}
|
</Descriptions.Item>
|
||||||
>
|
</Descriptions>
|
||||||
{model}
|
|
||||||
</Tag>
|
|
||||||
))}
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
</Card>
|
</Card>
|
||||||
<Card
|
<Card
|
||||||
style={{marginTop: 10}}
|
style={{marginTop: 10}}
|
||||||
|
|||||||
@@ -279,6 +279,11 @@ const SiderBar = () => {
|
|||||||
}}
|
}}
|
||||||
items={headerButtons}
|
items={headerButtons}
|
||||||
onSelect={(key) => {
|
onSelect={(key) => {
|
||||||
|
if (key.itemKey.toString().startsWith('chat')) {
|
||||||
|
styleDispatch({ type: 'SET_CHAT_PAGE', payload: true });
|
||||||
|
} else {
|
||||||
|
styleDispatch({ type: 'SET_CHAT_PAGE', payload: false });
|
||||||
|
}
|
||||||
setSelectedKeys([key.itemKey]);
|
setSelectedKeys([key.itemKey]);
|
||||||
}}
|
}}
|
||||||
footer={
|
footer={
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const StyleProvider = ({ children }) => {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
isMobile: false,
|
isMobile: false,
|
||||||
showSider: false,
|
showSider: false,
|
||||||
|
isChatPage: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const dispatch = (action) => {
|
const dispatch = (action) => {
|
||||||
@@ -25,6 +26,9 @@ export const StyleProvider = ({ children }) => {
|
|||||||
case 'SET_MOBILE':
|
case 'SET_MOBILE':
|
||||||
setState(prev => ({ ...prev, isMobile: action.payload }));
|
setState(prev => ({ ...prev, isMobile: action.payload }));
|
||||||
break;
|
break;
|
||||||
|
case 'SET_CHAT_PAGE':
|
||||||
|
setState(prev => ({ ...prev, isChatPage: action.payload }));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
setState(prev => ({ ...prev, ...action }));
|
setState(prev => ({ ...prev, ...action }));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,6 +175,19 @@ export function renderModelPrice(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function renderModelPriceSimple(
|
||||||
|
modelRatio,
|
||||||
|
modelPrice = -1,
|
||||||
|
groupRatio,
|
||||||
|
) {
|
||||||
|
// 1 ratio = $0.002 / 1K tokens
|
||||||
|
if (modelPrice !== -1) {
|
||||||
|
return '价格:$' + modelPrice + ' * 分组:' + groupRatio;
|
||||||
|
} else {
|
||||||
|
return '模型: ' + modelRatio + ' * 分组: ' + groupRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function renderAudioModelPrice(
|
export function renderAudioModelPrice(
|
||||||
inputTokens,
|
inputTokens,
|
||||||
completionTokens,
|
completionTokens,
|
||||||
|
|||||||
@@ -710,6 +710,8 @@ const EditChannel = (props) => {
|
|||||||
required
|
required
|
||||||
multiple
|
multiple
|
||||||
selection
|
selection
|
||||||
|
filter
|
||||||
|
searchPosition='dropdown'
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
handleInputChange('models', value);
|
handleInputChange('models', value);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const EditTagModal = (props) => {
|
|||||||
const [groupOptions, setGroupOptions] = useState([]);
|
const [groupOptions, setGroupOptions] = useState([]);
|
||||||
const [basicModels, setBasicModels] = useState([]);
|
const [basicModels, setBasicModels] = useState([]);
|
||||||
const [fullModels, setFullModels] = useState([]);
|
const [fullModels, setFullModels] = useState([]);
|
||||||
|
const [customModel, setCustomModel] = useState('');
|
||||||
const originInputs = {
|
const originInputs = {
|
||||||
tag: '',
|
tag: '',
|
||||||
new_tag: null,
|
new_tag: null,
|
||||||
@@ -183,6 +184,40 @@ const EditTagModal = (props) => {
|
|||||||
fetchGroups().then();
|
fetchGroups().then();
|
||||||
}, [visible]);
|
}, [visible]);
|
||||||
|
|
||||||
|
const addCustomModels = () => {
|
||||||
|
if (customModel.trim() === '') return;
|
||||||
|
// 使用逗号分隔字符串,然后去除每个模型名称前后的空格
|
||||||
|
const modelArray = customModel.split(',').map((model) => model.trim());
|
||||||
|
|
||||||
|
let localModels = [...inputs.models];
|
||||||
|
let localModelOptions = [...modelOptions];
|
||||||
|
let hasError = false;
|
||||||
|
|
||||||
|
modelArray.forEach((model) => {
|
||||||
|
// 检查模型是否已存在,且模型名称非空
|
||||||
|
if (model && !localModels.includes(model)) {
|
||||||
|
localModels.push(model); // 添加到模型列表
|
||||||
|
localModelOptions.push({
|
||||||
|
// 添加到下拉选项
|
||||||
|
key: model,
|
||||||
|
text: model,
|
||||||
|
value: model
|
||||||
|
});
|
||||||
|
} else if (model) {
|
||||||
|
showError('某些模型已存在!');
|
||||||
|
hasError = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasError) return; // 如果有错误则终止操作
|
||||||
|
|
||||||
|
// 更新状态值
|
||||||
|
setModelOptions(localModelOptions);
|
||||||
|
setCustomModel('');
|
||||||
|
handleInputChange('models', localModels);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SideSheet
|
<SideSheet
|
||||||
title="编辑标签"
|
title="编辑标签"
|
||||||
@@ -224,6 +259,8 @@ const EditTagModal = (props) => {
|
|||||||
required
|
required
|
||||||
multiple
|
multiple
|
||||||
selection
|
selection
|
||||||
|
filter
|
||||||
|
searchPosition='dropdown'
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
handleInputChange('models', value);
|
handleInputChange('models', value);
|
||||||
}}
|
}}
|
||||||
@@ -231,6 +268,18 @@ const EditTagModal = (props) => {
|
|||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
optionList={modelOptions}
|
optionList={modelOptions}
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
addonAfter={
|
||||||
|
<Button type="primary" onClick={addCustomModels}>
|
||||||
|
填入
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
placeholder="输入自定义模型名称"
|
||||||
|
value={customModel}
|
||||||
|
onChange={(value) => {
|
||||||
|
setCustomModel(value.trim());
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{ marginTop: 10 }}>
|
||||||
<Typography.Text strong>分组,留空则不更改:</Typography.Text>
|
<Typography.Text strong>分组,留空则不更改:</Typography.Text>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -103,11 +103,16 @@ const Playground = () => {
|
|||||||
// handleInputChange('group', localGroupOptions[0].value);
|
// handleInputChange('group', localGroupOptions[0].value);
|
||||||
|
|
||||||
if (localGroupOptions.length > 0) {
|
if (localGroupOptions.length > 0) {
|
||||||
// set default group at first
|
// set user group at first
|
||||||
localGroupOptions.unshift({
|
if (userState.user && userState.user.group) {
|
||||||
label: '用户分组',
|
let userGroup = userState.user.group;
|
||||||
value: '',
|
// Find and move user's group to the front
|
||||||
});
|
const userGroupIndex = localGroupOptions.findIndex(g => g.value === userGroup);
|
||||||
|
if (userGroupIndex > -1) {
|
||||||
|
const userGroupOption = localGroupOptions.splice(userGroupIndex, 1)[0];
|
||||||
|
localGroupOptions.unshift(userGroupOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
localGroupOptions = [{
|
localGroupOptions = [{
|
||||||
label: '用户分组',
|
label: '用户分组',
|
||||||
|
|||||||
Reference in New Issue
Block a user