shinkan-jinkendo/backend/planning_llm_usage.py

63 lines
1.7 KiB
Python
Raw Permalink Normal View History

"""
Zähler für produktive OpenRouter-Aufrufe innerhalb einer Planungs-API-Anfrage.
Wird per ContextVar gesetzt (Router: ``planning_llm_call_meter``); ``openrouter_chat_completion``
erhöht den Zähler nach erfolgreicher Antwort — nur wenn ein Meter aktiv ist.
"""
from __future__ import annotations
from contextlib import contextmanager
from contextvars import ContextVar
from typing import Iterator, Optional
_llm_call_counter: ContextVar[Optional["PlanningLlmCallCounter"]] = ContextVar(
"planning_llm_call_counter",
default=None,
)
class PlanningLlmCallCounter:
"""Anzahl erfolgreicher OpenRouter-Chat-Completions in einem Request-Kontext."""
__slots__ = ("count",)
def __init__(self) -> None:
self.count = 0
def record(self, amount: int = 1) -> None:
try:
n = int(amount)
except (TypeError, ValueError):
n = 1
if n > 0:
self.count += n
def current_planning_llm_call_counter() -> Optional[PlanningLlmCallCounter]:
return _llm_call_counter.get()
def record_planning_llm_call(amount: int = 1) -> None:
counter = _llm_call_counter.get()
if counter is not None:
counter.record(amount)
@contextmanager
def planning_llm_call_meter() -> Iterator[PlanningLlmCallCounter]:
"""Aktiviert LLM-Zählung für den umschlossenen Block (inkl. verschachtelter Aufrufe)."""
counter = PlanningLlmCallCounter()
token = _llm_call_counter.set(counter)
try:
yield counter
finally:
_llm_call_counter.reset(token)
__all__ = [
"PlanningLlmCallCounter",
"current_planning_llm_call_counter",
"planning_llm_call_meter",
"record_planning_llm_call",
]