mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-11 11:54:59 +03:00
Лимиты агента раньше хранились вразнобой (dailyCostMicros/dailyBudgetRub/ dailyDialogs/maxMessagesPerDialog), из них бэкенд читал только dailyCostMicros. Из-за путаницы валют на агенте FoxRay стоял лимит dailyCostMicros:100 (= \$0.0001), который блокировал ответы ИИ — 2 сообщения зависли без ответа. - limits.py: ключ dailyCostUsd (целые центы USD), сравнение с расходом в micros. У агента FoxRay ключа нет → лимит больше не блокирует ответы. - services.py: _normalize_limits отбрасывает устаревшие ключи при сохранении. - ingest.py: LimitExceeded теперь ловится как ProviderError — диалог передаётся оператору с fallback вместо зависания (раньше исключение пробрасывалось до poller). - AgentEditForm: одно поле «Бюджет в день, \$» вместо четырёх разнородных. - release/model.ts: удалён мёртвый limitLabel; расходы уже везде в долларах. - tests: обновлены под dailyCostUsd, добавлен тест на LimitExceeded в ingest.
33 lines
1.3 KiB
Python
33 lines
1.3 KiB
Python
from django.conf import settings
|
|
from django.db.models import Sum
|
|
from django.utils import timezone
|
|
|
|
from hub_platform.ai.models import LlmInvocation, LlmInvocationStatus
|
|
|
|
|
|
class LimitExceeded(Exception):
|
|
pass
|
|
|
|
|
|
def _day_start():
|
|
now = timezone.localtime()
|
|
return now.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
|
|
|
|
def daily_cost_micros(channel=None) -> int:
|
|
queryset = LlmInvocation.objects.filter(created_at__gte=_day_start(), status=LlmInvocationStatus.SUCCESS)
|
|
if channel is not None:
|
|
queryset = queryset.filter(channel=channel)
|
|
return queryset.aggregate(total=Sum("cost_micros"))["total"] or 0
|
|
|
|
|
|
def assert_within_limits(channel, agent) -> None:
|
|
global_limit = settings.HUB_AI_GLOBAL_DAILY_COST_LIMIT_MICROS
|
|
if global_limit and daily_cost_micros() >= global_limit:
|
|
raise LimitExceeded("Global daily AI cost limit reached")
|
|
# Канальный лимит хранится в целых центах USD (dailyCostUsd); расход учитывается
|
|
# в micro-USD. 1 цент = 10 000 micro-USD.
|
|
channel_limit = (agent.limits or {}).get("dailyCostUsd")
|
|
if channel_limit and daily_cost_micros(channel) >= int(channel_limit) * 10_000:
|
|
raise LimitExceeded("Channel daily AI cost limit reached")
|