- assertion_anchored_graph_retriever 断言锚定候选与 top30 合并 - pipeline/agentic_controller/llm_client 重试与 Q0 软回退 - question_decomposition JSON repair、citation_contract grouped 归一化 - api endpoint_path 全参数、retrieval 禁用 PC/SQLite、canonical-only 校验 - bounded_canonical/direct_flow 白名单、subquestion_orchestrator required_review - scripts/qa_v1_1_73_server.py 新服务入口(backend_guard + gate_policy) - 旧 start_qa_v1_1_73_*.sh 移入 docs/legacy_startup_scripts/
53 lines
1.3 KiB
Python
53 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from src.rag.qa_v1_1_73 import llm_client as module
|
|
|
|
|
|
class _Response:
|
|
def __init__(self, status_code: int) -> None:
|
|
self.status_code = status_code
|
|
|
|
def json(self):
|
|
return {"error": {"message": "upstream failure"}}
|
|
|
|
|
|
def _client(monkeypatch) -> module.LLMClient:
|
|
monkeypatch.setenv("QA_V1_LLM_API_KEY", "test-only")
|
|
monkeypatch.setenv("QA_V1_LLM_MAX_ATTEMPTS", "4")
|
|
monkeypatch.setenv("QA_V1_LLM_RETRY_BASE_SECONDS", "0")
|
|
return module.LLMClient()
|
|
|
|
|
|
def test_http_402_fails_without_retry(monkeypatch):
|
|
client = _client(monkeypatch)
|
|
calls = []
|
|
|
|
def post(*args, **kwargs):
|
|
calls.append((args, kwargs))
|
|
return _Response(402)
|
|
|
|
monkeypatch.setattr(module.requests, "post", post)
|
|
|
|
with pytest.raises(module.LLMNonRetryableError, match="HTTP 402"):
|
|
client.complete("system", "user")
|
|
|
|
assert len(calls) == 1
|
|
|
|
|
|
def test_http_503_keeps_bounded_retry(monkeypatch):
|
|
client = _client(monkeypatch)
|
|
calls = []
|
|
|
|
def post(*args, **kwargs):
|
|
calls.append((args, kwargs))
|
|
return _Response(503)
|
|
|
|
monkeypatch.setattr(module.requests, "post", post)
|
|
|
|
with pytest.raises(module.LLMResponseError, match="after 4 attempts"):
|
|
client.complete("system", "user")
|
|
|
|
assert len(calls) == 4
|