fix(rate-limits): treat empty policies as unlimited

This commit is contained in:
2026-05-24 22:28:25 +08:00
parent 6d99e26e2a
commit 71950d2b4f
9 changed files with 168 additions and 45 deletions
@@ -343,10 +343,10 @@ export function PlatformManagementPanel(props: {
</FormSection>
<FormSection icon={<ShieldCheck size={16} />} title="限流策略">
<Label>RPM / <Input value={form.rpmLimit} placeholder="不填不限" inputMode="numeric" onChange={(event) => setForm({ ...form, rpmLimit: event.target.value })} /></Label>
<Label>RPS / <Input value={form.rpsLimit} placeholder="不填不限" inputMode="numeric" onChange={(event) => setForm({ ...form, rpsLimit: event.target.value })} /></Label>
<Label>TPM / Token<Input value={form.tpmLimit} placeholder="不填不限" inputMode="numeric" onChange={(event) => setForm({ ...form, tpmLimit: event.target.value })} /></Label>
<Label><Input value={form.concurrencyLimit} placeholder="不填不限" inputMode="numeric" onChange={(event) => setForm({ ...form, concurrencyLimit: event.target.value })} /></Label>
<Label>RPM / <Input value={form.rpmLimit} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, rpmLimit: event.target.value })} /></Label>
<Label>RPS / <Input value={form.rpsLimit} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, rpsLimit: event.target.value })} /></Label>
<Label>TPM / Token<Input value={form.tpmLimit} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, tpmLimit: event.target.value })} /></Label>
<Label><Input value={form.concurrencyLimit} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, concurrencyLimit: event.target.value })} /></Label>
<div className="platformTogglePair">
<ToggleField checked={form.supportBase64Input} label="支持 Base64 输入" onChange={(checked) => setForm({ ...form, supportBase64Input: checked })} />
<ToggleField checked={form.supportUrlInput} label="支持 URL 输入" onChange={(checked) => setForm({ ...form, supportUrlInput: checked })} />
@@ -1172,13 +1172,13 @@ function formatDiscountFactor(value: number | undefined) {
function platformRateLimitSummary(policy: IntegrationPlatform['rateLimitPolicy']) {
const rules = Array.isArray(policy?.rules) ? policy.rules : [];
if (!rules.length) {
return { title: '未设置', subtitle: '跟随全局或模型策略' };
return { title: '不限', subtitle: '未配置限流上限' };
}
const labels = rules
.filter((rule) => typeof rule.limit === 'number' && Number.isFinite(rule.limit))
.filter((rule) => typeof rule.limit === 'number' && Number.isFinite(rule.limit) && rule.limit > 0)
.map((rule) => `${rateLimitMetricText(rule.metric)} ${formatLimit(rule.limit)}`);
if (!labels.length) {
return { title: '未设置', subtitle: '跟随全局或模型策略' };
return { title: '不限', subtitle: '未配置限流上限' };
}
return {
title: labels.slice(0, 2).join(' · '),
@@ -270,9 +270,9 @@ export function RuntimePoliciesPanel(props: {
<section className="runtimePolicySection spanTwo">
<header><strong></strong><span>TPM / RPM / </span></header>
<div className="runtimePolicyRows">
<Label>RPM / <Input value={form.rpm} inputMode="numeric" onChange={(event) => setForm({ ...form, rpm: event.target.value })} /></Label>
<Label>TPM / Token<Input value={form.tpm} inputMode="numeric" onChange={(event) => setForm({ ...form, tpm: event.target.value })} /></Label>
<Label><Input value={form.concurrency} inputMode="numeric" onChange={(event) => setForm({ ...form, concurrency: event.target.value })} /></Label>
<Label>RPM / <Input value={form.rpm} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, rpm: event.target.value })} /></Label>
<Label>TPM / Token<Input value={form.tpm} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, tpm: event.target.value })} /></Label>
<Label><Input value={form.concurrency} placeholder="不填或负数为不限" inputMode="numeric" onChange={(event) => setForm({ ...form, concurrency: event.target.value })} /></Label>
</div>
</section>
@@ -760,9 +760,9 @@ function policyToForm(policy: RuntimePolicySet): RuntimePolicyForm {
policyKey: policy.policyKey,
name: policy.name,
description: policy.description ?? '',
rpm: String(readRateLimit(rateRules, 'rpm') || ''),
tpm: String(readRateLimit(rateRules, 'tpm_total') || ''),
concurrency: String(readRateLimit(rateRules, 'concurrent') || ''),
rpm: formRateLimitText(readRateLimit(rateRules, 'rpm')),
tpm: formRateLimitText(readRateLimit(rateRules, 'tpm_total')),
concurrency: formRateLimitText(readRateLimit(rateRules, 'concurrent')),
retryEnabled: readBool(retry.enabled, true),
retryMaxAttempts: String(readNumber(retry.maxAttempts, 2)),
retryAllowKeywords: tagsFromValue(retry.allowKeywords),
@@ -825,9 +825,9 @@ function isDefaultPolicy(policy: RuntimePolicySet) {
function rateLimitSummary(policy: RuntimePolicySet) {
const rules = Array.isArray(policy.rateLimitPolicy?.rules) ? policy.rateLimitPolicy.rules : [];
const rpm = readRateLimit(rules, 'rpm') || '-';
const tpm = readRateLimit(rules, 'tpm_total') || '-';
const concurrent = readRateLimit(rules, 'concurrent') || '-';
const rpm = rateLimitText(readRateLimit(rules, 'rpm'));
const tpm = rateLimitText(readRateLimit(rules, 'tpm_total'));
const concurrent = rateLimitText(readRateLimit(rules, 'concurrent'));
return `RPM ${rpm} / TPM ${tpm} / 并发 ${concurrent}`;
}
@@ -848,7 +848,16 @@ function degradeSummary(policy: RuntimePolicySet) {
function readRateLimit(rules: unknown[], metric: string) {
const rule = rules.find((item) => readObject(item).metric === metric);
return readNumber(readObject(rule).limit, 0);
const limit = Number(readObject(rule).limit);
return Number.isFinite(limit) ? limit : undefined;
}
function formRateLimitText(value: number | undefined) {
return value === undefined ? '' : String(value);
}
function rateLimitText(value: number | undefined) {
return value !== undefined && value > 0 ? String(value) : '不限';
}
function stringifyKeywords(value: unknown) {
+1 -1
View File
@@ -397,7 +397,7 @@ function rateLimitPolicyPayload(form: Pick<PlatformWizardForm, 'rpmLimit' | 'rps
limitRule('tpm_total', form.tpmLimit),
limitRule('concurrent', form.concurrencyLimit),
].filter((rule): rule is NonNullable<ReturnType<typeof limitRule>> => Boolean(rule));
return rules.length ? { rules } : {};
return { rules };
}
function networkProxyPayload(form: PlatformWizardForm) {