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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -4
  3. data/lib/active_agent/base.rb +3 -2
  4. data/lib/active_agent/concerns/provider.rb +6 -2
  5. data/lib/active_agent/concerns/rescue.rb +39 -0
  6. data/lib/active_agent/concerns/streaming.rb +2 -1
  7. data/lib/active_agent/concerns/view.rb +1 -1
  8. data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/api/traces_controller.rb +117 -0
  9. data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/application_controller.rb +54 -0
  10. data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/dashboard_controller.rb +126 -0
  11. data/lib/active_agent/dashboard/app/controllers/active_agent/dashboard/traces_controller.rb +103 -0
  12. data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/agent_execution_job.rb +56 -0
  13. data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/application_job.rb +14 -0
  14. data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/sandbox_cleanup_job.rb +49 -0
  15. data/lib/active_agent/dashboard/app/jobs/active_agent/dashboard/sandbox_provision_job.rb +65 -0
  16. data/lib/active_agent/dashboard/app/jobs/active_agent/process_telemetry_traces_job.rb +77 -0
  17. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent.rb +256 -0
  18. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_run.rb +113 -0
  19. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_template.rb +208 -0
  20. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/agent_version.rb +60 -0
  21. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/application_record.rb +46 -0
  22. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/recording_action.rb +125 -0
  23. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/recording_snapshot.rb +83 -0
  24. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_run.rb +52 -0
  25. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/sandbox_session.rb +169 -0
  26. data/lib/active_agent/dashboard/app/models/active_agent/dashboard/session_recording.rb +193 -0
  27. data/lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb +198 -0
  28. data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/_trace_detail.html.erb +105 -0
  29. data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/index.html.erb +135 -0
  30. data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/metrics.html.erb +143 -0
  31. data/lib/active_agent/dashboard/app/views/active_agent/dashboard/traces/show.html.erb +36 -0
  32. data/lib/active_agent/dashboard/app/views/layouts/active_agent/dashboard/application.html.erb +94 -0
  33. data/lib/active_agent/dashboard/config/routes.rb +78 -0
  34. data/lib/active_agent/dashboard/engine.rb +39 -0
  35. data/lib/active_agent/dashboard.rb +151 -0
  36. data/lib/active_agent/providers/_base_provider.rb +2 -1
  37. data/lib/active_agent/providers/anthropic/request.rb +3 -1
  38. data/lib/active_agent/providers/anthropic/transforms.rb +88 -0
  39. data/lib/active_agent/providers/anthropic_provider.rb +14 -4
  40. data/lib/active_agent/providers/azure/_types.rb +5 -0
  41. data/lib/active_agent/providers/azure/options.rb +111 -0
  42. data/lib/active_agent/providers/azure_open_ai_provider.rb +2 -0
  43. data/lib/active_agent/providers/azure_openai_provider.rb +2 -0
  44. data/lib/active_agent/providers/azure_provider.rb +133 -0
  45. data/lib/active_agent/providers/azureopenai_provider.rb +2 -0
  46. data/lib/active_agent/providers/bedrock/_types.rb +8 -0
  47. data/lib/active_agent/providers/bedrock/bearer_client.rb +109 -0
  48. data/lib/active_agent/providers/bedrock/options.rb +77 -0
  49. data/lib/active_agent/providers/bedrock_provider.rb +84 -0
  50. data/lib/active_agent/providers/common/messages/_types.rb +6 -2
  51. data/lib/active_agent/providers/concerns/exception_handler.rb +1 -0
  52. data/lib/active_agent/providers/gemini/_types.rb +19 -0
  53. data/lib/active_agent/providers/gemini/options.rb +41 -0
  54. data/lib/active_agent/providers/gemini_provider.rb +94 -0
  55. data/lib/active_agent/providers/mock/request.rb +1 -4
  56. data/lib/active_agent/providers/open_ai/chat/transforms.rb +37 -1
  57. data/lib/active_agent/providers/open_ai/chat_provider.rb +5 -3
  58. data/lib/active_agent/providers/requesty/_types.rb +16 -0
  59. data/lib/active_agent/providers/requesty/options.rb +39 -0
  60. data/lib/active_agent/providers/requesty_provider.rb +63 -0
  61. data/lib/active_agent/providers/ruby_llm/_types.rb +77 -0
  62. data/lib/active_agent/providers/ruby_llm/embedding_request.rb +16 -0
  63. data/lib/active_agent/providers/ruby_llm/messages/_types.rb +109 -0
  64. data/lib/active_agent/providers/ruby_llm/messages/assistant.rb +27 -0
  65. data/lib/active_agent/providers/ruby_llm/messages/base.rb +48 -0
  66. data/lib/active_agent/providers/ruby_llm/messages/system.rb +18 -0
  67. data/lib/active_agent/providers/ruby_llm/messages/tool.rb +24 -0
  68. data/lib/active_agent/providers/ruby_llm/messages/user.rb +18 -0
  69. data/lib/active_agent/providers/ruby_llm/options.rb +28 -0
  70. data/lib/active_agent/providers/ruby_llm/request.rb +30 -0
  71. data/lib/active_agent/providers/ruby_llm/tool_proxy.rb +45 -0
  72. data/lib/active_agent/providers/ruby_llm_provider.rb +407 -0
  73. data/lib/active_agent/railtie.rb +32 -1
  74. data/lib/active_agent/telemetry/configuration.rb +213 -0
  75. data/lib/active_agent/telemetry/instrumentation.rb +155 -0
  76. data/lib/active_agent/telemetry/reporter.rb +176 -0
  77. data/lib/active_agent/telemetry/span.rb +267 -0
  78. data/lib/active_agent/telemetry/tracer.rb +184 -0
  79. data/lib/active_agent/telemetry.rb +162 -0
  80. data/lib/active_agent/version.rb +1 -1
  81. data/lib/active_agent.rb +2 -0
  82. data/lib/generators/active_agent/dashboard/install/install_generator.rb +96 -0
  83. data/lib/generators/active_agent/dashboard/install/templates/initializer.rb +89 -0
  84. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_runs.rb +42 -0
  85. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_templates.rb +38 -0
  86. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agent_versions.rb +22 -0
  87. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_agents.rb +53 -0
  88. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_sandbox_runs.rb +28 -0
  89. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_sandbox_sessions.rb +43 -0
  90. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_session_recordings.rb +44 -0
  91. data/lib/generators/active_agent/dashboard/install/templates/migrations/create_active_agent_telemetry_traces.rb +56 -0
  92. data/lib/generators/active_agent/dashboard/install_generator.rb +64 -0
  93. data/lib/generators/active_agent/dashboard/templates/active_agent_dashboard.rb.erb +30 -0
  94. data/lib/generators/active_agent/dashboard/templates/create_active_agent_telemetry_traces.rb.erb +30 -0
  95. 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