How the Kimi CLI Subagent System Works and How SubagentStore Persists Data
The Kimi CLI subagent system creates isolated LLM workers that persist their state through the SubagentStore class, which saves metadata, prompts, and conversation context to the session directory using atomic JSON writes, enabling full resumability across process lifecycles.
The Kimi CLI from MoonshotAI/kimi-cli implements a sophisticated multi-agent architecture where parent agents can spawn lightweight subagents to handle specific tasks. Understanding how the SubagentStore manages persistence is crucial for building reliable agent workflows that survive crashes and restarts while maintaining complete conversational state.
Core Architecture Components
The subagent system comprises three primary components that orchestrate agent lifecycle and persistence:
| Component | File Path | Responsibility |
|---|---|---|
| SubagentStore | src/kimi_cli/subagents/store.py |
Handles durable storage of agent state on disk |
| Agent / AgentLaunchSpec | src/kimi_cli/subagents/core.py |
Defines agent configuration and launch parameters |
| SubagentRunner | src/kimi_cli/subagents/runner.py |
Executes the agent loop with KimiSoul runtime |
These components integrate with the main Runtime class in src/kimi_cli/soul/agent.py, which attaches a SubagentStore instance to the current session:
# src/kimi_cli/soul/agent.py
self.subagent_store = SubagentStore(self.session)
How SubagentStore Persists Data
SubagentStore implements a file-based persistence mechanism that stores each subagent under the session directory at ~/.kimi/sessions/<session_id>/subagents/<agent_id>/. This approach ensures agent state remains isolated per session while remaining accessible to the CLI process.
Directory Layout and File Formats
When a subagent is created, the store generates a dedicated directory containing four critical files:
session/
└─ subagents/
└─ <agent_id>/
├─ meta.json # UUID, spec reference, creation timestamps
├─ prompt.txt # System prompt for the subagent
├─ wire.log # Serialized wire events (messages, tool calls)
└─ context.json # Serialized conversation state
The store utilizes an atomic_json_write utility to prevent data corruption during crashes. When updating meta.json or context.json, the system writes to a temporary file before atomically moving it to the target location, ensuring readers never encounter partially written data.
Persistence Guarantees
Each file serves a specific recovery purpose:
- meta.json: Contains the agent's UUID and specification reference, allowing the system to identify orphaned agents
- prompt.txt: Stores the immutable system prompt used to initialize the LLM context
- context.json: Holds the mutable conversation history and tool state, enabling exact resumption of interrupted sessions
- wire.log: Provides a complete audit trail of LLM interactions for debugging and replay scenarios
Creating and Launching Subagents
The creation flow begins in src/kimi_cli/tools/agent/ where the Agent tool constructs an AgentLaunchSpec describing the desired agent configuration. The launch sequence follows these steps:
- UUID Generation: The system generates a unique
agent_idto identify the subagent instance - Store Initialization:
SubagentStorecreates the agent directory structure under the current session - Spec Persistence: The launch specification, system prompt, and empty wire log are written to disk
- Runner Initialization: A
SubagentRunnerinstantiates a freshKimiSoulruntime bound to the stored state
This process ensures that from the moment of creation, the subagent's entire configuration exists on disk and can survive immediate process termination.
Running and Resuming Subagents
The SubagentRunner orchestrates execution by reading persisted state and managing the LLM runtime loop.
Execution Flow
When running a subagent, the runner performs the following operations:
# src/kimi_cli/subagents/runner.py
self._soul = KimiSoul(
runtime=self._runtime,
subagent_store=self._store,
# ... additional configuration
)
await self._soul.run()
During execution, the runner appends every inbound and outbound wire event to wire.log through the store interface. This continuous logging ensures that even if the process crashes mid-conversation, the transcript remains intact up to the last successful write.
Resuming Interrupted Sessions
To resume a subagent, the system invokes SubagentStore.load(agent_id), which:
- Reads
meta.jsonto verify the agent exists and belongs to the current session - Loads
prompt.txtto reinitialize the system context - Deserializes
context.jsonto restore the exact conversation state - Returns a fully initialized
SubagentRunnerready to continue execution
Deleting Subagent State
When subagents complete their tasks or need removal, SubagentStore.delete(agent_id) recursively removes the agent's directory, cleaning up all persisted files and freeing disk space.
Practical Usage Examples
The following examples demonstrate common interactions with the subagent persistence system.
Creating a Subagent
from kimi_cli.tools.agent import AgentTool
from kimi_cli.subagents import AgentLaunchSpec
spec = AgentLaunchSpec(
name="code-reviewer",
yaml_path="src/kimi_cli/agents/code_reviewer.yaml",
env={"REPO_PATH": "/home/user/project"},
)
# Launch persists the agent immediately
await AgentTool().run(spec)
Resuming an Existing Subagent
from kimi_cli.subagents import SubagentStore
store = SubagentStore(session) # Attach to current session
runner = await store.load("<agent-id>") # Restore from disk
await runner.run() # Continue conversation
Cleaning Up Completed Agents
from kimi_cli.subagents import SubagentStore
store = SubagentStore(session)
await store.delete("<agent-id>")
Summary
- The Kimi CLI subagent architecture relies on three core components:
SubagentStorefor persistence,AgentLaunchSpecfor configuration, andSubagentRunnerfor execution SubagentStorepersists data to~/.kimi/sessions/<session_id>/subagents/<agent_id>/using atomic JSON writes to prevent corruption- Each subagent stores its state across four files:
meta.json(metadata),prompt.txt(system prompt),context.json(conversation state), andwire.log(event history) - The integration with
KimiSoulinsrc/kimi_cli/subagents/runner.pyenables seamless resumption of agent conversations by reconstructing runtime state from persisted files - The persistence mechanism is validated by
tests/core/test_subagent_store.py, which guarantees correct file layout and recovery behavior
Frequently Asked Questions
How does SubagentStore ensure data consistency during crashes?
SubagentStore uses an atomic_json_write utility that writes to temporary files before atomically moving them to their final destination. This ensures that meta.json and context.json are never in a partially written state, preventing data corruption if the CLI process terminates unexpectedly during a write operation.
Can subagents persist across different CLI sessions?
Subagents are bound to their parent session directory (~/.kimi/sessions/<session_id>/), meaning they persist only within the lifecycle of that specific session. While the physical files remain on disk until deleted, the SubagentStore validates that agents belong to the current session context, typically preventing cross-session access unless explicitly migrated.
What is the difference between wire.log and context.json?
The wire.log file stores a chronological, append-only record of all wire events (LLM messages and tool calls) for audit and debugging purposes, while context.json contains the deserialized state required to resume the conversation, including the current message history and tool states. The log is for human inspection and replay, whereas the context file is for machine state restoration.
Where is the SubagentStore integrated into the main Kimi CLI runtime?
The store is attached to the Runtime object in src/kimi_cli/soul/agent.py via self.subagent_store = SubagentStore(self.session), making it available throughout the session. This integration allows tools in src/kimi_cli/tools/agent/ to create and manage subagents that automatically inherit the session's persistence guarantees.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →