관리자 사용량 근거를 정교화

This commit is contained in:
Yun Chan 2026-08-29 23:59:17 +09:00
parent ccdcfcd2f5
commit 707dba4f8f
10 changed files with 1136 additions and 209 deletions

View file

@ -13,6 +13,7 @@ import shutil
import tempfile
import time
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, AsyncIterator, Iterable, Literal, cast
@ -80,6 +81,10 @@ def _now() -> float:
return time.time()
def _utcnow() -> datetime:
return datetime.now(timezone.utc)
def _efforts(values: Iterable[str]) -> list[ReasoningEffort]:
allowed = set(ENGINE_REASONING_EFFORTS)
return [cast(ReasoningEffort, value) for value in values if value in allowed]
@ -597,6 +602,7 @@ def _structured_or_none(text: str, req: GenerateRequest) -> dict[str, Any] | Non
async def _generate_codex(
req: GenerateRequest, system_prompt: str, user_payload: str
) -> ProviderGenerateResult:
pricing_started_at = _utcnow()
binary = _binary("CODEX_BIN", "codex")
if binary is None:
raise ProviderError("Codex CLI를 찾을 수 없습니다.")
@ -652,6 +658,7 @@ async def _generate_codex(
model=model,
tokens_in=tokens_in,
tokens_out=tokens_out,
priced_at=pricing_started_at,
cached_input_tokens=cached_input_tokens,
)
return ProviderGenerateResult(
@ -685,6 +692,7 @@ async def _stream_agy(
--continue/--conversation을 쓰지 않는다. 회기 메모리는 요청의 마스킹된 prompt가
소유하고, 프로세스는 응답 종료한다.
"""
pricing_started_at = _utcnow()
binary = _binary("AGY_BIN", "agy")
if binary is None:
raise ProviderError("Agy CLI를 찾을 수 없습니다.")
@ -781,6 +789,7 @@ async def _stream_agy(
model=model,
tokens_in=tokens_in,
tokens_out=tokens_out,
priced_at=pricing_started_at,
cached_input_tokens=cached_input_tokens,
)
yield ProviderStreamEvent(
@ -800,6 +809,7 @@ async def _stream_agy(
async def _generate_claude_api(
req: GenerateRequest, system_prompt: str
) -> ProviderGenerateResult:
pricing_started_at = _utcnow()
api_key = os.environ.get("ANTHROPIC_API_KEY", "").strip()
if not api_key:
raise ProviderError("ANTHROPIC_API_KEY가 설정되지 않았습니다.")
@ -849,6 +859,7 @@ async def _generate_claude_api(
model=str(body.get("model") or model),
tokens_in=tokens_in,
tokens_out=tokens_out,
priced_at=pricing_started_at,
cached_input_tokens=int(usage.get("cache_read_input_tokens") or 0),
)
return ProviderGenerateResult(