feat: track logical call statistics across governed calls
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user