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:
Seefs
2026-02-02 14:37:31 +08:00
committed by GitHub
parent 6c0e9403a2
commit 540cf6c991
61 changed files with 2012 additions and 1004 deletions

View File

@@ -73,6 +73,7 @@ const RULE_TEMPLATES = {
key_sources: [{ type: 'gjson', path: 'prompt_cache_key' }],
value_regex: '',
ttl_seconds: 0,
skip_retry_on_failure: false,
include_using_group: true,
include_rule_name: true,
},
@@ -83,6 +84,7 @@ const RULE_TEMPLATES = {
key_sources: [{ type: 'gjson', path: 'metadata.user_id' }],
value_regex: '',
ttl_seconds: 0,
skip_retry_on_failure: false,
include_using_group: true,
include_rule_name: true,
},
@@ -112,6 +114,7 @@ const RULES_JSON_PLACEHOLDER = `[
],
"value_regex": "^[-0-9A-Za-z._:]{1,128}$",
"ttl_seconds": 600,
"skip_retry_on_failure": false,
"include_using_group": true,
"include_rule_name": true
}
@@ -153,7 +156,12 @@ const normalizeKeySource = (src) => {
const type = (src?.type || '').trim();
const key = (src?.key || '').trim();
const path = (src?.path || '').trim();
return { type, key, path };
if (type === 'gjson') {
return { type, key: '', path };
}
return { type, key, path: '' };
};
const makeUniqueName = (existingNames, baseName) => {
@@ -229,6 +237,7 @@ export default function SettingsChannelAffinity(props) {
user_agent_include_text: (r.user_agent_include || []).join('\n'),
value_regex: r.value_regex || '',
ttl_seconds: Number(r.ttl_seconds || 0),
skip_retry_on_failure: !!r.skip_retry_on_failure,
include_using_group: r.include_using_group ?? true,
include_rule_name: r.include_rule_name ?? true,
};
@@ -523,6 +532,7 @@ export default function SettingsChannelAffinity(props) {
key_sources: [{ type: 'gjson', path: '' }],
value_regex: '',
ttl_seconds: 0,
skip_retry_on_failure: false,
include_using_group: true,
include_rule_name: true,
};
@@ -583,6 +593,9 @@ export default function SettingsChannelAffinity(props) {
ttl_seconds: Number(values.ttl_seconds || 0),
include_using_group: !!values.include_using_group,
include_rule_name: !!values.include_rule_name,
...(values.skip_retry_on_failure
? { skip_retry_on_failure: true }
: {}),
...(userAgentInclude.length > 0
? { user_agent_include: userAgentInclude }
: {}),
@@ -1041,6 +1054,18 @@ export default function SettingsChannelAffinity(props) {
</Text>
</Col>
</Row>
<Row gutter={16}>
<Col xs={24} sm={12}>
<Form.Switch
field='skip_retry_on_failure'
label={t('失败后不重试')}
/>
<Text type='tertiary' size='small'>
{t('开启后,若该规则命中且请求失败,将不会切换渠道重试。')}
</Text>
</Col>
</Row>
</Collapse.Panel>
</Collapse>