activeagent 0.2.6.9 → 0.3.1

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: '08db8e070616e81109c24a4738d29cc5c7b2911a3b7584e90c23cd9a1072a20a'
4
- data.tar.gz: 424e66ddfde6018b15b33d440764604db3cb3c1c3bef3f6cc0c0e765cad8d06e
3
+ metadata.gz: d679bd3d4f68b5c696ed4cc194e9b5476ebb0da34d6ac683296f7f7f5feae0f8
4
+ data.tar.gz: 2f11870fc423e399c53bf0728203faf47cbe3303d7aa47bb2d5d77bc603cda8d
5
5
  SHA512:
6
- metadata.gz: d6b7d4b86153dfea08db656c6b0620229902d371fd0afccbc4eca30e961875a4982339dfd4cdc77c2349d9ecf7e9085a98de07a406c73c15cf4a25ffc0fe3548
7
- data.tar.gz: 4bb01d36f8610e25f0f0220f9b465779e15afa083786dfa8628def00b5a693a2804ff9665f967e484034ef30ea4312e2eafcc813aef1f66fb597ff7dd5bbbe49
6
+ metadata.gz: 8261c5df1f59b50a96e6c46f1363b470fadff9bbc0231ab6a1c2e6975e906d73d150f0c3d11367d8c766d49ffc0c67428ed3fb40a5fcbbd4c5b78e03a4274805
7
+ data.tar.gz: 64b70a42b0f09f175e441dccab85468946df03ec5f3cd6e007a5e4180d13726230817b5b4ddc4adc348a5b9b838adf8a9d3342490e7d6e96f07c79fa983bc366
@@ -3,7 +3,8 @@ require_relative "message"
3
3
  module ActiveAgent
4
4
  module ActionPrompt
5
5
  class Prompt
6
- attr_accessor :actions, :body, :content_type, :context_id, :instructions, :message, :messages, :options, :mime_version, :charset, :context, :parts
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
7
8
 
8
9
  def initialize(attributes = {})
9
10
  @options = attributes.fetch(:options, {})
@@ -27,6 +28,11 @@ module ActiveAgent
27
28
  set_messages
28
29
  end
29
30
 
31
+ def messages=(messages)
32
+ @messages = messages
33
+ set_messages
34
+ end
35
+
30
36
  # Generate the prompt as a string (for debugging or sending to the provider)
31
37
  def to_s
32
38
  @message.to_s
@@ -62,7 +68,7 @@ module ActiveAgent
62
68
  private
63
69
 
64
70
  def set_messages
65
- @messages = [Message.new(content: @instructions, role: :system)] + @messages
71
+ @messages = [Message.new(content: @instructions, role: :system)] + @messages if @instructions.present?
66
72
  end
67
73
 
68
74
  def set_message
@@ -71,6 +77,7 @@ module ActiveAgent
71
77
  elsif @body.is_a?(String) && @message.content.blank?
72
78
  @message = Message.new(content: @body, role: :user)
73
79
  end
80
+
74
81
  @messages << @message
75
82
  end
76
83
  end
@@ -219,15 +219,14 @@ module ActiveAgent
219
219
  end
220
220
 
221
221
  def handle_response(response)
222
- perform_actions(requested_actions: response.message.requested_actions) if response.message.requested_actions.present?
223
-
222
+ return response unless response.message.requested_actions.present?
223
+ perform_actions(requested_actions: response.message.requested_actions)
224
224
  update_prompt_context(response)
225
225
  end
226
226
 
227
227
  def update_prompt_context(response)
228
- # response.prompt = prompt_context
229
- # response.message = response.messages.last
230
- response
228
+ prompt_context.message = prompt_context.messages.last
229
+ ActiveAgent::GenerationProvider::Response.new(prompt: prompt_context)
231
230
  end
232
231
 
233
232
  def perform_actions(requested_actions:)
@@ -237,9 +236,12 @@ module ActiveAgent
237
236
  end
238
237
 
239
238
  def perform_action(action)
239
+ current_context = prompt_context.clone
240
240
  process(action.name, *action.params)
241
241
  prompt_context.messages.last.role = :tool
242
242
  prompt_context.messages.last.action_id = action.id
243
+ current_context.messages << prompt_context.messages.last
244
+ self.prompt_context = current_context
243
245
  end
244
246
 
245
247
  def initialize
@@ -293,34 +295,15 @@ module ActiveAgent
293
295
  end
294
296
  end
295
297
 
296
- class LateAttachmentsProxy < SimpleDelegator
297
- def inline
298
- self
299
- end
300
-
301
- def []=(_name, _content)
302
- _raise_error
303
- end
304
-
305
- private
306
-
307
- def _raise_error
308
- raise "Can't add attachments after `prompt` was called.\n" \
309
- "Make sure to use `attachments[]=` before calling `prompt`."
310
- end
311
- end
312
-
313
298
  def prompt_with(*)
314
299
  prompt_context.update_prompt_context(*)
315
300
  end
316
301
 
317
302
  def prompt(headers = {}, &block)
318
303
  return prompt_context if @_prompt_was_called && headers.blank? && !block
319
-
320
304
  content_type = headers[:content_type]
321
-
322
305
  headers = apply_defaults(headers)
323
-
306
+ prompt_context.messages = headers[:messages] || []
324
307
  prompt_context.context_id = headers[:context_id]
325
308
 
326
309
  prompt_context.charset = charset = headers[:charset]
@@ -334,6 +317,7 @@ module ActiveAgent
334
317
  prompt_context.content_type = set_content_type(prompt_context, content_type, headers[:content_type])
335
318
  prompt_context.charset = charset
336
319
  prompt_context.actions = headers[:actions] || action_schemas
320
+
337
321
  prompt_context
338
322
  end
339
323
 
@@ -41,4 +41,4 @@ module ActiveAgent
41
41
  end
42
42
  end
43
43
  end
44
- end
44
+ end
@@ -23,12 +23,6 @@ module ActiveAgent
23
23
  raise GenerationProviderError, e.message
24
24
  end
25
25
 
26
- def chat_prompt(parameters: prompt_parameters)
27
- parameters[:stream] = provider_stream if prompt.options[:stream] || config["stream"]
28
-
29
- chat_response(@client.chat(parameters: parameters))
30
- end
31
-
32
26
  def embed(prompt)
33
27
  @prompt = prompt
34
28
 
@@ -37,39 +31,25 @@ module ActiveAgent
37
31
  raise GenerationProviderError, e.message
38
32
  end
39
33
 
40
- def embeddings_parameters(input: prompt.message.content, model: "text-embedding-3-large")
41
- {
42
- model: model,
43
- input: input
44
- }
45
- end
46
-
47
- def embeddings_response(response)
48
- message = Message.new(content: response.dig("data", 0, "embedding"), role: "assistant")
49
-
50
- @response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message: message, raw_response: response)
51
- end
52
-
53
- def embeddings_prompt(parameters:)
54
- embeddings_response(@client.embeddings(parameters: embeddings_parameters))
55
- end
56
-
57
34
  private
58
35
 
59
36
  def provider_stream
60
- # prompt.options[:stream] will define a proc found in prompt at runtime
61
- # config[:stream] will define a proc found in config. stream would come from an Agent class's generate_with or stream_with method calls
62
37
  agent_stream = prompt.options[:stream]
63
38
  message = ActiveAgent::ActionPrompt::Message.new(content: "", role: :assistant)
64
- @response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message:)
65
39
 
40
+ @response = ActiveAgent::GenerationProvider::Response.new(prompt:, message:)
66
41
  proc do |chunk, bytesize|
67
- if (new_content = chunk.dig("choices", 0, "delta", "content"))
42
+ new_content = chunk.dig("choices", 0, "delta", "content")
43
+ if new_content && !new_content.blank
68
44
  message.content += new_content
69
45
 
70
46
  agent_stream.call(message, new_content, false) do |message, new_content|
71
47
  yield message, new_content if block_given?
72
48
  end
49
+ elsif chunk.dig("choices", 0, "delta", "tool_calls") && !chunk.dig("choices", 0, "delta", "tool_calls").empty?
50
+ message = handle_message(chunk.dig("choices", 0, "delta"))
51
+ prompt.messages << message
52
+ @response = ActiveAgent::GenerationProvider::Response.new(prompt:, message:)
73
53
  end
74
54
 
75
55
  agent_stream.call(message, nil, true) do |message|
@@ -109,30 +89,57 @@ module ActiveAgent
109
89
 
110
90
  message_json = response.dig("choices", 0, "message")
111
91
 
112
- message = ActiveAgent::ActionPrompt::Message.new(
92
+ message = handle_message(message_json)
93
+
94
+ update_context(prompt: prompt, message: message, response: response)
95
+
96
+ @response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message: message, raw_response: response)
97
+ end
98
+
99
+ def handle_message(message_json)
100
+ ActiveAgent::ActionPrompt::Message.new(
113
101
  content: message_json["content"],
114
- role: message_json["role"],
102
+ role: message_json["role"].intern,
115
103
  action_requested: message_json["finish_reason"] == "tool_calls",
116
104
  requested_actions: handle_actions(message_json["tool_calls"])
117
105
  )
118
- update_context(prompt: prompt, message: message, response: response)
106
+ end
107
+
108
+ def handle_actions(tool_calls)
109
+ return [] if tool_calls.nil? || tool_calls.empty?
110
+
111
+ tool_calls.map do |tool_call|
112
+ next if tool_call["function"].nil? || tool_call["function"]["name"].blank?
113
+ args = tool_call["function"]["arguments"].blank? ? nil : JSON.parse(tool_call["function"]["arguments"], {symbolize_names: true})
114
+
115
+ ActiveAgent::ActionPrompt::Action.new(
116
+ id: tool_call["id"],
117
+ name: tool_call.dig("function", "name"),
118
+ params: args
119
+ )
120
+ end.compact
121
+ end
122
+
123
+ def chat_prompt(parameters: prompt_parameters)
124
+ parameters[:stream] = provider_stream if prompt.options[:stream] || config["stream"]
125
+ chat_response(@client.chat(parameters: parameters))
126
+ end
127
+
128
+ def embeddings_parameters(input: prompt.message.content, model: "text-embedding-3-large")
129
+ {
130
+ model: model,
131
+ input: input
132
+ }
133
+ end
134
+
135
+ def embeddings_response(response)
136
+ message = Message.new(content: response.dig("data", 0, "embedding"), role: "assistant")
119
137
 
120
138
  @response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message: message, raw_response: response)
121
139
  end
122
140
 
123
- def handle_actions(tool_calls)
124
- if tool_calls
125
- tool_calls.map do |tool_call|
126
- ActiveAgent::ActionPrompt::Action.new(
127
- id: tool_call["id"],
128
- name: tool_call.dig("function", "name"),
129
- params: JSON.parse(
130
- tool_call.dig("function", "arguments"),
131
- {symbolize_names: true}
132
- )
133
- )
134
- end
135
- end
141
+ def embeddings_prompt(parameters:)
142
+ embeddings_response(@client.embeddings(parameters: embeddings_parameters))
136
143
  end
137
144
  end
138
145
  end
@@ -5,9 +5,9 @@ module ActiveAgent
5
5
  class Response
6
6
  attr_reader :message, :prompt, :raw_response
7
7
 
8
- def initialize(prompt:, message:, raw_response: nil)
9
- @message = message
8
+ def initialize(prompt:, message: nil, raw_response: nil)
10
9
  @prompt = prompt
10
+ @message = message || prompt.message
11
11
  @raw_response = raw_response
12
12
  end
13
13
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveAgent
2
- VERSION = "0.2.6.9"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -19,34 +19,8 @@ module ActiveAgent
19
19
  end
20
20
  end
21
21
 
22
- def create_test_file
23
- if test_framework == :rspec
24
- template "agent_spec.rb", File.join("spec/agents", class_path, "#{file_name}_agent_spec.rb")
25
- else
26
- template "agent_test.rb", File.join("test/agents", class_path, "#{file_name}_agent_test.rb")
27
- end
28
- end
29
-
30
- def create_view_files
31
- actions.each do |action|
32
- @action = action
33
- @schema_path = File.join("app/views", class_path, file_name, "#{action}.json.jbuilder")
34
- @view_path = File.join("app/views", class_path, file_name, "#{action}.html.erb")
35
- template "action.json.jbuilder", @schema_path
36
- template "action.html.erb", @view_path
37
- end
38
- end
39
-
40
22
  private
41
23
 
42
- def test_framework
43
- ::Rails.application.config.generators.options[:rails][:test_framework]
44
- end
45
-
46
- def template_engine
47
- ::Rails.application.config.generators.options[:rails][:template_engine]
48
- end
49
-
50
24
  def file_name # :doc:
51
25
  @_file_name ||= super + "_agent"
52
26
  end
@@ -12,10 +12,6 @@ module ActiveAgent
12
12
  def create_application_agent
13
13
  template "application_agent.rb", "app/agents/application_agent.rb"
14
14
  end
15
-
16
- def create_agent_layout_template
17
- template "agent.text.erb", "app/views/layouts/agent.text.erb"
18
- end
19
15
  end
20
16
  end
21
17
  end
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :activeagent do
3
+ # # Task goes here
4
+ # end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6.9
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-26 00:00:00.000000000 Z
11
+ date: 2025-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -150,7 +150,6 @@ files:
150
150
  - lib/active_agent/base.rb
151
151
  - lib/active_agent/callbacks.rb
152
152
  - lib/active_agent/deprecator.rb
153
- - lib/active_agent/engine.rb
154
153
  - lib/active_agent/generation.rb
155
154
  - lib/active_agent/generation_job.rb
156
155
  - lib/active_agent/generation_methods.rb
@@ -162,7 +161,6 @@ files:
162
161
  - lib/active_agent/generation_provider/response.rb
163
162
  - lib/active_agent/inline_preview_interceptor.rb
164
163
  - lib/active_agent/log_subscriber.rb
165
- - lib/active_agent/operation.rb
166
164
  - lib/active_agent/parameterized.rb
167
165
  - lib/active_agent/preview.rb
168
166
  - lib/active_agent/prompt_helper.rb
@@ -184,6 +182,9 @@ files:
184
182
  - lib/generators/active_agent/templates/agent_spec.rb.tt
185
183
  - lib/generators/active_agent/templates/agent_test.rb.tt
186
184
  - lib/generators/active_agent/templates/application_agent.rb.tt
185
+ - lib/generators/active_agent/templates/layout.html.erb
186
+ - lib/generators/active_agent/templates/layout.text.erb
187
+ - lib/tasks/activeagent_tasks.rake
187
188
  homepage: https://activeagents.ai
188
189
  licenses:
189
190
  - MIT
@@ -1,14 +0,0 @@
1
- # require "rails/engine"
2
-
3
- # module ActiveAgent
4
- # class Engine < ::Rails::Engine
5
- # isolate_namespace ActiveAgent
6
-
7
- # initializer "active_agent.view_paths" do |app|
8
- # # Adding your gem's view path to Rails lookup paths
9
- # ActiveSupport.on_load(:action_controller) do
10
- # append_view_path Engine.root.join("app/views")
11
- # end
12
- # end
13
- # end
14
- # end
@@ -1,13 +0,0 @@
1
- module ActiveAgent
2
- class Operation < AbstractController::Base
3
- include AbstractController::Rendering
4
- include ActionView::Rendering # Allows rendering of ERB templates without a view context tied to a request
5
- append_view_path "app/views" # Ensure the controller knows where to look for view templates
6
-
7
- def process_tool(tool_name, params)
8
- send(tool_name, params) # Dynamically calls the method corresponding to tool_name
9
- rescue NoMethodError
10
- "Tool not found: #{tool_name}"
11
- end
12
- end
13
- end