feat: expose bare generation time and hedge flags in CallStats
CallStats gains hedges/generation_ms/hedge_won (all defaulted, appended after total_latency_ms); _CallContext counts them via record_generation (overwrite for chat/OCR, accumulate for embedding batches) and register_hedge, and snapshot carries them out. All three _attempt implementations time only the transport call itself on the same injected clock as total_latency_ms; the chat sink is recorded by the orchestrator so hedge winner attribution stays with T3. Hedge counters stay 0/False until the T3 orchestration lands. Red-green evidence: tests/outputs/137/t2/ (10 new tests AttributeError red, then green; full unit+contracts 1621 passed).
This commit is contained in:
@@ -319,6 +319,20 @@ class TestEmbedBatching:
|
||||
assert resp.cost is None
|
||||
|
||||
|
||||
class TestEmbedGenerationMs:
|
||||
"""裸生成时间按批累加(1.3.7 H8): generation_ms = 各批 transport 耗时之和。"""
|
||||
|
||||
async def test_generation_ms_sums_batch_transports(self):
|
||||
# 0.25s 为二进制可精确表示值: int 截断下非精确值会因浮点误差少 1ms
|
||||
clock = FakeClock()
|
||||
transport = _ClockAdvancingEmbedTransport([(0.25, "ok"), (0.25, "ok")], clock)
|
||||
client, _ = _embed_client([_src()], [], transport=transport, now=clock)
|
||||
resp = await client.embed(["a", "bb", "ccc", "dddd"])
|
||||
assert resp.call_stats is not None
|
||||
assert resp.call_stats.attempts == 2
|
||||
assert resp.call_stats.generation_ms == 500
|
||||
|
||||
|
||||
class TestEmbedPostProcess:
|
||||
async def test_normalize_l2(self):
|
||||
raw = EmbeddingTransportResult(
|
||||
|
||||
Reference in New Issue
Block a user