thinking

package
v6.10.9-aug.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 14, 2026 License: MIT Imports: 8 Imported by: 0

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

View Source
const (
	GeminiDirectPrefix = "generationConfig.thinkingConfig"
	GeminiCLIPrefix    = "request.generationConfig.thinkingConfig"
)

Gemini-family path prefixes for thinkingConfig.

View Source
const (
	OpenAIEffortField = "reasoning_effort"
	CodexEffortField  = "reasoning.effort"
)

Reasoning effort field paths for OpenAI-family providers.

View Source
const (
	// ModeBudget indicates using a numeric budget (corresponds to suffix "(1000)" etc.)
	ModeBudget mode = 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
)

Variables

This section is empty.

Functions

func ApplyGeminiBudgetFormat

func ApplyGeminiBudgetFormat(body []byte, config Config, budget int, prefix string) ([]byte, error)

ApplyGeminiBudgetFormat applies budget-based thinking configuration using the given JSON path prefix. Used by gemini, gemini-cli, and antigravity providers which share identical logic but differ in JSON paths. The budget parameter allows callers to pre-process the budget (e.g., antigravity's Claude normalization).

func ApplyGeminiCompatible

func ApplyGeminiCompatible(
	body []byte,
	config Config,
	levelFn func([]byte, Config) ([]byte, error),
	budgetFn func([]byte, Config) ([]byte, error),
) ([]byte, error)

ApplyGeminiCompatible applies thinking configuration for user-defined models using the given JSON path prefix and format applier functions. This handles the mode routing logic shared across gemini-family providers.

func ApplyGeminiLevelFormat

func ApplyGeminiLevelFormat(body []byte, config Config, prefix string) ([]byte, error)

ApplyGeminiLevelFormat applies level-based thinking configuration using the given JSON path prefix. Used by gemini, gemini-cli, and antigravity providers which share identical logic but differ in JSON paths.

func ApplyReasoningEffort

func ApplyReasoningEffort(body []byte, config Config, modelInfo *registry.ModelInfo, fieldPath string) ([]byte, error)

ApplyReasoningEffort applies thinking configuration using the reasoning effort format. Used by openai and codex providers which share identical logic but differ in JSON field paths.

func ApplyThinking

func ApplyThinking(body []byte, model string, fromFormat string, toFormat string, providerKey string) ([]byte, error)

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)")
  • fromFormat: Source request format (e.g., openai, codex, gemini)
  • toFormat: Target provider format for the request body (gemini, gemini-cli, antigravity, claude, openai, codex, iflow)
  • providerKey: Provider identifier used for registry model lookups (may differ from toFormat, e.g., openrouter -> openai)

Returns:

  • Modified request body JSON with thinking configuration applied
  • Error if validation fails (Error). 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", "gemini", "gemini")

// Without suffix - uses body config
result, err := thinking.ApplyThinking(body, "gemini-2.5-pro", "gemini", "gemini", "gemini")

func ConvertBudgetToLevel

func ConvertBudgetToLevel(budget int) (string, bool)

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

func ConvertLevelToBudget(level string) (int, bool)

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

func GetThinkingText(part gjson.Result) string

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 HasContext1MTag

func HasContext1MTag(model string) bool

func HasLevel

func HasLevel(levels []string, target string) bool

HasLevel reports whether the given target level exists in the levels slice. Matching is case-insensitive with leading/trailing whitespace trimmed.

func IsUserDefinedModel

func IsUserDefinedModel(modelInfo *registry.ModelInfo) bool

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 MapToClaudeEffort

func MapToClaudeEffort(level string, supportsMax bool) (string, bool)

MapToClaudeEffort maps a generic thinking level string to a Claude adaptive thinking effort value (low/medium/high/max).

supportsMax indicates whether the target model supports "max" effort. Returns the mapped effort and true if the level is valid, or ("", false) otherwise.

func PreserveRequestModelDecorations

func PreserveRequestModelDecorations(resolved, requested string) string

func RegisterProvider

func RegisterProvider(name string, applier ProviderApplier)

RegisterProvider registers a provider applier by name.

func ValidateGeminiPreconditions

func ValidateGeminiPreconditions(body []byte, config Config) ([]byte, bool)

ValidateGeminiPreconditions validates the mode and body for Gemini-family thinking apply. Returns the (possibly sanitized) body and whether to continue.

Types

type Config

type Config struct {
	// Mode specifies the configuration mode
	Mode mode
	// 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 Level
}

Config 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

type Error

type Error 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]any
}

Error 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 (*Error) Error

func (e *Error) Error() string

Error implements the error interface. Returns the message directly without code prefix. Use Code field for programmatic error handling.

func (*Error) StatusCode

func (e *Error) StatusCode() int

StatusCode implements a portable status code interface for HTTP handlers.

type Level

type Level string

Level represents a discrete thinking level.

const (
	// LevelNone disables thinking
	LevelNone Level = "none"
	// LevelAuto enables automatic/dynamic thinking
	LevelAuto Level = "auto"

	// LevelHigh sets high thinking effort
	LevelHigh Level = "high"
	// LevelXHigh sets extra-high thinking effort
	LevelXHigh Level = "xhigh"
	// LevelMax sets maximum thinking effort
	LevelMax Level = "max"
)

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
	//   - Error if the configuration is invalid or unsupported
	Apply(body []byte, config Config, 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 Config 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 Error for unsupported configurations

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.

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.
Package iflow implements thinking configuration for iFlow models.
kimi
Package kimi implements thinking configuration for Kimi (Moonshot AI) models.
Package kimi implements thinking configuration for Kimi (Moonshot AI) models.
openai
Package openai implements thinking configuration for OpenAI/Codex models.
Package openai implements thinking configuration for OpenAI/Codex models.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL