| |
| |
| |
| |
| |
| |
| package codex |
|
|
| 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("codex", NewApplier()) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| func (a *Applier) Apply(body []byte, config thinking.ThinkingConfig, modelInfo *registry.ModelInfo) ([]byte, error) { |
| if thinking.IsUserDefinedModel(modelInfo) { |
| return applyCompatibleCodex(body, config) |
| } |
| if modelInfo.Thinking == nil { |
| return body, nil |
| } |
|
|
| |
| if config.Mode != thinking.ModeLevel && config.Mode != thinking.ModeNone { |
| return body, nil |
| } |
|
|
| if len(body) == 0 || !gjson.ValidBytes(body) { |
| body = []byte(`{}`) |
| } |
|
|
| if config.Mode == thinking.ModeLevel { |
| result, _ := sjson.SetBytes(body, "reasoning.effort", string(config.Level)) |
| return result, nil |
| } |
|
|
| effort := "" |
| support := modelInfo.Thinking |
| if config.Budget == 0 { |
| if support.ZeroAllowed || hasLevel(support.Levels, string(thinking.LevelNone)) { |
| effort = string(thinking.LevelNone) |
| } |
| } |
| if effort == "" && config.Level != "" { |
| effort = string(config.Level) |
| } |
| if effort == "" && len(support.Levels) > 0 { |
| effort = support.Levels[0] |
| } |
| if effort == "" { |
| return body, nil |
| } |
|
|
| result, _ := sjson.SetBytes(body, "reasoning.effort", effort) |
| return result, nil |
| } |
|
|
| func applyCompatibleCodex(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: |
| |
| level, ok := thinking.ConvertBudgetToLevel(config.Budget) |
| if !ok { |
| return body, nil |
| } |
| effort = level |
| default: |
| return body, nil |
| } |
|
|
| result, _ := sjson.SetBytes(body, "reasoning.effort", effort) |
| return result, nil |
| } |
|
|
| func hasLevel(levels []string, target string) bool { |
| for _, level := range levels { |
| if strings.EqualFold(strings.TrimSpace(level), target) { |
| return true |
| } |
| } |
| return false |
| } |
|
|