activeagent 1.0.1 → 1.0.3
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/README.md +10 -4
- data/lib/active_agent/base.rb +3 -2
- data/lib/active_agent/concerns/provider.rb +6 -2
- data/lib/active_agent/concerns/rescue.rb +39 -0
- data/lib/active_agent/concerns/streaming.rb +2 -1
- data/lib/active_agent/concerns/view.rb +1 -1
- data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/api/traces_controller.rb +117 -0
- data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/application_controller.rb +54 -0
- data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/dashboard_controller.rb +126 -0
- data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/traces_controller.rb +103 -0
- data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/agent_execution_job.rb +56 -0
- data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/application_job.rb +14 -0
- data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/sandbox_cleanup_job.rb +49 -0
- data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/sandbox_provision_job.rb +65 -0
- data/lib/active_agent/dashboard/app/jobs/active_agent/process_telemetry_traces_job.rb +77 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent.rb +256 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_run.rb +113 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_template.rb +208 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_version.rb +60 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/application_record.rb +46 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/recording_action.rb +125 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/recording_snapshot.rb +83 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_run.rb +52 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb +169 -0
- data/lib/active_agent/dashboard/app/models/active_agent/dashboard/session_recording.rb +193 -0
- data/lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb +198 -0
- data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/_trace_detail.html.erb +105 -0
- data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/index.html.erb +135 -0
- data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/metrics.html.erb +143 -0
- data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/show.html.erb +36 -0
- data/lib/active_agent/dashboard/app/views/layouts/active_agent/dashboard/application.html.erb +94 -0
- data/lib/active_agent/dashboard/config/routes.rb +78 -0
- data/lib/active_agent/dashboard/engine.rb +39 -0
- data/lib/active_agent/dashboard.rb +151 -0
- data/lib/active_agent/providers/_base_provider.rb +2 -1
- data/lib/active_agent/providers/anthropic/request.rb +3 -1
- data/lib/active_agent/providers/anthropic/transforms.rb +88 -0
- data/lib/active_agent/providers/anthropic_provider.rb +14 -4
- data/lib/active_agent/providers/azure/_types.rb +5 -0
- data/lib/active_agent/providers/azure/options.rb +111 -0
- data/lib/active_agent/providers/azure_open_ai_provider.rb +2 -0
- data/lib/active_agent/providers/azure_openai_provider.rb +2 -0
- data/lib/active_agent/providers/azure_provider.rb +133 -0
- data/lib/active_agent/providers/azureopenai_provider.rb +2 -0
- data/lib/active_agent/providers/bedrock/_types.rb +8 -0
- data/lib/active_agent/providers/bedrock/bearer_client.rb +109 -0
- data/lib/active_agent/providers/bedrock/options.rb +77 -0
- data/lib/active_agent/providers/bedrock_provider.rb +84 -0
- data/lib/active_agent/providers/common/messages/_types.rb +6 -2
- data/lib/active_agent/providers/concerns/exception_handler.rb +1 -0
- data/lib/active_agent/providers/gemini/_types.rb +19 -0
- data/lib/active_agent/providers/gemini/options.rb +41 -0
- data/lib/active_agent/providers/gemini_provider.rb +94 -0
- data/lib/active_agent/providers/mock/request.rb +1 -4
- data/lib/active_agent/providers/open_ai/chat/transforms.rb +37 -1
- data/lib/active_agent/providers/open_ai/chat_provider.rb +5 -3
- data/lib/active_agent/providers/requesty/_types.rb +16 -0
- data/lib/active_agent/providers/requesty/options.rb +39 -0
- data/lib/active_agent/providers/requesty_provider.rb +63 -0
- data/lib/active_agent/providers/ruby_llm/_types.rb +77 -0
- data/lib/active_agent/providers/ruby_llm/embedding_request.rb +16 -0
- data/lib/active_agent/providers/ruby_llm/messages/_types.rb +109 -0
- data/lib/active_agent/providers/ruby_llm/messages/assistant.rb +27 -0
- data/lib/active_agent/providers/ruby_llm/messages/base.rb +48 -0
- data/lib/active_agent/providers/ruby_llm/messages/system.rb +18 -0
- data/lib/active_agent/providers/ruby_llm/messages/tool.rb +24 -0
- data/lib/active_agent/providers/ruby_llm/messages/user.rb +18 -0
- data/lib/active_agent/providers/ruby_llm/options.rb +28 -0
- data/lib/active_agent/providers/ruby_llm/request.rb +30 -0
- data/lib/active_agent/providers/ruby_llm/tool_proxy.rb +45 -0
- data/lib/active_agent/providers/ruby_llm_provider.rb +407 -0
- data/lib/active_agent/railtie.rb +32 -1
- data/lib/active_agent/telemetry/configuration.rb +213 -0
- data/lib/active_agent/telemetry/instrumentation.rb +155 -0
- data/lib/active_agent/telemetry/reporter.rb +176 -0
- data/lib/active_agent/telemetry/span.rb +267 -0
- data/lib/active_agent/telemetry/tracer.rb +184 -0
- data/lib/active_agent/telemetry.rb +162 -0
- data/lib/active_agent/version.rb +1 -1
- data/lib/active_agent.rb +2 -0
- data/lib/generators/active_agent/dashboard/install/install_generator.rb +96 -0
- data/lib/generators/active_agent/dashboard/install/templates/initializer.rb +89 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_runs.rb +42 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_templates.rb +38 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_versions.rb +22 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agents.rb +53 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_sandbox_runs.rb +28 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_sandbox_sessions.rb +43 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_session_recordings.rb +44 -0
- data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_telemetry_traces.rb +56 -0
- data/lib/generators/active_agent/dashboard/install_generator.rb +64 -0
- data/lib/generators/active_agent/dashboard/templates/active_agent_dashboard.rb.erb +30 -0
- data/lib/generators/active_agent/dashboard/templates/create_active_agent_telemetry_traces.rb.erb +30 -0
- metadata +120 -17
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Load all message classes
|
|
4
|
+
require_relative "base"
|
|
5
|
+
require_relative "system"
|
|
6
|
+
require_relative "user"
|
|
7
|
+
require_relative "assistant"
|
|
8
|
+
require_relative "tool"
|
|
9
|
+
|
|
10
|
+
module ActiveAgent
|
|
11
|
+
module Providers
|
|
12
|
+
module RubyLLM
|
|
13
|
+
module Messages
|
|
14
|
+
# Type for Messages array
|
|
15
|
+
class MessagesType < ActiveModel::Type::Value
|
|
16
|
+
def initialize
|
|
17
|
+
super
|
|
18
|
+
@message_type = MessageType.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def cast(value)
|
|
22
|
+
case value
|
|
23
|
+
when Array
|
|
24
|
+
value.map { |v| @message_type.cast(v) }
|
|
25
|
+
when nil
|
|
26
|
+
nil
|
|
27
|
+
else
|
|
28
|
+
raise ArgumentError, "Cannot cast #{value.class} to Messages array"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def serialize(value)
|
|
33
|
+
case value
|
|
34
|
+
when Array
|
|
35
|
+
grouped = []
|
|
36
|
+
|
|
37
|
+
value.each do |message|
|
|
38
|
+
if grouped.empty? || grouped.last.role != message.role
|
|
39
|
+
grouped << message.deep_dup
|
|
40
|
+
else
|
|
41
|
+
grouped.last.content += message.content.deep_dup
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
grouped.map { |v| @message_type.serialize(v) }
|
|
46
|
+
when nil
|
|
47
|
+
nil
|
|
48
|
+
else
|
|
49
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def deserialize(value)
|
|
54
|
+
cast(value)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Type for individual Message
|
|
59
|
+
class MessageType < ActiveModel::Type::Value
|
|
60
|
+
def cast(value)
|
|
61
|
+
case value
|
|
62
|
+
when Base
|
|
63
|
+
value
|
|
64
|
+
when String
|
|
65
|
+
User.new(content: value)
|
|
66
|
+
when Hash
|
|
67
|
+
hash = value.deep_symbolize_keys
|
|
68
|
+
role = hash[:role]&.to_sym
|
|
69
|
+
|
|
70
|
+
case role
|
|
71
|
+
when :user, nil
|
|
72
|
+
User.new(**hash)
|
|
73
|
+
when :assistant
|
|
74
|
+
Assistant.new(**hash)
|
|
75
|
+
when :system
|
|
76
|
+
System.new(**hash)
|
|
77
|
+
when :tool
|
|
78
|
+
Tool.new(**hash)
|
|
79
|
+
else
|
|
80
|
+
raise ArgumentError, "Unknown message role: #{role}"
|
|
81
|
+
end
|
|
82
|
+
when nil
|
|
83
|
+
nil
|
|
84
|
+
else
|
|
85
|
+
raise ArgumentError, "Cannot cast #{value.class} to Message"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def serialize(value)
|
|
90
|
+
case value
|
|
91
|
+
when Base
|
|
92
|
+
value.serialize
|
|
93
|
+
when Hash
|
|
94
|
+
value
|
|
95
|
+
when nil
|
|
96
|
+
nil
|
|
97
|
+
else
|
|
98
|
+
raise ArgumentError, "Cannot serialize #{value.class}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def deserialize(value)
|
|
103
|
+
cast(value)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Messages
|
|
9
|
+
# Assistant message for RubyLLM provider.
|
|
10
|
+
#
|
|
11
|
+
# Drops extra fields that are part of the API response but not
|
|
12
|
+
# part of the message structure.
|
|
13
|
+
class Assistant < Base
|
|
14
|
+
attribute :role, :string, as: "assistant"
|
|
15
|
+
attribute :content
|
|
16
|
+
attribute :tool_calls
|
|
17
|
+
|
|
18
|
+
validates :content, presence: true, unless: :tool_calls
|
|
19
|
+
|
|
20
|
+
# Drop API response fields that aren't part of the message
|
|
21
|
+
drop_attributes :usage, :id, :model, :stop_reason, :stop_sequence, :type,
|
|
22
|
+
:input_tokens, :output_tokens
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_agent/providers/common/model"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Messages
|
|
9
|
+
# Base class for RubyLLM messages.
|
|
10
|
+
class Base < Common::BaseModel
|
|
11
|
+
attribute :role, :string
|
|
12
|
+
attribute :content
|
|
13
|
+
|
|
14
|
+
validates :role, presence: true
|
|
15
|
+
|
|
16
|
+
# Converts to common format.
|
|
17
|
+
#
|
|
18
|
+
# @return [Hash] message in canonical format with role and text content
|
|
19
|
+
def to_common
|
|
20
|
+
{
|
|
21
|
+
role: role,
|
|
22
|
+
content: extract_text_content,
|
|
23
|
+
name: nil
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Extracts text content from the content structure.
|
|
30
|
+
#
|
|
31
|
+
# @return [String] extracted text content
|
|
32
|
+
def extract_text_content
|
|
33
|
+
case content
|
|
34
|
+
when String
|
|
35
|
+
content
|
|
36
|
+
when Array
|
|
37
|
+
content.select { |block| block.is_a?(Hash) && block[:type] == "text" }
|
|
38
|
+
.map { |block| block[:text] }
|
|
39
|
+
.join("\n")
|
|
40
|
+
else
|
|
41
|
+
content.to_s
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Messages
|
|
9
|
+
# System message for RubyLLM provider.
|
|
10
|
+
class System < Base
|
|
11
|
+
attribute :role, :string, as: "system"
|
|
12
|
+
|
|
13
|
+
validates :content, presence: true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Messages
|
|
9
|
+
# Tool result message for RubyLLM provider.
|
|
10
|
+
class Tool < Base
|
|
11
|
+
attribute :role, :string, as: "tool"
|
|
12
|
+
attribute :content
|
|
13
|
+
attribute :tool_call_id, :string
|
|
14
|
+
|
|
15
|
+
def to_common
|
|
16
|
+
common = super
|
|
17
|
+
common[:tool_call_id] = tool_call_id if tool_call_id
|
|
18
|
+
common
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
module Messages
|
|
9
|
+
# User message for RubyLLM provider.
|
|
10
|
+
class User < Base
|
|
11
|
+
attribute :role, :string, as: "user"
|
|
12
|
+
|
|
13
|
+
validates :content, presence: true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_agent/providers/common/model"
|
|
4
|
+
|
|
5
|
+
module ActiveAgent
|
|
6
|
+
module Providers
|
|
7
|
+
module RubyLLM
|
|
8
|
+
# Configuration options for the RubyLLM provider.
|
|
9
|
+
#
|
|
10
|
+
# RubyLLM manages its own API keys via RubyLLM.configure, so no
|
|
11
|
+
# provider-specific API key attributes are needed here.
|
|
12
|
+
class Options < Common::BaseModel
|
|
13
|
+
attribute :model, :string
|
|
14
|
+
attribute :temperature, :float
|
|
15
|
+
attribute :max_tokens, :integer
|
|
16
|
+
|
|
17
|
+
def initialize(kwargs = {})
|
|
18
|
+
kwargs = kwargs.deep_symbolize_keys if kwargs.respond_to?(:deep_symbolize_keys)
|
|
19
|
+
super(**deep_compact(kwargs))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def extra_headers
|
|
23
|
+
{}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_agent/providers/common/model"
|
|
4
|
+
|
|
5
|
+
require_relative "messages/_types"
|
|
6
|
+
|
|
7
|
+
module ActiveAgent
|
|
8
|
+
module Providers
|
|
9
|
+
module RubyLLM
|
|
10
|
+
# Request model for RubyLLM provider.
|
|
11
|
+
class Request < Common::BaseModel
|
|
12
|
+
attribute :model, :string
|
|
13
|
+
attribute :messages, Messages::MessagesType.new
|
|
14
|
+
attribute :instructions
|
|
15
|
+
attribute :tools
|
|
16
|
+
attribute :tool_choice
|
|
17
|
+
attribute :temperature, :float
|
|
18
|
+
attribute :max_tokens, :integer
|
|
19
|
+
attribute :stream, :boolean, default: false
|
|
20
|
+
attribute :response_format
|
|
21
|
+
|
|
22
|
+
# Common Format Compatibility
|
|
23
|
+
def message=(value)
|
|
24
|
+
self.messages ||= []
|
|
25
|
+
self.messages << value
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveAgent
|
|
4
|
+
module Providers
|
|
5
|
+
module RubyLLM
|
|
6
|
+
# Bridges ActiveAgent tool definitions to RubyLLM's expected tool interface.
|
|
7
|
+
# RubyLLM expects tools as { "name" => tool } where each tool responds to
|
|
8
|
+
# #name, #description, #parameters, #params_schema, and #provider_params.
|
|
9
|
+
class ToolProxy
|
|
10
|
+
attr_reader :name, :description, :parameters
|
|
11
|
+
|
|
12
|
+
def initialize(name:, description:, parameters:)
|
|
13
|
+
@name = name
|
|
14
|
+
@description = description
|
|
15
|
+
@parameters = parameters
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# RubyLLM checks this first; returns the JSON Schema directly so
|
|
19
|
+
# RubyLLM doesn't try to interpret our parameters as Parameter objects.
|
|
20
|
+
# Deep-stringifies keys to match RubyLLM's internal schema format.
|
|
21
|
+
def params_schema
|
|
22
|
+
deep_stringify(@parameters) if @parameters.is_a?(Hash) && @parameters.any?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# RubyLLM merges this into the tool definition
|
|
26
|
+
def provider_params
|
|
27
|
+
{}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def deep_stringify(obj)
|
|
33
|
+
case obj
|
|
34
|
+
when Hash
|
|
35
|
+
obj.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify(v) }
|
|
36
|
+
when Array
|
|
37
|
+
obj.map { |v| deep_stringify(v) }
|
|
38
|
+
else
|
|
39
|
+
obj
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|