activeagent 0.4.1 → 0.4.2.rc2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c93bac60dcbdb44bfc6461435f84e79499682db83a93ea07526a5b546c2a1b63
4
- data.tar.gz: c3a7a995862ef152661b1ede6c012e17747c190853cdc501e0a0f99445c7fe40
3
+ metadata.gz: 1ac9862cc06ad052e647933e771cb13ee76b4dbf43f5cdd61b871e017d685477
4
+ data.tar.gz: cf42d4608113a3ca73432fdd404c319f97ddde53919440c54a0247c1002b3f00
5
5
  SHA512:
6
- metadata.gz: 5e2836e13ca5d353d221a33643c7c101320e2615982dceccf4dfdf25c9e9fe9bbdeb48503aa70d1a21ed1dd8cfdab0ec76348342dbbd29dc5cfb59f9306266f9
7
- data.tar.gz: edaddc4339c00242935f0ba70fdc95f98547c12ccd6d4b4da9cd4081dd051e3521c6b4bdb5745fe6e7a382e462024b0dc0aec12eacd730b2ebc5f12a81315d35
6
+ metadata.gz: 23f7ccf62009efc9a46f0fb3e200866850519178bec86a36edb00e0d7252023bb1bbeb88da3087d2eaa565749ac0c3ae43e25e576615804fa7368617c6010c71
7
+ data.tar.gz: bda215bf93b1e86352871be452fec8bbb7c77d3638ffa608e44ca4694b87a5dd5f9cf08bd1d87687e6116e65347aa3253b50970b012b9b76522ae6c4e3070016
@@ -204,11 +204,6 @@ module ActiveAgent
204
204
  # attr_accessor :context
205
205
 
206
206
  def perform_generation
207
- context.options.merge(options)
208
- if (action_methods - ActiveAgent::Base.descendants.first.action_methods).include? action_name
209
- context.message = context.messages.last
210
- context.actions = []
211
- end
212
207
  generation_provider.generate(context) if context && generation_provider
213
208
  handle_response(generation_provider.response)
214
209
  end
@@ -244,7 +239,9 @@ module ActiveAgent
244
239
  def initialize
245
240
  super
246
241
  @_prompt_was_called = false
247
- @_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:
@@ -298,10 +295,14 @@ module ActiveAgent
298
295
 
299
296
  def prompt(headers = {}, &block)
300
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
303
  context.messages = headers[:messages] || []
304
304
  context.context_id = headers[:context_id]
305
+ context.params = params
305
306
 
306
307
  context.charset = charset = headers[:charset]
307
308
 
@@ -325,6 +326,10 @@ module ActiveAgent
325
326
  context.charset = charset
326
327
  context.actions = headers[:actions] || action_schemas
327
328
 
329
+ if (action_methods - ActiveAgent::Base.descendants.first.action_methods).include? action_name
330
+ context.actions = (action_methods - [ action_name ])
331
+ end
332
+
328
333
  context
329
334
  end
330
335
 
@@ -448,6 +453,27 @@ module ActiveAgent
448
453
  context.add_part(message)
449
454
  end
450
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
475
+ end
476
+
451
477
  # This and #instrument_name is for caching instrument
452
478
  def instrument_payload(key)
453
479
  {
@@ -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
@@ -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.1"
2
+ VERSION = "0.4.2.rc2"
3
3
  end
@@ -0,0 +1,25 @@
1
+ Description:
2
+ Sets up ActiveAgent in your Rails application by creating the necessary
3
+ configuration files and application agent class.
4
+
5
+ This generator creates:
6
+ - Configuration file (config/active_agent.yml)
7
+ - Application agent base class (app/agents/application_agent.rb)
8
+ - Layout templates for agent views (via template engine hooks)
9
+
10
+ Examples:
11
+ `bin/rails generate active_agent:install`
12
+
13
+ creates the basic ActiveAgent setup:
14
+ Config: config/active_agent.yml
15
+ Base Agent: app/agents/application_agent.rb
16
+ Layouts: app/views/layouts/agent.html.erb
17
+ app/views/layouts/agent.text.erb
18
+ app/views/layouts/agent.json.erb
19
+
20
+ `bin/rails generate active_agent:install --template-engine=haml`
21
+
22
+ creates ActiveAgent setup with Haml layouts instead of ERB.
23
+
24
+ After running this generator, you can create individual agents with:
25
+ `bin/rails generate active_agent:agent AGENT_NAME ACTION_NAME`
@@ -1,18 +1,30 @@
1
1
  Description:
2
2
  Generates a new agent and its views. Passes the agent name, either
3
- CamelCased or under_scored, and an optional list of prompts as arguments.
3
+ CamelCased or under_scored, and an optional list of actions as arguments.
4
4
 
5
- This generates a agent class in app/agents and invokes your template
6
- engine and test framework generators.
5
+ This generates an agent class in app/agents and invokes your template
6
+ engine and test framework generators. If no ApplicationAgent exists,
7
+ it will be created automatically.
8
+
9
+ Views are created for each action in three formats:
10
+ - HTML (.html.erb) - for rich text responses
11
+ - Text (.text.erb) - for plain text responses
12
+ - JSON (.json.erb) - for structured function calling responses
7
13
 
8
14
  Examples:
9
- `bin/rails generate agent inventory search`
15
+ `bin/rails generate active_agent:agent inventory search`
10
16
 
11
- creates a sign up mailer class, views, and test:
12
- Agent: app/agents/inventory_agent.rb
13
- Views: app/views/inventory_agent/search.text.erb [...]
17
+ creates an inventory agent class, views, and test:
18
+ Agent: app/agents/inventory_agent.rb
19
+ Views: app/views/inventory_agent/search.html.erb
20
+ app/views/inventory_agent/search.text.erb
21
+ app/views/inventory_agent/search.json.erb
14
22
  Test: test/agents/inventory_agent_test.rb
15
23
 
16
- `bin/rails generate agent inventory search update report`
24
+ `bin/rails generate active_agent:agent inventory search update report`
17
25
 
18
26
  creates an inventory agent with search, update, and report actions.
27
+
28
+ `bin/rails generate active_agent:agent admin/user create --template-engine=haml`
29
+
30
+ creates a namespaced admin/user agent with Haml templates.
@@ -3,6 +3,9 @@
3
3
  module ActiveAgent
4
4
  module Generators
5
5
  class InstallGenerator < ::Rails::Generators::Base
6
+ def self.usage_path
7
+ @usage_path ||= File.expand_path("../USAGE", __dir__)
8
+ end
6
9
  source_root File.expand_path("templates", __dir__)
7
10
 
8
11
  hook_for :template_engine, :test_framework
@@ -10,6 +13,20 @@ module ActiveAgent
10
13
  def create_configuration
11
14
  template "active_agent.yml", "config/active_agent.yml"
12
15
  end
16
+
17
+ def create_application_agent
18
+ in_root do
19
+ if !File.exist?(application_agent_file_name)
20
+ template "application_agent.rb", application_agent_file_name
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def application_agent_file_name
28
+ "app/agents/application_agent.rb"
29
+ end
13
30
  end
14
31
  end
15
32
  end
@@ -32,7 +32,7 @@ module Erb # :nodoc:
32
32
  private
33
33
 
34
34
  def formats
35
- [ :text, :html ]
35
+ [ :text, :html, :json ]
36
36
  end
37
37
 
38
38
  def file_name
@@ -10,6 +10,7 @@ module Erb # :nodoc:
10
10
  def create_agent_layouts
11
11
  template "layout.html.erb.tt", "app/views/layouts/agent.html.erb"
12
12
  template "layout.text.erb.tt", "app/views/layouts/agent.text.erb"
13
+ template "layout.json.erb.tt", "app/views/layouts/agent.json.erb"
13
14
  end
14
15
  end
15
16
  end
@@ -0,0 +1 @@
1
+ <%%= yield %>
@@ -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 %>
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.1
4
+ version: 0.4.2.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
@@ -184,6 +184,7 @@ files:
184
184
  - lib/active_agent/test_case.rb
185
185
  - lib/active_agent/version.rb
186
186
  - lib/activeagent.rb
187
+ - lib/generators/USAGE
187
188
  - lib/generators/active_agent/USAGE
188
189
  - lib/generators/active_agent/agent_generator.rb
189
190
  - lib/generators/active_agent/install_generator.rb
@@ -194,8 +195,10 @@ files:
194
195
  - lib/generators/erb/install_generator.rb
195
196
  - lib/generators/erb/templates/application_agent.rb.tt
196
197
  - lib/generators/erb/templates/layout.html.erb.tt
198
+ - lib/generators/erb/templates/layout.json.erb.tt
197
199
  - lib/generators/erb/templates/layout.text.erb.tt
198
200
  - lib/generators/erb/templates/view.html.erb.tt
201
+ - lib/generators/erb/templates/view.json.erb.tt
199
202
  - lib/generators/erb/templates/view.text.erb.tt
200
203
  - lib/generators/test_unit/agent_generator.rb
201
204
  - lib/generators/test_unit/install_generator.rb