Przeglądaj źródła

feat(ratio): add advanced ratio fields to unset models editor

- Add cache/image/audio ratio columns to the table
- Add advanced ratio fields to the add model modal
- Update data init, submit, and addModel to handle new fields
- Use formRef to read InputNumber values (same fix as visual editor)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
master
fengsilin 1 tydzień temu
rodzic
commit
1fdf0a3f47
1 zmienionych plików z 153 dodań i 2 usunięć
  1. +153
    -2
      web/src/pages/Setting/Ratio/ModelRationNotSetEditor.jsx

+ 153
- 2
web/src/pages/Setting/Ratio/ModelRationNotSetEditor.jsx Wyświetl plik

@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com For commercial licensing, please contact support@quantumnous.com
*/ */


import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { import {
Table, Table,
Button, Button,
@@ -56,6 +56,7 @@ export default function ModelRatioNotSetEditor(props) {
const [batchRatioValue, setBatchRatioValue] = useState(''); const [batchRatioValue, setBatchRatioValue] = useState('');
const [batchCompletionRatioValue, setBatchCompletionRatioValue] = const [batchCompletionRatioValue, setBatchCompletionRatioValue] =
useState(''); useState('');
const addFormRef = useRef(null);
const { Text } = Typography; const { Text } = Typography;
// 定义可选的每页显示条数 // 定义可选的每页显示条数
const pageSizeOptions = [10, 20, 50, 100]; const pageSizeOptions = [10, 20, 50, 100];
@@ -85,6 +86,11 @@ export default function ModelRatioNotSetEditor(props) {
const modelPrice = JSON.parse(props.options.ModelPrice || '{}'); const modelPrice = JSON.parse(props.options.ModelPrice || '{}');
const modelRatio = JSON.parse(props.options.ModelRatio || '{}'); const modelRatio = JSON.parse(props.options.ModelRatio || '{}');
const completionRatio = JSON.parse(props.options.CompletionRatio || '{}'); const completionRatio = JSON.parse(props.options.CompletionRatio || '{}');
const cacheRatio = JSON.parse(props.options.CacheRatio || '{}');
const createCacheRatio = JSON.parse(props.options.CreateCacheRatio || '{}');
const imageRatio = JSON.parse(props.options.ImageRatio || '{}');
const audioRatio = JSON.parse(props.options.AudioRatio || '{}');
const audioCompletionRatio = JSON.parse(props.options.AudioCompletionRatio || '{}');


// 找出所有未设置价格和倍率的模型 // 找出所有未设置价格和倍率的模型
const unsetModels = enabledModels.filter((modelName) => { const unsetModels = enabledModels.filter((modelName) => {
@@ -101,6 +107,11 @@ export default function ModelRatioNotSetEditor(props) {
price: modelPrice[name] || '', price: modelPrice[name] || '',
ratio: modelRatio[name] || '', ratio: modelRatio[name] || '',
completionRatio: completionRatio[name] || '', completionRatio: completionRatio[name] || '',
cacheRatio: cacheRatio[name] ?? '',
cacheCreationRatio: createCacheRatio[name] ?? '',
imageRatio: imageRatio[name] ?? '',
audioRatio: audioRatio[name] ?? '',
audioCompletionRatio: audioCompletionRatio[name] ?? '',
})); }));


setModels(modelData); setModels(modelData);
@@ -142,6 +153,11 @@ export default function ModelRatioNotSetEditor(props) {
ModelPrice: JSON.parse(props.options.ModelPrice || '{}'), ModelPrice: JSON.parse(props.options.ModelPrice || '{}'),
ModelRatio: JSON.parse(props.options.ModelRatio || '{}'), ModelRatio: JSON.parse(props.options.ModelRatio || '{}'),
CompletionRatio: JSON.parse(props.options.CompletionRatio || '{}'), CompletionRatio: JSON.parse(props.options.CompletionRatio || '{}'),
CacheRatio: JSON.parse(props.options.CacheRatio || '{}'),
CreateCacheRatio: JSON.parse(props.options.CreateCacheRatio || '{}'),
ImageRatio: JSON.parse(props.options.ImageRatio || '{}'),
AudioRatio: JSON.parse(props.options.AudioRatio || '{}'),
AudioCompletionRatio: JSON.parse(props.options.AudioCompletionRatio || '{}'),
}; };


try { try {
@@ -159,6 +175,18 @@ export default function ModelRatioNotSetEditor(props) {
model.completionRatio, model.completionRatio,
); );
} }

// 高级倍率字段(0 是有效值)
if (model.cacheRatio !== '' && model.cacheRatio != null)
output.CacheRatio[model.name] = parseFloat(model.cacheRatio);
if (model.cacheCreationRatio !== '' && model.cacheCreationRatio != null)
output.CreateCacheRatio[model.name] = parseFloat(model.cacheCreationRatio);
if (model.imageRatio !== '' && model.imageRatio != null)
output.ImageRatio[model.name] = parseFloat(model.imageRatio);
if (model.audioRatio !== '' && model.audioRatio != null)
output.AudioRatio[model.name] = parseFloat(model.audioRatio);
if (model.audioCompletionRatio !== '' && model.audioCompletionRatio != null)
output.AudioCompletionRatio[model.name] = parseFloat(model.audioCompletionRatio);
}); });


// 准备API请求数组 // 准备API请求数组
@@ -252,6 +280,75 @@ export default function ModelRatioNotSetEditor(props) {
/> />
), ),
}, },
{
title: t('缓存读取倍率'),
dataIndex: 'cacheRatio',
key: 'cacheRatio',
render: (text, record) => (
<Input
value={text}
placeholder={t('全局默认值')}
disabled={record.price !== ''}
onChange={(value) => updateModel(record.name, 'cacheRatio', value)}
/>
),
},
{
title: t('缓存创建倍率(5分钟)'),
dataIndex: 'cacheCreationRatio',
key: 'cacheCreationRatio',
render: (text, record) => (
<Input
value={text}
placeholder={t('全局默认值')}
disabled={record.price !== ''}
onChange={(value) =>
updateModel(record.name, 'cacheCreationRatio', value)
}
/>
),
},
{
title: t('图片倍率'),
dataIndex: 'imageRatio',
key: 'imageRatio',
render: (text, record) => (
<Input
value={text}
placeholder={t('全局默认值')}
disabled={record.price !== ''}
onChange={(value) => updateModel(record.name, 'imageRatio', value)}
/>
),
},
{
title: t('音频输入倍率'),
dataIndex: 'audioRatio',
key: 'audioRatio',
render: (text, record) => (
<Input
value={text}
placeholder={t('全局默认值')}
disabled={record.price !== ''}
onChange={(value) => updateModel(record.name, 'audioRatio', value)}
/>
),
},
{
title: t('音频输出倍率'),
dataIndex: 'audioCompletionRatio',
key: 'audioCompletionRatio',
render: (text, record) => (
<Input
value={text}
placeholder={t('全局默认值')}
disabled={record.price !== ''}
onChange={(value) =>
updateModel(record.name, 'audioCompletionRatio', value)
}
/>
),
},
]; ];


const updateModel = (name, field, value) => { const updateModel = (name, field, value) => {
@@ -272,12 +369,29 @@ export default function ModelRatioNotSetEditor(props) {
showError(t('模型名称已存在')); showError(t('模型名称已存在'));
return; return;
} }
// 从表单读取高级倍率字段
let advancedValues = {};
if (addFormRef.current) {
const formValues = addFormRef.current.getValues();
advancedValues = {
cacheRatio: formValues.cacheRatio != null ? formValues.cacheRatio : '',
cacheCreationRatio: formValues.cacheCreationRatio != null ? formValues.cacheCreationRatio : '',
imageRatio: formValues.imageRatio != null ? formValues.imageRatio : '',
audioRatio: formValues.audioRatio != null ? formValues.audioRatio : '',
audioCompletionRatio: formValues.audioCompletionRatio != null ? formValues.audioCompletionRatio : '',
};
}
setModels((prev) => [ setModels((prev) => [
{ {
name: values.name, name: values.name,
price: values.price || '', price: values.price || '',
ratio: values.ratio || '', ratio: values.ratio || '',
completionRatio: values.completionRatio || '', completionRatio: values.completionRatio || '',
cacheRatio: advancedValues.cacheRatio ?? '',
cacheCreationRatio: advancedValues.cacheCreationRatio ?? '',
imageRatio: advancedValues.imageRatio ?? '',
audioRatio: advancedValues.audioRatio ?? '',
audioCompletionRatio: advancedValues.audioCompletionRatio ?? '',
}, },
...prev, ...prev,
]); ]);
@@ -457,7 +571,7 @@ export default function ModelRatioNotSetEditor(props) {
currentModel && addModel(currentModel); currentModel && addModel(currentModel);
}} }}
> >
<Form>
<Form getFormApi={(api) => (addFormRef.current = api)}>
<Form.Input <Form.Input
field='name' field='name'
label={t('模型名称')} label={t('模型名称')}
@@ -515,6 +629,43 @@ export default function ModelRatioNotSetEditor(props) {
})) }))
} }
/> />
<Form.InputNumber
field='cacheRatio'
label={t('缓存读取倍率')}
min={0}
step={0.01}
placeholder={t('全局默认值(1.0)')}
extraText={t('缓存命中时输入价格的倍率。0.5 = 缓存命中的 token 按输入价格的一半计费,留空使用全局默认值 1.0')}
/>
<Form.InputNumber
field='cacheCreationRatio'
label={t('缓存创建倍率(5分钟)')}
min={0}
step={0.01}
placeholder={t('全局默认值(1.25)')}
extraText={t('写入缓存的 token 按此倍率 × 输入价格计费。默认 1.25(5分钟 TTL);超过 1 小时自动按 1.6x 计费,留空使用全局默认值')}
/>
<Form.InputNumber
field='imageRatio'
label={t('图片倍率')}
min={0}
step={0.01}
placeholder={t('全局默认值')}
/>
<Form.InputNumber
field='audioRatio'
label={t('音频输入倍率')}
min={0}
step={0.01}
placeholder={t('全局默认值')}
/>
<Form.InputNumber
field='audioCompletionRatio'
label={t('音频输出倍率')}
min={0}
step={0.01}
placeholder={t('全局默认值')}
/>
</> </>
)} )}
</Form> </Form>


Ładowanie…
Anuluj
Zapisz