Class: RubyLLM::Agents::Result

Inherits:
Object
  • Object
show all
Extended by:
ActiveSupport::Delegation
Includes:
Trackable
Defined in:
lib/ruby_llm/agents/results/base.rb

Overview

Wrapper for agent execution results with full metadata

Provides access to the response content along with execution details like token usage, cost, timing, and model information.

Examples:

Basic usage

result = MyAgent.call(query: "test")
result.content        # => processed response
result.input_tokens   # => 150
result.total_cost     # => 0.00025

Backward compatible hash access

result[:key]          # delegates to result.content[:key]
result.dig(:nested, :key)

Direct Known Subclasses

RubyLLM::Agents::Routing::RoutingResult

Token Usage collapse

Cost collapse

Model Info collapse

Timing collapse

Status collapse

Error Info collapse

Reliability collapse

Tool Calls collapse

Thinking collapse

Execution Record collapse

Tracking collapse

Cancellation collapse

Debug collapse

Instance Attribute Summary collapse

Debug collapse

Deprecated Hash Delegation collapse

Instance Method Summary collapse

Methods included from Trackable

#as_cache_hit, #cached?, included

Constructor Details

#initialize(content:, **options) ⇒ Result

Creates a new Result instance

Parameters:

  • content (Hash, String)

    The processed response content

  • options (Hash)

    Execution metadata



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/ruby_llm/agents/results/base.rb', line 130

def initialize(content:, **options)
  @content = content

  # Token usage
  @input_tokens = options[:input_tokens]
  @output_tokens = options[:output_tokens]
  @cached_tokens = options[:cached_tokens] || 0
  @cache_creation_tokens = options[:cache_creation_tokens] || 0

  # Cost
  @input_cost = options[:input_cost]
  @output_cost = options[:output_cost]
  @total_cost = options[:total_cost]

  # Model info
  @model_id = options[:model_id]
  @chosen_model_id = options[:chosen_model_id] || options[:model_id]
  @temperature = options[:temperature]

  # Timing
  @started_at = options[:started_at]
  @completed_at = options[:completed_at]
  @duration_ms = options[:duration_ms]
  @time_to_first_token_ms = options[:time_to_first_token_ms]

  # Status
  @finish_reason = options[:finish_reason]
  @streaming = options[:streaming] || false

  # Error
  @error_class = options[:error_class]
  @error_message = options[:error_message]

  # Reliability
  @attempts = options[:attempts] || []
  @attempts_count = options[:attempts_count] || 1

  # Tool calls
  @tool_calls = options[:tool_calls] || []
  @tool_calls_count = options[:tool_calls_count] || 0

  # Thinking
  @thinking_text = options[:thinking_text]
  @thinking_signature = options[:thinking_signature]
  @thinking_tokens = options[:thinking_tokens]

  # Execution record
  @execution_id = options[:execution_id]

  # Caching
  @cached_at = options[:cached_at]

  # Tracking
  @agent_class_name = options[:agent_class_name]

  # Cancellation
  @cancelled = options[:cancelled] || false

  # Debug trace
  @trace = options[:trace]

  # Wrapper results (RoutingResult) opt out: the results they wrap have
  # already registered, and registering the wrapper too would report its
  # combined cost on top of its own parts.
  register_with_tracker unless options[:register_with_tracker] == false
end

Instance Attribute Details

#agent_class_nameObject (readonly)



114
115
116
# File 'lib/ruby_llm/agents/results/base.rb', line 114

def agent_class_name
  @agent_class_name
end

#attemptsArray<Hash> (readonly)

Returns Details of each attempt (for retries/fallbacks).

Returns:

  • (Array<Hash>)

    Details of each attempt (for retries/fallbacks)



88
89
90
# File 'lib/ruby_llm/agents/results/base.rb', line 88

def attempts
  @attempts
end

#attempts_countObject (readonly)



88
# File 'lib/ruby_llm/agents/results/base.rb', line 88

attr_reader :attempts, :attempts_count

#cache_creation_tokensObject (readonly)



38
# File 'lib/ruby_llm/agents/results/base.rb', line 38

attr_reader :input_tokens, :output_tokens, :cached_tokens, :cache_creation_tokens

#cached_tokensInteger (readonly)

Returns Number of tokens served from cache.

Returns:

  • (Integer)

    Number of tokens served from cache



38
# File 'lib/ruby_llm/agents/results/base.rb', line 38

attr_reader :input_tokens, :output_tokens, :cached_tokens, :cache_creation_tokens

#cancelledObject (readonly)



119
120
121
# File 'lib/ruby_llm/agents/results/base.rb', line 119

def cancelled
  @cancelled
end

#chosen_model_idString? (readonly)

Returns The model that actually responded (may differ if fallback used).

Returns:

  • (String, nil)

    The model that actually responded (may differ if fallback used)



56
# File 'lib/ruby_llm/agents/results/base.rb', line 56

attr_reader :model_id, :chosen_model_id, :temperature

#completed_atTime? (readonly)

Returns When execution completed.

Returns:

  • (Time, nil)

    When execution completed



67
# File 'lib/ruby_llm/agents/results/base.rb', line 67

attr_reader :started_at, :completed_at, :duration_ms, :time_to_first_token_ms

#contentObject (readonly)



27
28
29
# File 'lib/ruby_llm/agents/results/base.rb', line 27

def content
  @content
end

#duration_msInteger? (readonly)

Returns Execution duration in milliseconds.

Returns:

  • (Integer, nil)

    Execution duration in milliseconds



67
# File 'lib/ruby_llm/agents/results/base.rb', line 67

attr_reader :started_at, :completed_at, :duration_ms, :time_to_first_token_ms

#error_classString? (readonly)

Returns Exception class name if failed.

Returns:

  • (String, nil)

    Exception class name if failed



81
82
83
# File 'lib/ruby_llm/agents/results/base.rb', line 81

def error_class
  @error_class
end

#error_messageObject (readonly)



81
# File 'lib/ruby_llm/agents/results/base.rb', line 81

attr_reader :error_class, :error_message

#execution_idObject (readonly)



109
110
111
# File 'lib/ruby_llm/agents/results/base.rb', line 109

def execution_id
  @execution_id
end

#finish_reasonString? (readonly)

Returns Why generation stopped (stop, length, tool_calls, etc.).

Returns:

  • (String, nil)

    Why generation stopped (stop, length, tool_calls, etc.)



74
75
76
# File 'lib/ruby_llm/agents/results/base.rb', line 74

def finish_reason
  @finish_reason
end

#input_costFloat? (readonly)

Returns Cost of input tokens in USD.

Returns:

  • (Float, nil)

    Cost of input tokens in USD



47
48
49
# File 'lib/ruby_llm/agents/results/base.rb', line 47

def input_cost
  @input_cost
end

#input_tokensInteger? (readonly)

Returns Number of input tokens consumed.

Returns:

  • (Integer, nil)

    Number of input tokens consumed



38
39
40
# File 'lib/ruby_llm/agents/results/base.rb', line 38

def input_tokens
  @input_tokens
end

#model_idString? (readonly)

Returns The model that was requested.

Returns:

  • (String, nil)

    The model that was requested



56
57
58
# File 'lib/ruby_llm/agents/results/base.rb', line 56

def model_id
  @model_id
end

#output_costFloat? (readonly)

Returns Cost of output tokens in USD.

Returns:

  • (Float, nil)

    Cost of output tokens in USD



47
# File 'lib/ruby_llm/agents/results/base.rb', line 47

attr_reader :input_cost, :output_cost, :total_cost

#output_tokensInteger? (readonly)

Returns Number of output tokens generated.

Returns:

  • (Integer, nil)

    Number of output tokens generated



38
# File 'lib/ruby_llm/agents/results/base.rb', line 38

attr_reader :input_tokens, :output_tokens, :cached_tokens, :cache_creation_tokens

#started_atTime? (readonly)

Returns When execution started.

Returns:

  • (Time, nil)

    When execution started



67
68
69
# File 'lib/ruby_llm/agents/results/base.rb', line 67

def started_at
  @started_at
end

#streamingObject (readonly)



74
# File 'lib/ruby_llm/agents/results/base.rb', line 74

attr_reader :finish_reason, :streaming

#temperatureObject (readonly)



56
# File 'lib/ruby_llm/agents/results/base.rb', line 56

attr_reader :model_id, :chosen_model_id, :temperature

#thinking_signatureString? (readonly)

Returns Signature for multi-turn thinking continuity (Claude).

Returns:

  • (String, nil)

    Signature for multi-turn thinking continuity (Claude)



104
# File 'lib/ruby_llm/agents/results/base.rb', line 104

attr_reader :thinking_text, :thinking_signature, :thinking_tokens

#thinking_textString? (readonly)

Returns The reasoning/thinking content from the model.

Returns:

  • (String, nil)

    The reasoning/thinking content from the model



104
105
106
# File 'lib/ruby_llm/agents/results/base.rb', line 104

def thinking_text
  @thinking_text
end

#thinking_tokensObject (readonly)



104
# File 'lib/ruby_llm/agents/results/base.rb', line 104

attr_reader :thinking_text, :thinking_signature, :thinking_tokens

#time_to_first_token_msObject (readonly)



67
# File 'lib/ruby_llm/agents/results/base.rb', line 67

attr_reader :started_at, :completed_at, :duration_ms, :time_to_first_token_ms

#tool_callsArray<Hash> (readonly)

Returns Tool calls made during execution.

Returns:

  • (Array<Hash>)

    Tool calls made during execution



95
96
97
# File 'lib/ruby_llm/agents/results/base.rb', line 95

def tool_calls
  @tool_calls
end

#tool_calls_countObject (readonly)



95
# File 'lib/ruby_llm/agents/results/base.rb', line 95

attr_reader :tool_calls, :tool_calls_count

#total_costObject (readonly)



47
# File 'lib/ruby_llm/agents/results/base.rb', line 47

attr_reader :input_cost, :output_cost, :total_cost

#traceObject (readonly)



124
125
126
# File 'lib/ruby_llm/agents/results/base.rb', line 124

def trace
  @trace
end

Instance Method Details

#[](key) ⇒ Object

Deprecated.

Use result.content instead



332
333
334
335
336
337
338
# File 'lib/ruby_llm/agents/results/base.rb', line 332

def [](key)
  RubyLLM::Agents::Deprecations.warn(
    "Result#[] is deprecated. Use result.content[:key] instead.",
    caller
  )
  content&.[](key)
end

#cancelled?Boolean

Returns whether the execution was cancelled

Returns:

  • (Boolean)

    true if cancelled



241
242
243
# File 'lib/ruby_llm/agents/results/base.rb', line 241

def cancelled?
  cancelled == true
end

#dig(*keys) ⇒ Object

Deprecated.

Use result.content.dig(...) instead



341
342
343
344
345
346
347
# File 'lib/ruby_llm/agents/results/base.rb', line 341

def dig(*keys)
  RubyLLM::Agents::Deprecations.warn(
    "Result#dig is deprecated. Use result.content.dig(...) instead.",
    caller
  )
  content&.dig(*keys)
end

#each(&block) ⇒ Object

Deprecated.

Use result.content.each instead



368
369
370
371
372
373
374
# File 'lib/ruby_llm/agents/results/base.rb', line 368

def each(&block)
  RubyLLM::Agents::Deprecations.warn(
    "Result#each is deprecated. Use result.content.each instead.",
    caller
  )
  content&.each(&block)
end

#error?Boolean

Returns whether the execution failed

Returns:

  • (Boolean)

    true if an error occurred



234
235
236
# File 'lib/ruby_llm/agents/results/base.rb', line 234

def error?
  !success?
end

#executionRubyLLM::Agents::Execution?

Loads the associated Execution record from the database

Useful for debugging in the Rails console to inspect the full execution record after an agent call.

Examples:

result = MyAgent.call(query: "test")
result.execution  # => #<RubyLLM::Agents::Execution id: 42, ...>

Returns:



206
207
208
# File 'lib/ruby_llm/agents/results/base.rb', line 206

def execution
  @execution ||= Execution.find_by(id: execution_id) if execution_id
end

#keysObject

Deprecated.

Use result.content.keys instead



350
351
352
353
354
355
356
# File 'lib/ruby_llm/agents/results/base.rb', line 350

def keys
  RubyLLM::Agents::Deprecations.warn(
    "Result#keys is deprecated. Use result.content.keys instead.",
    caller
  )
  content&.keys
end

#map(&block) ⇒ Object

Deprecated.

Use result.content.map instead



377
378
379
380
381
382
383
# File 'lib/ruby_llm/agents/results/base.rb', line 377

def map(&block)
  RubyLLM::Agents::Deprecations.warn(
    "Result#map is deprecated. Use result.content.map instead.",
    caller
  )
  content&.map(&block)
end

#streaming?Boolean

Returns whether streaming was enabled

Returns:

  • (Boolean)

    true if streaming was used



220
221
222
# File 'lib/ruby_llm/agents/results/base.rb', line 220

def streaming?
  streaming == true
end

#success?Boolean

Returns whether the execution succeeded

Returns:

  • (Boolean)

    true if no error occurred



227
228
229
# File 'lib/ruby_llm/agents/results/base.rb', line 227

def success?
  error_class.nil?
end

#thinking?Boolean Also known as: has_thinking?

Returns whether thinking data is present in the result

Returns:

  • (Boolean)

    true if thinking_text is present



270
271
272
# File 'lib/ruby_llm/agents/results/base.rb', line 270

def thinking?
  thinking_text.present?
end

#to_hHash

Converts the result to a hash

Returns:

  • (Hash)

    All result data as a hash



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/ruby_llm/agents/results/base.rb', line 278

def to_h
  {
    cached_at: cached_at,
    content: content,
    input_tokens: input_tokens,
    output_tokens: output_tokens,
    total_tokens: total_tokens,
    cached_tokens: cached_tokens,
    cache_creation_tokens: cache_creation_tokens,
    input_cost: input_cost,
    output_cost: output_cost,
    total_cost: total_cost,
    model_id: model_id,
    chosen_model_id: chosen_model_id,
    temperature: temperature,
    started_at: started_at,
    completed_at: completed_at,
    duration_ms: duration_ms,
    time_to_first_token_ms: time_to_first_token_ms,
    finish_reason: finish_reason,
    streaming: streaming,
    error_class: error_class,
    error_message: error_message,
    attempts_count: attempts_count,
    attempts: attempts,
    tool_calls: tool_calls,
    tool_calls_count: tool_calls_count,
    thinking_text: thinking_text,
    thinking_signature: thinking_signature,
    thinking_tokens: thinking_tokens,
    execution_id: execution_id,
    agent_class_name: agent_class_name,
    trace: trace
  }.compact
end

#to_json(*args) ⇒ String

Custom to_json that returns content as JSON for backward compatibility

Parameters:

  • args (Array)

    Arguments passed to to_json

Returns:

  • (String)

    JSON representation



391
392
393
# File 'lib/ruby_llm/agents/results/base.rb', line 391

def to_json(*args)
  content.to_json(*args)
end

#tool_calls?Boolean Also known as: has_tool_calls?

Returns whether tool calls were made during execution

Returns:

  • (Boolean)

    true if tool_calls_count > 0



262
263
264
# File 'lib/ruby_llm/agents/results/base.rb', line 262

def tool_calls?
  tool_calls_count.to_i > 0
end

#total_tokensInteger

Returns total tokens (input + output)

Returns:

  • (Integer)

    Total token count



213
214
215
# File 'lib/ruby_llm/agents/results/base.rb', line 213

def total_tokens
  (input_tokens || 0) + (output_tokens || 0)
end

#truncated?Boolean

Returns whether the response was truncated due to max tokens

Returns:

  • (Boolean)

    true if finish_reason is "length"



255
256
257
# File 'lib/ruby_llm/agents/results/base.rb', line 255

def truncated?
  finish_reason == "length"
end

#used_fallback?Boolean

Returns whether a fallback model was used

Returns:

  • (Boolean)

    true if chosen_model_id differs from model_id



248
249
250
# File 'lib/ruby_llm/agents/results/base.rb', line 248

def used_fallback?
  chosen_model_id.present? && chosen_model_id != model_id
end

#valuesObject

Deprecated.

Use result.content.values instead



359
360
361
362
363
364
365
# File 'lib/ruby_llm/agents/results/base.rb', line 359

def values
  RubyLLM::Agents::Deprecations.warn(
    "Result#values is deprecated. Use result.content.values instead.",
    caller
  )
  content&.values
end