ruby_llm-agents 0.3.4 → 0.3.5
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.
- checksums.yaml +4 -4
- data/README.md +132 -1263
- data/app/controllers/concerns/ruby_llm/agents/filterable.rb +5 -1
- data/app/controllers/concerns/ruby_llm/agents/paginatable.rb +2 -1
- data/app/controllers/ruby_llm/agents/agents_controller.rb +21 -2
- data/app/controllers/ruby_llm/agents/dashboard_controller.rb +80 -16
- data/app/controllers/ruby_llm/agents/executions_controller.rb +83 -5
- data/app/models/ruby_llm/agents/execution/analytics.rb +17 -27
- data/app/models/ruby_llm/agents/execution/scopes.rb +25 -0
- data/app/models/ruby_llm/agents/execution/workflow.rb +299 -0
- data/app/models/ruby_llm/agents/execution.rb +9 -1
- data/app/models/ruby_llm/agents/tenant_budget.rb +165 -0
- data/app/services/ruby_llm/agents/agent_registry.rb +118 -7
- data/app/views/layouts/{rubyllm → ruby_llm}/agents/application.html.erb +91 -29
- data/app/views/ruby_llm/agents/agents/_empty_state.html.erb +23 -0
- data/app/views/ruby_llm/agents/agents/_workflow.html.erb +125 -0
- data/app/views/ruby_llm/agents/agents/index.html.erb +93 -0
- data/app/views/{rubyllm → ruby_llm}/agents/agents/show.html.erb +77 -20
- data/app/views/ruby_llm/agents/dashboard/_agent_comparison.html.erb +112 -0
- data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_execution_item.html.erb +7 -4
- data/app/views/ruby_llm/agents/dashboard/_tenant_budget.html.erb +115 -0
- data/app/views/{rubyllm → ruby_llm}/agents/dashboard/index.html.erb +9 -6
- data/app/views/{rubyllm → ruby_llm}/agents/executions/_execution.html.erb +1 -1
- data/app/views/{rubyllm → ruby_llm}/agents/executions/_filters.html.erb +39 -11
- data/app/views/{rubyllm → ruby_llm}/agents/executions/_list.html.erb +19 -9
- data/app/views/ruby_llm/agents/executions/_workflow_summary.html.erb +101 -0
- data/app/views/ruby_llm/agents/executions/index.html.erb +88 -0
- data/app/views/{rubyllm → ruby_llm}/agents/executions/show.html.erb +137 -126
- data/app/views/{rubyllm → ruby_llm}/agents/shared/_breadcrumbs.html.erb +2 -2
- data/app/views/ruby_llm/agents/shared/_executions_table.html.erb +251 -0
- data/app/views/{rubyllm → ruby_llm}/agents/shared/_filter_dropdown.html.erb +1 -1
- data/app/views/{rubyllm → ruby_llm}/agents/shared/_select_dropdown.html.erb +1 -1
- data/app/views/{rubyllm → ruby_llm}/agents/shared/_status_badge.html.erb +1 -1
- data/app/views/{rubyllm → ruby_llm}/agents/shared/_status_dot.html.erb +1 -1
- data/app/views/ruby_llm/agents/shared/_tenant_filter.html.erb +26 -0
- data/app/views/ruby_llm/agents/shared/_workflow_type_badge.html.erb +61 -0
- data/lib/generators/ruby_llm_agents/multi_tenancy_generator.rb +97 -0
- data/lib/generators/ruby_llm_agents/templates/add_attempts_migration.rb.tt +3 -3
- data/lib/generators/ruby_llm_agents/templates/add_tenant_to_executions_migration.rb.tt +23 -0
- data/lib/generators/ruby_llm_agents/templates/add_tool_calls_migration.rb.tt +2 -2
- data/lib/generators/ruby_llm_agents/templates/add_workflow_migration.rb.tt +38 -0
- data/lib/generators/ruby_llm_agents/templates/create_tenant_budgets_migration.rb.tt +45 -0
- data/lib/generators/ruby_llm_agents/templates/migration.rb.tt +17 -5
- data/lib/generators/ruby_llm_agents/upgrade_generator.rb +13 -0
- data/lib/ruby_llm/agents/alert_manager.rb +20 -16
- data/lib/ruby_llm/agents/base/caching.rb +4 -7
- data/lib/ruby_llm/agents/base/cost_calculation.rb +5 -3
- data/lib/ruby_llm/agents/base/execution.rb +61 -9
- data/lib/ruby_llm/agents/base/reliability_execution.rb +14 -9
- data/lib/ruby_llm/agents/base.rb +26 -0
- data/lib/ruby_llm/agents/budget_tracker.rb +250 -139
- data/lib/ruby_llm/agents/cache_helper.rb +98 -0
- data/lib/ruby_llm/agents/circuit_breaker.rb +48 -30
- data/lib/ruby_llm/agents/configuration.rb +40 -1
- data/lib/ruby_llm/agents/engine.rb +65 -1
- data/lib/ruby_llm/agents/inflections.rb +14 -0
- data/lib/ruby_llm/agents/instrumentation.rb +66 -0
- data/lib/ruby_llm/agents/reliability.rb +8 -2
- data/lib/ruby_llm/agents/version.rb +1 -1
- data/lib/ruby_llm/agents/workflow/instrumentation.rb +254 -0
- data/lib/ruby_llm/agents/workflow/parallel.rb +282 -0
- data/lib/ruby_llm/agents/workflow/pipeline.rb +306 -0
- data/lib/ruby_llm/agents/workflow/result.rb +390 -0
- data/lib/ruby_llm/agents/workflow/router.rb +429 -0
- data/lib/ruby_llm/agents/workflow.rb +232 -0
- data/lib/ruby_llm/agents.rb +1 -0
- metadata +50 -60
- data/app/views/rubyllm/agents/agents/index.html.erb +0 -20
- data/app/views/rubyllm/agents/dashboard/_agent_comparison.html.erb +0 -46
- data/app/views/rubyllm/agents/executions/index.html.erb +0 -28
- data/app/views/rubyllm/agents/executions/index.turbo_stream.erb +0 -18
- data/app/views/rubyllm/agents/shared/_executions_table.html.erb +0 -193
- /data/app/views/{rubyllm → ruby_llm}/agents/agents/_agent.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/agents/_version_comparison.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_action_center.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_alerts_feed.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_breaker_strip.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_budgets_bar.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_now_strip.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/dashboard/_top_errors.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/executions/dry_run.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/settings/show.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/shared/_nav_link.html.erb +0 -0
- /data/app/views/{rubyllm → ruby_llm}/agents/shared/_stat_card.html.erb +0 -0
|
@@ -120,6 +120,19 @@ module RubyLlmAgents
|
|
|
120
120
|
)
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
def create_add_workflow_migration
|
|
124
|
+
# Check if columns already exist
|
|
125
|
+
if column_exists?(:ruby_llm_agents_executions, :workflow_id)
|
|
126
|
+
say_status :skip, "workflow_id column already exists", :yellow
|
|
127
|
+
return
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
migration_template(
|
|
131
|
+
"add_workflow_migration.rb.tt",
|
|
132
|
+
File.join(db_migrate_path, "add_workflow_to_ruby_llm_agents_executions.rb")
|
|
133
|
+
)
|
|
134
|
+
end
|
|
135
|
+
|
|
123
136
|
def show_post_upgrade_message
|
|
124
137
|
say ""
|
|
125
138
|
say "RubyLLM::Agents upgrade migration created!", :green
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "faraday"
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
6
|
module RubyLLM
|
|
@@ -177,30 +177,34 @@ module RubyLLM
|
|
|
177
177
|
end
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
-
# Posts JSON to a URL
|
|
180
|
+
# Posts JSON to a URL using Faraday
|
|
181
181
|
#
|
|
182
182
|
# @param url [String] The URL
|
|
183
183
|
# @param payload [Hash] The payload
|
|
184
|
-
# @return [
|
|
184
|
+
# @return [Faraday::Response]
|
|
185
185
|
def post_json(url, payload)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
http.read_timeout = 10
|
|
191
|
-
|
|
192
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
|
193
|
-
request["Content-Type"] = "application/json"
|
|
194
|
-
request.body = payload.to_json
|
|
195
|
-
|
|
196
|
-
response = http.request(request)
|
|
186
|
+
response = http_client.post(url) do |req|
|
|
187
|
+
req.headers["Content-Type"] = "application/json"
|
|
188
|
+
req.body = payload.to_json
|
|
189
|
+
end
|
|
197
190
|
|
|
198
|
-
unless response.
|
|
199
|
-
Rails.logger.warn("[RubyLLM::Agents::AlertManager] Webhook returned #{response.
|
|
191
|
+
unless response.success?
|
|
192
|
+
Rails.logger.warn("[RubyLLM::Agents::AlertManager] Webhook returned #{response.status}: #{response.body}")
|
|
200
193
|
end
|
|
201
194
|
|
|
202
195
|
response
|
|
203
196
|
end
|
|
197
|
+
|
|
198
|
+
# Returns a configured Faraday HTTP client
|
|
199
|
+
#
|
|
200
|
+
# @return [Faraday::Connection]
|
|
201
|
+
def http_client
|
|
202
|
+
@http_client ||= Faraday.new do |conn|
|
|
203
|
+
conn.options.open_timeout = 5
|
|
204
|
+
conn.options.timeout = 10
|
|
205
|
+
conn.adapter Faraday.default_adapter
|
|
206
|
+
end
|
|
207
|
+
end
|
|
204
208
|
end
|
|
205
209
|
end
|
|
206
210
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../cache_helper"
|
|
4
|
+
|
|
3
5
|
module RubyLLM
|
|
4
6
|
module Agents
|
|
5
7
|
class Base
|
|
@@ -8,17 +10,12 @@ module RubyLLM
|
|
|
8
10
|
# Handles cache key generation and store access for
|
|
9
11
|
# caching agent execution results.
|
|
10
12
|
module Caching
|
|
11
|
-
|
|
12
|
-
#
|
|
13
|
-
# @return [ActiveSupport::Cache::Store] The cache store
|
|
14
|
-
def cache_store
|
|
15
|
-
RubyLLM::Agents.configuration.cache_store
|
|
16
|
-
end
|
|
13
|
+
include CacheHelper
|
|
17
14
|
|
|
18
15
|
# Generates the full cache key for this agent invocation
|
|
19
16
|
#
|
|
20
17
|
# @return [String] Cache key in format "ruby_llm_agent/ClassName/version/hash"
|
|
21
|
-
def
|
|
18
|
+
def agent_cache_key
|
|
22
19
|
["ruby_llm_agent", self.class.name, self.class.version, cache_key_hash].join("/")
|
|
23
20
|
end
|
|
24
21
|
|
|
@@ -65,7 +65,8 @@ module RubyLLM
|
|
|
65
65
|
# @param model_id [String] The model identifier
|
|
66
66
|
# @return [Object, nil] Model info or nil
|
|
67
67
|
def resolve_model_info(model_id)
|
|
68
|
-
RubyLLM::Models.resolve(model_id)
|
|
68
|
+
model_obj, _provider = RubyLLM::Models.resolve(model_id)
|
|
69
|
+
model_obj
|
|
69
70
|
rescue StandardError
|
|
70
71
|
nil
|
|
71
72
|
end
|
|
@@ -73,8 +74,9 @@ module RubyLLM
|
|
|
73
74
|
# Records cost from an attempt to the budget tracker
|
|
74
75
|
#
|
|
75
76
|
# @param attempt_tracker [AttemptTracker] The attempt tracker
|
|
77
|
+
# @param tenant_id [String, nil] Optional tenant identifier for multi-tenant tracking
|
|
76
78
|
# @return [void]
|
|
77
|
-
def record_attempt_cost(attempt_tracker)
|
|
79
|
+
def record_attempt_cost(attempt_tracker, tenant_id: nil)
|
|
78
80
|
successful = attempt_tracker.successful_attempt
|
|
79
81
|
return unless successful
|
|
80
82
|
|
|
@@ -93,7 +95,7 @@ module RubyLLM
|
|
|
93
95
|
total_cost = (input_tokens / 1_000_000.0 * input_price) +
|
|
94
96
|
(output_tokens / 1_000_000.0 * output_price)
|
|
95
97
|
|
|
96
|
-
BudgetTracker.record_spend!(self.class.name, total_cost)
|
|
98
|
+
BudgetTracker.record_spend!(self.class.name, total_cost, tenant_id: tenant_id)
|
|
97
99
|
rescue StandardError => e
|
|
98
100
|
Rails.logger.warn("[RubyLLM::Agents] Failed to record budget spend: #{e.message}")
|
|
99
101
|
end
|
|
@@ -20,7 +20,17 @@ module RubyLLM
|
|
|
20
20
|
return dry_run_response if @options[:dry_run]
|
|
21
21
|
return uncached_call(&block) if @options[:skip_cache] || !self.class.cache_enabled?
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
cache_key = agent_cache_key
|
|
24
|
+
|
|
25
|
+
# Check for cache hit BEFORE fetch to record it
|
|
26
|
+
if cache_store.exist?(cache_key)
|
|
27
|
+
started_at = Time.current
|
|
28
|
+
cached_result = cache_store.read(cache_key)
|
|
29
|
+
record_cache_hit_execution(cache_key, cached_result, started_at) if cached_result
|
|
30
|
+
return cached_result
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Cache miss - execute and store
|
|
24
34
|
cache_store.fetch(cache_key, expires_in: self.class.cache_ttl) do
|
|
25
35
|
uncached_call(&block)
|
|
26
36
|
end
|
|
@@ -105,7 +115,7 @@ module RubyLLM
|
|
|
105
115
|
attachments: @options[:with],
|
|
106
116
|
schema: schema&.class&.name,
|
|
107
117
|
streaming: self.class.streaming,
|
|
108
|
-
tools:
|
|
118
|
+
tools: resolved_tools.map { |t| t.respond_to?(:name) ? t.name : t.to_s }
|
|
109
119
|
},
|
|
110
120
|
model_id: model,
|
|
111
121
|
temperature: temperature,
|
|
@@ -113,6 +123,37 @@ module RubyLLM
|
|
|
113
123
|
)
|
|
114
124
|
end
|
|
115
125
|
|
|
126
|
+
# Resolves tools for this execution
|
|
127
|
+
#
|
|
128
|
+
# Checks for instance method override first (for dynamic tools),
|
|
129
|
+
# then falls back to class-level DSL configuration. This allows
|
|
130
|
+
# agents to define tools dynamically based on runtime context.
|
|
131
|
+
#
|
|
132
|
+
# @return [Array<Class>] Tool classes to use
|
|
133
|
+
def resolved_tools
|
|
134
|
+
# Check if instance defines tools method (not inherited from class singleton)
|
|
135
|
+
if self.class.instance_methods(false).include?(:tools)
|
|
136
|
+
tools
|
|
137
|
+
else
|
|
138
|
+
self.class.tools
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Resolves messages for this execution
|
|
143
|
+
#
|
|
144
|
+
# Priority order:
|
|
145
|
+
# 1. @override_messages (set via with_messages)
|
|
146
|
+
# 2. :messages option passed at call time
|
|
147
|
+
# 3. messages template method defined in subclass
|
|
148
|
+
#
|
|
149
|
+
# @return [Array<Hash>] Messages to apply to conversation
|
|
150
|
+
def resolved_messages
|
|
151
|
+
return @override_messages if @override_messages&.any?
|
|
152
|
+
return @options[:messages] if @options[:messages]&.any?
|
|
153
|
+
|
|
154
|
+
messages
|
|
155
|
+
end
|
|
156
|
+
|
|
116
157
|
# Returns the consolidated reliability configuration for this agent instance
|
|
117
158
|
#
|
|
118
159
|
# @return [Hash] Reliability config with :retries, :fallback_models, :total_timeout, :circuit_breaker
|
|
@@ -166,7 +207,8 @@ module RubyLLM
|
|
|
166
207
|
.with_temperature(temperature)
|
|
167
208
|
client = client.with_instructions(system_prompt) if system_prompt
|
|
168
209
|
client = client.with_schema(schema) if schema
|
|
169
|
-
client = client.with_tools(*
|
|
210
|
+
client = client.with_tools(*resolved_tools) if resolved_tools.any?
|
|
211
|
+
client = apply_messages(client, resolved_messages) if resolved_messages.any?
|
|
170
212
|
client
|
|
171
213
|
end
|
|
172
214
|
|
|
@@ -180,14 +222,26 @@ module RubyLLM
|
|
|
180
222
|
.with_temperature(temperature)
|
|
181
223
|
client = client.with_instructions(system_prompt) if system_prompt
|
|
182
224
|
client = client.with_schema(schema) if schema
|
|
183
|
-
client = client.with_tools(*
|
|
225
|
+
client = client.with_tools(*resolved_tools) if resolved_tools.any?
|
|
226
|
+
client = apply_messages(client, resolved_messages) if resolved_messages.any?
|
|
184
227
|
client
|
|
185
228
|
end
|
|
186
229
|
|
|
187
|
-
#
|
|
230
|
+
# Applies conversation history to the client
|
|
188
231
|
#
|
|
189
|
-
#
|
|
232
|
+
# @param client [RubyLLM::Chat] The chat client
|
|
233
|
+
# @param msgs [Array<Hash>] Messages with :role and :content keys
|
|
234
|
+
# @return [RubyLLM::Chat] Client with messages applied
|
|
235
|
+
def apply_messages(client, msgs)
|
|
236
|
+
msgs.reduce(client) do |c, message|
|
|
237
|
+
c.with_message(message[:role].to_s, message[:content])
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Builds a client with pre-populated conversation history
|
|
190
242
|
#
|
|
243
|
+
# @deprecated Use resolved_messages and apply_messages instead.
|
|
244
|
+
# Override the messages template method or pass messages: option to call.
|
|
191
245
|
# @param messages [Array<Hash>] Messages with :role and :content keys
|
|
192
246
|
# @return [RubyLLM::Chat] Client with messages added
|
|
193
247
|
# @example
|
|
@@ -196,9 +250,7 @@ module RubyLLM
|
|
|
196
250
|
# { role: "assistant", content: "Hi there!" }
|
|
197
251
|
# ])
|
|
198
252
|
def build_client_with_messages(messages)
|
|
199
|
-
|
|
200
|
-
client.with_message(message[:role], message[:content])
|
|
201
|
-
end
|
|
253
|
+
apply_messages(build_client, messages)
|
|
202
254
|
end
|
|
203
255
|
end
|
|
204
256
|
end
|
|
@@ -21,15 +21,19 @@ module RubyLLM
|
|
|
21
21
|
total_deadline = config[:total_timeout] ? Time.current + config[:total_timeout] : nil
|
|
22
22
|
started_at = Time.current
|
|
23
23
|
|
|
24
|
-
#
|
|
25
|
-
|
|
24
|
+
# Get current tenant_id for multi-tenancy support
|
|
25
|
+
global_config = RubyLLM::Agents.configuration
|
|
26
|
+
tenant_id = global_config.multi_tenancy_enabled? ? global_config.current_tenant_id : nil
|
|
27
|
+
|
|
28
|
+
# Pre-check budget (tenant_id is resolved automatically if not passed)
|
|
29
|
+
BudgetTracker.check_budget!(self.class.name, tenant_id: tenant_id) if global_config.budgets_enabled?
|
|
26
30
|
|
|
27
31
|
instrument_execution_with_attempts(models_to_try: models_to_try) do |attempt_tracker|
|
|
28
32
|
last_error = nil
|
|
29
33
|
|
|
30
34
|
models_to_try.each do |current_model|
|
|
31
|
-
# Check circuit breaker
|
|
32
|
-
breaker = get_circuit_breaker(current_model)
|
|
35
|
+
# Check circuit breaker (with tenant isolation if enabled)
|
|
36
|
+
breaker = get_circuit_breaker(current_model, tenant_id: tenant_id)
|
|
33
37
|
if breaker&.open?
|
|
34
38
|
attempt_tracker.record_short_circuit(current_model)
|
|
35
39
|
next
|
|
@@ -54,9 +58,9 @@ module RubyLLM
|
|
|
54
58
|
# Record success in circuit breaker
|
|
55
59
|
breaker&.record_success!
|
|
56
60
|
|
|
57
|
-
# Record budget spend
|
|
58
|
-
if @last_response &&
|
|
59
|
-
record_attempt_cost(attempt_tracker)
|
|
61
|
+
# Record budget spend (with tenant isolation if enabled)
|
|
62
|
+
if @last_response && global_config.budgets_enabled?
|
|
63
|
+
record_attempt_cost(attempt_tracker, tenant_id: tenant_id)
|
|
60
64
|
end
|
|
61
65
|
|
|
62
66
|
# Use throw instead of return to allow instrument_execution_with_attempts
|
|
@@ -118,12 +122,13 @@ module RubyLLM
|
|
|
118
122
|
# Gets or creates a circuit breaker for a model
|
|
119
123
|
#
|
|
120
124
|
# @param model_id [String] The model identifier
|
|
125
|
+
# @param tenant_id [String, nil] Optional tenant identifier for multi-tenant isolation
|
|
121
126
|
# @return [CircuitBreaker, nil] The circuit breaker or nil if not configured
|
|
122
|
-
def get_circuit_breaker(model_id)
|
|
127
|
+
def get_circuit_breaker(model_id, tenant_id: nil)
|
|
123
128
|
config = reliability_config[:circuit_breaker]
|
|
124
129
|
return nil unless config
|
|
125
130
|
|
|
126
|
-
CircuitBreaker.from_config(self.class.name, model_id, config)
|
|
131
|
+
CircuitBreaker.from_config(self.class.name, model_id, config, tenant_id: tenant_id)
|
|
127
132
|
end
|
|
128
133
|
end
|
|
129
134
|
end
|
data/lib/ruby_llm/agents/base.rb
CHANGED
|
@@ -137,6 +137,20 @@ module RubyLLM
|
|
|
137
137
|
nil
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
+
# Conversation history for multi-turn conversations
|
|
141
|
+
#
|
|
142
|
+
# Override in subclass to provide conversation history.
|
|
143
|
+
# Messages will be added to the chat before the user_prompt.
|
|
144
|
+
#
|
|
145
|
+
# @return [Array<Hash>] Array of messages with :role and :content keys
|
|
146
|
+
# @example
|
|
147
|
+
# def messages
|
|
148
|
+
# [{ role: :user, content: "Hello" }, { role: :assistant, content: "Hi!" }]
|
|
149
|
+
# end
|
|
150
|
+
def messages
|
|
151
|
+
[]
|
|
152
|
+
end
|
|
153
|
+
|
|
140
154
|
# Post-processes the LLM response
|
|
141
155
|
#
|
|
142
156
|
# Override to transform the response before returning to the caller.
|
|
@@ -151,6 +165,18 @@ module RubyLLM
|
|
|
151
165
|
end
|
|
152
166
|
|
|
153
167
|
# @!endgroup
|
|
168
|
+
|
|
169
|
+
# Sets conversation history and rebuilds the client
|
|
170
|
+
#
|
|
171
|
+
# @param msgs [Array<Hash>] Messages with :role and :content keys
|
|
172
|
+
# @return [self] Returns self for chaining
|
|
173
|
+
# @example
|
|
174
|
+
# agent.with_messages([{ role: :user, content: "Hi" }]).call
|
|
175
|
+
def with_messages(msgs)
|
|
176
|
+
@override_messages = msgs
|
|
177
|
+
@client = build_client
|
|
178
|
+
self
|
|
179
|
+
end
|
|
154
180
|
end
|
|
155
181
|
end
|
|
156
182
|
end
|