feat(kimi): Kimi K3 provider on the official kimi-code CLI (#713)

* feat(kimi): Kimi K3 provider on the official kimi-code CLI (Wave 1)

ModelProvider.KIMI routes through KimiCliProvider driving Moonshot's kimi
CLI on a Kimi subscription (OAuth device-code, no metered key). One-shot
delivery roles only (V1), interactive ban wired in both guard lists.

Auth: one shared RW auth mount; containers symlink credentials/ and
oauth/ (the CLI's cross-process refresh-lock dir) into a container-local
KIMI_CODE_HOME so every container and the host redeem the SAME rotating
refresh chain - live-verified that per-copy chains cross-invalidate after
the reuse-grace window. No orchestrator refresh daemon; an expires_at
preflight exits 78.

Config renderer mirrors the login-managed provider/model blocks
field-for-field (live-captured; the model value is the CLI-side name,
never the raw API id), plus per-role deny rules and the bash-guard as a
PreToolUse hook via a wrapper script (an env key on a hooks entry makes
the CLI silently drop ALL hooks - live-verified). Usage capture sums
wire.jsonl usage.record 4-bucket events; sniff classifies rate-limit/auth
from structured error text only, mapped to the shared 75/78 park
contract. Image installs the CLI latest-at-build (no version pin, by
policy) with the resolved version stamped as provenance, binary split to
/usr/local away from mutable state.

Migrations 090 (enum) + 091 (provider seed); catalog, pricing, routing
mode, and orchestrator park/usage wiring mirror the codex integration.

* feat(kimi): surface sweep + fleet-wide pin drop (Wave 2)

Compose x3 gain the agent-kimi-image service and the orchestrator's
read-write ~/.kimi-code mount + kimi-usage dir; .env.example documents
the Kimi block. Panel mirrors ModelProvider.KIMI and adds the kimi
routing mode (catalog filter, mode button, mix-picker group, badge) with
tests; provider routes gain the kimi remediation entry. CLAUDE.md and
docs/map document the runtime. Per the no-pins policy, agent-grok/
gemini/codex Dockerfiles drop their version pins for latest-at-build
with resolved-version provenance stamps (grok resolves 0.2.112 vs the
old 0.2.56 pin - verified by real builds of all four images).

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
Renzo F
2026-07-29 01:48:55 +02:00
committed by GitHub
co-authored by Renn F
parent eb470dfb33
commit 6374bbbed0
43 changed files with 3907 additions and 110 deletions
+95
View File
@@ -77,6 +77,23 @@ _GLM_OUTPUT = 4.40
_GLM_CACHE_READ = 0.26
_GLM_CACHE_WRITE = 1.40
# Moonshot Kimi — priced non-Anthropic (kimi-code CLI subscription, priced
# here for cost attribution like grok-build/gpt-5.3-codex).
_KIMI_K3_INPUT = 3.00
_KIMI_K3_OUTPUT = 15.00
_KIMI_K3_CACHE_READ = 0.30
_KIMI_K3_CACHE_WRITE = 3.00
_KIMI_CODING_INPUT = 0.95
_KIMI_CODING_OUTPUT = 4.00
_KIMI_CODING_CACHE_READ = 0.19
_KIMI_CODING_CACHE_WRITE = 0.95
_KIMI_CODING_HIGHSPEED_INPUT = 1.90
_KIMI_CODING_HIGHSPEED_OUTPUT = 8.00
_KIMI_CODING_HIGHSPEED_CACHE_READ = 0.38
_KIMI_CODING_HIGHSPEED_CACHE_WRITE = 1.90
# Tolerance for floating-point comparisons
_TOL = 1e-4
@@ -395,6 +412,78 @@ class TestCodexTier:
assert _CODEX_OUTPUT > _CODEX_INPUT
# ---------------------------------------------------------------------------
# Kimi tier (Moonshot — priced non-Anthropic, four login-managed aliases)
# ---------------------------------------------------------------------------
class TestKimiTier:
"""kimi-code/* pricing — cache_write folds to the input rate, same
convention as grok-build/gpt-5.3-codex (no published cache-write discount)."""
def test_k3_all_token_types(self) -> None:
cost = calculate_cost(
"kimi-code/k3",
tokens_input=_M,
tokens_output=_M,
tokens_cache_read=_M,
tokens_cache_write=_M,
)
expected = (
_KIMI_K3_INPUT
+ _KIMI_K3_OUTPUT
+ _KIMI_K3_CACHE_READ
+ _KIMI_K3_CACHE_WRITE
)
assert abs(cost - expected) < _TOL
def test_k3_256k_prices_the_same_as_k3(self) -> None:
# "kimi-code/k3" is a PREFIX of "kimi-code/k3-256k" — longest-fragment
# wins in _lookup_prices must resolve the 256k alias to its own entry,
# not silently fall through to the bare k3 fragment (same rates here,
# but the resolution path is what's under test).
cost = calculate_cost("kimi-code/k3-256k", tokens_input=_M, tokens_output=0)
assert abs(cost - _KIMI_K3_INPUT) < _TOL
def test_kimi_for_coding_all_token_types(self) -> None:
cost = calculate_cost(
"kimi-code/kimi-for-coding",
tokens_input=_M,
tokens_output=_M,
tokens_cache_read=_M,
tokens_cache_write=_M,
)
expected = (
_KIMI_CODING_INPUT
+ _KIMI_CODING_OUTPUT
+ _KIMI_CODING_CACHE_READ
+ _KIMI_CODING_CACHE_WRITE
)
assert abs(cost - expected) < _TOL
def test_kimi_for_coding_highspeed_resolves_its_own_longer_fragment(self) -> None:
# "kimi-code/kimi-for-coding" is a PREFIX of
# "kimi-code/kimi-for-coding-highspeed" — longest-fragment-wins must
# resolve the highspeed alias to its OWN (pricier) rate, not the base
# coding tier's cheaper one.
cost = calculate_cost(
"kimi-code/kimi-for-coding-highspeed", tokens_input=_M, tokens_output=0
)
assert abs(cost - _KIMI_CODING_HIGHSPEED_INPUT) < _TOL
assert cost > calculate_cost(
"kimi-code/kimi-for-coding", tokens_input=_M, tokens_output=0
)
def test_kimi_is_not_treated_as_anthropic(self) -> None:
assert _is_anthropic_model("kimi-code/k3") is False
assert calculate_cost("kimi-code/k3", tokens_input=_M, tokens_output=0) > 0.0
def test_output_is_pricier_than_input(self) -> None:
assert _KIMI_K3_OUTPUT > _KIMI_K3_INPUT
assert _KIMI_CODING_OUTPUT > _KIMI_CODING_INPUT
assert _KIMI_CODING_HIGHSPEED_OUTPUT > _KIMI_CODING_HIGHSPEED_INPUT
# ---------------------------------------------------------------------------
# GLM-5.2 tier (Ollama Cloud — priced non-Anthropic, grounded in a citable
# published rate; see the module's pricing-table comment for the source).
@@ -620,6 +709,12 @@ class TestCostResult:
assert result.unpriced is False
assert result.is_anthropic is False
def test_priced_non_anthropic_kimi_is_not_unpriced(self) -> None:
result = calculate_cost_result("kimi-code/k3", tokens_input=_M, tokens_output=0)
assert result.cost_usd > 0.0
assert result.unpriced is False
assert result.is_anthropic is False
def test_calculate_cost_matches_structured_cost_usd(self) -> None:
model = "claude-opus-5"
assert (