Class: Legion::Extensions::Llm::Canonical::Response
- Inherits:
-
Data
- Object
- Data
- Legion::Extensions::Llm::Canonical::Response
- Defined in:
- lib/legion/extensions/llm/canonical/response.rb
Overview
Canonical response shape — the provider-boundary contract. Per R2: does NOT replace Inference::Response (the pipeline envelope). Per Amendment A: immutable Data.define with strict factory. Unknown keys fold into metadata — never silently dropped.
Constant Summary collapse
- STOP_REASONS =
%i[end_turn tool_use max_tokens stop_sequence content_filter error].freeze
- BUILD_SITE =
'Canonical::Response.build'- FROM_HASH_SITE =
'Canonical::Response.from_hash'- NEW_SITE =
'Canonical::Response.new'
Instance Attribute Summary collapse
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#routing ⇒ Object
readonly
Returns the value of attribute routing.
-
#stop_reason ⇒ Object
readonly
Returns the value of attribute stop_reason.
-
#text ⇒ Object
readonly
Returns the value of attribute text.
-
#thinking ⇒ Object
readonly
Returns the value of attribute thinking.
-
#tool_calls ⇒ Object
readonly
Returns the value of attribute tool_calls.
-
#usage ⇒ Object
readonly
Returns the value of attribute usage.
Class Method Summary collapse
-
.build(text: '', thinking: nil, tool_calls: nil, usage: nil, stop_reason: nil, model: nil, routing: nil, metadata: {}) ⇒ Object
Build from keyword args (primary constructor).
-
.from_hash(source) ⇒ Object
Build from a Hash (raw provider response or deserialized wire payload).
-
.normalize_stop_reason!(stop_reason, site) ⇒ Object
L6: stop_reason validated at construction, in both factories.
-
.normalize_thinking!(thinking, site) ⇒ Object
L2: one normalizer per member, shared by build and from_hash.
- .normalize_tool_calls!(tool_calls, site) ⇒ Object
- .normalize_usage!(usage, site) ⇒ Object
Instance Method Summary collapse
-
#as_json ⇒ Object
MultiJson/Oj/::JSON callback — prevents Data.define #inspect leak into JSON.
-
#error? ⇒ Boolean
Whether the response ended due to an error.
-
#to_h ⇒ Object
Serialize to a Hash for AMQP/fleet/wire transport.
- #to_json ⇒ Object
-
#tool_call? ⇒ Boolean
Whether the response includes tool calls.
Instance Attribute Details
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def @metadata end |
#model ⇒ Object (readonly)
Returns the value of attribute model
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def model @model end |
#routing ⇒ Object (readonly)
Returns the value of attribute routing
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def routing @routing end |
#stop_reason ⇒ Object (readonly)
Returns the value of attribute stop_reason
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def stop_reason @stop_reason end |
#text ⇒ Object (readonly)
Returns the value of attribute text
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def text @text end |
#thinking ⇒ Object (readonly)
Returns the value of attribute thinking
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def thinking @thinking end |
#tool_calls ⇒ Object (readonly)
Returns the value of attribute tool_calls
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def tool_calls @tool_calls end |
#usage ⇒ Object (readonly)
Returns the value of attribute usage
13 14 15 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 13 def usage @usage end |
Class Method Details
.build(text: '', thinking: nil, tool_calls: nil, usage: nil, stop_reason: nil, model: nil, routing: nil, metadata: {}) ⇒ Object
Build from keyword args (primary constructor).
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 18 def self.build( text: '', thinking: nil, tool_calls: nil, usage: nil, stop_reason: nil, model: nil, routing: nil, metadata: {} ) new( text: text.to_s, thinking: normalize_thinking!(thinking, self::BUILD_SITE), tool_calls: normalize_tool_calls!(tool_calls, self::BUILD_SITE), usage: normalize_usage!(usage, self::BUILD_SITE), stop_reason: normalize_stop_reason!(stop_reason, self::BUILD_SITE), model: model, routing: routing || {}, metadata: Strict.(, self::BUILD_SITE) ) end |
.from_hash(source) ⇒ Object
Build from a Hash (raw provider response or deserialized wire payload).
Canonical keys only (O03a): edges pass stop_reason, not finish_reason.
36 37 38 39 40 41 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 36 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(**hash, metadata:) end |
.normalize_stop_reason!(stop_reason, site) ⇒ Object
L6: stop_reason validated at construction, in both factories.
44 45 46 47 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 44 def self.normalize_stop_reason!(stop_reason, site) stop_reason_sym = stop_reason&.to_sym Strict.enum!(stop_reason_sym, self::STOP_REASONS, site, :stop_reason) end |
.normalize_thinking!(thinking, site) ⇒ Object
L2: one normalizer per member, shared by build and from_hash.
50 51 52 53 54 55 56 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 50 def self.normalize_thinking!(thinking, site) return nil if thinking.nil? return thinking if thinking.is_a?(Thinking) Strict.expect_type!(thinking, [::Hash], site, :thinking) Thinking.from_hash(thinking) end |
.normalize_tool_calls!(tool_calls, site) ⇒ Object
58 59 60 61 62 63 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 58 def self.normalize_tool_calls!(tool_calls, site) return [] if tool_calls.nil? Strict.expect_type!(tool_calls, [::Array], site, :tool_calls) tool_calls.map { |tc| tc.is_a?(ToolCall) ? tc : ToolCall.from_hash(tc) } end |
.normalize_usage!(usage, site) ⇒ Object
65 66 67 68 69 70 71 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 65 def self.normalize_usage!(usage, site) return nil if usage.nil? return usage if usage.is_a?(Usage) Strict.expect_type!(usage, [::Hash], site, :usage) Usage.from_hash(usage) end |
Instance Method Details
#as_json ⇒ Object
MultiJson/Oj/::JSON callback — prevents Data.define #inspect leak into JSON.
79 80 81 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 79 def as_json(*) to_h end |
#error? ⇒ Boolean
Whether the response ended due to an error.
93 94 95 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 93 def error? stop_reason == :error end |
#to_h ⇒ Object
Serialize to a Hash for AMQP/fleet/wire transport.
74 75 76 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 74 def to_h super.compact end |
#to_json ⇒ Object
83 84 85 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 83 def to_json(*) to_h.to_json(*) end |
#tool_call? ⇒ Boolean
Whether the response includes tool calls.
88 89 90 |
# File 'lib/legion/extensions/llm/canonical/response.rb', line 88 def tool_call? !tool_calls.nil? && !tool_calls.empty? end |