Spaces:
Running on Zero
Running on Zero
| from __future__ import annotations | |
| import time | |
| import uuid | |
| from collections.abc import Iterator | |
| from contextlib import contextmanager | |
| from contextvars import ContextVar, Token | |
| from dataclasses import dataclass, field | |
| from typing import Any | |
| PRICE_PER_MTOK: dict[str, tuple[float, float]] = { | |
| "llama-3.3-70b-versatile": (0.59, 0.79), | |
| "llama-3.1-8b-instant": (0.05, 0.08), | |
| "gemini-2.5-flash-lite": (0.10, 0.40), | |
| "gemini-2.5-flash": (0.30, 2.50), | |
| "echo-1": (0.0, 0.0), | |
| } | |
| _DEFAULT_PRICE = (0.0, 0.0) | |
| class Span: | |
| name: str | |
| start_ms: float | |
| end_ms: float | None = None | |
| depth: int = 0 | |
| attributes: dict[str, Any] = field(default_factory=dict) | |
| error: str | None = None | |
| def duration_ms(self) -> float: | |
| return (self.end_ms if self.end_ms is not None else _now_ms()) - self.start_ms | |
| def to_dict(self) -> dict[str, Any]: | |
| return { | |
| "name": self.name, | |
| "duration_ms": round(self.duration_ms, 2), | |
| "depth": self.depth, | |
| "attributes": self.attributes, | |
| "error": self.error, | |
| } | |
| class TokenUsage: | |
| prompt_tokens: int = 0 | |
| completion_tokens: int = 0 | |
| calls: int = 0 | |
| def total_tokens(self) -> int: | |
| return self.prompt_tokens + self.completion_tokens | |
| def add(self, prompt: int, completion: int) -> None: | |
| self.prompt_tokens += prompt | |
| self.completion_tokens += completion | |
| self.calls += 1 | |
| def to_dict(self) -> dict[str, int]: | |
| return { | |
| "prompt_tokens": self.prompt_tokens, | |
| "completion_tokens": self.completion_tokens, | |
| "total_tokens": self.total_tokens, | |
| "llm_calls": self.calls, | |
| } | |
| class Trace: | |
| trace_id: str | |
| started_ms: float | |
| spans: list[Span] = field(default_factory=list) | |
| usage: TokenUsage = field(default_factory=TokenUsage) | |
| cost_usd: float = 0.0 | |
| metadata: dict[str, Any] = field(default_factory=dict) | |
| ended_ms: float | None = None | |
| def duration_ms(self) -> float: | |
| return (self.ended_ms if self.ended_ms is not None else _now_ms()) - self.started_ms | |
| def record_usage(self, model: str, prompt_tokens: int, completion_tokens: int) -> None: | |
| self.usage.add(prompt_tokens, completion_tokens) | |
| in_price, out_price = PRICE_PER_MTOK.get(model, _DEFAULT_PRICE) | |
| self.cost_usd += (prompt_tokens * in_price + completion_tokens * out_price) / 1_000_000 | |
| def stage_timings(self) -> dict[str, float]: | |
| out: dict[str, float] = {} | |
| for span in self.spans: | |
| if span.depth == 0: | |
| out[span.name] = round(out.get(span.name, 0.0) + span.duration_ms, 2) | |
| return out | |
| def to_dict(self) -> dict[str, Any]: | |
| return { | |
| "trace_id": self.trace_id, | |
| "duration_ms": round(self.duration_ms, 2), | |
| "spans": [s.to_dict() for s in self.spans], | |
| "stage_timings_ms": self.stage_timings(), | |
| "usage": self.usage.to_dict(), | |
| "estimated_cost_usd": round(self.cost_usd, 8), | |
| "metadata": self.metadata, | |
| } | |
| _current_trace: ContextVar[Trace | None] = ContextVar("secrag_current_trace", default=None) | |
| _current_depth: ContextVar[int] = ContextVar("secrag_current_depth", default=0) | |
| def _now_ms() -> float: | |
| return time.perf_counter() * 1000.0 | |
| def current_trace() -> Trace | None: | |
| return _current_trace.get() | |
| def current_trace_id() -> str | None: | |
| trace = _current_trace.get() | |
| return trace.trace_id if trace else None | |
| def start_trace(trace_id: str | None = None, **metadata: Any) -> Iterator[Trace]: | |
| trace = Trace( | |
| trace_id=trace_id or uuid.uuid4().hex[:16], | |
| started_ms=_now_ms(), | |
| metadata=dict(metadata), | |
| ) | |
| token: Token[Trace | None] = _current_trace.set(trace) | |
| depth_token: Token[int] = _current_depth.set(0) | |
| try: | |
| yield trace | |
| finally: | |
| trace.ended_ms = _now_ms() | |
| _current_trace.reset(token) | |
| _current_depth.reset(depth_token) | |
| def span(name: str, **attributes: Any) -> Iterator[Span]: | |
| trace = _current_trace.get() | |
| depth = _current_depth.get() | |
| current = Span(name=name, start_ms=_now_ms(), depth=depth, attributes=dict(attributes)) | |
| depth_token: Token[int] = _current_depth.set(depth + 1) | |
| if trace is not None: | |
| trace.spans.append(current) | |
| try: | |
| yield current | |
| except Exception as exc: | |
| current.error = f"{type(exc).__name__}: {exc}" | |
| raise | |
| finally: | |
| current.end_ms = _now_ms() | |
| _current_depth.reset(depth_token) | |
| def record_usage(model: str, prompt_tokens: int, completion_tokens: int) -> None: | |
| if (trace := _current_trace.get()) is not None: | |
| trace.record_usage(model, prompt_tokens, completion_tokens) | |
| def estimate_tokens(text: str) -> int: | |
| return max(1, len(text) // 4) | |