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
+15 -2
View File
@@ -16,6 +16,7 @@
from __future__ import annotations
import asyncio
import dataclasses
import math
import random
import time
@@ -47,6 +48,7 @@ from polygateway.types import (
EmbeddingResponse,
LLMResponse,
TelemetryStatus,
_CallContext,
strip_unsupported_extra_body,
validate_caller_dimensions,
)
@@ -184,7 +186,11 @@ class EmbeddingClient:
dimension_tenant_id, dimensions = validate_caller_dimensions(
tenant_id, meta, origin="embed(tenant_id=..., meta=...)"
)
# 校验均已通过 → 进入统计边界(设计 §3.5: `texts` 类型与调用方维度校验之后)
context = _CallContext(now=self._now)
if not texts:
# 合法零尝试: 返回真实统计(attempts=0),且**不写任何遥测行**
# ——与 cache_hit 不同,不要按"遥测必录"推断它有台账行(设计 §3 M2)
return EmbeddingResponse(
vectors=[],
dim=0,
@@ -195,6 +201,7 @@ class EmbeddingClient:
latency_ms=0,
call_id=str(uuid.uuid4()),
source_name="",
call_stats=context.snapshot(),
)
if not self._sources:
raise AllSourcesExhausted(scope=self._scope, reason="no_sources", retry_after_s=0.0)
@@ -207,9 +214,11 @@ class EmbeddingClient:
parent_call_id,
dimension_tenant_id,
dimensions,
context,
)
)
return self._merge(outcomes)
# 全批共享同一上下文,故分批是实现细节而非 N 次独立逻辑调用
return dataclasses.replace(self._merge(outcomes), call_stats=context.snapshot())
# —— 治理循环(与 RetryMW 同构;设计 §7.1 已声明的有限重复)——
@@ -220,6 +229,7 @@ class EmbeddingClient:
parent_call_id: str | None,
tenant_id: str | None,
meta: dict[str, Any],
context: _CallContext,
) -> _BatchOutcome:
fails = 0
reasons: dict[str, str] = {}
@@ -232,7 +242,7 @@ class EmbeddingClient:
continue
async with clock.attempting():
outcome = await self._attempt(
batch, *picked, reasons, session_id, parent_call_id, tenant_id, meta
batch, *picked, reasons, session_id, parent_call_id, tenant_id, meta, context
)
if isinstance(outcome, _BatchOutcome):
return outcome
@@ -258,10 +268,13 @@ class EmbeddingClient:
parent_call_id: str | None,
tenant_id: str | None,
meta: dict[str, Any],
context: _CallContext,
) -> _BatchOutcome | _FailedBatch:
call_id = str(uuid.uuid4())
started = self._now()
actual = 0
# 登记在 transport 调用**之前**(同 RetryMW): 失败与取消的尝试也真的发出去了
context.register_attempt()
try:
result = await self._transport.embed(texts=batch, source=source, call_id=call_id)
if self._expected_dim is not None and result.dim != self._expected_dim: