Files changed (3) hide show
  1. app/billing.py +1 -0
  2. app/main.py +16 -2
  3. app/models.py +1 -0
app/billing.py CHANGED
@@ -277,6 +277,7 @@ async def recent_logs(db: AsyncSession, limit: int = 100, offset: int = 0) -> li
277
  "prompt_tokens": r.prompt_tokens,
278
  "completion_tokens": r.completion_tokens,
279
  "total_tokens": r.total_tokens,
 
280
  "cost_usd": r.cost_usd,
281
  "status": r.status,
282
  "http_status": r.http_status,
 
277
  "prompt_tokens": r.prompt_tokens,
278
  "completion_tokens": r.completion_tokens,
279
  "total_tokens": r.total_tokens,
280
+ "cached_tokens": r.cached_tokens,
281
  "cost_usd": r.cost_usd,
282
  "status": r.status,
283
  "http_status": r.http_status,
app/main.py CHANGED
@@ -32,6 +32,9 @@ settings = get_settings()
32
  # 后台可编辑并热加载到运行时的参数
33
  EDITABLE_KEYS = admin.EDITABLE_KEYS
34
 
 
 
 
35
 
36
  async def _init_db() -> None:
37
  """建表(首次部署自动创建)。连接失败时打印脱敏诊断,便于定位 DATABASE_URL 问题。"""
@@ -60,20 +63,31 @@ async def _seed_admin() -> None:
60
 
61
 
62
  async def _migrate_pricing() -> None:
63
- """为已有数据库添加 cache_read_per_m 列,并回填种子缓存价。"""
64
  async with engine.begin() as conn:
65
  try:
66
  await conn.execute(text(
67
  "ALTER TABLE model_pricing ADD COLUMN IF NOT EXISTS cache_read_per_m FLOAT DEFAULT 0.0"
68
  ))
 
 
 
69
  except Exception:
70
  pass # 列已存在或非 PostgreSQL,忽略
71
- # 回填:已有行 cache_read_per_m 仍为 0 且种子数据有非零值的,更新为种子价
72
  async with SessionLocal() as db:
 
 
 
 
 
73
  for model, ip, op, cp in B.DEFAULT_PRICING:
74
  row = (await db.execute(select(ModelPricing).where(ModelPricing.model == model))).scalar_one_or_none()
75
  if row and row.cache_read_per_m == 0.0 and cp > 0.0:
76
  row.cache_read_per_m = cp
 
 
 
77
  await db.commit()
78
 
79
 
 
32
  # 后台可编辑并热加载到运行时的参数
33
  EDITABLE_KEYS = admin.EDITABLE_KEYS
34
 
35
+ # 旧版种子数据中已失效的模型名(Parasail 已下架),迁移时删除
36
+ _LEGACY_MODELS = {"parasail-deepseek-r1", "parasail-kimi-k25-elicit", "parasail-ai/GritLM-7B-vllm", "meta-llama/Llama-3.1-8B-Instruct"}
37
+
38
 
39
  async def _init_db() -> None:
40
  """建表(首次部署自动创建)。连接失败时打印脱敏诊断,便于定位 DATABASE_URL 问题。"""
 
63
 
64
 
65
  async def _migrate_pricing() -> None:
66
+ """迁移:加列、删旧种子、回填缓存价,并补入新种子模型。"""
67
  async with engine.begin() as conn:
68
  try:
69
  await conn.execute(text(
70
  "ALTER TABLE model_pricing ADD COLUMN IF NOT EXISTS cache_read_per_m FLOAT DEFAULT 0.0"
71
  ))
72
+ await conn.execute(text(
73
+ "ALTER TABLE request_logs ADD COLUMN IF NOT EXISTS cached_tokens INTEGER DEFAULT 0"
74
+ ))
75
  except Exception:
76
  pass # 列已存在或非 PostgreSQL,忽略
77
+
78
  async with SessionLocal() as db:
79
+ # 删除旧版已失效的种子模型
80
+ for m in _LEGACY_MODELS:
81
+ await db.execute(delete(ModelPricing).where(ModelPricing.model == m))
82
+
83
+ # 回填:已有行 cache_read_per_m 仍为 0 且种子数据有非零值的,更新为种子价
84
  for model, ip, op, cp in B.DEFAULT_PRICING:
85
  row = (await db.execute(select(ModelPricing).where(ModelPricing.model == model))).scalar_one_or_none()
86
  if row and row.cache_read_per_m == 0.0 and cp > 0.0:
87
  row.cache_read_per_m = cp
88
+ elif not row:
89
+ # 种子数据中不存在的新模型,直接插入
90
+ db.add(ModelPricing(model=model, input_per_m=ip, output_per_m=op, cache_read_per_m=cp))
91
  await db.commit()
92
 
93
 
app/models.py CHANGED
@@ -73,6 +73,7 @@ class RequestLog(Base):
73
  prompt_tokens: Mapped[int] = mapped_column(Integer, default=0)
74
  completion_tokens: Mapped[int] = mapped_column(Integer, default=0)
75
  total_tokens: Mapped[int] = mapped_column(Integer, default=0)
 
76
  cost_usd: Mapped[float] = mapped_column(Float, default=0.0)
77
  # success / failed / error
78
  status: Mapped[str] = mapped_column(String(16), index=True, default="success")
 
73
  prompt_tokens: Mapped[int] = mapped_column(Integer, default=0)
74
  completion_tokens: Mapped[int] = mapped_column(Integer, default=0)
75
  total_tokens: Mapped[int] = mapped_column(Integer, default=0)
76
+ cached_tokens: Mapped[int] = mapped_column(Integer, default=0)
77
  cost_usd: Mapped[float] = mapped_column(Float, default=0.0)
78
  # success / failed / error
79
  status: Mapped[str] = mapped_column(String(16), index=True, default="success")