activeagent 0.2.5 → 0.2.6.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.
- checksums.yaml +4 -4
- data/lib/active_agent/action_prompt/action.rb +1 -1
- data/lib/active_agent/action_prompt/prompt.rb +7 -8
- data/lib/active_agent/base.rb +15 -17
- data/lib/active_agent/callbacks.rb +14 -1
- data/lib/active_agent/generation_job.rb +1 -1
- data/lib/active_agent/generation_provider/open_ai_provider.rb +14 -11
- data/lib/active_agent/railtie.rb +8 -10
- data/lib/active_agent/version.rb +1 -1
- data/lib/activeagent.rb +1 -0
- data/lib/generators/active_agent/templates/application_agent.rb.tt +2 -2
- metadata +9 -7
- data/README.md +0 -188
- data/Rakefile +0 -2
- data/lib/generators/active_agent/templates/initializer.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5be38e4a523b45e6456791eaa43e9a04ea377d0d6921c8c0e427b8bb06418f3
|
4
|
+
data.tar.gz: 191f478a1d79f5bfe65e2016f9ec4063dce945eb09912da2cd70d393f0fda3c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f4749307fec6f7b9a7339486c09b9f20d61b05388a67f12f0c2e00267fc14979f6d193f649c64117f13b822baac75511b0269700a6362d0e3cb548c9d68c1df
|
7
|
+
data.tar.gz: 7b3adbd0b9372d037b6fd303f55103d06e54ae7693b3920c7746ee1b7efe95f14134c7998a0bf5034e044fd3548ab0e44bf69df7a64109a2a0e319201273cd84
|
@@ -12,7 +12,7 @@ module ActiveAgent
|
|
12
12
|
@instructions = attributes.fetch(:instructions, "")
|
13
13
|
@body = attributes.fetch(:body, "")
|
14
14
|
@content_type = attributes.fetch(:content_type, "text/plain")
|
15
|
-
@message = attributes.fetch(:message,
|
15
|
+
@message = attributes.fetch(:message, nil)
|
16
16
|
@messages = attributes.fetch(:messages, [])
|
17
17
|
@params = attributes.fetch(:params, {})
|
18
18
|
@mime_version = attributes.fetch(:mime_version, "1.0")
|
@@ -21,8 +21,8 @@ module ActiveAgent
|
|
21
21
|
@headers = attributes.fetch(:headers, {})
|
22
22
|
@parts = attributes.fetch(:parts, [])
|
23
23
|
|
24
|
-
set_message if attributes[:message].is_a?(String) || @body.is_a?(String) && @message
|
25
|
-
set_messages
|
24
|
+
set_message if attributes[:message].is_a?(String) || @body.is_a?(String) && @message&.content
|
25
|
+
set_messages
|
26
26
|
end
|
27
27
|
|
28
28
|
# Generate the prompt as a string (for debugging or sending to the provider)
|
@@ -30,12 +30,11 @@ module ActiveAgent
|
|
30
30
|
@message.to_s
|
31
31
|
end
|
32
32
|
|
33
|
-
def add_part(
|
34
|
-
@message =
|
33
|
+
def add_part(message)
|
34
|
+
@message = message
|
35
|
+
set_message if @content_type == message.content_type && @message.content.present?
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
@parts << prompt_part
|
37
|
+
@parts << context
|
39
38
|
end
|
40
39
|
|
41
40
|
def multipart?
|
data/lib/active_agent/base.rb
CHANGED
@@ -128,8 +128,8 @@ module ActiveAgent
|
|
128
128
|
# Define how the agent should generate content
|
129
129
|
def generate_with(provider, **options)
|
130
130
|
self.generation_provider = provider
|
131
|
-
self.options = (options || {}).merge(options)
|
132
|
-
generation_provider.config.merge!(options)
|
131
|
+
self.options = (options || {}).merge(options)
|
132
|
+
generation_provider.config.merge!(self.options)
|
133
133
|
end
|
134
134
|
|
135
135
|
def stream_with(&stream)
|
@@ -203,20 +203,20 @@ module ActiveAgent
|
|
203
203
|
attr_internal :context
|
204
204
|
|
205
205
|
def perform_generation
|
206
|
-
context.options.merge(options)
|
206
|
+
context.options.merge(options)
|
207
207
|
generation_provider.generate(context) if context && generation_provider
|
208
|
-
handle_response(generation_provider.response)
|
209
|
-
generation_provider.response
|
208
|
+
handle_response(generation_provider.response)
|
210
209
|
end
|
211
210
|
|
212
211
|
def handle_response(response)
|
213
212
|
perform_actions(requested_actions: response.message.requested_actions) if response.message.requested_actions.present?
|
214
|
-
|
213
|
+
|
214
|
+
update_context(response)
|
215
215
|
end
|
216
216
|
|
217
217
|
def update_context(response)
|
218
218
|
context.message = response.message
|
219
|
-
|
219
|
+
response
|
220
220
|
end
|
221
221
|
|
222
222
|
def perform_actions(requested_actions:)
|
@@ -232,7 +232,7 @@ module ActiveAgent
|
|
232
232
|
def initialize
|
233
233
|
super
|
234
234
|
@_prompt_was_called = false
|
235
|
-
@_context = ActiveAgent::ActionPrompt::Prompt.new(instructions: options[:instructions])
|
235
|
+
@_context = ActiveAgent::ActionPrompt::Prompt.new(instructions: options[:instructions], options: options)
|
236
236
|
end
|
237
237
|
|
238
238
|
def process(method_name, *args) # :nodoc:
|
@@ -241,7 +241,7 @@ module ActiveAgent
|
|
241
241
|
action: method_name,
|
242
242
|
args: args
|
243
243
|
}
|
244
|
-
|
244
|
+
|
245
245
|
ActiveSupport::Notifications.instrument("process.active_agent", payload) do
|
246
246
|
super
|
247
247
|
@_context = ActiveAgent::ActionPrompt::Prompt.new unless @_prompt_was_called
|
@@ -332,7 +332,7 @@ module ActiveAgent
|
|
332
332
|
|
333
333
|
def action_schemas
|
334
334
|
action_methods.map do |action|
|
335
|
-
if action != "
|
335
|
+
if action != "text_prompt"
|
336
336
|
JSON.parse render_to_string(locals: {action_name: action}, action: action, formats: :json)
|
337
337
|
end
|
338
338
|
end.compact
|
@@ -431,24 +431,22 @@ module ActiveAgent
|
|
431
431
|
|
432
432
|
def create_parts_from_responses(context, responses)
|
433
433
|
if responses.size > 1
|
434
|
-
prompt_container = ActiveAgent::ActionPrompt::Prompt.new
|
435
|
-
prompt_container.content_type = "multipart/alternative"
|
434
|
+
# prompt_container = ActiveAgent::ActionPrompt::Prompt.new
|
435
|
+
# prompt_container.content_type = "multipart/alternative"
|
436
436
|
responses.each { |r| insert_part(context, r, context.charset) }
|
437
|
-
context.add_part(prompt_container)
|
437
|
+
# context.add_part(prompt_container)
|
438
438
|
else
|
439
439
|
responses.each { |r| insert_part(context, r, context.charset) }
|
440
440
|
end
|
441
441
|
end
|
442
442
|
|
443
|
-
def insert_part(
|
444
|
-
prompt = ActiveAgent::ActionPrompt::Prompt.new
|
443
|
+
def insert_part(context, response, charset)
|
445
444
|
message = ActiveAgent::ActionPrompt::Message.new(
|
446
445
|
content: response[:body],
|
447
446
|
content_type: response[:content_type],
|
448
447
|
charset: charset
|
449
448
|
)
|
450
|
-
|
451
|
-
container.add_part(prompt)
|
449
|
+
context.add_part(message)
|
452
450
|
end
|
453
451
|
# This and #instrument_name is for caching instrument
|
454
452
|
def instrument_payload(key)
|
@@ -7,6 +7,7 @@ module ActiveAgent
|
|
7
7
|
included do
|
8
8
|
include ActiveSupport::Callbacks
|
9
9
|
define_callbacks :generate, skip_after_callbacks_if_terminated: true
|
10
|
+
define_callbacks :stream, skip_after_callbacks_if_terminated: true
|
10
11
|
end
|
11
12
|
|
12
13
|
module ClassMethods
|
@@ -26,6 +27,18 @@ module ActiveAgent
|
|
26
27
|
def around_generate(*filters, &)
|
27
28
|
set_callback(:generate, :around, *filters, &)
|
28
29
|
end
|
30
|
+
|
31
|
+
# Defines a callback for handling streaming responses during generation
|
32
|
+
def on_stream(*filters, &)
|
33
|
+
set_callback(:stream, :before, *filters, &)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Helper method to run stream callbacks
|
38
|
+
def run_stream_callbacks(message, delta = nil, stop = false)
|
39
|
+
run_callbacks(:stream) do
|
40
|
+
yield(message, delta, stop) if block_given?
|
41
|
+
end
|
29
42
|
end
|
30
43
|
end
|
31
|
-
end
|
44
|
+
end
|
@@ -17,7 +17,8 @@ module ActiveAgent
|
|
17
17
|
|
18
18
|
def generate(prompt)
|
19
19
|
@prompt = prompt
|
20
|
-
|
20
|
+
|
21
|
+
# prompt_parameters(model: @model_name, messages: prompt.messages, tools: prompt.actions)
|
21
22
|
# parameters[:instructions] = prompt.instructions.content if prompt.instructions.present?
|
22
23
|
|
23
24
|
chat_prompt(parameters: prompt_parameters)
|
@@ -60,19 +61,19 @@ module ActiveAgent
|
|
60
61
|
def provider_stream
|
61
62
|
# prompt.options[:stream] will define a proc found in prompt at runtime
|
62
63
|
# config[:stream] will define a proc found in config. stream would come from an Agent class's generate_with or stream_with method calls
|
63
|
-
agent_stream = prompt.options[:stream]
|
64
|
+
agent_stream = prompt.options[:stream]
|
65
|
+
message = ActiveAgent::ActionPrompt::Message.new(content: "", role: :assistant)
|
66
|
+
@response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message: )
|
67
|
+
|
64
68
|
proc do |chunk, bytesize|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
# Call the custom stream_proc if provided
|
71
|
-
agent_stream.call(message) if agent_stream.respond_to?(:call)
|
69
|
+
if new_content = chunk.dig("choices", 0, "delta", "content")
|
70
|
+
message.content += new_content
|
71
|
+
agent_stream.call(message) if agent_stream.respond_to?(:call)
|
72
|
+
end
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
75
|
-
def prompt_parameters(model: @model_name, messages: @prompt.messages, temperature: @config["temperature"] || 0.7, tools: @prompt.actions)
|
76
|
+
def prompt_parameters(model: @prompt.options[:model] || @model_name, messages: @prompt.messages, temperature: @config["temperature"] || 0.7, tools: @prompt.actions)
|
76
77
|
{
|
77
78
|
model: model,
|
78
79
|
messages: messages,
|
@@ -82,14 +83,16 @@ module ActiveAgent
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def chat_response(response)
|
86
|
+
return @response if prompt.options[:stream]
|
87
|
+
|
85
88
|
message_json = response.dig("choices", 0, "message")
|
89
|
+
|
86
90
|
message = ActiveAgent::ActionPrompt::Message.new(
|
87
91
|
content: message_json["content"],
|
88
92
|
role: message_json["role"],
|
89
93
|
action_requested: message_json["finish_reason"] == "tool_calls",
|
90
94
|
requested_actions: handle_actions(message_json["tool_calls"])
|
91
95
|
)
|
92
|
-
|
93
96
|
update_context(prompt: prompt, message: message, response: response)
|
94
97
|
|
95
98
|
@response = ActiveAgent::GenerationProvider::Response.new(prompt: prompt, message: message, raw_response: response)
|
data/lib/active_agent/railtie.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "active_job/railtie"
|
4
4
|
require "active_agent"
|
5
|
-
require "active_agent/engine"
|
5
|
+
# require "active_agent/engine"
|
6
6
|
require "rails"
|
7
7
|
require "abstract_controller/railties/routes_helpers"
|
8
8
|
|
@@ -10,7 +10,7 @@ module ActiveAgent
|
|
10
10
|
class Railtie < Rails::Railtie # :nodoc:
|
11
11
|
config.active_agent = ActiveSupport::OrderedOptions.new
|
12
12
|
config.active_agent.preview_paths = []
|
13
|
-
config.eager_load_namespaces <<
|
13
|
+
config.eager_load_namespaces << ActiveAgent
|
14
14
|
|
15
15
|
initializer "active_agent.deprecator", before: :load_environment_config do |app|
|
16
16
|
app.deprecators[:active_agent] = ActiveAgent.deprecator
|
@@ -34,6 +34,8 @@ module ActiveAgent
|
|
34
34
|
# make sure readers methods get compiled
|
35
35
|
options.asset_host ||= app.config.asset_host
|
36
36
|
options.relative_url_root ||= app.config.relative_url_root
|
37
|
+
|
38
|
+
ActiveAgent.load_configuration(Rails.root.join('config', 'active_agent.yml'))
|
37
39
|
|
38
40
|
ActiveSupport.on_load(:active_agent) do
|
39
41
|
include AbstractController::UrlFor
|
@@ -46,20 +48,16 @@ module ActiveAgent
|
|
46
48
|
self.view_paths = ["#{Rails.root}/app/views"]
|
47
49
|
self.preview_paths |= options[:preview_paths]
|
48
50
|
|
49
|
-
if
|
50
|
-
self.
|
51
|
-
end
|
52
|
-
|
53
|
-
if options.smtp_settings
|
54
|
-
self.smtp_settings = options.smtp_settings
|
51
|
+
if generation_job = options.delete(:generation_job)
|
52
|
+
self.generation_job = generation_job.constantize
|
55
53
|
end
|
56
54
|
|
57
55
|
options.each { |k, v| send(:"#{k}=", v) }
|
58
56
|
end
|
59
57
|
|
60
58
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
61
|
-
include ActiveAgent::TestHelper
|
62
|
-
include ActiveAgent::TestCase::ClearTestDeliveries
|
59
|
+
# include ActiveAgent::TestHelper
|
60
|
+
# include ActiveAgent::TestCase::ClearTestDeliveries
|
63
61
|
end
|
64
62
|
end
|
65
63
|
|
data/lib/active_agent/version.rb
CHANGED
data/lib/activeagent.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "active_agent"
|
@@ -4,8 +4,8 @@ class ApplicationAgent < ActiveAgent::Base
|
|
4
4
|
|
5
5
|
generate_with :openai, model: "gpt-4o-mini", instructions: "You are a helpful assistant."
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def text_prompt
|
8
|
+
prompt { |format| format.text { render plain: params[:message] } }
|
9
9
|
end
|
10
10
|
end
|
11
11
|
<% 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.
|
4
|
+
version: 0.2.6.rc1
|
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-
|
11
|
+
date: 2025-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -137,8 +137,6 @@ executables: []
|
|
137
137
|
extensions: []
|
138
138
|
extra_rdoc_files: []
|
139
139
|
files:
|
140
|
-
- README.md
|
141
|
-
- Rakefile
|
142
140
|
- lib/active_agent.rb
|
143
141
|
- lib/active_agent/README.md
|
144
142
|
- lib/active_agent/action_prompt.rb
|
@@ -172,6 +170,7 @@ files:
|
|
172
170
|
- lib/active_agent/service.rb
|
173
171
|
- lib/active_agent/test_case.rb
|
174
172
|
- lib/active_agent/version.rb
|
173
|
+
- lib/activeagent.rb
|
175
174
|
- lib/generators/active_agent/USAGE
|
176
175
|
- lib/generators/active_agent/agent_generator.rb
|
177
176
|
- lib/generators/active_agent/install_generator.rb
|
@@ -182,11 +181,14 @@ files:
|
|
182
181
|
- lib/generators/active_agent/templates/agent_spec.rb.tt
|
183
182
|
- lib/generators/active_agent/templates/agent_test.rb.tt
|
184
183
|
- lib/generators/active_agent/templates/application_agent.rb.tt
|
185
|
-
|
186
|
-
homepage: https://rubygems.org/gems/activeagent
|
184
|
+
homepage: https://activeagents.ai
|
187
185
|
licenses:
|
188
186
|
- MIT
|
189
|
-
metadata:
|
187
|
+
metadata:
|
188
|
+
bug_tracker_uri: https://github.com/activeagents/activeagent/issues
|
189
|
+
documentation_uri: https://github.com/activeagents/activeagent
|
190
|
+
source_code_uri: https://github.com/activeagents/activeagent
|
191
|
+
rubygems_mfa_required: 'true'
|
190
192
|
post_install_message:
|
191
193
|
rdoc_options: []
|
192
194
|
require_paths:
|
data/README.md
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
# Active Agent
|
2
|
-
|
3
|
-
## Install
|
4
|
-
|
5
|
-
### Gemfile
|
6
|
-
`gem 'activeagent', require: 'active_agent'`
|
7
|
-
|
8
|
-
### CLI
|
9
|
-
`gem install activeagent`
|
10
|
-
|
11
|
-
### Rails Generator
|
12
|
-
After installing the gem, run the Rails installation generator:
|
13
|
-
|
14
|
-
```bash
|
15
|
-
$ rails generate active_agent:install
|
16
|
-
```
|
17
|
-
|
18
|
-
This will create:
|
19
|
-
```
|
20
|
-
create config/initializers/active_agent.rb
|
21
|
-
create config/active_agent.yml
|
22
|
-
create app/agents/application_agent.rb
|
23
|
-
create app/agents
|
24
|
-
```
|
25
|
-
|
26
|
-
- An initializer that uses default configurations
|
27
|
-
```ruby
|
28
|
-
# config/initializers/active_agent.rb
|
29
|
-
ActiveAgent.load_configuration(Rails.root.join('config', 'active_agent.yml'))
|
30
|
-
```
|
31
|
-
- A YAML configuration file for provider settings, such as OpenAI and might include environment-specific configurations:
|
32
|
-
```yaml
|
33
|
-
# config/active_agent.yml
|
34
|
-
development:
|
35
|
-
openai:
|
36
|
-
service: "OpenAI"
|
37
|
-
api_key: <%= Rails.application.credentials.dig(:openai, :api_key) %>
|
38
|
-
model: "gpt-3.5-turbo"
|
39
|
-
temperature: 0.7
|
40
|
-
|
41
|
-
production:
|
42
|
-
openai:
|
43
|
-
service: "OpenAI"
|
44
|
-
api_key: <%= Rails.application.credentials.dig(:openai, :api_key) %>
|
45
|
-
model: "gpt-3.5-turbo"
|
46
|
-
temperature: 0.7
|
47
|
-
|
48
|
-
```
|
49
|
-
- A base application agent class
|
50
|
-
```ruby
|
51
|
-
# app/agents/application_agent.rb
|
52
|
-
class ApplicationAgent < ActiveAgent::Base
|
53
|
-
layout 'agent'
|
54
|
-
|
55
|
-
def prompt
|
56
|
-
super { |format| format.text { render plain: params[:message] } }
|
57
|
-
end
|
58
|
-
```
|
59
|
-
- The agents directory structure
|
60
|
-
|
61
|
-
## Agent
|
62
|
-
Create agents that take instructions, prompts, and perform actions
|
63
|
-
|
64
|
-
### Rails Generator
|
65
|
-
To use the Rails Active Agent generator to create a new agent and the associated views for the requested action prompts:
|
66
|
-
|
67
|
-
```bash
|
68
|
-
$ rails generate active_agent:agent travel search book plans
|
69
|
-
```
|
70
|
-
This will create:
|
71
|
-
```
|
72
|
-
create app/agents/travel_agent.rb
|
73
|
-
create app/views/agents/travel/search.text.erb
|
74
|
-
create app/views/agents/travel/book.text.erb
|
75
|
-
create app/views/agents/travel/plans.text.erb
|
76
|
-
```
|
77
|
-
|
78
|
-
The generator creates:
|
79
|
-
- An agent class inheriting from ApplicationAgent
|
80
|
-
- Text template views for each action
|
81
|
-
- Action methods in the agent class for processing prompts
|
82
|
-
|
83
|
-
### Agent Actions
|
84
|
-
```ruby
|
85
|
-
class TravelAgent < ApplicationAgent
|
86
|
-
def search
|
87
|
-
|
88
|
-
prompt { |format| format.text { render plain: "Searching for travel options" } }
|
89
|
-
end
|
90
|
-
|
91
|
-
def book
|
92
|
-
prompt { |format| format.text { render plain: "Booking travel plans" } }
|
93
|
-
end
|
94
|
-
|
95
|
-
def plans
|
96
|
-
prompt { |format| format.text { render plain: "Making travel plans" } }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
```
|
100
|
-
|
101
|
-
## Action Prompt
|
102
|
-
|
103
|
-
Action Prompt provides the structured interface for composing AI interactions through messages, actions/tools, and conversation context. [Read more about Action Prompt](lib/active_agent/action_prompt/README.md)
|
104
|
-
|
105
|
-
```ruby
|
106
|
-
agent.prompt(message: "Find hotels in Paris",
|
107
|
-
actions: [{name: "search", params: {query: "hotels paris"}}])
|
108
|
-
```
|
109
|
-
|
110
|
-
The prompt interface manages:
|
111
|
-
- Message content and roles (system/user/assistant)
|
112
|
-
- Action/tool definitions and requests
|
113
|
-
- Headers and context tracking
|
114
|
-
- Content types and multipart handling
|
115
|
-
|
116
|
-
### Generation Provider
|
117
|
-
|
118
|
-
Generation Provider defines how prompts are sent to AI services for completion and embedding generation. [Read more about Generation Providers](lib/active_agent/generation_provider/README.md)
|
119
|
-
|
120
|
-
```ruby
|
121
|
-
class VacationAgent < ActiveAgent::Base
|
122
|
-
# Try not to get too model-rous with the parameters!
|
123
|
-
generate_with :openai,
|
124
|
-
model: "gpt-4",
|
125
|
-
temperature: 0.7
|
126
|
-
|
127
|
-
# Embed yourself in the joy of vector search
|
128
|
-
embed_with :openai,
|
129
|
-
model: "text-embedding-ada-002"
|
130
|
-
end
|
131
|
-
```
|
132
|
-
|
133
|
-
Providers handle:
|
134
|
-
- API client configuration
|
135
|
-
- Prompt/completion generation
|
136
|
-
- Stream processing
|
137
|
-
- Embedding generation
|
138
|
-
- Context management
|
139
|
-
- Error handling
|
140
|
-
|
141
|
-
### Queue Generation
|
142
|
-
|
143
|
-
Active Agent also supports queued generation with Active Job using a common Generation Job interface.
|
144
|
-
|
145
|
-
### Perform actions
|
146
|
-
|
147
|
-
Active Agents can define methods that are autoloaded as callable tools. These actions’ default schema will be provided to the agent’s context as part of the prompt request to the Generation Provider.
|
148
|
-
|
149
|
-
## Actions
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
def get_cat_image_base64
|
153
|
-
uri = URI("https://cataas.com/cat")
|
154
|
-
response = Net::HTTP.get_response(uri)
|
155
|
-
|
156
|
-
if response.is_a?(Net::HTTPSuccess)
|
157
|
-
image_data = response.body
|
158
|
-
Base64.strict_encode64(image_data)
|
159
|
-
else
|
160
|
-
raise "Failed to fetch cat image. Status code: #{response.code}"
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
class SupportAgent < ActiveAgent
|
165
|
-
generate_with :openai,
|
166
|
-
model: "gpt-4o",
|
167
|
-
instructions: "Help people with their problems",
|
168
|
-
temperature: 0.7
|
169
|
-
|
170
|
-
def get_cat_image
|
171
|
-
prompt { |format| format.text { render plain: get_cat_image_base64 } }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
```
|
175
|
-
|
176
|
-
## Prompts
|
177
|
-
|
178
|
-
### Basic
|
179
|
-
|
180
|
-
#### Plain text prompt and response templates
|
181
|
-
|
182
|
-
### HTML
|
183
|
-
|
184
|
-
### Action Schema JSON
|
185
|
-
|
186
|
-
response = SupportAgent.prompt(‘show me a picture of a cat’).generate_now
|
187
|
-
|
188
|
-
response.message
|
data/Rakefile
DELETED