- gateway/proxy/ 十文件:config(ProxyConfig:元->毫元加载期换算 D-P1、差异化售价、 桶/峰谷/限流/semcache 配置)/ errors(8 类 HTTP 语义异常)/ ledger(四表两索引 DDL, WAL,ReviewQueue 连接纪律)/ auth·pricing·normalizer·semcache·upstream(§6 签名占位) / routes(/proxy/v1/models OpenAI 形状)/ __init__(build_proxy_router 组装点) - settings DEFAULTS 增 proxy 段(enabled 默认 False,D-P7) - api.py 首次 include_router(enabled 门控 + 装配失败不拖垮主应用) - serve.py workers>1 拒绝启动(D-P9:WEB_CONCURRENCY/UVICORN_WORKERS 校验) - 测试 +4(门控 404/DDL 幂等/毫元换算/池模型列表),全量 322 passed
29 lines
1.1 KiB
Python
29 lines
1.1 KiB
Python
"""代理面路由(T-P0 骨架:/proxy/v1/models;主对话路由 T-P4 落地)。"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Request
|
|
|
|
from gateway.proxy.config import ProxyConfig
|
|
|
|
|
|
def build_proxy_router(cfg: ProxyConfig, pool) -> APIRouter:
|
|
"""组装代理面路由(唯一组装点;pool 为 gateway.model_pool.PoolStore)。"""
|
|
router = APIRouter(prefix="/proxy")
|
|
|
|
@router.get("/v1/models", tags=["proxy"])
|
|
async def list_models():
|
|
"""学生面:池内允许代理的模型列表(OpenAI /models 形状)。"""
|
|
entries = pool.list().get("entries", [])
|
|
names = [e["model"] for e in entries
|
|
if e.get("enabled") and e.get("backend") not in ("mock",)]
|
|
# 去重保序
|
|
seen, data = set(), []
|
|
for n in names:
|
|
if n not in seen:
|
|
seen.add(n)
|
|
data.append({"id": n, "object": "model", "owned_by": "campus-proxy"})
|
|
return {"object": "list", "data": data}
|
|
|
|
# /v1/chat/completions 与 /admin/* 在 T-P1/T-P4 追加
|
|
return router
|