Class: Legion::Extensions::Llm::Canonical::Thinking::Config

Inherits:
Data
  • Object
show all
Defined in:
lib/legion/extensions/llm/canonical/thinking_config.rb

Overview

Normalized config for thinking across providers — one name, one shape (04 §8): Canonical::Thinking::Config. Members: enabled, effort, budget, summary, metadata

Constant Summary collapse

EFFORT_LEVELS =

Closed set of valid effort levels.

%w[none low medium high xhigh max].freeze
EFFORT_BUDGET =

SSOT for the effort<->budget conversion. A client dialect supplies only ONE axis (Anthropic = budget_tokens only; OpenAI = effort only), but a provider translator may need the OTHER. This single map lets every provider ask for whichever axis it needs and always get a usable value, so thinking survives any client x provider pair (best-effort, never silently dropped). effort -> budget is exact; budget -> effort uses the band boundaries above. 'none' has no budget — resolves to nil.

{
  'low' => 1024, 'medium' => 8192, 'high' => 16_384,
  'xhigh' => 24_576, 'max' => 32_768
}.freeze
SUMMARY_LEVELS =

Closed set of valid summary levels.

%i[auto none concise detailed].freeze
BUILD_SITE =
'Canonical::Thinking::Config.build'
FROM_HASH_SITE =
'Canonical::Thinking::Config.from_hash'
NEW_SITE =
'Canonical::Thinking::Config.new'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#budgetObject (readonly)

Returns the value of attribute budget

Returns:

  • (Object)

    the current value of budget



13
14
15
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 13

def budget
  @budget
end

#effortObject (readonly)

Returns the value of attribute effort

Returns:

  • (Object)

    the current value of effort



13
14
15
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 13

def effort
  @effort
end

#enabledObject (readonly)

Returns the value of attribute enabled

Returns:

  • (Object)

    the current value of enabled



13
14
15
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 13

def enabled
  @enabled
end

#metadataObject (readonly)

Returns the value of attribute metadata

Returns:

  • (Object)

    the current value of metadata



13
14
15
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 13

def 
  @metadata
end

#summaryObject (readonly)

Returns the value of attribute summary

Returns:

  • (Object)

    the current value of summary



13
14
15
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 13

def summary
  @summary
end

Class Method Details

.build(enabled: true, effort: nil, budget: nil, summary: nil, metadata: {}) ⇒ Object



14
15
16
17
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 14

def self.build(enabled: true, effort: nil, budget: nil, summary: nil, metadata: {})
  new(enabled: enabled, effort: effort_string!(effort, self::BUILD_SITE), budget: budget,
      summary: summary, metadata: Strict.metadata!(, self::BUILD_SITE))
end

.effort_string!(effort, site) ⇒ Object

M4: effort is a closed enum (the EFFORT_BUDGET keys), not an unbounded string — an unrecognized effort is a contract error at construction, never a silently-derived budget.

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 32

def self.effort_string!(effort, site)
  return nil if effort.nil?

  value = effort.is_a?(::Symbol) ? effort.to_s : Strict.expect_type!(effort, [::String], site, :effort)
  normalized = value.downcase
  allowed = self::EFFORT_LEVELS
  raise ArgumentError, "#{site}: Invalid effort: #{value.inspect}. Must be one of: #{allowed.join(', ')}" unless allowed.include?(normalized)

  normalized
end

.from_hash(source) ⇒ Object

Build from a Hash.



20
21
22
23
24
25
26
27
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 20

def self.from_hash(source)
  Strict.require_hash!(source, self::FROM_HASH_SITE)
  hash = Strict.symbolize_keys(source)
   = Strict.fold_unknowns!(self, self::FROM_HASH_SITE, hash)
  build(enabled: hash.key?(:enabled) ? hash[:enabled] : true,
        effort: hash[:effort], budget: hash[:budget],
        summary: hash[:summary], metadata: )
end

.summary_enum!(value, site) ⇒ Object

Validate summary is a closed enum.



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 44

def self.summary_enum!(value, site)
  return nil if value.nil?

  sym = value.is_a?(::String) ? value.to_sym : value
  Strict.expect_type!(sym, [::Symbol], site, :summary)
  allowed = self::SUMMARY_LEVELS
  unless allowed.include?(sym)
    raise ArgumentError,
          "#{site}: Invalid summary: #{value.inspect}. Must be one of: #{allowed.map(&:inspect).join(', ')}"
  end

  sym
end

Instance Method Details

#as_jsonObject



64
65
66
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 64

def as_json(*)
  to_h
end

#enabled?Boolean

Whether thinking is enabled (the enabled member).

Returns:

  • (Boolean)


73
74
75
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 73

def enabled?
  enabled
end

#resolved_budgetObject

Budget for a provider that needs a token budget (e.g. Anthropic), derived from effort when budget was not explicitly set. nil when effort is 'none' or neither axis is configured. Only FILLS — never overwrites a supplied budget. Both axes may be carried together.



81
82
83
84
85
86
87
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 81

def resolved_budget
  return budget unless budget.nil?
  return nil if effort.nil?
  return nil if effort == 'none'

  self.class::EFFORT_BUDGET[effort]
end

#resolved_effortObject

Effort for a provider that needs an effort level (e.g. OpenAI), derived from budget when effort was not explicitly set. nil only when neither axis is configured. Only FILLS — never overwrites a supplied effort.



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 93

def resolved_effort
  return effort unless effort.nil?
  return nil if budget.nil?

  bands = self.class::EFFORT_BUDGET
  if budget <= bands['low'] then 'low'
  elsif budget <= bands['medium'] then 'medium'
  elsif budget <= bands['high'] then 'high'
  elsif budget <= bands['xhigh'] then 'xhigh'
  else 'max'
  end
end

#to_hObject

Serialize to a Hash for AMQP/fleet/wire transport. Faithful to what was SET — never fabricates the missing axis (use resolved_* for that).



60
61
62
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 60

def to_h
  super.compact
end

#to_jsonObject



68
69
70
# File 'lib/legion/extensions/llm/canonical/thinking_config.rb', line 68

def to_json(*)
  to_h.to_json(*)
end