activeagent 0.4.0 → 0.4.2.rc1

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_agent/action_prompt/base.rb +78 -50
  3. data/lib/active_agent/action_prompt/prompt.rb +23 -8
  4. data/lib/active_agent/base.rb +2 -2
  5. data/lib/active_agent/generation.rb +6 -6
  6. data/lib/active_agent/version.rb +1 -1
  7. data/lib/generators/active_agent/USAGE +3 -3
  8. data/lib/generators/active_agent/agent_generator.rb +5 -3
  9. data/lib/generators/active_agent/install_generator.rb +2 -9
  10. data/lib/generators/active_agent/templates/agent.rb.tt +1 -1
  11. data/lib/generators/erb/agent_generator.rb +43 -0
  12. data/lib/generators/erb/install_generator.rb +17 -0
  13. data/lib/generators/erb/templates/application_agent.rb.tt +7 -0
  14. data/lib/generators/erb/templates/layout.html.erb.tt +1 -0
  15. data/lib/generators/erb/templates/layout.json.erb.tt +1 -0
  16. data/lib/generators/erb/templates/layout.text.erb.tt +1 -0
  17. data/lib/generators/erb/templates/view.html.erb.tt +5 -0
  18. data/lib/generators/erb/templates/view.json.erb.tt +16 -0
  19. data/lib/generators/erb/templates/view.text.erb.tt +3 -0
  20. data/lib/generators/test_unit/agent_generator.rb +30 -0
  21. data/lib/generators/test_unit/install_generator.rb +13 -0
  22. data/lib/generators/test_unit/templates/functional_test.rb.tt +20 -0
  23. data/lib/generators/test_unit/templates/preview.rb.tt +14 -0
  24. metadata +14 -7
  25. data/lib/generators/active_agent/templates/action.html.erb.tt +0 -0
  26. data/lib/generators/active_agent/templates/action.json.jbuilder.tt +0 -14
  27. data/lib/generators/active_agent/templates/agent.html.erb +0 -1
  28. data/lib/generators/active_agent/templates/agent.text.erb +0 -1
  29. data/lib/generators/active_agent/templates/agent_spec.rb.tt +0 -0
  30. data/lib/generators/active_agent/templates/agent_test.rb.tt +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8567895dba91f6a677d35693b104e3a85f138cfcba9d6e5a2e0b50d536d435c9
4
- data.tar.gz: 5debb8cd50b84a5d4859df01fefcd4b9161c30aae75a0dd1a53e08054331b554
3
+ metadata.gz: 9502dc9a10e641ee19eda0abaaab702610935eabde01ea947fc661a8d88af2e1
4
+ data.tar.gz: 3828eb1a71d0de917c5140f67b065e7e5b4c076de1572e58d658590d5da964d7
5
5
  SHA512:
6
- metadata.gz: d1aabd80bf2ee0e66141de25f799beb042aa662006a8c2bc96d083f86dfd02fd3518732da58dedc8ad09347ee7262c16c1b0244b433bbbe556d980e8ed6027d6
7
- data.tar.gz: ab612e4af865564a94fed7cb8bf0626e696a5a54b3302b14505f36f58a4d55e3716340175b815a020430f903e2e8fe8f61f2d50ef4ca6ac4d027780952964cd0
6
+ metadata.gz: 5dba06808ee99e8f986a9f255a6ab9e112e83b7d512b592126da6ff5d8f9ff2568664abf0ca92d6096abc7ef025364f1e835f14bde70fab32c9ccbf94be24617
7
+ data.tar.gz: 96eb68d1cc75a05dda5d6835fef6e68b3724a049742d1e189567a1378b3ea6edefe0c1ca2471183ceed27f8873143c21dbfc15ae2ad5e935471ff64e7a189ce5
@@ -173,7 +173,7 @@ module ActiveAgent
173
173
  end
174
174
  end
175
175
 
176
- attr_internal :prompt_context
176
+ attr_internal :context
177
177
 
178
178
  def agent_stream
179
179
  proc do |message, delta, stop|
@@ -184,8 +184,8 @@ module ActiveAgent
184
184
  end
185
185
 
186
186
  def embed
187
- prompt_context.options.merge(options)
188
- generation_provider.embed(prompt_context) if prompt_context && generation_provider
187
+ context.options.merge(options)
188
+ generation_provider.embed(context) if context && generation_provider
189
189
  handle_response(generation_provider.response)
190
190
  end
191
191
 
@@ -194,34 +194,29 @@ module ActiveAgent
194
194
  def embed
195
195
  agent_class = ActiveAgent::Base.descendants.first
196
196
  agent = agent_class.new
197
- agent.prompt_context = ActiveAgent::ActionPrompt::Prompt.new(message: self)
197
+ agent.context = ActiveAgent::ActionPrompt::Prompt.new(message: self)
198
198
  agent.embed
199
199
  self
200
200
  end
201
201
  end
202
202
 
203
- # Make prompt_context accessible for chaining
204
- # attr_accessor :prompt_context
203
+ # Make context accessible for chaining
204
+ # attr_accessor :context
205
205
 
206
206
  def perform_generation
207
- prompt_context.options.merge(options)
208
- if (action_methods - ActiveAgent::Base.descendants.first.action_methods).include? action_name
209
- prompt_context.message = prompt_context.messages.last
210
- prompt_context.actions = []
211
- end
212
- generation_provider.generate(prompt_context) if prompt_context && generation_provider
207
+ generation_provider.generate(context) if context && generation_provider
213
208
  handle_response(generation_provider.response)
214
209
  end
215
210
 
216
211
  def handle_response(response)
217
212
  return response unless response.message.requested_actions.present?
218
213
  perform_actions(requested_actions: response.message.requested_actions)
219
- update_prompt_context(response)
214
+ update_context(response)
220
215
  end
221
216
 
222
- def update_prompt_context(response)
223
- prompt_context.message = prompt_context.messages.last
224
- ActiveAgent::GenerationProvider::Response.new(prompt: prompt_context)
217
+ def update_context(response)
218
+ context.message = context.messages.last
219
+ ActiveAgent::GenerationProvider::Response.new(prompt: context)
225
220
  end
226
221
 
227
222
  def perform_actions(requested_actions:)
@@ -231,20 +226,22 @@ module ActiveAgent
231
226
  end
232
227
 
233
228
  def perform_action(action)
234
- current_context = prompt_context.clone
229
+ current_context = context.clone
235
230
  process(action.name, *action.params)
236
- prompt_context.messages.last.role = :tool
237
- prompt_context.messages.last.action_id = action.id
238
- prompt_context.messages.last.action_name = action.name
239
- prompt_context.messages.last.generation_id = action.id
240
- current_context.messages << prompt_context.messages.last
241
- self.prompt_context = current_context
231
+ context.messages.last.role = :tool
232
+ context.messages.last.action_id = action.id
233
+ context.messages.last.action_name = action.name
234
+ context.messages.last.generation_id = action.id
235
+ current_context.messages << context.messages.last
236
+ self.context = current_context
242
237
  end
243
238
 
244
239
  def initialize
245
240
  super
246
241
  @_prompt_was_called = false
247
- @_prompt_context = ActiveAgent::ActionPrompt::Prompt.new(instructions: options[:instructions], options: options)
242
+ @_context = ActiveAgent::ActionPrompt::Prompt.new(
243
+ instructions: prepare_instructions(options[:instructions]), options: options
244
+ )
248
245
  end
249
246
 
250
247
  def process(method_name, *args) # :nodoc:
@@ -256,7 +253,7 @@ module ActiveAgent
256
253
 
257
254
  ActiveSupport::Notifications.instrument("process.active_agent", payload) do
258
255
  super
259
- @_prompt_context = ActiveAgent::ActionPrompt::Prompt.new unless @_prompt_was_called
256
+ @_context = ActiveAgent::ActionPrompt::Prompt.new unless @_prompt_was_called
260
257
  end
261
258
  end
262
259
  ruby2_keywords(:process)
@@ -286,24 +283,28 @@ module ActiveAgent
286
283
 
287
284
  def headers(args = nil)
288
285
  if args
289
- @_prompt_context.headers(args)
286
+ @_context.headers(args)
290
287
  else
291
- @_prompt_context
288
+ @_context
292
289
  end
293
290
  end
294
291
 
295
292
  def prompt_with(*)
296
- prompt_context.update_prompt_context(*)
293
+ context.update_context(*)
297
294
  end
298
295
 
299
296
  def prompt(headers = {}, &block)
300
- return prompt_context if @_prompt_was_called && headers.blank? && !block
297
+ return context if @_prompt_was_called && headers.blank? && !block
298
+
299
+ context.instructions = prepare_instructions(headers[:instructions]) if headers.has_key?(:instructions)
300
+ context.options.merge!(options)
301
301
  content_type = headers[:content_type]
302
302
  headers = apply_defaults(headers)
303
- prompt_context.messages = headers[:messages] || []
304
- prompt_context.context_id = headers[:context_id]
303
+ context.messages = headers[:messages] || []
304
+ context.context_id = headers[:context_id]
305
+ context.params = params
305
306
 
306
- prompt_context.charset = charset = headers[:charset]
307
+ context.charset = charset = headers[:charset]
307
308
 
308
309
  if headers[:message].present? && headers[:message].is_a?(ActiveAgent::ActionPrompt::Message)
309
310
  headers[:body] = headers[:message].content
@@ -314,25 +315,31 @@ module ActiveAgent
314
315
  end
315
316
 
316
317
  # wrap_generation_behavior!(headers[:generation_method], headers[:generation_method_options])
317
- # assign_headers_to_prompt_context(prompt_context, headers)
318
+ # assign_headers_to_context(context, headers)
318
319
  responses = collect_responses(headers, &block)
319
320
 
320
321
  @_prompt_was_called = true
321
322
 
322
- create_parts_from_responses(prompt_context, responses)
323
+ create_parts_from_responses(context, responses)
324
+
325
+ context.content_type = set_content_type(context, content_type, headers[:content_type])
326
+ context.charset = charset
327
+ context.actions = headers[:actions] || action_schemas
328
+
329
+ if (action_methods - ActiveAgent::Base.descendants.first.action_methods).include? action_name
330
+ context.actions = (action_methods - [ action_name ])
331
+ end
323
332
 
324
- prompt_context.content_type = set_content_type(prompt_context, content_type, headers[:content_type])
325
- prompt_context.charset = charset
326
- prompt_context.actions = headers[:actions] || action_schemas
333
+ context
334
+ end
327
335
 
328
- prompt_context
336
+ def action_methods
337
+ super - ActiveAgent::Base.public_instance_methods(false).map(&:to_s)
329
338
  end
330
339
 
331
340
  def action_schemas
332
341
  action_methods.map do |action|
333
- if action != "text_prompt"
334
- JSON.parse render_to_string(locals: { action_name: action }, action: action, formats: :json)
335
- end
342
+ JSON.parse render_to_string(locals: { action_name: action }, action: action, formats: :json)
336
343
  end.compact
337
344
  end
338
345
 
@@ -342,7 +349,7 @@ module ActiveAgent
342
349
  if user_content_type.present?
343
350
  user_content_type
344
351
  else
345
- prompt_context.content_type || class_default
352
+ context.content_type || class_default
346
353
  end
347
354
  end
348
355
 
@@ -373,11 +380,11 @@ module ActiveAgent
373
380
  end
374
381
  end
375
382
 
376
- def assign_headers_to_prompt_context(prompt_context, headers)
383
+ def assign_headers_to_context(context, headers)
377
384
  assignable = headers.except(:parts_order, :content_type, :body, :role, :template_name,
378
385
  :template_path, :delivery_method, :delivery_method_options)
379
386
 
380
- assignable.each { |k, v| prompt_context.send(k, v) if prompt_context.respond_to?(k) }
387
+ assignable.each { |k, v| context.send(k, v) if context.respond_to?(k) }
381
388
  end
382
389
 
383
390
  def collect_responses(headers, &)
@@ -426,24 +433,45 @@ module ActiveAgent
426
433
  end
427
434
  end
428
435
 
429
- def create_parts_from_responses(prompt_context, responses)
436
+ def create_parts_from_responses(context, responses)
430
437
  if responses.size > 1
431
438
  # prompt_container = ActiveAgent::ActionPrompt::Prompt.new
432
439
  # prompt_container.content_type = "multipart/alternative"
433
- responses.each { |r| insert_part(prompt_context, r, prompt_context.charset) }
434
- # prompt_context.add_part(prompt_container)
440
+ responses.each { |r| insert_part(context, r, context.charset) }
441
+ # context.add_part(prompt_container)
435
442
  else
436
- responses.each { |r| insert_part(prompt_context, r, prompt_context.charset) }
443
+ responses.each { |r| insert_part(context, r, context.charset) }
437
444
  end
438
445
  end
439
446
 
440
- def insert_part(prompt_context, response, charset)
447
+ def insert_part(context, response, charset)
441
448
  message = ActiveAgent::ActionPrompt::Message.new(
442
449
  content: response[:body],
443
450
  content_type: response[:content_type],
444
451
  charset: charset
445
452
  )
446
- prompt_context.add_part(message)
453
+ context.add_part(message)
454
+ end
455
+
456
+ def prepare_instructions(instructions)
457
+ case instructions
458
+ when Hash
459
+ raise ArgumentError, "Expected `:template` key in instructions hash" unless instructions[:template]
460
+ return unless lookup_context.exists?(instructions[:template], agent_name, false, [], formats: [ :text ])
461
+
462
+ template = lookup_context.find_template(instructions[:template], agent_name, false, [], formats: [ :text ])
463
+ render_to_string(template: template.virtual_path, locals: instructions[:locals] || {}, layout: false)
464
+ when String
465
+ instructions
466
+ when NilClass
467
+ default_template_name = "instructions"
468
+ return unless lookup_context.exists?(default_template_name, agent_name, false, [], formats: [ :text ])
469
+
470
+ template = lookup_context.find_template(default_template_name, agent_name, false, [], formats: [ :text ])
471
+ render_to_string(template: template.virtual_path, layout: false)
472
+ else
473
+ raise ArgumentError, "Instructions must be Hash, String or NilClass objects"
474
+ end
447
475
  end
448
476
 
449
477
  # This and #instrument_name is for caching instrument
@@ -3,8 +3,8 @@ require_relative "message"
3
3
  module ActiveAgent
4
4
  module ActionPrompt
5
5
  class Prompt
6
- attr_reader :messages
7
- attr_accessor :actions, :body, :content_type, :context_id, :instructions, :message, :options, :mime_version, :charset, :context, :parts, :params, :action_choice, :agent_class
6
+ attr_reader :messages, :instructions
7
+ attr_accessor :actions, :body, :content_type, :context_id, :message, :options, :mime_version, :charset, :context, :parts, :params, :action_choice, :agent_class
8
8
 
9
9
  def initialize(attributes = {})
10
10
  @options = attributes.fetch(:options, {})
@@ -25,7 +25,7 @@ module ActiveAgent
25
25
  @parts = attributes.fetch(:parts, [])
26
26
  @messages = Message.from_messages(@messages)
27
27
  set_message if attributes[:message].is_a?(String) || @body.is_a?(String) && @message&.content
28
- set_messages
28
+ set_messages if @instructions.present?
29
29
  end
30
30
 
31
31
  def messages=(messages)
@@ -33,16 +33,27 @@ module ActiveAgent
33
33
  set_messages
34
34
  end
35
35
 
36
+ def instructions=(instructions)
37
+ @instructions = instructions
38
+ if @messages[0].present? && @messages[0].role == :system
39
+ @messages[0] = instructions_message
40
+ else
41
+ set_messages
42
+ end
43
+ end
44
+
36
45
  # Generate the prompt as a string (for debugging or sending to the provider)
37
46
  def to_s
38
47
  @message.to_s
39
48
  end
40
49
 
41
50
  def add_part(message)
42
- @message = message
43
- set_message if @content_type == message.content_type && @message.content.present?
51
+ if @content_type == message.content_type && message.content.present?
52
+ @message = message
53
+ set_message
54
+ end
44
55
 
45
- @parts << context
56
+ @parts << message
46
57
  end
47
58
 
48
59
  def multipart?
@@ -67,8 +78,12 @@ module ActiveAgent
67
78
 
68
79
  private
69
80
 
81
+ def instructions_message
82
+ Message.new(content: @instructions, role: :system)
83
+ end
84
+
70
85
  def set_messages
71
- @messages = [ Message.new(content: @instructions, role: :system) ] + Message.from_messages(@messages) if @instructions.present?
86
+ @messages = [ instructions_message ] + @messages
72
87
  end
73
88
 
74
89
  def set_message
@@ -78,7 +93,7 @@ module ActiveAgent
78
93
  @message = Message.new(content: @body, role: :user)
79
94
  end
80
95
 
81
- @messages << @message
96
+ @messages = @messages + [ @message ]
82
97
  end
83
98
  end
84
99
  end
@@ -28,8 +28,8 @@ module ActiveAgent
28
28
  # It is built on top of ActionPrompt which provides methods for generating content, handling actions, and managing prompts.
29
29
  # ActiveAgent::Base is designed to be extended by specific agent implementations.
30
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
31
+ # Base actions include: prompt_context, continue, reasoning, reiterate, and conclude
32
+ def prompt_context
33
33
  prompt(stream: params[:stream], messages: params[:messages], message: params[:message], context_id: params[:context_id])
34
34
  end
35
35
  end
@@ -6,24 +6,24 @@ module ActiveAgent
6
6
  def initialize(agent_class, action, *args)
7
7
  @agent_class, @action, @args = agent_class, action, args
8
8
  @processed_agent = nil
9
- @prompt_context = nil
9
+ @context = nil
10
10
  end
11
11
  ruby2_keywords(:initialize)
12
12
 
13
13
  def __getobj__
14
- @prompt_context ||= processed_agent.prompt_context
14
+ @context ||= processed_agent.context
15
15
  end
16
16
 
17
- def __setobj__(prompt_context)
18
- @prompt_context = prompt_context
17
+ def __setobj__(context)
18
+ @context = context
19
19
  end
20
20
 
21
- def prompt_context
21
+ def context
22
22
  __getobj__
23
23
  end
24
24
 
25
25
  def processed?
26
- @processed_agent || @prompt_context
26
+ @processed_agent || @context
27
27
  end
28
28
 
29
29
  def generate_later!(options = {})
@@ -1,3 +1,3 @@
1
1
  module ActiveAgent
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.2.rc1"
3
3
  end
@@ -6,13 +6,13 @@ Description:
6
6
  engine and test framework generators.
7
7
 
8
8
  Examples:
9
- `bin/rails generate agent inventory search`
9
+ `bin/rails generate active_agent:agent inventory search`
10
10
 
11
- creates a sign up mailer class, views, and test:
11
+ creates an inventory agent class, views, and test:
12
12
  Agent: app/agents/inventory_agent.rb
13
13
  Views: app/views/inventory_agent/search.text.erb [...]
14
14
  Test: test/agents/inventory_agent_test.rb
15
15
 
16
- `bin/rails generate agent inventory search update report`
16
+ `bin/rails generate active_agent:agent inventory search update report`
17
17
 
18
18
  creates an inventory agent with search, update, and report actions.
@@ -7,10 +7,10 @@ module ActiveAgent
7
7
 
8
8
  argument :actions, type: :array, default: [], banner: "method method"
9
9
 
10
- check_class_collision
10
+ check_class_collision suffix: "Agent"
11
11
 
12
12
  def create_agent_file
13
- template "agent.rb", File.join("app/agents", class_path, "#{file_name}.rb")
13
+ template "agent.rb", File.join("app/agents", class_path, "#{file_name}_agent.rb")
14
14
 
15
15
  in_root do
16
16
  if behavior == :invoke && !File.exist?(application_agent_file_name)
@@ -19,10 +19,12 @@ module ActiveAgent
19
19
  end
20
20
  end
21
21
 
22
+ hook_for :template_engine, :test_framework
23
+
22
24
  private
23
25
 
24
26
  def file_name # :doc:
25
- @_file_name ||= super + "_agent"
27
+ @_file_name ||= super.sub(/_agent\z/i, "")
26
28
  end
27
29
 
28
30
  def application_agent_file_name
@@ -5,18 +5,11 @@ module ActiveAgent
5
5
  class InstallGenerator < ::Rails::Generators::Base
6
6
  source_root File.expand_path("templates", __dir__)
7
7
 
8
+ hook_for :template_engine, :test_framework
9
+
8
10
  def create_configuration
9
11
  template "active_agent.yml", "config/active_agent.yml"
10
12
  end
11
-
12
- def create_application_agent
13
- template "application_agent.rb", "app/agents/application_agent.rb"
14
- end
15
-
16
- def create_agent_layouts
17
- template "agent.html.erb", "app/views/layouts/agent.html.erb"
18
- template "agent.text.erb", "app/views/layouts/agent.text.erb"
19
- end
20
13
  end
21
14
  end
22
15
  end
@@ -1,5 +1,5 @@
1
1
  <% module_namespacing do -%>
2
- class <%= class_name %> < ApplicationAgent
2
+ class <%= class_name %>Agent < ApplicationAgent
3
3
  <% actions.each_with_index do |action, index| -%>
4
4
  <% if index != 0 -%>
5
5
 
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/erb"
4
+
5
+ module Erb # :nodoc:
6
+ module Generators # :nodoc:
7
+ class AgentGenerator < Base # :nodoc:
8
+ source_root File.expand_path("templates", __dir__)
9
+ argument :actions, type: :array, default: [], banner: "method method"
10
+
11
+ def copy_view_files
12
+ view_base_path = File.join("app/views", class_path, file_name + "_agent")
13
+ empty_directory view_base_path
14
+
15
+ if behavior == :invoke
16
+ formats.each do |format|
17
+ layout_path = File.join("app/views/layouts", class_path, filename_with_extensions("agent", format))
18
+ template filename_with_extensions(:layout, format), layout_path unless File.exist?(layout_path)
19
+ end
20
+ end
21
+
22
+ actions.each do |action|
23
+ @action = action
24
+
25
+ formats.each do |format|
26
+ @path = File.join(view_base_path, filename_with_extensions(action, format))
27
+ template filename_with_extensions(:view, format), @path
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def formats
35
+ [ :text, :html, :json ]
36
+ end
37
+
38
+ def file_name
39
+ @_file_name ||= super.sub(/_agent\z/i, "")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Erb # :nodoc:
6
+ module Generators # :nodoc:
7
+ class InstallGenerator < ::Rails::Generators::Base # :nodoc:
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ def create_agent_layouts
11
+ template "layout.html.erb.tt", "app/views/layouts/agent.html.erb"
12
+ template "layout.text.erb.tt", "app/views/layouts/agent.text.erb"
13
+ template "layout.json.erb.tt", "app/views/layouts/agent.json.erb"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ <% module_namespacing do -%>
2
+ class ApplicationAgent < ActiveAgent::Base
3
+ layout 'agent'
4
+
5
+ generate_with :openai, model: "gpt-4o-mini", instructions: "You are a helpful assistant."
6
+ end
7
+ <% end %>
@@ -0,0 +1 @@
1
+ <%%= yield %>
@@ -0,0 +1 @@
1
+ <%%= yield %>
@@ -0,0 +1 @@
1
+ <%%= yield %>
@@ -0,0 +1,5 @@
1
+ <h1><%= class_name %>#<%= @action %></h1>
2
+
3
+ <p>
4
+ <%%= @message %>, find me in <%= @path %>
5
+ </p>
@@ -0,0 +1,16 @@
1
+ <%%= {
2
+ type: :function,
3
+ function: {
4
+ name: action_name,
5
+ description: "This action takes no params and gets a random cat image and returns it as a base64 string.",
6
+ parameters: {
7
+ type: :object,
8
+ properties: {
9
+ param_name: {
10
+ type: :string,
11
+ description: "The param_description"
12
+ }
13
+ }
14
+ }
15
+ }
16
+ }.to_json.html_safe %>
@@ -0,0 +1,3 @@
1
+ <%= class_name %>#<%= @action %>
2
+
3
+ <%%= @message %>, find me in <%= @path %>
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/test_unit"
4
+
5
+ module TestUnit # :nodoc:
6
+ module Generators # :nodoc:
7
+ class AgentGenerator < Base # :nodoc:
8
+ source_root File.expand_path("templates", __dir__)
9
+ argument :actions, type: :array, default: [], banner: "method method"
10
+
11
+ def check_class_collision
12
+ class_collisions "#{class_name}AgentTest", "#{class_name}AgentPreview"
13
+ end
14
+
15
+ def create_test_files
16
+ template "functional_test.rb", File.join("test/agents", class_path, "#{file_name}_agent_test.rb")
17
+ end
18
+
19
+ def create_preview_files
20
+ template "preview.rb", File.join("test/agents/previews", class_path, "#{file_name}_agent_preview.rb")
21
+ end
22
+
23
+ private
24
+
25
+ def file_name
26
+ @_file_name ||= super.sub(/_agent\z/i, "")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/test_unit"
4
+
5
+ module TestUnit # :nodoc:
6
+ module Generators # :nodoc:
7
+ class InstallGenerator < Base # :nodoc:
8
+ # TestUnit install generator for ActiveAgent
9
+ # This can be used to create additional test-specific files during installation
10
+ # Currently no additional files are needed for TestUnit setup
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ require "test_helper"
2
+
3
+ <% module_namespacing do -%>
4
+ class <%= class_name %>AgentTest < ActiveAgent::TestCase
5
+ <% actions.each_with_index do |action, index| -%>
6
+ <% if index != 0 -%>
7
+
8
+ <% end -%>
9
+ test "<%= action %>" do
10
+ agent = <%= class_name %>Agent.<%= action %>
11
+ assert_equal <%= action.to_s.humanize.inspect %>, agent.prompt_context
12
+ end
13
+ <% end -%>
14
+ <% if actions.blank? -%>
15
+ # test "the truth" do
16
+ # assert true
17
+ # end
18
+ <% end -%>
19
+ end
20
+ <% end -%>
@@ -0,0 +1,14 @@
1
+ <% module_namespacing do -%>
2
+ # Preview all agent views/prompts templates at http://localhost:3000/active_agent/agents/<%= file_path %>_agent
3
+ class <%= class_name %>AgentPreview < ActiveAgent::Preview
4
+ <% actions.each_with_index do |action, index| -%>
5
+ <% if index != 0 -%>
6
+
7
+ <% end -%>
8
+ # Preview this email at http://localhost:3000/active_agent/agents/<%= file_path %>_agent/<%= action %>
9
+ def <%= action %>
10
+ <%= class_name %>Agent.<%= action %>
11
+ end
12
+ <% end -%>
13
+ end
14
+ <% end -%>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
@@ -187,15 +187,22 @@ files:
187
187
  - lib/generators/active_agent/USAGE
188
188
  - lib/generators/active_agent/agent_generator.rb
189
189
  - lib/generators/active_agent/install_generator.rb
190
- - lib/generators/active_agent/templates/action.html.erb.tt
191
- - lib/generators/active_agent/templates/action.json.jbuilder.tt
192
190
  - lib/generators/active_agent/templates/active_agent.yml
193
- - lib/generators/active_agent/templates/agent.html.erb
194
191
  - lib/generators/active_agent/templates/agent.rb.tt
195
- - lib/generators/active_agent/templates/agent.text.erb
196
- - lib/generators/active_agent/templates/agent_spec.rb.tt
197
- - lib/generators/active_agent/templates/agent_test.rb.tt
198
192
  - lib/generators/active_agent/templates/application_agent.rb.tt
193
+ - lib/generators/erb/agent_generator.rb
194
+ - lib/generators/erb/install_generator.rb
195
+ - lib/generators/erb/templates/application_agent.rb.tt
196
+ - lib/generators/erb/templates/layout.html.erb.tt
197
+ - lib/generators/erb/templates/layout.json.erb.tt
198
+ - lib/generators/erb/templates/layout.text.erb.tt
199
+ - lib/generators/erb/templates/view.html.erb.tt
200
+ - lib/generators/erb/templates/view.json.erb.tt
201
+ - lib/generators/erb/templates/view.text.erb.tt
202
+ - lib/generators/test_unit/agent_generator.rb
203
+ - lib/generators/test_unit/install_generator.rb
204
+ - lib/generators/test_unit/templates/functional_test.rb.tt
205
+ - lib/generators/test_unit/templates/preview.rb.tt
199
206
  - lib/tasks/activeagent_tasks.rake
200
207
  homepage: https://activeagents.ai
201
208
  licenses:
@@ -1,14 +0,0 @@
1
- json.type :function
2
- json.function do
3
- json.name action_name
4
- json.description "TODO: Write a description for this action"
5
- json.parameters do
6
- json.type :object
7
- json.properties do
8
- json.param_name do
9
- json.type :string
10
- json.description "The param_description"
11
- end
12
- end
13
- end
14
- end
@@ -1 +0,0 @@
1
- <%= yield if block_given? %>
@@ -1 +0,0 @@
1
- <%= yield if block_given? %>