Class: Legion::LLM::Inference::Request

Inherits:
Data
  • Object
show all
Defined in:
lib/legion/llm/inference/request.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent

Returns:

  • (Object)

    the current value of agent



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def agent
  @agent
end

#billingObject (readonly)

Returns the value of attribute billing

Returns:

  • (Object)

    the current value of billing



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def billing
  @billing
end

#body_model_hint_decisionObject (readonly)

Returns the value of attribute body_model_hint_decision

Returns:

  • (Object)

    the current value of body_model_hint_decision



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def body_model_hint_decision
  @body_model_hint_decision
end

#cacheObject (readonly)

Returns the value of attribute cache

Returns:

  • (Object)

    the current value of cache



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def cache
  @cache
end

#callerObject (readonly)

Returns the value of attribute caller

Returns:

  • (Object)

    the current value of caller



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def caller
  @caller
end

#classificationObject (readonly)

Returns the value of attribute classification

Returns:

  • (Object)

    the current value of classification



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def classification
  @classification
end

#context_strategyObject (readonly)

Returns the value of attribute context_strategy

Returns:

  • (Object)

    the current value of context_strategy



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def context_strategy
  @context_strategy
end

#conversation_idObject (readonly)

Returns the value of attribute conversation_id

Returns:

  • (Object)

    the current value of conversation_id



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def conversation_id
  @conversation_id
end

#enrichmentsObject (readonly)

Returns the value of attribute enrichments

Returns:

  • (Object)

    the current value of enrichments



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def enrichments
  @enrichments
end

#extraObject (readonly)

Returns the value of attribute extra

Returns:

  • (Object)

    the current value of extra



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def extra
  @extra
end

#forkObject (readonly)

Returns the value of attribute fork

Returns:

  • (Object)

    the current value of fork



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def fork
  @fork
end

#generationObject (readonly)

Returns the value of attribute generation

Returns:

  • (Object)

    the current value of generation



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def generation
  @generation
end

#hooksObject (readonly)

Returns the value of attribute hooks

Returns:

  • (Object)

    the current value of hooks



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def hooks
  @hooks
end

#idObject (readonly)

Returns the value of attribute id

Returns:

  • (Object)

    the current value of id



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def id
  @id
end

#idempotency_keyObject (readonly)

Returns the value of attribute idempotency_key

Returns:

  • (Object)

    the current value of idempotency_key



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def idempotency_key
  @idempotency_key
end

#messagesObject (readonly)

Returns the value of attribute messages

Returns:

  • (Object)

    the current value of messages



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def messages
  @messages
end

#metadataObject (readonly)

Returns the value of attribute metadata

Returns:

  • (Object)

    the current value of metadata



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def 
  @metadata
end

#modalityObject (readonly)

Returns the value of attribute modality

Returns:

  • (Object)

    the current value of modality



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def modality
  @modality
end

#predictionsObject (readonly)

Returns the value of attribute predictions

Returns:

  • (Object)

    the current value of predictions



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def predictions
  @predictions
end

#priorityObject (readonly)

Returns the value of attribute priority

Returns:

  • (Object)

    the current value of priority



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def priority
  @priority
end

#response_formatObject (readonly)

Returns the value of attribute response_format

Returns:

  • (Object)

    the current value of response_format



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def response_format
  @response_format
end

#routingObject (readonly)

Returns the value of attribute routing

Returns:

  • (Object)

    the current value of routing



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def routing
  @routing
end

#routing_contextObject (readonly)

Returns the value of attribute routing_context

Returns:

  • (Object)

    the current value of routing_context



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def routing_context
  @routing_context
end

#routing_settings_snapshotObject (readonly)

Returns the value of attribute routing_settings_snapshot

Returns:

  • (Object)

    the current value of routing_settings_snapshot



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def routing_settings_snapshot
  @routing_settings_snapshot
end

#schema_versionObject (readonly)

Returns the value of attribute schema_version

Returns:

  • (Object)

    the current value of schema_version



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def schema_version
  @schema_version
end

#stopObject (readonly)

Returns the value of attribute stop

Returns:

  • (Object)

    the current value of stop



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def stop
  @stop
end

#streamObject (readonly)

Returns the value of attribute stream

Returns:

  • (Object)

    the current value of stream



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def stream
  @stream
end

#systemObject (readonly)

Returns the value of attribute system

Returns:

  • (Object)

    the current value of system



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def system
  @system
end

#testObject (readonly)

Returns the value of attribute test

Returns:

  • (Object)

    the current value of test



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def test
  @test
end

#thinkingObject (readonly)

Returns the value of attribute thinking

Returns:

  • (Object)

    the current value of thinking



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def thinking
  @thinking
end

#tokensObject (readonly)

Returns the value of attribute tokens

Returns:

  • (Object)

    the current value of tokens



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def tokens
  @tokens
end

#tool_choiceObject (readonly)

Returns the value of attribute tool_choice

Returns:

  • (Object)

    the current value of tool_choice



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def tool_choice
  @tool_choice
end

#toolsObject (readonly)

Returns the value of attribute tools

Returns:

  • (Object)

    the current value of tools



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def tools
  @tools
end

#tracingObject (readonly)

Returns the value of attribute tracing

Returns:

  • (Object)

    the current value of tracing



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def tracing
  @tracing
end

#trusted_constraintsObject (readonly)

Returns the value of attribute trusted_constraints

Returns:

  • (Object)

    the current value of trusted_constraints



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def trusted_constraints
  @trusted_constraints
end

#ttlObject (readonly)

Returns the value of attribute ttl

Returns:

  • (Object)

    the current value of ttl



14
15
16
# File 'lib/legion/llm/inference/request.rb', line 14

def ttl
  @ttl
end

Class Method Details

.auto_routing_model?(model) ⇒ Boolean

Returns:

  • (Boolean)


166
167
168
169
170
171
172
# File 'lib/legion/llm/inference/request.rb', line 166

def self.auto_routing_model?(model)
  routing_settings = Legion::Settings.dig(:llm, :routing) || {}
  configured = routing_settings[:auto_routing_model_aliases]
  aliases = Array(configured).map { |entry| entry.to_s.strip.downcase }.reject(&:empty?)
  aliases = [AUTO_ROUTING_MODEL_KEY] if aliases.empty?
  aliases.include?(model.to_s.strip.downcase)
end

.build(routing_context: nil, **kwargs) ⇒ Object

SSOT v3 §7.2 additive build order. routing_context is injected only by build_for_test; otherwise a fresh server seed is created here. The new trusted fields are always populated (derived from existing routing kwargs when a caller has not yet migrated), so every Request carries them.



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

def self.build(routing_context: nil, **kwargs)
  routing, extra = normalize_auto_routing(
    kwargs.fetch(:routing, { provider: nil, model: nil }),
    kwargs.fetch(:extra, {})
  )

  ctx = routing_context || Legion::LLM::RoutingContext.build
  settings_snapshot = kwargs[:routing_settings_snapshot] || Legion::LLM::Router::SettingsState.current
  trusted = kwargs[:trusted_constraints] || trusted_from_routing(routing, settings_snapshot)
  body_decision = Legion::LLM::Router::BodyModelHintPolicy.call(
    body_model: kwargs[:client_model], trusted_model: trusted.model, settings_snapshot: settings_snapshot
  )

  new(
    routing_context:           ctx,
    routing_settings_snapshot: settings_snapshot,
    trusted_constraints:       trusted,
    body_model_hint_decision:  body_decision,
    id:                        kwargs[:id] || "req_#{SecureRandom.hex(12)}",
    conversation_id:           kwargs[:conversation_id],
    idempotency_key:           kwargs[:idempotency_key],
    schema_version:            kwargs.fetch(:schema_version, '1.0.0'),
    system:                    kwargs[:system],
    messages:                  kwargs.fetch(:messages, []),
    tools:                     kwargs.key?(:tools) ? kwargs[:tools] : nil,
    tool_choice:               kwargs.fetch(:tool_choice, { mode: :auto }),
    routing:                   routing,
    tokens:                    kwargs.fetch(:tokens, { max: 4096 }),
    stop:                      kwargs.fetch(:stop, { sequences: [] }),
    generation:                kwargs.fetch(:generation, {}),
    thinking:                  kwargs[:thinking],
    response_format:           kwargs.fetch(:response_format, { type: :text }),
    stream:                    kwargs.fetch(:stream, false),
    fork:                      kwargs[:fork],
    context_strategy:          kwargs.fetch(:context_strategy, :auto),
    cache:                     kwargs.fetch(:cache, { strategy: :default, cacheable: true }),
    priority:                  kwargs.fetch(:priority, :normal),
    ttl:                       kwargs[:ttl],
    extra:                     extra,
    metadata:                  kwargs.fetch(:metadata, {}),
    enrichments:               kwargs.fetch(:enrichments, {}),
    predictions:               kwargs.fetch(:predictions, {}),
    tracing:                   kwargs[:tracing],
    classification:            kwargs[:classification],
    caller:                    kwargs[:caller],
    agent:                     kwargs[:agent],
    billing:                   kwargs[:billing],
    test:                      kwargs[:test],
    modality:                  kwargs[:modality],
    hooks:                     kwargs[:hooks]
  )
end

.build_for_test(routing_seed:, **keywords) ⇒ Object

SSOT v3 §7.2 test helper: delegates to the production normalization path, substituting only a deterministic RoutingContext. It cannot bypass body policy, constraint derivation, or request freezing.



150
151
152
# File 'lib/legion/llm/inference/request.rb', line 150

def self.build_for_test(routing_seed:, **keywords)
  build(routing_context: Legion::LLM::RoutingContext.for_test(routing_seed: routing_seed), **keywords)
end

.default_auto_routing_intentObject



174
175
176
177
178
# File 'lib/legion/llm/inference/request.rb', line 174

def self.default_auto_routing_intent
  intent = Legion::Settings[:llm][:routing][:default_intent]
  intent = intent.is_a?(Hash) ? normalize_hash(intent) : {}
  intent.merge(operation: :chat, effort: :moderate)
end

.from_chat_args(**kwargs) ⇒ Object



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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/legion/llm/inference/request.rb', line 86

def self.from_chat_args(**kwargs)
  request_id = kwargs[:request_id] || kwargs[:id]
  messages = []
  if kwargs[:messages]
    messages = kwargs[:messages]
  elsif kwargs[:message]
    msg = kwargs[:message]
    messages = msg.is_a?(Array) ? msg : [{ role: :user, content: msg }]
  end

  routing = {
    provider: kwargs[:provider],
    model:    kwargs[:model]
  }

  extra = kwargs.except(
    :message, :messages, :model, :provider, :system,
    :tools, :tool_choice, :stream, :caller, :classification, :billing,
    :agent, :test, :tracing, :priority, :conversation_id,
    :request_id, :id, :generation, :thinking, :response_format,
    :context_strategy, :cache, :fork, :tokens, :stop,
    :modality, :hooks, :idempotency_key, :ttl, :metadata,
    :enrichments, :predictions
  )

  build_args = {
    messages:         messages,
    system:           kwargs[:system],
    routing:          routing,
    tools:            kwargs.key?(:tools) ? kwargs[:tools] : nil,
    tool_choice:      kwargs[:tool_choice] || { mode: :auto },
    stream:           kwargs.fetch(:stream, false),
    generation:       kwargs[:generation] || {},
    thinking:         kwargs[:thinking],
    response_format:  kwargs[:response_format] || { type: :text },
    context_strategy: kwargs.fetch(:context_strategy, :auto),
    cache:            kwargs[:cache] || { strategy: :default, cacheable: true },
    fork:             kwargs[:fork],
    tokens:           kwargs[:tokens] || { max: 4096 },
    stop:             kwargs[:stop] || { sequences: [] },
    modality:         kwargs[:modality],
    hooks:            kwargs[:hooks],
    caller:           kwargs[:caller],
    classification:   kwargs[:classification],
    billing:          kwargs[:billing],
    agent:            kwargs[:agent],
    test:             kwargs[:test],
    tracing:          kwargs[:tracing],
    priority:         kwargs.fetch(:priority, :normal),
    conversation_id:  kwargs[:conversation_id],
    idempotency_key:  kwargs[:idempotency_key],
    ttl:              kwargs[:ttl],
    metadata:         kwargs[:metadata] || {},
    enrichments:      kwargs[:enrichments] || {},
    predictions:      kwargs[:predictions] || {},
    extra:            extra
  }
  build_args[:id] = request_id if request_id
  build(**build_args)
end

.normalize_auto_routing(routing, extra) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/legion/llm/inference/request.rb', line 180

def self.normalize_auto_routing(routing, extra)
  normalized_routing = normalize_hash(routing)
  normalized_extra = normalize_hash(extra)
  return [normalized_routing, normalized_extra] unless auto_routing_model?(normalized_routing[:model])

  normalized_routing = normalized_routing.dup
  normalized_routing[:model] = nil
  normalized_extra = normalized_extra.dup
  normalized_extra[:requested_model_alias] = Legion::LLM::Inference::AUTO_ROUTING_MODEL_KEY
  if normalized_routing.values_at(:provider, :instance, :instance_id, :provider_instance).compact.any? ||
     normalized_extra[:tier]
    return [normalized_routing, normalized_extra]
  end

  normalized_extra[:intent] ||= default_auto_routing_intent
  normalized_extra[:auto_route] = true
  [normalized_routing, normalized_extra]
end

.normalize_hash(value) ⇒ Object



199
200
201
202
203
204
205
# File 'lib/legion/llm/inference/request.rb', line 199

def self.normalize_hash(value)
  return {} unless value.is_a?(Hash)

  value.each_with_object({}) do |(key, hash_value), normalized|
    normalized[key.respond_to?(:to_sym) ? key.to_sym : key] = hash_value
  end
end

.trusted_from_routing(routing, settings_snapshot) ⇒ Object

Derive trusted constraints from a legacy routing hash for callers not yet migrated to pass an explicit trusted_constraints value. The routing hash is trusted internal input (not an untrusted client body field).



157
158
159
160
161
162
163
164
# File 'lib/legion/llm/inference/request.rb', line 157

def self.trusted_from_routing(routing, settings_snapshot)
  routing ||= {}
  instance = routing[:instance] || routing[:instance_id] || routing[:provider_instance]
  Legion::LLM::Router::HeaderConstraints.from_internal(
    provider: routing[:provider], instance_id: instance, model: routing[:model],
    tier: routing[:tier], maximum_attempts: nil, settings_snapshot: settings_snapshot
  )
end