Kimi Agent SDK

repository·main·Indexed 19 days ago

https://github.com/moonshotai/kimi-agent-sdk

The Kimi Agent SDK provides programmatic access to the Kimi CLI agent runtime, enabling developers to build AI-driven applications, automations, and custom tools. It supports Go, Node.js, and Python, and includes capabilities for implementing ExternalTools and iterative AI coding patterns like the Ralph Loop.

Tokens
48.1K
Snippets
143
Records
199
Agent score
67%

What's inside kimi-agent-sdk

  1. Overview of Kimi Agent SDK

    main

    Kimi Agent SDK is a collection of multi-language libraries that expose the Kimi Code (Kimi CLI) agent runtime within your applications. It allows you to use the Kimi CLI as an execution engine while building custom products, automations, or tooling.

    Key capabilities include:

    • Building custom applications: Integrating Kimi Agent into existing tools and workflows.
    • Automating tasks: Scripting complex, multi-turn conversations.
    • Extending capabilities: Registering custom tools for the model to call.
    • Handling approvals: Programmatically managing permission requests and tool calls.

    The SDKs are thin, language-native clients that reuse Kimi CLI configurations, tools, skills, and MCP servers, supporting real-time response streaming.

  2. Overview of Kimi Agent SDK for Python

    main

    The Kimi Agent SDK for Python allows you to programmatically control the Kimi CLI (Kimi Code) agent runtime. It is designed to integrate agentic capabilities into Python applications, enabling you to:

    • Run agent sessions.
    • Stream responses from the agent.
    • Handle human-in-the-loop approvals required by the agent during execution.
  3. What is the Ralph Loop pattern?

    main

    Ralph Loop (also known as the Ralph Wiggum technique) is an iterative AI coding pattern designed for autonomous task completion. Instead of relying on the AI agent's self-reported success, the pattern follows a strict loop:

    1. Task Assignment: Give the AI agent a specific task.
    2. Execution: The agent executes the task.
    3. External Verification: Run an actual command (e.g., a linter, test suite, or custom script) to verify completion. Do not trust the agent's output alone.
    4. Iteration: If the verification command returns a non-zero exit code, the loop continues. If it returns 0, the task is considered complete.

    This approach provides fresh context each iteration, avoids context pollution, and allows for unattended autonomous operation.

  4. What is KAOS (Kimi Agent Operating System)

    main

    KAOS is a runtime abstraction layer designed to decouple agent tools from their underlying execution environment. It provides a standardized interface for common operations such as:

    • File system operations
    • Process execution
    • Path manipulation

    This abstraction allows the same agent code to be executed interchangeably across different environments (local or cloud) without modifying the core tool logic.

  5. Understand the Session, Turn, and Step concepts

    main

    The Kimi Code runtime is structured around three hierarchical concepts:

    • Session: The top-level container representing a running Kimi Code process. It maintains the configuration, available tools, and the entire conversation state.
    • Turn: A single interaction initiated by calling Session.prompt(...). A turn encompasses the full round-trip from the user's input to the complete streamed response from the agent.
    • Step: The granular units of work within a single Turn. As an agent reasons, calls tools, or produces output, it moves through steps. You can identify step boundaries in the Wire stream via StepBegin and StepInterrupted events.

    Important Constraints:

    • Sequentiality: You must fully consume a turn (iterate through the entire stream) or explicitly cancel() it before you can start a new turn on the same session. Starting a new prompt while one is active raises a SessionStateError.
    • Approvals: If the agent requests permission via an ApprovalRequest, you must resolve it. An unresolved request will block the turn indefinitely.
    # A Turn is one call to prompt()
    async for msg in session.prompt("Hello"):
        # This loop processes the Turn
        pass
  6. How the JSON-RPC 2.0 Streaming extension works

    main

    The go/wire/jsonrpc2 package implements a custom streaming extension to multiplex stream frames over a single JSON-RPC connection using the id field. This extension is not part of the official JSON-RPC 2.0 spec.

    Stream States (stream field)

    Constants defined in go/wire/jsonrpc2/codec.go:

    • StreamDisable (0): Standard request/response; no stream expected.
    • StreamOpen (1): Declares that the current id is authorized for subsequent stream frames. This is set on the base request or response.
    • StreamSync (2): A data frame containing payload in the data field.
    • StreamClose (3): An EOF frame indicating the end of the stream.

    Wire Semantics

    1. Stream-enabled base message: A message where stream == StreamOpen. It functions as a normal request/response but signals that the id can handle multiplexed frames.
    2. Stream frames: Messages where stream > StreamOpen. These are treated as frames rather than requests/responses:
      • stream == StreamSync: Contains data (json.RawMessage).
      • stream == StreamClose: Signals end-of-stream; data is typically omitted.

    Critical Requirement: Globally Unique IDs

    If a connection is bi-directional (the Codec acts as both client and server), both sides must ensure that id values are globally unique across both directions to prevent stream frames from being routed to the wrong receiver.

  7. Handle and resolve Approval Requests

    main

    When the agent attempts an action that requires permission (like running a shell command), it emits an ApprovalRequest. You must resolve these requests to allow the turn to proceed.

    ApprovalRequest Properties:

    • id: Unique identifier for the request.
    • action: The type of action (e.g., "run shell command").
    • description: A human-readable explanation of what the agent wants to do.

    Resolution Options: Call req.resolve(choice) with one of the following strings:

    • "approve": Approves the current request.
    • "approve_for_session": Approves the current request and all subsequent similar requests for the remainder of this session.
    • "reject": Rejects the request.

    Example Logic:

    from kimi_agent_sdk import ApprovalRequest
    
    async def handle_approvals(msg):
        if isinstance(msg, ApprovalRequest):
            if msg.action == "run shell command":
                await msg.resolve("approve")
            else:
                await msg.resolve("reject")
  8. Handle `Message` objects and content parts

    main

    The prompt() function yields Message instances (specifically kosong.message.Message). Each message contains structured data about the agent's response or tool execution.

    Message Fields:

    • role: The sender's role (assistant or tool).
    • content: A list of ContentPart objects (text, thinking, images, audio, video). Even single strings are stored as a list of parts.
    • tool_calls: List of tool call requests (only for assistant role).
    • tool_call_id: The ID associated with a tool response (only for tool role).

    Common Tasks:

    • Extracting Text: Use message.extract_text() to easily get a concatenated string of all text parts in the message.
    • Inspecting Structure: Access message.content directly to inspect specific ContentPart types like TextPart or ToolCall.
    from kimi_agent_sdk import Message, TextPart, ToolCall
    
    # Example: Assistant message with tool calls
    message = Message(
        role="assistant",
        content=[TextPart(text="Let me check the current directory.")],
        tool_calls=[
            ToolCall(
                id="tc_1",
                type="function",
                function={"name": "Shell", "arguments": "{\"command\":\"ls\"}"},
            )
        ],
    )
    
    # Example: Tool message responding to a call
    tool_message = Message(
        role="tool",
        tool_call_id="tc_1",
        content=[TextPart(text="file1.py\nfile2.py")],
    )
  9. Understand JSON Schema generation for Go tools

    main

    The SDK automatically maps Go types to JSON Schema types for your tool's argument structs.

    Type Mappings

    Go TypeJSON Schema Type
    string"string"
    bool"boolean"
    int, int8, int16, int32, int64"integer"
    uint, uint8, uint16, uint32, uint64"integer"
    float32, float64"number"
    struct"object"
    []T, [N]T"array"
    map[string]T"object"
    *TSame as T, but optional

    Required vs Optional Fields

    • Required: Fields are required by default.
    • Optional: A field becomes optional if:
      1. The json tag includes omitempty or omitzero (e.g., Limit int json:"limit,omitempty"``).
      2. The field is a pointer type (e.g., Options *SearchOptions).

    Field Descriptions

    Use the description struct tag to provide context to the model for specific fields:

    type SearchArgs struct {
        Query  string `json:"query" description:"The search query string"`
        Limit  int    `json:"limit,omitempty" description:"Maximum number of results"`
    }

    Unsupported Types

    kimi.CreateTool will return an error if your argument struct contains:

    • func types
    • interface{} / any (with some exceptions)
    • chan types
  10. Manage conversation turns with the Session and Turn interfaces

    main

    A Session manages the lifecycle of an interaction. You can use session.prompt(content) to send a message. This returns a Turn object.

    A Turn represents an ongoing conversation turn and supports:

    • Async Iteration: Iterate over StreamEvents emitted during the turn.
    • interrupt(): Stops the current turn.
    • approve(requestId, response): Approves a tool call with an ApprovalResponse ('approve' | 'approve_for_session' | 'reject').
    • result: A Promise that resolves to the RunResult (status: 'finished' | 'cancelled' | 'max_steps_reached').