qfa.services.call_context#

Request-scoped ContextVar carrying the active call’s correlation context.

A single ContextVar[CallContext | None] propagates tenant_id, operation, and call_id from the driving adapter (the FastAPI dependency call_scope_for() in production) down to the driven adapter (TrackingLLMAdapter), which reads it when stamping each persisted LLMCallRecord. The orchestrator in between never touches it.

Entry is via call_scope(), which takes the correlation UUID as a required argument — in HTTP requests, that’s the same UUID RequestIdMiddleware placed in X-Request-ID, so header, logs, and llm_calls.call_id rows always join cleanly. Non-HTTP callers (CLI, jobs, tests) pass request_id=uuid4() themselves.

asyncio propagates ContextVars across create_task / gather via snapshot-on-spawn, so fan-out from a public orchestrator method preserves the context without explicit forwarding.

Functions

call_scope(tenant_id, operation, request_id)

Set current_call_context for the duration of the block.

qfa.services.call_context.call_scope(tenant_id: str, operation: Operation, request_id: UUID) AsyncIterator[CallContext][source]#

Set current_call_context for the duration of the block.

Parameters:
  • tenant_id (str) – Tenant making the call.

  • operation (Operation) – Public orchestrator operation issuing the call.

  • request_id (UUID) – Correlation UUID for the API invocation. Becomes the call_id field of the resulting CallContext and is stamped onto every LLMCallRecord persisted inside the scope. In HTTP requests this is the same UUID set in the X-Request-ID header by RequestIdMiddleware; non-HTTP callers pass a freshly-generated uuid4().

Yields:

CallContext – The context that was set.