mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
- list_all_candidates 返回 provider_batch_count,区分"无候选"与"无 Provider" 避免分页在有 Provider 但无候选时提前终止 - 将配额检查逻辑从 aware_scheduler.py 拆分到 quota_skipper.py - 提取 reorder_candidates 方法,支持跨页汇总后全局重排序 - CandidateResolver 分页循环改用 provider_batch_count 判断终止 - candidate extra_data 中新增 mapping_matched_model 字段 - 新增契约测试和分页行为测试
41 lines
1.5 KiB
Python
41 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import FastAPI
|
|
|
|
|
|
def _build_contract_app() -> FastAPI:
|
|
from src.api.public.claude import router as claude_router
|
|
from src.api.public.gemini import router as gemini_router
|
|
from src.api.public.openai import router as openai_router
|
|
|
|
app = FastAPI()
|
|
app.include_router(claude_router)
|
|
app.include_router(openai_router)
|
|
app.include_router(gemini_router)
|
|
return app
|
|
|
|
|
|
def test_public_api_routes_contract_paths_and_tags() -> None:
|
|
app = _build_contract_app()
|
|
schema = app.openapi()
|
|
|
|
paths = schema.get("paths") or {}
|
|
|
|
expected = [
|
|
("/v1/messages", "post", "Claude API"),
|
|
("/v1/messages/count_tokens", "post", "Claude API"),
|
|
("/v1/chat/completions", "post", "OpenAI API"),
|
|
("/v1/responses", "post", "OpenAI API"),
|
|
("/v1beta/models/{model}:generateContent", "post", "Gemini API"),
|
|
("/v1beta/models/{model}:streamGenerateContent", "post", "Gemini API"),
|
|
("/v1/models/{model}:generateContent", "post", "Gemini API"),
|
|
("/v1/models/{model}:streamGenerateContent", "post", "Gemini API"),
|
|
]
|
|
|
|
for path, method, expected_tag in expected:
|
|
assert path in paths, f"missing path {path}"
|
|
operations = paths.get(path) or {}
|
|
assert method in operations, f"missing {method.upper()} {path}"
|
|
tags = operations.get(method, {}).get("tags") or []
|
|
assert expected_tag in tags, f"{method.upper()} {path} missing tag {expected_tag}"
|