activeagent 0.3.3 → 0.4.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.
@@ -1,14 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_agent/prompt_helper"
4
- require "active_agent/action_prompt/prompt"
5
- require "active_agent/collector"
6
- require "active_support/core_ext/string/inflections"
7
- require "active_support/core_ext/hash/except"
8
- require "active_support/core_ext/module/anonymous"
9
-
10
- # require "active_agent/log_subscriber"
11
- require "active_agent/rescuable"
4
+ require "active_agent/action_prompt/base"
12
5
 
13
6
  # The ActiveAgent module provides a framework for creating agents that can generate content
14
7
  # and handle various actions. The Base class within this module extends AbstractController::Base
@@ -30,446 +23,14 @@ require "active_agent/rescuable"
30
23
  # The class also includes several protected instance variables and defines hooks for loading
31
24
  # additional functionality.
32
25
  module ActiveAgent
33
- class Base < AbstractController::Base
34
- include Callbacks
35
- include GenerationMethods
36
- include GenerationProvider
37
- include QueuedGeneration
38
- include Rescuable
39
- include Parameterized
40
- include Previews
41
- # include FormBuilder
42
-
43
- abstract!
44
-
45
- include AbstractController::Rendering
46
-
47
- include AbstractController::Logger
48
- include AbstractController::Helpers
49
- include AbstractController::Translation
50
- include AbstractController::AssetPaths
51
- include AbstractController::Callbacks
52
- include AbstractController::Caching
53
-
54
- include ActionView::Layouts
55
-
56
- PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [ :@_action_has_layout ]
57
-
58
- helper ActiveAgent::PromptHelper
59
-
60
- class_attribute :options
61
-
62
- class_attribute :default_params, default: {
63
- mime_version: "1.0",
64
- charset: "UTF-8",
65
- content_type: "text/plain",
66
- parts_order: [ "text/plain", "text/enriched", "text/html" ]
67
- }.freeze
68
-
69
- class << self
70
- # Register one or more Observers which will be notified when prompt is generated.
71
- def register_observers(*observers)
72
- observers.flatten.compact.each { |observer| register_observer(observer) }
73
- end
74
-
75
- # Unregister one or more previously registered Observers.
76
- def unregister_observers(*observers)
77
- observers.flatten.compact.each { |observer| unregister_observer(observer) }
78
- end
79
-
80
- # Register one or more Interceptors which will be called before prompt is sent.
81
- def register_interceptors(*interceptors)
82
- interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
83
- end
84
-
85
- # Unregister one or more previously registered Interceptors.
86
- def unregister_interceptors(*interceptors)
87
- interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
88
- end
89
-
90
- # Register an Observer which will be notified when prompt is generated.
91
- # Either a class, string, or symbol can be passed in as the Observer.
92
- # If a string or symbol is passed in it will be camelized and constantized.
93
- def register_observer(observer)
94
- Prompt.register_observer(observer_class_for(observer))
95
- end
96
-
97
- # Unregister a previously registered Observer.
98
- # Either a class, string, or symbol can be passed in as the Observer.
99
- # If a string or symbol is passed in it will be camelized and constantized.
100
- def unregister_observer(observer)
101
- Prompt.unregister_observer(observer_class_for(observer))
102
- end
103
-
104
- # Register an Interceptor which will be called before prompt is sent.
105
- # Either a class, string, or symbol can be passed in as the Interceptor.
106
- # If a string or symbol is passed in it will be camelized and constantized.
107
- def register_interceptor(interceptor)
108
- Prompt.register_interceptor(observer_class_for(interceptor))
109
- end
110
-
111
- # Unregister a previously registered Interceptor.
112
- # Either a class, string, or symbol can be passed in as the Interceptor.
113
- # If a string or symbol is passed in it will be camelized and constantized.
114
- def unregister_interceptor(interceptor)
115
- Prompt.unregister_interceptor(observer_class_for(interceptor))
116
- end
117
-
118
- def observer_class_for(value) # :nodoc:
119
- case value
120
- when String, Symbol
121
- value.to_s.camelize.constantize
122
- else
123
- value
124
- end
125
- end
126
- private :observer_class_for
127
-
128
- # Define how the agent should generate content
129
- def generate_with(provider, **options)
130
- self.generation_provider = provider
131
- self.options = (options || {}).merge(options)
132
- self.options[:stream] = new.agent_stream if self.options[:stream]
133
- generation_provider.config.merge!(self.options)
134
- end
135
-
136
- def stream_with(&stream)
137
- self.options = (options || {}).merge(stream: stream)
138
- end
139
-
140
- # Returns the name of the current agent. This method is also being used as a path for a view lookup.
141
- # If this is an anonymous agent, this method will return +anonymous+ instead.
142
- def agent_name
143
- @agent_name ||= anonymous? ? "anonymous" : name.underscore
144
- end
145
- # Allows to set the name of current agent.
146
- attr_writer :agent_name
147
- alias_method :controller_path, :agent_name
148
-
149
- # Sets the defaults through app configuration:
150
- #
151
- # config.action_agent.default(from: "no-reply@example.org")
152
- #
153
- # Aliased by ::default_options=
154
- def default(value = nil)
155
- self.default_params = default_params.merge(value).freeze if value
156
- default_params
157
- end
158
- # Allows to set defaults through app configuration:
159
- #
160
- # config.action_agent.default_options = { from: "no-reply@example.org" }
161
- alias_method :default_options=, :default
162
-
163
- # Wraps a prompt generation inside of ActiveSupport::Notifications instrumentation.
164
- #
165
- # This method is actually called by the +ActionPrompt::Prompt+ object itself
166
- # through a callback when you call <tt>:generate_prompt</tt> on the +ActionPrompt::Prompt+,
167
- # calling +generate_prompt+ directly and passing an +ActionPrompt::Prompt+ will do
168
- # nothing except tell the logger you generated the prompt.
169
- def generate_prompt(prompt) # :nodoc:
170
- ActiveSupport::Notifications.instrument("deliver.active_agent") do |payload|
171
- set_payload_for_prompt(payload, prompt)
172
- yield # Let Prompt do the generation actions
173
- end
174
- end
175
-
176
- private
177
-
178
- def set_payload_for_prompt(payload, prompt)
179
- payload[:prompt] = prompt.encoded
180
- payload[:agent] = agent_name
181
- payload[:message_id] = prompt.message_id
182
- payload[:date] = prompt.date
183
- payload[:perform_generations] = prompt.perform_generations
184
- end
185
-
186
- def method_missing(method_name, ...)
187
- if action_methods.include?(method_name.name)
188
- Generation.new(self, method_name, ...)
189
- else
190
- super
191
- end
192
- end
193
-
194
- def respond_to_missing?(method, include_all = false)
195
- action_methods.include?(method.name) || super
196
- end
26
+ class Base < ActiveAgent::ActionPrompt::Base
27
+ # This class is the base class for agents in the ActiveAgent framework.
28
+ # It is built on top of ActionPrompt which provides methods for generating content, handling actions, and managing prompts.
29
+ # ActiveAgent::Base is designed to be extended by specific agent implementations.
30
+ # It provides a common set of agent actions for self-contained agents that can determine their own actions using all available actions.
31
+ # Base actions include: text_prompt, continue, reasoning, reiterate, and conclude
32
+ def text_prompt
33
+ prompt(stream: params[:stream], messages: params[:messages], message: params[:message], context_id: params[:context_id])
197
34
  end
198
-
199
- attr_internal :prompt_context
200
-
201
- def agent_stream
202
- proc do |message, delta, stop|
203
- run_stream_callbacks(message, delta, stop) do |message, delta, stop|
204
- yield message, delta, stop if block_given?
205
- end
206
- end
207
- end
208
-
209
- def embed
210
- prompt_context.options.merge(options)
211
- generation_provider.embed(prompt_context) if prompt_context && generation_provider
212
- handle_response(generation_provider.response)
213
- end
214
-
215
- # Add embedding capability to Message class
216
- ActiveAgent::ActionPrompt::Message.class_eval do
217
- def embed
218
- agent_class = ActiveAgent::Base.descendants.first
219
- agent = agent_class.new
220
- agent.prompt_context = ActiveAgent::ActionPrompt::Prompt.new(message: self)
221
- agent.embed
222
- self
223
- end
224
- end
225
-
226
- # Make prompt_context accessible for chaining
227
- # attr_accessor :prompt_context
228
-
229
- def perform_generation
230
- prompt_context.options.merge(options)
231
- generation_provider.generate(prompt_context) if prompt_context && generation_provider
232
- handle_response(generation_provider.response)
233
- end
234
-
235
- def handle_response(response)
236
- return response unless response.message.requested_actions.present?
237
- perform_actions(requested_actions: response.message.requested_actions)
238
- update_prompt_context(response)
239
- end
240
-
241
- def update_prompt_context(response)
242
- prompt_context.message = prompt_context.messages.last
243
- ActiveAgent::GenerationProvider::Response.new(prompt: prompt_context)
244
- end
245
-
246
- def perform_actions(requested_actions:)
247
- requested_actions.each do |action|
248
- perform_action(action)
249
- end
250
- end
251
-
252
- def perform_action(action)
253
- current_context = prompt_context.clone
254
- process(action.name, *action.params)
255
- prompt_context.messages.last.role = :tool
256
- prompt_context.messages.last.action_id = action.id
257
- current_context.messages << prompt_context.messages.last
258
- self.prompt_context = current_context
259
- end
260
-
261
- def initialize
262
- super
263
- @_prompt_was_called = false
264
- @_prompt_context = ActiveAgent::ActionPrompt::Prompt.new(instructions: options[:instructions], options: options)
265
- end
266
-
267
- def process(method_name, *args) # :nodoc:
268
- payload = {
269
- agent: self.class.name,
270
- action: method_name,
271
- args: args
272
- }
273
-
274
- ActiveSupport::Notifications.instrument("process.active_agent", payload) do
275
- super
276
- @_prompt_context = ActiveAgent::ActionPrompt::Prompt.new unless @_prompt_was_called
277
- end
278
- end
279
- ruby2_keywords(:process)
280
-
281
- class NullPrompt # :nodoc:
282
- def message
283
- ""
284
- end
285
-
286
- def header
287
- {}
288
- end
289
-
290
- def respond_to?(string, include_all = false)
291
- true
292
- end
293
-
294
- def method_missing(...)
295
- nil
296
- end
297
- end
298
-
299
- # Returns the name of the agent object.
300
- def agent_name
301
- self.class.agent_name
302
- end
303
-
304
- def headers(args = nil)
305
- if args
306
- @_prompt_context.headers(args)
307
- else
308
- @_prompt_context
309
- end
310
- end
311
-
312
- def prompt_with(*)
313
- prompt_context.update_prompt_context(*)
314
- end
315
-
316
- def prompt(headers = {}, &block)
317
- return prompt_context if @_prompt_was_called && headers.blank? && !block
318
- content_type = headers[:content_type]
319
- headers = apply_defaults(headers)
320
- prompt_context.messages = headers[:messages] || []
321
- prompt_context.context_id = headers[:context_id]
322
-
323
- prompt_context.charset = charset = headers[:charset]
324
-
325
- responses = collect_responses(headers, &block)
326
-
327
- @_prompt_was_called = true
328
-
329
- create_parts_from_responses(prompt_context, responses)
330
-
331
- prompt_context.content_type = set_content_type(prompt_context, content_type, headers[:content_type])
332
- prompt_context.charset = charset
333
- prompt_context.actions = headers[:actions] || action_schemas
334
-
335
- prompt_context
336
- end
337
-
338
- def action_schemas
339
- action_methods.map do |action|
340
- if action != "text_prompt"
341
- JSON.parse render_to_string(locals: { action_name: action }, action: action, formats: :json)
342
- end
343
- end.compact
344
- end
345
-
346
- private
347
-
348
- def set_content_type(m, user_content_type, class_default) # :doc:
349
- if user_content_type.present?
350
- user_content_type
351
- else
352
- prompt_context.content_type || class_default
353
- end
354
- end
355
-
356
- # Translates the +subject+ using \Rails I18n class under <tt>[agent_scope, action_name]</tt> scope.
357
- # If it does not find a translation for the +subject+ under the specified scope it will default to a
358
- # humanized version of the <tt>action_name</tt>.
359
- # If the subject has interpolations, you can pass them through the +interpolations+ parameter.
360
- def default_i18n_subject(interpolations = {}) # :doc:
361
- agent_scope = self.class.agent_name.tr("/", ".")
362
- I18n.t(:subject, **interpolations.merge(scope: [ agent_scope, action_name ], default: action_name.humanize))
363
- end
364
-
365
- def apply_defaults(headers)
366
- default_values = self.class.default.except(*headers.keys).transform_values do |value|
367
- compute_default(value)
368
- end
369
-
370
- headers.reverse_merge(default_values)
371
- end
372
-
373
- def compute_default(value)
374
- return value unless value.is_a?(Proc)
375
-
376
- if value.arity == 1
377
- instance_exec(self, &value)
378
- else
379
- instance_exec(&value)
380
- end
381
- end
382
-
383
- def assign_headers_to_prompt_context(prompt_context, headers)
384
- assignable = headers.except(:parts_order, :content_type, :body, :template_name,
385
- :template_path, :delivery_method, :delivery_method_options)
386
- assignable.each { |k, v| prompt_context[k] = v }
387
- end
388
-
389
- def collect_responses(headers, &)
390
- if block_given?
391
- collect_responses_from_block(headers, &)
392
- elsif headers[:body]
393
- collect_responses_from_text(headers)
394
- else
395
- collect_responses_from_templates(headers)
396
- end
397
- end
398
-
399
- def collect_responses_from_block(headers)
400
- templates_name = headers[:template_name] || action_name
401
- collector = Collector.new(lookup_context) { render(templates_name) }
402
- yield(collector)
403
- collector.responses
404
- end
405
-
406
- def collect_responses_from_text(headers)
407
- [ {
408
- body: headers.delete(:body),
409
- content_type: headers[:content_type] || "text/plain"
410
- } ]
411
- end
412
-
413
- def collect_responses_from_templates(headers)
414
- templates_path = headers[:template_path] || self.class.agent_name
415
- templates_name = headers[:template_name] || action_name
416
-
417
- each_template(Array(templates_path), templates_name).map do |template|
418
- next if template.format == :json
419
-
420
- format = template.format || formats.first
421
- {
422
- body: render(template: template, formats: [ format ]),
423
- content_type: Mime[format].to_s
424
- }
425
- end.compact
426
- end
427
-
428
- def each_template(paths, name, &)
429
- templates = lookup_context.find_all(name, paths)
430
- if templates.empty?
431
- raise ActionView::MissingTemplate.new(paths, name, paths, false, "agent")
432
- else
433
- templates.uniq(&:format).each(&)
434
- end
435
- end
436
-
437
- def create_parts_from_responses(prompt_context, responses)
438
- if responses.size > 1
439
- # prompt_container = ActiveAgent::ActionPrompt::Prompt.new
440
- # prompt_container.content_type = "multipart/alternative"
441
- responses.each { |r| insert_part(prompt_context, r, prompt_context.charset) }
442
- # prompt_context.add_part(prompt_container)
443
- else
444
- responses.each { |r| insert_part(prompt_context, r, prompt_context.charset) }
445
- end
446
- end
447
-
448
- def insert_part(prompt_context, response, charset)
449
- message = ActiveAgent::ActionPrompt::Message.new(
450
- content: response[:body],
451
- content_type: response[:content_type],
452
- charset: charset
453
- )
454
- prompt_context.add_part(message)
455
- end
456
-
457
- # This and #instrument_name is for caching instrument
458
- def instrument_payload(key)
459
- {
460
- agent: agent_name,
461
- key: key
462
- }
463
- end
464
-
465
- def instrument_name
466
- "active_agent"
467
- end
468
-
469
- def _protected_ivars
470
- PROTECTED_IVARS
471
- end
472
-
473
- ActiveSupport.run_load_hooks(:active_agent, self)
474
35
  end
475
36
  end
@@ -6,31 +6,31 @@ module ActiveAgent
6
6
 
7
7
  included do
8
8
  include ActiveSupport::Callbacks
9
- define_callbacks :generate, skip_after_callbacks_if_terminated: true
9
+ define_callbacks :generation, skip_after_callbacks_if_terminated: true
10
10
  define_callbacks :stream, skip_after_callbacks_if_terminated: true
11
11
  end
12
12
 
13
13
  module ClassMethods
14
14
  # Defines a callback that will get called right before the
15
15
  # prompt is sent to the generation provider method.
16
- def before_generate(*filters, &)
17
- set_callback(:generate, :before, *filters, &)
16
+ def before_generation(*filters, &blk)
17
+ set_callback(:generation, :before, *filters, &blk)
18
18
  end
19
19
 
20
20
  # Defines a callback that will get called right after the
21
21
  # prompt's generation method is finished.
22
- def after_generate(*filters, &)
23
- set_callback(:generate, :after, *filters, &)
22
+ def after_generation(*filters, &blk)
23
+ set_callback(:generation, :after, *filters, &blk)
24
24
  end
25
25
 
26
26
  # Defines a callback that will get called around the prompt's generation method.
27
- def around_generate(*filters, &)
28
- set_callback(:generate, :around, *filters, &)
27
+ def around_generation(*filters, &blk)
28
+ set_callback(:generation, :around, *filters, &blk)
29
29
  end
30
30
 
31
31
  # Defines a callback for handling streaming responses during generation
32
- def on_stream(*filters, &)
33
- set_callback(:stream, :before, *filters, &)
32
+ def on_stream(*filters, &blk)
33
+ set_callback(:stream, :before, *filters, &blk)
34
34
  end
35
35
  end
36
36
 
@@ -36,7 +36,7 @@ module ActiveAgent
36
36
 
37
37
  def generate_now!
38
38
  processed_agent.handle_exceptions do
39
- processed_agent.run_callbacks(:generate) do
39
+ processed_agent.run_callbacks(:generation) do
40
40
  processed_agent.perform_generation!
41
41
  end
42
42
  end
@@ -44,7 +44,7 @@ module ActiveAgent
44
44
 
45
45
  def generate_now
46
46
  processed_agent.handle_exceptions do
47
- processed_agent.run_callbacks(:generate) do
47
+ processed_agent.run_callbacks(:generation) do
48
48
  processed_agent.perform_generation
49
49
  end
50
50
  end
@@ -70,7 +70,7 @@ module ActiveAgent
70
70
  "method*, or 3. use a custom Active Job instead of #generate_later."
71
71
  else
72
72
  @agent_class.generation_job.set(options).perform_later(
73
- @agent_class.name, @action.to_s, args: @args
73
+ @agent_class.name, @action.to_s, generation_method.to_s, args: @args
74
74
  )
75
75
  end
76
76
  end
@@ -18,12 +18,14 @@ module ActiveAgent
18
18
 
19
19
  rescue_from StandardError, with: :handle_exception_with_agent_class
20
20
 
21
- def perform(agent_class_name, action_name, args:, params: nil)
22
- agent_class = agent_class_name.constantize
23
- agent = agent_class.new
24
- agent.params = params if params
25
- agent.process(action_name, *args)
26
- agent.perform_generation
21
+ def perform(agent, agent_method, generation_method, args:, kwargs: nil, params: nil)
22
+ agent_class = params ? agent.constantize.with(params) : agent.constantize
23
+ prompt = if kwargs
24
+ agent_class.public_send(agent_method, *args, **kwargs)
25
+ else
26
+ agent_class.public_send(agent_method, *args)
27
+ end
28
+ prompt.send(generation_method)
27
29
  end
28
30
 
29
31
  private
@@ -10,7 +10,12 @@ module ActiveAgent
10
10
  super
11
11
  @api_key = config["api_key"]
12
12
  @model_name = config["model"] || "gpt-4o-mini"
13
- @client = OpenAI::Client.new(access_token: @api_key, log_errors: true)
13
+
14
+ @client = if (@host = config["host"])
15
+ OpenAI::Client.new(uri_base: @host, access_token: @api_key)
16
+ else
17
+ OpenAI::Client.new(access_token: @api_key)
18
+ end
14
19
  end
15
20
 
16
21
  def generate(prompt)
@@ -33,18 +38,20 @@ module ActiveAgent
33
38
 
34
39
  def provider_stream
35
40
  agent_stream = prompt.options[:stream]
41
+
36
42
  message = ActiveAgent::ActionPrompt::Message.new(content: "", role: :assistant)
37
43
 
38
44
  @response = ActiveAgent::GenerationProvider::Response.new(prompt:, message:)
39
45
  proc do |chunk, bytesize|
40
46
  new_content = chunk.dig("choices", 0, "delta", "content")
41
- if new_content && !new_content.blank
47
+ if new_content && !new_content.blank?
48
+ message.generation_id = chunk.dig("id")
42
49
  message.content += new_content
43
50
 
44
51
  agent_stream.call(message, new_content, false) do |message, new_content|
45
52
  yield message, new_content if block_given?
46
53
  end
47
- elsif chunk.dig("choices", 0, "delta", "tool_calls") && !chunk.dig("choices", 0, "delta", "tool_calls").empty?
54
+ elsif chunk.dig("choices", 0, "delta", "tool_calls") && chunk.dig("choices", 0, "delta", "role")
48
55
  message = handle_message(chunk.dig("choices", 0, "delta"))
49
56
  prompt.messages << message
50
57
  @response = ActiveAgent::GenerationProvider::Response.new(prompt:, message:)
@@ -70,13 +77,17 @@ module ActiveAgent
70
77
  provider_message = {
71
78
  role: message.role,
72
79
  tool_call_id: message.action_id.presence,
80
+ name: message.action_name.presence,
81
+ tool_calls: message.raw_actions.present? ? message.raw_actions[:tool_calls] : (message.requested_actions.map { |action| { type: "function", name: action.name, arguments: action.params.to_json } } if message.action_requested),
82
+ generation_id: message.generation_id,
73
83
  content: message.content,
74
84
  type: message.content_type,
75
85
  charset: message.charset
76
86
  }.compact
77
87
 
78
- if message.content_type == "image_url"
79
- provider_message[:image_url] = {url: message.content}
88
+ if message.content_type == "image_url" || message.content[0..4] == "data:"
89
+ provider_message[:type] = "image_url"
90
+ provider_message[:image_url] = { url: message.content }
80
91
  end
81
92
  provider_message
82
93
  end
@@ -84,9 +95,8 @@ module ActiveAgent
84
95
 
85
96
  def chat_response(response)
86
97
  return @response if prompt.options[:stream]
87
-
88
98
  message_json = response.dig("choices", 0, "message")
89
-
99
+ message_json["id"] = response.dig("id") if message_json["id"].blank?
90
100
  message = handle_message(message_json)
91
101
 
92
102
  update_context(prompt: prompt, message: message, response: response)
@@ -96,9 +106,11 @@ module ActiveAgent
96
106
 
97
107
  def handle_message(message_json)
98
108
  ActiveAgent::ActionPrompt::Message.new(
109
+ generation_id: message_json["id"],
99
110
  content: message_json["content"],
100
111
  role: message_json["role"].intern,
101
112
  action_requested: message_json["finish_reason"] == "tool_calls",
113
+ raw_actions: message_json["tool_calls"] || [],
102
114
  requested_actions: handle_actions(message_json["tool_calls"])
103
115
  )
104
116
  end
@@ -108,7 +120,7 @@ module ActiveAgent
108
120
 
109
121
  tool_calls.map do |tool_call|
110
122
  next if tool_call["function"].nil? || tool_call["function"]["name"].blank?
111
- args = tool_call["function"]["arguments"].blank? ? nil : JSON.parse(tool_call["function"]["arguments"], {symbolize_names: true})
123
+ args = tool_call["function"]["arguments"].blank? ? nil : JSON.parse(tool_call["function"]["arguments"], { symbolize_names: true })
112
124
 
113
125
  ActiveAgent::ActionPrompt::Action.new(
114
126
  id: tool_call["id"],
@@ -57,7 +57,7 @@ module ActiveAgent
57
57
  super
58
58
  else
59
59
  @agent_class.generation_job.set(options).perform_later(
60
- @agent_class.name, @action.to_s, params: @params, args: @args
60
+ @agent_class.name, @action.to_s, generation_method.to_s, params: @params, args: @args
61
61
  )
62
62
  end
63
63
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveAgent
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/active_agent.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "yaml"
2
2
  require "abstract_controller"
3
- require "active_agent/action_prompt"
4
3
  require "active_agent/generation_provider"
5
4
  require "active_agent/version"
6
5
  require "active_agent/deprecator"
@@ -49,7 +48,7 @@ module ActiveAgent
49
48
 
50
49
  def load_configuration(file)
51
50
  if File.exist?(file)
52
- config_file = YAML.load(ERB.new(File.read(file)).result)
51
+ config_file = YAML.load(ERB.new(File.read(file)).result, aliases: true)
53
52
  env = ENV["RAILS_ENV"] || ENV["ENV"] || "development"
54
53
  @config = config_file[env] || config_file
55
54
  end
@@ -3,9 +3,5 @@ class ApplicationAgent < ActiveAgent::Base
3
3
  layout 'agent'
4
4
 
5
5
  generate_with :openai, model: "gpt-4o-mini", instructions: "You are a helpful assistant."
6
-
7
- def text_prompt
8
- prompt { |format| format.text { render plain: params[:message] } }
9
- end
10
6
  end
11
7
  <% end %>