fix(llm): request_id 条件透传贯通网关日志(CR-H4,守 §9.3)
This commit is contained in:
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
import structlog
|
||||
from fakes import FakeAdapter, FakeLedger, fake_route
|
||||
from ww_llm_gateway.gateway import Gateway
|
||||
from ww_llm_gateway.routing import resolve_route
|
||||
@@ -60,6 +61,33 @@ async def test_stream_yields_deltas_and_records_once(req: LlmRequest) -> None:
|
||||
assert ledger.records[0].output_tokens == 50
|
||||
|
||||
|
||||
async def test_run_logs_request_id_from_request(scope: Scope) -> None:
|
||||
# CR-H4:调用方设了 request_id 时,网关 llm_call 日志必须带上它(贯通 §9.3 追踪)。
|
||||
ledger = FakeLedger()
|
||||
gw = Gateway({"deepseek": FakeAdapter()}, ledger, resolver=fake_route)
|
||||
req = LlmRequest(tier="writer", input="x", scope=scope, request_id="rid-xyz")
|
||||
|
||||
with structlog.testing.capture_logs() as logs:
|
||||
await gw.run(req)
|
||||
|
||||
call = next(entry for entry in logs if entry["event"] == "llm_call")
|
||||
assert call["request_id"] == "rid-xyz"
|
||||
|
||||
|
||||
async def test_run_omits_request_id_when_unset(scope: Scope) -> None:
|
||||
# 未设 request_id 时**不得**发出该键——否则 None 会覆盖 merge_contextvars 供的 id,
|
||||
# 反倒回退了 sync/SSE 路径的追踪(条件透传锁定)。
|
||||
ledger = FakeLedger()
|
||||
gw = Gateway({"deepseek": FakeAdapter()}, ledger, resolver=fake_route)
|
||||
req = LlmRequest(tier="writer", input="x", scope=scope)
|
||||
|
||||
with structlog.testing.capture_logs() as logs:
|
||||
await gw.run(req)
|
||||
|
||||
call = next(entry for entry in logs if entry["event"] == "llm_call")
|
||||
assert "request_id" not in call
|
||||
|
||||
|
||||
async def test_unknown_provider_raises_llm_unavailable(req: LlmRequest) -> None:
|
||||
gw = Gateway({}, FakeLedger(), resolver=fake_route)
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ def test_llm_request_has_no_thinking_field() -> None:
|
||||
"output_schema",
|
||||
"max_tokens",
|
||||
"scope",
|
||||
"request_id", # CR-H4:可选端到端追踪字段(additive/optional)。
|
||||
}
|
||||
# 同名但另一处 live 字段 `Capabilities.thinking`(适配器能力矩阵)不受影响。
|
||||
assert "thinking" in Capabilities.model_fields
|
||||
|
||||
Reference in New Issue
Block a user