Purpose of the Kosong Package in MoonshotAI/Kimi-Code: LLM Abstraction Layer Explained

The @moonshot-ai/kosong package serves as the core LLM abstraction layer that unifies interactions with OpenAI, Anthropic, Google Gemini, and Kimi's own backend behind a single provider-agnostic API.

The kosong package is a foundational component of the MoonshotAI/kimi-code repository that eliminates vendor lock-in by collapsing diverse LLM SDKs into a type-safe, uniform interface. It enables the Kimi Code CLI, server, and SDKs to switch between language models without code changes. By centralizing message formatting, capability detection, and error handling, the package ensures consistent behavior across heterogeneous AI providers.

What Is the Kosong Package?

At its heart, kosong (published as @moonshot-ai/kosong) implements a provider-agnostic abstraction over large language model services. Implemented in TypeScript under the packages/kosong/ directory, it exposes a clean surface area through src/index.ts while keeping provider-specific adapters isolated in src/providers/. This architecture allows the rest of the Kimi Code ecosystem to treat every LLM—whether OpenAI's GPT-4o, Anthropic's Claude, or Kimi's own models—as interchangeable backends that share a common contract for generation, streaming, and tool use.

Core Responsibilities and Architecture

The package is organized around six distinct responsibilities, each mapped to specific source modules within the repository.

Unified Message Model

All inter-provider communication normalizes to a rich message schema defined in src/message.ts. This module exports TypeScript interfaces for text, images, audio, and tool call parts, ensuring that a message constructed for OpenAI can be transparently routed to Anthropic or Kimi without transformation boilerplate. The barrel file src/index.ts re-exports these types as the canonical message API for downstream consumers.

Provider Interface and Adapters

Each LLM vendor implements a concrete ChatProvider interface defined in src/provider.ts. The package ships with dedicated adapters located in src/providers/:

These adapters are intentionally excluded from the root barrel file to prevent type bundle pollution, as noted in the comments within src/index.ts.

Model Capability Catalog

To prevent runtime errors from unsupported features, src/catalog.ts and src/capability.ts maintain a matrix mapping model identifiers to their supported capabilities—such as tool use, streaming, and token limits. This catalog acts as a source of truth that the generate function consults before dispatching requests, ensuring that a caller requesting tool calls from a non-tool model receives an immediate, descriptive error rather than a provider-side failure.

Token Usage Tracking

Accurate billing and observability require aggregating token counts across request-response cycles. The package exports addUsage, emptyUsage, grandTotal, and inputTotal from src/usage.ts to accumulate consumption statistics. These utilities normalize disparate provider reporting formats into a unified Usage object returned with every generation result.

Error Normalization

Rather than leaking vendor-specific SDK errors, src/errors.ts defines a hierarchical error taxonomy covering rate limits, quota exhaustion, context overflows, and authentication failures. By catching provider-specific exceptions and re-throwing normalized equivalents, kosong allows calling code to handle failures generically—for example, retrying on any provider's rate limit without custom catch blocks for each SDK.

Generation Orchestration

The high-level generate function exported from src/generate.ts serves as the primary entry point. It orchestrates the entire request lifecycle: selecting the provider, validating capabilities against the catalog, managing streaming callbacks, handling tool call loops, and aggregating usage statistics. The function returns a typed GenerateResult containing the completion text, message history, and token consumption metrics.

Implementation Details by Source File

The following table maps critical files in the packages/kosong/src/ directory to their architectural roles:

File Responsibility
src/index.ts Central barrel file re-exporting the public API (messages, providers, capabilities, errors, usage)
src/generate.ts Core orchestration logic implementing the generate function for chat completions
src/provider.ts Base ChatProvider interface and factory types
src/message.ts Unified message part definitions (text, image, tool call, etc.)
src/capability.ts Model capability flags and "unknown" fallback definitions
src/catalog.ts Model ID to capability mapping and remote catalog resolution
src/usage.ts Token aggregation utilities (addUsage, grandTotal, etc.)
src/errors.ts Normalized error hierarchy for LLM failures
src/providers/kimi.ts Kimi backend adapter with native option support
src/providers/anthropic.ts Anthropic Claude adapter
src/providers/openai-legacy.ts Legacy OpenAI completions adapter

Usage Examples

Basic Chat Completion with OpenAI

The following example demonstrates creating a provider instance and generating a response using standard OpenAI credentials:

import { createProvider, generate } from '@moonshot-ai/kosong';

// Factory auto-detects provider type from the 'type' field
const provider = createProvider({
  type: 'openai',
  apiKey: process.env.OPENAI_API_KEY,
  model: 'gpt-4o-mini',
});

// Simple generation call returns typed result with usage stats
const result = await generate(provider, [
  { role: 'user', content: 'Explain the purpose of the kosong package.' },
]);

console.log(result.completion); // Formatted response text
console.log(result.usage);      // Aggregated token counts

Streaming and Tool Calls with Anthropic

For interactive applications, provide callback hooks to consume streaming chunks and tool invocations in real time:

import { createProvider, generate } from '@moonshot-ai/kosong';

const provider = createProvider({
  type: 'anthropic',
  apiKey: process.env.ANTHROPIC_API_KEY,
  model: 'claude-3-5-sonnet-20240620',
});

const callbacks = {
  onChunk: chunk => process.stdout.write(chunk.delta?.content ?? ''),
  onToolCall: tool => console.log('Tool called:', tool.name),
};

await generate(
  provider,
  [{ role: 'user', content: 'What is the current date?' }],
  callbacks
);

Kimi Backend with Provider-Specific Options

Access Kimi-exclusive features by passing provider-specific configuration to the factory:

import { createProvider, generate } from '@moonshot-ai/kosong';

const provider = createProvider({
  type: 'kimi',
  apiKey: process.env.KIMI_API_KEY,
  model: 'kimi-1.5-large',
  thinking: { keep: true }, // Kimi-specific extended reasoning option
});

const result = await generate(provider, [
  { role: 'user', content: 'List the steps to bake a cake.' }
]);

console.log(result.completion);

Summary

  • Kosong (@moonshot-ai/kosong) is the provider-agnostic LLM abstraction layer at the core of MoonshotAI/kimi-code.
  • It normalizes message models, capabilities, errors, and token usage across OpenAI, Anthropic, Google, and Kimi backends.
  • Provider adapters in src/providers/ implement a common ChatProvider interface while isolating vendor-specific logic.
  • The generate function in src/generate.ts serves as the unified entry point for all chat completions, handling streaming, tool calls, and usage aggregation.
  • Token tracking utilities (addUsage, grandTotal) and normalized error hierarchies (src/errors.ts) ensure consistent observability and error handling.

Frequently Asked Questions

What is the primary purpose of the kosong package in Kimi Code?

The kosong package provides a unified interface for multiple LLM providers, allowing the Kimi Code platform to interact with OpenAI, Anthropic, Google Gemini, and Kimi's own models through a single API. It handles the normalization of message formats, capability detection, and error handling so that upstream components remain agnostic to the underlying vendor SDK.

How does kosong handle provider-specific features?

While the core API remains consistent, kosong exposes provider-specific options through the createProvider factory function. For example, when using the Kimi backend via src/providers/kimi.ts, you can pass Kimi-exclusive parameters like thinking: { keep: true } directly in the provider configuration. These options are typed as KimiOptions and processed by the respective adapter without affecting the generic generate contract.

What functions does kosong provide for tracking token usage?

The package exports several aggregation utilities from src/usage.ts: emptyUsage initializes a zeroed usage object, addUsage combines two usage records, inputTotal sums prompt tokens, and grandTotal calculates the complete token consumption across all categories. These functions normalize disparate provider reporting formats into a consistent Usage structure attached to every GenerateResult.

How does kosong normalize errors across different LLM providers?

Rather than exposing raw SDK exceptions, kosong defines a comprehensive error hierarchy in src/errors.ts. It catches provider-specific failures—such as Anthropic's rate limits or OpenAI's context overflows—and re-throws them as standardized error types (e.g., RateLimitError, ContextOverflowError). This allows calling code to implement generic retry and error-handling logic without importing vendor-specific error classes.

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 →