| |
| |
| |
| |
| |
| |
| |
| |
| package iflow |
|
|
| import ( |
| "strings" |
|
|
| "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" |
| ) |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| type Applier struct{} |
|
|
| var _ thinking.ProviderApplier = (*Applier)(nil) |
|
|
| |
| func NewApplier() *Applier { |
| return &Applier{} |
| } |
|
|
| func init() { |
| thinking.RegisterProvider("iflow", NewApplier()) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| func (a *Applier) Apply(body []byte, config thinking.ThinkingConfig, modelInfo *registry.ModelInfo) ([]byte, error) { |
| if thinking.IsUserDefinedModel(modelInfo) { |
| return body, nil |
| } |
| if modelInfo.Thinking == nil { |
| return body, nil |
| } |
|
|
| if isEnableThinkingModel(modelInfo.ID) { |
| return applyEnableThinking(body, config, isGLMModel(modelInfo.ID)), nil |
| } |
|
|
| if isMiniMaxModel(modelInfo.ID) { |
| return applyMiniMax(body, config), nil |
| } |
|
|
| return body, nil |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| func configToBoolean(config thinking.ThinkingConfig) bool { |
| switch config.Mode { |
| case thinking.ModeNone: |
| return false |
| case thinking.ModeAuto: |
| return true |
| case thinking.ModeBudget: |
| return config.Budget > 0 |
| case thinking.ModeLevel: |
| return config.Level != thinking.LevelNone |
| default: |
| return true |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| func applyEnableThinking(body []byte, config thinking.ThinkingConfig, setClearThinking bool) []byte { |
| enableThinking := configToBoolean(config) |
|
|
| if len(body) == 0 || !gjson.ValidBytes(body) { |
| body = []byte(`{}`) |
| } |
|
|
| result, _ := sjson.SetBytes(body, "chat_template_kwargs.enable_thinking", enableThinking) |
|
|
| |
| result, _ = sjson.DeleteBytes(result, "chat_template_kwargs.clear_thinking") |
|
|
| |
| if enableThinking && setClearThinking { |
| result, _ = sjson.SetBytes(result, "chat_template_kwargs.clear_thinking", false) |
| } |
|
|
| return result |
| } |
|
|
| |
| |
| |
| |
| |
| func applyMiniMax(body []byte, config thinking.ThinkingConfig) []byte { |
| reasoningSplit := configToBoolean(config) |
|
|
| if len(body) == 0 || !gjson.ValidBytes(body) { |
| body = []byte(`{}`) |
| } |
|
|
| result, _ := sjson.SetBytes(body, "reasoning_split", reasoningSplit) |
|
|
| return result |
| } |
|
|
| |
| func isEnableThinkingModel(modelID string) bool { |
| if isGLMModel(modelID) { |
| return true |
| } |
| id := strings.ToLower(modelID) |
| switch id { |
| case "qwen3-max-preview", "deepseek-v3.2", "deepseek-v3.1": |
| return true |
| default: |
| return false |
| } |
| } |
|
|
| |
| func isGLMModel(modelID string) bool { |
| return strings.HasPrefix(strings.ToLower(modelID), "glm") |
| } |
|
|
| |
| |
| func isMiniMaxModel(modelID string) bool { |
| return strings.HasPrefix(strings.ToLower(modelID), "minimax") |
| } |
|
|