CODING AGENT HARNESS · SOURCE AUDITREPORT 14 / 18
14

Kimi CLI

检查点、D-Mail、后台任务和持久子 Agent 让长任务体验突出;默认 KAOS 仍是宿主执行。

Python · Checkpointed Long-running AgentApache-2.0main
SOURCE
VERIFIED
Repository
MoonshotAI/kimi-cli
Commit
4a550effdfcb29a25a5d325bf935296cc50cd417
Commit date
2026-07-16T10:03:00Z
Findings
30
Citations
95
Tracked files
988
EXECUTIVE READING

先给结论,再进入源码

核心机制

带 checkpoint 的多 step;notification injection;D-Mail 回退

上下文

可挽救 JSONL;摘要保尾;压缩后恢复活动后台任务

安全边界

统一 approval/YOLO/AFK/Plan gate;默认本地 KAOS 非 OS 沙箱

适用建设

超长自主任务、后台 build、可恢复研究与编码

值得借鉴

  • 长任务中途纠偏优秀
  • 重复调用治理具体
  • 子 Agent 生命周期完整

需要警惕

  • 默认无 OS 沙箱
  • AFK 等同自动批准
  • 插件子进程可获新鲜凭据

直接带走

  • D-Mail 语义回退
  • 压缩后任务 rehydrate
  • 分阶梯重复调用刹车
00 · METHOD

研究口径:先锁提交,再沿运行链读代码

README POLICY

README 只作入口;结论来自 KimiSoul 主循环、Kosong 流/工具契约、Context/Compaction、Approval/KAOS、MCP、Plugin/Hook、Subagent、Session/Wire、Telemetry、默认 agent spec/system prompt 与对应测试。

FACT POLICY

明确区分 KAOS 执行抽象与 OS 级沙箱,区分同 step 工具并发与跨 step 重复抑制,区分 prompt 约束与代码强制 allowlist/approval。

INFERENCE POLICY

不推断 Moonshot 服务端内部;对无默认沙箱、遥测字段边界和子 Agent 隔离只按本提交可见本地代码陈述。

L1运行实现
L2接口契约
L3测试证明
L4文档佐证
L5明确推断

本页引用 36 个不同源码/测试文件;证据角色分布:实现 73 · 契约 8 · 测试 6 · 配置 4 · Prompt 4。代码块是固定提交中的原文截取,长区间仅在中部折叠,首尾行号保持真实。

01 · TECHNICAL MAPS

架构总图与单轮执行链路

两张图均由本页证据账本生成,并通过 Archify showcase 9 项校验(0 error / 0 warning)。图可单独打开、搜索、缩放和追踪关系。

FIGURE 01Kimi CLI Harness 架构图全屏打开 ↗
FIGURE 02用户输入到工具回写的技术链路全屏打开 ↗
02 · COVERAGE MAP

审计维度与证据等级

架构与 Agent Loop verified L1 / L2 / L3

turn/step 状态机、流式生成、工具异步执行、重试、steer、D-Mail 回滚与重复调用止损。

Provider、流式与重试 verified L1 / L2 / L3

Kosong provider abstraction、Kimi/OpenAI/Anthropic/Gemini/Vertex、thinking 与请求级 completion budget。

上下文、压缩与恢复 verified L1 / L2 / L3

JSONL、usage/pending estimate、checkpoint/revert、摘要保尾、背景任务快照。

工具与执行 verified L1 / L2 / L3

动态工具装载、并发 futures、重复调用治理、前后台 Shell 与结果预算。

安全与沙箱 verified L1 / L2 / L3

统一 approval、YOLO/AFK、Plan gate、hook;本地 KAOS 直接宿主执行,非 OS 沙箱。

MCP、插件与 Hooks verified L1 / L2 / L3

延迟 MCP、OAuth、输出截断、subprocess plugins、server/wire hooks。

指令与 Skills verified L1 / L2 / L3

Jinja system prompt、AGENTS 层级与预算、跨品牌 skills、slash/flow skills。

子 Agent 与协作 verified L1 / L2 / L3

coder/explore/plan、前后台执行、持久实例/resume、模型覆盖、统一 approval/wire。

持久化、观测与成熟度 verified L1 / L2 / L3

context/wire/state/subagent artifacts、trace/wire events、opt-out telemetry、Apache-2.0。

01
DIMENSION · ARCHITECTURE-LOOP

架构与 Agent Loop

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

01
L1事实kimi-loop-001

每轮是带检查点的多步状态机,不是单次聊天请求

源码事实

run 先刷新 OAuth、建立 approval source、运行 UserPromptSubmit hook,再进入 _turn;_turn 先 checkpoint、持久化 user message,然后 _agent_loop 逐 step 做压缩、checkpoint、LLM+工具执行,直到无工具调用、拒绝或重复调用强停。

白话解释

一次用户输入可能触发多次“模型思考—调工具—看结果—再思考”,每一步前都留存档点。

对自研 Harness 的含义

长任务可恢复、可插话,也需要严格的步数上限和副作用治理。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L659–L742
  659      async def run(
  660          self,
  661          user_input: str | list[ContentPart],
  662          *,
  663          skip_user_prompt_hook: bool = False,
  664      ):
  665          approval_source_token = None
  666          created_approval_source: ApprovalSource | None = None
  667          turn_started = False
  668          turn_finished = False
  669          interrupt_reason: str | None = None
  670          turn_t0 = time.monotonic()
  671          self._set_trace_id(None)
  672          if get_current_approval_source_or_none() is None:
  673              created_approval_source = ApprovalSource(kind="foreground_turn", id=uuid.uuid4().hex)
  674              approval_source_token = set_current_approval_source(created_approval_source)
  675          try:
  676              # Refresh OAuth tokens on each turn to avoid idle-time expirations.
  677              await self._runtime.oauth.ensure_fresh(self._runtime)
  678  
  679              # Set session_id ContextVar for toolset hooks
  680              from kimi_cli.soul.toolset import set_session_id
  681  
  682              set_session_id(self._runtime.session.id)
      … 50 lines omitted; exact range 659–742 …
  733                          await ret
  734              elif self._loop_control.max_ralph_iterations != 0:
  735                  runner = FlowRunner.ralph_loop(
  736                      user_message,
  737                      self._loop_control.max_ralph_iterations,
  738                  )
  739                  await runner.run(self, "")
  740              else:
  741                  await self._turn(user_message)
  742  
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:659–742 turn 初始化、hook、slash/flow/普通 turn 路由。
  • 实现 src/kimi_cli/soul/kimisoul.py:841–852 checkpoint、user message 落盘、进入 agent loop。
  • 实现 src/kimi_cli/soul/kimisoul.py:998–1041 step guard、auto compaction、checkpoint 和 step execution。
02
L1事实kimi-loop-002

每 step 先注入通知/动态约束,再一次生成并等待并发工具

源码事实

root 每 step 最多领取 4 条 pending notification;Plan/AFK 等 injection 合并成 user-side system reminder;历史归一化后调用 kosong.step,流式回调消息和工具结果,随后 await 所有 tool results 并 shield 写回上下文。

白话解释

模型每次再开口前都会先收新通知和当前模式规则;工具可以边生成边启动,结果到齐后才记账。

对自研 Harness 的含义

实时性和并行性强;动态注入是上下文的一部分,会影响 token 与缓存。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L1132–L1194
 1132          # ═══════════════════════════════════════════════════════════════════════
 1133          # 2e.1. NOTIFICATION DELIVERY (root role only)
 1134          # ═══════════════════════════════════════════════════════════════════════
 1135          if self.is_root:
 1136  
 1137              async def _append_notification(view: NotificationView) -> None:
 1138                  await self._context.append_message(build_notification_message(view, self._runtime))
 1139                  # --- Notification hook ---
 1140                  from kimi_cli.hooks import events
 1141  
 1142                  _hook_task = asyncio.create_task(
 1143                      self._hook_engine.trigger(
 1144                          "Notification",
 1145                          matcher_value=view.event.type,
 1146                          input_data=events.notification(
 1147                              session_id=self._runtime.session.id,
 1148                              cwd=str(Path.cwd()),
 1149                              sink="llm",
 1150                              notification_type=view.event.type,
 1151                              title=view.event.title,
 1152                              body=view.event.body,
 1153                              severity=view.event.severity,
 1154                          ),
 1155                      )
      … 29 lines omitted; exact range 1132–1194 …
 1185              system_prompt=self._agent.system_prompt,
 1186              tools=self._agent.toolset.tools,
 1187              history=effective_history,
 1188              input_tokens_floor=self._context.token_count_with_pending,
 1189          )
 1190          request_chat_provider = with_kimi_generation_overrides(chat_provider, generation_overrides)
 1191          request_chat_provider = with_trace_callback(
 1192              request_chat_provider,
 1193              self._set_trace_id,
 1194          )
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:1132–1194 notification、dynamic injection、history normalization。
  • 实现 src/kimi_cli/soul/kimisoul.py:1196–1216 Kosong step 与流式 callbacks。
  • 实现 src/kimi_cli/soul/kimisoul.py:1274–1295 等待工具结果并 shield context growth。
03
L1事实kimi-loop-003

steer 与 D-Mail 提供两种中途改道机制

源码事实

steer queue 会在 step 结束或相邻 step 间作为新的 user message 注入;SendDMail 可携 checkpoint id 触发 BackToTheFuture,主循环旋转并回退 context,再注入未来消息并清空重复调用状态。

白话解释

用户插话是在当前路线后追加新指令;D-Mail 则像读档,把对话回到旧存档再塞入一张“未来经验”纸条。

对自研 Harness 的含义

适合长程纠偏和探索回溯,但文件系统副作用不会随 context 自动回滚。

边界
  • 回滚的是对话 JSONL,不是 git/worktree 或外部服务事务。
关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L622–L653
  622      def steer(self, content: str | list[ContentPart]) -> None:
  623          """Queue a steer message for injection into the current turn."""
  624          self._steer_queue.put_nowait(content)
  625  
  626      async def _consume_pending_steers(self) -> bool:
  627          """Drain the steer queue and inject as follow-up user messages.
  628  
  629          Returns True if any steers were consumed.
  630  
  631          Note: /btw is intercepted at the UI layer (``classify_input``) before
  632          reaching the steer queue, so it never appears here.
  633          """
  634          consumed = False
  635          while not self._steer_queue.empty():
  636              content = self._steer_queue.get_nowait()
  637              await self._inject_steer(content)
  638              wire_send(SteerInput(user_input=content))
  639              consumed = True
  640          return consumed
  641  
  642      async def _inject_steer(self, content: str | list[ContentPart]) -> None:
  643          """Inject a single steer as a regular follow-up user message."""
  644          parts = cast(
  645              list[ContentPart],
  646              [TextPart(text=content)] if isinstance(content, str) else list(content),
  647          )
  648          message = Message(role="user", content=parts)
  649          if self._runtime.llm is None:
  650              raise LLMNotSet()
  651          if missing_caps := check_message(message, self._runtime.llm.capabilities):
  652              raise LLMNotSupported(self._runtime.llm, list(missing_caps))
  653          await self._context.append_message(message)
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:622–653 steer queue 和 user message 注入。
  • 实现 src/kimi_cli/soul/kimisoul.py:1099–1109 D-Mail revert 后重建 checkpoint。
  • 实现 src/kimi_cli/soul/kimisoul.py:1312–1336 pending D-Mail 变成 BackToTheFuture signal。
04
L1事实kimi-loop-004

错误恢复分 OAuth、连接、空响应和 HTTP 状态码

源码事实

step/compaction 使用指数抖动重试;401 仅对 OAuth provider 强制刷新一次;连接/超时可调用 RetryableChatProvider.on_retryable_error 并只恢复一次;空响应和 429/500/502/503/504 进入 tenacity。

白话解释

不是遇错一律重试:令牌过期先换令牌,连接坏了让 provider 重建连接,服务繁忙才退避。

对自研 Harness 的含义

恢复语义清楚;408/409/529 在遥测里可标 retryable,但当前 Python 重试循环并不重试它们。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L1220–L1249
 1220          def _before_step_retry_sleep(retry_state: RetryCallState) -> None:
 1221              self._retry_log("step", retry_state)
 1222              self._emit_step_retry(retry_state, max_attempts=max_attempts)
 1223  
 1224          @tenacity.retry(
 1225              retry=retry_if_exception(self._is_retryable_error),
 1226              before_sleep=_before_step_retry_sleep,
 1227              wait=wait_exponential_jitter(initial=0.3, max=5, jitter=0.5),
 1228              stop=stop_after_attempt(max_attempts),
 1229              reraise=True,
 1230          )
 1231          async def _kosong_step_with_retry() -> StepResult:
 1232              return await self._run_with_connection_recovery(
 1233                  "step",
 1234                  _run_step_once,
 1235                  chat_provider=chat_provider,
 1236              )
 1237  
 1238          t0 = time.monotonic()
 1239          try:
 1240              result = await _kosong_step_with_retry()
 1241          except Exception as _step_exc:
 1242              if isinstance(_step_exc, ChatProviderError):
 1243                  _track_api_error(
 1244                      _step_exc,
 1245                      llm=self._runtime.llm,
 1246                      duration_ms=int((time.monotonic() - t0) * 1000),
 1247                      input_tokens=self._context.token_count,
 1248                  )
 1249              raise
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:1220–1249 step retry wrapper 与 API error telemetry。
  • 契约 src/kimi_cli/soul/kimisoul.py:1647–1658 实际 retryable 分类。
  • 实现 src/kimi_cli/soul/kimisoul.py:1660–1743 401 refresh 与连接恢复。
02
DIMENSION · PROVIDERS-STREAMING

Provider、流式与重试

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

05
L2事实kimi-provider-001

Kosong 把流式生成和工具调度拆成两层契约

源码事实

generate 合并流式 Text/Think/ToolCall part,拒绝完全空或仅 thinking 的异常响应;step 在完整 tool call 到达时立即交 Toolset.handle,并收集异步 futures,生成失败/取消时取消所有在途工具。

白话解释

底层负责把碎片拼成完整回复,上层负责一看到完整工具单就开工;若模型流中断,尚未完成的工具任务会被收拢取消。

对自研 Harness 的含义

Provider 和 Harness 解耦,同时避免中断后悬挂任务。

关键源码 · 实现
packages/kosong/src/kosong/_generate.py · L52–L103
   52      message = Message(role="assistant", content=[])
   53      pending_part: StreamedMessagePart | None = None  # message part that is currently incomplete
   54  
   55      logger.trace("Generating with history: {history}", history=history)
   56      stream = await chat_provider.generate(system_prompt, tools, history)
   57      if on_trace_id:
   58          # getattr for robustness against third-party StreamedMessage
   59          # implementations that predate the trace_id property.
   60          await callback(on_trace_id, getattr(stream, "trace_id", None))
   61      async for part in stream:
   62          logger.trace("Received part: {part}", part=part)
   63          if on_message_part:
   64              await callback(on_message_part, part.model_copy(deep=True))
   65  
   66          if pending_part is None:
   67              pending_part = part
   68          elif not pending_part.merge_in_place(part):  # try merge into the pending part
   69              # unmergeable part must push the pending part to the buffer
   70              _message_append(message, pending_part)
   71              if isinstance(pending_part, ToolCall) and on_tool_call:
   72                  await callback(on_tool_call, pending_part)
   73              pending_part = part
   74  
   75      # end of message
      … 18 lines omitted; exact range 52–103 …
   94              "stream was interrupted or the output token budget was exhausted "
   95              "during reasoning."
   96          )
   97  
   98      return GenerateResult(
   99          id=stream.id,
  100          message=message,
  101          usage=stream.usage,
  102          trace_id=getattr(stream, "trace_id", None),
  103      )
查看全部 2 处证据
  • 实现 packages/kosong/src/kosong/_generate.py:52–103 stream merge、empty/think-only validation。
  • 契约 packages/kosong/src/kosong/__init__.py:104–174 step、tool future dispatch 与 cancellation。
06
L1事实kimi-provider-002

同一 LLM 层支持 Kimi、OpenAI、Anthropic、Gemini 与 Vertex

源码事实

create_llm 按 provider type 构造 Kimi、OpenAI legacy/Responses、Anthropic、GoogleGenAI/Vertex,以及测试 Echo/Chaos;模型 capability 决定 thinking/image 等能力,thinking 可按配置开启或关闭。

白话解释

主循环不绑某一家 API,同一套工具和上下文可换不同模型协议。

对自研 Harness 的含义

可移植性好,但 Kimi 专属 generation override、prompt cache key 与 preserved thinking 只在 Kimi provider 生效。

关键源码 · 实现
src/kimi_cli/llm.py · L326–L470
  326  def create_llm(
  327      provider: LLMProvider,
  328      model: LLMModel,
  329      *,
  330      thinking: bool | None = None,
  331      session_id: str | None = None,
  332      oauth: OAuthManager | None = None,
  333  ) -> LLM | None:
  334      if provider.type not in {"_echo", "_scripted_echo"} and (
  335          not provider.base_url or not model.model
  336      ):
  337          logger.warning(
  338              "Cannot create LLM: missing base_url or model (provider_type={provider_type})",
  339              provider_type=provider.type,
  340          )
  341          return None
  342  
  343      resolved_api_key = (
  344          oauth.resolve_api_key(provider.api_key, provider.oauth)
  345          if oauth and provider.oauth
  346          else provider.api_key.get_secret_value()
  347      )
  348  
  349      match provider.type:
      … 111 lines omitted; exact range 326–470 …
  461                      model=model.model,
  462                      base_url=provider.base_url,
  463                      api_key=resolved_api_key,
  464                      default_headers=_kimi_default_headers(provider, oauth),
  465                  ),
  466                  chaos_config=ChaosConfig(
  467                      error_probability=0.8,
  468                      error_types=[429, 500, 503],
  469                  ),
  470              )
查看全部 2 处证据
  • 实现 src/kimi_cli/llm.py:326–470 provider factory。
  • 实现 src/kimi_cli/llm.py:472–501 capabilities、thinking 与 LLM assembly。
07
L1事实kimi-provider-003

completion 上限按真实请求估算并留安全边际

源码事实

请求估算包含 system prompt、工具 schema、role/metadata、tool calls、media 与历史;Kimi completion cap 取配置预算和剩余 context 的较小值,主 step 还把 pending token floor 与 safety margin 算入。

白话解释

不只数聊天正文,还把工具说明书和图片等隐藏成本算进去,再决定模型最多还能写多少。

对自研 Harness 的含义

减少输出顶破窗口;估算仍非 provider tokenizer 的精确值。

关键源码 · 实现
src/kimi_cli/llm.py · L181–L263
  181  def compute_max_completion_tokens(
  182      *,
  183      max_context_size: int,
  184      input_tokens: int,
  185      response_budget: int | None,
  186      fallback_budget: int = DEFAULT_UNKNOWN_CONTEXT_COMPLETION_TOKENS,
  187  ) -> int:
  188      """Compute the Kimi completion cap from the hard cap and remaining context."""
  189      if max_context_size <= 0:
  190          return max(1, response_budget if response_budget is not None else fallback_budget)
  191  
  192      input_tokens = max(0, input_tokens)
  193      remaining = max(1, max_context_size - input_tokens)
  194      requested = response_budget if response_budget is not None else max_context_size
  195      return max(1, min(requested, remaining))
  196  
  197  
  198  def estimate_request_tokens(
  199      system_prompt: str,
  200      tools: Sequence[Tool],
  201      history: Sequence[Message],
  202  ) -> int:
  203      """Estimate all token-bearing parts of a chat request.
  204  
      … 49 lines omitted; exact range 181–263 …
  254  
  255      for tool_call in message.tool_calls or ():
  256          total += _estimate_text_tokens(tool_call.id)
  257          total += _estimate_text_tokens(tool_call.function.name)
  258          total += _estimate_text_tokens(tool_call.function.arguments or "")
  259          if tool_call.extras:
  260              total += _estimate_text_tokens(
  261                  json.dumps(tool_call.extras, ensure_ascii=False, separators=(",", ":"))
  262              )
  263      return total
查看全部 2 处证据
  • 实现 src/kimi_cli/llm.py:181–263 completion cap 与 request token estimator。
  • 实现 src/kimi_cli/soul/kimisoul.py:1365–1387 每请求计算 Kimi generation override。
03
DIMENSION · CONTEXT-COMPACTION

上下文、压缩与恢复

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

08
L1事实kimi-context-001

上下文是可增量恢复的 JSONL 事件账本

源码事实

Context 将普通消息与 _system_prompt、_checkpoint、_usage 记录写入同一 JSONL;restore 跳过 malformed/non-object/invalid record,重建 history、checkpoint cursor、最新 token count 和 usage 之后的 pending estimate。

白话解释

每条对话、存档点和 token 仪表读数都单独写一行;尾部坏一行不会让整场会话报废。

对自研 Harness 的含义

易审计、易增量追加;没有数据库事务,靠逐行容错和旋转文件恢复。

关键源码 · 实现
src/kimi_cli/soul/context.py · L20–L65
   20  class Context:
   21      def __init__(self, file_backend: Path):
   22          self._file_backend = file_backend
   23          self._history: list[Message] = []
   24          self._token_count: int = 0
   25          self._pending_token_estimate: int = 0
   26          self._next_checkpoint_id: int = 0
   27          """The ID of the next checkpoint, starting from 0, incremented after each checkpoint."""
   28          self._system_prompt: str | None = None
   29  
   30      async def restore(self) -> bool:
   31          logger.debug("Restoring context from file: {file_backend}", file_backend=self._file_backend)
   32          if self._history:
   33              logger.error("The context storage is already modified")
   34              raise RuntimeError("The context storage is already modified")
   35          if not self._file_backend.exists():
   36              logger.debug("No context file found, skipping restoration")
   37              return False
   38          if self._file_backend.stat().st_size == 0:
   39              logger.debug("Empty context file, skipping restoration")
   40              return False
   41  
   42          messages_after_last_usage: list[Message] = []
   43          async with aiofiles.open(self._file_backend, encoding="utf-8", errors="replace") as f:
      … 12 lines omitted; exact range 20–65 …
   56                  self._apply_context_record(
   57                      line_json,
   58                      history=self._history,
   59                      messages_after_last_usage=messages_after_last_usage,
   60                      file_backend=self._file_backend,
   61                      line_no=line_no,
   62                  )
   63  
   64          self._pending_token_estimate = estimate_text_tokens(messages_after_last_usage)
   65          return True
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/context.py:20–65 restore 与 pending estimate。
  • 实现 src/kimi_cli/soul/context.py:232–248 message/usage append。
  • 实现 src/kimi_cli/soul/context.py:250–339 record validation 与 salvage。
09
L1事实kimi-context-002

checkpoint 回退会保留旧文件并重算状态

源码事实

revert_to 先把当前 context 文件旋转为备份,再逐行复制到指定 checkpoint 之前,重新构建 history/usage/system prompt/checkpoint 与 pending estimate;clear 也先旋转而非直接覆盖。

白话解释

读档时旧账本不会消失,而是改名存档;新账本只抄到目标存档点。

对自研 Harness 的含义

误回退可人工取回旋转文件;磁盘占用会随压缩/回退累计。

关键源码 · 实现
src/kimi_cli/soul/context.py · L123–L200
  123      async def checkpoint(self, add_user_message: bool):
  124          checkpoint_id = self._next_checkpoint_id
  125          self._next_checkpoint_id += 1
  126          logger.debug("Checkpointing, ID: {id}", id=checkpoint_id)
  127  
  128          async with aiofiles.open(self._file_backend, "a", encoding="utf-8") as f:
  129              await f.write(json.dumps({"role": "_checkpoint", "id": checkpoint_id}) + "\n")
  130          if add_user_message:
  131              await self.append_message(
  132                  Message(role="user", content=[system(f"CHECKPOINT {checkpoint_id}")])
  133              )
  134  
  135      async def revert_to(self, checkpoint_id: int):
  136          """
  137          Revert the context to the specified checkpoint.
  138          After this, the specified checkpoint and all subsequent content will be
  139          removed from the context. File backend will be rotated.
  140  
  141          Args:
  142              checkpoint_id (int): The ID of the checkpoint to revert to. 0 is the first checkpoint.
  143  
  144          Raises:
  145              ValueError: When the checkpoint does not exist.
  146              RuntimeError: When no available rotation path is found.
      … 44 lines omitted; exact range 123–200 …
  191                      line_json,
  192                      history=self._history,
  193                      messages_after_last_usage=messages_after_last_usage,
  194                      file_backend=rotated_file_path,
  195                      line_no=line_no,
  196                  )
  197                  if keep_line:
  198                      await new_file.write(line)
  199  
  200          self._pending_token_estimate = estimate_text_tokens(messages_after_last_usage)
查看全部 2 处证据
  • 实现 src/kimi_cli/soul/context.py:123–200 checkpoint 和 revert rotation/rebuild。
  • 实现 src/kimi_cli/soul/context.py:202–230 clear rotation。
10
L1事实kimi-context-003

压缩由阈值触发,摘要旧历史并保留最近轮次

源码事实

should_auto_compact 同时检查 context ratio 和 reserved context;SimpleCompaction 默认保留最近两组 user/assistant,把更早历史交 EmptyToolset 摘要、去除 thinking,再用 compaction prefix + summary + preserved messages 重建 context。

白话解释

箱子快满时,把旧账压成一页摘要,最近几轮原样保留;摘要过程不能再调用工具。

对自研 Harness 的含义

实现简单稳定,但摘要是有损的,字符/4 估算对 CJK 偏低,代码中也明确承认。

关键源码 · 实现
src/kimi_cli/soul/compaction.py · L37–L82
   37          The estimate is intentionally conservative — it will be replaced by the
   38          real value on the next LLM call.
   39          """
   40          if self.usage is not None and len(self.messages) > 0:
   41              summary_tokens = self.usage.output
   42              preserved_tokens = estimate_text_tokens(self.messages[1:])
   43              return summary_tokens + preserved_tokens
   44  
   45          return estimate_text_tokens(self.messages)
   46  
   47  
   48  def estimate_text_tokens(messages: Sequence[Message]) -> int:
   49      """Estimate tokens from message text content using a character-based heuristic."""
   50      total_chars = 0
   51      for msg in messages:
   52          for part in msg.content:
   53              if isinstance(part, TextPart):
   54                  total_chars += len(part.text)
   55      # ~4 chars per token for English; somewhat underestimates for CJK text,
   56      # but this is a temporary estimate that gets corrected on the next LLM call.
   57      return total_chars // 4
   58  
   59  
   60  def should_auto_compact(
      … 12 lines omitted; exact range 37–82 …
   73      return (
   74          token_count >= max_context_size * trigger_ratio
   75          or token_count + reserved_context_size >= max_context_size
   76      )
   77  
   78  
   79  @runtime_checkable
   80  class Compaction(Protocol):
   81      async def compact(
   82          self,
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/compaction.py:37–82 auto compact trigger 与 token estimate。
  • 实现 src/kimi_cli/soul/compaction.py:85–174 prepare/summary/preserve 实现。
  • 测试 tests/core/test_simple_compaction.py:1–120 压缩触发、preserve 与摘要契约。
11
L1事实kimi-context-004

压缩后显式恢复活动后台任务与动态约束状态

源码事实

root compaction 前估算摘要后请求预算;压缩成功后 clear/重写 system prompt/checkpoint/messages,再追加 active task snapshot、重设 token count、通知 injection providers reset,并发 CompactionEnd/telemetry/PostCompact。

白话解释

摘要不会让正在跑的 build/test 凭空消失;压缩后会重新贴一张活动任务清单,并让 Plan/AFK 提醒重新校准。

对自研 Harness 的含义

避免长后台任务在摘要后失联;活动任务快照本身也占上下文。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L1432–L1476
 1432          chat_provider = self._runtime.llm.chat_provider if self._runtime.llm is not None else None
 1433          compaction_overrides = None
 1434          if chat_provider is not None and isinstance(self._compaction, SimpleCompaction):
 1435              compact_message, to_preserve = self._compaction.prepare(
 1436                  self._context.history,
 1437                  custom_instruction=custom_instruction,
 1438              )
 1439              if compact_message is not None:
 1440                  post_compaction_history = [
 1441                      Message(
 1442                          role="user",
 1443                          content=[system(COMPACTION_OUTPUT_PREFIX)],
 1444                      ),
 1445                      *to_preserve,
 1446                  ]
 1447                  if self.is_root:
 1448                      active_task_snapshot = build_active_task_snapshot(
 1449                          self._runtime.background_tasks
 1450                      )
 1451                      if active_task_snapshot is not None:
 1452                          post_compaction_history.append(
 1453                              Message(
 1454                                  role="user",
 1455                                  content=[
      … 11 lines omitted; exact range 1432–1476 …
 1467                      self._agent.toolset.tools,
 1468                      post_compaction_history,
 1469                  )
 1470                  compaction_overrides = self._compute_completion_overrides(
 1471                      chat_provider,
 1472                      system_prompt=COMPACTION_SYSTEM_PROMPT,
 1473                      tools=(),
 1474                      history=[compact_message],
 1475                      input_tokens_floor=post_compaction_input_tokens,
 1476                  )
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:1432–1476 post-compaction history/budget 预估。
  • 实现 src/kimi_cli/soul/kimisoul.py:1573–1606 context 重建、task snapshot、provider reset。
  • 实现 src/kimi_cli/soul/kimisoul.py:1608–1644 compaction telemetry 与 PostCompact hook。
04
DIMENSION · TOOLS-EXECUTION

工具与执行

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

12
L1事实kimi-tools-001

工具表由 agent spec 动态装配,插件和 MCP 追加进入同一 Toolset

源码事实

load_agent 从 YAML 选 tools/allowed_tools 并应用 exclude_tools,通过依赖注入实例化;插件冲突时跳过;MCP config 验证后可后台加载或延迟到首轮。

白话解释

工具箱不是写死在循环里,而是由角色配置装配;本地插件和远程 MCP 最终都变成模型看到的同类工具。

对自研 Harness 的含义

角色最小权限容易表达;工具名称冲突按先到内建优先。

关键源码 · 实现
src/kimi_cli/soul/agent.py · L411–L451
  411      # Register built-in subagent types before loading tools because some tools render
  412      # descriptions from the labor market on initialization.
  413      for subagent_name, subagent_spec in agent_spec.subagents.items():
  414          logger.debug(
  415              "Registering builtin subagent type: {subagent_name}", subagent_name=subagent_name
  416          )
  417          builtin_spec = load_agent_spec(subagent_spec.path)
  418          tool_policy = (
  419              ToolPolicy(mode="allowlist", tools=tuple(builtin_spec.allowed_tools))
  420              if builtin_spec.allowed_tools is not None
  421              else ToolPolicy(mode="inherit")
  422          )
  423          runtime.labor_market.add_builtin_type(
  424              AgentTypeDefinition(
  425                  name=subagent_name,
  426                  description=subagent_spec.description,
  427                  agent_file=subagent_spec.path,
  428                  when_to_use=builtin_spec.when_to_use,
  429                  default_model=builtin_spec.model,
  430                  tool_policy=tool_policy,
  431              )
  432          )
  433  
  434      toolset = KimiToolset()
      … 7 lines omitted; exact range 411–451 …
  442          DenwaRenji: runtime.denwa_renji,
  443          Approval: runtime.approval,
  444          LaborMarket: runtime.labor_market,
  445          Environment: runtime.environment,
  446      }
  447      tools = agent_spec.allowed_tools if agent_spec.allowed_tools is not None else agent_spec.tools
  448      if agent_spec.exclude_tools:
  449          logger.debug("Excluding tools: {tools}", tools=agent_spec.exclude_tools)
  450          tools = [tool for tool in tools if tool not in agent_spec.exclude_tools]
  451      toolset.load_tools(tools, tool_deps)
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/agent.py:411–451 subagent policy 与 built-in tool loading。
  • 实现 src/kimi_cli/soul/agent.py:453–485 plugin/MCP append 与 deferred loading。
  • 配置 src/kimi_cli/agents/default/agent.yaml:1–36 root tool/subagent inventory。
13
L1事实kimi-tools-002

同一模型回复里的不同工具并发启动,完全重复调用共享结果

源码事实

Kosong 收到完整 tool call 即调用 Toolset.handle;KimiToolset 为每个新 call 创建 asyncio task。同 step 相同 name+canonical args 不重复执行,而是等待原 task 并复制 result。

白话解释

模型一口气开多张不同工单会一起跑;两张完全相同的工单只做一次,第二张拿同一结果。

对自研 Harness 的含义

吞吐高且减少重复副作用;不同工具之间没有全局串行保证。

关键源码 · 实现
packages/kosong/src/kosong/__init__.py · L134–L167
  134      tool_calls: list[ToolCall] = []
  135      tool_result_futures: dict[str, ToolResultFuture] = {}
  136  
  137      def future_done_callback(future: ToolResultFuture):
  138          if on_tool_result:
  139              try:
  140                  result = future.result()
  141                  on_tool_result(result)
  142              except asyncio.CancelledError:
  143                  return
  144  
  145      async def on_tool_call(tool_call: ToolCall):
  146          tool_calls.append(tool_call)
  147          result = toolset.handle(tool_call)
  148  
  149          if isinstance(result, ToolResult):
  150              future = ToolResultFuture()
  151              future.add_done_callback(future_done_callback)
  152              future.set_result(result)
  153              tool_result_futures[tool_call.id] = future
  154          else:
  155              result.add_done_callback(future_done_callback)
  156              tool_result_futures[tool_call.id] = result
  157  
  158      try:
  159          result = await generate(
  160              chat_provider,
  161              system_prompt,
  162              toolset.tools,
  163              history,
  164              on_message_part=on_message_part,
  165              on_tool_call=on_tool_call,
  166              on_trace_id=on_trace_id,
  167          )
查看全部 3 处证据
  • 实现 packages/kosong/src/kosong/__init__.py:134–167 tool call 到达即 handle 并登记 future。
  • 实现 src/kimi_cli/soul/toolset.py:343–423 same-step dedup/result sharing。
  • 实现 src/kimi_cli/soul/toolset.py:454–611 async tool task 与 hook/telemetry。
14
L1事实kimi-tools-003

跨 step 重复调用按 3/5/8/12 阶梯提醒并强停

源码事实

Toolset 对 canonical tool call 维护连续 streak:第 3 次开始提示换方法,第 5 次展示调用细节,第 8 次要求停止工具并总结,第 12 次设置 force_stop_turn。

白话解释

不是第一次重复就封杀,而是逐级提醒;连续十二次原地打转才硬踩刹车。

对自研 Harness 的含义

降低模型卡死和费用失控,也允许合理重试;canonicalization 只比较名称和 JSON 参数,不判断外部状态是否变化。

关键源码 · 实现
src/kimi_cli/soul/toolset.py · L116–L172
  116  _REMINDER_TEXT_1 = (
  117      "\n\n<system-reminder>\n"
  118      "You are repeating the exact same tool call with identical parameters."
  119      " Please carefully analyze the previous result. If the task is not yet complete,"
  120      " try a different method or parameters instead of repeating the same call."
  121      "\n</system-reminder>"
  122  )
  123  
  124  
  125  def _make_reminder_text_2(tool_name: str, repeat_count: int, canonical_args: str) -> str:
  126      return (
  127          "\n\n<system-reminder>\n"
  128          "You have repeatedly called the same tool with identical parameters many times.\n"
  129          "Repeated tool call detected:\n"
  130          f"- tool: {tool_name}\n"
  131          f"- repeated_times: {repeat_count}\n"
  132          f"- arguments: {canonical_args}\n"
  133          "The previous repeated calls did not make progress. Do not call this exact same tool "
  134          "with the exact same arguments again.\n"
  135          "Carefully inspect the latest tool result and choose a different next action, "
  136          "different parameters, or finish the task if enough evidence has been gathered."
  137          "\n</system-reminder>"
  138      )
  139  
      … 23 lines omitted; exact range 116–172 …
  163  ) -> tuple[RepeatAction, str | None]:
  164      if streak >= _REPEAT_FORCE_STOP_STREAK:
  165          return "stop", _REMINDER_TEXT_3
  166      if streak >= _REPEAT_REMINDER_3_START:
  167          return "r3", _REMINDER_TEXT_3
  168      if streak >= _REPEAT_REMINDER_2_START:
  169          return "r2", _make_reminder_text_2(tool_name, streak, canonical_args)
  170      if streak >= _REPEAT_REMINDER_1_START:
  171          return "r1", _REMINDER_TEXT_1
  172      return "none", None
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/toolset.py:116–172 repeat thresholds/reminders。
  • 实现 src/kimi_cli/soul/toolset.py:425–453 cross-step repeat tracking/force stop。
  • 实现 src/kimi_cli/soul/kimisoul.py:1338–1346 turn force-stop resolution。
15
L1事实kimi-tools-004

前台 Shell 有 5 分钟上限,后台任务可到 24 小时并持久通知

源码事实

Shell 参数限制前台 timeout <=300s、后台 <=86400s;两者都先 approval。前台通过 KAOS 流式读 stdout/stderr,取消/超时 kill 当前进程;后台交 BackgroundTaskManager 持久化,完成后自动通知,并可 TaskList/Output/Stop 管理。

白话解释

短命令当场等,长 build/server 作为有编号的后台任务继续跑,不用让对话一直卡住。

对自研 Harness 的含义

长任务体验完整;前台 LocalKaos.kill 只 kill 直接子进程,后台 worker 才显式管理整个进程组。

关键源码 · 契约
src/kimi_cli/tools/shell/__init__.py · L22–L57
   22  MAX_FOREGROUND_TIMEOUT = 5 * 60
   23  MAX_BACKGROUND_TIMEOUT = 24 * 60 * 60
   24  
   25  
   26  class Params(BaseModel):
   27      command: str = Field(description="The command to execute.")
   28      timeout: int = Field(
   29          description=(
   30              "The timeout in seconds for the command to execute. "
   31              "If the command takes longer than this, it will be killed."
   32          ),
   33          default=60,
   34          ge=1,
   35          le=MAX_BACKGROUND_TIMEOUT,
   36      )
   37      run_in_background: bool = Field(
   38          default=False,
   39          description="Whether to run the command as a background task.",
   40      )
   41      description: str = Field(
   42          default="",
   43          description=(
   44              "A short description for the background task. Required when run_in_background=true."
   45          ),
      … 2 lines omitted; exact range 22–57 …
   48      @model_validator(mode="after")
   49      def _validate_background_fields(self) -> Self:
   50          if self.run_in_background and not self.description.strip():
   51              raise ValueError("description is required when run_in_background is true")
   52          if not self.run_in_background and self.timeout > MAX_FOREGROUND_TIMEOUT:
   53              raise ValueError(
   54                  f"timeout must be <= {MAX_FOREGROUND_TIMEOUT}s for foreground commands; "
   55                  f"use run_in_background=true for longer timeouts (up to {MAX_BACKGROUND_TIMEOUT}s)"
   56              )
   57          return self
查看全部 4 处证据
  • 契约 src/kimi_cli/tools/shell/__init__.py:22–57 前后台 timeout validation。
  • 实现 src/kimi_cli/tools/shell/__init__.py:81–142 foreground approval/stream/timeout。
  • 实现 src/kimi_cli/tools/shell/__init__.py:144–219 background dispatch 与 task hints。
  • 实现 src/kimi_cli/background/worker.py:87–169 process-group termination/timeout escalation。
05
DIMENSION · SECURITY-SANDBOX

安全与沙箱

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

16
L1事实kimi-security-001

统一审批支持单次、整会话、拒绝反馈、YOLO 与 AFK

源码事实

Approval 绑定当前 tool call/source;普通请求进入共享 ApprovalRuntime/wire。approve_for_session 缓存 action 并批准同 action pending requests;拒绝反馈返回模型。YOLO 自动批准,AFK 也隐含自动批准且可持久或仅本次 invocation。

白话解释

每种危险动作可这次放行、整场放行或拒绝并告诉模型原因;无人值守模式等同自动批准。

对自研 Harness 的含义

root、前台和后台子 Agent 共用一个审批面;AFK 是高风险开关,不能理解为只关闭提问。

关键源码 · 实现
src/kimi_cli/soul/approval.py · L130–L199
  130  class Approval:
  131      def __init__(
  132          self,
  133          yolo: bool = False,
  134          *,
  135          state: ApprovalState | None = None,
  136          runtime: ApprovalRuntime | None = None,
  137      ):
  138          self._state = state or ApprovalState(yolo=yolo)
  139          self._runtime = runtime or ApprovalRuntime()
  140  
  141      def share(self) -> Approval:
  142          """Create a new approval queue that shares approval state."""
  143          return Approval(state=self._state, runtime=self._runtime)
  144  
  145      def set_runtime(self, runtime: ApprovalRuntime) -> None:
  146          self._runtime = runtime
  147  
  148      @property
  149      def runtime(self) -> ApprovalRuntime:
  150          return self._runtime
  151  
  152      def set_yolo(self, yolo: bool) -> None:
  153          self._state.yolo = yolo
      … 36 lines omitted; exact range 130–199 …
  190          return self._state.afk or self._state.runtime_afk
  191  
  192      def is_afk_flag(self) -> bool:
  193          """True only when persisted afk mode is active."""
  194          return self._state.afk
  195  
  196      def is_runtime_afk(self) -> bool:
  197          """True only when afk came from this invocation."""
  198          return self._state.runtime_afk
  199  
查看全部 4 处证据
  • 实现 src/kimi_cli/soul/approval.py:130–199 shared state、YOLO/AFK semantics。
  • 实现 src/kimi_cli/soul/approval.py:200–299 tool-bound approval request。
  • 实现 src/kimi_cli/soul/approval.py:336–396 approve/session cache/reject。
  • 实现 src/kimi_cli/approval_runtime/runtime.py:61–152 request/wait/resolve runtime。
17
L1事实kimi-security-002

Plan 模式不是隐藏工具,而是写工具调用时再强制拒绝

源码事实

KimiSoul 把 plan-mode checker/path 绑定给 WriteFile/StrReplaceFile,并明确工具不 hide/unhide;Plan 子 Agent 的 YAML 则代码级 allowlist 不包含 Shell/写工具,测试验证。

白话解释

root 的 Plan 模式仍让模型知道写工具存在,但真调用时门禁拦下;专门 plan 子 Agent 更严格,工具箱里压根没有写和 shell。

对自研 Harness 的含义

运行时 gate 能给出清楚反馈;真正最小权限应优先用 subagent allowlist。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L409–L463
  409      def _bind_plan_mode_tools(self) -> None:
  410          """Bind plan mode state to tools that support it."""
  411          if not isinstance(self._agent.toolset, KimiToolset):
  412              return
  413  
  414          def checker() -> bool:
  415              return self._plan_mode
  416  
  417          def path_getter() -> Path | None:
  418              return self.get_plan_file_path()
  419  
  420          # WriteFile gets both checker and path_getter (for plan file auto-approve)
  421          from kimi_cli.tools.file.write import WriteFile
  422  
  423          write_tool = self._agent.toolset.find("WriteFile")
  424          if isinstance(write_tool, WriteFile):
  425              write_tool.bind_plan_mode(checker, path_getter)
  426  
  427          from kimi_cli.tools.file.replace import StrReplaceFile
  428  
  429          replace_tool = self._agent.toolset.find("StrReplaceFile")
  430          if isinstance(replace_tool, StrReplaceFile):
  431              replace_tool.bind_plan_mode(checker, path_getter)
  432  
      … 21 lines omitted; exact range 409–463 …
  454                  self._approval.is_auto_approve,
  455              )
  456  
  457          # AskUserQuestion — bind afk checker for auto-dismiss.
  458          # Yolo alone keeps the tool live; only afk (no user present) dismisses.
  459          from kimi_cli.tools.ask_user import AskUserQuestion
  460  
  461          ask_tool = self._agent.toolset.find("AskUserQuestion")
  462          if isinstance(ask_tool, AskUserQuestion):
  463              ask_tool.bind_afk(self._approval.is_afk)
查看全部 4 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:409–463 plan checker/tool binding。
  • 契约 src/kimi_cli/soul/kimisoul.py:519–526 工具不隐藏、call-time reject。
  • 配置 src/kimi_cli/agents/default/plan.yaml:14–29 plan agent allow/exclude tools。
  • 测试 tests/core/test_subagent_builder.py:63–86 plan agent 无 Shell/写工具。
18
L1限制kimi-security-003

默认本地 KAOS 是宿主执行抽象,不是 OS 级沙箱

源码事实

默认 system prompt 明确 operating environment is not in a sandbox;LocalKaos 直接用 pathlib/aiofiles 操作宿主路径,并用 asyncio.create_subprocess_exec 启动宿主进程,没有容器、seatbelt、seccomp 或 restricted token。

白话解释

KAOS 让同一套代码能接本地或 SSH,但没有把命令关进隔离房间;一旦用户批准,进程拿的是当前用户权限。

对自研 Harness 的含义

企业场景必须把 Kimi CLI 外包进容器/VM/受限账户,审批与提示词不能替代隔离。

关键源码 · Prompt
src/kimi_cli/agents/default/system.md · L67–L81
   67  # Working Environment
   68  
   69  ## Operating System
   70  
   71  You are running on **${KIMI_OS}**. The Shell tool executes commands using **${KIMI_SHELL}**.{% if KIMI_OS == "Windows" %} Use Unix shell syntax inside Shell commands — `/dev/null` not `NUL`, forward slashes in paths (backslashes are escape characters in bash).{% endif +%}
   72  
   73  The operating environment is not in a sandbox. Any actions you do will immediately affect the user's system. So you MUST be extremely cautious. Unless being explicitly instructed to do so, you should never access (read/write/execute) files outside of the working directory.
   74  
   75  ## Date and Time
   76  
   77  The current date and time in ISO format is `${KIMI_NOW}`. This is only a reference for you when searching the web, or checking file modification time, etc. If you need the exact time, use Shell tool with proper command.
   78  
   79  ## Working Directory
   80  
   81  The current working directory is `${KIMI_WORK_DIR}`. This should be considered as the project root if you are instructed to perform tasks on the project. Every file system operation will be relative to the working directory if you do not explicitly specify the absolute path. Tools may require absolute paths for some parameters, IF SO, YOU MUST use absolute paths for these parameters.
查看全部 3 处证据
  • Prompt src/kimi_cli/agents/default/system.md:67–81 明确声明环境非 sandbox。
  • 实现 packages/kaos/src/kaos/local.py:31–78 本地 filesystem/cwd 直接映射。
  • 实现 packages/kaos/src/kaos/local.py:139–176 宿主文件写入与 subprocess exec。
06
DIMENSION · MCP-PLUGINS-HOOKS

MCP、插件与 Hooks

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

19
L1事实kimi-hooks-001

Hook 同时支持本地命令与客户端 wire subscription

源码事实

HookEngine 按 regex 匹配并去重 server command,同时加入 wire subscriptions,并发执行;任意 result=block 即整体 block。UserPromptSubmit、Pre/PostToolUse、Stop/Failure、Compact、Notification、Subagent 等事件均接入。

白话解释

组织可以在模型动作前后插入自己的门卫/审计脚本,也可以让 IDE 客户端参与判断。

对自研 Harness 的含义

扩展面完整;engine、命令错误与超时通常 fail-open,只有成功返回 block/exit 2 才阻止。

关键源码 · 契约
src/kimi_cli/hooks/engine.py · L65–L91
   65  class HookEngine:
   66      """Loads hook definitions and executes matching hooks in parallel.
   67  
   68      Supports two hook sources:
   69      - Server-side (config.toml): shell commands executed locally
   70      - Client-side (wire subscriptions): forwarded to client via HookRequest
   71      """
   72  
   73      def __init__(
   74          self,
   75          hooks: list[HookDef] | None = None,
   76          cwd: str | None = None,
   77          *,
   78          on_triggered: OnTriggered | None = None,
   79          on_resolved: OnResolved | None = None,
   80          on_wire_hook: OnWireHookRequest | None = None,
   81      ):
   82          self._hooks: list[HookDef] = list(hooks) if hooks else []
   83          self._wire_subs: list[WireHookSubscription] = []
   84          self._cwd = cwd
   85          self._on_triggered = on_triggered
   86          self._on_resolved = on_resolved
   87          self._on_wire_hook = on_wire_hook
   88          self._by_event: dict[str, list[HookDef]] = {}
   89          self._wire_by_event: dict[str, list[WireHookSubscription]] = {}
   90          self._pending_fire_and_forget: set[asyncio.Task[Any]] = set()
   91          self._rebuild_index()
查看全部 4 处证据
  • 契约 src/kimi_cli/hooks/engine.py:65–91 server/wire hook sources。
  • 实现 src/kimi_cli/hooks/engine.py:205–256 match、fail-open 与 telemetry isolation。
  • 实现 src/kimi_cli/hooks/engine.py:287–319 parallel execution 与 block aggregation。
  • 实现 src/kimi_cli/hooks/runner.py:27–89 shell hook exit/timeout semantics。
20
L1风险kimi-plugin-001

插件工具是经审批的本地子进程,可获得新鲜 Host 凭证

源码事实

PluginTool 每次调用先请求 action=plugin:name 审批,把 JSON params 写 stdin,在插件目录执行声明 command,120 秒超时;inject mapping 可把当前 API key/base URL 注入干净环境。插件安装校验名称防 path traversal,并用同文件系统 staging swap。

白话解释

插件本质是本机程序,不是受限脚本;它能按配置拿到主机凭证,所以安装来源和权限同样重要。

对自研 Harness 的含义

能力强但供应链风险高;approval 只确认“运行插件”,不审计插件内部每个文件/网络动作。

关键源码 · 实现
src/kimi_cli/plugin/tool.py · L37–L130
   37  class PluginTool(CallableTool):
   38      """A tool that executes a plugin command in a subprocess.
   39  
   40      Parameters are passed via stdin as JSON.
   41      stdout is captured as the tool result.
   42      Host credentials are injected as environment variables at runtime
   43      (not baked into config files) to handle OAuth token refresh.
   44      """
   45  
   46      def __init__(
   47          self,
   48          tool_spec: PluginToolSpec,
   49          plugin_dir: Path,
   50          *,
   51          inject: dict[str, str],
   52          config: Config,
   53          approval: Approval | None = None,
   54          **kwargs: Any,
   55      ):
   56          super().__init__(
   57              name=tool_spec.name,
   58              description=tool_spec.description,
   59              parameters=tool_spec.parameters or {"type": "object", "properties": {}},
   60              **kwargs,
      … 60 lines omitted; exact range 37–130 …
  121              error_msg = err_output or output or f"Exit code {proc.returncode}"
  122              return ToolError(
  123                  message=f"Plugin tool '{self.name}' failed: {error_msg}",
  124                  brief=f"Exit {proc.returncode}",
  125              )
  126  
  127          if err_output:
  128              logger.debug("Plugin tool {name} stderr: {err}", name=self.name, err=err_output)
  129  
  130          return ToolOk(output=output)
查看全部 3 处证据
  • 实现 src/kimi_cli/plugin/tool.py:37–130 approval、credential env、subprocess/timeout。
  • 实现 src/kimi_cli/plugin/manager.py:54–108 name validation、staging install/swap。
  • 测试 tests/core/test_plugin_tool.py:49–153 stdin/stdout/error/credential injection tests。
21
L1事实kimi-mcp-001

MCP 延迟启动、逐服务器状态化,并对富媒体共享 100K 字符预算

源码事实

agent 可 defer MCP,首个 agent loop 后台启动并等待,向 UI 发 loading/status;server 状态区分 connected/unauthorized/failed。MCP 结果的文本、image/audio/video data URL 共用 100000 字符预算,超额媒体丢弃并加 truncation notice。

白话解释

远程工具不必拖慢 CLI 启动,但真正开始工作前会等它们连好;一个巨型网页 DOM 或截图不能把上下文塞爆。

对自研 Harness 的含义

体验和上下文安全较好;首轮仍会被 MCP 连接完成阻塞,OAuth token 持久落在 share dir。

关键源码 · 实现
src/kimi_cli/soul/agent.py · L467–L485
  467      if mcp_configs:
  468          validated_mcp_configs: list[MCPConfig] = []
  469          if mcp_configs:
  470              from fastmcp.mcp_config import MCPConfig
  471  
  472              for mcp_config in mcp_configs:
  473                  try:
  474                      validated_mcp_configs.append(
  475                          mcp_config
  476                          if isinstance(mcp_config, MCPConfig)
  477                          else MCPConfig.model_validate(mcp_config)
  478                      )
  479                  except pydantic.ValidationError as e:
  480                      raise MCPConfigError(f"Invalid MCP config: {e}") from e
  481          if start_mcp_loading:
  482              await toolset.load_mcp_tools(validated_mcp_configs, runtime, in_background=True)
  483          else:
  484              toolset.defer_mcp_tool_loading(validated_mcp_configs, runtime)
  485  
查看全部 4 处证据
  • 实现 src/kimi_cli/soul/agent.py:467–485 MCP validation/background/defer。
  • 实现 src/kimi_cli/soul/kimisoul.py:962–993 首轮 loading/status/wait。
  • 实现 src/kimi_cli/soul/toolset.py:1019–1080 100K shared MCP result budget。
  • 测试 tests/tools/test_mcp_tool_result.py:30–138 text/media truncation regression tests。
07
DIMENSION · INSTRUCTIONS-SKILLS

指令与 Skills

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

22
L1事实kimi-instructions-001

系统指令是 Jinja 模板,运行环境与项目说明在启动时冻结

源码事实

load_agent 用 StrictUndefined Jinja 渲染 system.md 和 builtin/spec args;Context 首次写入 _system_prompt,子 Agent resume 时优先复用持久 prompt 而非当前模板。

白话解释

系统提示词像带变量的表单,启动时填入 OS、shell、目录、文件树、AGENTS 和技能;恢复旧子 Agent 时继续沿用当时版本。

对自研 Harness 的含义

保证 resume 行为稳定;模板升级不会自动改变旧子 Agent 的规则。

关键源码 · 实现
src/kimi_cli/soul/agent.py · L494–L517
  494  def _load_system_prompt(
  495      path: Path, args: dict[str, str], builtin_args: BuiltinSystemPromptArgs
  496  ) -> str:
  497      logger.info("Loading system prompt: {path}", path=path)
  498      system_prompt = path.read_text(encoding="utf-8").strip()
  499      logger.debug(
  500          "Substituting system prompt with builtin args: {builtin_args}, spec args: {spec_args}",
  501          builtin_args=builtin_args,
  502          spec_args=args,
  503      )
  504      env = JinjaEnvironment(
  505          loader=FileSystemLoader(path.parent),
  506          keep_trailing_newline=True,
  507          lstrip_blocks=True,
  508          trim_blocks=True,
  509          variable_start_string="${",
  510          variable_end_string="}",
  511          undefined=StrictUndefined,
  512      )
  513      try:
  514          template = env.from_string(system_prompt)
  515          return template.render(asdict(builtin_args), **args)
  516      except UndefinedError as exc:
  517          raise SystemPromptTemplateError(f"Missing system prompt arg in {path}: {exc}") from exc
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/agent.py:494–517 StrictUndefined Jinja render。
  • 实现 src/kimi_cli/subagents/core.py:58–69 resume reuse/persist system prompt。
  • Prompt src/kimi_cli/agents/default/system.md:67–117 environment/AGENTS prompt slots。
23
L1事实kimi-instructions-002

AGENTS.md 按 root→cwd 合并,叶子优先分享 32KiB 总预算

源码事实

load_agents_md 从 project root 走到 work dir,每层检查 .kimi/AGENTS.md、AGENTS.md、agents.md;普通大小写候选按优先级择一而 .kimi 可并存,内容预算从叶子向根分配,最后按根到叶顺序拼接并标源。

白话解释

越靠近正在工作的目录越有机会完整进入上下文,但展示顺序仍是先总规则、后局部规则。

对自研 Harness 的含义

符合层级覆盖直觉;超过 32KiB 的上层说明可能被截短。

关键源码 · 实现
src/kimi_cli/soul/agent.py · L87–L168
   87  async def load_agents_md(work_dir: KaosPath) -> str | None:
   88      """Discover and merge ``AGENTS.md`` files from the project root down to *work_dir*.
   89  
   90      For each directory on the path, the following candidates are checked in order:
   91  
   92      1. ``.kimi/AGENTS.md``  — project-local kimi config (highest priority)
   93      2. ``AGENTS.md``        — standard location
   94      3. ``agents.md``        — lowercase variant (mutually exclusive with 2)
   95  
   96      Within a single directory, ``.kimi/AGENTS.md`` and ``AGENTS.md``/``agents.md``
   97      are **both** loaded (with ``.kimi/`` first), but ``AGENTS.md`` and ``agents.md``
   98      are mutually exclusive (uppercase wins).
   99  
  100      All discovered files are concatenated root→leaf, separated by ``\\n\\n``, with
  101      source annotations.  Total size is capped at :data:`_AGENTS_MD_MAX_BYTES`.
  102      Budget is allocated leaf-first so deeper (more specific) files are never
  103      truncated in favour of shallower ones.
  104      """
  105      project_root = await find_project_root(work_dir)
  106      dirs = await _dirs_root_to_leaf(work_dir, project_root)
  107  
  108      # Phase 1: collect all candidate files (root → leaf order)
  109      discovered: list[tuple[KaosPath, str]] = []  # (path, content)
  110      for d in dirs:
      … 48 lines omitted; exact range 87–168 …
  159          remaining -= len(content.encode())
  160          budgeted[i] = (path, content)
  161  
  162      # Phase 3: assemble in root → leaf order, skipping entries emptied by truncation
  163      parts: list[str] = []
  164      for path, content in budgeted:
  165          if content:
  166              parts.append(f"<!-- From: {path} -->\n{content}")
  167  
  168      return "\n\n".join(parts) if parts else None
查看全部 2 处证据
  • 实现 src/kimi_cli/soul/agent.py:87–168 AGENTS discovery、precedence、budget、assembly。
  • Prompt src/kimi_cli/agents/default/system.md:99–123 AGENTS precedence/user priority 说明。
24
L1事实kimi-skills-001

Skills 跨 kimi/claude/codex 目录合并,并映射为 slash/flow 命令

源码事实

Config 默认 merge_all_available_skills=true,支持 extra skill dirs;system prompt 只列摘要并要求按需读取 SKILL.md。KimiSoul 把 standard/flow skill 注册为 slash command,flow 还构造成 FlowRunner。

白话解释

技能不是把全文常驻提示词,而是先给目录卡片,需要时再读;同一套 CLI 还能复用其他 Agent 生态的技能目录。

对自研 Harness 的含义

节省上下文并增强兼容;skill 发现冲突需依赖 scope precedence。

关键源码 · 配置
src/kimi_cli/config.py · L242–L259
  242      merge_all_available_skills: bool = Field(
  243          default=True,
  244          description=(
  245              "Merge skills from all existing brand directories (kimi/claude/codex) "
  246              "instead of using only the first one found. Defaults to true so users "
  247              "who keep skills in multiple brand directories see everything out of "
  248              "the box; set to false to restore the first-match-only behaviour."
  249          ),
  250      )
  251      extra_skill_dirs: list[str] = Field(
  252          default_factory=list,
  253          description=(
  254              "Extra directories to discover skills from, added on top of the "
  255              "built-in / user / project locations. Each entry may be an absolute "
  256              "path, ``~``-prefixed (expanded against $HOME), or relative to the "
  257              "project root (the nearest ``.git`` directory above the work dir). "
  258              "Missing paths are silently skipped."
  259          ),
查看全部 3 处证据
  • 配置 src/kimi_cli/config.py:242–259 跨品牌 merge 与 extra dirs。
  • Prompt src/kimi_cli/agents/default/system.md:125–148 skill scope/on-demand instructions。
  • 实现 src/kimi_cli/soul/kimisoul.py:854–900 skill/flow slash command registration。
08
DIMENSION · COLLABORATION-SUBAGENTS

子 Agent 与协作

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

25
L1事实kimi-subagent-001

内建 coder/explore/plan 用代码级工具白名单切分角色

源码事实

root 加载 spec 时为每个 subagent 注册 AgentTypeDefinition 与 allowlist policy;coder 有 Shell/写工具但无 Agent/AskUser/Todo,explore 无写工具但仍有 Shell,plan 连 Shell 也没有。SubagentBuilder 不加载 MCP。

白话解释

主 Agent 能雇三种工人:能改代码、只探索、只规划;每种工人拿到的钥匙不同,而且不能继续无限招下级。

对自研 Harness 的含义

避免递归爆炸并缩小权限;explore 的 Shell 只读要求部分依赖 prompt,不是命令级只读 parser。

边界
  • explore 虽无文件写工具,但 Shell 本身能运行任意获批命令;只读 Shell 主要由 prompt 约束。
关键源码 · 实现
src/kimi_cli/soul/agent.py · L411–L431
  411      # Register built-in subagent types before loading tools because some tools render
  412      # descriptions from the labor market on initialization.
  413      for subagent_name, subagent_spec in agent_spec.subagents.items():
  414          logger.debug(
  415              "Registering builtin subagent type: {subagent_name}", subagent_name=subagent_name
  416          )
  417          builtin_spec = load_agent_spec(subagent_spec.path)
  418          tool_policy = (
  419              ToolPolicy(mode="allowlist", tools=tuple(builtin_spec.allowed_tools))
  420              if builtin_spec.allowed_tools is not None
  421              else ToolPolicy(mode="inherit")
  422          )
  423          runtime.labor_market.add_builtin_type(
  424              AgentTypeDefinition(
  425                  name=subagent_name,
  426                  description=subagent_spec.description,
  427                  agent_file=subagent_spec.path,
  428                  when_to_use=builtin_spec.when_to_use,
  429                  default_model=builtin_spec.model,
  430                  tool_policy=tool_policy,
  431              )
查看全部 3 处证据
  • 实现 src/kimi_cli/soul/agent.py:411–431 subagent type/tool policy registration。
  • 实现 src/kimi_cli/subagents/builder.py:12–36 subagent runtime/model/load without MCP。
  • 测试 tests/core/test_subagent_builder.py:13–86 coder/explore/plan tool contracts。
26
L1事实kimi-subagent-002

子 Agent 是可恢复的持久实例,可前台或后台运行

源码事实

Agent tool 可新建或按 agent_id resume,前台默认无 timeout、后台默认配置 timeout,均上限 1 小时;实例独立保存 context.jsonl、wire.jsonl、meta、prompt、output。resume 复用历史和原始 type,并拒绝并发 resume。

白话解释

子 Agent 不是一次性函数调用,而是有身份证和独立笔记本的小会话;以后可以继续找同一个人接着做。

对自研 Harness 的含义

适合长期分工;需要清理实例磁盘,并防止后台和前台同时写同一上下文。

关键源码 · 契约
src/kimi_cli/tools/agent/__init__.py · L17–L60
   17  MAX_FOREGROUND_TIMEOUT = 60 * 60  # 1 hour
   18  MAX_BACKGROUND_TIMEOUT = 60 * 60  # 1 hour
   19  
   20  
   21  class Params(BaseModel):
   22      description: str = Field(description="A short (3-5 word) description of the task")
   23      prompt: str = Field(description="The task for the agent to perform")
   24      subagent_type: str = Field(
   25          default="coder",
   26          description="The built-in agent type to use. Defaults to `coder`.",
   27      )
   28      model: str | None = Field(
   29          default=None,
   30          description=(
   31              "Optional model override. Selection priority is: this parameter, then the built-in "
   32              "type default model, then the parent agent's current model."
   33          ),
   34      )
   35      resume: str | None = Field(
   36          default=None,
   37          description="Optional agent ID to resume instead of creating a new instance.",
   38      )
   39      run_in_background: bool = Field(
   40          default=False,
      … 10 lines omitted; exact range 17–60 …
   51              "Foreground: no default timeout (runs until completion), max 3600s (1hr). "
   52              "Background: default from config (15min), max 3600s (1hr). "
   53              "The agent is stopped if it exceeds this limit."
   54          ),
   55          ge=30,
   56          le=MAX_BACKGROUND_TIMEOUT,
   57      )
   58  
   59      @property
   60      def effective_timeout(self) -> int | None:
查看全部 4 处证据
  • 契约 src/kimi_cli/tools/agent/__init__.py:17–60 foreground/background/resume/timeout params。
  • 实现 src/kimi_cli/subagents/store.py:64–125 per-agent artifacts/store。
  • 实现 src/kimi_cli/subagents/runner.py:357–391 resume identity/concurrency guard/new instance。
  • 测试 tests/core/test_subagent_resume_e2e.py:76–148 resume accumulates context。
27
L1事实kimi-subagent-003

子 Agent 共享审批/任务/通知底座,但拥有独立 soul/context/模型

源码事实

Runtime.copy_for_subagent 共享 session、approval state/runtime、labor market、environment、notifications、background manager、store/root wire hub,创建独立 DenwaRenji 与 role;builder 可按 tool override→type default→parent 顺序克隆模型。子 Agent wire events 包装回 parent tool call,approval request 直达 root。

白话解释

工人各有自己的对话脑和可选模型,但共用老板的审批台、后台任务台和通知总线。

对自研 Harness 的含义

协作可观测且审批统一;共享 session 级资源使隔离不是进程级/租户级。

关键源码 · 实现
src/kimi_cli/soul/agent.py · L339–L369
  339      def copy_for_subagent(
  340          self,
  341          *,
  342          agent_id: str,
  343          subagent_type: str,
  344          llm_override: LLM | None = None,
  345      ) -> Runtime:
  346          """Clone runtime for a subagent."""
  347          return Runtime(
  348              config=self.config,
  349              oauth=self.oauth,
  350              llm=llm_override if llm_override is not None else self.llm,
  351              session=self.session,
  352              builtin_args=self.builtin_args,
  353              denwa_renji=DenwaRenji(),  # subagent must have its own DenwaRenji
  354              approval=self.approval.share(),
  355              labor_market=self.labor_market,
  356              environment=self.environment,
  357              notifications=self.notifications,
  358              background_tasks=self.background_tasks.copy_for_role("subagent"),
  359              skills=self.skills,
  360              # Share the same list reference so /add-dir mutations propagate to all agents
  361              additional_dirs=self.additional_dirs,
  362              skills_dirs=self.skills_dirs,
  363              subagent_store=self.subagent_store,
  364              approval_runtime=self.approval_runtime,
  365              root_wire_hub=self.root_wire_hub,
  366              subagent_id=agent_id,
  367              subagent_type=subagent_type,
  368              role="subagent",
  369          )
查看全部 4 处证据
  • 实现 src/kimi_cli/soul/agent.py:339–369 copy_for_subagent shared/isolated fields。
  • 实现 src/kimi_cli/subagents/builder.py:19–42 model priority/runtime clone。
  • 实现 src/kimi_cli/subagents/runner.py:242–288 stable approval source/hooks/run。
  • 实现 src/kimi_cli/subagents/runner.py:393–425 wire routing to parent/root。
09
DIMENSION · PERSISTENCE-OBSERVABILITY-MATURITY

持久化、观测与成熟度

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

28
L1事实kimi-observe-001

Wire 事件与 trace id 贯穿 turn、step、tool、approval、MCP、compaction

源码事实

KimiSoul 发 Turn/Step/Retry/Status/Compaction/MCP 等 wire events;provider x-trace-id 存 ContextVar 并继承到工具 task;Toolset 记录 outcome/duration/dedup/error,approval 记录 surface/mode/result。

白话解释

界面看到的不是一行最终文本,而是一条可还原执行过程的事件河流,并能把 API 请求、工具和审批串起来。

对自研 Harness 的含义

适合 IDE/ACP/Wire 客户端和故障分析;不是完整 deterministic replay,外部副作用仍不可重放。

关键源码 · 实现
src/kimi_cli/soul/kimisoul.py · L1009–L1076
 1009              # ── 2b. Step Begin ──────────────────────────────────────────────────
 1010              wire_send(StepBegin(n=step_no))
 1011              back_to_the_future: BackToTheFuture | None = None
 1012              step_outcome: StepOutcome | None = None
 1013  
 1014              try:
 1015                  # ── 2c. Context Compaction ──────────────────────────────────────
 1016                  if should_auto_compact(
 1017                      self._context.token_count_with_pending,
 1018                      self._runtime.llm.max_context_size,
 1019                      trigger_ratio=self._loop_control.compaction_trigger_ratio,
 1020                      reserved_context_size=self._loop_control.reserved_context_size,
 1021                  ):
 1022                      logger.info("Context too long, compacting...")
 1023                      try:
 1024                          await self.compact_context()
 1025                      except Exception as compact_err:
 1026                          logger.error(
 1027                              "Context compaction failed at step {step_no}: {error_type}: {error}",
 1028                              step_no=step_no,
 1029                              error_type=type(compact_err).__name__,
 1030                              error=compact_err,
 1031                          )
 1032                          raise
      … 34 lines omitted; exact range 1009–1076 …
 1067                              session_id=self._runtime.session.id,
 1068                              cwd=str(Path.cwd()),
 1069                              error_type=type(e).__name__,
 1070                              error_message=str(e),
 1071                          ),
 1072                      )
 1073                  )
 1074                  _hook_task.add_done_callback(lambda t: t.exception() if not t.cancelled() else None)
 1075                  # break the agent loop
 1076                  raise
查看全部 4 处证据
  • 实现 src/kimi_cli/soul/kimisoul.py:1009–1076 step lifecycle wire/error hook。
  • 实现 src/kimi_cli/telemetry/__init__.py:52–71 task-local trace id。
  • 实现 src/kimi_cli/soul/toolset.py:483–591 tool telemetry/hooks。
  • 实现 src/kimi_cli/soul/approval.py:36–67 permission result dimensions。
29
L1事实kimi-observe-002

匿名遥测默认开启但可配置/环境变量关闭,代码禁止传用户内容

源码事实

Config telemetry 默认 true;app 在 false 或 KIMI_DISABLE_TELEMETRY 时永久 disable。track 只接受 primitive properties,注释明确禁止 user input、file paths、code snippets;sink 30 秒或 50 条 flush,网络失败写本地 JSONL 下次重试。

白话解释

默认会上报事件名、耗时、模型/平台等运行指标,但设计规则不允许把提示词、路径和代码塞进事件;用户可以关闭。

对自研 Harness 的含义

隐私边界主要靠调用方遵守字段规范与 primitive validator,不是自动内容脱敏器。

关键源码 · 配置
src/kimi_cli/config.py · L261–L264
  261      telemetry: bool = Field(
  262          default=True,
  263          description="Enable anonymous telemetry to help improve kimi-cli. Set to false to disable.",
  264      )
查看全部 4 处证据
  • 配置 src/kimi_cli/config.py:261–264 telemetry default/opt-out。
  • 实现 src/kimi_cli/app.py:329–352 config/env disable 与 sink setup。
  • 契约 src/kimi_cli/telemetry/__init__.py:176–204 nonblocking track 和 no-content rule。
  • 实现 src/kimi_cli/telemetry/sink.py:19–88 buffer/threshold/periodic flush。
30
L2事实kimi-maturity-001

会话、子 Agent 与遥测均有损坏/并发防护,许可证为 Apache-2.0

源码事实

Session state 保存采用 fresh read-modify-write,Context 跳过坏 JSONL,SubagentStore 跳过非法 meta,approval 按 source 生命周期取消 pending;项目 LICENSE 为 Apache License 2.0。

白话解释

它把“崩一次后还能继续”和“后台任务结束后别留下悬空审批”当成正式设计,而不是只做 happy path。

对自研 Harness 的含义

工程成熟度较高;跨文件 state/context/wire 并非单事务,极端断电仍可能出现局部不同步。

关键源码 · 实现
src/kimi_cli/session.py · L84–L97
   84      def save_state(self) -> None:
   85          """Persist the session state to disk.
   86  
   87          Reloads externally-mutable fields (title, archive) from disk first
   88          to avoid overwriting concurrent changes made by the web API.
   89          """
   90          fresh = load_session_state(self.dir)
   91          self.state.custom_title = fresh.custom_title
   92          self.state.title_generated = fresh.title_generated
   93          self.state.title_generate_attempts = fresh.title_generate_attempts
   94          self.state.archived = fresh.archived
   95          self.state.archived_at = fresh.archived_at
   96          self.state.auto_archive_exempt = fresh.auto_archive_exempt
   97          save_session_state(self.state, self.dir)
查看全部 4 处证据
  • 实现 src/kimi_cli/session.py:84–97 fresh state merge/save。
  • 实现 src/kimi_cli/subagents/store.py:163–196 invalid metadata skip。
  • 实现 src/kimi_cli/soul/kimisoul.py:832–839 turn-source approval cleanup。
  • 契约 LICENSE:1–6 Apache License 2.0。
APPENDIX · SOURCE INDEX

本报告引用过的实现文件

这是一份代码阅读索引,不是仓库文件总表。机器候选扫描覆盖整个仓库;进入结论的文件必须经人工沿调用链复核。

  1. 01src/kimi_cli/soul/kimisoul.pyL659–742, 841–852, 998–1041, 1132–1194, 1196–1216, 1274–1295, 622–653, 1099–1109, 1312–1336, 1220–1249, 1647–1658, 1660–1743, 1365–1387, 1432–1476, 1573–1606, 1608–1644, 1338–1346, 409–463, 519–526, 962–993, 854–900, 1009–1076, 832–839
  2. 02packages/kosong/src/kosong/_generate.pyL52–103
  3. 03packages/kosong/src/kosong/__init__.pyL104–174, 134–167
  4. 04src/kimi_cli/llm.pyL326–470, 472–501, 181–263
  5. 05src/kimi_cli/soul/context.pyL20–65, 232–248, 250–339, 123–200, 202–230
  6. 06src/kimi_cli/soul/compaction.pyL37–82, 85–174
  7. 07tests/core/test_simple_compaction.pyL1–120
  8. 08src/kimi_cli/soul/agent.pyL411–451, 453–485, 467–485, 494–517, 87–168, 411–431, 339–369
  9. 09src/kimi_cli/agents/default/agent.yamlL1–36
  10. 10src/kimi_cli/soul/toolset.pyL343–423, 454–611, 116–172, 425–453, 1019–1080, 483–591
  11. 11src/kimi_cli/tools/shell/__init__.pyL22–57, 81–142, 144–219
  12. 12src/kimi_cli/background/worker.pyL87–169
  13. 13src/kimi_cli/soul/approval.pyL130–199, 200–299, 336–396, 36–67
  14. 14src/kimi_cli/approval_runtime/runtime.pyL61–152
  15. 15src/kimi_cli/agents/default/plan.yamlL14–29
  16. 16tests/core/test_subagent_builder.pyL63–86, 13–86
  17. 17src/kimi_cli/agents/default/system.mdL67–81, 67–117, 99–123, 125–148
  18. 18packages/kaos/src/kaos/local.pyL31–78, 139–176
  19. 19src/kimi_cli/hooks/engine.pyL65–91, 205–256, 287–319
  20. 20src/kimi_cli/hooks/runner.pyL27–89
  21. 21src/kimi_cli/plugin/tool.pyL37–130
  22. 22src/kimi_cli/plugin/manager.pyL54–108
  23. 23tests/core/test_plugin_tool.pyL49–153
  24. 24tests/tools/test_mcp_tool_result.pyL30–138
  25. 25src/kimi_cli/subagents/core.pyL58–69
  26. 26src/kimi_cli/config.pyL242–259, 261–264
  27. 27src/kimi_cli/subagents/builder.pyL12–36, 19–42
  28. 28src/kimi_cli/tools/agent/__init__.pyL17–60
  29. 29src/kimi_cli/subagents/store.pyL64–125, 163–196
  30. 30src/kimi_cli/subagents/runner.pyL357–391, 242–288, 393–425
  31. 31tests/core/test_subagent_resume_e2e.pyL76–148
  32. 32src/kimi_cli/telemetry/__init__.pyL52–71, 176–204
  33. 33src/kimi_cli/app.pyL329–352
  34. 34src/kimi_cli/telemetry/sink.pyL19–88
  35. 35src/kimi_cli/session.pyL84–97
  36. 36LICENSEL1–6