mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: 使用量轮询接口添加 API 格式转换字段
- 前端:添加 api_format、endpoint_api_format、has_format_conversion 类型定义 - 前端:轮询时同步更新格式转换相关字段 - 后端:查询时返回格式转换字段,包含历史数据兼容逻辑 - 后端:优化 import 位置提升性能
This commit is contained in:
@@ -223,6 +223,9 @@ export const meApi = {
|
|||||||
rate_multiplier?: number | null
|
rate_multiplier?: number | null
|
||||||
response_time_ms: number | null
|
response_time_ms: number | null
|
||||||
first_byte_time_ms: number | null
|
first_byte_time_ms: number | null
|
||||||
|
api_format?: string | null
|
||||||
|
endpoint_api_format?: string | null
|
||||||
|
has_format_conversion?: boolean | null
|
||||||
}>
|
}>
|
||||||
}> {
|
}> {
|
||||||
const params = ids ? { ids } : {}
|
const params = ids ? { ids } : {}
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ export const usageApi = {
|
|||||||
first_byte_time_ms: number | null
|
first_byte_time_ms: number | null
|
||||||
provider?: string | null
|
provider?: string | null
|
||||||
api_key_name?: string | null
|
api_key_name?: string | null
|
||||||
|
api_format?: string | null
|
||||||
|
endpoint_api_format?: string | null
|
||||||
|
has_format_conversion?: boolean | null
|
||||||
}>
|
}>
|
||||||
}> {
|
}> {
|
||||||
const params = ids?.length ? { ids: ids.join(',') } : {}
|
const params = ids?.length ? { ids: ids.join(',') } : {}
|
||||||
|
|||||||
@@ -290,6 +290,10 @@ async function pollActiveRequests() {
|
|||||||
record.rate_multiplier = update.rate_multiplier ?? undefined
|
record.rate_multiplier = update.rate_multiplier ?? undefined
|
||||||
record.response_time_ms = update.response_time_ms ?? undefined
|
record.response_time_ms = update.response_time_ms ?? undefined
|
||||||
record.first_byte_time_ms = update.first_byte_time_ms ?? undefined
|
record.first_byte_time_ms = update.first_byte_time_ms ?? undefined
|
||||||
|
// API 格式/格式转换:streaming 时已可确定,轮询时同步更新
|
||||||
|
if (update.api_format !== undefined) record.api_format = update.api_format
|
||||||
|
if (update.endpoint_api_format !== undefined) record.endpoint_api_format = update.endpoint_api_format
|
||||||
|
if (update.has_format_conversion !== undefined) record.has_format_conversion = update.has_format_conversion
|
||||||
// 管理员接口返回额外字段
|
// 管理员接口返回额外字段
|
||||||
if ('provider' in update && typeof update.provider === 'string') {
|
if ('provider' in update && typeof update.provider === 'string') {
|
||||||
record.provider = update.provider
|
record.provider = update.provider
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
|||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from src.core.api_format.metadata import can_passthrough
|
||||||
from src.core.logger import logger
|
from src.core.logger import logger
|
||||||
from src.models.database import ApiKey, Provider, ProviderAPIKey, Usage, User, UserRole
|
from src.models.database import ApiKey, Provider, ProviderAPIKey, Usage, User, UserRole
|
||||||
from src.services.model.cost import ModelCostService
|
from src.services.model.cost import ModelCostService
|
||||||
@@ -1959,6 +1960,10 @@ class UsageService:
|
|||||||
Usage.first_byte_time_ms, # 首字时间 (TTFB)
|
Usage.first_byte_time_ms, # 首字时间 (TTFB)
|
||||||
Usage.created_at,
|
Usage.created_at,
|
||||||
Usage.provider_endpoint_id,
|
Usage.provider_endpoint_id,
|
||||||
|
# API 格式 / 格式转换(streaming 状态时已可确定)
|
||||||
|
Usage.api_format,
|
||||||
|
Usage.endpoint_api_format,
|
||||||
|
Usage.has_format_conversion,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 管理员轮询:可附带 provider 与上游 key 名称(注意:不要在普通用户接口暴露上游 key 信息)
|
# 管理员轮询:可附带 provider 与上游 key 名称(注意:不要在普通用户接口暴露上游 key 信息)
|
||||||
@@ -2008,6 +2013,18 @@ class UsageService:
|
|||||||
|
|
||||||
result: List[Dict[str, Any]] = []
|
result: List[Dict[str, Any]] = []
|
||||||
for r in records:
|
for r in records:
|
||||||
|
api_format = getattr(r, "api_format", None)
|
||||||
|
endpoint_api_format = getattr(r, "endpoint_api_format", None)
|
||||||
|
has_format_conversion = getattr(r, "has_format_conversion", None)
|
||||||
|
|
||||||
|
# 兼容历史数据:当 streaming 状态已拿到两个格式但 has_format_conversion 为空时,回填推断结果
|
||||||
|
if (
|
||||||
|
has_format_conversion is None
|
||||||
|
and api_format
|
||||||
|
and endpoint_api_format
|
||||||
|
):
|
||||||
|
has_format_conversion = not can_passthrough(api_format, endpoint_api_format)
|
||||||
|
|
||||||
item: Dict[str, Any] = {
|
item: Dict[str, Any] = {
|
||||||
"id": r.id,
|
"id": r.id,
|
||||||
"status": "failed" if r.id in timeout_ids else r.status,
|
"status": "failed" if r.id in timeout_ids else r.status,
|
||||||
@@ -2021,6 +2038,12 @@ class UsageService:
|
|||||||
"response_time_ms": r.response_time_ms,
|
"response_time_ms": r.response_time_ms,
|
||||||
"first_byte_time_ms": r.first_byte_time_ms, # 首字时间 (TTFB)
|
"first_byte_time_ms": r.first_byte_time_ms, # 首字时间 (TTFB)
|
||||||
}
|
}
|
||||||
|
if api_format:
|
||||||
|
item["api_format"] = api_format
|
||||||
|
if endpoint_api_format:
|
||||||
|
item["endpoint_api_format"] = endpoint_api_format
|
||||||
|
if has_format_conversion is not None:
|
||||||
|
item["has_format_conversion"] = bool(has_format_conversion)
|
||||||
if include_admin_fields:
|
if include_admin_fields:
|
||||||
item["provider"] = r.provider_name
|
item["provider"] = r.provider_name
|
||||||
item["api_key_name"] = r.api_key_name
|
item["api_key_name"] = r.api_key_name
|
||||||
|
|||||||
Reference in New Issue
Block a user