feat: track logical call statistics across governed calls

This commit is contained in:
2026-09-09 10:04:39 -04:00
parent 300ced5dbd
commit 87c261bf73
13 changed files with 650 additions and 10 deletions
+31
View File
@@ -615,3 +615,34 @@ class TestReasonlessTelemetryContract:
await getattr(client, method)(b"image")
assert len(recorder.rows) == len(script)
assert all(r["error"] and r["reasoning_effort"] is None for r in recorder.rows)
class TestOcrLogicalCallStats:
"""OCR 两个公开方法各自拥有一次逻辑调用(1.3.5 设计 §3/§3.5)。"""
async def test_text_success_counts_one_attempt(self):
client, _, _ = _client([_src()], ["text"])
r = await client.recognize_text(b"jpg")
assert r.call_stats is not None and r.call_stats.attempts == 1
async def test_layout_two_http_calls_count_as_one_attempt(self):
"""POST + ZIP GET 在同一次 transport 调用内,计 **1** 次尝试而非 2。
`attempts` 的语义是"调用 transport 端口的次数",不是 HTTP 请求条数。
"""
client, _, _ = _client([_src()], ["layout"])
r = await client.parse_layout(b"jpg")
assert r.call_stats is not None and r.call_stats.attempts == 1
async def test_retry_counts_every_attempt(self):
client, _, _ = _client([_src(), _src(name="m2")], [TransientError("t1"), "text"])
r = await client.recognize_text(b"jpg")
assert r.call_stats.attempts == 2
async def test_input_validation_stays_outside_the_stats_boundary(self):
"""`image` 类型/空校验先于上下文创建(M1 例外),保持原异常行为。"""
client, _, _ = _client([_src()], [])
with pytest.raises(TypeError):
await client.recognize_text("not-bytes")
with pytest.raises(ValueError):
await client.recognize_text(b"")