mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/ - 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层 - 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构 - 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations) - 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image - 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
177 lines
6.4 KiB
Python
177 lines
6.4 KiB
Python
from __future__ import annotations
|
||
|
||
from sqlalchemy.orm import Session
|
||
|
||
from src.models.database import ProviderAPIKey
|
||
from src.services.model.cost import ModelCostService
|
||
|
||
|
||
class UsagePricingMixin:
|
||
"""定价相关方法"""
|
||
|
||
@classmethod
|
||
async def get_model_price_async(
|
||
cls, db: Session, provider: str, model: str
|
||
) -> tuple[float, float]:
|
||
"""异步获取模型价格(输入价格,输出价格)每1M tokens
|
||
|
||
查找逻辑:
|
||
1. 直接通过 GlobalModel.name 匹配
|
||
2. 查找该 Provider 的 Model 实现并获取价格
|
||
3. 如果找不到则使用系统默认价格
|
||
"""
|
||
|
||
service = ModelCostService(db)
|
||
return await service.get_model_price_async(provider, model)
|
||
|
||
@classmethod
|
||
def get_model_price(cls, db: Session, provider: str, model: str) -> tuple[float, float]:
|
||
"""获取模型价格(输入价格,输出价格)每1M tokens
|
||
|
||
查找逻辑:
|
||
1. 直接通过 GlobalModel.name 匹配
|
||
2. 查找该 Provider 的 Model 实现并获取价格
|
||
3. 如果找不到则使用系统默认价格
|
||
"""
|
||
|
||
service = ModelCostService(db)
|
||
return service.get_model_price(provider, model)
|
||
|
||
@classmethod
|
||
async def get_cache_prices_async(
|
||
cls, db: Session, provider: str, model: str, input_price: float
|
||
) -> tuple[float | None, float | None]:
|
||
"""异步获取模型缓存价格(缓存创建价格,缓存读取价格)每1M tokens"""
|
||
service = ModelCostService(db)
|
||
return await service.get_cache_prices_async(provider, model, input_price)
|
||
|
||
@classmethod
|
||
def get_cache_prices(
|
||
cls, db: Session, provider: str, model: str, input_price: float
|
||
) -> tuple[float | None, float | None]:
|
||
"""获取模型缓存价格(缓存创建价格,缓存读取价格)每1M tokens"""
|
||
service = ModelCostService(db)
|
||
return service.get_cache_prices(provider, model, input_price)
|
||
|
||
@classmethod
|
||
async def get_request_price_async(cls, db: Session, provider: str, model: str) -> float | None:
|
||
"""异步获取模型按次计费价格"""
|
||
service = ModelCostService(db)
|
||
return await service.get_request_price_async(provider, model)
|
||
|
||
@classmethod
|
||
def get_request_price(cls, db: Session, provider: str, model: str) -> float | None:
|
||
"""获取模型按次计费价格"""
|
||
service = ModelCostService(db)
|
||
return service.get_request_price(provider, model)
|
||
|
||
@staticmethod
|
||
def calculate_cost(
|
||
input_tokens: int,
|
||
output_tokens: int,
|
||
input_price_per_1m: float,
|
||
output_price_per_1m: float,
|
||
cache_creation_input_tokens: int = 0,
|
||
cache_read_input_tokens: int = 0,
|
||
cache_creation_price_per_1m: float | None = None,
|
||
cache_read_price_per_1m: float | None = None,
|
||
price_per_request: float | None = None,
|
||
) -> tuple[float, float, float, float, float, float, float]:
|
||
"""计算成本(价格是每百万tokens)- 固定价格模式
|
||
|
||
Returns:
|
||
Tuple of (input_cost, output_cost, cache_creation_cost,
|
||
cache_read_cost, cache_cost, request_cost, total_cost)
|
||
"""
|
||
return ModelCostService.compute_cost(
|
||
input_tokens=input_tokens,
|
||
output_tokens=output_tokens,
|
||
input_price_per_1m=input_price_per_1m,
|
||
output_price_per_1m=output_price_per_1m,
|
||
cache_creation_input_tokens=cache_creation_input_tokens,
|
||
cache_read_input_tokens=cache_read_input_tokens,
|
||
cache_creation_price_per_1m=cache_creation_price_per_1m,
|
||
cache_read_price_per_1m=cache_read_price_per_1m,
|
||
price_per_request=price_per_request,
|
||
)
|
||
|
||
@classmethod
|
||
async def calculate_cost_with_strategy_async(
|
||
cls,
|
||
db: Session,
|
||
provider: str,
|
||
model: str,
|
||
input_tokens: int,
|
||
output_tokens: int,
|
||
cache_creation_input_tokens: int = 0,
|
||
cache_read_input_tokens: int = 0,
|
||
api_format: str | None = None,
|
||
cache_ttl_minutes: int | None = None,
|
||
) -> tuple[float, float, float, float, float, float, float, int | None]:
|
||
"""使用策略模式计算成本(支持阶梯计费)
|
||
|
||
根据 api_format 选择对应的计费策略,支持阶梯计费和 TTL 差异化。
|
||
|
||
Returns:
|
||
Tuple of (input_cost, output_cost, cache_creation_cost,
|
||
cache_read_cost, cache_cost, request_cost, total_cost, tier_index)
|
||
"""
|
||
service = ModelCostService(db)
|
||
return await service.compute_cost_with_strategy_async(
|
||
provider=provider,
|
||
model=model,
|
||
input_tokens=input_tokens,
|
||
output_tokens=output_tokens,
|
||
cache_creation_input_tokens=cache_creation_input_tokens,
|
||
cache_read_input_tokens=cache_read_input_tokens,
|
||
api_format=api_format,
|
||
cache_ttl_minutes=cache_ttl_minutes,
|
||
)
|
||
|
||
@classmethod
|
||
async def _get_rate_multiplier_and_free_tier(
|
||
cls,
|
||
db: Session,
|
||
provider_api_key_id: str | None,
|
||
provider_id: str | None,
|
||
api_format: str | None = None,
|
||
) -> tuple[float, bool]:
|
||
"""获取费率倍数和是否免费套餐(使用缓存)"""
|
||
from src.services.cache.provider_cache import ProviderCacheService
|
||
|
||
return await ProviderCacheService.get_rate_multiplier_and_free_tier(
|
||
db, provider_api_key_id, provider_id, api_format
|
||
)
|
||
|
||
@staticmethod
|
||
def _get_rate_multiplier_sync(
|
||
db: Session,
|
||
provider_api_key_id: str,
|
||
api_format: str | None = None,
|
||
) -> float | None:
|
||
"""
|
||
同步获取 ProviderAPIKey 的 rate_multiplier
|
||
|
||
Args:
|
||
db: 数据库会话
|
||
provider_api_key_id: ProviderAPIKey ID
|
||
api_format: API 格式(可选),如 "CLAUDE"、"OPENAI"
|
||
|
||
Returns:
|
||
rate_multiplier 或 None
|
||
"""
|
||
from src.services.cache.provider_cache import ProviderCacheService
|
||
|
||
provider_key = (
|
||
db.query(ProviderAPIKey.rate_multipliers)
|
||
.filter(ProviderAPIKey.id == provider_api_key_id)
|
||
.first()
|
||
)
|
||
|
||
if not provider_key:
|
||
return None
|
||
|
||
return ProviderCacheService.compute_rate_multiplier(
|
||
provider_key.rate_multipliers, api_format
|
||
)
|