Class: Rubino::LLM::AdapterResponse
- Inherits:
-
Object
- Object
- Rubino::LLM::AdapterResponse
- 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
-
#cache_creation_tokens ⇒ Object
readonly
Returns the value of attribute cache_creation_tokens.
-
#cache_read_tokens ⇒ Object
readonly
Returns the value of attribute cache_read_tokens.
-
#content ⇒ Object
readonly
Returns the value of attribute content.
-
#input_tokens ⇒ Object
readonly
Returns the value of attribute input_tokens.
-
#model_id ⇒ Object
readonly
Returns the value of attribute model_id.
-
#output_tokens ⇒ Object
readonly
Returns the value of attribute output_tokens.
-
#raw ⇒ Object
readonly
Returns the value of attribute raw.
-
#stop_reason ⇒ Object
readonly
Returns the value of attribute stop_reason.
-
#thinking ⇒ Object
readonly
Returns the value of attribute thinking.
-
#tool_calls ⇒ Object
readonly
Returns the value of attribute tool_calls.
Instance Method Summary collapse
-
#final_text_block ⇒ Object
The final assistant text block in isolation (see #initialize).
-
#halted? ⇒ Boolean
See #initialize — the streaming tool loop was cut short by the budget.
- #has_tool_calls? ⇒ Boolean
-
#initialize(content:, tool_calls:, input_tokens:, output_tokens:, model_id:, interrupted: false, thinking: nil, stop_reason: nil, raw: nil, cache_read_tokens: 0, cache_creation_tokens: 0, halted: false, final_text_block: nil) ⇒ AdapterResponse
constructor
A new instance of AdapterResponse.
-
#interrupted? ⇒ Boolean
The stream was truncated;
contentis an incomplete partial, not a finished turn. - #text_only? ⇒ Boolean
- #total_tokens ⇒ Object
-
#usage ⇒ Object
Token usage as a nil-safe Hash, the shape the recovery layers read.
Constructor Details
#initialize(content:, tool_calls:, input_tokens:, output_tokens:, model_id:, interrupted: false, thinking: nil, stop_reason: nil, raw: nil, cache_read_tokens: 0, cache_creation_tokens: 0, halted: false, final_text_block: 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# 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, cache_read_tokens: 0, cache_creation_tokens: 0, halted: false, final_text_block: nil) @content = content # The LAST assistant text block of the turn, in isolation — the answer text # the model emitted AFTER its final tool call, with no earlier pre-tool # narration glued on (#core-F1). `content` keeps EVERY text block of the # turn concatenated (needed for the transcript and on-screen render); this # field is what a headless one-shot `result` should surface, so # `OUT=$(rubino prompt …)` returns just the answer and not # "I'll do X now.<answer>". Falls back to `content` when the adapter did not # track block boundaries (non-streaming / Halt / test doubles), where the # response already carries only the final block. @final_text_block = final_text_block @tool_calls = tool_calls || [] @input_tokens = input_tokens || 0 @output_tokens = output_tokens || 0 @model_id = model_id # Prompt-cache usage surfaced by the provider (#311). cache_read_tokens # > 0 means the cached prefix/tool-block was reused on this request; # cache_creation_tokens > 0 means it was (re)written. Default 0 so every # existing caller / provider path that omits them is unaffected. @cache_read_tokens = cache_read_tokens || 0 @cache_creation_tokens = cache_creation_tokens || 0 # 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 # True when the streaming round-trip loop was HALTED mid-flight because # the per-turn iteration/time budget was exhausted (#355a). The Loop reads # this to run its budget-exhausted summary instead of treating the # buffered preamble as the final answer. @halted = halted end |
Instance Attribute Details
#cache_creation_tokens ⇒ Object (readonly)
Returns the value of attribute cache_creation_tokens.
15 16 17 |
# File 'lib/rubino/llm/adapter_response.rb', line 15 def cache_creation_tokens @cache_creation_tokens end |
#cache_read_tokens ⇒ Object (readonly)
Returns the value of attribute cache_read_tokens.
15 16 17 |
# File 'lib/rubino/llm/adapter_response.rb', line 15 def cache_read_tokens @cache_read_tokens end |
#content ⇒ Object (readonly)
Returns the value of attribute content.
15 16 17 |
# File 'lib/rubino/llm/adapter_response.rb', line 15 def content @content end |
#input_tokens ⇒ Object (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_id ⇒ Object (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_tokens ⇒ Object (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 |
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
15 16 17 |
# File 'lib/rubino/llm/adapter_response.rb', line 15 def raw @raw end |
#stop_reason ⇒ Object (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 |
#thinking ⇒ Object (readonly)
Returns the value of attribute thinking.
15 16 17 |
# File 'lib/rubino/llm/adapter_response.rb', line 15 def thinking @thinking end |
#tool_calls ⇒ Object (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
#final_text_block ⇒ Object
The final assistant text block in isolation (see #initialize). Used by the headless one-shot answer path so a turn that ended with a tool call returns only the post-tool answer, not the pre-tool narration concatenated in content. Falls back to content when no per-block boundary was tracked.
99 100 101 |
# File 'lib/rubino/llm/adapter_response.rb', line 99 def final_text_block @final_text_block.nil? ? @content : @final_text_block end |
#halted? ⇒ Boolean
See #initialize — the streaming tool loop was cut short by the budget.
65 66 67 |
# File 'lib/rubino/llm/adapter_response.rb', line 65 def halted? @halted end |
#has_tool_calls? ⇒ Boolean
87 88 89 |
# File 'lib/rubino/llm/adapter_response.rb', line 87 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.
83 84 85 |
# File 'lib/rubino/llm/adapter_response.rb', line 83 def interrupted? @interrupted end |
#text_only? ⇒ Boolean
91 92 93 |
# File 'lib/rubino/llm/adapter_response.rb', line 91 def text_only? !has_tool_calls? && !@content.nil? && !@content.empty? end |
#total_tokens ⇒ Object
103 104 105 |
# File 'lib/rubino/llm/adapter_response.rb', line 103 def total_tokens @input_tokens + @output_tokens end |
#usage ⇒ Object
Token usage as a nil-safe Hash, the shape the recovery layers read. Carries the prompt-cache counters (#311) so a caller can confirm a cache hit (cache_read_input_tokens > 0) without reaching into the raw body.
72 73 74 75 76 77 78 79 |
# File 'lib/rubino/llm/adapter_response.rb', line 72 def usage { input_tokens: @input_tokens, output_tokens: @output_tokens, cache_read_input_tokens: @cache_read_tokens, cache_creation_input_tokens: @cache_creation_tokens } end |