feat: carry caller dimensions down the embedding chain
EmbeddingClient does not go through the chat onion: it builds its own ChatRequest inside _emit purely to reuse the shared TelemetryEmitter, so wiring chat() alone left every embed row without a tenant. Validate the dimensions at the embed() entry (before batching, since anything failing further down is degraded to a warning) and thread them through _embed_batch -> _attempt -> _emit so every batch row carries the same pair.
This commit is contained in:
@@ -412,6 +412,45 @@ class TestEmbedTelemetry:
|
||||
assert len(rec.rows[1]["messages"]) < 1000 # 长文本截断后入库
|
||||
|
||||
|
||||
class TestEmbedCallerDimensions:
|
||||
"""issue #11: 调用方自定义维度必须沿 embed 链四层透传到每一行遥测。"""
|
||||
|
||||
async def test_single_batch_row_carries_dimensions(self):
|
||||
rec = _MemoryRecorder()
|
||||
client, _ = _embed_client([_src()], ["ok"], batch_size=2, telemetry=rec)
|
||||
await client.embed(["a"], tenant_id="t1", meta={"batch": "b-42"})
|
||||
assert rec.rows[0]["tenant_id"] == "t1"
|
||||
assert rec.rows[0]["meta"] == '{"batch": "b-42"}'
|
||||
|
||||
async def test_every_batch_row_carries_the_same_dimensions(self):
|
||||
"""维度属于本次 `embed()` 调用,不随批次变化。
|
||||
|
||||
只断言首行会漏掉"只有第一批带维度"的实现——那正是逐层透传最容易漏的形态。
|
||||
"""
|
||||
rec = _MemoryRecorder()
|
||||
client, _ = _embed_client([_src()], ["ok", "ok", "ok"], batch_size=1, telemetry=rec)
|
||||
await client.embed(["a", "b", "c"], tenant_id="t1", meta={"batch": "b-42"})
|
||||
assert len(rec.rows) == 3 # 切成三批,每批一行
|
||||
assert [r["tenant_id"] for r in rec.rows] == ["t1", "t1", "t1"]
|
||||
assert [r["meta"] for r in rec.rows] == ['{"batch": "b-42"}'] * 3
|
||||
|
||||
async def test_invalid_meta_rejected_before_any_telemetry(self):
|
||||
"""校验在切批之前: 遥测层的失败都被降级成 warning,放下游等于没有校验。"""
|
||||
rec = _MemoryRecorder()
|
||||
client, _ = _embed_client([_src()], ["ok"], batch_size=2, telemetry=rec)
|
||||
with pytest.raises(ValueError, match="meta"):
|
||||
await client.embed(["a"], meta={"Bad Key": 1})
|
||||
assert rec.rows == []
|
||||
assert client._transport.calls == [] # 连调用都没发出
|
||||
|
||||
async def test_defaults_land_as_sentinels(self):
|
||||
rec = _MemoryRecorder()
|
||||
client, _ = _embed_client([_src()], ["ok"], batch_size=2, telemetry=rec)
|
||||
await client.embed(["a"])
|
||||
assert rec.rows[0]["tenant_id"] == "" # 空串哨兵,不是 None
|
||||
assert rec.rows[0]["meta"] == "{}"
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _captured_warnings():
|
||||
"""捕获库发出的 WARNING;loguru 不经标准 logging,pytest 的 caplog 抓不到。"""
|
||||
|
||||
Reference in New Issue
Block a user