mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-12 04:28:28 +08:00
refactor: 重构限流系统和健康监控,支持按 API 格式区分
- 将 adaptive_concurrency 重命名为 adaptive_rpm,从并发控制改为 RPM 控制 - 健康监控器支持按 API 格式独立管理健康度和熔断器状态 - 新增 model_permissions 模块,支持按格式配置允许的模型 - 重构前端提供商相关表单组件,新增 Collapsible UI 组件 - 新增数据库迁移脚本支持新的数据结构
This commit is contained in:
@@ -67,7 +67,6 @@ export interface GlobalModelExport {
|
||||
|
||||
export interface ProviderExport {
|
||||
name: string
|
||||
display_name: string
|
||||
description?: string | null
|
||||
website?: string | null
|
||||
billing_type?: string | null
|
||||
@@ -76,10 +75,13 @@ export interface ProviderExport {
|
||||
rpm_limit?: number | null
|
||||
provider_priority?: number
|
||||
is_active: boolean
|
||||
rate_limit?: number | null
|
||||
concurrent_limit?: number | null
|
||||
timeout?: number | null
|
||||
max_retries?: number | null
|
||||
proxy?: any
|
||||
config?: any
|
||||
endpoints: EndpointExport[]
|
||||
api_keys: ProviderKeyExport[]
|
||||
models: ModelExport[]
|
||||
}
|
||||
|
||||
@@ -89,27 +91,26 @@ export interface EndpointExport {
|
||||
headers?: any
|
||||
timeout?: number
|
||||
max_retries?: number
|
||||
max_concurrent?: number | null
|
||||
rate_limit?: number | null
|
||||
is_active: boolean
|
||||
custom_path?: string | null
|
||||
config?: any
|
||||
keys: KeyExport[]
|
||||
proxy?: any
|
||||
}
|
||||
|
||||
export interface KeyExport {
|
||||
export interface ProviderKeyExport {
|
||||
api_key: string
|
||||
name?: string | null
|
||||
note?: string | null
|
||||
api_formats: string[]
|
||||
rate_multiplier?: number
|
||||
rate_multipliers?: Record<string, number> | null
|
||||
internal_priority?: number
|
||||
global_priority?: number | null
|
||||
max_concurrent?: number | null
|
||||
rate_limit?: number | null
|
||||
daily_limit?: number | null
|
||||
monthly_limit?: number | null
|
||||
allowed_models?: string[] | null
|
||||
rpm_limit?: number | null
|
||||
allowed_models?: any
|
||||
capabilities?: any
|
||||
cache_ttl_minutes?: number
|
||||
max_probe_interval_minutes?: number
|
||||
is_active: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ export interface RequestDetail {
|
||||
request_body?: Record<string, any>
|
||||
provider_request_headers?: Record<string, any>
|
||||
response_headers?: Record<string, any>
|
||||
client_response_headers?: Record<string, any>
|
||||
response_body?: Record<string, any>
|
||||
metadata?: Record<string, any>
|
||||
// 阶梯计费信息
|
||||
|
||||
@@ -14,7 +14,7 @@ export async function toggleAdaptiveMode(
|
||||
message: string
|
||||
key_id: string
|
||||
is_adaptive: boolean
|
||||
max_concurrent: number | null
|
||||
rpm_limit: number | null
|
||||
effective_limit: number | null
|
||||
}> {
|
||||
const response = await client.patch(`/api/admin/adaptive/keys/${keyId}/mode`, data)
|
||||
@@ -22,16 +22,16 @@ export async function toggleAdaptiveMode(
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Key 的固定并发限制
|
||||
* 设置 Key 的固定 RPM 限制
|
||||
*/
|
||||
export async function setConcurrentLimit(
|
||||
export async function setRpmLimit(
|
||||
keyId: string,
|
||||
limit: number
|
||||
): Promise<{
|
||||
message: string
|
||||
key_id: string
|
||||
is_adaptive: boolean
|
||||
max_concurrent: number
|
||||
rpm_limit: number
|
||||
previous_mode: string
|
||||
}> {
|
||||
const response = await client.patch(`/api/admin/adaptive/keys/${keyId}/limit`, null, {
|
||||
|
||||
@@ -27,15 +27,9 @@ export async function createEndpoint(
|
||||
api_format: string
|
||||
base_url: string
|
||||
custom_path?: string
|
||||
auth_type?: string
|
||||
auth_header?: string
|
||||
headers?: Record<string, string>
|
||||
timeout?: number
|
||||
max_retries?: number
|
||||
priority?: number
|
||||
weight?: number
|
||||
max_concurrent?: number
|
||||
rate_limit?: number
|
||||
is_active?: boolean
|
||||
config?: Record<string, any>
|
||||
proxy?: ProxyConfig | null
|
||||
@@ -52,16 +46,10 @@ export async function updateEndpoint(
|
||||
endpointId: string,
|
||||
data: Partial<{
|
||||
base_url: string
|
||||
custom_path: string
|
||||
auth_type: string
|
||||
auth_header: string
|
||||
custom_path: string | null
|
||||
headers: Record<string, string>
|
||||
timeout: number
|
||||
max_retries: number
|
||||
priority: number
|
||||
weight: number
|
||||
max_concurrent: number
|
||||
rate_limit: number
|
||||
is_active: boolean
|
||||
config: Record<string, any>
|
||||
proxy: ProxyConfig | null
|
||||
@@ -74,7 +62,7 @@ export async function updateEndpoint(
|
||||
/**
|
||||
* 删除 Endpoint
|
||||
*/
|
||||
export async function deleteEndpoint(endpointId: string): Promise<{ message: string; deleted_keys_count: number }> {
|
||||
export async function deleteEndpoint(endpointId: string): Promise<{ message: string; affected_keys_count: number }> {
|
||||
const response = await client.delete(`/api/admin/endpoints/${endpointId}`)
|
||||
return response.data
|
||||
}
|
||||
|
||||
@@ -32,16 +32,21 @@ export async function getKeyHealth(keyId: string): Promise<HealthStatus> {
|
||||
|
||||
/**
|
||||
* 恢复Key健康状态(一键恢复:重置健康度 + 关闭熔断器 + 取消自动禁用)
|
||||
* @param keyId Key ID
|
||||
* @param apiFormat 可选,指定 API 格式(如 CLAUDE、OPENAI),不指定则恢复所有格式
|
||||
*/
|
||||
export async function recoverKeyHealth(keyId: string): Promise<{
|
||||
export async function recoverKeyHealth(keyId: string, apiFormat?: string): Promise<{
|
||||
message: string
|
||||
details: {
|
||||
api_format?: string
|
||||
health_score: number
|
||||
circuit_breaker_open: boolean
|
||||
is_active: boolean
|
||||
}
|
||||
}> {
|
||||
const response = await client.patch(`/api/admin/endpoints/health/keys/${keyId}`)
|
||||
const response = await client.patch(`/api/admin/endpoints/health/keys/${keyId}`, null, {
|
||||
params: apiFormat ? { api_format: apiFormat } : undefined
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import client from '../client'
|
||||
import type { EndpointAPIKey } from './types'
|
||||
import type { EndpointAPIKey, AllowedModels } from './types'
|
||||
|
||||
/**
|
||||
* 能力定义类型
|
||||
@@ -49,67 +49,6 @@ export async function getModelCapabilities(modelName: string): Promise<ModelCapa
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Endpoint 的所有 Keys
|
||||
*/
|
||||
export async function getEndpointKeys(endpointId: string): Promise<EndpointAPIKey[]> {
|
||||
const response = await client.get(`/api/admin/endpoints/${endpointId}/keys`)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 Endpoint 添加 Key
|
||||
*/
|
||||
export async function addEndpointKey(
|
||||
endpointId: string,
|
||||
data: {
|
||||
endpoint_id: string
|
||||
api_key: string
|
||||
name: string // 密钥名称(必填)
|
||||
rate_multiplier?: number // 成本倍率(默认 1.0)
|
||||
internal_priority?: number // Endpoint 内部优先级(数字越小越优先)
|
||||
max_concurrent?: number // 最大并发数(留空=自适应模式)
|
||||
rate_limit?: number
|
||||
daily_limit?: number
|
||||
monthly_limit?: number
|
||||
cache_ttl_minutes?: number // 缓存 TTL(分钟),0=禁用
|
||||
max_probe_interval_minutes?: number // 熔断探测间隔(分钟)
|
||||
allowed_models?: string[] // 允许使用的模型列表
|
||||
capabilities?: Record<string, boolean> // 能力标签配置
|
||||
note?: string // 备注说明(可选)
|
||||
}
|
||||
): Promise<EndpointAPIKey> {
|
||||
const response = await client.post(`/api/admin/endpoints/${endpointId}/keys`, data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 Endpoint Key
|
||||
*/
|
||||
export async function updateEndpointKey(
|
||||
keyId: string,
|
||||
data: Partial<{
|
||||
api_key: string
|
||||
name: string // 密钥名称
|
||||
rate_multiplier: number // 成本倍率
|
||||
internal_priority: number // Endpoint 内部优先级(提供商优先模式,数字越小越优先)
|
||||
global_priority: number // 全局 Key 优先级(全局 Key 优先模式,数字越小越优先)
|
||||
max_concurrent: number // 最大并发数(留空=自适应模式)
|
||||
rate_limit: number
|
||||
daily_limit: number
|
||||
monthly_limit: number
|
||||
cache_ttl_minutes: number // 缓存 TTL(分钟),0=禁用
|
||||
max_probe_interval_minutes: number // 熔断探测间隔(分钟)
|
||||
allowed_models: string[] | null // 允许使用的模型列表,null 表示允许所有
|
||||
capabilities: Record<string, boolean> | null // 能力标签配置
|
||||
is_active: boolean
|
||||
note: string // 备注说明
|
||||
}>
|
||||
): Promise<EndpointAPIKey> {
|
||||
const response = await client.put(`/api/admin/endpoints/keys/${keyId}`, data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整的 API Key(用于查看和复制)
|
||||
*/
|
||||
@@ -119,22 +58,71 @@ export async function revealEndpointKey(keyId: string): Promise<{ api_key: strin
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 Endpoint Key
|
||||
* 删除 Key
|
||||
*/
|
||||
export async function deleteEndpointKey(keyId: string): Promise<{ message: string }> {
|
||||
const response = await client.delete(`/api/admin/endpoints/keys/${keyId}`)
|
||||
return response.data
|
||||
}
|
||||
|
||||
|
||||
// ========== Provider 级别的 Keys API ==========
|
||||
|
||||
|
||||
/**
|
||||
* 批量更新 Endpoint Keys 的优先级(用于拖动排序)
|
||||
* 获取 Provider 的所有 Keys
|
||||
*/
|
||||
export async function batchUpdateKeyPriority(
|
||||
endpointId: string,
|
||||
priorities: Array<{ key_id: string; internal_priority: number }>
|
||||
): Promise<{ message: string; updated_count: number }> {
|
||||
const response = await client.put(`/api/admin/endpoints/${endpointId}/keys/batch-priority`, {
|
||||
priorities
|
||||
})
|
||||
export async function getProviderKeys(providerId: string): Promise<EndpointAPIKey[]> {
|
||||
const response = await client.get(`/api/admin/endpoints/providers/${providerId}/keys`)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 为 Provider 添加 Key
|
||||
*/
|
||||
export async function addProviderKey(
|
||||
providerId: string,
|
||||
data: {
|
||||
api_formats: string[] // 支持的 API 格式列表(必填)
|
||||
api_key: string
|
||||
name: string
|
||||
rate_multiplier?: number // 默认成本倍率
|
||||
rate_multipliers?: Record<string, number> | null // 按 API 格式的成本倍率
|
||||
internal_priority?: number
|
||||
rpm_limit?: number | null // RPM 限制(留空=自适应模式)
|
||||
cache_ttl_minutes?: number
|
||||
max_probe_interval_minutes?: number
|
||||
allowed_models?: AllowedModels
|
||||
capabilities?: Record<string, boolean>
|
||||
note?: string
|
||||
}
|
||||
): Promise<EndpointAPIKey> {
|
||||
const response = await client.post(`/api/admin/endpoints/providers/${providerId}/keys`, data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 Key
|
||||
*/
|
||||
export async function updateProviderKey(
|
||||
keyId: string,
|
||||
data: Partial<{
|
||||
api_formats: string[] // 支持的 API 格式列表
|
||||
api_key: string
|
||||
name: string
|
||||
rate_multiplier: number // 默认成本倍率
|
||||
rate_multipliers: Record<string, number> | null // 按 API 格式的成本倍率
|
||||
internal_priority: number
|
||||
global_priority: number | null
|
||||
rpm_limit: number | null // RPM 限制(留空=自适应模式)
|
||||
cache_ttl_minutes: number
|
||||
max_probe_interval_minutes: number
|
||||
allowed_models: AllowedModels
|
||||
capabilities: Record<string, boolean> | null
|
||||
is_active: boolean
|
||||
note: string
|
||||
}>
|
||||
): Promise<EndpointAPIKey> {
|
||||
const response = await client.put(`/api/admin/endpoints/keys/${keyId}`, data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
@@ -147,14 +147,26 @@ export async function queryProviderUpstreamModels(
|
||||
|
||||
/**
|
||||
* 从上游提供商导入模型
|
||||
* @param providerId 提供商 ID
|
||||
* @param modelIds 模型 ID 列表
|
||||
* @param options 可选配置
|
||||
* @param options.tiered_pricing 阶梯计费配置
|
||||
* @param options.price_per_request 按次计费价格
|
||||
*/
|
||||
export async function importModelsFromUpstream(
|
||||
providerId: string,
|
||||
modelIds: string[]
|
||||
modelIds: string[],
|
||||
options?: {
|
||||
tiered_pricing?: object
|
||||
price_per_request?: number
|
||||
}
|
||||
): Promise<ImportFromUpstreamResponse> {
|
||||
const response = await client.post(
|
||||
`/api/admin/providers/${providerId}/import-from-upstream`,
|
||||
{ model_ids: modelIds }
|
||||
{
|
||||
model_ids: modelIds,
|
||||
...options
|
||||
}
|
||||
)
|
||||
return response.data
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import client from '../client'
|
||||
import type { ProviderWithEndpointsSummary } from './types'
|
||||
import type { ProviderWithEndpointsSummary, ProxyConfig } from './types'
|
||||
|
||||
/**
|
||||
* 获取 Providers 摘要(包含 Endpoints 统计)
|
||||
@@ -23,7 +23,7 @@ export async function getProvider(providerId: string): Promise<ProviderWithEndpo
|
||||
export async function updateProvider(
|
||||
providerId: string,
|
||||
data: Partial<{
|
||||
display_name: string
|
||||
name: string
|
||||
description: string
|
||||
website: string
|
||||
provider_priority: number
|
||||
@@ -33,6 +33,10 @@ export async function updateProvider(
|
||||
quota_last_reset_at: string // 周期开始时间
|
||||
quota_expires_at: string
|
||||
rpm_limit: number | null
|
||||
// 请求配置(从 Endpoint 迁移)
|
||||
timeout: number
|
||||
max_retries: number
|
||||
proxy: ProxyConfig | null
|
||||
cache_ttl_minutes: number // 0表示不支持缓存,>0表示支持缓存并设置TTL(分钟)
|
||||
max_probe_interval_minutes: number
|
||||
is_active: boolean
|
||||
@@ -83,7 +87,6 @@ export interface TestModelResponse {
|
||||
provider?: {
|
||||
id: string
|
||||
name: string
|
||||
display_name: string
|
||||
}
|
||||
model?: string
|
||||
}
|
||||
@@ -92,4 +95,3 @@ export async function testModel(data: TestModelRequest): Promise<TestModelRespon
|
||||
const response = await client.post('/api/admin/provider-query/test-model', data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,38 @@ export const API_FORMAT_LABELS: Record<string, string> = {
|
||||
[API_FORMATS.GEMINI_CLI]: 'Gemini CLI',
|
||||
}
|
||||
|
||||
// API 格式缩写映射(用于空间紧凑的显示场景)
|
||||
export const API_FORMAT_SHORT: Record<string, string> = {
|
||||
[API_FORMATS.OPENAI]: 'O',
|
||||
[API_FORMATS.OPENAI_CLI]: 'OC',
|
||||
[API_FORMATS.CLAUDE]: 'C',
|
||||
[API_FORMATS.CLAUDE_CLI]: 'CC',
|
||||
[API_FORMATS.GEMINI]: 'G',
|
||||
[API_FORMATS.GEMINI_CLI]: 'GC',
|
||||
}
|
||||
|
||||
// API 格式排序顺序(统一的显示顺序)
|
||||
export const API_FORMAT_ORDER: string[] = [
|
||||
API_FORMATS.OPENAI,
|
||||
API_FORMATS.OPENAI_CLI,
|
||||
API_FORMATS.CLAUDE,
|
||||
API_FORMATS.CLAUDE_CLI,
|
||||
API_FORMATS.GEMINI,
|
||||
API_FORMATS.GEMINI_CLI,
|
||||
]
|
||||
|
||||
// 工具函数:按标准顺序排序 API 格式数组
|
||||
export function sortApiFormats(formats: string[]): string[] {
|
||||
return [...formats].sort((a, b) => {
|
||||
const aIdx = API_FORMAT_ORDER.indexOf(a)
|
||||
const bIdx = API_FORMAT_ORDER.indexOf(b)
|
||||
if (aIdx === -1 && bIdx === -1) return 0
|
||||
if (aIdx === -1) return 1
|
||||
if (bIdx === -1) return -1
|
||||
return aIdx - bIdx
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 代理配置类型
|
||||
*/
|
||||
@@ -37,18 +69,9 @@ export interface ProviderEndpoint {
|
||||
api_format: string
|
||||
base_url: string
|
||||
custom_path?: string // 自定义请求路径(可选,为空则使用 API 格式默认路径)
|
||||
auth_type: string
|
||||
auth_header?: string
|
||||
headers?: Record<string, string>
|
||||
timeout: number
|
||||
max_retries: number
|
||||
priority: number
|
||||
weight: number
|
||||
max_concurrent?: number
|
||||
rate_limit?: number
|
||||
health_score: number
|
||||
consecutive_failures: number
|
||||
last_failure_at?: string
|
||||
is_active: boolean
|
||||
config?: Record<string, any>
|
||||
proxy?: ProxyConfig | null
|
||||
@@ -58,25 +81,55 @@ export interface ProviderEndpoint {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型权限配置类型(支持简单列表和按格式字典两种模式)
|
||||
*
|
||||
* 使用示例:
|
||||
* 1. 不限制(允许所有模型): null
|
||||
* 2. 简单列表模式(所有 API 格式共享同一个白名单): ["gpt-4", "claude-3-opus"]
|
||||
* 3. 按格式字典模式(不同 API 格式使用不同的白名单):
|
||||
* { "OPENAI": ["gpt-4"], "CLAUDE": ["claude-3-opus"] }
|
||||
*/
|
||||
export type AllowedModels = string[] | Record<string, string[]> | null
|
||||
|
||||
// AllowedModels 类型守卫函数
|
||||
export function isAllowedModelsList(value: AllowedModels): value is string[] {
|
||||
return Array.isArray(value)
|
||||
}
|
||||
|
||||
export function isAllowedModelsDict(value: AllowedModels): value is Record<string, string[]> {
|
||||
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
||||
return false
|
||||
}
|
||||
// 验证所有值都是字符串数组
|
||||
return Object.values(value).every(
|
||||
(v) => Array.isArray(v) && v.every((item) => typeof item === 'string')
|
||||
)
|
||||
}
|
||||
|
||||
export interface EndpointAPIKey {
|
||||
id: string
|
||||
endpoint_id: string
|
||||
provider_id: string
|
||||
api_formats: string[] // 支持的 API 格式列表
|
||||
api_key_masked: string
|
||||
api_key_plain?: string | null
|
||||
name: string // 密钥名称(必填,用于识别)
|
||||
rate_multiplier: number // 成本倍率(真实成本 = 表面成本 × 倍率)
|
||||
internal_priority: number // Endpoint 内部优先级
|
||||
rate_multiplier: number // 默认成本倍率(真实成本 = 表面成本 × 倍率)
|
||||
rate_multipliers?: Record<string, number> | null // 按 API 格式的成本倍率,如 {"CLAUDE": 1.0, "OPENAI": 0.8}
|
||||
internal_priority: number // Key 内部优先级
|
||||
global_priority?: number | null // 全局 Key 优先级
|
||||
max_concurrent?: number
|
||||
rate_limit?: number
|
||||
daily_limit?: number
|
||||
monthly_limit?: number
|
||||
allowed_models?: string[] | null // 允许使用的模型列表(null = 支持所有模型)
|
||||
rpm_limit?: number | null // RPM 速率限制 (1-10000),null 表示自适应模式
|
||||
allowed_models?: AllowedModels // 允许使用的模型列表(null=不限制,列表=简单白名单,字典=按格式区分)
|
||||
capabilities?: Record<string, boolean> | null // 能力标签配置(如 cache_1h, context_1m)
|
||||
// 缓存与熔断配置
|
||||
cache_ttl_minutes: number // 缓存 TTL(分钟),0=禁用
|
||||
max_probe_interval_minutes: number // 熔断探测间隔(分钟)
|
||||
// 按格式的健康度数据
|
||||
health_by_format?: Record<string, FormatHealthData>
|
||||
circuit_breaker_by_format?: Record<string, FormatCircuitBreakerData>
|
||||
// 聚合字段(从 health_by_format 计算,用于列表显示)
|
||||
health_score: number
|
||||
circuit_breaker_open?: boolean
|
||||
consecutive_failures: number
|
||||
last_failure_at?: string
|
||||
request_count: number
|
||||
@@ -89,10 +142,10 @@ export interface EndpointAPIKey {
|
||||
last_used_at?: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
// 自适应并发字段
|
||||
is_adaptive?: boolean // 是否为自适应模式(max_concurrent=NULL)
|
||||
effective_limit?: number // 当前有效限制(自适应使用学习值,固定使用配置值)
|
||||
learned_max_concurrent?: number
|
||||
// 自适应 RPM 字段
|
||||
is_adaptive?: boolean // 是否为自适应模式(rpm_limit=NULL)
|
||||
effective_limit?: number // 当前有效 RPM 限制(自适应使用学习值,固定使用配置值)
|
||||
learned_rpm_limit?: number // 学习到的 RPM 限制
|
||||
// 滑动窗口利用率采样
|
||||
utilization_samples?: Array<{ ts: number; util: number }> // 利用率采样窗口
|
||||
last_probe_increase_at?: string // 上次探测性扩容时间
|
||||
@@ -100,8 +153,7 @@ export interface EndpointAPIKey {
|
||||
rpm_429_count?: number
|
||||
last_429_at?: string
|
||||
last_429_type?: string
|
||||
// 熔断器字段(滑动窗口 + 半开模式)
|
||||
circuit_breaker_open?: boolean
|
||||
// 单格式场景的熔断器字段
|
||||
circuit_breaker_open_at?: string
|
||||
next_probe_at?: string
|
||||
half_open_until?: string
|
||||
@@ -110,17 +162,36 @@ export interface EndpointAPIKey {
|
||||
request_results_window?: Array<{ ts: number; ok: boolean }> // 请求结果滑动窗口
|
||||
}
|
||||
|
||||
// 按格式的健康度数据
|
||||
export interface FormatHealthData {
|
||||
health_score: number
|
||||
error_rate: number
|
||||
window_size: number
|
||||
consecutive_failures: number
|
||||
last_failure_at?: string | null
|
||||
circuit_breaker: FormatCircuitBreakerData
|
||||
}
|
||||
|
||||
// 按格式的熔断器数据
|
||||
export interface FormatCircuitBreakerData {
|
||||
open: boolean
|
||||
open_at?: string | null
|
||||
next_probe_at?: string | null
|
||||
half_open_until?: string | null
|
||||
half_open_successes: number
|
||||
half_open_failures: number
|
||||
}
|
||||
|
||||
export interface EndpointAPIKeyUpdate {
|
||||
api_formats?: string[] // 支持的 API 格式列表
|
||||
name?: string
|
||||
api_key?: string // 仅在需要更新时提供
|
||||
rate_multiplier?: number
|
||||
rate_multiplier?: number // 默认成本倍率
|
||||
rate_multipliers?: Record<string, number> | null // 按 API 格式的成本倍率
|
||||
internal_priority?: number
|
||||
global_priority?: number | null
|
||||
max_concurrent?: number | null // null 表示切换为自适应模式
|
||||
rate_limit?: number
|
||||
daily_limit?: number
|
||||
monthly_limit?: number
|
||||
allowed_models?: string[] | null
|
||||
rpm_limit?: number | null // RPM 速率限制 (1-10000),null 表示切换为自适应模式
|
||||
allowed_models?: AllowedModels
|
||||
capabilities?: Record<string, boolean> | null
|
||||
cache_ttl_minutes?: number
|
||||
max_probe_interval_minutes?: number
|
||||
@@ -198,7 +269,6 @@ export interface PublicEndpointStatusMonitorResponse {
|
||||
export interface ProviderWithEndpointsSummary {
|
||||
id: string
|
||||
name: string
|
||||
display_name: string
|
||||
description?: string
|
||||
website?: string
|
||||
provider_priority: number
|
||||
@@ -208,9 +278,10 @@ export interface ProviderWithEndpointsSummary {
|
||||
quota_reset_day?: number
|
||||
quota_last_reset_at?: string // 当前周期开始时间
|
||||
quota_expires_at?: string
|
||||
rpm_limit?: number | null
|
||||
rpm_used?: number
|
||||
rpm_reset_at?: string
|
||||
// 请求配置(从 Endpoint 迁移)
|
||||
timeout?: number // 请求超时(秒)
|
||||
max_retries?: number // 最大重试次数
|
||||
proxy?: ProxyConfig | null // 代理配置
|
||||
is_active: boolean
|
||||
total_endpoints: number
|
||||
active_endpoints: number
|
||||
@@ -253,13 +324,10 @@ export interface HealthSummary {
|
||||
}
|
||||
}
|
||||
|
||||
export interface ConcurrencyStatus {
|
||||
endpoint_id?: string
|
||||
endpoint_current_concurrency: number
|
||||
endpoint_max_concurrent?: number
|
||||
key_id?: string
|
||||
key_current_concurrency: number
|
||||
key_max_concurrent?: number
|
||||
export interface KeyRpmStatus {
|
||||
key_id: string
|
||||
current_rpm: number
|
||||
rpm_limit?: number
|
||||
}
|
||||
|
||||
export interface ProviderModelMapping {
|
||||
@@ -361,7 +429,6 @@ export interface ModelPriceRange {
|
||||
export interface ModelCatalogProviderDetail {
|
||||
provider_id: string
|
||||
provider_name: string
|
||||
provider_display_name?: string | null
|
||||
model_id?: string | null
|
||||
target_model: string
|
||||
input_price_per_1m?: number | null
|
||||
@@ -534,10 +601,10 @@ export interface UpstreamModel {
|
||||
*/
|
||||
export interface ImportFromUpstreamSuccessItem {
|
||||
model_id: string
|
||||
global_model_id: string
|
||||
global_model_name: string
|
||||
provider_model_id: string
|
||||
created_global_model: boolean
|
||||
global_model_id?: string // 可选,未关联时为空字符串
|
||||
global_model_name?: string // 可选,未关联时为空字符串
|
||||
created_global_model: boolean // 始终为 false(不再自动创建 GlobalModel)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user