Module: Legion::LLM::Helper

Includes:
Legion::Logging::Helper
Included in:
Extensions::Helpers::LLM
Defined in:
lib/legion/llm/helper.rb

Instance Method Summary collapse

Instance Method Details

#llm_ask(message:) ⇒ Object



89
90
91
# File 'lib/legion/llm/helper.rb', line 89

def llm_ask(message:, **)
  Legion::LLM.ask(message: message, **)
end

#llm_budget_remainingObject



134
135
136
137
138
139
# File 'lib/legion/llm/helper.rb', line 134

def llm_budget_remaining
  Legion::LLM::Hooks::BudgetGuard.remaining
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.budget_remaining')
  Float::INFINITY
end

#llm_can_embed?Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
# File 'lib/legion/llm/helper.rb', line 102

def llm_can_embed?
  llm_connected? && Legion::LLM.can_embed?
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.can_embed')
  false
end

#llm_chat(message, model: nil, provider: nil, intent: nil, tier: nil, tools: [], instructions: nil, compress: 0, escalate: nil, max_escalations: nil, quality_check: nil, caller: nil, use_default_intent: false) ⇒ Object

--- Core Operations ---



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/legion/llm/helper.rb', line 37

def llm_chat(message, model: nil, provider: nil, intent: nil, tier: nil, tools: [],
             instructions: nil, compress: 0, escalate: nil, max_escalations: nil,
             quality_check: nil, caller: nil, use_default_intent: false)
  # SSOT v3: forward explicit provider/model or none. An omitted model/provider
  # is an empty constraint the router resolves, never a configured default.
  effective_model = model
  effective_provider = provider
  effective_intent = intent || (use_default_intent ? llm_default_intent : nil)

  if compress.positive?
    message = Legion::LLM::Context::Compressor.compress(message, level: compress)
    instructions = Legion::LLM::Context::Compressor.compress(instructions, level: compress) if instructions
  end

  if escalate
    return Legion::LLM.chat(model: effective_model, provider: effective_provider,
                            intent: effective_intent, tier: tier,
                            escalate: true, max_escalations: max_escalations,
                            quality_check: quality_check, message: message, caller: caller)
  end

  chat = Legion::LLM.chat(model: effective_model, provider: effective_provider,
                          intent: effective_intent, tier: tier,
                          escalate: false, caller: caller)
  chat.with_instructions(instructions) if instructions
  chat.with_tools(*tools) unless tools.empty?
  chat.ask(message)
end

#llm_connected?Boolean

--- Status ---

Returns:

  • (Boolean)


95
96
97
98
99
100
# File 'lib/legion/llm/helper.rb', line 95

def llm_connected?
  defined?(Legion::LLM) && Legion::LLM.started?
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.connected')
  false
end

#llm_cost_estimate(model: nil, input_tokens: 0, output_tokens: 0) ⇒ Object

--- Cost / Budget ---



118
119
120
121
122
123
124
125
# File 'lib/legion/llm/helper.rb', line 118

def llm_cost_estimate(model: nil, input_tokens: 0, output_tokens: 0)
  model ||= llm_default_model
  Legion::LLM::Metering::Pricing.estimate(model_id: model, input_tokens: input_tokens,
                                          output_tokens: output_tokens)
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.cost_estimate', model: model)
  0.0
end

#llm_cost_summary(since: nil) ⇒ Object



127
128
129
130
131
132
# File 'lib/legion/llm/helper.rb', line 127

def llm_cost_summary(since: nil)
  Legion::LLM::Metering::Recorder.summary(since: since)
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.cost_summary')
  { total_cost_usd: 0.0, total_requests: 0, total_input_tokens: 0, total_output_tokens: 0, by_model: {} }
end

#llm_default_intentObject



28
29
30
31
32
33
# File 'lib/legion/llm/helper.rb', line 28

def llm_default_intent
  Legion::Settings.dig(:llm, :routing, :default_intent)
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.default_intent')
  nil
end

#llm_default_modelObject

--- Layered Defaults --- Override in your LEX to set extension-specific defaults. Resolution chain: per-call kwarg -> LEX override -> Settings -> nil (auto-detect)



14
15
16
17
18
19
# File 'lib/legion/llm/helper.rb', line 14

def llm_default_model
  Legion::Settings[:llm][:default_model]
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.default_model')
  nil
end

#llm_default_providerObject



21
22
23
24
25
26
# File 'lib/legion/llm/helper.rb', line 21

def llm_default_provider
  Legion::Settings[:llm][:default_provider]
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.default_provider')
  nil
end

#llm_embed(text) ⇒ Object



66
67
68
# File 'lib/legion/llm/helper.rb', line 66

def llm_embed(text, **)
  Legion::LLM.embed(text, **)
end

#llm_embed_batch(texts) ⇒ Object



70
71
72
# File 'lib/legion/llm/helper.rb', line 70

def llm_embed_batch(texts, **)
  Legion::LLM.embed_batch(texts, **)
end

#llm_routing_enabled?Boolean

Returns:

  • (Boolean)


109
110
111
112
113
114
# File 'lib/legion/llm/helper.rb', line 109

def llm_routing_enabled?
  llm_connected? && Legion::LLM::Router.routing_enabled?
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'llm.helper.routing_enabled')
  false
end

#llm_session(model: nil, provider: nil, intent: nil, tier: nil, caller: nil, use_default_intent: false) ⇒ Object



74
75
76
77
78
79
80
81
82
83
# File 'lib/legion/llm/helper.rb', line 74

def llm_session(model: nil, provider: nil, intent: nil, tier: nil, caller: nil, use_default_intent: false)
  # SSOT v3: forward explicit provider/model or none (empty constraint).
  effective_model = model
  effective_provider = provider
  effective_intent = intent || (use_default_intent ? llm_default_intent : nil)

  Legion::LLM.chat(model: effective_model, provider: effective_provider,
                   intent: effective_intent, tier: tier,
                   escalate: false, caller: caller)
end

#llm_structured(messages:, schema:) ⇒ Object



85
86
87
# File 'lib/legion/llm/helper.rb', line 85

def llm_structured(messages:, schema:, **)
  Legion::LLM.structured(messages: messages, schema: schema, **)
end