Files
librefang-registry/providers/novita.toml
T
Evan 6785807633 feat(providers): add reasoning_echo_policy field for OpenAI-compat reasoning_content handling (#90)
Refs librefang/librefang#4842 — long-term replacement for the substring
match that the OpenAI driver currently uses to decide how to handle
`reasoning_content` on historical assistant turns.

Three provider-specific behaviours that the driver must distinguish at
wire time, now expressed as catalog metadata:

* `strip`  — DeepSeek R1 / deepseek-reasoner. The API rejects requests
  that carry reasoning_content on previous assistant messages.
* `echo`   — DeepSeek V4 Flash. Thinking mode is on by default and the
  API rejects multi-turn requests when assistant turns containing
  tool_calls don't echo back the original reasoning text. This is the
  bug surfaced in librefang/librefang#4842.
* `empty_string` — Moonshot / Kimi K2 family. The field must be present
  (empty string) on tool_calls turns, with thinking disabled wire-side
  for multi-turn compatibility.
* `none` (default) — most providers; field is omitted entirely.

V4 Pro is intentionally NOT marked `echo` — librefang#4842 reports it
working out-of-the-box; flip when there's an empirical reproducer.

Marks affected models:

  providers/deepseek.toml
    deepseek-v4-flash → echo
    deepseek-reasoner → strip
  providers/moonshot.toml
    kimi-k2.6, kimi-k2.5, kimi-k2 → empty_string
  providers/kimi-coding.toml
    kimi-for-coding → empty_string
  providers/byteplus-coding.toml
    kimi-k2.5 → empty_string
  providers/novita.toml
    moonshotai/kimi-k2-thinking → empty_string

Tooling:

* schema.toml registers the field with the four enum options and a
  `none` default so existing TOML files keep parsing unchanged.
* scripts/validate.py rejects unknown enum values; verified with a
  hand-crafted negative case (`reasoning_echo_policy = "bogus"` →
  validation fails with the expected message).
* `python3 scripts/validate.py` passes (267 models).

The librefang side that consumes this field will land in a follow-up
PR — until then, registry consumers ignore the field via
`#[serde(default)]` and the existing substring fallback continues to
work, so this commit is safe to ship independently.
2026-05-11 00:41:24 +09:00

93 lines
2.2 KiB
TOML

# Novita AI — https://novita.ai
# OpenAI-compatible LLM gateway. Endpoint: https://api.novita.ai/openai/v1
# Pricing reflects values returned by GET /openai/v1/models on 2026-04-25
# (input_token_price_per_m / output_token_price_per_m, scaled /10000 to USD).
# Models: 6
[provider]
id = "novita"
display_name = "Novita AI"
api_key_env = "NOVITA_API_KEY"
base_url = "https://api.novita.ai/openai/v1"
key_required = true
[[models]]
id = "deepseek/deepseek-v3.2"
display_name = "DeepSeek V3.2 (Novita)"
tier = "frontier"
context_window = 163840
max_output_tokens = 65536
input_cost_per_m = 0.4
output_cost_per_m = 1.2
supports_tools = true
supports_vision = false
supports_streaming = true
aliases = []
[[models]]
id = "moonshotai/kimi-k2-thinking"
display_name = "Kimi K2 Thinking (Novita)"
tier = "frontier"
context_window = 262144
max_output_tokens = 262144
input_cost_per_m = 0.60
output_cost_per_m = 2.50
supports_tools = true
supports_vision = false
supports_streaming = true
supports_thinking = true
reasoning_echo_policy = "empty_string"
aliases = []
[[models]]
id = "minimax/minimax-m2"
display_name = "MiniMax M2 (Novita)"
tier = "smart"
context_window = 204800
max_output_tokens = 131072
input_cost_per_m = 0.30
output_cost_per_m = 1.20
supports_tools = true
supports_vision = false
supports_streaming = true
aliases = []
[[models]]
id = "meta-llama/llama-3.3-70b-instruct"
display_name = "Llama 3.3 70B (Novita)"
tier = "smart"
context_window = 131072
max_output_tokens = 120000
input_cost_per_m = 0.1
output_cost_per_m = 0.32
supports_tools = true
supports_vision = false
supports_streaming = true
aliases = []
[[models]]
id = "qwen/qwen3-coder-30b-a3b-instruct"
display_name = "Qwen3 Coder 30B (Novita)"
tier = "balanced"
context_window = 160000
max_output_tokens = 32768
input_cost_per_m = 0.07
output_cost_per_m = 0.27
supports_tools = true
supports_vision = false
supports_streaming = true
aliases = []
[[models]]
id = "zai-org/glm-4.7-flash"
display_name = "GLM 4.7 Flash (Novita)"
tier = "balanced"
context_window = 200000
max_output_tokens = 128000
input_cost_per_m = 0.07
output_cost_per_m = 0.40
supports_tools = true
supports_vision = false
supports_streaming = true
aliases = []