增加单一源保护全局策略
This commit is contained in:
@@ -6,7 +6,7 @@ import { Badge, Button, Card, CardContent, CardHeader, CardTitle, ConfirmDialog,
|
||||
import type { LoadState } from '../../types';
|
||||
|
||||
type RuntimePanelTab = 'model' | 'runner';
|
||||
type RunnerPolicyStrategy = 'failover' | 'hardStop' | 'priorityDemote';
|
||||
type RunnerPolicyStrategy = 'failover' | 'hardStop' | 'priorityDemote' | 'singleSource';
|
||||
|
||||
type RuntimePolicyForm = {
|
||||
policyKey: string;
|
||||
@@ -54,6 +54,7 @@ type RunnerPolicyForm = {
|
||||
priorityDemoteCodes: string[];
|
||||
priorityDemoteStatusCodes: string[];
|
||||
priorityDemoteKeywords: string[];
|
||||
singleSourceProtectionEnabled: boolean;
|
||||
metadataJson: string;
|
||||
status: string;
|
||||
};
|
||||
@@ -353,6 +354,13 @@ function RunnerPolicyEditor(props: {
|
||||
enabled: props.form.priorityDemoteEnabled,
|
||||
icon: <Gauge size={15} />,
|
||||
},
|
||||
{
|
||||
value: 'singleSource' as const,
|
||||
title: '单一源保护',
|
||||
description: '只有一个可用源时跳过自动禁用和冷却',
|
||||
enabled: props.form.singleSourceProtectionEnabled,
|
||||
icon: <ShieldCheck size={15} />,
|
||||
},
|
||||
];
|
||||
const activeDefinition = strategyDefinitions.find((item) => item.value === activeStrategy) ?? strategyDefinitions[0];
|
||||
|
||||
@@ -455,6 +463,17 @@ function RunnerPolicyEditor(props: {
|
||||
<KeywordField label="降级关键词" value={props.form.priorityDemoteKeywords} onChange={(value) => patch({ priorityDemoteKeywords: value })} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeStrategy === 'singleSource' && (
|
||||
<div className="runtimePolicyRows runnerPolicyDetailRows">
|
||||
<Toggle
|
||||
checked={props.form.singleSourceProtectionEnabled}
|
||||
label="启用单一源保护"
|
||||
onChange={(checked) => patch({ singleSourceProtectionEnabled: checked })}
|
||||
/>
|
||||
<span className="runtimeFieldHint spanTwo">本次调度只有一个可用源时,命中自动禁用、运行策略冷却或故障切换冷却动作都只记录保护事件,不修改平台或模型状态。</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -554,6 +573,7 @@ function runnerPolicyToForm(policy: GatewayRunnerPolicy | null): RunnerPolicyFor
|
||||
const failover = readObject(policy?.failoverPolicy);
|
||||
const hardStop = readObject(policy?.hardStopPolicy);
|
||||
const priorityDemote = readObject(policy?.priorityDemotePolicy);
|
||||
const singleSource = readObject(policy?.singleSourcePolicy);
|
||||
return {
|
||||
name: policy?.name ?? '默认全局调度策略',
|
||||
description: policy?.description ?? '控制多个候选平台之间的故障切换;模型运行策略只可覆盖 failoverPolicy,不能覆盖 hardStopPolicy。',
|
||||
@@ -579,6 +599,7 @@ function runnerPolicyToForm(policy: GatewayRunnerPolicy | null): RunnerPolicyFor
|
||||
priorityDemoteCodes: tagsFromValue(priorityDemote.codes ?? ['network', 'timeout', 'stream_read_error', 'rate_limit', 'server_error', 'overloaded']),
|
||||
priorityDemoteStatusCodes: tagsFromValue(priorityDemote.statusCodes ?? [408, 429, 500, 502, 503, 504]),
|
||||
priorityDemoteKeywords: tagsFromValue(priorityDemote.keywords ?? ['timeout', 'network', 'rate_limit', 'overloaded', 'temporarily_unavailable', 'server_error', '429', '5xx']),
|
||||
singleSourceProtectionEnabled: readBool(singleSource.enabled, true),
|
||||
metadataJson: JSON.stringify(policy?.metadata ?? {}, null, 2),
|
||||
status: policy?.status ?? 'active',
|
||||
};
|
||||
@@ -617,6 +638,9 @@ function runnerFormToPayload(form: RunnerPolicyForm): GatewayRunnerPolicyUpsertR
|
||||
statusCodes: parseNumberTags(form.priorityDemoteStatusCodes),
|
||||
keywords: cleanTags(form.priorityDemoteKeywords),
|
||||
},
|
||||
singleSourcePolicy: {
|
||||
enabled: form.singleSourceProtectionEnabled,
|
||||
},
|
||||
metadata: parseJson(form.metadataJson),
|
||||
status: form.status.trim() || 'active',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user