feat: wire the telemetry text cap through settings
`PGW_TELEMETRY_TEXT_CAP` now reaches the emitter on every assembly path. Unset means no truncation, which stays the default: a truncated row is no longer audit evidence and cannot be replayed, and downstreams rely on that today. The flip side — contracts and bids sitting in `llm_calls` indefinitely, multi-tenant — is spelled out in `.env.example` so readers can weigh both. All three `from_settings` paths are wired (chat, embedding, OCR): they write the same table, so capping only chat would leave half of it uncontrolled. `TelemetryEmitter.__init__` now rejects `text_cap <= 0`; it is the single point where the three clients converge, so the direct construction path — a public assembly route the settings guard never sees — is covered too. `0` would otherwise reduce every body to a bare elision marker.
This commit is contained in:
@@ -1602,6 +1602,16 @@ class TestTelemetryTextCap:
|
||||
assert messages[1]["content"][0]["text"] == _LONG
|
||||
assert json.loads(row["messages"])[0]["content"] == _CAPPED # 落库那份确已截断
|
||||
|
||||
def test_non_positive_cap_rejected_at_construction(self):
|
||||
"""emitter 是三个 Client 唯一的汇合点,值域校验放这一处即覆盖全部装配路。
|
||||
|
||||
settings 层那道只管 env;直接构造 `GatewayClient(..., text_cap=0)` 是库
|
||||
承诺的另一条公共装配路,没有这道闸就会把每条正文写成一个光秃秃的省略标记。
|
||||
"""
|
||||
for bad in (0, -1):
|
||||
with pytest.raises(ValueError, match="text_cap"):
|
||||
TelemetryEmitter(_MemoryRecorder(), text_cap=bad)
|
||||
|
||||
|
||||
class _StubEmbedTransport:
|
||||
async def embed(self, *, texts, source, call_id):
|
||||
|
||||
Reference in New Issue
Block a user