The Kimi CLI provider enables CAO to work with Kimi Code CLI, Moonshot AI's coding agent CLI tool. Kimi CLI runs as an interactive TUI using prompt_toolkit.
- Kimi CLI: Install via
brew install kimi-clioruv tool install kimi-cli - Authentication: Run
kimi login(OAuth-based) - tmux 3.3+
Verify installation:
kimi --version# Authenticate
kimi login
# Launch with CAO
cao launch --agents code_supervisor --provider kimi_cliThe provider detects Kimi CLI states by analyzing tmux terminal output:
| Status | Pattern | Description |
|---|---|---|
| IDLE | 💫 or ✨ at bottom (optionally prefixed with username@dirname) |
Prompt visible, ready for input |
| PROCESSING | No prompt at bottom | Response is streaming |
| COMPLETED | Prompt at bottom + latching flag (user input detected) | Task finished |
| ERROR | Error:, APIError:, ConnectionError: patterns |
Error detected |
- 💫 (dizzy): Thinking mode enabled (default behavior)
- ✨ (sparkle): Thinking mode disabled (
--no-thinkingflag)
The provider matches both symbols using the pattern (?:\w+@[\w.-]+)?[✨💫]. The username@dirname prefix is optional to support both v1.20.0+ (bare emoji) and earlier versions.
Response extraction from terminal output (supports two formats):
v1.20.0+ (inline prompt format):
- Find the last prompt-with-input line (
💫 message text) - Collect all content between that line and the next bare prompt (
💫) - Filter out thinking bullets (gray ANSI-styled
•lines)
Pre-v1.20.0 (input box format):
- Find the last user input box (bordered with
╭─/╰─) - Collect all content between the box end and the next prompt
- Filter out thinking bullets
Fallback (long responses where markers scroll out of capture): Extract all content up to the last idle prompt, filtering out TUI chrome.
Both thinking and response lines use the • (bullet) prefix. The provider distinguishes them using ANSI color codes in the raw terminal output:
- Thinking:
\x1b[38;5;244m•(gray color 244 + italic) - Response: Plain
•without ANSI color prefix
Agent profiles are optional for Kimi CLI. If provided, the provider:
- Creates a temporary YAML agent file that extends Kimi's built-in
defaultagent - Writes the system prompt as a separate markdown file
- Passes the agent file via
--agent-file
version: 1
agent:
extend: default
system_prompt_path: ./system.mdTemp files are automatically cleaned up when the provider's cleanup() method is called.
MCP servers from agent profiles are passed via --mcp-config as a JSON string:
kimi --yolo --mcp-config '{"server-name": {"command": "npx", "args": ["-y", "cao-mcp-server"]}}'Kimi CLI defaults to a 60-second MCP tool call timeout (tool_call_timeout_ms=60000 in ~/.kimi/config.toml). This is too short for handoff operations, which create a worker terminal, wait for completion, and extract output — routinely exceeding 60 seconds.
The provider automatically modifies ~/.kimi/config.toml to set tool_call_timeout_ms=600000 when MCP servers are configured, increasing the timeout to 600 seconds (10 minutes) to match CAO's default handoff timeout. The original value is restored during cleanup(). This is the same direct-config-write pattern used by the Gemini CLI provider (~/.gemini/settings.json).
Why not --config flag? Kimi CLI's --config flag causes it to bypass the default config file (~/.kimi/config.toml), which breaks OAuth authentication — the CLI shows "model: not set" and /login refuses to work. Modifying the config file directly avoids this issue.
Without this override, the supervisor Kimi CLI agent receives a ToolError("Timeout while calling MCP tool handoff") after 60 seconds, even though the worker is still processing.
Kimi CLI does not automatically forward parent shell environment variables to MCP subprocesses. The provider explicitly injects CAO_TERMINAL_ID into the env field of each MCP server config so that tools like handoff and assign can create new agent windows in the same tmux session (instead of creating separate sessions). Existing env entries are preserved, and an existing CAO_TERMINAL_ID value is never overwritten.
| Flag | Purpose |
|---|---|
--yolo |
Auto-approve all tool action confirmations |
--agent-file FILE |
Custom agent YAML file |
--mcp-config TEXT |
MCP server configuration (JSON, repeatable) |
--work-dir DIR |
Set working directory |
--no-thinking |
Disable thinking mode (changes prompt to ✨) |
- Initialize: Create unique temp dir → set MCP timeout in
~/.kimi/config.toml(if MCP servers) → wait for shell → sendcd <tempdir> && TERM=xterm-256color kimi --yolo→ wait for IDLE or COMPLETED (up to 120s) - Status Detection: Check bottom 50 lines for idle prompt pattern (end-of-line anchored)
- Message Extraction: Line-based approach mapping raw and clean output for thinking filtering
- Exit: Send
/exitcommand - Cleanup: Remove temp agent files, restore MCP timeout in config.toml, reset state
╭────────────────────────────────────────────────────────╮
│ Welcome to Kimi Code CLI! │
╰────────────────────────────────────────────────────────╯
💫 create a function
• [thinking] Let me create the function...
• Here is the function:
def greet(name):
return f"Hello, {name}!"
💫
The provider handles several v1.20.0 behavioral changes:
- Prompt format: Changed from
user@dirname💫to bare💫. The idle pattern uses an optional prefix. - Input display: Removed bordered input boxes (
╭─...╰─). User input now appears inline on the prompt line (💫 message text). - TERM variable: Kimi CLI silently exits when
TERM=tmux-256color(the tmux default). The provider overrides withTERM=xterm-256color. - Per-directory lock: Only one Kimi instance can run in a given directory. Each provider instance uses its own temp directory via
cd.
# Run all Kimi CLI E2E tests
uv run pytest -m e2e test/e2e/ -v -k kimi_cli
# Run specific test type
uv run pytest -m e2e test/e2e/test_handoff.py -v -k kimi_cli
uv run pytest -m e2e test/e2e/test_assign.py -v -k kimi_cli
uv run pytest -m e2e test/e2e/test_send_message.py -v -k kimi_cli
uv run pytest -m e2e test/e2e/test_supervisor_orchestration.py -v -k KimiCli -o "addopts="Prerequisites for E2E tests:
- CAO server running (
cao-server) kimiCLI authenticated (kimi login)- Agent profiles installed (
cao install developer)
# Verify kimi is on PATH (command is `kimi`, not `kimi-cli`)
which kimi
kimi --version# Re-authenticate
kimi loginIf Kimi CLI takes too long to start, check:
- Network connectivity (Kimi requires API access)
- Authentication status (
kimi login) - The provider waits up to 120 seconds for initialization
The provider checks the bottom 50 lines for the idle prompt (IDLE_PROMPT_TAIL_LINES = 50). This accounts for Kimi's TUI padding lines between the prompt and the status bar, which varies with terminal height (e.g., a 46-row terminal has ~32 empty padding lines). If Kimi's TUI layout changes significantly, this constant may need adjustment.