# Модели и цены TextMachine (Р4/Р5: состав и цены — ТОЛЬКО здесь, с датой
# проверки; код не знает ни одной цены).
#
# Источники проверки 2026-07-10 (D3-цепочка/канал B заведены пакетом №3; каждый
# слаг live-фактчекнут — /models И пробный вызов, правило двух направлений):
#   DeepSeek  https://api-docs.deepseek.com/quick_start/pricing  (v4-pro $0.435/$0.87, cache-hit $0.003625)
#   Z.AI/GLM  https://docs.z.ai/guides/overview/pricing          (glm-5.1 $1.4/$4.4, cached $0.26)
#   Kimi      https://platform.kimi.ai/docs/pricing/chat-k26
#   xAI       https://docs.x.ai/docs/models (Grok 4.1 Fast retired 15.05.2026!)
#   Gemini    https://ai.google.dev/gemini-api/docs/pricing      (3.1-pro-preview $2/$12 ≤200k, cache $0.20, output incl. thinking)
#   Mistral   https://mistral.ai/pricing/api                     (Large 3 = mistral-large-2512 $0.5/$1.5; FAQ "$2/$6" = legacy Large 2)
#   OpenAI    https://developers.openai.com/api/docs/models/gpt-5-mini  (gpt-5-mini $0.25/$2.0, cached $0.025)
# Live-факты пакета №3 (2026-07-10, все HTTP 200 пробным вызовом, кроме отмеченного):
#   • gemini-3.1-pro → 404 NOT_FOUND; callable слаг ТОЛЬКО gemini-3.1-pro-preview (D3-текст назвать -preview — пинг).
#   • Gemini thinking-токены НЕ в completion_tokens (проба: completion=2, total=847 → 823 thinking в total_tokens,
#     поля reasoning_tokens нет) → провайдер gemini reasoning:additive_total (адаптер деривит reasoning=total−prompt−completion,
#     иначе mistral-класс слепоты потолка на mandatory-thinking апексе).
#   • gpt-5-mini жив пробой (→ dated gpt-5-mini-2025-08-07), но снят с прайс-страницы (там gpt-5.4/5.5/5.6); кандидат D3, не в цепочке Ф1.
prices_checked: "2026-07-10"

# Fallback-якорь цены: неизвестная модель (например, фактическая модель после
# фейловера, которой нет в таблице) книжится по этой цене, никогда по $0.
default_model: deepseek-v4-flash

providers:
  deepseek:
    kind: openai
    base_url: https://api.deepseek.com/v1
    api_key_env: DEEPSEEK_API_KEY
    reasoning: subset # thinking внутри completion_tokens
    # ⚠️ ЭХО-МИНА (трасса 2026-07-04, PROGRESS «Ответ Полигону»): на плотном CJK
    # DeepSeek с thinking ВЫКЛ воспроизводимо возвращает ИСХОДНИК вместо перевода
    # (тихий отказ, HTTP 200). Держится только тем, что reasoning:"off" через
    # ReasoningNone — осознанный no-op (thinking остаётся ON по дефолту). Флаг
    # включает fail-fast (config.echoMineViolation): нельзя завести deepseek
    # capabilities.reasoning.off_extra_body:{thinking:{type:disabled}} — включит
    # эхо в проде. GLM с thinking:disabled безопасен (вход — русский черновик).
    echoes_when_thinking_off: true
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  zai: # GLM, международный контур (docs.z.ai)
    kind: openai
    base_url: https://api.z.ai/api/paas/v4
    api_key_env: ZAI_API_KEY
    reasoning: subset
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  kimi: # API-хост — api.moonshot.ai (intl, НЕ .cn). Веб-консоль переехала
    # platform.moonshot.ai → platform.kimi.ai, но API-эндпоинт остаётся
    # api.moonshot.ai: api.kimi.ai НЕ резолвится (DNS fail, live-проба 2026-07-04
    # /models: 000; moonshot.ai → 200 c kimi-k2.6). Прежний base_url был битый.
    kind: openai
    base_url: https://api.moonshot.ai/v1
    api_key_env: KIMI_API_KEY
    reasoning: subset
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  xai: # Grok — центральная модель Фазы 1: дефолт-редактор SFW + главный тир канала B + судья 18+.
    # ⚠️ ГИГИЕНА АККАУНТОВ (D8/оркестратор): XAI_API_KEY обязан быть ЧИСТЫМ прод-аккаунтом
    # БЕЗ data-sharing. Промо-$150-аккаунт (data-sharing) — ТОЛЬКО eval/NSFW, реальные книги
    # через него гнать нельзя. По ключу это не проверяется — подтвердить перед боевым прогоном.
    kind: openai
    base_url: https://api.x.ai/v1
    api_key_env: XAI_API_KEY
    reasoning: additive # xAI биллит reasoning ПОВЕРХ completion (проверено vojo); think-ON заблокирован до резерва в EstimateUSD (D6.2/F3)
    permissive: true # главный пермиссив-тир канала B + reasoning-ON эскалация (D3/D19.1): channel:adult-стадия/escalate_to изолируются ТИПОМ на permissive-провайдера (D4.1)
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  # Anthropic убран из стека по решению владельца (04.07): дорого, в RU-контуре
  # экономически недоступен (Р5), в eval не валидирован. Судья Р4 — Gemini
  # (нативный адаптер, Фаза 2). Нативный Anthropic-адаптер в коде помечен
  # DEPRECATED, но НЕ удалён — оставлен как референс нативного адаптера под
  # Gemini Фазы 2 (см. provider_anthropic.go). Эскалация — не-Anthropic (Kimi/GLM).

  gemini: # Google Gemini через OpenAI-совместимый слой (base .../v1beta/openai). Апекс канала A +
    # судья Фазы 2. ⚠️ Нативный Gemini API нужен для safety-off судьи 18+ (safety_settings не
    # проходят через OpenAI-слой — exp00); OpenAI-слой достаточен для перевода/эскалации (фильтры OFF
    # по дефолту у 3.x, кроме неконфигурируемого PROHIBITED_CONTENT — D21.9).
    kind: openai
    base_url: https://generativelanguage.googleapis.com/v1beta/openai
    api_key_env: GEMINI_API_KEY
    # reasoning:additive_total — thinking у Gemini биллится как output, но в OpenAI-слое НЕ попадает в
    # completion_tokens и НЕ отдаётся полем reasoning_tokens (в отличие от xAI); виден ТОЛЬКО как
    # total_tokens−prompt−completion (live-проба 2026-07-10: completion=2, total=847 → 823 thinking).
    # Адаптер деривит их из total и биллит по output — иначе mandatory-thinking апекс слепил бы потолок.
    reasoning: additive_total
    timeouts: { attempt_s: 300, max_attempts: 3, backoff_cap_s: 60 } # апекс думает дольше

  openai: # OpenAI прямой ключ (D3: Anthropic убран, OpenAI ОСТАЁТСЯ). gpt-5-nano альт-черновик,
    # gpt-5-mini кандидат-редактор/second-opinion судья — НЕ в дефолтной цепочке Ф1 (слот под Ф2).
    kind: openai
    base_url: https://api.openai.com/v1
    api_key_env: OPENAI_API_KEY
    reasoning: subset # gpt-5: reasoning_tokens ⊆ completion (OpenAI-спека), покрыто maxTokens
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  mistral: # Mistral La Plateforme (base api.mistral.ai/v1). Переводчик-дефолт канала B (D19.1):
    # 10/10 чисто на violence, policy 11.06.2026 без запрета adult, НЕ reasoning-модель → эхо-мины нет.
    kind: openai
    base_url: https://api.mistral.ai/v1
    api_key_env: MISTRAL_API_KEY
    reasoning: subset # mistral-large — не thinking-модель; reasoning-токенов нет
    permissive: true # переводчик канала B (D19.1); channel:adult-стадия изолируется ТИПОМ (D4.1)
    timeouts: { attempt_s: 240, max_attempts: 3, backoff_cap_s: 60 }

  local: # ollama/llama-server на стенде (боевой env — memory textmachine-local-stand)
    kind: local
    base_url: http://127.0.0.1:11434/v1
    model: huihui_ai/qwen3-abliterated:8b
    max_tokens: 8192 # у ollama лимит покрывает thinking+ответ вместе
    permissive: true # abliterated-скрининг/дешёвый фолбэк канала B (D3/D19.1)
    timeouts: { attempt_s: 600, max_attempts: 2, backoff_cap_s: 10 } # полигон: чанки 63–278 с

models:
  deepseek-v4-flash:
    provider: deepseek
    price: { input_per_m: 0.14, cached_per_m: 0.0028, cache_write_per_m: 0, output_per_m: 0.28 }
    capabilities:
      # Floor per quirks (thinking ⊆ completion, subset): <8000 → reasoning eats the
      # budget, content пуст, finish=length (НЕ отказ). Schema, not a comment (D24.3).
      min_max_tokens: 8000
    note: >-
      Черновик (Р4). Автокэш по префиксу, отдельной цены записи нет.
      deepseek-chat/reasoner отключаются 24.07.2026 — сюда не возвращаться.

  deepseek-v4-pro:
    provider: deepseek
    # $0.435/$0.87, cache-hit $0.003625 (факт. 2026-07-10, api-docs.deepseek.com/quick_start/pricing).
    price: { input_per_m: 0.435, cached_per_m: 0.003625, cache_write_per_m: 0, output_per_m: 0.87 }
    capabilities:
      # Floor 8000 (D24.3): без него хоп наследовал бюджет праймари (2048/3291 на
      # приёмке этапа A) и вернул finish=length / 0 байт контента — эскалация впустую.
      min_max_tokens: 8000
    note: >-
      Эскалация черновика канала A, хоп 1 (D3): deepseek-эхо 25% на приёмочной 蛊真人 (D18) → single-hop
      фолбэк с draft. Наследует deepseek: thinking ON (эхо-мина того же класса — echoes_when_thinking_off),
      reasoning ⊆ completion (subset). Живьём 2026-07-10: /models ✓, chat 200 (reasoning_content, перевёл).

  glm-5:
    provider: zai
    price: { input_per_m: 1.0, cached_per_m: 0.2, cache_write_per_m: 0, output_per_m: 3.2 }
    # thinking-выключатель переехал из extra_body в capabilities.reasoning (D3.1):
    # тело запроса байт-в-байт то же ({thinking:{type:disabled}} при reasoning=off),
    # но теперь это единая wire-форма — и off_extra_body разблокирует think-ON
    # эскалацию (D6.2) без второй ручки. Смена снапшота осознанная (--resnapshot).
    capabilities:
      reasoning:
        control: extra_body_disable
        off_extra_body: { thinking: { type: disabled } } # эмпирика полигона: thinking GLM — таймауты ×3
    note: Редактор ru-стиля (Р4). Флагманы линейки уже GLM-5.1/5.2 ($1.4/$4.4) — пересмотреть к Фазе 2.

  glm-5.1:
    provider: zai
    # $1.4/$4.4, cached $0.26 (факт. 2026-07-10, docs.z.ai/guides/overview/pricing).
    price: { input_per_m: 1.4, cached_per_m: 0.26, cache_write_per_m: 0, output_per_m: 4.4 }
    capabilities:
      reasoning:
        control: extra_body_disable
        off_extra_body: { thinking: { type: disabled } } # как glm-5: thinking GLM — таймауты ×3 (полигон)
    note: >-
      Эскалация канала A, хоп 2 (D3), кросс-семейный к deepseek-хопу 1. Живьём 2026-07-10: /models ✓
      (glm-4.5..5.2 листятся), chat 200 (thinking:disabled → reasoning_tokens=0). Флагман линейки vs glm-5.

  kimi-k2.6:
    provider: kimi
    price: { input_per_m: 0.95, cached_per_m: 0.16, cache_write_per_m: 0, output_per_m: 4.0 }
    # Альт-редактор (bake-off эксп-04, проиграл grok-4.3): принимает ТОЛЬКО temperature:1
    # (иначе 400), ~11k reasoning tok/абзац. capabilities фиксируют квирк, чтобы edit-стадия
    # на temp 0.4 не 400-ла; min_max_tokens закрепляет min-бюджет схемой (был комментарий).
    capabilities:
      temperature: { mode: force, value: 1 }
      # Floor 16000 (D24.3): <16000 → reasoning съедает лимит, content пустой, finish=length.
      min_max_tokens: 16000
    note: Альтернативный редактор (Р4).

  grok-4.3:
    provider: xai
    # $1.25/$2.50/1M (факт. 2026-07-04, docs.x.ai). cached_per_m=input: кэш-цену xAI
    # не верифицировали, а для редактора (черновик — свежий вход на чанк) cache-hit≈0,
    # поэтому консервативно не моделируем скидку — потолок не слепнет. Уточнит полигон.
    price: { input_per_m: 1.25, cached_per_m: 1.25, cache_write_per_m: 0, output_per_m: 2.50 }
    # Дефолт-редактор (bake-off эксп-04): temperature шлём; reasoning OFF даётся ТОЛЬКО явным
    # reasoning_effort:"none" (control:effort + off_effort:none). Дефолт grok = low → омиссия
    # заставляет думать: проба eval 05.07 (Chat Completions) — omission→444 reasoning-ток., "none"→0.
    # control:none (off-by-omission) молча оставил бы low; control:effort/off_effort шлёт явный none.
    capabilities:
      temperature: { mode: send }
      reasoning: { control: effort, off_effort: none }
    note: >-
      Дефолт-редактор SFW (D3, bake-off эксп-04) + главный пермиссив-тир канала B + судья 18+.
      reasoning additive: think-ON только после резерва в EstimateUSD (D6.2/техдолг F3). Включена
      в edit-стадию C1/C2 (D1/D3, консолидация 05.07); прод-прогон — только с ЧИСТЫМ xAI-ключом без data-sharing.

  gemini-3.1-pro-preview: # ⚠️ слаг ИМЕННО -preview: gemini-3.1-pro → HTTP 404 NOT_FOUND (live 2026-07-10)
    provider: gemini
    # $2/$12 за 1M ≤200k (факт. 2026-07-10, ai.google.dev/gemini-api/docs/pricing; >200k тир $4/$18 —
    # не моделируем, чанки книги ≤200k). Output ВКЛЮЧАЕТ thinking-токены (reasoning-as-output, D3.2/D6.3).
    price: { input_per_m: 2.0, cached_per_m: 0.20, cache_write_per_m: 0, output_per_m: 12.0 }
    capabilities:
      # mandatory: thinking обязателен (thinking_budget:0 → HTTP 400, D6.3); адаптер молча глотает
      # reasoning:"off", forced thinking биллится как output. Учёт токенов — provider gemini reasoning:additive_total.
      reasoning: { control: mandatory }
      # Floor 8000 (D24.3): mandatory-thinking съедает бюджет; <8000 → перевод обрезан.
      # Раньше «дать max_tokens ≥8000» — комментарий; теперь схема (thinking ⊆ бюджета, additive_total).
      min_max_tokens: 8000
    note: >-
      Апекс канала A / судья Фазы 2 (D3). min_max_tokens 8000 держит thinking внутри бюджета (резерв не слепнет; settle
      биллит thinking через additive_total). Судья 18+ требует НАТИВНОГО Gemini (safety-off) — Ф2. Живьём 2026-07-10: chat 200.

  mistral-large-2512:
    provider: mistral
    # $0.5/$1.5 за 1M (факт. 2026-07-10, mistral.ai/pricing/api — Mistral Large 3, релиз дек.2025, Apache 2.0,
    # 262K). ⚠️ Маркетинг-FAQ mistral.ai/pricing даёт generic "$2/$6" = legacy Large 2; per-model /pricing/api
    # = $0.5/$1.5 (OpenRouter согласен) → разрешает D19-подозрение ($0.5/$1.5 при $2/$6 = 4×). cached=input
    # консервативно (cache-read не моделируем; канал B — свежий вход/чанк, hit≈0, потолок не слепнет).
    price: { input_per_m: 0.5, cached_per_m: 0.5, cache_write_per_m: 0, output_per_m: 1.5 }
    note: >-
      Переводчик-дефолт канала B (D19.1): 10/10 чисто на violence, policy 11.06.2026 без запрета adult, не
      reasoning-модель (эхо-мины нет). Полный wiring канала B — Ф2 (конфиг-слот). Полигон перепроверяет цену (D19.5б).
      Живьём 2026-07-10: /models ✓, chat 200.

  gpt-5-mini: # кандидат-редактор/second-opinion судья (D3) — НЕ в дефолтной цепочке Ф1
    provider: openai
    # $0.25/$2.0, cached $0.025 (факт. 2026-07-10, developers.openai.com/api/docs/models/gpt-5-mini). Слаг жив
    # (chat 200 → dated gpt-5-mini-2025-08-07), но снят с текущей прайс-страницы (там gpt-5.4/5.5/5.6) — пересмотр к Ф2.
    price: { input_per_m: 0.25, cached_per_m: 0.025, cache_write_per_m: 0, output_per_m: 2.0 }
    capabilities:
      budget_field: max_completion_tokens        # gpt-5: max_tokens → HTTP 400
      temperature: { mode: omit }                # gpt-5: temperature не принимается → HTTP 400
      reasoning: { control: effort, off_effort: minimal } # reasoning ON выжигает бюджет → пустой ответ; шлём minimal
    note: >-
      Кандидат-редактор Р4 / second-opinion судья (D3). Не в дефолтной цепочке Ф1 (слот под Ф2).
      Живьём 2026-07-10 — chat 200.

  # claude-sonnet-5 / claude-opus-4-8 удалены вместе с провайдером anthropic
  # (см. комментарий у providers выше). Судья Фазы 2 — Gemini: нативный адаптер для
  # safety-off судьи 18+; для перевода/эскалации достаточно OpenAI-слоя (провайдер gemini выше).

  local-qwen3-8b:
    provider: local
    price: { input_per_m: 0, cached_per_m: 0, cache_write_per_m: 0, output_per_m: 0 }
    note: Скрининг/экстракция (Р4 — «спецслужба, не переводчик»). $0 допустим только для local-провайдера.
