Class: Rubino::LLM::AdapterResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/llm/adapter_response.rb

Overview

Structured response returned by all LLM adapters — the normalized shape the conversation loop and its recovery layers read, never ruby_llm internals. This is the Ruby side of the reference normalize_response seam: the loop branches only on content / thinking / tool_calls / stop_reason / interrupted?, never on provider types.

All recovery-layer fields (thinking, stop_reason, usage, raw) default nil-safely so existing callers that construct only the core fields keep working unchanged.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content:, tool_calls:, input_tokens:, output_tokens:, model_id:, interrupted: false, thinking: nil, stop_reason: nil, raw: nil) ⇒ AdapterResponse

Returns a new instance of AdapterResponse.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rubino/llm/adapter_response.rb', line 18

def initialize(content:, tool_calls:, input_tokens:, output_tokens:, model_id:,
               interrupted: false, thinking: nil, stop_reason: nil, raw: nil)
  @content       = content
  @tool_calls    = tool_calls || []
  @input_tokens  = input_tokens || 0
  @output_tokens = output_tokens || 0
  @model_id      = model_id
  # True when this response holds only a buffered partial from a stream that
  # was cut before a clean completion (no finish_reason / [DONE]). The Loop
  # must treat it as a turn failure, never as a final answer.
  @interrupted   = interrupted
  # Reasoning text/summary if the provider surfaced it (think blocks are
  # already split out of +content+). nil when not surfaced on this path.
  @thinking      = thinking
  # Normalized finish reason: :stop | :length | :tool_calls | nil. Drives
  # truncation continuation (later slice). Left nil where unreachable —
  # never fabricated.
  @stop_reason   = stop_reason
  # Escape hatch to the underlying provider response. The loop must NOT
  # branch on it; it exists for diagnostics / later-slice needs only.
  @raw           = raw
end

Instance Attribute Details

#contentObject (readonly)

Returns the value of attribute content.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def content
  @content
end

#input_tokensObject (readonly)

Returns the value of attribute input_tokens.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def input_tokens
  @input_tokens
end

#model_idObject (readonly)

Returns the value of attribute model_id.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def model_id
  @model_id
end

#output_tokensObject (readonly)

Returns the value of attribute output_tokens.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def output_tokens
  @output_tokens
end

#rawObject (readonly)

Returns the value of attribute raw.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def raw
  @raw
end

#stop_reasonObject (readonly)

Returns the value of attribute stop_reason.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def stop_reason
  @stop_reason
end

#thinkingObject (readonly)

Returns the value of attribute thinking.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def thinking
  @thinking
end

#tool_callsObject (readonly)

Returns the value of attribute tool_calls.



15
16
17
# File 'lib/rubino/llm/adapter_response.rb', line 15

def tool_calls
  @tool_calls
end

Instance Method Details

#has_tool_calls?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/rubino/llm/adapter_response.rb', line 52

def has_tool_calls?
  !@tool_calls.empty?
end

#interrupted?Boolean

The stream was truncated; content is an incomplete partial, not a finished turn. See AdapterResponse#initialize and Loop#run.

Returns:

  • (Boolean)


48
49
50
# File 'lib/rubino/llm/adapter_response.rb', line 48

def interrupted?
  @interrupted
end

#text_only?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/rubino/llm/adapter_response.rb', line 56

def text_only?
  !has_tool_calls? && !@content.nil? && !@content.empty?
end

#total_tokensObject



60
61
62
# File 'lib/rubino/llm/adapter_response.rb', line 60

def total_tokens
  @input_tokens + @output_tokens
end

#usageObject

Token usage as a nil-safe Hash, the shape the recovery layers read.



42
43
44
# File 'lib/rubino/llm/adapter_response.rb', line 42

def usage
  { input_tokens: @input_tokens, output_tokens: @output_tokens }
end