kimi-cli 0.35__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.

Potentially problematic release.


This version of kimi-cli might be problematic. Click here for more details.

Files changed (76) hide show
  1. kimi_cli/CHANGELOG.md +304 -0
  2. kimi_cli/__init__.py +374 -0
  3. kimi_cli/agent.py +261 -0
  4. kimi_cli/agents/koder/README.md +3 -0
  5. kimi_cli/agents/koder/agent.yaml +24 -0
  6. kimi_cli/agents/koder/sub.yaml +11 -0
  7. kimi_cli/agents/koder/system.md +72 -0
  8. kimi_cli/config.py +138 -0
  9. kimi_cli/llm.py +8 -0
  10. kimi_cli/metadata.py +117 -0
  11. kimi_cli/prompts/metacmds/__init__.py +4 -0
  12. kimi_cli/prompts/metacmds/compact.md +74 -0
  13. kimi_cli/prompts/metacmds/init.md +21 -0
  14. kimi_cli/py.typed +0 -0
  15. kimi_cli/share.py +8 -0
  16. kimi_cli/soul/__init__.py +59 -0
  17. kimi_cli/soul/approval.py +69 -0
  18. kimi_cli/soul/context.py +142 -0
  19. kimi_cli/soul/denwarenji.py +37 -0
  20. kimi_cli/soul/kimisoul.py +248 -0
  21. kimi_cli/soul/message.py +76 -0
  22. kimi_cli/soul/toolset.py +25 -0
  23. kimi_cli/soul/wire.py +101 -0
  24. kimi_cli/tools/__init__.py +85 -0
  25. kimi_cli/tools/bash/__init__.py +97 -0
  26. kimi_cli/tools/bash/bash.md +31 -0
  27. kimi_cli/tools/dmail/__init__.py +38 -0
  28. kimi_cli/tools/dmail/dmail.md +15 -0
  29. kimi_cli/tools/file/__init__.py +21 -0
  30. kimi_cli/tools/file/glob.md +17 -0
  31. kimi_cli/tools/file/glob.py +149 -0
  32. kimi_cli/tools/file/grep.md +5 -0
  33. kimi_cli/tools/file/grep.py +285 -0
  34. kimi_cli/tools/file/patch.md +8 -0
  35. kimi_cli/tools/file/patch.py +131 -0
  36. kimi_cli/tools/file/read.md +14 -0
  37. kimi_cli/tools/file/read.py +139 -0
  38. kimi_cli/tools/file/replace.md +7 -0
  39. kimi_cli/tools/file/replace.py +132 -0
  40. kimi_cli/tools/file/write.md +5 -0
  41. kimi_cli/tools/file/write.py +107 -0
  42. kimi_cli/tools/mcp.py +85 -0
  43. kimi_cli/tools/task/__init__.py +156 -0
  44. kimi_cli/tools/task/task.md +26 -0
  45. kimi_cli/tools/test.py +55 -0
  46. kimi_cli/tools/think/__init__.py +21 -0
  47. kimi_cli/tools/think/think.md +1 -0
  48. kimi_cli/tools/todo/__init__.py +27 -0
  49. kimi_cli/tools/todo/set_todo_list.md +15 -0
  50. kimi_cli/tools/utils.py +150 -0
  51. kimi_cli/tools/web/__init__.py +4 -0
  52. kimi_cli/tools/web/fetch.md +1 -0
  53. kimi_cli/tools/web/fetch.py +94 -0
  54. kimi_cli/tools/web/search.md +1 -0
  55. kimi_cli/tools/web/search.py +126 -0
  56. kimi_cli/ui/__init__.py +68 -0
  57. kimi_cli/ui/acp/__init__.py +441 -0
  58. kimi_cli/ui/print/__init__.py +176 -0
  59. kimi_cli/ui/shell/__init__.py +326 -0
  60. kimi_cli/ui/shell/console.py +3 -0
  61. kimi_cli/ui/shell/liveview.py +158 -0
  62. kimi_cli/ui/shell/metacmd.py +309 -0
  63. kimi_cli/ui/shell/prompt.py +574 -0
  64. kimi_cli/ui/shell/setup.py +192 -0
  65. kimi_cli/ui/shell/update.py +204 -0
  66. kimi_cli/utils/changelog.py +101 -0
  67. kimi_cli/utils/logging.py +18 -0
  68. kimi_cli/utils/message.py +8 -0
  69. kimi_cli/utils/path.py +23 -0
  70. kimi_cli/utils/provider.py +64 -0
  71. kimi_cli/utils/pyinstaller.py +24 -0
  72. kimi_cli/utils/string.py +12 -0
  73. kimi_cli-0.35.dist-info/METADATA +24 -0
  74. kimi_cli-0.35.dist-info/RECORD +76 -0
  75. kimi_cli-0.35.dist-info/WHEEL +4 -0
  76. kimi_cli-0.35.dist-info/entry_points.txt +3 -0
kimi_cli/CHANGELOG.md ADDED
@@ -0,0 +1,304 @@
1
+ # Changelog
2
+
3
+ <!--
4
+ Release notes will be parsed and available as /release-notes
5
+ The parser extracts for each version:
6
+ - a short description (first paragraph after the version header)
7
+ - bullet entries beginning with "- " under that version (across any subsections)
8
+ Internal builds may append content to the Unreleased section.
9
+ Only write entries that are worth mentioning to users.
10
+ -->
11
+
12
+ ## [0.35] - 2025-10-22
13
+
14
+ ### Changed
15
+
16
+ - Minor UI improvements
17
+ - Auto download ripgrep if not found in the system
18
+ - Always approve tool calls in `--print` mode
19
+ - Add `/feedback` meta command
20
+
21
+ ## [0.34] - 2025-10-21
22
+
23
+ ### Added
24
+
25
+ - Add `/update` meta command to check for updates and auto-update in background
26
+ - Support running interactive shell commands in raw shell mode
27
+ - Add `/setup` meta command to setup LLM provider and model
28
+ - Add `/reload` meta command to reload configuration
29
+
30
+ ## [0.33] - 2025-10-18
31
+
32
+ ### Added
33
+
34
+ - Add `/version` meta command
35
+ - Add raw shell mode, which can be switched to by Ctrl-K
36
+ - Show shortcuts in bottom status line
37
+
38
+ ### Fixed
39
+
40
+ - Fix logging redirection
41
+ - Merge duplicated input histories
42
+
43
+ ## [0.32] - 2025-10-16
44
+
45
+ ### Added
46
+
47
+ - Add bottom status line
48
+ - Support file path auto-completion (`@filepath`)
49
+
50
+ ### Fixed
51
+
52
+ - Do not auto-complete meta command in the middle of user input
53
+
54
+ ## [0.31] - 2025-10-14
55
+
56
+ ### Fixed
57
+
58
+ - Fix step interrupting by Ctrl-C, for real
59
+
60
+ ## [0.30] - 2025-10-14
61
+
62
+ ### Added
63
+
64
+ - Add `/compact` meta command to allow manually compacting context
65
+
66
+ ### Fixed
67
+
68
+ - Fix `/clear` meta command when context is empty
69
+
70
+ ## [0.29] - 2025-10-14
71
+
72
+ ### Added
73
+
74
+ - Support Enter key to accept completion in shell mode
75
+ - Remember user input history across sessions in shell mode
76
+ - Add `/reset` meta command as an alias for `/clear`
77
+
78
+ ### Fixed
79
+
80
+ - Fix step interrupting by Ctrl-C
81
+
82
+ ### Changed
83
+
84
+ - Disable `SendDMail` tool in Kimi Koder agent
85
+
86
+ ## [0.28] - 2025-10-13
87
+
88
+ ### Added
89
+
90
+ - Add `/init` meta command to analyze the codebase and generate an `AGENTS.md` file
91
+ - Add `/clear` meta command to clear the context
92
+
93
+ ### Fixed
94
+
95
+ - Fix `ReadFile` output
96
+
97
+ ## [0.27] - 2025-10-11
98
+
99
+ ### Added
100
+
101
+ - Add `--mcp-config-file` and `--mcp-config` options to load MCP configs
102
+
103
+ ### Changed
104
+
105
+ - Rename `--agent` option to `--agent-file`
106
+
107
+ ## [0.26] - 2025-10-11
108
+
109
+ ### Fixed
110
+
111
+ - Fix possible encoding error in `--output-format stream-json` mode
112
+
113
+ ## [0.25] - 2025-10-11
114
+
115
+ ### Changed
116
+
117
+ - Rename package name `ensoul` to `kimi-cli`
118
+ - Rename `ENSOUL_*` builtin system prompt arguments to `KIMI_*`
119
+ - Further decouple `App` with `Soul`
120
+ - Split `Soul` protocol and `KimiSoul` implementation for better modularity
121
+
122
+ ## [0.24] - 2025-10-10
123
+
124
+ ### Fixed
125
+
126
+ - Fix ACP `cancel` method
127
+
128
+ ## [0.23] - 2025-10-09
129
+
130
+ ### Added
131
+
132
+ - Add `extend` field to agent file to support agent file extension
133
+ - Add `exclude_tools` field to agent file to support excluding tools
134
+ - Add `subagents` field to agent file to support defining subagents
135
+
136
+ ## [0.22] - 2025-10-09
137
+
138
+ ### Changed
139
+
140
+ - Improve `SearchWeb` and `FetchURL` tool call visualization
141
+ - Improve search result output format
142
+
143
+ ## [0.21] - 2025-10-09
144
+
145
+ ### Added
146
+
147
+ - Add `--print` option as a shortcut for `--ui print`, `--acp` option as a shortcut for `--ui acp`
148
+ - Support `--output-format stream-json` to print output in JSON format
149
+ - Add `SearchWeb` tool with `services.moonshot_search` configuration. You need to configure it with `"services": {"moonshot_search": {"api_key": "your-search-api-key"}}` in your config file.
150
+ - Add `FetchURL` tool
151
+ - Add `Think` tool
152
+ - Add `PatchFile` tool, not enabled in Kimi Koder agent
153
+ - Enable `SendDMail` and `Task` tool in Kimi Koder agent with better tool prompts
154
+ - Add `ENSOUL_NOW` builtin system prompt argument
155
+
156
+ ### Changed
157
+
158
+ - Better-looking `/release-notes`
159
+ - Improve tool descriptions
160
+ - Improve tool output truncation
161
+
162
+ ## [0.20] - 2025-09-30
163
+
164
+ ### Added
165
+
166
+ - Add `--ui acp` option to start Agent Client Protocol (ACP) server
167
+
168
+ ## [0.19] - 2025-09-29
169
+
170
+ ### Added
171
+
172
+ - Support piped stdin for print UI
173
+ - Support `--input-format=stream-json` for piped JSON input
174
+
175
+ ### Fixed
176
+
177
+ - Do not include `CHECKPOINT` messages in the context when `SendDMail` is not enabled
178
+
179
+ ## [0.18] - 2025-09-29
180
+
181
+ ### Added
182
+
183
+ - Support `max_context_size` in LLM model configurations to configure the maximum context size (in tokens)
184
+
185
+ ### Improved
186
+
187
+ - Improve `ReadFile` tool description
188
+
189
+ ## [0.17] - 2025-09-29
190
+
191
+ ### Fixed
192
+
193
+ - Fix step count in error message when exceeded max steps
194
+ - Fix history file assertion error in `kimi_run`
195
+ - Fix error handling in print mode and single command shell mode
196
+ - Add retry for LLM API connection errors and timeout errors
197
+
198
+ ### Changed
199
+
200
+ - Increase default max-steps-per-run to 100
201
+
202
+ ## [0.16.0] - 2025-09-26
203
+
204
+ ### Tools
205
+
206
+ - Add `SendDMail` tool (disabled in Kimi Koder, can be enabled in custom agent)
207
+
208
+ ### SDK
209
+
210
+ - Session history file can be specified via `_history_file` parameter when creating a new session
211
+
212
+ ## [0.15.0] - 2025-09-26
213
+
214
+ - Improve tool robustness
215
+
216
+ ## [0.14.0] - 2025-09-25
217
+
218
+ ### Added
219
+
220
+ - Add `StrReplaceFile` tool
221
+
222
+ ### Improved
223
+
224
+ - Emphasize the use of the same language as the user
225
+
226
+ ## [0.13.0] - 2025-09-25
227
+
228
+ ### Added
229
+
230
+ - Add `SetTodoList` tool
231
+ - Add `User-Agent` in LLM API calls
232
+
233
+ ### Improved
234
+
235
+ - Better system prompt and tool description
236
+ - Better error messages for LLM
237
+
238
+ ## [0.12.0] - 2025-09-24
239
+
240
+ ### Added
241
+
242
+ - Add `print` UI mode, which can be used via `--ui print` option
243
+ - Add logging and `--debug` option
244
+
245
+ ### Changed
246
+
247
+ - Catch EOF error for better experience
248
+
249
+ ## [0.11.1] - 2025-09-22
250
+
251
+ ### Changed
252
+
253
+ - Rename `max_retry_per_step` to `max_retries_per_step`
254
+
255
+ ## [0.11.0] - 2025-09-22
256
+
257
+ ### Added
258
+
259
+ - Add `/release-notes` command
260
+ - Add retry for LLM API errors
261
+ - Add loop control configuration, e.g. `{"loop_control": {"max_steps_per_run": 50, "max_retry_per_step": 3}}`
262
+
263
+ ### Changed
264
+
265
+ - Better extreme cases handling in `read_file` tool
266
+ - Prevent Ctrl-C from exiting the CLI, force the use of Ctrl-D or `exit` instead
267
+
268
+ ## [0.10.1] - 2025-09-18
269
+
270
+ - Make slash commands look slightly better
271
+ - Improve `glob` tool
272
+
273
+ ## [0.10.0] - 2025-09-17
274
+
275
+ ### Added
276
+
277
+ - Add `read_file` tool
278
+ - Add `write_file` tool
279
+ - Add `glob` tool
280
+ - Add `task` tool
281
+
282
+ ### Changed
283
+
284
+ - Improve tool call visualization
285
+ - Improve session management
286
+ - Restore context usage when `--continue` a session
287
+
288
+ ## [0.9.0] - 2025-09-15
289
+
290
+ - Remove `--session` and `--continue` options
291
+
292
+ ## [0.8.1] - 2025-09-14
293
+
294
+ - Fix config model dumping
295
+
296
+ ## [0.8.0] - 2025-09-14
297
+
298
+ - Add `shell` tool and basic system prompt
299
+ - Add tool call visualization
300
+ - Add context usage count
301
+ - Support interrupting the agent loop
302
+ - Support project-level `AGENTS.md`
303
+ - Support custom agent defined with YAML
304
+ - Support oneshot task via `kimi -c`
kimi_cli/__init__.py ADDED
@@ -0,0 +1,374 @@
1
+ import asyncio
2
+ import contextlib
3
+ import importlib.metadata
4
+ import json
5
+ import os
6
+ import subprocess
7
+ import sys
8
+ import textwrap
9
+ import warnings
10
+ from datetime import datetime
11
+ from pathlib import Path
12
+ from typing import Any, Literal
13
+
14
+ import click
15
+ from pydantic import SecretStr
16
+
17
+ from kimi_cli.agent import (
18
+ DEFAULT_AGENT_FILE,
19
+ AgentGlobals,
20
+ BuiltinSystemPromptArgs,
21
+ load_agent_with_mcp,
22
+ load_agents_md,
23
+ )
24
+ from kimi_cli.config import (
25
+ Config,
26
+ ConfigError,
27
+ LLMModel,
28
+ LLMProvider,
29
+ load_config,
30
+ )
31
+ from kimi_cli.metadata import Session, continue_session, new_session
32
+ from kimi_cli.share import get_share_dir
33
+ from kimi_cli.soul.approval import Approval
34
+ from kimi_cli.soul.context import Context
35
+ from kimi_cli.soul.denwarenji import DenwaRenji
36
+ from kimi_cli.soul.kimisoul import KimiSoul
37
+ from kimi_cli.ui.acp import ACPServer
38
+ from kimi_cli.ui.print import InputFormat, OutputFormat, PrintApp
39
+ from kimi_cli.ui.shell import Reload, ShellApp
40
+ from kimi_cli.utils.logging import StreamToLogger, logger
41
+ from kimi_cli.utils.provider import augment_provider_with_env_vars, create_llm
42
+
43
+ __version__ = importlib.metadata.version("kimi-cli")
44
+ USER_AGENT = f"KimiCLI/{__version__}"
45
+
46
+ UIMode = Literal["shell", "print", "acp"]
47
+
48
+
49
+ @click.command(context_settings=dict(help_option_names=["-h", "--help"]))
50
+ @click.version_option(__version__)
51
+ @click.option(
52
+ "--verbose",
53
+ is_flag=True,
54
+ default=False,
55
+ help="Print verbose information. Default: no.",
56
+ )
57
+ @click.option(
58
+ "--debug",
59
+ is_flag=True,
60
+ default=False,
61
+ help="Log debug information. Default: no.",
62
+ )
63
+ @click.option(
64
+ "--agent-file",
65
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, path_type=Path),
66
+ default=DEFAULT_AGENT_FILE,
67
+ help="Custom agent specification file. Default: builtin Kimi Koder.",
68
+ )
69
+ @click.option(
70
+ "--model",
71
+ "-m",
72
+ "model_name",
73
+ type=str,
74
+ default=None,
75
+ help="LLM model to use. Default: default model set in config file.",
76
+ )
77
+ @click.option(
78
+ "--work-dir",
79
+ "-w",
80
+ type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
81
+ default=Path.cwd(),
82
+ help="Working directory for the agent. Default: current directory.",
83
+ )
84
+ @click.option(
85
+ "--continue",
86
+ "-C",
87
+ "continue_",
88
+ is_flag=True,
89
+ default=False,
90
+ help="Continue the previous session for the working directory. Default: no.",
91
+ )
92
+ @click.option(
93
+ "--command",
94
+ "-c",
95
+ "--query",
96
+ "-q",
97
+ "command",
98
+ type=str,
99
+ default=None,
100
+ help="User query to the agent. Default: prompt interactively.",
101
+ )
102
+ @click.option(
103
+ "--ui",
104
+ "ui",
105
+ type=click.Choice(["shell", "print", "acp"]),
106
+ default="shell",
107
+ help="UI mode to use. Default: shell.",
108
+ )
109
+ @click.option(
110
+ "--print",
111
+ "ui",
112
+ flag_value="print",
113
+ help="Run in print mode. Shortcut for `--ui print`.",
114
+ )
115
+ @click.option(
116
+ "--acp",
117
+ "ui",
118
+ flag_value="acp",
119
+ help="Start ACP server. Shortcut for `--ui acp`.",
120
+ )
121
+ @click.option(
122
+ "--input-format",
123
+ type=click.Choice(["text", "stream-json"]),
124
+ default=None,
125
+ help=(
126
+ "Input format to use. Must be used with `--print` "
127
+ "and the input must be piped in via stdin. "
128
+ "Default: text."
129
+ ),
130
+ )
131
+ @click.option(
132
+ "--output-format",
133
+ type=click.Choice(["text", "stream-json"]),
134
+ default=None,
135
+ help="Output format to use. Must be used with `--print`. Default: text.",
136
+ )
137
+ @click.option(
138
+ "--mcp-config-file",
139
+ type=click.Path(exists=True, file_okay=True, dir_okay=False, path_type=Path),
140
+ multiple=True,
141
+ help=(
142
+ "MCP config file to load. Add this option multiple times to specify multiple MCP configs. "
143
+ "Default: none."
144
+ ),
145
+ )
146
+ @click.option(
147
+ "--mcp-config",
148
+ type=str,
149
+ multiple=True,
150
+ help=(
151
+ "MCP config JSON to load. Add this option multiple times to specify multiple MCP configs. "
152
+ "Default: none."
153
+ ),
154
+ )
155
+ def kimi(
156
+ verbose: bool,
157
+ debug: bool,
158
+ agent_file: Path,
159
+ model_name: str | None,
160
+ work_dir: Path,
161
+ continue_: bool,
162
+ command: str | None,
163
+ ui: UIMode,
164
+ input_format: InputFormat | None,
165
+ output_format: OutputFormat | None,
166
+ mcp_config_file: list[Path],
167
+ mcp_config: list[str],
168
+ ):
169
+ """Kimi, your next CLI agent."""
170
+ echo = click.echo if verbose else lambda *args, **kwargs: None
171
+
172
+ logger.add(
173
+ get_share_dir() / "logs" / "kimi.log",
174
+ level="DEBUG" if debug else "INFO",
175
+ rotation="06:00",
176
+ retention="10 days",
177
+ )
178
+
179
+ work_dir = work_dir.absolute()
180
+
181
+ if continue_:
182
+ session = continue_session(work_dir)
183
+ if session is None:
184
+ raise click.BadOptionUsage(
185
+ "--continue", "No previous session found for the working directory"
186
+ )
187
+ echo(f"✓ Continuing previous session: {session.id}")
188
+ else:
189
+ session = new_session(work_dir)
190
+ echo(f"✓ Created new session: {session.id}")
191
+ echo(f"✓ Session history file: {session.history_file}")
192
+
193
+ if input_format is not None and ui != "print":
194
+ raise click.BadOptionUsage(
195
+ "--input-format",
196
+ "Input format is only supported for print UI",
197
+ )
198
+ if output_format is not None and ui != "print":
199
+ raise click.BadOptionUsage(
200
+ "--output-format",
201
+ "Output format is only supported for print UI",
202
+ )
203
+
204
+ try:
205
+ mcp_configs = [json.loads(conf.read_text()) for conf in mcp_config_file]
206
+ except json.JSONDecodeError as e:
207
+ raise click.BadOptionUsage("--mcp-config-file", f"Invalid JSON: {e}") from e
208
+
209
+ try:
210
+ mcp_configs += [json.loads(conf) for conf in mcp_config]
211
+ except json.JSONDecodeError as e:
212
+ raise click.BadOptionUsage("--mcp-config", f"Invalid JSON: {e}") from e
213
+
214
+ while True:
215
+ try:
216
+ try:
217
+ config = load_config()
218
+ except ConfigError as e:
219
+ raise click.ClickException(f"Failed to load config: {e}") from e
220
+ echo(f"✓ Loaded config: {config}")
221
+
222
+ succeeded = asyncio.run(
223
+ kimi_run(
224
+ config=config,
225
+ model_name=model_name,
226
+ work_dir=work_dir,
227
+ session=session,
228
+ command=command,
229
+ agent_file=agent_file,
230
+ verbose=verbose,
231
+ ui=ui,
232
+ input_format=input_format,
233
+ output_format=output_format,
234
+ mcp_configs=mcp_configs,
235
+ )
236
+ )
237
+ if not succeeded:
238
+ sys.exit(1)
239
+ break
240
+ except Reload:
241
+ continue
242
+
243
+
244
+ async def kimi_run(
245
+ *,
246
+ config: Config,
247
+ model_name: str | None,
248
+ work_dir: Path,
249
+ session: Session,
250
+ command: str | None = None,
251
+ agent_file: Path = DEFAULT_AGENT_FILE,
252
+ verbose: bool = True,
253
+ ui: UIMode = "shell",
254
+ input_format: InputFormat | None = None,
255
+ output_format: OutputFormat | None = None,
256
+ mcp_configs: list[dict[str, Any]] | None = None,
257
+ ) -> bool:
258
+ """Run Kimi CLI."""
259
+ echo = click.echo if verbose else lambda *args, **kwargs: None
260
+
261
+ model: LLMModel | None = None
262
+ provider: LLMProvider | None = None
263
+
264
+ # try to use config file
265
+ if not model_name and config.default_model:
266
+ # no --model specified && default model is set in config
267
+ model = config.models[config.default_model]
268
+ provider = config.providers[model.provider]
269
+ if model_name and model_name in config.models:
270
+ # --model specified && model is set in config
271
+ model = config.models[model_name]
272
+ provider = config.providers[model.provider]
273
+
274
+ if not model:
275
+ model = LLMModel(provider="", model="", max_context_size=100_000)
276
+ provider = LLMProvider(type="kimi", base_url="", api_key=SecretStr(""))
277
+
278
+ # try overwrite with environment variables
279
+ assert provider is not None
280
+ assert model is not None
281
+ augment_provider_with_env_vars(provider, model)
282
+
283
+ if not provider.base_url or not model.model:
284
+ llm = None
285
+ else:
286
+ echo(f"✓ Using LLM provider: {provider}")
287
+ echo(f"✓ Using LLM model: {model}")
288
+ stream = ui != "print" # use non-streaming mode only for print UI
289
+ llm = create_llm(provider, model, stream=stream)
290
+
291
+ # TODO: support Windows
292
+ ls = subprocess.run(["ls", "-la"], capture_output=True, text=True)
293
+ agents_md = load_agents_md(work_dir) or ""
294
+ if agents_md:
295
+ echo(f"✓ Loaded agents.md: {textwrap.shorten(agents_md, width=100)}")
296
+
297
+ agent_globals = AgentGlobals(
298
+ config=config,
299
+ llm=llm,
300
+ builtin_args=BuiltinSystemPromptArgs(
301
+ KIMI_NOW=datetime.now().astimezone().isoformat(),
302
+ KIMI_WORK_DIR=work_dir,
303
+ KIMI_WORK_DIR_LS=ls.stdout,
304
+ KIMI_AGENTS_MD=agents_md,
305
+ ),
306
+ denwa_renji=DenwaRenji(),
307
+ session=session,
308
+ approval=Approval(),
309
+ )
310
+ try:
311
+ agent = await load_agent_with_mcp(agent_file, agent_globals, mcp_configs or [])
312
+ except ValueError as e:
313
+ raise click.BadParameter(f"Failed to load agent: {e}") from e
314
+ echo(f"✓ Loaded agent: {agent.name}")
315
+ echo(f"✓ Loaded system prompt: {textwrap.shorten(agent.system_prompt, width=100)}")
316
+ echo(f"✓ Loaded tools: {[tool.name for tool in agent.toolset.tools]}")
317
+
318
+ if command is not None:
319
+ command = command.strip()
320
+ if not command:
321
+ raise click.BadParameter("Command cannot be empty")
322
+
323
+ context = Context(session.history_file)
324
+ restored = await context.restore()
325
+ if restored:
326
+ echo(f"✓ Restored history from {session.history_file}")
327
+
328
+ soul = KimiSoul(
329
+ agent,
330
+ agent_globals,
331
+ context=context,
332
+ loop_control=config.loop_control,
333
+ )
334
+
335
+ original_cwd = Path.cwd()
336
+ os.chdir(work_dir)
337
+
338
+ try:
339
+ if ui == "shell":
340
+ if command is None and not sys.stdin.isatty():
341
+ command = sys.stdin.read().strip()
342
+ echo(f"✓ Read command from stdin: {command}")
343
+
344
+ app = ShellApp(
345
+ soul,
346
+ welcome_info={
347
+ "Directory": str(work_dir),
348
+ "Session": session.id,
349
+ },
350
+ )
351
+ # to ignore possible warnings from dateparser
352
+ warnings.filterwarnings("ignore", category=DeprecationWarning)
353
+ with contextlib.redirect_stderr(StreamToLogger()):
354
+ return await app.run(command)
355
+ elif ui == "print":
356
+ app = PrintApp(soul, input_format or "text", output_format or "text")
357
+ return await app.run(command)
358
+ elif ui == "acp":
359
+ if command is not None:
360
+ logger.warning("ACP server ignores command argument")
361
+ app = ACPServer(soul)
362
+ return await app.run()
363
+ else:
364
+ raise click.BadParameter(f"Invalid UI mode: {ui}")
365
+ finally:
366
+ os.chdir(original_cwd)
367
+
368
+
369
+ def main():
370
+ kimi()
371
+
372
+
373
+ if __name__ == "__main__":
374
+ main()