CodeDocs Vault

Key Abstractions & Design Patterns

Core Classes

Runtime

src/kimi_cli/soul/agent.py:64

An immutable dataclass containing all execution dependencies:

@dataclass(frozen=True)
class Runtime:
    config: Config                      # Application configuration
    oauth: OAuthManager                 # OAuth token management
    llm: LLM | None                     # LLM instance (None if not configured)
    session: Session                    # Session metadata
    builtin_args: BuiltinSystemPromptArgs  # Template variables
    denwa_renji: DenwaRenji            # D-Mail manager
    approval: Approval                  # Tool approval system
    labor_market: LaborMarket          # Subagent registry
    environment: Environment           # System environment info
    skills: Mapping[str, DiscoveredSkill]  # Available skills

Factory method:

@staticmethod
async def create(
    config: Config,
    oauth: OAuthManager,
    llm: LLM | None,
    session: Session,
    *,
    yolo: bool = False,
    skills_roots: Sequence[Path] = (),
) -> Runtime:
    # Creates all dependencies and returns frozen Runtime

Subagent cloning:

def copy_for_fixed_subagent(self) -> Runtime:
    """Clone for fixed subagent with separate DenwaRenji."""
 
def copy_for_dynamic_subagent(self) -> Runtime:
    """Clone for dynamic subagent with shared LaborMarket."""

Agent

src/kimi_cli/soul/agent.py:157

A loaded agent with its configuration:

@dataclass(frozen=True)
class Agent:
    name: str                  # Agent identifier
    system_prompt: str         # Rendered system prompt
    toolset: KimiToolset       # Available tools
    runtime: Runtime           # Execution context

Context

src/kimi_cli/soul/context.py

Manages conversation history with checkpoint support:

class Context:
    def __init__(self, backend: Path | None = None):
        self._messages: list[Message] = []
        self._checkpoints: dict[int, int] = {}  # id -> message index
        self._backend = backend  # File path for persistence
 
    def append_message(self, message: Message) -> None:
        """Add message and persist to backend."""
 
    def checkpoint(self, checkpoint_id: int) -> None:
        """Create a checkpoint at current position."""
 
    def revert_to(self, checkpoint_id: int) -> None:
        """Remove messages after checkpoint (time-travel)."""
 
    @classmethod
    def restore(cls, backend: Path) -> Context:
        """Load context from file backend."""

File format (JSONL):

{"role": "user", "content": [...]}
{"role": "assistant", "content": [...]}
{"role": "_checkpoint", "id": 0}
{"role": "_usage", "token_count": 1500}

KimiToolset

src/kimi_cli/soul/toolset.py:71

Tool registry and execution manager:

class KimiToolset(Toolset):
    def add(self, tool: Tool) -> None:
        """Register a tool."""
 
    def find(self, name: str) -> Tool | None:
        """Find tool by name."""
 
    async def handle(self, tool_call: ToolCall) -> ToolResult:
        """Execute tool call with context tracking."""
 
    def load_tools(
        self,
        paths: Sequence[str],
        dependencies: dict[type, Any],
    ) -> None:
        """Load tools from module paths with DI."""
 
    async def load_mcp_tools(
        self,
        mcp_configs: Sequence[MCPServerConfig],
        runtime: Runtime,
    ) -> None:
        """Load tools from MCP servers (async background)."""

Approval

src/kimi_cli/soul/approval.py

Action gating system:

class Approval:
    def __init__(self, *, yolo: bool = False):
        self._yolo = yolo
        self._auto_approved: set[tuple[str, str]] = set()
        self._pending: asyncio.Queue[Request] = asyncio.Queue()
 
    async def request(
        self,
        sender: str,
        action: str,
        description: str,
        display: str | None = None,
    ) -> bool:
        """Request approval for an action."""
        if self._yolo:
            return True
        if (sender, action) in self._auto_approved:
            return True
 
        # Create request and wait for resolution
        request = Request(sender, action, description, display)
        self._pending.put_nowait(request)
        return await request.future
 
    def fetch_request(self) -> Request | None:
        """Soul fetches pending approval requests."""
 
    def resolve_request(
        self,
        request: Request,
        response: Literal["approve", "approve_for_session", "reject"],
    ) -> None:
        """Soul resolves with user's decision."""

DenwaRenji

src/kimi_cli/soul/denwarenji.py

Time-travel messaging system:

class DenwaRenji:
    """D-Mail manager for checkpoint-based time travel."""
 
    def send_dmail(self, dmail: DMail) -> None:
        """Tool sends D-Mail to be processed."""
 
    def set_n_checkpoints(self, n: int) -> None:
        """Track current checkpoint count."""
 
    def fetch_pending_dmail(self) -> DMail | None:
        """Soul fetches and clears pending D-Mail."""
 
@dataclass
class DMail:
    checkpoint_id: int
    messages: list[Message]

LaborMarket

src/kimi_cli/soul/agent.py:168

Registry for subagents:

@dataclass
class LaborMarket:
    fixed_subagents: dict[str, Agent]    # Pre-loaded from agent.yaml
    dynamic_subagents: dict[str, Agent]  # Created via CreateSubagent
 
    def register_dynamic(self, name: str, agent: Agent) -> None:
        """Register a dynamically created subagent."""
 
    def find(self, name: str) -> Agent | None:
        """Find subagent by name (checks both registries)."""

Tool System

Tool Base Classes

Tools extend kosong's CallableTool or CallableTool2[Params]:

# Simple tool with manual parameter handling
class MyTool(CallableTool):
    name = "my_tool"
    description = "Does something"
    params = {...}  # JSON Schema
 
    async def __call__(self, **kwargs) -> ToolReturnValue:
        ...
 
# Typed tool with Pydantic params
class MyTypedTool(CallableTool2[MyParams]):
    name = "my_typed_tool"
    description = "Does something with typed params"
 
    async def __call__(self, params: MyParams) -> ToolReturnValue:
        ...

Return Types

# Success with content
return ToolOk("Operation completed")
return ToolOk(content=[TextPart("Result"), ImagePart(data)])
 
# Error
return ToolError("Something went wrong")
 
# Rejection (user denied approval)
return ToolRejectedError("User rejected the action")

Dependency Injection

Tools receive dependencies via constructor:

class Shell(CallableTool2[ShellParams]):
    def __init__(self, approval: Approval, environment: Environment):
        self._approval = approval
        self._environment = environment

Loading mechanism in toolset.py:152:

def load_tools(self, paths: Sequence[str], deps: dict[type, Any]):
    for path in paths:
        module_path, class_name = path.rsplit(":", 1)
        module = importlib.import_module(module_path)
        tool_class = getattr(module, class_name)
 
        # Inspect __init__ for dependencies
        sig = inspect.signature(tool_class.__init__)
        kwargs = {}
        for param in sig.parameters.values():
            if param.annotation in deps:
                kwargs[param.name] = deps[param.annotation]
 
        tool = tool_class(**kwargs)
        self.add(tool)

MCP Tools

MCP server tools are wrapped:

# toolset.py:355
class MCPTool(CallableTool):
    """Wrapper for MCP server tools."""
 
    def __init__(self, mcp_tool: fastmcp.Tool, client: MCPClient):
        self.name = mcp_tool.name
        self.description = mcp_tool.description
        self.params = mcp_tool.inputSchema
        self._client = client
 
    async def __call__(self, **kwargs) -> ToolReturnValue:
        result = await self._client.call_tool(self.name, kwargs)
        return ToolOk(result.content)

Design Patterns

1. Dependency Injection

Tools and components receive dependencies at construction rather than accessing globals:

# Good: Dependencies injected
class WriteFile(CallableTool2[WriteFileParams]):
    def __init__(self, approval: Approval):
        self._approval = approval
 
# Usage in loader
tool = WriteFile(approval=runtime.approval)

2. Protocol/Structural Subtyping

The Soul protocol enables alternative implementations:

class Soul(Protocol):
    async def run(self, user_input: str) -> AsyncIterator[WireMessage]:
        ...
 
    def compact_context(self) -> AsyncIterator[WireMessage]:
        ...

3. Context Variables

Track state across async boundaries:

# toolset.py
current_tool_call: ContextVar[ToolCall | None] = ContextVar(
    "current_tool_call", default=None
)
 
def get_current_tool_call_or_none() -> ToolCall | None:
    return current_tool_call.get()
 
# In handle()
async def handle(self, tool_call: ToolCall):
    token = current_tool_call.set(tool_call)
    try:
        result = await tool(tool_call.arguments)
    finally:
        current_tool_call.reset(token)

4. Wire Protocol (Observer Pattern)

Decouple soul logic from UI:

# Soul sends events
yield WireMessage.MessagePart(TextPart("Hello"))
yield WireMessage.ToolCallRequest(tool_call)
yield WireMessage.ApprovalRequest(request)
 
# UI receives and renders
async for msg in soul.run(user_input):
    match msg:
        case WireMessage.MessagePart(part):
            render_part(part)
        case WireMessage.ApprovalRequest(req):
            response = prompt_user(req)
            soul.resolve_approval(req, response)

5. Immutable Configuration

Config models use frozen Pydantic:

class Config(BaseModel):
    model_config = ConfigDict(frozen=True)
 
    models: dict[str, LLMModel]
    providers: dict[str, LLMProvider]
    loop_control: LoopControl

6. Checkpoint-based Time Travel

Enable reverting conversation state:

# Create checkpoint
context.checkpoint(checkpoint_id=5)
 
# Later: revert to checkpoint
context.revert_to(checkpoint_id=5)  # Removes all messages after checkpoint 5

7. Factory Methods

Complex object creation encapsulated:

# KimiCLI.create() - factory for entire application
kimi = await KimiCLI.create(session, config, model_name=...)
 
# Runtime.create() - factory for runtime dependencies
runtime = await Runtime.create(config, oauth, llm, session, ...)
 
# load_agent() - factory for agent with tools
agent = await load_agent(agent_file, runtime, mcp_configs)

Class Relationships

┌─────────────────────────────────────────────────────────────────┐
│                           KimiCLI                               │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                        owns                               │  │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────────────┐  │  │
│  │  │  KimiSoul  │  │  Runtime   │  │ env_overrides      │  │  │
│  │  └─────┬──────┘  └──────┬─────┘  └────────────────────┘  │  │
│  │        │                │                                 │  │
│  └────────┼────────────────┼────────────────────────────────┘  │
│           │                │                                    │
│     ┌─────▼─────┐    ┌─────▼─────┐                             │
│     │   Agent   │    │  Config   │                             │
│     │  Context  │    │  OAuth    │                             │
│     │   Wire    │    │   LLM     │                             │
│     │Compaction │    │ Session   │                             │
│     └───────────┘    │ Approval  │                             │
│                      │DenwaRenji │                             │
│                      │LaborMarket│                             │
│                      │Environment│                             │
│                      │  Skills   │                             │
│                      └───────────┘                             │
└─────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────┐
│                          Agent                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                       owns                               │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │   │
│  │  │    name      │  │system_prompt │  │   toolset    │   │   │
│  │  └──────────────┘  └──────────────┘  └──────┬───────┘   │   │
│  │                                             │            │   │
│  │                    ┌────────────────────────▼───────┐   │   │
│  │                    │          KimiToolset           │   │   │
│  │                    │  ┌───────────────────────────┐ │   │   │
│  │                    │  │ tools: dict[str, Tool]    │ │   │   │
│  │                    │  │ mcp_clients: list[Client] │ │   │   │
│  │                    │  └───────────────────────────┘ │   │   │
│  │                    └────────────────────────────────┘   │   │
│  │                                                          │   │
│  │  ┌──────────────────────────────────────────────────┐   │   │
│  │  │               runtime (ref to Runtime)            │   │   │
│  │  └──────────────────────────────────────────────────┘   │   │
│  └─────────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────────┘