diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json
index 295c464d..8c808d01 100644
--- a/web/src/i18n/locales/en.json
+++ b/web/src/i18n/locales/en.json
@@ -1726,5 +1726,7 @@
"放大编辑": "Expand editor",
"编辑公告内容": "Edit announcement content",
"自适应列表": "Adaptive list",
- "紧凑列表": "Compact list"
+ "紧凑列表": "Compact list",
+ "仅显示矛盾倍率": "Only show conflicting ratios",
+ "矛盾": "Conflict"
}
\ No newline at end of file
diff --git a/web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js b/web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js
index 983f3afe..ca3e396d 100644
--- a/web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js
+++ b/web/src/pages/Setting/Ratio/ModelSettingsVisualEditor.js
@@ -8,7 +8,9 @@ import {
Form,
Space,
RadioGroup,
- Radio
+ Radio,
+ Checkbox,
+ Tag
} from '@douyinfe/semi-ui';
import {
IconDelete,
@@ -30,6 +32,7 @@ export default function ModelSettingsVisualEditor(props) {
const [loading, setLoading] = useState(false);
const [pricingMode, setPricingMode] = useState('per-token'); // 'per-token' or 'per-request'
const [pricingSubMode, setPricingSubMode] = useState('ratio'); // 'ratio' or 'token-price'
+ const [conflictOnly, setConflictOnly] = useState(false);
const formRef = useRef(null);
const pageSize = 10;
const quotaPerUnit = getQuotaPerUnit();
@@ -47,13 +50,19 @@ export default function ModelSettingsVisualEditor(props) {
...Object.keys(completionRatio),
]);
- const modelData = Array.from(modelNames).map((name) => ({
- name,
- price: modelPrice[name] === undefined ? '' : modelPrice[name],
- ratio: modelRatio[name] === undefined ? '' : modelRatio[name],
- completionRatio:
- completionRatio[name] === undefined ? '' : completionRatio[name],
- }));
+ const modelData = Array.from(modelNames).map((name) => {
+ const price = modelPrice[name] === undefined ? '' : modelPrice[name];
+ const ratio = modelRatio[name] === undefined ? '' : modelRatio[name];
+ const comp = completionRatio[name] === undefined ? '' : completionRatio[name];
+
+ return {
+ name,
+ price,
+ ratio,
+ completionRatio: comp,
+ hasConflict: price !== '' && (ratio !== '' || comp !== ''),
+ };
+ });
setModels(modelData);
} catch (error) {
@@ -69,11 +78,13 @@ export default function ModelSettingsVisualEditor(props) {
};
// 在 return 语句之前,先处理过滤和分页逻辑
- const filteredModels = models.filter((model) =>
- searchText
+ const filteredModels = models.filter((model) => {
+ const keywordMatch = searchText
? model.name.toLowerCase().includes(searchText.toLowerCase())
- : true,
- );
+ : true;
+ const conflictMatch = conflictOnly ? model.hasConflict : true;
+ return keywordMatch && conflictMatch;
+ });
// 然后基于过滤后的数据计算分页数据
const pagedData = getPagedData(filteredModels, currentPage, pageSize);
@@ -152,6 +163,16 @@ export default function ModelSettingsVisualEditor(props) {
title: t('模型名称'),
dataIndex: 'name',
key: 'name',
+ render: (text, record) => (
+
+ {text}
+ {record.hasConflict && (
+