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

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

Pick from a set of options with reasoning.



127
128
129
130
# File 'lib/legion/llm/inference/prompt.rb', line 127

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

.dispatch(message, intent: nil, tier: nil, 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.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
# File 'lib/legion/llm/inference/prompt.rb', line 16

def dispatch(message,
             intent: nil,
             tier: nil,
             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,
             **)
  # SSOT v3: dispatch no longer pre-selects a provider/model. It forwards the
  # caller's explicit constraints or none — an omitted provider/model is an
  # empty constraint the canonical Request -> Executor (RoutingSession) path
  # resolves. The executor's routing step owns provider inference, tier
  # lane selection, and any old-path default injection (kept behind the
  # SSOT-active gate). The only thing done here is clearing the provider for
  # an auto-routing placeholder model and defaulting its routing intent.
  routing_explicit = { provider: !provider.nil?, model: !model.nil?, tier: !tier.nil? }
  resolved_provider = provider
  resolved_model = model
  auto_route = Inference::Request.auto_routing_model?(resolved_model)

  if auto_route
    resolved_provider = nil
    intent ||= Inference::Request.default_auto_routing_intent
  end

  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,
          routing_explicit: routing_explicit,
          **)
end

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

Extract structured data from unstructured text.



121
122
123
124
# File 'lib/legion/llm/inference/prompt.rb', line 121

def extract(text, schema:, tools: [], **)
  prompt = build_extract_prompt(text)
  dispatch(prompt, schema: schema, tools: tools, **)
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.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
# File 'lib/legion/llm/inference/prompt.rb', line 73

def 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,
            **)
  # SSOT v3: provider/model resolution is the executor/RoutingSession's job.
  # Forward explicit-or-nil and only raise when nothing can resolve the
  # request — no explicit pin, no auto-routing placeholder, no inventory
  # lane, no configured default, and no active SSOT registry.
  auto_route = Inference::Request.auto_routing_model?(model)
  unless routing_resolvable?(provider, model, auto_route)
    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], publish an inventory lane, 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.



115
116
117
118
# File 'lib/legion/llm/inference/prompt.rb', line 115

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