feat(web): refresh rate limits timestamp and tpm settlement display
This commit is contained in:
parent
b609640a9f
commit
d69aaed444
@ -187,6 +187,7 @@ export function App() {
|
||||
const [auditLogs, setAuditLogs] = useState<GatewayAuditLog[]>([]);
|
||||
const [rateLimitWindows, setRateLimitWindows] = useState<RateLimitWindow[]>([]);
|
||||
const [modelRateLimits, setModelRateLimits] = useState<ModelRateLimitStatus[]>([]);
|
||||
const [modelRateLimitsUpdatedAt, setModelRateLimitsUpdatedAt] = useState<number | null>(null);
|
||||
const [tenants, setTenants] = useState<GatewayTenant[]>([]);
|
||||
const [users, setUsers] = useState<GatewayUser[]>([]);
|
||||
const [userGroups, setUserGroups] = useState<UserGroup[]>([]);
|
||||
@ -249,6 +250,7 @@ export function App() {
|
||||
void Promise.all([listModelRateLimitStatuses(token), listPlatforms(token)])
|
||||
.then(([rateLimitResponse, platformResponse]) => {
|
||||
setModelRateLimits(rateLimitResponse.items);
|
||||
setModelRateLimitsUpdatedAt(Date.now());
|
||||
setPlatforms(platformResponse.items);
|
||||
loadedDataKeysRef.current.add('modelRateLimits');
|
||||
loadedDataKeysRef.current.add('platforms');
|
||||
@ -299,10 +301,11 @@ export function App() {
|
||||
platforms,
|
||||
pricingRules,
|
||||
pricingRuleSets,
|
||||
providers,
|
||||
rateLimitWindows,
|
||||
modelRateLimits,
|
||||
runtimePolicySets,
|
||||
providers,
|
||||
rateLimitWindows,
|
||||
modelRateLimits,
|
||||
modelRateLimitsUpdatedAt,
|
||||
runtimePolicySets,
|
||||
taskResult,
|
||||
tasks,
|
||||
tenants,
|
||||
@ -310,7 +313,7 @@ export function App() {
|
||||
users,
|
||||
walletAccounts,
|
||||
walletTransactions,
|
||||
}), [accessRules, apiKeys, auditLogs, baseModels, modelCatalog, modelRateLimits, models, networkProxyConfig, platforms, pricingRuleSets, pricingRules, providers, rateLimitWindows, runnerPolicy, runtimePolicySets, taskResult, tasks, tenants, userGroups, users, walletAccounts, walletTransactions]);
|
||||
}), [accessRules, apiKeys, auditLogs, baseModels, modelCatalog, modelRateLimits, modelRateLimitsUpdatedAt, models, networkProxyConfig, platforms, pricingRuleSets, pricingRules, providers, rateLimitWindows, runnerPolicy, runtimePolicySets, taskResult, tasks, tenants, userGroups, users, walletAccounts, walletTransactions]);
|
||||
|
||||
async function refresh(nextToken = token) {
|
||||
await ensureRouteData(nextToken, true);
|
||||
@ -415,7 +418,11 @@ export function App() {
|
||||
setRateLimitWindows((await listRateLimitWindows(nextToken)).items);
|
||||
return;
|
||||
case 'modelRateLimits':
|
||||
setModelRateLimits((await listModelRateLimitStatuses(nextToken)).items);
|
||||
{
|
||||
const response = await listModelRateLimitStatuses(nextToken);
|
||||
setModelRateLimits(response.items);
|
||||
setModelRateLimitsUpdatedAt(Date.now());
|
||||
}
|
||||
return;
|
||||
case 'tenants':
|
||||
setTenants((await listTenants(nextToken)).items);
|
||||
|
||||
@ -37,6 +37,7 @@ export interface ConsoleData {
|
||||
providers: CatalogProvider[];
|
||||
rateLimitWindows: RateLimitWindow[];
|
||||
modelRateLimits: ModelRateLimitStatus[];
|
||||
modelRateLimitsUpdatedAt: number | null;
|
||||
runtimePolicySets: RuntimePolicySet[];
|
||||
taskResult: GatewayTask | null;
|
||||
tasks: GatewayTask[];
|
||||
|
||||
@ -137,9 +137,10 @@ export function AdminPage(props: {
|
||||
<PlatformManagementPanel
|
||||
baseModels={props.data.baseModels}
|
||||
message={props.operationMessage}
|
||||
networkProxyConfig={props.data.networkProxyConfig}
|
||||
modelRateLimits={props.data.modelRateLimits}
|
||||
platformModels={props.data.models}
|
||||
networkProxyConfig={props.data.networkProxyConfig}
|
||||
modelRateLimits={props.data.modelRateLimits}
|
||||
modelRateLimitsUpdatedAt={props.data.modelRateLimitsUpdatedAt}
|
||||
platformModels={props.data.models}
|
||||
platforms={props.data.platforms}
|
||||
pricingRuleSets={props.data.pricingRuleSets}
|
||||
providers={props.data.providers}
|
||||
|
||||
@ -22,9 +22,10 @@ import { ModelCatalogCard } from './ModelCatalogCard';
|
||||
|
||||
export function PlatformManagementPanel(props: {
|
||||
baseModels: BaseModelCatalogItem[];
|
||||
message: string;
|
||||
modelRateLimits: ModelRateLimitStatus[];
|
||||
networkProxyConfig: { globalHttpProxy?: string; globalHttpProxySet: boolean; globalHttpProxySource?: string } | null;
|
||||
message: string;
|
||||
modelRateLimits: ModelRateLimitStatus[];
|
||||
modelRateLimitsUpdatedAt: number | null;
|
||||
networkProxyConfig: { globalHttpProxy?: string; globalHttpProxySet: boolean; globalHttpProxySource?: string } | null;
|
||||
platforms: IntegrationPlatform[];
|
||||
platformModels: PlatformModel[];
|
||||
pricingRuleSets: PricingRuleSet[];
|
||||
@ -200,11 +201,16 @@ export function PlatformManagementPanel(props: {
|
||||
providerMap={providerMap}
|
||||
onModelQueryChange={setModelQuery}
|
||||
now={now}
|
||||
onPlatformChange={setSelectedPlatformId}
|
||||
/>
|
||||
) : (
|
||||
<RateLimitStatusTable statuses={props.modelRateLimits} platformMap={platformMap} now={now} />
|
||||
)}
|
||||
onPlatformChange={setSelectedPlatformId}
|
||||
/>
|
||||
) : (
|
||||
<RateLimitStatusTable
|
||||
now={now}
|
||||
platformMap={platformMap}
|
||||
statuses={props.modelRateLimits}
|
||||
updatedAt={props.modelRateLimitsUpdatedAt}
|
||||
/>
|
||||
)}
|
||||
{props.message && <p className="formMessage">{props.message}</p>}
|
||||
</CardContent>
|
||||
</Card>
|
||||
@ -572,7 +578,7 @@ function PlatformModelTable(props: {
|
||||
);
|
||||
}
|
||||
|
||||
function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platformMap: Map<string, IntegrationPlatform>; now: number }) {
|
||||
function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platformMap: Map<string, IntegrationPlatform>; now: number; updatedAt: number | null }) {
|
||||
if (!props.statuses.length) {
|
||||
return <EmptyState title="暂无限流状态" description="模型产生请求后会在这里显示实时 RPM、TPM 和并发窗口。" />;
|
||||
}
|
||||
@ -580,7 +586,7 @@ function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platfor
|
||||
<section className="platformLimitView">
|
||||
<div className="platformLimitHeader">
|
||||
<span><Gauge size={15} />按综合满载率从高到低排序</span>
|
||||
<small>每 3 秒刷新一次;TPM 显示已结算 + 预占。</small>
|
||||
<small>每 3 秒刷新一次;TPM 显示已结算 + 预占;最新更新时间 {formatTimeOfDay(props.updatedAt)}。</small>
|
||||
</div>
|
||||
<div className="platformLimitTableViewport">
|
||||
<Table className="platformDataTable platformLimitTable">
|
||||
@ -1195,15 +1201,26 @@ function rateLimitMetricText(metric: string) {
|
||||
}
|
||||
|
||||
function metricCell(metric: ModelRateLimitStatus['rpm'], includeReserved = false) {
|
||||
if (!metric.limited) return <span className="rateMetricCell"><strong>{formatLimit(metric.currentValue)} / 不限</strong><small>未配置上限</small></span>;
|
||||
if (!metric.limited) return <span className="rateMetricCell"><strong>{formatLimit(metric.currentValue)} / 不限</strong><small>{includeReserved ? reservedMetricText(metric) : '未配置上限'}</small></span>;
|
||||
return (
|
||||
<span className="rateMetricCell">
|
||||
<strong>{formatLimit(metric.currentValue)} / {formatLimit(metric.limitValue)}</strong>
|
||||
<small>{includeReserved && metric.reservedValue > 0 ? `已用 ${formatLimit(metric.usedValue)} · 预占 ${formatLimit(metric.reservedValue)}` : `窗口 ${formatPercent(metric.ratio)}`}</small>
|
||||
<small>{includeReserved ? reservedMetricText(metric) : `窗口 ${formatPercent(metric.ratio)}`}</small>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function reservedMetricText(metric: ModelRateLimitStatus['rpm']) {
|
||||
return `已结算 ${formatLimit(metric.usedValue)} + 预占 ${formatLimit(metric.reservedValue)}`;
|
||||
}
|
||||
|
||||
function formatTimeOfDay(timestamp: number | null) {
|
||||
if (!timestamp) return '暂无';
|
||||
const date = new Date(timestamp);
|
||||
const pad = (value: number) => String(value).padStart(2, '0');
|
||||
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
||||
}
|
||||
|
||||
function modelRuntimeStatusCell(status: ModelRateLimitStatus, now: number) {
|
||||
const modelCooldownMs = cooldownRemainingMs(status.modelCooldownUntil, now);
|
||||
const platformCooldownMs = cooldownRemainingMs(status.platformCooldownUntil, now);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user