ruby_llm-agents 3.11.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/ruby_llm/agents/agents_controller.rb +74 -0
  3. data/app/controllers/ruby_llm/agents/analytics_controller.rb +304 -0
  4. data/app/controllers/ruby_llm/agents/executions_controller.rb +5 -0
  5. data/app/controllers/ruby_llm/agents/tenants_controller.rb +74 -2
  6. data/app/models/ruby_llm/agents/agent_override.rb +47 -0
  7. data/app/models/ruby_llm/agents/execution/analytics.rb +37 -16
  8. data/app/models/ruby_llm/agents/execution.rb +51 -1
  9. data/app/services/ruby_llm/agents/agent_registry.rb +8 -1
  10. data/app/views/layouts/ruby_llm/agents/application.html.erb +4 -2
  11. data/app/views/ruby_llm/agents/agents/_config_agent.html.erb +93 -4
  12. data/app/views/ruby_llm/agents/agents/show.html.erb +17 -2
  13. data/app/views/ruby_llm/agents/analytics/index.html.erb +398 -0
  14. data/app/views/ruby_llm/agents/executions/_audio_player.html.erb +1 -1
  15. data/app/views/ruby_llm/agents/executions/_filters.html.erb +12 -8
  16. data/app/views/ruby_llm/agents/executions/show.html.erb +26 -12
  17. data/app/views/ruby_llm/agents/shared/_filter_dropdown.html.erb +46 -7
  18. data/app/views/ruby_llm/agents/shared/_tenant_filter.html.erb +2 -2
  19. data/app/views/ruby_llm/agents/system_config/show.html.erb +6 -2
  20. data/app/views/ruby_llm/agents/tenants/index.html.erb +3 -2
  21. data/app/views/ruby_llm/agents/tenants/show.html.erb +225 -0
  22. data/config/routes.rb +12 -4
  23. data/lib/generators/ruby_llm_agents/templates/create_overrides_migration.rb.tt +28 -0
  24. data/lib/generators/ruby_llm_agents/templates/initializer.rb.tt +27 -1
  25. data/lib/generators/ruby_llm_agents/templates/skills/AGENTS.md.tt +1 -1
  26. data/lib/generators/ruby_llm_agents/templates/skills/TOOLS.md.tt +1 -1
  27. data/lib/generators/ruby_llm_agents/upgrade_generator.rb +14 -0
  28. data/lib/ruby_llm/agents/base_agent.rb +90 -133
  29. data/lib/ruby_llm/agents/core/base.rb +9 -0
  30. data/lib/ruby_llm/agents/core/configuration.rb +93 -7
  31. data/lib/ruby_llm/agents/core/version.rb +1 -1
  32. data/lib/ruby_llm/agents/dsl/base.rb +131 -4
  33. data/lib/ruby_llm/agents/dsl/knowledge.rb +157 -0
  34. data/lib/ruby_llm/agents/dsl.rb +1 -1
  35. data/lib/ruby_llm/agents/image/concerns/image_operation_execution.rb +9 -5
  36. data/lib/ruby_llm/agents/infrastructure/retention_job.rb +118 -0
  37. data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +32 -20
  38. data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +22 -1
  39. data/lib/ruby_llm/agents/pipeline/middleware/reliability.rb +1 -1
  40. data/lib/ruby_llm/agents/rails/engine.rb +20 -4
  41. data/lib/ruby_llm/agents/routing.rb +28 -5
  42. data/lib/ruby_llm/agents/stream_event.rb +2 -10
  43. data/lib/ruby_llm/agents/tool.rb +1 -1
  44. data/lib/ruby_llm/agents.rb +1 -3
  45. data/lib/tasks/ruby_llm_agents.rake +7 -0
  46. metadata +9 -5
  47. data/lib/ruby_llm/agents/agent_tool.rb +0 -143
  48. data/lib/ruby_llm/agents/dsl/agents.rb +0 -141
@@ -115,6 +115,15 @@ module RubyLLM
115
115
  @ask_message || options[:message] || super
116
116
  end
117
117
 
118
+ # Override call to capture the caller's stream block so it can be
119
+ # forwarded to the delegated agent. Without this, chunks from the
120
+ # delegated agent are swallowed because build_result has no access
121
+ # to the original block.
122
+ def call(&block)
123
+ @delegation_stream_block = block
124
+ super
125
+ end
126
+
118
127
  # Override process_response to parse the route from LLM output.
119
128
  def process_response(response)
120
129
  raw = response.content.to_s.strip.downcase.gsub(/[^a-z0-9_]/, "")
@@ -131,25 +140,39 @@ module RubyLLM
131
140
  end
132
141
 
133
142
  # Override build_result to return a RoutingResult.
134
- # Auto-delegates to the mapped agent when the route has an `agent:` mapping.
143
+ # Auto-delegates to the mapped agent when the route has an `agent:` mapping,
144
+ # unless the caller opts out with `auto_delegate: false`.
135
145
  def build_result(content, response, context)
136
146
  base = super
137
147
 
138
- # Auto-delegate to the mapped agent
139
148
  agent_class = content[:agent_class]
140
- if agent_class
141
- content[:delegated_result] = agent_class.call(**delegation_params)
149
+ if agent_class && auto_delegate?
150
+ content[:delegated_result] = if @delegation_stream_block
151
+ agent_class.call(**delegation_params, &@delegation_stream_block)
152
+ else
153
+ agent_class.call(**delegation_params)
154
+ end
142
155
  end
143
156
 
144
157
  RoutingResult.new(base_result: base, route_data: content)
145
158
  end
146
159
 
160
+ # Whether auto-delegation to the mapped agent is enabled for this call.
161
+ # Defaults to true. Pass `auto_delegate: false` to receive a
162
+ # classification-only RoutingResult with `delegated? == false` and
163
+ # `agent_class` set so the caller can invoke it manually.
164
+ #
165
+ # @return [Boolean]
166
+ def auto_delegate?
167
+ @options.fetch(:auto_delegate, true)
168
+ end
169
+
147
170
  # Builds params to forward to the delegated agent.
148
171
  # Forwards original message and custom params, excludes routing internals.
149
172
  #
150
173
  # @return [Hash] Params for the delegated agent
151
174
  def delegation_params
152
- forward = @options.except(:dry_run, :skip_cache, :debug, :stream_events)
175
+ forward = @options.except(:dry_run, :skip_cache, :debug, :stream_events, :auto_delegate)
153
176
  forward[:_parent_execution_id] = @parent_execution_id if @parent_execution_id
154
177
  forward[:_root_execution_id] = @root_execution_id if @root_execution_id
155
178
  forward
@@ -7,7 +7,7 @@ module RubyLLM
7
7
  # When `stream_events: true` is passed to an agent call, the stream
8
8
  # block receives StreamEvent objects instead of raw RubyLLM chunks.
9
9
  # This provides visibility into the full execution lifecycle —
10
- # text chunks, tool invocations, agent delegations, and errors.
10
+ # text chunks, tool invocations, and errors.
11
11
  #
12
12
  # @example Basic usage
13
13
  # MyAgent.call(query: "test", stream_events: true) do |event|
@@ -15,15 +15,12 @@ module RubyLLM
15
15
  # when :chunk then print event.data[:content]
16
16
  # when :tool_start then puts "Running #{event.data[:tool_name]}..."
17
17
  # when :tool_end then puts "Done (#{event.data[:duration_ms]}ms)"
18
- # when :agent_start then puts "Delegated to #{event.data[:agent_name]}"
19
- # when :agent_end then puts "Agent done (#{event.data[:duration_ms]}ms)"
20
18
  # when :error then puts "Error: #{event.data[:message]}"
21
19
  # end
22
20
  # end
23
21
  #
24
22
  class StreamEvent
25
- # @return [Symbol] Event type (:chunk, :tool_start, :tool_end,
26
- # :agent_start, :agent_end, :error)
23
+ # @return [Symbol] Event type (:chunk, :tool_start, :tool_end, :error)
27
24
  attr_reader :type
28
25
 
29
26
  # @return [Hash] Event-specific data
@@ -48,11 +45,6 @@ module RubyLLM
48
45
  @type == :tool_start || @type == :tool_end
49
46
  end
50
47
 
51
- # @return [Boolean] Whether this is an agent lifecycle event
52
- def agent_event?
53
- @type == :agent_start || @type == :agent_end
54
- end
55
-
56
48
  # @return [Boolean] Whether this is an error event
57
49
  def error?
58
50
  @type == :error
@@ -31,7 +31,7 @@ module RubyLLM
31
31
  # @example Using with an agent
32
32
  # class CodingAgent < ApplicationAgent
33
33
  # param :container_id, required: true
34
- # tools [BashTool]
34
+ # tools BashTool
35
35
  # end
36
36
  #
37
37
  # CodingAgent.call(query: "list files", container_id: "abc123")
@@ -23,9 +23,6 @@ require_relative "agents/dsl"
23
23
  # BaseAgent - new middleware-based agent architecture
24
24
  require_relative "agents/base_agent"
25
25
 
26
- # Agent-as-Tool adapter
27
- require_relative "agents/agent_tool"
28
-
29
26
  # Streaming events
30
27
  require_relative "agents/stream_event"
31
28
 
@@ -99,6 +96,7 @@ if defined?(Rails)
99
96
  require_relative "agents/core/inflections"
100
97
  require_relative "agents/core/instrumentation"
101
98
  require_relative "agents/infrastructure/execution_logger_job"
99
+ require_relative "agents/infrastructure/retention_job"
102
100
  end
103
101
  require_relative "agents/rails/engine" if defined?(Rails::Engine)
104
102
 
@@ -7,6 +7,13 @@ namespace :ruby_llm_agents do
7
7
  RubyLlmAgents::DoctorGenerator.start([])
8
8
  end
9
9
 
10
+ desc "Run the retention job synchronously (soft + hard purges per configuration)"
11
+ task purge: :environment do
12
+ result = RubyLLM::Agents::RetentionJob.new.perform
13
+ puts "Soft purged: #{result[:soft_purged]} executions (details destroyed)"
14
+ puts "Hard purged: #{result[:hard_purged]} executions (rows destroyed)"
15
+ end
16
+
10
17
  desc "Rename an agent type in execution records. Usage: rake ruby_llm_agents:rename_agent FROM=OldName TO=NewName [DRY_RUN=1]"
11
18
  task rename_agent: :environment do
12
19
  from = ENV["FROM"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm-agents
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - adham90
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.12.0
32
+ version: 1.14.1
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 1.12.0
39
+ version: 1.14.1
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: csv
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -80,12 +80,14 @@ files:
80
80
  - app/controllers/concerns/ruby_llm/agents/paginatable.rb
81
81
  - app/controllers/concerns/ruby_llm/agents/sortable.rb
82
82
  - app/controllers/ruby_llm/agents/agents_controller.rb
83
+ - app/controllers/ruby_llm/agents/analytics_controller.rb
83
84
  - app/controllers/ruby_llm/agents/dashboard_controller.rb
84
85
  - app/controllers/ruby_llm/agents/executions_controller.rb
85
86
  - app/controllers/ruby_llm/agents/requests_controller.rb
86
87
  - app/controllers/ruby_llm/agents/system_config_controller.rb
87
88
  - app/controllers/ruby_llm/agents/tenants_controller.rb
88
89
  - app/helpers/ruby_llm/agents/application_helper.rb
90
+ - app/models/ruby_llm/agents/agent_override.rb
89
91
  - app/models/ruby_llm/agents/execution.rb
90
92
  - app/models/ruby_llm/agents/execution/analytics.rb
91
93
  - app/models/ruby_llm/agents/execution/metrics.rb
@@ -112,6 +114,7 @@ files:
112
114
  - app/views/ruby_llm/agents/agents/_sortable_header.html.erb
113
115
  - app/views/ruby_llm/agents/agents/index.html.erb
114
116
  - app/views/ruby_llm/agents/agents/show.html.erb
117
+ - app/views/ruby_llm/agents/analytics/index.html.erb
115
118
  - app/views/ruby_llm/agents/dashboard/_action_center.html.erb
116
119
  - app/views/ruby_llm/agents/dashboard/_tenant_budget.html.erb
117
120
  - app/views/ruby_llm/agents/dashboard/_top_tenants.html.erb
@@ -185,6 +188,7 @@ files:
185
188
  - lib/generators/ruby_llm_agents/templates/application_transcriber.rb.tt
186
189
  - lib/generators/ruby_llm_agents/templates/background_remover.rb.tt
187
190
  - lib/generators/ruby_llm_agents/templates/create_execution_details_migration.rb.tt
191
+ - lib/generators/ruby_llm_agents/templates/create_overrides_migration.rb.tt
188
192
  - lib/generators/ruby_llm_agents/templates/create_tenant_budgets_migration.rb.tt
189
193
  - lib/generators/ruby_llm_agents/templates/create_tenants_migration.rb.tt
190
194
  - lib/generators/ruby_llm_agents/templates/embedder.rb.tt
@@ -221,7 +225,6 @@ files:
221
225
  - lib/generators/ruby_llm_agents/upgrade_generator.rb
222
226
  - lib/ruby_llm-agents.rb
223
227
  - lib/ruby_llm/agents.rb
224
- - lib/ruby_llm/agents/agent_tool.rb
225
228
  - lib/ruby_llm/agents/audio/elevenlabs/model_registry.rb
226
229
  - lib/ruby_llm/agents/audio/speaker.rb
227
230
  - lib/ruby_llm/agents/audio/speaker/active_storage_support.rb
@@ -240,9 +243,9 @@ files:
240
243
  - lib/ruby_llm/agents/core/llm_tenant.rb
241
244
  - lib/ruby_llm/agents/core/version.rb
242
245
  - lib/ruby_llm/agents/dsl.rb
243
- - lib/ruby_llm/agents/dsl/agents.rb
244
246
  - lib/ruby_llm/agents/dsl/base.rb
245
247
  - lib/ruby_llm/agents/dsl/caching.rb
248
+ - lib/ruby_llm/agents/dsl/knowledge.rb
246
249
  - lib/ruby_llm/agents/dsl/queryable.rb
247
250
  - lib/ruby_llm/agents/dsl/reliability.rb
248
251
  - lib/ruby_llm/agents/eval.rb
@@ -287,6 +290,7 @@ files:
287
290
  - lib/ruby_llm/agents/infrastructure/circuit_breaker.rb
288
291
  - lib/ruby_llm/agents/infrastructure/execution_logger_job.rb
289
292
  - lib/ruby_llm/agents/infrastructure/reliability.rb
293
+ - lib/ruby_llm/agents/infrastructure/retention_job.rb
290
294
  - lib/ruby_llm/agents/pipeline.rb
291
295
  - lib/ruby_llm/agents/pipeline/builder.rb
292
296
  - lib/ruby_llm/agents/pipeline/context.rb
@@ -1,143 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- module Agents
5
- # Wraps an agent class as a RubyLLM::Tool so it can be used
6
- # in another agent's `tools` list. The LLM sees the sub-agent
7
- # as a callable tool and can invoke it with the agent's declared params.
8
- module AgentTool
9
- MAX_AGENT_TOOL_DEPTH = 5
10
-
11
- # Wraps an agent class as a RubyLLM::Tool subclass.
12
- #
13
- # @param agent_class [Class] A BaseAgent subclass
14
- # @param forwarded_params [Array<Symbol>] Params auto-injected from parent (excluded from LLM schema)
15
- # @param description_override [String, nil] Custom description for the tool
16
- # @param delegate [Boolean] Whether this tool represents an agent delegate (from `agents` DSL)
17
- # @return [Class] An anonymous RubyLLM::Tool subclass
18
- def self.for(agent_class, forwarded_params: [], description_override: nil, delegate: false)
19
- tool_name = derive_tool_name(agent_class)
20
- tool_desc = description_override || (agent_class.respond_to?(:description) ? agent_class.description : nil)
21
- agent_params = agent_class.respond_to?(:params) ? agent_class.params : {}
22
- captured_agent_class = agent_class
23
- captured_forwarded = Array(forwarded_params).map(&:to_sym)
24
- is_delegate = delegate
25
-
26
- Class.new(RubyLLM::Tool) do
27
- description tool_desc if tool_desc
28
-
29
- # Map agent params to tool params, excluding forwarded ones
30
- agent_params.each do |name, config|
31
- next if name.to_s.start_with?("_")
32
- next if captured_forwarded.include?(name.to_sym)
33
-
34
- param name,
35
- desc: config[:desc] || "#{name} parameter",
36
- required: config[:required] == true,
37
- type: AgentTool.map_type(config[:type])
38
- end
39
-
40
- # Store references on the class
41
- define_singleton_method(:agent_class) { captured_agent_class }
42
- define_singleton_method(:tool_name) { tool_name }
43
- define_singleton_method(:agent_delegate?) { is_delegate }
44
- define_singleton_method(:forwarded_params) { captured_forwarded }
45
-
46
- # Instance #name returns the derived tool name
47
- define_method(:name) { tool_name }
48
-
49
- define_method(:execute) do |**kwargs|
50
- depth = (Thread.current[:ruby_llm_agents_tool_depth] || 0) + 1
51
- if depth > MAX_AGENT_TOOL_DEPTH
52
- return "Error calling #{captured_agent_class.name}: Agent tool depth exceeded (max #{MAX_AGENT_TOOL_DEPTH})"
53
- end
54
-
55
- Thread.current[:ruby_llm_agents_tool_depth] = depth
56
-
57
- # Inject hierarchy context from thread-local (set by calling agent)
58
- caller_ctx = Thread.current[:ruby_llm_agents_caller_context]
59
-
60
- call_kwargs = kwargs.dup
61
- if caller_ctx
62
- call_kwargs[:_parent_execution_id] = caller_ctx.execution_id
63
- call_kwargs[:_root_execution_id] = caller_ctx.root_execution_id || caller_ctx.execution_id
64
- call_kwargs[:tenant] = caller_ctx.tenant_object if caller_ctx.tenant_id && !call_kwargs.key?(:tenant)
65
-
66
- # Inject forwarded params from the parent agent instance
67
- if captured_forwarded.any? && caller_ctx.agent_instance
68
- captured_forwarded.each do |param_name|
69
- next if call_kwargs.key?(param_name)
70
- if caller_ctx.agent_instance.respond_to?(param_name)
71
- call_kwargs[param_name] = caller_ctx.agent_instance.send(param_name)
72
- end
73
- end
74
- end
75
- end
76
-
77
- result = captured_agent_class.call(**call_kwargs)
78
- content = result.respond_to?(:content) ? result.content : result
79
- case content
80
- when String then content
81
- when Hash then content.to_json
82
- when nil then "(no response)"
83
- else content.to_s
84
- end
85
- rescue => e
86
- "Error calling #{captured_agent_class.name}: #{e.message}"
87
- ensure
88
- Thread.current[:ruby_llm_agents_tool_depth] = depth - 1
89
- end
90
- end
91
- end
92
-
93
- # Converts agent class name to tool name.
94
- #
95
- # @example
96
- # ResearchAgent -> "research"
97
- # CodeReviewAgent -> "code_review"
98
- #
99
- # @param agent_class [Class] The agent class
100
- # @return [String] Snake-cased tool name
101
- def self.derive_tool_name(agent_class)
102
- raw = agent_class.name.to_s.split("::").last
103
- raw.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
104
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
105
- .downcase
106
- .sub(/_agent$/, "")
107
- end
108
-
109
- # Maps Ruby types to JSON Schema types for tool parameters.
110
- #
111
- # @param type [Class, Symbol, nil] Ruby type
112
- # @return [Symbol] JSON Schema type
113
- def self.map_type(type)
114
- case type
115
- when :integer then :integer
116
- when :number, :float then :number
117
- when :boolean then :boolean
118
- when :array then :array
119
- when :object then :object
120
- else
121
- # Handle class objects (Integer, Float, Array, Hash, etc.)
122
- if type.is_a?(Class)
123
- if type <= Integer
124
- :integer
125
- elsif type <= Float
126
- :number
127
- elsif type <= Array
128
- :array
129
- elsif type <= Hash
130
- :object
131
- elsif type == TrueClass || type == FalseClass
132
- :boolean
133
- else
134
- :string
135
- end
136
- else
137
- :string
138
- end
139
- end
140
- end
141
- end
142
- end
143
- end
@@ -1,141 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- module Agents
5
- module DSL
6
- # DSL module for declaring sub-agents on an agent class.
7
- #
8
- # Provides two forms — simple list for common cases, block for
9
- # per-agent configuration:
10
- #
11
- # @example Simple form
12
- # agents [ModelsAgent, ViewsAgent], forward: [:workspace_path]
13
- #
14
- # @example Block form
15
- # agents do
16
- # use ModelsAgent, timeout: 180, description: "Build models"
17
- # use ViewsAgent
18
- # forward :workspace_path, :project_id
19
- # parallel true
20
- # end
21
- #
22
- module Agents
23
- # Declares sub-agents for this agent class.
24
- #
25
- # @param list [Array<Class>, nil] Agent classes (simple form)
26
- # @param options [Hash] Global options (simple form)
27
- # @yield Configuration block (block form)
28
- # @return [Array<Hash>] Agent entries
29
- def agents(list = nil, **options, &block)
30
- if block
31
- config = AgentsConfig.new
32
- config.instance_eval(&block)
33
- @agents_config = config
34
- elsif list
35
- config = AgentsConfig.new
36
- Array(list).each { |a| config.use(a) }
37
- options.each { |k, v| config.send(k, *Array(v)) }
38
- @agents_config = config
39
- end
40
- @agents_config&.agent_entries || []
41
- end
42
-
43
- # Returns the agents configuration object.
44
- #
45
- # @return [AgentsConfig] Configuration (empty if no agents declared)
46
- def agents_config
47
- @agents_config ||
48
- (superclass.respond_to?(:agents_config) ? superclass.agents_config : nil) ||
49
- AgentsConfig.new
50
- end
51
- end
52
- end
53
-
54
- # Configuration object for the `agents` DSL.
55
- #
56
- # Holds the list of agent entries and global options like
57
- # `parallel`, `forward`, `max_depth`, and `instructions`.
58
- #
59
- class AgentsConfig
60
- attr_reader :agent_entries
61
-
62
- def initialize
63
- @agent_entries = []
64
- @options = {
65
- parallel: true,
66
- timeout: nil,
67
- max_depth: 5,
68
- forward: [],
69
- instructions: nil
70
- }
71
- end
72
-
73
- # Registers an agent class with optional per-agent overrides.
74
- #
75
- # @param agent_class [Class] A BaseAgent subclass
76
- # @param timeout [Integer, nil] Per-agent timeout override
77
- # @param description [String, nil] Per-agent description override
78
- def use(agent_class, timeout: nil, description: nil)
79
- @agent_entries << {
80
- agent_class: agent_class,
81
- timeout: timeout,
82
- description: description
83
- }
84
- end
85
-
86
- # @!group Global Options
87
-
88
- def parallel(value = true)
89
- @options[:parallel] = value
90
- end
91
-
92
- def timeout(seconds)
93
- @options[:timeout] = seconds
94
- end
95
-
96
- def max_depth(depth)
97
- @options[:max_depth] = depth
98
- end
99
-
100
- def instructions(text)
101
- @options[:instructions] = text
102
- end
103
-
104
- def forward(*params)
105
- @options[:forward] = params.flatten
106
- end
107
-
108
- # @!endgroup
109
-
110
- # @!group Query Methods
111
-
112
- def parallel?
113
- @options[:parallel]
114
- end
115
-
116
- def timeout_for(agent_class)
117
- entry = @agent_entries.find { |e| e[:agent_class] == agent_class }
118
- entry&.dig(:timeout) || @options[:timeout]
119
- end
120
-
121
- def forwarded_params
122
- @options[:forward]
123
- end
124
-
125
- def max_depth_value
126
- @options[:max_depth]
127
- end
128
-
129
- def instructions_text
130
- @options[:instructions]
131
- end
132
-
133
- def description_for(agent_class)
134
- entry = @agent_entries.find { |e| e[:agent_class] == agent_class }
135
- entry&.dig(:description)
136
- end
137
-
138
- # @!endgroup
139
- end
140
- end
141
- end