Files
librefang-registry/providers/moonshot.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

57 lines
1.3 KiB
TOML

# Moonshot / Kimi — https://moonshot.ai
# Models: 3
[provider]
id = "moonshot"
display_name = "Moonshot (Kimi)"
api_key_env = "MOONSHOT_API_KEY"
base_url = "https://api.moonshot.ai/v1"
key_required = true
[[models]]
id = "kimi-k2.6"
display_name = "Kimi K2.6"
tier = "frontier"
context_window = 262144
max_output_tokens = 16384
input_cost_per_m = 0.74
output_cost_per_m = 3.49
supports_tools = true
supports_vision = true
supports_streaming = true
supports_thinking = true
# Kimi requires reasoning_content present (empty string) on assistant
# turns with tool_calls, with thinking disabled wire-side for multi-turn
# compatibility. See librefang/librefang openai driver.
reasoning_echo_policy = "empty_string"
aliases = ["kimi", "kimi-k2.6-0420"]
[[models]]
id = "kimi-k2.5"
display_name = "Kimi K2.5"
tier = "frontier"
context_window = 131072
max_output_tokens = 16384
input_cost_per_m = 0.44
output_cost_per_m = 2.0
supports_tools = true
supports_vision = true
supports_streaming = true
supports_thinking = true
reasoning_echo_policy = "empty_string"
aliases = ["kimi-k2.5-0711"]
[[models]]
id = "kimi-k2"
display_name = "Kimi K2"
tier = "frontier"
context_window = 131072
max_output_tokens = 16384
input_cost_per_m = 0.57
output_cost_per_m = 2.3
supports_tools = true
supports_vision = true
supports_streaming = true
reasoning_echo_policy = "empty_string"
aliases = []