mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-10 22:20:25 +00:00
fix: channel affinity (#2799)
* fix: channel affinity log styles * fix: Issue with incorrect data storage when switching key sources * feat: support not retrying after a single rule configuration fails * fix: render channel affinity tooltip as multiline content * feat: channel affinity cache hit * fix: prevent ChannelAffinityUsageCacheModal infinite loading and hide data before fetch * chore: format backend with gofmt and frontend with prettier/eslint autofix
This commit is contained in:
@@ -199,9 +199,9 @@ export default function SettingGlobalModel(props) {
|
||||
'global.pass_through_request_enabled': value,
|
||||
})
|
||||
}
|
||||
extraText={
|
||||
t('开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启')
|
||||
}
|
||||
extraText={t(
|
||||
'开启后,所有请求将直接透传给上游,不会进行任何处理(重定向和渠道适配也将失效),请谨慎开启',
|
||||
)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -210,11 +210,7 @@ export default function SettingGlobalModel(props) {
|
||||
<Form.TextArea
|
||||
label={t('禁用思考处理的模型列表')}
|
||||
field={'global.thinking_model_blacklist'}
|
||||
placeholder={
|
||||
t('例如:') +
|
||||
'\n' +
|
||||
thinkingExample
|
||||
}
|
||||
placeholder={t('例如:') + '\n' + thinkingExample}
|
||||
rows={4}
|
||||
rules={[
|
||||
{
|
||||
@@ -270,12 +266,12 @@ export default function SettingGlobalModel(props) {
|
||||
|
||||
<Row style={{ marginTop: 10 }}>
|
||||
<Col span={24}>
|
||||
<Form.TextArea
|
||||
label={t('参数配置')}
|
||||
field={chatCompletionsToResponsesPolicyKey}
|
||||
placeholder={
|
||||
t('例如(指定渠道):') +
|
||||
'\n' +
|
||||
<Form.TextArea
|
||||
label={t('参数配置')}
|
||||
field={chatCompletionsToResponsesPolicyKey}
|
||||
placeholder={
|
||||
t('例如(指定渠道):') +
|
||||
'\n' +
|
||||
chatCompletionsToResponsesPolicyExample +
|
||||
'\n\n' +
|
||||
t('例如(全渠道):') +
|
||||
@@ -370,7 +366,9 @@ export default function SettingGlobalModel(props) {
|
||||
<Col span={24}>
|
||||
<Banner
|
||||
type='warning'
|
||||
description={t('警告:启用保活后,如果已经写入保活数据后渠道出错,系统无法重试,如果必须开启,推荐设置尽可能大的Ping间隔')}
|
||||
description={t(
|
||||
'警告:启用保活后,如果已经写入保活数据后渠道出错,系统无法重试,如果必须开启,推荐设置尽可能大的Ping间隔',
|
||||
)}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -49,8 +49,7 @@ export default function SettingGrokModel(props) {
|
||||
.validate()
|
||||
.then(() => {
|
||||
const updateArray = compareObjects(inputs, inputsRow);
|
||||
if (!updateArray.length)
|
||||
return showWarning(t('你似乎并没有修改什么'));
|
||||
if (!updateArray.length) return showWarning(t('你似乎并没有修改什么'));
|
||||
|
||||
const requestQueue = updateArray.map((item) => {
|
||||
const value = String(inputs[item.key]);
|
||||
|
||||
@@ -18,7 +18,15 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { Button, Col, Form, Row, Spin, Card, Typography } from '@douyinfe/semi-ui';
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
Form,
|
||||
Row,
|
||||
Spin,
|
||||
Card,
|
||||
Typography,
|
||||
} from '@douyinfe/semi-ui';
|
||||
import {
|
||||
compareObjects,
|
||||
API,
|
||||
@@ -88,9 +96,7 @@ export default function SettingModelDeployment(props) {
|
||||
showError(t('网络连接失败,请检查网络设置或稍后重试'));
|
||||
} else {
|
||||
const rawMessage =
|
||||
error?.response?.data?.message ||
|
||||
error?.message ||
|
||||
'';
|
||||
error?.response?.data?.message || error?.message || '';
|
||||
const localizedMessage = rawMessage
|
||||
? getLocalizedMessage(rawMessage)
|
||||
: t('未知错误');
|
||||
@@ -104,7 +110,7 @@ export default function SettingModelDeployment(props) {
|
||||
function onSubmit() {
|
||||
const updateArray = compareObjects(inputs, inputsRow);
|
||||
if (!updateArray.length) return showWarning(t('你似乎并没有修改什么'));
|
||||
|
||||
|
||||
const requestQueue = updateArray.map((item) => {
|
||||
let value = String(inputs[item.key]);
|
||||
return API.put('/api/option/', {
|
||||
@@ -112,7 +118,7 @@ export default function SettingModelDeployment(props) {
|
||||
value,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
setLoading(true);
|
||||
Promise.all(requestQueue)
|
||||
.then((res) => {
|
||||
@@ -141,7 +147,7 @@ export default function SettingModelDeployment(props) {
|
||||
'model_deployment.ionet.api_key': '',
|
||||
'model_deployment.ionet.enabled': false,
|
||||
};
|
||||
|
||||
|
||||
const currentInputs = {};
|
||||
for (let key in defaultInputs) {
|
||||
if (props.options.hasOwnProperty(key)) {
|
||||
@@ -150,7 +156,7 @@ export default function SettingModelDeployment(props) {
|
||||
currentInputs[key] = defaultInputs[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setInputs(currentInputs);
|
||||
setInputsRow(structuredClone(currentInputs));
|
||||
refForm.current?.setValues(currentInputs);
|
||||
@@ -165,9 +171,11 @@ export default function SettingModelDeployment(props) {
|
||||
getFormApi={(formAPI) => (refForm.current = formAPI)}
|
||||
style={{ marginBottom: 15 }}
|
||||
>
|
||||
<Form.Section
|
||||
<Form.Section
|
||||
text={
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<div
|
||||
style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
|
||||
>
|
||||
<span>{t('模型部署设置')}</span>
|
||||
</div>
|
||||
}
|
||||
@@ -186,7 +194,9 @@ export default function SettingModelDeployment(props) {
|
||||
|
||||
<Card
|
||||
title={
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<div
|
||||
style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
|
||||
>
|
||||
<Cloud size={18} />
|
||||
<span>io.net</span>
|
||||
</div>
|
||||
@@ -226,18 +236,16 @@ export default function SettingModelDeployment(props) {
|
||||
}
|
||||
disabled={!inputs['model_deployment.ionet.enabled']}
|
||||
extraText={t('请使用 Project 为 io.cloud 的密钥')}
|
||||
mode="password"
|
||||
mode='password'
|
||||
/>
|
||||
<div style={{ display: 'flex', gap: '12px' }}>
|
||||
<Button
|
||||
type="outline"
|
||||
size="small"
|
||||
type='outline'
|
||||
size='small'
|
||||
icon={<Zap size={16} />}
|
||||
onClick={testApiKey}
|
||||
loading={testing}
|
||||
disabled={
|
||||
!inputs['model_deployment.ionet.enabled']
|
||||
}
|
||||
disabled={!inputs['model_deployment.ionet.enabled']}
|
||||
style={{
|
||||
height: '32px',
|
||||
fontSize: '13px',
|
||||
@@ -271,7 +279,10 @@ export default function SettingModelDeployment(props) {
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<Text strong style={{ display: 'block', marginBottom: '8px' }}>
|
||||
<Text
|
||||
strong
|
||||
style={{ display: 'block', marginBottom: '8px' }}
|
||||
>
|
||||
{t('获取 io.net API Key')}
|
||||
</Text>
|
||||
<ul
|
||||
@@ -287,14 +298,16 @@ export default function SettingModelDeployment(props) {
|
||||
}}
|
||||
>
|
||||
<li>{t('访问 io.net 控制台的 API Keys 页面')}</li>
|
||||
<li>{t('创建或选择密钥时,将 Project 设置为 io.cloud')}</li>
|
||||
<li>
|
||||
{t('创建或选择密钥时,将 Project 设置为 io.cloud')}
|
||||
</li>
|
||||
<li>{t('复制生成的密钥并粘贴到此处')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Button
|
||||
icon={<ArrowUpRight size={16} />}
|
||||
type="primary"
|
||||
theme="solid"
|
||||
type='primary'
|
||||
theme='solid'
|
||||
style={{ width: '100%' }}
|
||||
onClick={() =>
|
||||
window.open('https://ai.io.net/ai/api-keys', '_blank')
|
||||
@@ -308,7 +321,7 @@ export default function SettingModelDeployment(props) {
|
||||
</Card>
|
||||
|
||||
<Row>
|
||||
<Button size='default' type="primary" onClick={onSubmit}>
|
||||
<Button size='default' type='primary' onClick={onSubmit}>
|
||||
{t('保存设置')}
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
Reference in New Issue
Block a user