Class: RubyPi::Agent::Result

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_pi/agent/result.rb

Overview

Value object returned by Agent::Core#run and Agent::Core#continue. Captures everything about the completed agent interaction in a single, inspectable object.

Examples:

Inspecting an agent result

result = agent.run("Hello")
if result.success?
  puts result.content
  puts "Used #{result.turns} turns"
  result.tool_calls_made.each { |tc| puts "  Called: #{tc[:tool_name]}" }
else
  puts "Error: #{result.error.message}"
end

Checking for truncation (Issue #19)

result = agent.run("Complex task")
if result.truncated?
  puts "Warning: agent hit max iterations — result may be incomplete"
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content: nil, messages: [], tool_calls_made: [], usage: {}, turns: 0, error: nil, stop_reason: :complete) ⇒ Result

Creates a new Result instance.

Parameters:

  • content (String, nil) (defaults to: nil)

    the final assistant text

  • messages (Array<Hash>) (defaults to: [])

    full conversation history

  • tool_calls_made (Array<Hash>) (defaults to: [])

    executed tool call records

  • usage (Hash) (defaults to: {})

    token usage statistics

  • turns (Integer) (defaults to: 0)

    number of completed cycles

  • error (Exception, nil) (defaults to: nil)

    error if the run failed

  • stop_reason (Symbol) (defaults to: :complete)

    why the agent stopped (:complete, :max_iterations, :error)



72
73
74
75
76
77
78
79
80
# File 'lib/ruby_pi/agent/result.rb', line 72

def initialize(content: nil, messages: [], tool_calls_made: [], usage: {}, turns: 0, error: nil, stop_reason: :complete)
  @content = content
  @messages = Array(messages).freeze
  @tool_calls_made = Array(tool_calls_made).freeze
  @usage = usage
  @turns = turns
  @error = error
  @stop_reason = stop_reason
end

Instance Attribute Details

#contentString? (readonly)

Returns the final text content from the assistant.

Returns:

  • (String, nil)

    the final text content from the assistant



34
35
36
# File 'lib/ruby_pi/agent/result.rb', line 34

def content
  @content
end

#errorRubyPi::Error, ... (readonly)

Returns the error if the run failed.

Returns:

  • (RubyPi::Error, StandardError, nil)

    the error if the run failed



51
52
53
# File 'lib/ruby_pi/agent/result.rb', line 51

def error
  @error
end

#messagesArray<Hash> (readonly)

Returns the full conversation history (all messages).

Returns:

  • (Array<Hash>)

    the full conversation history (all messages)



37
38
39
# File 'lib/ruby_pi/agent/result.rb', line 37

def messages
  @messages
end

#stop_reasonSymbol (readonly)

Issue #19: Added stop_reason to distinguish between a natural stop (LLM signaled completion) and hitting the max iteration limit. Previously, max_iterations produced a Result with no error, making success? return true even though the agent was forcibly stopped.

Returns:

  • (Symbol)

    the reason the agent stopped — :complete, :max_iterations, or :error. Allows callers to distinguish between a clean finish and being guillotined by the iteration limit.



61
62
63
# File 'lib/ruby_pi/agent/result.rb', line 61

def stop_reason
  @stop_reason
end

#tool_calls_madeArray<Hash> (readonly)

Returns tool calls that were executed, each with :tool_name, :arguments, and :result keys.

Returns:

  • (Array<Hash>)

    tool calls that were executed, each with :tool_name, :arguments, and :result keys



41
42
43
# File 'lib/ruby_pi/agent/result.rb', line 41

def tool_calls_made
  @tool_calls_made
end

#turnsInteger (readonly)

Returns the number of think-act-observe cycles completed.

Returns:

  • (Integer)

    the number of think-act-observe cycles completed



48
49
50
# File 'lib/ruby_pi/agent/result.rb', line 48

def turns
  @turns
end

#usageHash (readonly)

Returns aggregate token usage with :input_tokens and :output_tokens keys.

Returns:

  • (Hash)

    aggregate token usage with :input_tokens and :output_tokens keys



45
46
47
# File 'lib/ruby_pi/agent/result.rb', line 45

def usage
  @usage
end

Instance Method Details

#success?Boolean

Returns true if the agent run completed without error AND was not truncated by the max iteration limit.

Issue #19: Previously returned true when max_iterations was reached (because error was nil). Now returns false for truncated runs so callers can detect incomplete results.

Returns:

  • (Boolean)

    true only if the run completed naturally without error



90
91
92
# File 'lib/ruby_pi/agent/result.rb', line 90

def success?
  @error.nil? && @stop_reason != :max_iterations
end

#to_hHash

Returns a hash representation of the result for serialization. Includes both the error class name and message for full diagnostic context when an error is present.

Returns:

  • (Hash)


110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ruby_pi/agent/result.rb', line 110

def to_h
  {
    content: @content,
    messages: @messages,
    tool_calls_made: @tool_calls_made,
    usage: @usage,
    turns: @turns,
    error: @error ? { class: @error.class.name, message: @error.message } : nil,
    success: success?,
    stop_reason: @stop_reason,
    truncated: truncated?
  }
end

#to_sString Also known as: inspect

Returns a human-readable string representation of the result.

Returns:

  • (String)


127
128
129
130
131
132
133
134
135
# File 'lib/ruby_pi/agent/result.rb', line 127

def to_s
  status = success? ? "success" : "error"
  parts = ["status=#{status}", "turns=#{@turns}", "stop_reason=#{@stop_reason}"]
  parts << "tools=#{@tool_calls_made.size}" unless @tool_calls_made.empty?
  parts << "content=#{@content&.slice(0, 80).inspect}" if @content
  parts << "error=#{@error.class}: #{@error.message}" if @error
  parts << "truncated=true" if truncated?
  "#<RubyPi::Agent::Result #{parts.join(', ')}>"
end

#truncated?Boolean

Returns true if the agent was stopped by hitting the max iteration limit rather than completing naturally.

Issue #19: Provides a convenient predicate for checking truncation without inspecting stop_reason directly.

Returns:

  • (Boolean)

    true if the run was truncated by max_iterations



101
102
103
# File 'lib/ruby_pi/agent/result.rb', line 101

def truncated?
  @stop_reason == :max_iterations
end