shinkan-jinkendo/backend/planning_llm_usage.py
Lars 9cee862c32
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Test Suite / pytest-backend (push) Successful in 49s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 15s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m26s
Implement Planning Prompt Enhancements and LLM Usage Tracking
- Added new fields for goal query, user notes, max steps, and search query in the AiPromptPreviewBody to support planning prompts.
- Integrated planning prompt handling in the preview_ai_prompt function, allowing for distinct processing of planning and exercise prompts.
- Introduced LLM usage tracking in openrouter_chat_completion and planning_exercise_suggest functions to monitor AI call metrics.
- Updated frontend components to accommodate new input fields for planning prompts, enhancing user experience and functionality.
2026-06-15 07:50:49 +02:00

63 lines
1.7 KiB
Python

"""
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",
]