Class: RubyLLM::Agents::Routing::RoutingResult

Inherits:
RubyLLM::Agents::Result show all
Defined in:
lib/ruby_llm/agents/routing/result.rb

Overview

Wraps a standard Result with routing-specific accessors.

When the route has an agent: mapping, the router auto-delegates to that agent. The delegated result is available via delegated_result, and content returns the delegated agent's content.

Examples:

Classification only (no agent mapping)

result = SupportRouter.call(message: "I was charged twice")
result.route        # => :billing
result.delegated?   # => false

Auto-delegation (with agent mapping)

result = SupportRouter.call(message: "I was charged twice")
result.route            # => :billing
result.delegated?       # => true
result.delegated_to     # => BillingAgent
result.content          # => BillingAgent's response content
result.routing_cost     # => cost of classification step
result.total_cost       # => classification + delegation

Instance Attribute Summary collapse

Attributes inherited from RubyLLM::Agents::Result

#agent_class_name, #attempts, #attempts_count, #cache_creation_tokens, #cached_tokens, #cancelled, #chosen_model_id, #completed_at, #content, #duration_ms, #error_class, #error_message, #execution_id, #finish_reason, #input_cost, #input_tokens, #model_id, #output_cost, #output_tokens, #started_at, #streaming, #temperature, #thinking_signature, #thinking_text, #thinking_tokens, #time_to_first_token_ms, #tool_calls, #tool_calls_count, #total_cost, #trace

Instance Method Summary collapse

Methods inherited from RubyLLM::Agents::Result

#[], #cancelled?, #dig, #each, #error?, #execution, #keys, #map, #streaming?, #success?, #thinking?, #to_json, #tool_calls?, #total_tokens, #truncated?, #used_fallback?, #values

Methods included from Trackable

#as_cache_hit, #cached?, included

Constructor Details

#initialize(base_result:, route_data:) ⇒ RoutingResult

Creates a new RoutingResult by wrapping a base Result with route data.

Parameters:

  • base_result (Result)

    The standard Result from BaseAgent execution

  • route_data (Hash)

    Parsed route information

Options Hash (route_data:):

  • :route (Symbol)

    The classified route name

  • :agent_class (Class, nil)

    Mapped agent class

  • :raw_response (String)

    Raw LLM text

  • :delegated_result (Result, nil)

    Result from auto-delegation



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ruby_llm/agents/routing/result.rb', line 47

def initialize(base_result:, route_data:)
  @delegated_result = route_data[:delegated_result]
  @routing_cost = base_result.total_cost
  @routing_tokens = base_result.total_tokens

  # A routed call is two LLM calls: classify, then delegate. Every
  # figure on this result covers BOTH, so they stay consistent with each
  # other — total_cost used to include the delegation while the token
  # counts did not, which made cost-per-token nonsense. Classification
  # alone is still available via #routing_cost / #routing_tokens.
  total = combine(base_result, :total_cost)

  # Use delegated content when available
  effective_content = if @delegated_result
    @delegated_result.respond_to?(:content) ? @delegated_result.content : route_data
  else
    route_data
  end

  super(
    content: effective_content,
    input_tokens: combine(base_result, :input_tokens),
    output_tokens: combine(base_result, :output_tokens),
    input_cost: combine(base_result, :input_cost),
    output_cost: combine(base_result, :output_cost),
    total_cost: total,
    # The wrapped results already registered with the active Tracker;
    # registering this wrapper too reported the combined figures on top
    # of the parts, doubling the cost of every routed call.
    register_with_tracker: false,
    model_id: base_result.model_id,
    chosen_model_id: base_result.chosen_model_id,
    temperature: base_result.temperature,
    started_at: base_result.started_at,
    completed_at: base_result.completed_at,
    duration_ms: base_result.duration_ms,
    finish_reason: base_result.finish_reason,
    streaming: base_result.streaming,
    error_class: base_result.error_class,
    error_message: base_result.error_message,
    attempts_count: base_result.attempts_count
  )

  @route = route_data[:route]
  @agent_class = route_data[:agent_class]
  @raw_response = route_data[:raw_response]
end

Instance Attribute Details

#agent_classClass? (readonly)

Returns The mapped agent class (if defined via agent:).

Returns:

  • (Class, nil)

    The mapped agent class (if defined via agent:)



31
32
33
# File 'lib/ruby_llm/agents/routing/result.rb', line 31

def agent_class
  @agent_class
end

#delegated_resultResult? (readonly)

Returns The result from the delegated agent (if auto-delegated).

Returns:

  • (Result, nil)

    The result from the delegated agent (if auto-delegated)



37
38
39
# File 'lib/ruby_llm/agents/routing/result.rb', line 37

def delegated_result
  @delegated_result
end

#raw_responseString (readonly)

Returns The raw text response from the LLM.

Returns:

  • (String)

    The raw text response from the LLM



34
35
36
# File 'lib/ruby_llm/agents/routing/result.rb', line 34

def raw_response
  @raw_response
end

#routeSymbol (readonly)

Returns The classified route name.

Returns:

  • (Symbol)

    The classified route name



28
29
30
# File 'lib/ruby_llm/agents/routing/result.rb', line 28

def route
  @route
end

Instance Method Details

#delegated?Boolean

Whether the router auto-delegated to a mapped agent

Returns:

  • (Boolean)


98
99
100
# File 'lib/ruby_llm/agents/routing/result.rb', line 98

def delegated?
  !@delegated_result.nil?
end

#delegated_toClass?

The agent class that was auto-invoked (alias for agent_class)

Returns:

  • (Class, nil)


105
106
107
# File 'lib/ruby_llm/agents/routing/result.rb', line 105

def delegated_to
  @agent_class if delegated?
end

#routing_costFloat

Cost of the classification step only (excluding delegation)

Returns:

  • (Float)


112
113
114
# File 'lib/ruby_llm/agents/routing/result.rb', line 112

def routing_cost
  @routing_cost || 0
end

#routing_tokensInteger

Tokens used by the classification step only (excluding delegation)

Returns:

  • (Integer)


119
120
121
# File 'lib/ruby_llm/agents/routing/result.rb', line 119

def routing_tokens
  @routing_tokens || 0
end

#to_hHash

Converts the result to a hash including routing fields.

Returns:

  • (Hash)

    All result data plus route, agent_class, raw_response



126
127
128
129
130
131
132
133
# File 'lib/ruby_llm/agents/routing/result.rb', line 126

def to_h
  super.merge(
    route: route,
    agent_class: agent_class&.name,
    raw_response: raw_response,
    delegated: delegated?
  )
end