"""The LangSmith tracer the playground's agents share.

The extraction agents are classes and each holds its own `LangSmithTracer`.
The playground's agents are module-level functions with no instance to hold
one, so this module owns the single tracer they all open runs on. Most call
sites wrap one pydantic-ai `Agent.run` or `Agent.run_stream` the way the
extraction agents do: open the run with the prompt as messages, set the
assistant message and usage on exit. The ranker in `ranking.py` opens one run
per pass around many TypeSafe calls and records their combined outputs.

Document identity is not an argument the answer functions take, so the route
that knows it sets `document_key` for the request and each run copies it into
its metadata. Same no-op contract as the extraction tracer: with
`TRACE_TO_LANGSMITH` unset nothing here reaches the network.
"""

from __future__ import annotations

from contextvars import ContextVar
from typing import Any, Dict, Optional

from quber.agents.langsmith_tracer import LangSmithTracer

# The document the request in flight is asking about. Set by the route, read
# by the runs; a contextvar so concurrent requests never see each other's.
document_key: ContextVar[Optional[str]] = ContextVar("document_key", default=None)

_tracer: Optional[LangSmithTracer] = None


def tracer() -> LangSmithTracer:
    """The process-wide tracer, built on first use so settings are final."""
    global _tracer
    if _tracer is None:
        _tracer = LangSmithTracer(run_name="quber-playground")
    return _tracer


def run_metadata() -> Dict[str, Any]:
    """The document key of the request in flight, or nothing."""
    doc = document_key.get()
    return {"doc_key": doc} if doc else {}
