Documentation
¶
Overview ¶
Package thinking provides unified thinking configuration processing.
Package thinking provides unified thinking configuration processing logic.
Package thinking provides unified thinking configuration processing.
Package thinking provides unified thinking configuration processing.
This file implements suffix parsing functionality for extracting thinking configuration from model names in the format model(value).
Package thinking provides unified thinking configuration processing.
This package offers a unified interface for parsing, validating, and applying thinking configurations across various AI providers (Claude, Gemini, OpenAI, iFlow).
Package thinking provides unified thinking configuration processing logic.
Index ¶
- Constants
- func ApplyThinking(body []byte, model string, provider string) ([]byte, error)
- func ClampBudget(value int, modelInfo *registry.ModelInfo, provider string) int
- func ConvertBudgetToLevel(budget int) (string, bool)
- func ConvertLevelToBudget(level string) (int, bool)
- func GetThinkingText(part gjson.Result) string
- func IsUserDefinedModel(modelInfo *registry.ModelInfo) bool
- func ParseNumericSuffix(rawSuffix string) (budget int, ok bool)
- func RegisterProvider(name string, applier ProviderApplier)
- func StripThinkingConfig(body []byte, provider string) []byte
- type ErrorCode
- type ModelCapability
- type ProviderApplier
- type SuffixResult
- type ThinkingConfig
- type ThinkingError
- type ThinkingLevel
- type ThinkingMode
Constants ¶
const ( // ThresholdMinimal is the upper bound for "minimal" level (1-512) ThresholdMinimal = 512 // ThresholdLow is the upper bound for "low" level (513-1024) ThresholdLow = 1024 // ThresholdMedium is the upper bound for "medium" level (1025-8192) ThresholdMedium = 8192 // ThresholdHigh is the upper bound for "high" level (8193-24576) ThresholdHigh = 24576 )
BudgetThreshold constants define the upper bounds for each thinking level. These are used by ConvertBudgetToLevel for range-based mapping.
Variables ¶
This section is empty.
Functions ¶
func ApplyThinking ¶
ApplyThinking applies thinking configuration to a request body.
This is the unified entry point for all providers. It follows the processing order defined in FR25: route check → model capability query → config extraction → validation → application.
Suffix Priority: When the model name includes a thinking suffix (e.g., "gemini-2.5-pro(8192)"), the suffix configuration takes priority over any thinking parameters in the request body. This enables users to override thinking settings via the model name without modifying their request payload.
Parameters:
- body: Original request body JSON
- model: Model name, optionally with thinking suffix (e.g., "claude-sonnet-4-5(16384)")
- provider: Provider name (gemini, gemini-cli, antigravity, claude, openai, codex, iflow)
Returns:
- Modified request body JSON with thinking configuration applied
- Error if validation fails (ThinkingError). On error, the original body is returned (not nil) to enable defensive programming patterns.
Passthrough behavior (returns original body without error):
- Unknown provider (not in providerAppliers map)
- modelInfo.Thinking is nil (model doesn't support thinking)
Note: Unknown models (modelInfo is nil) are treated as user-defined models: we skip validation and still apply the thinking config so the upstream can validate it.
Example:
// With suffix - suffix config takes priority result, err := thinking.ApplyThinking(body, "gemini-2.5-pro(8192)", "gemini") // Without suffix - uses body config result, err := thinking.ApplyThinking(body, "gemini-2.5-pro", "gemini")
func ClampBudget ¶
ClampBudget clamps a budget value to the model's supported range.
Logging:
- Warn when value=0 but ZeroAllowed=false
- Debug when value is clamped to min/max
Fields: provider, model, original_value, clamped_to, min, max
func ConvertBudgetToLevel ¶
ConvertBudgetToLevel converts a budget value to the nearest thinking level.
This is a semantic conversion that maps numeric budgets to discrete levels. Uses threshold-based mapping for range conversion.
Budget → Level thresholds:
- -1 → auto
- 0 → none
- 1-512 → minimal
- 513-1024 → low
- 1025-8192 → medium
- 8193-24576 → high
- 24577+ → xhigh
Returns:
- level: The converted thinking level string
- ok: true if budget is valid, false for invalid negatives (< -1)
func ConvertLevelToBudget ¶
ConvertLevelToBudget converts a thinking level to a budget value.
This is a semantic conversion that maps discrete levels to numeric budgets. Level matching is case-insensitive.
Level → Budget mapping:
- none → 0
- auto → -1
- minimal → 512
- low → 1024
- medium → 8192
- high → 24576
- xhigh → 32768
Returns:
- budget: The converted budget value
- ok: true if level is valid, false otherwise
func GetThinkingText ¶
GetThinkingText extracts the thinking text from a content part. Handles various formats: - Simple string: { "thinking": "text" } or { "text": "text" } - Wrapped object: { "thinking": { "text": "text", "cache_control": {...} } } - Gemini-style: { "thought": true, "text": "text" } Returns the extracted text string.
func IsUserDefinedModel ¶
IsUserDefinedModel reports whether the model is a user-defined model that should have thinking configuration passed through without validation.
User-defined models are configured via config file's models[] array (e.g., openai-compatibility.*.models[], *-api-key.models[]). These models are marked with UserDefined=true at registration time.
User-defined models should have their thinking configuration applied directly, letting the upstream service validate the configuration.
func ParseNumericSuffix ¶
ParseNumericSuffix attempts to parse a raw suffix as a numeric budget value.
This function parses the raw suffix content (from ParseSuffix.RawSuffix) as an integer. Only non-negative integers are considered valid numeric suffixes.
Platform note: The budget value uses Go's int type, which is 32-bit on 32-bit systems and 64-bit on 64-bit systems. Values exceeding the platform's int range will return ok=false.
Leading zeros are accepted: "08192" parses as 8192.
Examples:
- "8192" -> budget=8192, ok=true
- "0" -> budget=0, ok=true (represents ModeNone)
- "08192" -> budget=8192, ok=true (leading zeros accepted)
- "-1" -> budget=0, ok=false (negative numbers are not valid numeric suffixes)
- "high" -> budget=0, ok=false (not a number)
- "9223372036854775808" -> budget=0, ok=false (overflow on 64-bit systems)
For special handling of -1 as auto mode, use ParseSpecialSuffix instead.
func RegisterProvider ¶
func RegisterProvider(name string, applier ProviderApplier)
RegisterProvider registers a provider applier by name.
func StripThinkingConfig ¶
StripThinkingConfig removes thinking configuration fields from request body.
This function is used when a model doesn't support thinking but the request contains thinking configuration. The configuration is silently removed to prevent upstream API errors.
Parameters:
- body: Original request body JSON
- provider: Provider name (determines which fields to strip)
Returns:
- Modified request body JSON with thinking configuration removed
- Original body is returned unchanged if:
- body is empty or invalid JSON
- provider is unknown
- no thinking configuration found
Types ¶
type ErrorCode ¶
type ErrorCode string
ErrorCode represents the type of thinking configuration error.
const ( // ErrInvalidSuffix indicates the suffix format cannot be parsed. // Example: "model(abc" (missing closing parenthesis) ErrInvalidSuffix ErrorCode = "INVALID_SUFFIX" // ErrUnknownLevel indicates the level value is not in the valid list. // Example: "model(ultra)" where "ultra" is not a valid level ErrUnknownLevel ErrorCode = "UNKNOWN_LEVEL" // ErrThinkingNotSupported indicates the model does not support thinking. // Example: claude-haiku-4-5 does not have thinking capability ErrThinkingNotSupported ErrorCode = "THINKING_NOT_SUPPORTED" // ErrLevelNotSupported indicates the model does not support level mode. // Example: using level with a budget-only model ErrLevelNotSupported ErrorCode = "LEVEL_NOT_SUPPORTED" // ErrProviderMismatch indicates the provider does not match the model. // Example: applying Claude format to a Gemini model ErrProviderMismatch ErrorCode = "PROVIDER_MISMATCH" )
Error codes for thinking configuration processing.
type ModelCapability ¶
type ModelCapability int
ModelCapability describes the thinking format support of a model.
const ( // CapabilityUnknown indicates modelInfo is nil (passthrough behavior, internal use). CapabilityUnknown ModelCapability = iota - 1 // CapabilityNone indicates model doesn't support thinking (Thinking is nil). CapabilityNone // CapabilityBudgetOnly indicates the model supports numeric budgets only. CapabilityBudgetOnly // CapabilityLevelOnly indicates the model supports discrete levels only. CapabilityLevelOnly // CapabilityHybrid indicates the model supports both budgets and levels. CapabilityHybrid )
type ProviderApplier ¶
type ProviderApplier interface {
// Apply applies the thinking configuration to the request body.
//
// Parameters:
// - body: Original request body JSON
// - config: Unified thinking configuration
// - modelInfo: Model registry information containing ThinkingSupport properties
//
// Returns:
// - Modified request body JSON
// - ThinkingError if the configuration is invalid or unsupported
Apply(body []byte, config ThinkingConfig, modelInfo *registry.ModelInfo) ([]byte, error)
}
ProviderApplier defines the interface for provider-specific thinking configuration application.
Types implementing this interface are responsible for converting a unified ThinkingConfig into provider-specific format and applying it to the request body.
Implementation requirements:
- Apply method must be idempotent
- Must not modify the input config or modelInfo
- Returns a modified copy of the request body
- Returns appropriate ThinkingError for unsupported configurations
func GetProviderApplier ¶
func GetProviderApplier(provider string) ProviderApplier
GetProviderApplier returns the ProviderApplier for the given provider name. Returns nil if the provider is not registered.
type SuffixResult ¶
type SuffixResult struct {
// ModelName is the model name with the suffix removed.
// If no suffix was found, this equals the original input.
ModelName string
// HasSuffix indicates whether a valid suffix was found.
HasSuffix bool
// RawSuffix is the content inside the parentheses, without the parentheses.
// Empty string if HasSuffix is false.
RawSuffix string
}
SuffixResult represents the result of parsing a model name for thinking suffix.
A thinking suffix is specified in the format model-name(value), where value can be a numeric budget (e.g., "16384") or a level name (e.g., "high").
func ParseSuffix ¶
func ParseSuffix(model string) SuffixResult
ParseSuffix extracts thinking suffix from a model name.
The suffix format is: model-name(value) Examples:
- "claude-sonnet-4-5(16384)" -> ModelName="claude-sonnet-4-5", RawSuffix="16384"
- "gpt-5.2(high)" -> ModelName="gpt-5.2", RawSuffix="high"
- "gemini-2.5-pro" -> ModelName="gemini-2.5-pro", HasSuffix=false
This function only extracts the suffix; it does not validate or interpret the suffix content. Use ParseNumericSuffix, ParseLevelSuffix, etc. for content interpretation.
type ThinkingConfig ¶
type ThinkingConfig struct {
// Mode specifies the configuration mode
Mode ThinkingMode
// Budget is the thinking budget (token count), only effective when Mode is ModeBudget.
// Special values: 0 means disabled, -1 means automatic
Budget int
// Level is the thinking level, only effective when Mode is ModeLevel
Level ThinkingLevel
}
ThinkingConfig represents a unified thinking configuration.
This struct is used to pass thinking configuration information between components. Depending on Mode, either Budget or Level field is effective:
- ModeNone: Budget=0, Level is ignored
- ModeAuto: Budget=-1, Level is ignored
- ModeBudget: Budget is a positive integer, Level is ignored
- ModeLevel: Budget is ignored, Level is a valid level
func ValidateConfig ¶
func ValidateConfig(config ThinkingConfig, modelInfo *registry.ModelInfo, provider string) (*ThinkingConfig, error)
ValidateConfig validates a thinking configuration against model capabilities.
This function performs comprehensive validation:
- Checks if the model supports thinking
- Auto-converts between Budget and Level formats based on model capability
- Validates that requested level is in the model's supported levels list
- Clamps budget values to model's allowed range
Parameters:
- config: The thinking configuration to validate
- support: Model's ThinkingSupport properties (nil means no thinking support)
Returns:
- Normalized ThinkingConfig with clamped values
- ThinkingError if validation fails (ErrThinkingNotSupported, ErrLevelNotSupported, etc.)
Auto-conversion behavior:
- Budget-only model + Level config → Level converted to Budget
- Level-only model + Budget config → Budget converted to Level
- Hybrid model → preserve original format
type ThinkingError ¶
type ThinkingError struct {
// Code is the machine-readable error code
Code ErrorCode
// Message is the human-readable error description.
// Should be lowercase, no trailing period, with context if applicable.
Message string
// Model is the model name related to this error (optional)
Model string
// Details contains additional context information (optional)
Details map[string]interface{}
}
ThinkingError represents an error that occurred during thinking configuration processing.
This error type provides structured information about the error, including:
- Code: A machine-readable error code for programmatic handling
- Message: A human-readable description of the error
- Model: The model name related to the error (optional)
- Details: Additional context information (optional)
func NewThinkingError ¶
func NewThinkingError(code ErrorCode, message string) *ThinkingError
NewThinkingError creates a new ThinkingError with the given code and message.
func NewThinkingErrorWithModel ¶
func NewThinkingErrorWithModel(code ErrorCode, message, model string) *ThinkingError
NewThinkingErrorWithModel creates a new ThinkingError with model context.
func (*ThinkingError) Error ¶
func (e *ThinkingError) Error() string
Error implements the error interface. Returns the message directly without code prefix. Use Code field for programmatic error handling.
func (*ThinkingError) StatusCode ¶
func (e *ThinkingError) StatusCode() int
StatusCode implements a portable status code interface for HTTP handlers.
type ThinkingLevel ¶
type ThinkingLevel string
ThinkingLevel represents a discrete thinking level.
const ( // LevelNone disables thinking LevelNone ThinkingLevel = "none" // LevelAuto enables automatic/dynamic thinking LevelAuto ThinkingLevel = "auto" // LevelMinimal sets minimal thinking effort LevelMinimal ThinkingLevel = "minimal" // LevelLow sets low thinking effort LevelLow ThinkingLevel = "low" // LevelMedium sets medium thinking effort LevelMedium ThinkingLevel = "medium" // LevelHigh sets high thinking effort LevelHigh ThinkingLevel = "high" // LevelXHigh sets extra-high thinking effort LevelXHigh ThinkingLevel = "xhigh" )
func ParseLevelSuffix ¶
func ParseLevelSuffix(rawSuffix string) (level ThinkingLevel, ok bool)
ParseLevelSuffix attempts to parse a raw suffix as a discrete thinking level.
This function parses the raw suffix content (from ParseSuffix.RawSuffix) as a level. Only discrete effort levels are valid: minimal, low, medium, high, xhigh. Level matching is case-insensitive.
Special values (none, auto) are NOT handled by this function; use ParseSpecialSuffix instead. This separation allows callers to prioritize special value handling.
Examples:
- "high" -> level=LevelHigh, ok=true
- "HIGH" -> level=LevelHigh, ok=true (case insensitive)
- "medium" -> level=LevelMedium, ok=true
- "none" -> level="", ok=false (special value, use ParseSpecialSuffix)
- "auto" -> level="", ok=false (special value, use ParseSpecialSuffix)
- "8192" -> level="", ok=false (numeric, use ParseNumericSuffix)
- "ultra" -> level="", ok=false (unknown level)
type ThinkingMode ¶
type ThinkingMode int
ThinkingMode represents the type of thinking configuration mode.
const ( // ModeBudget indicates using a numeric budget (corresponds to suffix "(1000)" etc.) ModeBudget ThinkingMode = iota // ModeLevel indicates using a discrete level (corresponds to suffix "(high)" etc.) ModeLevel // ModeNone indicates thinking is disabled (corresponds to suffix "(none)" or budget=0) ModeNone // ModeAuto indicates automatic/dynamic thinking (corresponds to suffix "(auto)" or budget=-1) ModeAuto )
func ParseSpecialSuffix ¶
func ParseSpecialSuffix(rawSuffix string) (mode ThinkingMode, ok bool)
ParseSpecialSuffix attempts to parse a raw suffix as a special thinking mode value.
This function handles special strings that represent a change in thinking mode:
- "none" -> ModeNone (disables thinking)
- "auto" -> ModeAuto (automatic/dynamic thinking)
- "-1" -> ModeAuto (numeric representation of auto mode)
String values are case-insensitive.
func (ThinkingMode) String ¶
func (m ThinkingMode) String() string
String returns the string representation of ThinkingMode.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
provider
|
|
|
antigravity
Package antigravity implements thinking configuration for Antigravity API format.
|
Package antigravity implements thinking configuration for Antigravity API format. |
|
claude
Package claude implements thinking configuration scaffolding for Claude models.
|
Package claude implements thinking configuration scaffolding for Claude models. |
|
codex
Package codex implements thinking configuration for Codex (OpenAI Responses API) models.
|
Package codex implements thinking configuration for Codex (OpenAI Responses API) models. |
|
gemini
Package gemini implements thinking configuration for Gemini models.
|
Package gemini implements thinking configuration for Gemini models. |
|
geminicli
Package geminicli implements thinking configuration for Gemini CLI API format.
|
Package geminicli implements thinking configuration for Gemini CLI API format. |
|
iflow
Package iflow implements thinking configuration for iFlow models (GLM, MiniMax).
|
Package iflow implements thinking configuration for iFlow models (GLM, MiniMax). |
|
openai
Package openai implements thinking configuration for OpenAI/Codex models.
|
Package openai implements thinking configuration for OpenAI/Codex models. |