Module: Legion::LLM::Inference::Prompt

Extended by:
Legion::Logging::Helper
Defined in:
lib/legion/llm/inference/prompt.rb

Class Method Summary collapse

Class Method Details

.config_value(config, key, default = nil) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/legion/llm/inference/prompt.rb', line 20

def config_value(config, key, default = nil)
  return default unless config.respond_to?(:key?)

  string_key = key.to_s
  return config[string_key] if config.key?(string_key)

  symbol_key = key.to_sym if key.respond_to?(:to_sym)
  return config[symbol_key] if symbol_key && config.key?(symbol_key)

  default
end

.decide(question, options:, tools: []) ⇒ Object

Pick from a set of options with reasoning.



136
137
138
139
# File 'lib/legion/llm/inference/prompt.rb', line 136

def decide(question, options:, tools: [], **)
  prompt = build_decide_prompt(question, options)
  dispatch(prompt, tools: tools, **)
end

.dispatch(message, intent: nil, tier: nil, exclude: {}, provider: nil, model: nil, schema: nil, tools: nil, escalate: nil, max_escalations: 3, thinking: nil, temperature: nil, max_tokens: nil, tracing: nil, agent: nil, caller: nil, cache: nil, quality_check: nil) ⇒ Object

Auto-routed: Router picks the best provider+model based on intent. Primary entry point for most LLM calls. When provider/model are passed explicitly, they take precedence over routing.



35
36
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/legion/llm/inference/prompt.rb', line 35

def dispatch(message, # rubocop:disable Metrics/ParameterLists
             intent: nil,
             tier: nil,
             exclude: {},
             provider: nil,
             model: nil,
             schema: nil,
             tools: nil,
             escalate: nil,
             max_escalations: 3,
             thinking: nil,
             temperature: nil,
             max_tokens: nil,
             tracing: nil,
             agent: nil,
             caller: nil,
             cache: nil,
             quality_check: nil,
             **)
  resolved_provider = provider
  resolved_model = model

  if resolved_provider.nil? && resolved_model.nil? && defined?(Router) && Router.routing_enabled? && (intent || tier)
    resolution = Router.resolve(intent: intent, tier: tier, exclude: exclude)
    resolved_provider = resolution&.provider
    resolved_model = resolution&.model
  end

  resolved_provider ||= llm_setting(:default_provider)
  resolved_model ||= llm_setting(:default_model)

  request(message,
          provider:        resolved_provider,
          model:           resolved_model,
          intent:          intent,
          tier:            tier,
          schema:          schema,
          tools:           tools,
          escalate:        escalate,
          max_escalations: max_escalations,
          thinking:        thinking,
          temperature:     temperature,
          max_tokens:      max_tokens,
          tracing:         tracing,
          agent:           agent,
          caller:          caller,
          cache:           cache,
          quality_check:   quality_check,
          **)
end

.extract(text, schema:, tools: []) ⇒ Object

Extract structured data from unstructured text.



130
131
132
133
# File 'lib/legion/llm/inference/prompt.rb', line 130

def extract(text, schema:, tools: [], **)
  prompt = build_extract_prompt(text)
  dispatch(prompt, schema: schema, tools: tools, **)
end

.llm_setting(key, default = nil) ⇒ Object



13
14
15
16
17
18
# File 'lib/legion/llm/inference/prompt.rb', line 13

def llm_setting(key, default = nil)
  Legion::LLM::Settings.value(key, default: default)
rescue StandardError => e
  handle_exception(e, level: :warn, handled: true, operation: 'llm.inference.prompt.llm_setting', key: key)
  default
end

.request(message, provider:, model:, intent: nil, tier: nil, schema: nil, tools: nil, escalate: nil, max_escalations: 3, thinking: nil, temperature: nil, max_tokens: nil, tracing: nil, agent: nil, caller: nil, cache: nil, quality_check: nil) ⇒ Object

Pinned: caller specifies exact provider+model. Full pipeline runs in-process.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/legion/llm/inference/prompt.rb', line 87

def request(message, # rubocop:disable Metrics/ParameterLists
            provider:,
            model:,
            intent: nil,
            tier: nil,
            schema: nil,
            tools: nil,
            escalate: nil,
            max_escalations: 3,
            thinking: nil,
            temperature: nil,
            max_tokens: nil,
            tracing: nil,
            agent: nil,
            caller: nil,
            cache: nil,
            quality_check: nil,
            **)
  if provider.nil? || model.nil?
    raise LLMError, "Prompt.request: provider and model must be set (got provider=#{provider.inspect}, model=#{model.inspect}). " \
                    'Configure Legion::Settings[:llm][:default_provider] and [:default_model], or pass them explicitly.'
  end

  pipeline_request = build_pipeline_request(
    message, provider: provider, model: model, intent: intent, tier: tier,
             schema: schema, tools: tools,
             escalate: escalate, max_escalations: max_escalations,
             thinking: thinking, temperature: temperature, max_tokens: max_tokens,
             tracing: tracing, agent: agent, caller: caller, cache: cache,
             quality_check: quality_check, **
  )

  executor = Inference::Executor.new(pipeline_request)
  executor.call
end

.summarize(messages, tools: []) ⇒ Object

Condense a conversation or feedback history into a shorter form.



124
125
126
127
# File 'lib/legion/llm/inference/prompt.rb', line 124

def summarize(messages, tools: [], **)
  prompt = build_summarize_prompt(messages)
  dispatch(prompt, tools: tools, **)
end