kimi

package module
v0.0.0-...-5418740 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2026 License: Apache-2.0 Imports: 19 Imported by: 1

README

Kimi Agent SDK for Go

Go SDK for programmatically controlling Kimi Agent sessions via the kimi-cli.

Installation

go get github.com/MoonshotAI/kimi-agent-sdk/go

Prerequisites

  • kimi CLI installed and available in PATH
  • KIMI_BASE_URL, KIMI_API_KEY, KIMI_MODEL_NAME environment variables set, or use kimi.Option instead

Usage

package main

import (
    "context"
    "fmt"

    kimi "github.com/MoonshotAI/kimi-agent-sdk/go"
    "github.com/MoonshotAI/kimi-agent-sdk/go/wire"
)

func main() {
    session, err := kimi.NewSession(
        kimi.WithBaseURL("https://api.moonshot.ai/v1"),
        kimi.WithAPIKey("your-api-key"),
        kimi.WithModel("kimi-k2-thinking-turbo"),
    )
    if err != nil {
        panic(err)
    }
    defer session.Close()

    turn, err := session.Prompt(context.Background(), wire.NewStringContent("Hello!"))
    if err != nil {
        panic(err)
    }

    for step := range turn.Steps {
        for msg := range step.Messages {
            if cp, ok := msg.(wire.ContentPart); ok && cp.Type == wire.ContentPartTypeText {
                fmt.Print(cp.Text.Value)
            }
        }
    }

    // Check for errors that occurred during streaming
    if err := turn.Err(); err != nil {
        panic(err)
    }
}

Turn Methods

After consuming all messages from a turn, you can inspect the turn's final state:

  • turn.Err() - Returns any error that occurred during streaming
  • turn.Result() - Returns the wire.PromptResult containing the final status
  • turn.Usage() - Returns token usage information (Context and Tokens)

Responding to Requests

For wire.Request messages (e.g., ApprovalRequest), you must call Respond(). Failing to do so will block the session indefinitely.

for step := range turn.Steps {
    for msg := range step.Messages {
        if req, ok := msg.(wire.ApprovalRequest); ok {
            // Approve the request
            req.Respond(wire.ApprovalRequestResponseApprove)
            // Or reject: req.Respond(wire.ApprovalRequestResponseReject)
        }
    }
}

External Tools

You can register external tools that the model can call during a session. Use kimi.CreateTool to create a tool from a Go function, and kimi.WithTools to register them.

Note: External tools require wire_protocol_version >= 2. The SDK automatically detects the protocol version from the CLI. If your CLI version doesn't support protocol v2, external tools will be silently ignored.

Defining a Tool
// Define argument struct - JSON schema is generated automatically
type WeatherArgs struct {
    Location string `json:"location" description:"City name"`
    Unit     string `json:"unit,omitempty" description:"Temperature unit (celsius or fahrenheit)"`
}

// Define result type - can be string, fmt.Stringer, or any JSON-serializable type
type WeatherResult struct {
    Temperature float64 `json:"temperature"`
    Condition   string  `json:"condition"`
}

// Create the tool function
func getWeather(args WeatherArgs) (WeatherResult, error) {
    // Your implementation here
    return WeatherResult{Temperature: 22.0, Condition: "Sunny"}, nil
}
Registering Tools
tool, err := kimi.CreateTool(getWeather,
    kimi.WithName("get_weather"),
    kimi.WithDescription("Get current weather for a location"),
)
if err != nil {
    panic(err)
}

session, err := kimi.NewSession(
    kimi.WithTools(tool),
    // ... other options
)
Tool Options
  • kimi.WithName(name) - Set tool name (defaults to function name)
  • kimi.WithDescription(desc) - Set tool description
  • kimi.WithFieldDescription(field, desc) - Set description for a struct field (alternative to description tag)
  • kimi.WithSchema(schema) - Set JSON schema directly, bypassing automatic generation
JSON Schema Generation

The SDK automatically generates JSON schema from the argument struct:

  • Struct fields become object properties
  • Fields with omitempty or omitzero tag are optional
  • Pointer fields are always optional
  • Use description tag or kimi.WithFieldDescription to document fields
How It Works

When the model calls your tool, the SDK automatically:

  1. Receives ToolCall request from the CLI
  2. Parses arguments and calls your function
  3. Converts the result to string:
    • string → returned directly
    • fmt.Stringer → calls .String()
    • Other types → JSON serialized
  4. Sends the result back via ToolResult

You don't need to handle external tool calls manually - just consume messages as usual.

Important Notes

  1. Sequential Prompts: Call Prompt sequentially. Wait for the previous turn to complete before starting a new one.

  2. Resource Cleanup: Always use defer session.Close() to ensure proper cleanup.

  3. Consume All Messages: You must consume all messages from step.Messages and all steps from turn.Steps before starting a new Prompt.

  4. Cancellation: You can cancel a turn either by canceling the context or by calling turn.Cancel() explicitly.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrTurnNotFound = errors.New("turn not found")
)

Functions

This section is empty.

Types

type Canceller

type Canceller interface {
	ID() uint64
	Cancel() error
}

type Cargo

type Cargo[R any] interface {
	Err() error
	Result() R
	Canceller
}

type Config

type Config struct {
	DefaultModel string                 `json:"default_model" toml:"default_model"`
	Models       map[string]LLMModel    `json:"models" toml:"models"`
	Providers    map[string]LLMProvider `json:"providers" toml:"providers"`
	LoopControl  LoopControl            `json:"loop_control" toml:"loop_control"`
	Services     Services               `json:"services" toml:"services"`
	MCP          MCPConfig              `json:"mcp" toml:"mcp"`
}

type Constructor

type Constructor[T any, R any] interface {
	RPCRequest() (*R, error)
	Construct(
		ctx context.Context,
		id uint64,
		stdioTransport transport.Transport,
		errorPointer *atomic.Pointer[error],
		resultPointer *atomic.Pointer[R],
		wireProtocolVersion string,
		wireMessageChan <-chan wire.Message,
		wireRequestResponseChan chan<- wire.RequestResponse,
		exit func(error) error,
	) *T
}

type LLMModel

type LLMModel struct {
	Provider       string                   `json:"provider" toml:"provider"`
	Model          string                   `json:"model" toml:"model"`
	MaxContextSize int                      `json:"max_context_size" toml:"max_context_size"`
	Capabilities   map[ModelCapability]bool `json:"capabilities,omitempty" toml:"capabilities,omitempty"`
}

type LLMProvider

type LLMProvider struct {
	Type          ProviderType      `json:"type" toml:"type"`
	BaseURL       string            `json:"base_url" toml:"base_url"`
	APIKey        string            `json:"api_key" toml:"api_key"`
	Env           map[string]string `json:"env,omitempty" toml:"env,omitempty"`
	CustomHeaders map[string]string `json:"custom_headers,omitempty" toml:"custom_headers,omitempty"`
}

type LoopControl

type LoopControl struct {
	MaxStepsPerRun    int `json:"max_steps_per_run" toml:"max_steps_per_run"`
	MaxRetriesPerStep int `json:"max_retries_per_step" toml:"max_retries_per_step"`
}

type MCPClientConfig

type MCPClientConfig struct {
	ToolCallTimeoutMS int `json:"tool_call_timeout_ms" toml:"tool_call_timeout_ms"`
}

type MCPConfig

type MCPConfig struct {
	Client MCPClientConfig `json:"client" toml:"client"`
}

type ModelCapability

type ModelCapability string
const (
	ModelCapabilityImageIn  ModelCapability = "image_in"
	ModelCapabilityVideoIn  ModelCapability = "video_in"
	ModelCapabilityThinking ModelCapability = "thinking"
)

type MoonshotFetchConfig

type MoonshotFetchConfig struct {
	BaseURL       string            `json:"base_url" toml:"base_url"`
	APIKey        string            `json:"api_key" toml:"api_key"`
	CustomHeaders map[string]string `json:"custom_headers,omitempty" toml:"custom_headers,omitempty"`
}

type MoonshotSearchConfig

type MoonshotSearchConfig struct {
	BaseURL       string            `json:"base_url" toml:"base_url"`
	APIKey        string            `json:"api_key" toml:"api_key"`
	CustomHeaders map[string]string `json:"custom_headers,omitempty" toml:"custom_headers,omitempty"`
}

type Option

type Option func(*option)

func WithAPIKey

func WithAPIKey(apiKey string) Option

func WithArgs

func WithArgs(args ...string) Option

WithArgs appends custom command line arguments.

func WithAutoApprove

func WithAutoApprove() Option

func WithBaseURL

func WithBaseURL(baseURL string) Option

func WithConfig

func WithConfig(config *Config) Option

func WithConfigFile

func WithConfigFile(file string) Option

func WithExecutable

func WithExecutable(executable string) Option

func WithMCPConfig

func WithMCPConfig(config *MCPConfig) Option

func WithMCPConfigFile

func WithMCPConfigFile(file string) Option

func WithModel

func WithModel(model string) Option

func WithSession

func WithSession(session string) Option

func WithSkillsDir

func WithSkillsDir(dir string) Option

func WithThinking

func WithThinking(thinking bool) Option

func WithTools

func WithTools(tools ...Tool) Option

func WithWorkDir

func WithWorkDir(dir string) Option

type ProviderType

type ProviderType string
const (
	ProviderTypeKimi            ProviderType = "kimi"
	ProviderTypeOpenAILegacy    ProviderType = "openai_legacy"
	ProviderTypeOpenAIResponses ProviderType = "openai_responses"
	ProviderTypeAnthropic       ProviderType = "anthropic"
	ProviderTypeGoogleGenAI     ProviderType = "google_genai" // for backward-compatibility, equals to `gemini`
	ProviderTypeGemini          ProviderType = "gemini"
	ProviderTypeVertexAI        ProviderType = "vertexai"
)

type Responder

type Responder struct {
	transport.Transport
	// contains filtered or unexported fields
}

func (*Responder) Event

func (r *Responder) Event(event *wire.EventParams) (*wire.EventResult, error)

func (*Responder) Request

func (r *Responder) Request(request *wire.RequestParams) (wire.RequestResult, error)

type ResponderFunc

type ResponderFunc func(wire.RequestResponse) error

func (ResponderFunc) Respond

func (f ResponderFunc) Respond(r wire.RequestResponse) error

type Services

type Services struct {
	MoonshotSearch *MoonshotSearchConfig `json:"moonshot_search,omitempty" toml:"moonshot_search,omitempty"`
	MoonshotFetch  *MoonshotFetchConfig  `json:"moonshot_fetch,omitempty" toml:"moonshot_fetch,omitempty"`
}

type Session

type Session struct {
	SlashCommands []wire.SlashCommand
	// contains filtered or unexported fields
}

func NewSession

func NewSession(options ...Option) (*Session, error)

func (*Session) Close

func (s *Session) Close() error

func (*Session) Prompt

func (s *Session) Prompt(ctx context.Context, content wire.Content) (*Turn, error)

type SingleTurn

type SingleTurn struct {
	*Turn
	// contains filtered or unexported fields
}

SingleTurn wraps a Turn and its associated Session for single-use scenarios. When Close or Cancel is called, it cancels the turn and closes the session.

func Prompt

func Prompt(ctx context.Context, content wire.Content, options ...Option) (*SingleTurn, error)

Prompt is a convenient function for single-turn prompts. Use SingleTurn.Close() (or Cancel()) to release resources when done.

func (*SingleTurn) Cancel

func (st *SingleTurn) Cancel() error

Cancel cancels the turn and closes the session. It is equivalent to Close.

func (*SingleTurn) Close

func (st *SingleTurn) Close() error

Close cancels the turn and closes the session.

type Step

type Step struct {
	Messages <-chan wire.Message
	// contains filtered or unexported fields
}

type Tool

type Tool struct {
	// contains filtered or unexported fields
}

func CreateTool

func CreateTool[T any, U any](function func(T) (U, error), options ...ToolOption) (Tool, error)

CreateTool creates a Tool from a function. The function must have signature func(T) (U, error) where T is a struct type. The result U can be: string (returned directly), fmt.Stringer (calls .String()), or any other type (JSON serialized).

type ToolOption

type ToolOption func(*toolOption)

func WithDescription

func WithDescription(description string) ToolOption

WithDescription sets the tool description.

func WithFieldDescription

func WithFieldDescription(fieldName, description string) ToolOption

WithFieldDescription sets description for a struct field. The fieldName should be the Go struct field name (not the JSON name).

func WithName

func WithName(name string) ToolOption

WithName sets the tool name (overrides auto-detected name from function).

func WithSchema

func WithSchema(schema json.RawMessage) ToolOption

WithSchema sets the JSON schema directly, bypassing automatic schema generation from the parameter type. Use this when you need full control over the schema or when the automatic generation doesn't meet your needs.

type Turn

type Turn struct {
	Steps <-chan *Step
	// contains filtered or unexported fields
}

func (*Turn) Cancel

func (t *Turn) Cancel() error

func (*Turn) Err

func (t *Turn) Err() error

func (*Turn) ID

func (t *Turn) ID() uint64

func (*Turn) Result

func (t *Turn) Result() wire.PromptResult

func (*Turn) Usage

func (t *Turn) Usage() *Usage

type Usage

type Usage struct {
	Context float64
	Tokens  wire.TokenUsage
}

Directories

Path Synopsis
transport
Package transport is a generated GoMock package.
Package transport is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL