kimi-cli 0.35__py3-none-any.whl → 0.52__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. kimi_cli/CHANGELOG.md +165 -0
  2. kimi_cli/__init__.py +0 -374
  3. kimi_cli/agents/{koder → default}/agent.yaml +1 -1
  4. kimi_cli/agents/{koder → default}/system.md +1 -1
  5. kimi_cli/agentspec.py +115 -0
  6. kimi_cli/app.py +208 -0
  7. kimi_cli/cli.py +321 -0
  8. kimi_cli/config.py +33 -16
  9. kimi_cli/constant.py +4 -0
  10. kimi_cli/exception.py +16 -0
  11. kimi_cli/llm.py +144 -3
  12. kimi_cli/metadata.py +6 -69
  13. kimi_cli/prompts/__init__.py +4 -0
  14. kimi_cli/session.py +103 -0
  15. kimi_cli/soul/__init__.py +130 -9
  16. kimi_cli/soul/agent.py +159 -0
  17. kimi_cli/soul/approval.py +5 -6
  18. kimi_cli/soul/compaction.py +106 -0
  19. kimi_cli/soul/context.py +1 -1
  20. kimi_cli/soul/kimisoul.py +180 -80
  21. kimi_cli/soul/message.py +6 -6
  22. kimi_cli/soul/runtime.py +96 -0
  23. kimi_cli/soul/toolset.py +3 -2
  24. kimi_cli/tools/__init__.py +35 -31
  25. kimi_cli/tools/bash/__init__.py +25 -9
  26. kimi_cli/tools/bash/cmd.md +31 -0
  27. kimi_cli/tools/dmail/__init__.py +5 -4
  28. kimi_cli/tools/file/__init__.py +8 -0
  29. kimi_cli/tools/file/glob.md +1 -1
  30. kimi_cli/tools/file/glob.py +4 -4
  31. kimi_cli/tools/file/grep.py +36 -19
  32. kimi_cli/tools/file/patch.py +52 -10
  33. kimi_cli/tools/file/read.py +6 -5
  34. kimi_cli/tools/file/replace.py +16 -4
  35. kimi_cli/tools/file/write.py +16 -4
  36. kimi_cli/tools/mcp.py +7 -4
  37. kimi_cli/tools/task/__init__.py +60 -41
  38. kimi_cli/tools/task/task.md +1 -1
  39. kimi_cli/tools/todo/__init__.py +4 -2
  40. kimi_cli/tools/utils.py +1 -1
  41. kimi_cli/tools/web/fetch.py +2 -1
  42. kimi_cli/tools/web/search.py +13 -12
  43. kimi_cli/ui/__init__.py +0 -68
  44. kimi_cli/ui/acp/__init__.py +67 -38
  45. kimi_cli/ui/print/__init__.py +46 -69
  46. kimi_cli/ui/shell/__init__.py +145 -154
  47. kimi_cli/ui/shell/console.py +27 -1
  48. kimi_cli/ui/shell/debug.py +187 -0
  49. kimi_cli/ui/shell/keyboard.py +183 -0
  50. kimi_cli/ui/shell/metacmd.py +34 -81
  51. kimi_cli/ui/shell/prompt.py +245 -28
  52. kimi_cli/ui/shell/replay.py +104 -0
  53. kimi_cli/ui/shell/setup.py +19 -19
  54. kimi_cli/ui/shell/update.py +11 -5
  55. kimi_cli/ui/shell/visualize.py +576 -0
  56. kimi_cli/ui/wire/README.md +109 -0
  57. kimi_cli/ui/wire/__init__.py +340 -0
  58. kimi_cli/ui/wire/jsonrpc.py +48 -0
  59. kimi_cli/utils/__init__.py +0 -0
  60. kimi_cli/utils/aiohttp.py +10 -0
  61. kimi_cli/utils/changelog.py +6 -2
  62. kimi_cli/utils/clipboard.py +10 -0
  63. kimi_cli/utils/message.py +15 -1
  64. kimi_cli/utils/rich/__init__.py +33 -0
  65. kimi_cli/utils/rich/markdown.py +959 -0
  66. kimi_cli/utils/rich/markdown_sample.md +108 -0
  67. kimi_cli/utils/rich/markdown_sample_short.md +2 -0
  68. kimi_cli/utils/signals.py +41 -0
  69. kimi_cli/utils/string.py +8 -0
  70. kimi_cli/utils/term.py +114 -0
  71. kimi_cli/wire/__init__.py +73 -0
  72. kimi_cli/wire/message.py +191 -0
  73. kimi_cli-0.52.dist-info/METADATA +186 -0
  74. kimi_cli-0.52.dist-info/RECORD +99 -0
  75. kimi_cli-0.52.dist-info/entry_points.txt +3 -0
  76. kimi_cli/agent.py +0 -261
  77. kimi_cli/agents/koder/README.md +0 -3
  78. kimi_cli/prompts/metacmds/__init__.py +0 -4
  79. kimi_cli/soul/wire.py +0 -101
  80. kimi_cli/ui/shell/liveview.py +0 -158
  81. kimi_cli/utils/provider.py +0 -64
  82. kimi_cli-0.35.dist-info/METADATA +0 -24
  83. kimi_cli-0.35.dist-info/RECORD +0 -76
  84. kimi_cli-0.35.dist-info/entry_points.txt +0 -3
  85. /kimi_cli/agents/{koder → default}/sub.yaml +0 -0
  86. /kimi_cli/prompts/{metacmds/compact.md → compact.md} +0 -0
  87. /kimi_cli/prompts/{metacmds/init.md → init.md} +0 -0
  88. {kimi_cli-0.35.dist-info → kimi_cli-0.52.dist-info}/WHEEL +0 -0
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.3
2
+ Name: kimi-cli
3
+ Version: 0.52
4
+ Summary: Kimi CLI is your next CLI agent.
5
+ Requires-Dist: agent-client-protocol==0.6.3
6
+ Requires-Dist: aiofiles==25.1.0
7
+ Requires-Dist: aiohttp==3.13.2
8
+ Requires-Dist: typer==0.20.0
9
+ Requires-Dist: kosong==0.22.0
10
+ Requires-Dist: loguru==0.7.3
11
+ Requires-Dist: patch-ng==1.19.0
12
+ Requires-Dist: prompt-toolkit==3.0.52
13
+ Requires-Dist: pillow==12.0.0
14
+ Requires-Dist: pyyaml==6.0.3
15
+ Requires-Dist: rich==14.2.0
16
+ Requires-Dist: ripgrepy==2.2.0
17
+ Requires-Dist: streamingjson==0.0.5
18
+ Requires-Dist: trafilatura==2.0.0
19
+ Requires-Dist: tenacity==9.1.2
20
+ Requires-Dist: fastmcp==2.12.5
21
+ Requires-Dist: pydantic==2.12.4
22
+ Requires-Dist: httpx[socks]==0.28.1
23
+ Requires-Python: >=3.13
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Kimi CLI
27
+
28
+ [![Commit Activity](https://img.shields.io/github/commit-activity/w/MoonshotAI/kimi-cli)](https://github.com/MoonshotAI/kimi-cli/graphs/commit-activity)
29
+ [![Checks](https://img.shields.io/github/check-runs/MoonshotAI/kimi-cli/main)](https://github.com/MoonshotAI/kimi-cli/actions)
30
+ [![Version](https://img.shields.io/pypi/v/kimi-cli)](https://pypi.org/project/kimi-cli/)
31
+ [![Downloads](https://img.shields.io/pypi/dw/kimi-cli)](https://pypistats.org/packages/kimi-cli)
32
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/MoonshotAI/kimi-cli)
33
+
34
+ [中文](https://www.kimi.com/coding/docs/kimi-cli.html)
35
+
36
+ Kimi CLI is a new CLI agent that can help you with your software development tasks and terminal operations.
37
+
38
+ > [!IMPORTANT]
39
+ > Kimi CLI is currently in technical preview.
40
+
41
+ ## Key features
42
+
43
+ - Shell-like UI and shell command execution
44
+ - Zsh integration
45
+ - [Agent Client Protocol] support
46
+ - MCP support
47
+ - And more to come...
48
+
49
+ [Agent Client Protocol]: https://github.com/agentclientprotocol/agent-client-protocol
50
+
51
+ ## Installation
52
+
53
+ Kimi CLI is published as a Python package on PyPI. We highly recommend installing it with [uv](https://docs.astral.sh/uv/). If you have not installed uv yet, please follow the instructions [here](https://docs.astral.sh/uv/getting-started/installation/) to install it first.
54
+
55
+ Once uv is installed, you can install Kimi CLI with:
56
+
57
+ ```sh
58
+ uv tool install --python 3.13 kimi-cli
59
+ ```
60
+
61
+ Run `kimi --help` to check if Kimi CLI is installed successfully.
62
+
63
+ > [!IMPORTANT]
64
+ > Due to the security checks on macOS, the first time you run `kimi` command may take 10 seconds or more depending on your system environment.
65
+
66
+ ## Upgrading
67
+
68
+ Upgrade Kimi CLI to the latest version with:
69
+
70
+ ```sh
71
+ uv tool upgrade kimi-cli --no-cache
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ Run `kimi` command in the directory you want to work on, then send `/setup` to setup Kimi CLI:
77
+
78
+ ![](./docs/images/setup.png)
79
+
80
+ After setup, Kimi CLI will be ready to use. You can send `/help` to get more information.
81
+
82
+ ## Features
83
+
84
+ ### Shell mode
85
+
86
+ Kimi CLI is not only a coding agent, but also a shell. You can switch the mode by pressing `Ctrl-X`. In shell mode, you can directly run shell commands without leaving Kimi CLI.
87
+
88
+ > [!NOTE]
89
+ > Built-in shell commands like `cd` are not supported yet.
90
+
91
+ ### Zsh integration
92
+
93
+ You can use Kimi CLI together with Zsh, to empower your shell experience with AI agent capabilities.
94
+
95
+ Install the [zsh-kimi-cli](https://github.com/MoonshotAI/zsh-kimi-cli) plugin via:
96
+
97
+ ```sh
98
+ git clone https://github.com/MoonshotAI/zsh-kimi-cli.git \
99
+ ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/kimi-cli
100
+ ```
101
+
102
+ > [!NOTE]
103
+ > If you are using a plugin manager other than Oh My Zsh, you may need to refer to the plugin's README for installation instructions.
104
+
105
+ Then add `kimi-cli` to your Zsh plugin list in `~/.zshrc`:
106
+
107
+ ```sh
108
+ plugins=(... kimi-cli)
109
+ ```
110
+
111
+ After restarting Zsh, you can switch to agent mode by pressing `Ctrl-X`.
112
+
113
+ ### ACP support
114
+
115
+ Kimi CLI supports [Agent Client Protocol] out of the box. You can use it together with any ACP-compatible editor or IDE.
116
+
117
+ For example, to use Kimi CLI with [Zed](https://zed.dev/), add the following configuration to your `~/.config/zed/settings.json`:
118
+
119
+ ```json
120
+ {
121
+ "agent_servers": {
122
+ "Kimi CLI": {
123
+ "command": "kimi",
124
+ "args": ["--acp"],
125
+ "env": {}
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ Then you can create Kimi CLI threads in Zed's agent panel.
132
+
133
+ ### Using MCP tools
134
+
135
+ Kimi CLI supports the well-established MCP config convention. For example:
136
+
137
+ ```json
138
+ {
139
+ "mcpServers": {
140
+ "context7": {
141
+ "url": "https://mcp.context7.com/mcp",
142
+ "headers": {
143
+ "CONTEXT7_API_KEY": "YOUR_API_KEY"
144
+ }
145
+ },
146
+ "chrome-devtools": {
147
+ "command": "npx",
148
+ "args": ["-y", "chrome-devtools-mcp@latest"]
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
154
+ Run `kimi` with `--mcp-config-file` option to connect to the specified MCP servers:
155
+
156
+ ```sh
157
+ kimi --mcp-config-file /path/to/mcp.json
158
+ ```
159
+
160
+ ## Development
161
+
162
+ To develop Kimi CLI, run:
163
+
164
+ ```sh
165
+ git clone https://github.com/MoonshotAI/kimi-cli.git
166
+ cd kimi-cli
167
+
168
+ make prepare # prepare the development environment
169
+ ```
170
+
171
+ Then you can start working on Kimi CLI.
172
+
173
+ Refer to the following commands after you make changes:
174
+
175
+ ```sh
176
+ uv run kimi # run Kimi CLI
177
+
178
+ make format # format code
179
+ make check # run linting and type checking
180
+ make test # run tests
181
+ make help # show all make targets
182
+ ```
183
+
184
+ ## Contributing
185
+
186
+ We welcome contributions to Kimi CLI! Please refer to [CONTRIBUTING.md](./CONTRIBUTING.md) for more information.
@@ -0,0 +1,99 @@
1
+ kimi_cli/CHANGELOG.md,sha256=cc0250bcf4e0ef66c39068a33440df96190cae22b740ce43273cb98f3829b9cc,10268
2
+ kimi_cli/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
3
+ kimi_cli/agents/default/agent.yaml,sha256=6e5c51987ef5cfc0c4c4e34cc20b6fc975953ee219623fccae81a19155aab7b3,709
4
+ kimi_cli/agents/default/sub.yaml,sha256=e0c1ea34fdb04b0d6dc635709f0f130aff25d7f9fb97e238470143c8145be251,634
5
+ kimi_cli/agents/default/system.md,sha256=1d8fd4956b2442215396b5e9651771c9da8f9505ccbd3b6d5e91b1ac4ff35418,5001
6
+ kimi_cli/agentspec.py,sha256=1148b5184ca610b2fb261ce365a63eb2fc9d09497330fe0ea4b2567fc98d5657,4307
7
+ kimi_cli/app.py,sha256=f2e5607329ee90636f7ff08876d3be3c3fa5234220586049c89c6172461d6e8a,7495
8
+ kimi_cli/cli.py,sha256=a565cbf6529baa59729c629ab3b8a2e12a3c1e2476733b93859a986a9b4182fd,9094
9
+ kimi_cli/config.py,sha256=db5f038c00920be9e10ad30bdecd4cb6be4b77de22845423a83c974e14f67dfc,4962
10
+ kimi_cli/constant.py,sha256=78e25b9304cca7b6f70bb08bf0e1fee4b066297a05386e56dd6935ba42027cd9,110
11
+ kimi_cli/exception.py,sha256=a3fec07566da7d2d34be8cc454fb825f34109bbde3cddf69e1ece6ab21b4b219,259
12
+ kimi_cli/llm.py,sha256=0502113bc3830cffb4334342c775a5588bfd7323b2b46de3d6a3d526e812f5ea,5283
13
+ kimi_cli/metadata.py,sha256=bde1e7eaa3d9c27a83cdeaf5506fe384290fb1b5d094f0fe9bb182cbbfec6b1f,1573
14
+ kimi_cli/prompts/__init__.py,sha256=6dc5ed2d841f145c09550075f30853cdc51f00d2f5d9aa1097f8edea770536e7,174
15
+ kimi_cli/prompts/compact.md,sha256=6655bd7d8270b24d8f97b51ef7c471cf71d686c56f8ec9a5cc9e47caa3aae87c,1877
16
+ kimi_cli/prompts/init.md,sha256=d271a0df6dd7b330ffec4f645a74c0392dafc1b3bfc1e3f2a77624e96cf6abbe,1380
17
+ kimi_cli/py.typed,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
18
+ kimi_cli/session.py,sha256=a5ec3caa828428dd65fe6cb540cee1768a4def33a84a2f42d4744711e7bf550e,3681
19
+ kimi_cli/share.py,sha256=4292df7f44177419c45c772a933b5f36e2b7533f8cef9842629a438bc7856dc0,204
20
+ kimi_cli/soul/__init__.py,sha256=7183fea252b68dcddf710ec292419fb7c53bb163a30525f0331f43a8541826ca,5792
21
+ kimi_cli/soul/agent.py,sha256=6d44374a884b0f8e5075337188c59be8cd820f635fbb6195c5d4099a65d05206,5025
22
+ kimi_cli/soul/approval.py,sha256=48cd230dff81dfd70bd85f1ad2b99604d5569cf617a4c79c444f9772bbc89ce6,2552
23
+ kimi_cli/soul/compaction.py,sha256=e38e5386fec2c236a1960a3814611cb093bd2e10645759961f2ef47b5d3747d0,3594
24
+ kimi_cli/soul/context.py,sha256=8ae001e6fc0229ccf74c94f1aadfbef90a48d8eb0a78b9113ed720d32b5e543f,5850
25
+ kimi_cli/soul/denwarenji.py,sha256=66b95f052a1fa844e2347972d34e1916a7be24d3e493701b451f5380b0375c9f,1384
26
+ kimi_cli/soul/kimisoul.py,sha256=80b9cbc8bb8d2a017631bc639886f0b2da96f56fb24f0182b0c5e1f76c298a6d,12889
27
+ kimi_cli/soul/message.py,sha256=ed31c9eecfe83a5d363327e0c91c74ef66106faf741c3892a0826d9226faf674,2536
28
+ kimi_cli/soul/runtime.py,sha256=9421a3ce6882587a95ecdf77b3d75f3b7ecab55cf68dc57e3e563b93e5a02e46,2690
29
+ kimi_cli/soul/toolset.py,sha256=9eda995fbbf18a17855ac15a83b28d3af88d34fc64efbac0674a2bf2221b52fc,772
30
+ kimi_cli/tools/__init__.py,sha256=ab932d54793212c7036a29e1fa54b4f763349b450f0ab4da3108a2b2b3646068,3432
31
+ kimi_cli/tools/bash/__init__.py,sha256=6302aad1ca202a633ea68ffa0dfac0de407966b5b3bb4ba5757e15915fd09ca4,3489
32
+ kimi_cli/tools/bash/bash.md,sha256=5d9cc54b3718097951340b0a737c8e1fa308341fd2c4ebd121be94de31dd5f73,2348
33
+ kimi_cli/tools/bash/cmd.md,sha256=af5a0042ba2e2373078427f14f078205a51585f888f3744af5280fb23c0ab45a,2603
34
+ kimi_cli/tools/dmail/__init__.py,sha256=a33270355aee9d8acae93aeb5cf51bcff5018607b8be79ed579619f058e7826c,1326
35
+ kimi_cli/tools/dmail/dmail.md,sha256=0d18cae387dd52127ddc99e296253c09e68ccba5f343153c0adbe77d7586e759,1912
36
+ kimi_cli/tools/file/__init__.py,sha256=1516fb4c71097f9c14b605e7b9a1872af8786bdcb48323d1fa83bb1419436abb,546
37
+ kimi_cli/tools/file/glob.md,sha256=11fbfaf6033f57b69c6f91077ddd90505036937cd7217600d96992b9a48b7ca7,1400
38
+ kimi_cli/tools/file/glob.py,sha256=a95f0f502fe6458f8c21a7aa5f15e27828993b05fed83b83f8a7c0dc9c50a48b,5431
39
+ kimi_cli/tools/file/grep.md,sha256=12353db42cf3b5d9d91ac7c0f0b9c2a732e8b050c23a78f4e668db823cca4d50,245
40
+ kimi_cli/tools/file/grep.py,sha256=269f106bac7a3ab95f395a1e8233b45a104bcc11fc0a90a8f2beac08ef06588b,10710
41
+ kimi_cli/tools/file/patch.md,sha256=f9edbed6c6a03bf7448a51acc1f42622395fd7f1674a814e9a3b2302d3b7b92e,404
42
+ kimi_cli/tools/file/patch.py,sha256=7f96b7735609d183d54136adde8fd05352f20d865c2aebc640173c492d5257ab,6624
43
+ kimi_cli/tools/file/read.md,sha256=4c2d83e557daadc0612fb1a613e252b2c8e4df7ae57e6db094e9e75e994cb23b,1066
44
+ kimi_cli/tools/file/read.py,sha256=76ea260a813a987a4e34706f6cc3c2b77fc3f31a76831883caa91f9ab86df6a6,5109
45
+ kimi_cli/tools/file/replace.md,sha256=f429f263fa580f2f6107907a33ba8800dcdbd4fc1d9ff8dc4f858bd76ec6bbc6,267
46
+ kimi_cli/tools/file/replace.py,sha256=d2dd7381e004d0539a8cc0b6fa294aaed879d6ff18dde81dc0f4837b7c46c220,5206
47
+ kimi_cli/tools/file/write.md,sha256=f37b0f4742da57797ec4dd29fbd4fdc9b6617c6be644724a3b16d651c6129cec,324
48
+ kimi_cli/tools/file/write.py,sha256=ce40a695be5d45fc725545ec7134f0b963c7ddda0084e6ba59a0ac0d6d465d26,4380
49
+ kimi_cli/tools/mcp.py,sha256=68c307e702a61737ec7d761a273abb74261a57925d50ffa59fbd2db1b2037dc4,3731
50
+ kimi_cli/tools/task/__init__.py,sha256=7a57f159bc0775fbc9b2ebb18c2cf8b973a4e0c82eb298225d9f78f4628f0ea9,6927
51
+ kimi_cli/tools/task/task.md,sha256=391cc3553c7d310a323626bae180dd41cb810fb1233583713ebde105f954147a,2280
52
+ kimi_cli/tools/test.py,sha256=c094a91a2d1a5259e192f1147facd5eebd5e5c413787fce167db90e4b41b5119,1442
53
+ kimi_cli/tools/think/__init__.py,sha256=31b06088e2404cb09d42e0acec97c185e4861890bb687f28b41f39cea01b5733,603
54
+ kimi_cli/tools/think/think.md,sha256=ab40d4de1d8adb208384a4ab548e35776283cb0a681c6e208b041fc40ccba724,200
55
+ kimi_cli/tools/todo/__init__.py,sha256=2ea7deb0c06c97e200ccbb4c9b1e8cf0eb440ca8b0e87167204dcd41df0715fc,961
56
+ kimi_cli/tools/todo/set_todo_list.md,sha256=89509503f43ab321d440a04dc133ddc3e29859f68907a42c39e6093f7bfd485c,1654
57
+ kimi_cli/tools/utils.py,sha256=2e00d6f04f91e05a91bfb691e547a76193063fa6769a03f7d3ff992aba9372bf,4596
58
+ kimi_cli/tools/web/__init__.py,sha256=e13108c598828a8a05907a7a821e7ac92f5d63572bb9866dc12ca026094acb42,95
59
+ kimi_cli/tools/web/fetch.md,sha256=56d00bd93b4e379c4f7efe445fce963eb26b8d20f85d4c19097ba6f33bd0019a,67
60
+ kimi_cli/tools/web/fetch.py,sha256=66448121d27d67f75b977c32244c721c2ccff1b2e097c2fe6717e66018d8f747,3183
61
+ kimi_cli/tools/web/search.md,sha256=24049f9e90d37083e0fc78b8b2e3a5f6fadf09bea00f36712b235d1212a2f532,146
62
+ kimi_cli/tools/web/search.py,sha256=8f757f1eb83a878bd2a9d8c3d0c137c244c2a1314b5de8d2a55da5261773b162,4469
63
+ kimi_cli/ui/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
64
+ kimi_cli/ui/acp/__init__.py,sha256=bfcdd6e32ed84b710b3c5034edcfdd1cad3141dfee649a29601c8c955968d4ca,18294
65
+ kimi_cli/ui/print/__init__.py,sha256=8c55a2a9ee8382544b24da90a286a7611e0ebd706cdc98aeb42059635f4cc0e6,5541
66
+ kimi_cli/ui/shell/__init__.py,sha256=bc209f41d2c3e5da4a4442e9f84002f34be1c12256182786c99e02cc05a7d0d2,12125
67
+ kimi_cli/ui/shell/console.py,sha256=bcbf7efd214cba3d2259f2a2c1842250cde96d49e4f9f1e0b60273cf1c366be3,842
68
+ kimi_cli/ui/shell/debug.py,sha256=b6d7f5475580814bc3dc34abdc472e5bd2c06368e88cae517de1bacc343af9bf,5557
69
+ kimi_cli/ui/shell/keyboard.py,sha256=23e5fbc4b6acda4c0f3b5297a0ae6eb09a90f4b5b37b2e95b7ce86a2da0d5dca,5160
70
+ kimi_cli/ui/shell/metacmd.py,sha256=85f09997bc40279029ada6a12819d4edb4fb7d0ccac5e535d385257bb7e14347,7649
71
+ kimi_cli/ui/shell/prompt.py,sha256=c078b7071a114e0869f655e90258f78bbffa80c70da7dc36164bde6921a8a76c,26697
72
+ kimi_cli/ui/shell/replay.py,sha256=dfc50d6721dbd43566683f224c6df3b7c6e8f0ea06a726a1e4f3139fdb102227,3762
73
+ kimi_cli/ui/shell/setup.py,sha256=6270ea039ebffbe11834e73a5c6f895d46c76d2460760bc5bec2741062f6a6fb,5258
74
+ kimi_cli/ui/shell/update.py,sha256=56dcb0bd1da82b98c22bfdddca717a2805bd8ac3e93bf23fb3b508549c41fae8,7340
75
+ kimi_cli/ui/shell/visualize.py,sha256=fa425172f252d4bf4b05fa515fff0e87559d9d10590b4a33c6b8b9a72d24cb87,21531
76
+ kimi_cli/ui/wire/README.md,sha256=0d9beaf38d4f4f1777013e85445e615fcacfe3a169d11151c42a141dec6196bd,4849
77
+ kimi_cli/ui/wire/__init__.py,sha256=9252f53cd32b5a114afdbc402817a627818a48897554977908b5c5e64864801e,11932
78
+ kimi_cli/ui/wire/jsonrpc.py,sha256=c093a540e70026cb48eae494cf4c8ad04f1180338eaaad0a23d64798bb679944,995
79
+ kimi_cli/utils/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
80
+ kimi_cli/utils/aiohttp.py,sha256=f8f61e3beaf6439e949c33c3a10db3035bf88136e882b09c858ea92a4c888e00,245
81
+ kimi_cli/utils/changelog.py,sha256=8079109bae377c141d8f50b8ea5e5c2f1e44a6a70c0dcfb9987b3b480283ed9b,3536
82
+ kimi_cli/utils/clipboard.py,sha256=81944e1ba313c8784e513b10e2a0bb759ac5acd4ee27cb335c876e5e93bb8fe6,212
83
+ kimi_cli/utils/logging.py,sha256=129298ac214ecd8d913c3431cc05d754f9c4c8c4042c458618bf9e8ddebdb763,399
84
+ kimi_cli/utils/message.py,sha256=e2ed32c5cac8e2c637fc9ea89c6643fd80a06e211b68d126312e4118b94b2d06,727
85
+ kimi_cli/utils/path.py,sha256=fdd4fc08999ddc7c610f884b4ba8d27932248b9ed06b5eb4139519edd00b3f75,687
86
+ kimi_cli/utils/pyinstaller.py,sha256=e5d709d0490ef8645bbed2d2363920c59f25bd17c04f471bf4a8c0fa2ebe1801,581
87
+ kimi_cli/utils/rich/__init__.py,sha256=2cb421c8491bd11aa2360119f88a4788337fc9884aba05d6400761a0e24c4c2b,909
88
+ kimi_cli/utils/rich/markdown.py,sha256=e81efafad7e82d52fab7d0d873d81c829054dd6c147c385b02ae91f9d8de4f92,33863
89
+ kimi_cli/utils/rich/markdown_sample.md,sha256=2b04c7ad3eadca4bff61e5ccf4d9f2bc400110867afbce190e671ef3ff28007c,1792
90
+ kimi_cli/utils/rich/markdown_sample_short.md,sha256=52f9186332bd41e0e84586c7025c3e69df69cf406add8e71d2413735aeb8aa24,17
91
+ kimi_cli/utils/signals.py,sha256=20e0d158a1043189d44815fe3624cd0bfe41e99620a18ac9e12c0eda6db5220f,1387
92
+ kimi_cli/utils/string.py,sha256=0d437d3633199df1051813af8b49a2f808c6525547310cc5c3d427710d2eae06,593
93
+ kimi_cli/utils/term.py,sha256=89dc154e08730c56b2a69c8a2073a76b9736841b56bebc2b30a7bd1d0723c8f5,3049
94
+ kimi_cli/wire/__init__.py,sha256=86e62344d4a56a4979eb08f5b62c74aeb858a4b0ef54bfc2ec8b095eb7fe1b49,2037
95
+ kimi_cli/wire/message.py,sha256=826d21d7c2aca32124449b50d6352b880edbf517e87173441d4d38d6700f915f,5573
96
+ kimi_cli-0.52.dist-info/WHEEL,sha256=70ab3c2925fe316809860cb034f99ba13c4b49819b339959274aab755cc084a8,78
97
+ kimi_cli-0.52.dist-info/entry_points.txt,sha256=4a8d437328d2f5f95fd5b718206f7c249c99542444c452d9b45befef1bd58b62,43
98
+ kimi_cli-0.52.dist-info/METADATA,sha256=ea845873311442b649724a6878df8f3cc87c49d231ee8257c46d8c7139241a2b,5206
99
+ kimi_cli-0.52.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ kimi = kimi_cli.cli:cli
3
+
kimi_cli/agent.py DELETED
@@ -1,261 +0,0 @@
1
- import importlib
2
- import inspect
3
- import string
4
- from pathlib import Path
5
- from typing import Any, NamedTuple
6
-
7
- import fastmcp
8
- import yaml
9
- from kosong.tooling import Toolset
10
- from kosong.tooling.simple import ToolType
11
- from pydantic import BaseModel, Field
12
-
13
- from kimi_cli.config import Config
14
- from kimi_cli.llm import LLM
15
- from kimi_cli.metadata import Session
16
- from kimi_cli.soul.approval import Approval
17
- from kimi_cli.soul.denwarenji import DenwaRenji
18
- from kimi_cli.soul.toolset import CustomToolset
19
- from kimi_cli.tools.mcp import MCPTool
20
- from kimi_cli.utils.logging import logger
21
-
22
-
23
- class AgentSpec(BaseModel):
24
- """Agent specification."""
25
-
26
- extend: str | None = Field(default=None, description="Agent file to extend")
27
- name: str | None = Field(default=None, description="Agent name") # required
28
- system_prompt_path: Path | None = Field(
29
- default=None, description="System prompt path"
30
- ) # required
31
- system_prompt_args: dict[str, str] = Field(
32
- default_factory=dict, description="System prompt arguments"
33
- )
34
- tools: list[str] | None = Field(default=None, description="Tools") # required
35
- exclude_tools: list[str] | None = Field(default=None, description="Tools to exclude")
36
- subagents: dict[str, "SubagentSpec"] | None = Field(default=None, description="Subagents")
37
-
38
-
39
- class SubagentSpec(BaseModel):
40
- """Subagent specification."""
41
-
42
- path: Path = Field(description="Subagent file path")
43
- description: str = Field(description="Subagent description")
44
-
45
-
46
- class BuiltinSystemPromptArgs(NamedTuple):
47
- """Builtin system prompt arguments."""
48
-
49
- KIMI_NOW: str
50
- """The current datetime."""
51
- KIMI_WORK_DIR: Path
52
- """The current working directory."""
53
- KIMI_WORK_DIR_LS: str
54
- """The `ls -la` output of current working directory."""
55
- KIMI_AGENTS_MD: str # TODO: move to first message from system prompt
56
- """The content of AGENTS.md."""
57
-
58
-
59
- class AgentGlobals(NamedTuple):
60
- """Agent globals."""
61
-
62
- config: Config
63
- llm: LLM | None
64
- builtin_args: BuiltinSystemPromptArgs
65
- denwa_renji: DenwaRenji
66
- session: Session
67
- approval: Approval
68
-
69
-
70
- class Agent(NamedTuple):
71
- """The loaded agent."""
72
-
73
- name: str
74
- system_prompt: str
75
- toolset: Toolset
76
-
77
-
78
- def get_agents_dir() -> Path:
79
- return Path(__file__).parent / "agents"
80
-
81
-
82
- DEFAULT_AGENT_FILE = get_agents_dir() / "koder" / "agent.yaml"
83
-
84
-
85
- async def load_agent_with_mcp(
86
- agent_file: Path,
87
- globals_: AgentGlobals,
88
- mcp_configs: list[dict[str, Any]],
89
- ) -> Agent:
90
- agent = load_agent(agent_file, globals_)
91
- assert isinstance(agent.toolset, CustomToolset)
92
- if mcp_configs:
93
- await _load_mcp_tools(agent.toolset, mcp_configs)
94
- return agent
95
-
96
-
97
- def load_agent(
98
- agent_file: Path,
99
- globals_: AgentGlobals,
100
- ) -> Agent:
101
- """
102
- Load agent from specification file.
103
-
104
- Raises:
105
- ValueError: If the agent spec is not valid.
106
- """
107
- agent_spec = _load_agent_spec(agent_file)
108
- assert agent_spec.extend is None, "agent extension should be recursively resolved"
109
- if agent_spec.name is None:
110
- raise ValueError("Agent name is required")
111
- if agent_spec.system_prompt_path is None:
112
- raise ValueError("System prompt path is required")
113
- if agent_spec.tools is None:
114
- raise ValueError("Tools are required")
115
-
116
- system_prompt = _load_system_prompt(
117
- agent_spec.system_prompt_path, agent_spec.system_prompt_args, globals_.builtin_args
118
- )
119
-
120
- tool_deps = {
121
- AgentSpec: agent_spec,
122
- AgentGlobals: globals_,
123
- Config: globals_.config,
124
- BuiltinSystemPromptArgs: globals_.builtin_args,
125
- Session: globals_.session,
126
- DenwaRenji: globals_.denwa_renji,
127
- Approval: globals_.approval,
128
- }
129
- tools = agent_spec.tools
130
- if agent_spec.exclude_tools:
131
- logger.debug("Excluding tools: {tools}", tools=agent_spec.exclude_tools)
132
- tools = [tool for tool in tools if tool not in agent_spec.exclude_tools]
133
- toolset = CustomToolset()
134
- bad_tools = _load_tools(toolset, tools, tool_deps)
135
- if bad_tools:
136
- raise ValueError(f"Invalid tools: {bad_tools}")
137
-
138
- return Agent(
139
- name=agent_spec.name,
140
- system_prompt=system_prompt,
141
- toolset=toolset,
142
- )
143
-
144
-
145
- def _load_agent_spec(agent_file: Path) -> AgentSpec:
146
- assert agent_file.is_file(), "expect agent file to exist"
147
- with open(agent_file, encoding="utf-8") as f:
148
- data: dict[str, Any] = yaml.safe_load(f)
149
-
150
- version = data.get("version", 1)
151
- if version != 1:
152
- raise ValueError(f"Unsupported agent spec version: {version}")
153
-
154
- agent_spec = AgentSpec(**data.get("agent", {}))
155
- if agent_spec.system_prompt_path is not None:
156
- agent_spec.system_prompt_path = agent_file.parent / agent_spec.system_prompt_path
157
- if agent_spec.subagents is not None:
158
- for v in agent_spec.subagents.values():
159
- v.path = agent_file.parent / v.path
160
- if agent_spec.extend:
161
- if agent_spec.extend == "default":
162
- base_agent_file = DEFAULT_AGENT_FILE
163
- else:
164
- base_agent_file = agent_file.parent / agent_spec.extend
165
- base_agent_spec = _load_agent_spec(base_agent_file)
166
- if agent_spec.name is not None:
167
- base_agent_spec.name = agent_spec.name
168
- if agent_spec.system_prompt_path is not None:
169
- base_agent_spec.system_prompt_path = agent_spec.system_prompt_path
170
- for k, v in agent_spec.system_prompt_args.items():
171
- base_agent_spec.system_prompt_args[k] = v
172
- if agent_spec.tools is not None:
173
- base_agent_spec.tools = agent_spec.tools
174
- if agent_spec.exclude_tools is not None:
175
- base_agent_spec.exclude_tools = agent_spec.exclude_tools
176
- if agent_spec.subagents is not None:
177
- base_agent_spec.subagents = agent_spec.subagents
178
- agent_spec = base_agent_spec
179
- return agent_spec
180
-
181
-
182
- def _load_system_prompt(
183
- path: Path, args: dict[str, str], builtin_args: BuiltinSystemPromptArgs
184
- ) -> str:
185
- system_prompt = path.read_text().strip()
186
- logger.debug(
187
- "Substituting system prompt with builtin args: {builtin_args}, spec args: {spec_args}",
188
- builtin_args=builtin_args,
189
- spec_args=args,
190
- )
191
- return string.Template(system_prompt).substitute(builtin_args._asdict(), **args)
192
-
193
-
194
- def _load_tools(
195
- toolset: CustomToolset,
196
- tool_paths: list[str],
197
- dependencies: dict[type[Any], Any],
198
- ) -> list[str]:
199
- bad_tools = []
200
- for tool_path in tool_paths:
201
- tool = _load_tool(tool_path, dependencies)
202
- if tool:
203
- toolset += tool
204
- else:
205
- bad_tools.append(tool_path)
206
- logger.debug("Loaded tools: {tools}", tools=toolset.tools)
207
- if bad_tools:
208
- logger.error("Bad tools: {bad_tools}", bad_tools=bad_tools)
209
- return bad_tools
210
-
211
-
212
- def _load_tool(tool_path: str, dependencies: dict[type[Any], Any]) -> ToolType | None:
213
- logger.debug("Loading tool: {tool_path}", tool_path=tool_path)
214
- module_name, class_name = tool_path.rsplit(":", 1)
215
- try:
216
- module = importlib.import_module(module_name)
217
- except ImportError:
218
- return None
219
- cls = getattr(module, class_name, None)
220
- if cls is None:
221
- return None
222
- args = []
223
- for param in inspect.signature(cls).parameters.values():
224
- if param.kind == inspect.Parameter.KEYWORD_ONLY:
225
- # once we encounter a keyword-only parameter, we stop injecting dependencies
226
- break
227
- # all positional parameters should be dependencies to be injected
228
- if param.annotation not in dependencies:
229
- raise ValueError(f"Tool dependency not found: {param.annotation}")
230
- args.append(dependencies[param.annotation])
231
- return cls(*args)
232
-
233
-
234
- async def _load_mcp_tools(
235
- toolset: CustomToolset,
236
- mcp_configs: list[dict[str, Any]],
237
- ):
238
- """
239
- Raises:
240
- ValueError: If the MCP config is not valid.
241
- RuntimeError: If the MCP server cannot be connected.
242
- """
243
- for mcp_config in mcp_configs:
244
- client = fastmcp.Client(mcp_config)
245
- async with client:
246
- for tool in await client.list_tools():
247
- toolset += MCPTool(tool, client)
248
- return toolset
249
-
250
-
251
- def load_agents_md(work_dir: Path) -> str | None:
252
- paths = [
253
- work_dir / "AGENTS.md",
254
- work_dir / "agents.md",
255
- ]
256
- for path in paths:
257
- if path.is_file():
258
- logger.debug("Loaded agents.md: {path}", path=path)
259
- return path.read_text().strip()
260
- logger.debug("No AGENTS.md found")
261
- return None
@@ -1,3 +0,0 @@
1
- # Kimi Koder
2
-
3
- Kimi Koder is a CLI agent that can help you with your software development tasks.
@@ -1,4 +0,0 @@
1
- from pathlib import Path
2
-
3
- INIT = (Path(__file__).parent / "init.md").read_text()
4
- COMPACT = (Path(__file__).parent / "compact.md").read_text()
kimi_cli/soul/wire.py DELETED
@@ -1,101 +0,0 @@
1
- import asyncio
2
- import uuid
3
- from contextvars import ContextVar
4
- from enum import Enum
5
- from typing import NamedTuple
6
-
7
- from kosong.base.message import ContentPart, ToolCall, ToolCallPart
8
- from kosong.tooling import ToolResult
9
-
10
- from kimi_cli.soul import StatusSnapshot
11
- from kimi_cli.utils.logging import logger
12
-
13
-
14
- class StepBegin(NamedTuple):
15
- n: int
16
-
17
-
18
- class StepInterrupted(NamedTuple):
19
- pass
20
-
21
-
22
- class StatusUpdate(NamedTuple):
23
- status: StatusSnapshot
24
-
25
-
26
- type ControlFlowEvent = StepBegin | StepInterrupted | StatusUpdate
27
- type Event = ControlFlowEvent | ContentPart | ToolCall | ToolCallPart | ToolResult
28
-
29
-
30
- class ApprovalResponse(Enum):
31
- APPROVE = "approve"
32
- APPROVE_FOR_SESSION = "approve_for_session"
33
- REJECT = "reject"
34
-
35
-
36
- class ApprovalRequest:
37
- def __init__(self, tool_call_id: str, action: str, description: str):
38
- self.id = str(uuid.uuid4())
39
- self.tool_call_id = tool_call_id
40
- self.action = action
41
- self.description = description
42
- self._future = asyncio.Future[ApprovalResponse]()
43
-
44
- def __repr__(self) -> str:
45
- return (
46
- f"ApprovalRequest(id={self.id}, tool_call_id={self.tool_call_id}, "
47
- f"action={self.action}, description={self.description})"
48
- )
49
-
50
- async def wait(self) -> ApprovalResponse:
51
- """
52
- Wait for the request to be resolved or cancelled.
53
-
54
- Returns:
55
- ApprovalResponse: The response to the approval request.
56
- """
57
- return await self._future
58
-
59
- def resolve(self, response: ApprovalResponse) -> None:
60
- """
61
- Resolve the approval request with the given response.
62
- This will cause the `wait()` method to return the response.
63
- """
64
- self._future.set_result(response)
65
-
66
-
67
- type WireMessage = Event | ApprovalRequest
68
-
69
-
70
- class Wire:
71
- """
72
- A channel for communication between the soul and the UI.
73
- """
74
-
75
- def __init__(self):
76
- self._queue = asyncio.Queue[WireMessage]()
77
-
78
- def send(self, msg: WireMessage) -> None:
79
- if not isinstance(msg, ContentPart | ToolCallPart):
80
- logger.debug("Sending wire message: {msg}", msg=msg)
81
- self._queue.put_nowait(msg)
82
-
83
- async def receive(self) -> WireMessage:
84
- msg = await self._queue.get()
85
- if not isinstance(msg, ContentPart | ToolCallPart):
86
- logger.debug("Receiving wire message: {msg}", msg=msg)
87
- return msg
88
-
89
- def shutdown(self) -> None:
90
- self._queue.shutdown()
91
-
92
-
93
- current_wire = ContextVar[Wire | None]("current_wire", default=None)
94
-
95
-
96
- def get_wire_or_none() -> Wire | None:
97
- """
98
- Get the current wire or None.
99
- Expect to be not None when called from anywhere in the agent loop.
100
- """
101
- return current_wire.get()