activeagent 1.9.3 → 1.9.4

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: a7ecc64cad33188dd3cdfc563b553e49d0a05d42192698365a467061e6bb6d59
4
- data.tar.gz: c3923cee8e401e17e3170c28f2fc83d8c290d70c5a4bc4d301951031d7d9cf43
3
+ metadata.gz: 715323643179a060b32d624ba906586778645e818c0436d4e4efe9ea6585847e
4
+ data.tar.gz: 3efe81e8a8d5357baf0f46adcfa5ce2fedd96234bb8ed603ffae63bac17bec58
5
5
  SHA512:
6
- metadata.gz: 66e3244ce04d56625f880e26c18cbe3f353f35eca2f4dd5922a1adafb1d542ee5216065401e7ddbbe88cccc1c40336076ab6d4a30d54a5360846cad595ae9717
7
- data.tar.gz: b023e5fe43f6674b7040086cc5a47c19fffc4bf3e919d0bb0ab0138d5c4839d3463f09e5a66d7047e4e28262628465a066b343ee76a503732b803ddc5d270bff
6
+ metadata.gz: 4a0ca1235fb0e8290ad261b61d77e38b4ee87372158384644612d54e81742f9f743968c8b8fa2c4e5cbebd57b62cdba7b0b0efbede6b3ad78176a7d7cca8dc37
7
+ data.tar.gz: 8fc1c553e0a008287280492dc401efccf1fdd675417985ef8acd8df3cb86ebe263a7cf6066b1740c8c387c1eb6de92ffffe428c5024b33a3ddf0464e729202a3
data/CHANGELOG.md CHANGED
@@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.4] - 2026-10-25
9
+
10
+ ### Added
11
+
12
+ - **Host links in the dashboard's user menu** (`actionagent`).
13
+ `ActionAgent.user_menu_links` takes an Array of `{ label:, href: }` or a
14
+ Proc receiving the signed-in user and the current owner, and the header's
15
+ avatar menu lists them above "Sign out". A hosted platform points them at
16
+ its workspace, members and account settings pages, and shows its admin
17
+ pages to the users who may use them; a self-hosted install leaves it unset
18
+ and sees the menu it had. Malformed entries are dropped and a raising Proc
19
+ is logged, so the menu seam cannot take the dashboard down.
20
+
21
+ ### Fixed
22
+
23
+ - **Keep the trace console usable offline** (`actionagent`). The console
24
+ ships its own inline styles and uses native details and ordinary links
25
+ instead of CDN-hosted Tailwind, Turbo and Stimulus. Automatic refresh is
26
+ opt-in (30 or 60 seconds) and uses the browser's refresh mechanism;
27
+ expanding a trace no longer depends on JavaScript or a host asset pipeline.
28
+ - **Discover and call generated agent previews** (`activeagent`). TestUnit
29
+ writes previews under `test/agents/previews`, with current URLs and query
30
+ parameters passed to the agent. Discovery checks for newly added files,
31
+ and the default image interceptor accepts generation objects.
32
+
33
+ - **Restore Rails browser previews** (`activeagent`). `/rails/agents` lists
34
+ previews and renders their prompt requests without executing a provider.
35
+ Namespaced actions and Markdown downloads work, unknown actions return
36
+ 404, and all endpoints enforce Rails' local-request restriction. Preview
37
+ directories participate in development reloading, including configured
38
+ paths and the legacy `test/docs/previews` directory. The dashboard gem is
39
+ not needed; the routes remain disabled outside development by default.
40
+
41
+ - **Generate runnable agent tests** (`activeagent`). TestUnit agent tests
42
+ inherit from `ActiveSupport::TestCase` instead of the nonexistent
43
+ `ActiveAgent::TestCase`. Plain and namespaced agents, including agents
44
+ without actions, can load in a Rails host without calling a provider.
45
+
46
+ ### Changed
47
+
48
+ - **One badge for every status and message role in the dashboard**
49
+ (`actionagent`). The agent cards' status pill and provider chip, the run
50
+ and sandbox session status pills (Agent Interactions, the sandbox runner)
51
+ and the message role pills in conversation streams all render through the
52
+ shared `Badge` (soft tint, strong mono text, radius 4) with one status
53
+ tone map (`statusTone`) and one role map (`roleBadge`), so an `active`
54
+ agent, a `complete` run and an `Assistant` turn look the same wherever
55
+ they appear and follow the dark theme, which the cards' Tailwind pills
56
+ did not. Two tones join the tokens for the system and developer roles.
57
+
8
58
  ## [1.9.3] - 2026-10-21
9
59
 
10
60
  Releases `activeagent` and `actionagent` 1.9.3, with the matching browser
@@ -68,7 +68,7 @@ module ActiveAgent
68
68
  class << self
69
69
  # Returns all agent preview classes.
70
70
  def all
71
- load_previews if descendants.empty?
71
+ load_previews
72
72
  descendants.sort_by { |agent| agent.name.titleize }
73
73
  end
74
74
 
@@ -111,7 +111,7 @@ module ActiveAgent
111
111
 
112
112
  def load_previews
113
113
  preview_paths.each do |preview_path|
114
- Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require file }
114
+ Dir["#{preview_path}/**/*_preview.rb"].sort.each { |file| require_dependency file }
115
115
  end
116
116
  end
117
117
 
@@ -58,6 +58,13 @@ module ActiveAgent
58
58
  "--color-info" => "#3b82f6",
59
59
  "--color-info-soft" => "#dbeafe",
60
60
  "--color-info-text" => "#1e40af",
61
+ # The system and developer message roles: badge tones like the four above.
62
+ "--color-system" => "#8b5cf6",
63
+ "--color-system-soft" => "#ede9fe",
64
+ "--color-system-text" => "#6d28d9",
65
+ "--color-dev" => "#14b8a6",
66
+ "--color-dev-soft" => "#ccfbf1",
67
+ "--color-dev-text" => "#0f766e",
61
68
 
62
69
  # Trace span colors (observability)
63
70
  "--span-root" => "#9ca3af",
@@ -111,7 +118,11 @@ module ActiveAgent
111
118
  "--color-error-soft" => "rgba(220,38,38,0.15)",
112
119
  "--color-error-text" => "#f87171",
113
120
  "--color-info-soft" => "rgba(59,130,246,0.15)",
114
- "--color-info-text" => "#93c5fd"
121
+ "--color-info-text" => "#93c5fd",
122
+ "--color-system-soft" => "rgba(139,92,246,0.15)",
123
+ "--color-system-text" => "#c4b5fd",
124
+ "--color-dev-soft" => "rgba(20,184,166,0.15)",
125
+ "--color-dev-text" => "#5eead4"
115
126
  }.freeze
116
127
 
117
128
  # One CSS rule declaring `tokens` as custom properties on `scope`, with
@@ -28,6 +28,7 @@ module ActiveAgent
28
28
  end
29
29
 
30
30
  def transform! # :nodoc:
31
+ return context unless context.respond_to?(:html_part)
31
32
  return context if html_part.blank?
32
33
 
33
34
  html_part.body = html_part.decoded.gsub(PATTERN) do |match|
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>ActiveAgent Previews</title>
7
+ <style>
8
+ body { color-scheme: light dark; font: 16px/1.5 system-ui, sans-serif; max-width: 1000px; padding: 1rem; margin: auto; }
9
+ pre { white-space: pre-wrap; overflow-wrap: anywhere; border: 1px solid; border-radius: .25rem; padding: 1rem; }
10
+ a { text-underline-offset: .2em; }
11
+ </style>
12
+ </head>
13
+ <body>
14
+ <nav><%= link_to "All agent previews", rails_agent_previews_path %></nav>
15
+ <%= yield %>
16
+ </body>
17
+ </html>
@@ -0,0 +1,14 @@
1
+ <h1>Agent Previews</h1>
2
+ <% if @previews.empty? %>
3
+ <p>No previews found. Generate an agent or add an ActiveAgent::Preview subclass under test/agents/previews.</p>
4
+ <% end %>
5
+ <% @previews.each do |preview| %>
6
+ <section>
7
+ <h2><%= preview.preview_name %></h2>
8
+ <ul>
9
+ <% preview.prompts.each do |prompt| %>
10
+ <li><%= link_to prompt, rails_agent_preview_path("#{preview.preview_name}/#{prompt}") %></li>
11
+ <% end %>
12
+ </ul>
13
+ </section>
14
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <h1><%= @preview.preview_name %> / <%= @prompt %></h1>
2
+ <p><%= link_to "Download Markdown", "#{download_rails_agent_preview_path("#{@preview.preview_name}/#{@prompt}")}?#{request.query_parameters.to_query}" %></p>
3
+ <pre><%= @content %></pre>
@@ -6,6 +6,8 @@ require "active_agent"
6
6
  require "active_agent/railtie/schema_generator_extension"
7
7
  require "abstract_controller/railties/routes_helpers"
8
8
 
9
+ Rails.autoload :AgentsController, "rails/agents_controller"
10
+
9
11
  module ActiveAgent
10
12
  class Railtie < Rails::Railtie # :nodoc:
11
13
  config.active_agent = ActiveSupport::OrderedOptions.new
@@ -101,8 +103,12 @@ module ActiveAgent
101
103
  end
102
104
 
103
105
  initializer "active_agent.set_autoload_paths", before: :set_autoload_paths do |app|
104
- # options = app.config.active_agent
105
- # app.config.paths["test/agents/previews"].concat(options.preview_paths)
106
+ options = app.config.active_agent
107
+ options.preview_paths |= [ "#{app.root}/test/agents/previews", "#{app.root}/test/docs/previews" ]
108
+ # This runs before set_configs assigns show_previews its development default.
109
+ if options.show_previews.nil? ? Rails.env.development? : options.show_previews
110
+ app.config.autoload_paths.concat(options.preview_paths)
111
+ end
106
112
  end
107
113
 
108
114
  initializer "active_agent.compile_config_methods" do
@@ -132,9 +138,9 @@ module ActiveAgent
132
138
 
133
139
  if options.show_previews
134
140
  app.routes.prepend do
135
- get "/rails/agents" => "rails/agents#index", :internal => true
136
- get "/rails/agents/download/*path" => "rails/agents#download", :internal => true
137
- get "/rails/agents/*path" => "rails/agents#preview", :internal => true
141
+ get "/rails/agents" => "rails/agents#index", :internal => true, :as => :rails_agent_previews
142
+ get "/rails/agents/download/*path" => "rails/agents#download", :internal => true, :as => :download_rails_agent_preview, :format => false
143
+ get "/rails/agents/*path" => "rails/agents#preview", :internal => true, :as => :rails_agent_preview, :format => false
138
144
  end
139
145
  end
140
146
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveAgent
2
- VERSION = "1.9.3"
2
+ VERSION = "1.9.4"
3
3
  end
@@ -17,7 +17,7 @@ module TestUnit # :nodoc:
17
17
  end
18
18
 
19
19
  def create_preview_files
20
- template "preview.rb", File.join("test/docs/previews", class_path, "#{file_name}_agent_preview.rb")
20
+ template "preview.rb", File.join("test/agents/previews", class_path, "#{file_name}_agent_preview.rb")
21
21
  end
22
22
 
23
23
  private
@@ -1,7 +1,7 @@
1
1
  require "test_helper"
2
2
 
3
3
  <% module_namespacing do -%>
4
- class <%= class_name %>AgentTest < ActiveAgent::TestCase
4
+ class <%= class_name %>AgentTest < ActiveSupport::TestCase
5
5
  <% actions.each_with_index do |action, index| -%>
6
6
  <% if index != 0 -%>
7
7
 
@@ -1,13 +1,13 @@
1
1
  <% module_namespacing do -%>
2
- # Preview all agent views/prompts templates at http://localhost:3000/active_agent/agents/<%= file_path %>_agent
2
+ # Preview all agent views/prompts templates at http://localhost:3000/rails/agents/<%= file_path %>_agent
3
3
  class <%= class_name %>AgentPreview < ActiveAgent::Preview
4
4
  <% actions.each_with_index do |action, index| -%>
5
5
  <% if index != 0 -%>
6
6
 
7
7
  <% end -%>
8
- # Preview this email at http://localhost:3000/active_agent/agents/<%= file_path %>_agent/<%= action %>
8
+ # Preview this prompt at http://localhost:3000/rails/agents/<%= file_path %>_agent/<%= action %>
9
9
  def <%= action %>
10
- <%= class_name %>Agent.<%= action %>
10
+ <%= class_name %>Agent.with(params).<%= action %>
11
11
  end
12
12
  <% end -%>
13
13
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/application_controller"
4
+
5
+ class Rails::AgentsController < Rails::ApplicationController # :nodoc:
6
+ prepend_view_path File.expand_path("../active_agent/preview/templates", __dir__)
7
+ layout "active_agent/preview"
8
+ before_action :require_local!
9
+
10
+ def index
11
+ @previews = ActiveAgent::Preview.all
12
+ end
13
+
14
+ def preview
15
+ if found = ActiveAgent::Preview.find(params[:path])
16
+ @previews = [ found ]
17
+ render :index
18
+ elsif load_preview
19
+ render :preview
20
+ end
21
+ end
22
+
23
+ def download
24
+ return unless load_preview
25
+
26
+ send_data @content, type: "text/markdown", disposition: "attachment",
27
+ filename: "#{@preview.preview_name.tr('/', '-')}-#{@prompt}.md"
28
+ end
29
+
30
+ private
31
+
32
+ def load_preview
33
+ name, _, @prompt = params[:path].to_s.rpartition("/")
34
+ @preview = ActiveAgent::Preview.find(name)
35
+ unless @preview&.prompt_exists?(@prompt)
36
+ head :not_found
37
+ return false
38
+ end
39
+
40
+ @content = @preview.call(@prompt, request.query_parameters).prompt_preview
41
+ true
42
+ end
43
+ 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: 1.9.3
4
+ version: 1.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-21 00:00:00.000000000 Z
11
+ date: 2026-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -482,6 +482,9 @@ files:
482
482
  - lib/active_agent/input_request.rb
483
483
  - lib/active_agent/input_request/resume.rb
484
484
  - lib/active_agent/model_capabilities.rb
485
+ - lib/active_agent/preview/templates/layouts/active_agent/preview.html.erb
486
+ - lib/active_agent/preview/templates/rails/agents/index.html.erb
487
+ - lib/active_agent/preview/templates/rails/agents/preview.html.erb
485
488
  - lib/active_agent/providers/_base_provider.rb
486
489
  - lib/active_agent/providers/anthropic/_types.rb
487
490
  - lib/active_agent/providers/anthropic/options.rb
@@ -641,6 +644,7 @@ files:
641
644
  - lib/generators/test_unit/install_generator.rb
642
645
  - lib/generators/test_unit/templates/functional_test.rb.tt
643
646
  - lib/generators/test_unit/templates/preview.rb.tt
647
+ - lib/rails/agents_controller.rb
644
648
  - lib/tasks/activeagent_tasks.rake
645
649
  homepage: https://activeagents.ai
646
650
  licenses: