Merge branch 'alpha' into feature/claude-code
# Conflicts: # web/src/components/table/channels/modals/EditChannelModal.jsx
This commit is contained in:
@@ -43,6 +43,9 @@ import {
|
||||
Tag,
|
||||
Typography,
|
||||
} from '@douyinfe/semi-ui';
|
||||
import { getChannelModels, copy, getChannelIcon, getModelCategories, selectFilter } from '../../../../helpers';
|
||||
import ModelSelectModal from './ModelSelectModal';
|
||||
import JSONEditor from '../../../common/JSONEditor';
|
||||
import { CHANNEL_OPTIONS, CLAUDE_CODE_DEFAULT_SYSTEM_PROMPT } from '../../../../constants';
|
||||
import {
|
||||
IconBolt,
|
||||
@@ -70,7 +73,9 @@ const STATUS_CODE_MAPPING_EXAMPLE = {
|
||||
};
|
||||
|
||||
const REGION_EXAMPLE = {
|
||||
default: 'us-central1',
|
||||
"default": 'global',
|
||||
"gemini-1.5-pro-002": "europe-west2",
|
||||
"gemini-1.5-flash-002": "europe-west2",
|
||||
'claude-3-5-sonnet-20240620': 'europe-west1',
|
||||
};
|
||||
|
||||
@@ -149,6 +154,8 @@ const EditChannelModal = (props) => {
|
||||
const [authorizationCode, setAuthorizationCode] = useState('');
|
||||
const [oauthParams, setOauthParams] = useState(null);
|
||||
const [isExchangingCode, setIsExchangingCode] = useState(false);
|
||||
const [modelModalVisible, setModelModalVisible] = useState(false);
|
||||
const [fetchedModels, setFetchedModels] = useState([]);
|
||||
const formApiRef = useRef(null);
|
||||
const [vertexKeys, setVertexKeys] = useState([]);
|
||||
const [vertexFileList, setVertexFileList] = useState([]);
|
||||
@@ -404,7 +411,7 @@ const EditChannelModal = (props) => {
|
||||
// return;
|
||||
// }
|
||||
setLoading(true);
|
||||
const models = inputs['models'] || [];
|
||||
const models = [];
|
||||
let err = false;
|
||||
|
||||
if (isEdit) {
|
||||
@@ -445,8 +452,9 @@ const EditChannelModal = (props) => {
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
handleInputChange(name, Array.from(new Set(models)));
|
||||
showSuccess(t('获取模型列表成功'));
|
||||
const uniqueModels = Array.from(new Set(models));
|
||||
setFetchedModels(uniqueModels);
|
||||
setModelModalVisible(true);
|
||||
} else {
|
||||
showError(t('获取模型列表失败'));
|
||||
}
|
||||
@@ -1071,7 +1079,7 @@ const EditChannelModal = (props) => {
|
||||
rules={[{ required: true, message: t('请选择渠道类型') }]}
|
||||
optionList={channelOptionList}
|
||||
style={{ width: '100%' }}
|
||||
filter={modelSelectFilter}
|
||||
filter={selectFilter}
|
||||
autoClearSearchValue={false}
|
||||
searchPosition='dropdown'
|
||||
onSearch={(value) => setChannelSearchValue(value)}
|
||||
@@ -1305,24 +1313,24 @@ const EditChannelModal = (props) => {
|
||||
)}
|
||||
|
||||
{inputs.type === 41 && (
|
||||
<Form.TextArea
|
||||
<JSONEditor
|
||||
field='other'
|
||||
label={t('部署地区')}
|
||||
placeholder={t(
|
||||
'请输入部署地区,例如:us-central1\n支持使用模型映射格式\n{\n "default": "us-central1",\n "claude-3-5-sonnet-20240620": "europe-west1"\n}'
|
||||
)}
|
||||
autosize
|
||||
value={inputs.other || ''}
|
||||
onChange={(value) => handleInputChange('other', value)}
|
||||
rules={[{ required: true, message: t('请填写部署地区') }]}
|
||||
template={REGION_EXAMPLE}
|
||||
templateLabel={t('填入模板')}
|
||||
editorType="region"
|
||||
formApi={formApiRef.current}
|
||||
extraText={
|
||||
<Text
|
||||
className="!text-semi-color-primary cursor-pointer"
|
||||
onClick={() => handleInputChange('other', JSON.stringify(REGION_EXAMPLE, null, 2))}
|
||||
>
|
||||
{t('填入模板')}
|
||||
<Text type="tertiary" size="small">
|
||||
{t('设置默认地区和特定模型的专用地区')}
|
||||
</Text>
|
||||
}
|
||||
showClear
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1515,7 +1523,7 @@ const EditChannelModal = (props) => {
|
||||
placeholder={t('请选择该渠道所支持的模型')}
|
||||
rules={[{ required: true, message: t('请选择模型') }]}
|
||||
multiple
|
||||
filter={modelSelectFilter}
|
||||
filter={selectFilter}
|
||||
autoClearSearchValue={false}
|
||||
searchPosition='dropdown'
|
||||
optionList={modelOptions}
|
||||
@@ -1578,24 +1586,24 @@ const EditChannelModal = (props) => {
|
||||
showClear
|
||||
/>
|
||||
|
||||
<Form.TextArea
|
||||
<JSONEditor
|
||||
field='model_mapping'
|
||||
label={t('模型重定向')}
|
||||
placeholder={
|
||||
t('此项可选,用于修改请求体中的模型名称,为一个 JSON 字符串,键为请求中模型名称,值为要替换的模型名称,例如:') +
|
||||
`\n${JSON.stringify(MODEL_MAPPING_EXAMPLE, null, 2)}`
|
||||
}
|
||||
autosize
|
||||
value={inputs.model_mapping || ''}
|
||||
onChange={(value) => handleInputChange('model_mapping', value)}
|
||||
template={MODEL_MAPPING_EXAMPLE}
|
||||
templateLabel={t('填入模板')}
|
||||
editorType="keyValue"
|
||||
formApi={formApiRef.current}
|
||||
extraText={
|
||||
<Text
|
||||
className="!text-semi-color-primary cursor-pointer"
|
||||
onClick={() => handleInputChange('model_mapping', JSON.stringify(MODEL_MAPPING_EXAMPLE, null, 2))}
|
||||
>
|
||||
{t('填入模板')}
|
||||
<Text type="tertiary" size="small">
|
||||
{t('键为请求中的模型名称,值为要替换的模型名称')}
|
||||
</Text>
|
||||
}
|
||||
showClear
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -1685,7 +1693,7 @@ const EditChannelModal = (props) => {
|
||||
showClear
|
||||
/>
|
||||
|
||||
<Form.TextArea
|
||||
<JSONEditor
|
||||
field='status_code_mapping'
|
||||
label={t('状态码复写')}
|
||||
placeholder={
|
||||
@@ -1693,17 +1701,17 @@ const EditChannelModal = (props) => {
|
||||
'\n' +
|
||||
JSON.stringify(STATUS_CODE_MAPPING_EXAMPLE, null, 2)
|
||||
}
|
||||
autosize
|
||||
value={inputs.status_code_mapping || ''}
|
||||
onChange={(value) => handleInputChange('status_code_mapping', value)}
|
||||
template={STATUS_CODE_MAPPING_EXAMPLE}
|
||||
templateLabel={t('填入模板')}
|
||||
editorType="keyValue"
|
||||
formApi={formApiRef.current}
|
||||
extraText={
|
||||
<Text
|
||||
className="!text-semi-color-primary cursor-pointer"
|
||||
onClick={() => handleInputChange('status_code_mapping', JSON.stringify(STATUS_CODE_MAPPING_EXAMPLE, null, 2))}
|
||||
>
|
||||
{t('填入模板')}
|
||||
<Text type="tertiary" size="small">
|
||||
{t('键为原状态码,值为要复写的状态码,仅影响本地判断')}
|
||||
</Text>
|
||||
}
|
||||
showClear
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -1716,25 +1724,19 @@ const EditChannelModal = (props) => {
|
||||
</Avatar>
|
||||
<div>
|
||||
<Text className="text-lg font-medium">{t('渠道额外设置')}</Text>
|
||||
<div className="text-xs text-gray-600">
|
||||
<Text
|
||||
className="!text-semi-color-primary cursor-pointer"
|
||||
onClick={() => window.open('https://github.com/QuantumNous/new-api/blob/main/docs/channel/other_setting.md')}
|
||||
>
|
||||
{t('设置说明')}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Form.Switch
|
||||
field='force_format'
|
||||
label={t('强制格式化')}
|
||||
checkedText={t('开')}
|
||||
uncheckedText={t('关')}
|
||||
onChange={(value) => handleChannelSettingsChange('force_format', value)}
|
||||
extraText={t('强制将响应格式化为 OpenAI 标准格式(只适用于OpenAI渠道类型)')}
|
||||
/>
|
||||
{inputs.type === 1 && (
|
||||
<Form.Switch
|
||||
field='force_format'
|
||||
label={t('强制格式化')}
|
||||
checkedText={t('开')}
|
||||
uncheckedText={t('关')}
|
||||
onChange={(value) => handleChannelSettingsChange('force_format', value)}
|
||||
extraText={t('强制将响应格式化为 OpenAI 标准格式(只适用于OpenAI渠道类型)')}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Form.Switch
|
||||
field='thinking_to_content'
|
||||
@@ -1791,6 +1793,17 @@ const EditChannelModal = (props) => {
|
||||
onVisibleChange={(visible) => setIsModalOpenurl(visible)}
|
||||
/>
|
||||
</SideSheet>
|
||||
<ModelSelectModal
|
||||
visible={modelModalVisible}
|
||||
models={fetchedModels}
|
||||
selected={inputs.models}
|
||||
onConfirm={(selectedModels) => {
|
||||
handleInputChange('models', selectedModels);
|
||||
showSuccess(t('模型列表已更新'));
|
||||
setModelModalVisible(false);
|
||||
}}
|
||||
onCancel={() => setModelModalVisible(false)}
|
||||
/>
|
||||
|
||||
{/* OAuth Authorization Modal */}
|
||||
<Modal
|
||||
|
||||
Reference in New Issue
Block a user