[stack 4/8] feat(trace): opt-in trace store linked to usage.jsonl - #307
OnlineChef (ChefGroep) wants to merge 4 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Review note (non-blocking): in |
Stacked re-landing of #298 (
feat/trace-store). Position 4/8; base:stack/20261005-03-gui-redesign. Merge bottom-up; each layer is a real merge of the original PR head, so the diff shows only that PR plus any conflict resolution (noted in the merge commit message).Stack
Original description:
What
usage.jsonlstays the compact telemetry SOT. Full prompts/responses go to a separate local store,trace.sqlite, linked bytraceId(= requestId). Off by default.Modes (
OCX_TRACE)off(default): nothing read or stored.metadata: no bodies stored; each usage row gets a payload-freetraceobject: byte sizes, message/tool-call/tool-def/attachment counts, request/outbound/response hashes, plussystemHash,toolsHash,prefixHashof the final provider wire body.redacted: also stores inbound request, final provider body and response (gzip BLOBs), secrets stripped with the existinglib/redact.full: verbatim bodies, explicit opt-in.Knobs:
OCX_TRACE_TTL_HOURS(24),OCX_TRACE_MAX_BODY_BYTES(512 KiB),OCX_TRACE_MAX_DB_MB(256, oldest evicted first),OCX_TRACE_SAMPLE(1.0).Why the section hashes
For cache-hit debugging: two consecutive turns with equal
prefixHashbut a movedsystemHashortoolsHashtells you which section broke the provider prompt-cache prefix, without storing any content.Wiring
src/trace/{types,settings,store,capture}.ts(new). Store isbun:sqlite, WAL, TTL + size-cap pruning, every entry point swallows its own failures./v1/responses,/v1/messages,/v1/chat/completions:beginTrace(reads a clone of the inbound body) +runWithTrace(AsyncLocalStorage).fetchWithHeaderTimeoutrecords the final wire body vianoteOutboundRequestBody(last body wins on retries;outboundCountrecords how many were sent).inspectResponseLogJson/inspectResponseLogSsePayloadfeed the bounded response copy.addFinalRequestLogfinalizes the trace and stampstraceId+traceon the usage row;normalizeUsageEntrywhitelists/validates them.reference/cli.md.Verified locally
bun test: newtests/trace.test.ts(16) plus usage-log, request-log, usage-failure-persistence, usage-surfaces, usage-log-metrics, debug-settings, response-cache-e2e, api-usage, adapter-usage, chat-completions-endpoint, claude-messages-endpoint, openai-responses-passthrough, client-server-route-gate: all green.bun run privacy:scan: passed.bun run typecheckand the full suite (the 1 GB sandbox OOMs on tsc). Relying on CI for those; please treat red CI as authoritative.Known limits (follow-ups)
fetchWithHeaderTimeout; adapters with their own fetch showoutboundBytesabsent./v1/responses/compact, WebSocket and live/realtime routes are not wired.redactedis pattern-based: free-text secrets in prompts that match no known pattern are not detectable.readTrace/listTracesorsqlite3ontrace.sqlite.logCacheHitRequest) are not traced.Summary by CodeRabbit