Module: Rubino::Config::ReasoningPrefs

Defined in:
lib/rubino/config/reasoning_prefs.rb

Overview

Single source of truth for how reasoning/thinking preferences are resolved from config, shared by the LLM adapter gate and the CLI render path so they can never drift.

Two orthogonal knobs:

* display.reasoning — how reasoning is RENDERED (hidden | collapsed | full)
* thinking.effort   — how HARD the model thinks (off | low | medium | high)

display.show_reasoning (legacy boolean) maps in for back-compat ONLY when display.reasoning is unset: true→full, false→hidden.

Constant Summary collapse

RENDER_MODES =
%i[hidden collapsed full].freeze
DEFAULT_MODE =
:collapsed
EFFORTS =
%i[off low medium high].freeze
DEFAULT_EFFORT =
:medium
EFFORT_BUDGETS =

Effort → Anthropic thinking-token budget. off disables thinking (0).

{
  off: 0,
  low: 4_000,
  medium: 8_000,
  high: 16_000
}.freeze

Class Method Summary collapse

Class Method Details

.effort(config) ⇒ Object

The effort symbol for a config object, or nil when thinking.effort is unset (so callers can fall back to the existing thinking_budget chain).



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rubino/config/reasoning_prefs.rb', line 48

def effort(config)
  raw = config&.dig("thinking", "effort")
  return nil if raw.nil?
  # YAML parses an unquoted `off` as the boolean false, which used to
  # silently break thinking-budget gating (#79) — coerce it back to :off
  # here, the single read boundary, so a doc-following config keeps working.
  return :off if raw == false

  sym = raw.to_s.strip.downcase.to_sym
  EFFORTS.include?(sym) ? sym : nil
end

.effort_budget(effort) ⇒ Object

Token budget for an effort symbol (nil/unknown → nil so the caller can fall back to its own default chain).



62
63
64
# File 'lib/rubino/config/reasoning_prefs.rb', line 62

def effort_budget(effort)
  EFFORT_BUDGETS[effort]
end

.mode(config) ⇒ Object

The render mode symbol for a config object. Prefers display.reasoning; falls back to the legacy display.show_reasoning boolean; else the default.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/rubino/config/reasoning_prefs.rb', line 34

def mode(config)
  raw = config&.dig("display", "reasoning")
  sym = raw.to_s.strip.downcase.to_sym unless raw.nil?
  return sym if RENDER_MODES.include?(sym)

  legacy = config&.dig("display", "show_reasoning")
  return :full if legacy == true
  return :hidden if legacy == false

  DEFAULT_MODE
end