Skip to content

feat(kimicode): Kimi Code CLI provider, parse ~/.kimi-code wire sessions#750

Open
ozymandiashh wants to merge 2 commits into
getagentseal:mainfrom
ozymandiashh:pr/747-kimicode
Open

feat(kimicode): Kimi Code CLI provider, parse ~/.kimi-code wire sessions#750
ozymandiashh wants to merge 2 commits into
getagentseal:mainfrom
ozymandiashh:pr/747-kimicode

Conversation

@ozymandiashh

Copy link
Copy Markdown
Collaborator

Adds a kimicode provider for Kimi Code CLI (MoonshotAI/kimi-code, the successor of kimi-cli). Requested in #747.

Schema provenance: verified live, not reverse engineered

Unlike the usual new-provider flow, this one was built against a live Kimi Code CLI install (0.27.0, macOS arm64): real sessions were generated locally (success single-turn, multi-tool, multi-turn continuation, retry-only failure), the store was inspected on disk, and the provider was validated against that real store before this PR. The observed schema:

  • ~/.kimi-code/sessions/wd_<project>_<hash>/session_<uuid>/ with state.json (title, workDir, ISO timestamps, agents map) and per-agent agents/<id>/wire.jsonl event streams (metadata carries protocol_version: "1.4").
  • Per-turn usage arrives as usage.record events: inputOther -> input, output -> output, inputCacheRead -> cacheRead, inputCacheCreation -> cacheWrite. No cost fields exist anywhere, so cost is computed from tokens via calculateCost and flagged estimated (kimi-k3 pricing has been in the fallback since fix(pricing): add kimi-k3 to the pricing fallback #709).
  • The alias trap: usage.record.model is the config ALIAS (for example k3), while the real model id (for example kimi-k3) lives on llm.request events. Rows resolve through the alias-to-model map first with the nearest preceding request as fallback, so aliases never leak into reports. This exact case is exercised by a regression test.
  • Retry-only failed sessions (repeated llm.request with attempt, no usage.record) parse to zero usage without throwing; malformed JSONL lines are skipped.
  • Subagents get their own wire.jsonl under the same session (parsed as separate sources, no double counting); multi-turn continuations append to one wire.jsonl and parse as one session with several turns.
  • Tool calls (tool.call loop events) feed the tool breakdown; tool state resets at turn boundaries so a failed turn cannot bleed tools into the next row.

Robustness

Hardened after an adversarial multi-model review pass: alias-first model resolution, turn-boundary tool-state resets, and the dedup key's store invariant (per-agent wire exclusivity) documented in the provider docs.

Validation

  • Fixture suite covers: single-turn, multi-tool, multi-turn, retry-only failure, subagent wires, malformed lines, alias-vs-real-model resolution, and tool-bleed regressions. All sanitized, no live store required.
  • Real-store check on the machine that generated the sessions: report --provider=kimicode returns 2 usage-bearing sessions, 9 calls, correct token mapping (non-zero cacheRead), and the real model id in the models table; doctor shows the resolved ~/.kimi-code probe root with 4/4 sessions parsed.
  • npx tsc --noEmit clean; kimicode + registry + full local suites green.

Scope note

kimi-cli (the predecessor) is being wound down and Kimi Code CLI migrates its config and sessions into ~/.kimi-code on install, so this provider targets the kimi-code store only. KIMI_CODE_HOME overrides the root.

Closes #747

…ons (getagentseal#747)

Adds a provider for Kimi Code CLI (MoonshotAI/kimi-code, the successor of
kimi-cli), reading ~/.kimi-code/sessions/wd_*/session_*/: state.json for
session metadata and per-agent agents/<id>/wire.jsonl event streams.

- Usage from usage.record events: inputOther->input, output->output,
  inputCacheRead->cacheRead, inputCacheCreation->cacheWrite. The store has
  no cost fields, so cost is computed from tokens and flagged estimated.
- Real model attribution: usage.record.model carries the config ALIAS; the
  real model id lives on llm.request events. Rows resolve the alias through
  the alias->model map first, with the nearest preceding request as
  fallback, so aliases never leak into reports.
- Subagent wire files parse as separate sources under one session without
  double counting; multi-turn continuations in one wire.jsonl are one
  session with multiple turns; retry-only failed sessions parse to zero
  usage; malformed JSONL lines are skipped.
- Tool calls feed the tool breakdown; tool state resets at turn boundaries
  so a failed turn cannot bleed its tools into the next row.
- KIMI_CODE_HOME override, eager registration, PROVIDER_ENV_VARS and
  PROVIDER_PARSE_VERSIONS entries, probeRoots for doctor, docs page.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for Kimi-Code

1 participant