mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 04:10:51 +08:00
- OAuth2 device authorization grant flow (RFC 8628) for authentication - Streaming and non-streaming chat completions via OpenAI-compatible API - Models: kimi-k2, kimi-k2-thinking, kimi-k2.5 - CLI `--kimi-login` command for device flow auth - Token management with automatic refresh - Thinking/reasoning effort support for thinking-enabled models Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
// Package kimi implements thinking configuration for Kimi (Moonshot AI) models.
|
|
//
|
|
// Kimi models use the OpenAI-compatible reasoning_effort format with discrete levels
|
|
// (low/medium/high). The provider strips any existing thinking config and applies
|
|
// the unified ThinkingConfig in OpenAI format.
|
|
package kimi
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
|
|
"github.com/router-for-me/CLIProxyAPI/v6/internal/thinking"
|
|
"github.com/tidwall/gjson"
|
|
"github.com/tidwall/sjson"
|
|
)
|
|
|
|
// Applier implements thinking.ProviderApplier for Kimi models.
|
|
//
|
|
// Kimi-specific behavior:
|
|
// - Output format: reasoning_effort (string: low/medium/high)
|
|
// - Uses OpenAI-compatible format
|
|
// - Supports budget-to-level conversion
|
|
type Applier struct{}
|
|
|
|
var _ thinking.ProviderApplier = (*Applier)(nil)
|
|
|
|
// NewApplier creates a new Kimi thinking applier.
|
|
func NewApplier() *Applier {
|
|
return &Applier{}
|
|
}
|
|
|
|
func init() {
|
|
thinking.RegisterProvider("kimi", NewApplier())
|
|
}
|
|
|
|
// Apply applies thinking configuration to Kimi request body.
|
|
//
|
|
// Expected output format:
|
|
//
|
|
// {
|
|
// "reasoning_effort": "high"
|
|
// }
|
|
func (a *Applier) Apply(body []byte, config thinking.ThinkingConfig, modelInfo *registry.ModelInfo) ([]byte, error) {
|
|
if thinking.IsUserDefinedModel(modelInfo) {
|
|
return applyCompatibleKimi(body, config)
|
|
}
|
|
if modelInfo.Thinking == nil {
|
|
return body, nil
|
|
}
|
|
|
|
if len(body) == 0 || !gjson.ValidBytes(body) {
|
|
body = []byte(`{}`)
|
|
}
|
|
|
|
var effort string
|
|
switch config.Mode {
|
|
case thinking.ModeLevel:
|
|
if config.Level == "" {
|
|
return body, nil
|
|
}
|
|
effort = string(config.Level)
|
|
case thinking.ModeNone:
|
|
// Kimi uses "none" to disable thinking
|
|
effort = string(thinking.LevelNone)
|
|
case thinking.ModeBudget:
|
|
// Convert budget to level using threshold mapping
|
|
level, ok := thinking.ConvertBudgetToLevel(config.Budget)
|
|
if !ok {
|
|
return body, nil
|
|
}
|
|
effort = level
|
|
case thinking.ModeAuto:
|
|
// Auto mode maps to "auto" effort
|
|
effort = string(thinking.LevelAuto)
|
|
default:
|
|
return body, nil
|
|
}
|
|
|
|
if effort == "" {
|
|
return body, nil
|
|
}
|
|
|
|
result, err := sjson.SetBytes(body, "reasoning_effort", effort)
|
|
if err != nil {
|
|
return body, fmt.Errorf("kimi thinking: failed to set reasoning_effort: %w", err)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// applyCompatibleKimi applies thinking config for user-defined Kimi models.
|
|
func applyCompatibleKimi(body []byte, config thinking.ThinkingConfig) ([]byte, error) {
|
|
if len(body) == 0 || !gjson.ValidBytes(body) {
|
|
body = []byte(`{}`)
|
|
}
|
|
|
|
var effort string
|
|
switch config.Mode {
|
|
case thinking.ModeLevel:
|
|
if config.Level == "" {
|
|
return body, nil
|
|
}
|
|
effort = string(config.Level)
|
|
case thinking.ModeNone:
|
|
effort = string(thinking.LevelNone)
|
|
if config.Level != "" {
|
|
effort = string(config.Level)
|
|
}
|
|
case thinking.ModeAuto:
|
|
effort = string(thinking.LevelAuto)
|
|
case thinking.ModeBudget:
|
|
// Convert budget to level
|
|
level, ok := thinking.ConvertBudgetToLevel(config.Budget)
|
|
if !ok {
|
|
return body, nil
|
|
}
|
|
effort = level
|
|
default:
|
|
return body, nil
|
|
}
|
|
|
|
result, err := sjson.SetBytes(body, "reasoning_effort", effort)
|
|
if err != nil {
|
|
return body, fmt.Errorf("kimi thinking: failed to set reasoning_effort: %w", err)
|
|
}
|
|
return result, nil
|
|
}
|