0.167.22
Fixed
- Cached-токены не читались в OpenAI-стриминге — метрика кэша всегда ноль в интерактивном чате ( — P2). Нестриминговый путь читал
prompt_tokens_details.cached_tokens(openai_compat.goparseOpenAIResponse), стриминговый — нет: интерактивный чат всегда streaming, поэтомуmetrics.RecordLLMCallиllmlogполучалиCachedTokens=0, и экономия на промпт-кэше была невидима (Anthropic-путь читал кэш в обеих ветках — расхождение только на OpenAI-совместимых). Фикс:LLMResponse.Usage.CachedTokensв стриминговом результате читается изusage.prompt_tokens_details.cached_tokensпоследнего usage-чанка. Попутно закрыта мина аккумулятора SDK:ChatCompletionAccumulatorсуммирует usage по чанкам (streamaccumulator.go), и шлюз, повторяющий usage-объект в каждом чанке, умножалPromptTokensна их число — теперь ведётся отдельный tracking последнего usage-чанка (last-chunk-wins, семантика OpenAI-спеки: usage приходит один раз, полным, в финальном чанке), accumulator остаётся фолбэком когда usage-чанков нет вовсе. Вся инфраструктура отображения (llmlogsaved_tokens, метрики, store-суммари, UI) уже была готова — не хватало только источника. Тесты: положительные — usage-чанк сprompt_tokens_details.cached_tokens: 768→CachedTokens=768; без details → 0 без паники; отрицательный — шлюз повторяет один и тот же usage в 3 чанках → итог не умножается (42/7/49/32, а не ×3).