How Runtime and Agent Classes Interact in Kimi-CLI: Dependency Injection and Multi-Agent Architecture

The Runtime class acts as a service container that provides execution-time dependencies to the Agent class, which encapsulates system prompts and toolsets, while sub-agents receive deep-copied runtimes via copy_for_subagent to maintain shared state with role-specific isolation.

The interaction between Runtime and Agent classes forms the architectural backbone of the MoonshotAI/kimi-cli project. This design pattern decouples service management from agent logic, enabling sophisticated multi-agent workflows through runtime composition and inheritance. Understanding how these classes collaborate is essential for extending the framework or implementing custom agent behaviors.

The Runtime Service Container

Core Responsibilities

The Runtime dataclass serves as a comprehensive service locator that aggregates all execution-time dependencies a Kimi agent requires. It encapsulates session handling, configuration management, OAuth credentials, LLM access, notification systems, and background task management. When an agent needs to interact with external services or access configuration state, it retrieves these capabilities through its stored Runtime instance rather than instantiating them directly.

Factory Initialization via Runtime.create

The framework constructs runtimes through the Runtime.create class method defined in src/kimi_cli/soul/agent.py (lines 71-104). This factory method initializes a fully-populated runtime containing:

  • Configuration objects and logger instances
  • OAuth manager for authentication flows
  • LLM client for model interactions
  • Session state management
  • Built-in system prompt arguments (builtin_args)
  • Skill discovery mechanisms
  • Notification and background task managers
from kimi_cli.soul.agent import Runtime
from kimi_cli.config import Config
from kimi_cli.auth.oauth import OAuthManager
from kimi_cli.llm import LLM
from kimi_cli.session import Session

runtime = await Runtime.create(
    config=Config(...),
    oauth=OAuthManager(...),
    llm=LLM(...),
    session=Session(...),
    yolo=False,
)

Agent Class Integration with Runtime Services

The load_agent Bridge Function

The load_agent function in src/kimi_cli/soul/agent.py (lines 84-92) serves as the primary bridge between Runtime and Agent classes. This function receives a Runtime instance and uses it to:

  • Render the system prompt via _load_system_prompt using the runtime's builtin_args
  • Register built-in sub-agent types in the runtime's LaborMarket
  • Construct a dependency map (tool_deps) that includes the runtime itself and its fields

The resulting Agent dataclass stores the original Runtime object directly, giving it persistent access to all underlying services throughout its lifecycle.

Dependency Injection Through tool_deps

The runtime propagates its services to individual tools through the tool_deps parameter. When KimiToolset initializes, it consumes this dependency map, allowing tools to access runtime fields such as configuration, session state, and LLM clients. This injection pattern ensures tools remain stateless while accessing shared resources.

from kimi_cli.tools.base import BaseTool

class EchoTool(BaseTool):
    name = "echo"

    async def run(self, message: str) -> str:
        logger = self.runtime.config.logger
        logger.info("EchoTool called")
        return f"ECHO: {message}"

Sub-Agent Architecture and Runtime Inheritance

Deep Copying with copy_for_subagent

When the /agent tool spawns sub-agents, it invokes Runtime.copy_for_subagent (defined in src/kimi_cli/soul/agent.py, lines 39-70). This method creates a new Runtime instance that preserves the parent agent's execution context while enabling role-specific customization. The method accepts parameters for agent_id, subagent_type, and optional llm_override configurations.

Shared State vs Role-Specific Isolation

The copy_for_subagent method implements a sophisticated sharing strategy:

  • Shared references: Immutable fields such as config, oauth, and session are reused across parent and child agents
  • Mutable collection sharing: Collections like additional_dirs are shared by reference so changes propagate across the agent hierarchy
  • Isolated components: Each sub-agent receives a distinct DenwaRenji instance and a role-specific BackgroundTaskManager

# Inside a tool implementation (e.g., the /agent tool)

sub_runtime = agent.runtime.copy_for_subagent(
    agent_id="sub-123",
    subagent_type="my-subtype",
    llm_override=None,
)

sub_agent = await load_agent(
    agent_file=Path("agents/sub.yaml"),
    runtime=sub_runtime,
    mcp_configs=[],
)

Implementation Examples

Creating a Root Runtime and Loading the Main Agent

This example demonstrates the standard initialization pattern for a primary agent:

from pathlib import Path
from kimi_cli.soul.agent import Runtime, load_agent

# Initialize the service container

runtime = await Runtime.create(
    config=my_config,
    oauth=my_oauth,
    llm=my_llm,
    session=my_session,
    yolo=False,
)

# Load agent with runtime injection

agent = await load_agent(
    agent_file=Path("agents/default.yaml"),
    runtime=runtime,
    mcp_configs=[],
)

Spawning a Sub-Agent from a Running Agent

Sub-agents inherit the parent's runtime state while maintaining isolation:


# Within an agent tool execution context

sub_runtime = agent.runtime.copy_for_subagent(
    agent_id="helper-001",
    subagent_type="analyzer",
)

sub_agent = await load_agent(
    agent_file=Path("agents/analyzer.yaml"),
    runtime=sub_runtime,
    mcp_configs=[],
)

Summary

  • The Runtime class functions as a comprehensive service container managing all execution-time dependencies including configuration, LLM access, and session state.
  • The Agent class stores a Runtime reference and consumes its services through the load_agent initialization process and tool_deps injection.
  • Runtime.create builds fully populated runtime instances, while load_agent bridges the runtime services with agent-specific configuration.
  • Runtime.copy_for_subagent enables multi-agent hierarchies by deep-copying runtimes with selective state sharing and role-specific isolation.
  • Tools access runtime services through dependency injection, maintaining clean separation between tool logic and service management.

Frequently Asked Questions

What services does the Runtime class actually provide to Agents?

The Runtime class provides session management, OAuth authentication, LLM client access, configuration objects, notification systems, background task management, and built-in system prompt arguments. According to the kimi-cli source code, these services are aggregated in src/kimi_cli/soul/agent.py and passed to agents during the load_agent initialization phase.

How do sub-agents share state with their parent agents?

Sub-agents share state through the copy_for_subagent method, which creates a new runtime that reuses references to immutable fields like config and session while sharing mutable collections such as additional_dirs. This ensures that file system changes or configuration updates propagate across the agent hierarchy while maintaining separate execution contexts for background tasks.

Where is the Agent class defined and what does it store?

The Agent dataclass is defined in src/kimi_cli/soul/agent.py (lines 72-80). It stores the agent name, rendered system prompt, a KimiToolset instance, and the Runtime object passed during initialization. This structure allows the agent to maintain its specific configuration while delegating service access to the runtime.

How does dependency injection work for custom tools?

Custom tools receive runtime access through the tool_deps dependency map constructed during load_agent execution. The KimiToolset passes these dependencies to each tool instance, allowing tools to access self.runtime and its fields (such as config.logger or session) without direct instantiation, as implemented in src/kimi_cli/soul/agent.py.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →