"""Nanomon - Track LLM usage across DSPy program runs.

Example usage:
    import dspy
    from nanomon import NanomonRunContext

    context = NanomonRunContext(default_tags=["production"])

    lm = dspy.LM(model="gpt-4o-mini")
    dspy.settings.configure(lm=context.instrument_lm(lm))

    program = ...  # DSPy module

    with context.run(tags=["exp-12"], metadata={"dataset": "qa-set-1"}):
        program("Explain X")
"""

from nanomon.callback import NanomonCallback
from nanomon.context import NanomonRunContext
from nanomon.decorators import configure_nanomon, create_nanomon_tracker, nanomon
from nanomon.errors import (
    NanomonError,
    ExtractorError,
    RunPayloadValidationError,
    SinkWriteError,
)
from nanomon.instrumentation import ActiveContext, InstrumentedLM
from nanomon.sinks import ApiSink, MultiSink, Sink, SqliteSink
from nanomon.types import ModelStats, RunState, RunStatus
from nanomon.usage_extractors import (
    DefaultUsageExtractor,
    ExtractorChain,
    UsageExtractor,
)
from nanomon.utils import Clock, SystemClock

__version__ = "0.2.2"

__all__ = [
    # Main class
    "NanomonRunContext",
    # Decorators
    "configure_nanomon",
    "create_nanomon_tracker",
    "nanomon",
    # Instrumentation
    "ActiveContext",
    "InstrumentedLM",
    "NanomonCallback",
    # Sinks (for advanced users)
    "Sink",
    "ApiSink",
    "SqliteSink",
    "MultiSink",
    # Types
    "RunState",
    "RunStatus",
    "ModelStats",
    # Extractors
    "UsageExtractor",
    "DefaultUsageExtractor",
    "ExtractorChain",
    # Utils
    "Clock",
    "SystemClock",
    # Errors
    "NanomonError",
    "SinkWriteError",
    "RunPayloadValidationError",
    "ExtractorError",
]
