actionagent 1.7.2 → 1.8.0

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/action_agent.css +1 -1
  3. data/app/assets/builds/action_agent.js +59 -54
  4. data/app/controllers/action_agent/api/agents_controller.rb +19 -3
  5. data/app/controllers/action_agent/api/code_sessions_controller.rb +156 -0
  6. data/app/controllers/action_agent/api/evaluations_controller.rb +27 -130
  7. data/app/controllers/action_agent/api/github_connections_controller.rb +147 -0
  8. data/app/controllers/action_agent/api/mcp_controller.rb +38 -5
  9. data/app/controllers/action_agent/api/mcp_servers_controller.rb +10 -1
  10. data/app/controllers/action_agent/api/provider_keys_controller.rb +54 -3
  11. data/app/controllers/action_agent/api/provider_models_controller.rb +10 -6
  12. data/app/controllers/action_agent/api/sandboxes_controller.rb +97 -6
  13. data/app/controllers/concerns/action_agent/api/evaluation_run_starting.rb +93 -0
  14. data/app/controllers/concerns/action_agent/api/mcp_dashboard_tools.rb +507 -0
  15. data/app/controllers/concerns/action_agent/api/run_sandbox.rb +65 -0
  16. data/app/jobs/action_agent/code_session_job.rb +166 -0
  17. data/app/jobs/action_agent/sandbox_cleanup_job.rb +80 -11
  18. data/app/jobs/action_agent/sandbox_provision_job.rb +122 -14
  19. data/app/jobs/action_agent/sandbox_run_job.rb +10 -3
  20. data/app/models/action_agent/agent.rb +16 -6
  21. data/app/models/action_agent/agent_run.rb +20 -1
  22. data/app/models/action_agent/code_session.rb +141 -0
  23. data/app/models/action_agent/evaluation_run.rb +23 -1
  24. data/app/models/action_agent/github_connection.rb +75 -0
  25. data/app/models/action_agent/provider_key.rb +142 -10
  26. data/app/models/action_agent/sandbox_session.rb +193 -17
  27. data/app/serializers/action_agent/evaluation_serializer.rb +118 -0
  28. data/app/serializers/action_agent/telemetry_trace_serializer.rb +10 -2
  29. data/app/services/action_agent/agent_execution_service.rb +4 -2
  30. data/app/services/action_agent/agent_tool_roster.rb +20 -9
  31. data/app/services/action_agent/claude_code_auth.rb +86 -0
  32. data/app/services/action_agent/dashboard_assistant_service.rb +47 -5
  33. data/app/services/action_agent/evaluation_tool_resolver.rb +18 -0
  34. data/app/services/action_agent/github_client.rb +111 -0
  35. data/app/services/action_agent/local_sandbox_backend.rb +1689 -0
  36. data/app/services/action_agent/local_sandbox_databases.rb +257 -0
  37. data/app/services/action_agent/mcp_client.rb +5 -1
  38. data/app/services/action_agent/mcp_tool_dispatcher.rb +137 -17
  39. data/app/services/action_agent/mock_sandbox_backend.rb +39 -0
  40. data/app/services/action_agent/ollama_host_probe.rb +75 -0
  41. data/app/services/action_agent/payload_bounds.rb +36 -0
  42. data/app/services/action_agent/sandbox_manifest.rb +67 -0
  43. data/app/services/action_agent/sandbox_orchestrator.rb +69 -14
  44. data/app/services/action_agent/scenario_evaluation_runner.rb +50 -4
  45. data/app/services/action_agent/secret_scrubber.rb +37 -0
  46. data/app/services/action_agent/tool_discovery.rb +19 -5
  47. data/config/routes.rb +22 -3
  48. data/lib/action_agent/engine.rb +1 -0
  49. data/lib/action_agent/version.rb +1 -1
  50. data/lib/action_agent.rb +147 -3
  51. data/lib/generators/action_agent/install_generator.rb +30 -3
  52. data/lib/generators/action_agent/templates/action_agent.rb.erb +44 -0
  53. data/lib/generators/action_agent/templates/add_provider_key_api_key.rb.erb +25 -0
  54. data/lib/generators/action_agent/templates/create_active_agent_code_sessions.rb.erb +59 -0
  55. data/lib/generators/action_agent/templates/create_active_agent_dashboard_tables.rb.erb +2 -0
  56. data/lib/generators/action_agent/templates/create_active_agent_github_connections.rb.erb +61 -0
  57. data/lib/tasks/claude_code.rake +16 -0
  58. data/lib/tasks/sandbox.rake +26 -0
  59. metadata +23 -1
@@ -102,11 +102,38 @@ module ActionAgent
102
102
  # shipped. Emitted after them, so on a fresh install it runs once the
103
103
  # table exists, finds the columns the create-table migration made, and
104
104
  # changes nothing.
105
- return if existing_migration?("add_evaluation_report_identity")
105
+ unless existing_migration?("add_evaluation_report_identity")
106
+ migration_template(
107
+ "add_evaluation_report_identity.rb.erb",
108
+ "db/migrate/add_evaluation_report_identity.rb"
109
+ )
110
+ end
111
+
112
+ # A remote Ollama's optional API key arrived after the dashboard tables
113
+ # shipped. Guarded, so on a fresh install it finds the column the
114
+ # create-table migration made and changes nothing.
115
+ unless existing_migration?("add_provider_key_api_key")
116
+ migration_template(
117
+ "add_provider_key_api_key.rb.erb",
118
+ "db/migrate/add_provider_key_api_key.rb"
119
+ )
120
+ end
121
+
122
+ # GitHub connections and checkout sandboxes, likewise later than the
123
+ # dashboard tables.
124
+ unless existing_migration?("create_active_agent_github_connections")
125
+ migration_template(
126
+ "create_active_agent_github_connections.rb.erb",
127
+ "db/migrate/create_active_agent_github_connections.rb"
128
+ )
129
+ end
130
+
131
+ # Claude Code sessions inside those checkouts.
132
+ return if existing_migration?("create_active_agent_code_sessions")
106
133
 
107
134
  migration_template(
108
- "add_evaluation_report_identity.rb.erb",
109
- "db/migrate/add_evaluation_report_identity.rb"
135
+ "create_active_agent_code_sessions.rb.erb",
136
+ "db/migrate/create_active_agent_code_sessions.rb"
110
137
  )
111
138
  end
112
139
 
@@ -106,6 +106,50 @@ ActionAgent.configure do |config|
106
106
  #
107
107
  # config.assistant_enabled = true
108
108
 
109
+ # ==========================================================================
110
+ # Sandboxes
111
+ # ==========================================================================
112
+ #
113
+ # Which backend boots sandboxes: :mock (the default, in memory, runs
114
+ # nothing), :local, or one you register in sandbox_backends to run them in
115
+ # containers. The SANDBOX_BACKEND environment variable overrides it.
116
+ #
117
+ # config.sandbox_service = :local
118
+ # config.sandbox_backends = { "cloud_run" => "CloudRunService" }
119
+ #
120
+ # :local clones a repository connected in Settings -> Integrations onto
121
+ # this machine and boots it as child processes of the dashboard, as the
122
+ # checkout's .activeagents/sandbox.yml says. That runs the repository's
123
+ # code, and Claude Code sessions in it, with the dashboard's privileges, so
124
+ # it is off outside development and test until you enable it here.
125
+ #
126
+ # config.local_sandboxes_enabled = true
127
+ # config.local_sandbox_root = Rails.root.join("tmp/action_agent/sandboxes")
128
+ # config.local_sandbox_boot_timeout = 600 # seconds, for checkout, setup and boot
129
+ #
130
+ # Claude Code sessions in a ready checkout. Nobody is there to answer a
131
+ # permission prompt: "acceptEdits" lets a session edit files in the
132
+ # checkout and run filesystem commands, and anything else that would ask
133
+ # is denied.
134
+ #
135
+ # config.claude_code_command = "claude"
136
+ # config.claude_code_permission_mode = "acceptEdits"
137
+ # config.claude_code_max_turns = nil # Claude Code's own default
138
+ # config.claude_code_timeout = 1800 # seconds
139
+ #
140
+ # How sessions authenticate. :api_key (the default) uses the Anthropic API
141
+ # key connected in Settings -> Integrations (from the Claude Console,
142
+ # https://platform.claude.com). :local_login, with the :local backend only,
143
+ # uses this machine's own Claude Code login (`claude /login`); the dashboard
144
+ # never reads or stores it. Claude subscription tokens (`claude
145
+ # setup-token`) are not accepted: Anthropic does not allow third-party apps
146
+ # to hold Claude.ai credentials.
147
+ #
148
+ # config.claude_code_auth = :local_login
149
+ #
150
+ # Expired sandboxes are stopped by `bin/rails action_agent:sandbox:reap`.
151
+ # Schedule it every few minutes.
152
+
109
153
  # ==========================================================================
110
154
  # UI
111
155
  # ==========================================================================
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adds the optional api_key column to provider keys: a host-based provider
4
+ # (Ollama) can be a remote server behind an authenticating proxy, or Ollama
5
+ # Cloud, and then needs a Bearer key alongside its host URL. Emitted for an
6
+ # install whose dashboard tables predate it; the create-table migration
7
+ # carries the column for a fresh install. Guarded, so it is safe to re-run.
8
+ class AddProviderKeyApiKey < ActiveRecord::Migration<%= migration_version %>
9
+ def up
10
+ return unless table_exists?(table)
11
+ return if column_exists?(table, :api_key)
12
+
13
+ add_column table, :api_key, :string
14
+ end
15
+
16
+ def down
17
+ remove_column table, :api_key if table_exists?(table) && column_exists?(table, :api_key)
18
+ end
19
+
20
+ private
21
+
22
+ def table
23
+ "#{ActionAgent.table_name_prefix}provider_keys"
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Claude Code sessions run inside an app_runtime sandbox's checkout: the
4
+ # prompt, the scrubbed stream-json transcript, the reported outcome and the
5
+ # resulting diff. Emitted alongside the dashboard tables on a fresh install,
6
+ # and on its own for an install that predates it.
7
+ #
8
+ # Table names follow ActionAgent.table_name_prefix, and JSON columns are
9
+ # jsonb on PostgreSQL and json elsewhere, the same way as
10
+ # create_active_agent_dashboard_tables.
11
+ class CreateActiveAgentCodeSessions < ActiveRecord::Migration<%= migration_version %>
12
+ def change
13
+ prefix = ActionAgent.table_name_prefix
14
+
15
+ create_table "#{prefix}code_sessions" do |t|
16
+ t.bigint :sandbox_session_id, null: false
17
+ t.text :prompt, null: false
18
+ t.integer :status, default: 0, null: false
19
+ t.column :events, json_type, **json_default([])
20
+ t.integer :dropped_events_count, default: 0, null: false
21
+ t.text :result
22
+ t.text :diff
23
+ t.text :error_message
24
+ t.string :model
25
+ t.string :claude_session_id
26
+ t.integer :num_turns
27
+ t.integer :duration_ms
28
+ t.decimal :total_cost_usd, precision: 12, scale: 6
29
+ t.integer :input_tokens
30
+ t.integer :output_tokens
31
+ t.datetime :started_at
32
+ t.datetime :finished_at
33
+ t.bigint :user_id
34
+ t.bigint :account_id
35
+ t.timestamps
36
+ t.index :sandbox_session_id
37
+ t.index :user_id
38
+ t.index :account_id
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def json_type
45
+ @json_type ||= postgres? ? :jsonb : :json
46
+ end
47
+
48
+ # MySQL rejects a default on a JSON column outright, so the column is
49
+ # created without one there.
50
+ def json_default(value, null: nil)
51
+ return {} unless postgres?
52
+
53
+ null.nil? ? { default: value } : { default: value, null: null }
54
+ end
55
+
56
+ def postgres?
57
+ connection.adapter_name.to_s.downcase.include?("postgres")
58
+ end
59
+ end
@@ -326,6 +326,8 @@ class CreateActiveAgentDashboardTables < ActiveRecord::Migration<%= migration_ve
326
326
  create_table "#{prefix}provider_keys" do |t|
327
327
  t.string :provider, null: false
328
328
  t.string :credential, null: false
329
+ # Optional Bearer key for a host-based provider (remote Ollama).
330
+ t.string :api_key
329
331
  t.bigint :user_id
330
332
  t.bigint :account_id
331
333
  t.timestamps
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ # GitHub connections: an owner's OAuth grant (Settings -> Integrations), the
4
+ # repositories they made available to the workspace, and the checkout a
5
+ # sandbox session boots its app runtime from. Emitted alongside the dashboard
6
+ # tables on a fresh install, and on its own for an install that predates it.
7
+ #
8
+ # Table names follow ActionAgent.table_name_prefix, and JSON columns are
9
+ # jsonb on PostgreSQL and json elsewhere, the same way as
10
+ # create_active_agent_dashboard_tables.
11
+ class CreateActiveAgentGithubConnections < ActiveRecord::Migration<%= migration_version %>
12
+ def change
13
+ prefix = ActionAgent.table_name_prefix
14
+
15
+ create_table "#{prefix}github_connections" do |t|
16
+ # The OAuth access token, encrypted at rest (text: ciphertext is longer
17
+ # than the token).
18
+ t.text :access_token, null: false
19
+ t.bigint :github_user_id, null: false
20
+ t.string :login, null: false
21
+ t.string :avatar_url
22
+ t.string :scopes
23
+ # The repositories the owner made available, as GitHub described them
24
+ # when they were chosen: full_name, id, private, default_branch.
25
+ t.column :repositories, json_type, **json_default([])
26
+ t.bigint :user_id
27
+ t.bigint :account_id
28
+ t.timestamps
29
+ t.index :account_id
30
+ t.index :user_id
31
+ end
32
+
33
+ # A sandbox booted from a checkout of one of those repositories, and the
34
+ # app runtime's MCP endpoint (and the bearer token it expects, encrypted)
35
+ # once the backend reports them.
36
+ change_table "#{prefix}sandbox_sessions" do |t|
37
+ t.string :repository
38
+ t.string :repository_ref
39
+ t.string :runtime_mcp_url
40
+ t.text :runtime_mcp_token
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def json_type
47
+ @json_type ||= postgres? ? :jsonb : :json
48
+ end
49
+
50
+ # MySQL rejects a default on a JSON column outright, so the column is
51
+ # created without one there.
52
+ def json_default(value, null: nil)
53
+ return {} unless postgres?
54
+
55
+ null.nil? ? { default: value } : { default: value, null: null }
56
+ end
57
+
58
+ def postgres?
59
+ connection.adapter_name.to_s.downcase.include?("postgres")
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :action_agent do
4
+ namespace :claude_code do
5
+ # Earlier versions accepted a `claude setup-token` token (a Claude
6
+ # subscription credential) for the Claude Code connection. Anthropic does
7
+ # not let third-party products store those, and they are no longer used;
8
+ # this removes the ones still stored. Run it once after upgrading.
9
+ desc "Delete stored Claude Code connections holding a Claude subscription token (sk-ant-oat…), " \
10
+ "which are no longer used; their owners connect an Anthropic API key instead"
11
+ task purge_subscription_tokens: :environment do
12
+ count = ActionAgent::ProviderKey.purge_subscription_tokens!
13
+ puts "Deleted #{count} stored Claude subscription token(s)"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :action_agent do
4
+ namespace :sandbox do
5
+ desc "Write this app's checkout sandbox runtime manifest ({mcp_path, mcp_token}) to " \
6
+ "$ACTION_AGENT_SANDBOX_MANIFEST, or print it"
7
+ task manifest: :environment do
8
+ manifest = JSON.generate(ActionAgent::SandboxManifest.generate)
9
+
10
+ if (path = ENV[ActionAgent::SandboxManifest::PATH_ENV].presence)
11
+ File.write(path, manifest)
12
+ else
13
+ puts manifest
14
+ end
15
+ rescue ActionAgent::SandboxManifest::Error => e
16
+ abort "action_agent:sandbox:manifest: #{e.message}"
17
+ end
18
+
19
+ desc "Expire sandbox sessions past their expiry and release what their backend holds " \
20
+ "(processes, containers). Schedule it, e.g. every few minutes."
21
+ task reap: :environment do
22
+ count = ActionAgent::SandboxCleanupJob.cleanup_expired!
23
+ puts "Expired #{count.to_i} sandbox session(s)"
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
@@ -129,9 +129,11 @@ files:
129
129
  - app/controllers/action_agent/api/analytics_controller.rb
130
130
  - app/controllers/action_agent/api/api_keys_controller.rb
131
131
  - app/controllers/action_agent/api/base_controller.rb
132
+ - app/controllers/action_agent/api/code_sessions_controller.rb
132
133
  - app/controllers/action_agent/api/dashboard_assistant_controller.rb
133
134
  - app/controllers/action_agent/api/evaluation_reports_controller.rb
134
135
  - app/controllers/action_agent/api/evaluations_controller.rb
136
+ - app/controllers/action_agent/api/github_connections_controller.rb
135
137
  - app/controllers/action_agent/api/instance_tiers_controller.rb
136
138
  - app/controllers/action_agent/api/interaction_messages_controller.rb
137
139
  - app/controllers/action_agent/api/interactions_controller.rb
@@ -151,9 +153,13 @@ files:
151
153
  - app/controllers/action_agent/dashboard_controller.rb
152
154
  - app/controllers/action_agent/traces_controller.rb
153
155
  - app/controllers/concerns/action_agent/api/agent_serialization.rb
156
+ - app/controllers/concerns/action_agent/api/evaluation_run_starting.rb
154
157
  - app/controllers/concerns/action_agent/api/ingest_authentication.rb
158
+ - app/controllers/concerns/action_agent/api/mcp_dashboard_tools.rb
159
+ - app/controllers/concerns/action_agent/api/run_sandbox.rb
155
160
  - app/jobs/action_agent/agent_execution_job.rb
156
161
  - app/jobs/action_agent/application_job.rb
162
+ - app/jobs/action_agent/code_session_job.rb
157
163
  - app/jobs/action_agent/evaluation_run_job.rb
158
164
  - app/jobs/action_agent/process_telemetry_traces_job.rb
159
165
  - app/jobs/action_agent/sandbox_cleanup_job.rb
@@ -171,10 +177,12 @@ files:
171
177
  - app/models/action_agent/agent_version.rb
172
178
  - app/models/action_agent/api_key.rb
173
179
  - app/models/action_agent/application_record.rb
180
+ - app/models/action_agent/code_session.rb
174
181
  - app/models/action_agent/evaluation.rb
175
182
  - app/models/action_agent/evaluation_run.rb
176
183
  - app/models/action_agent/evaluation_scenario.rb
177
184
  - app/models/action_agent/evaluation_scenario_result.rb
185
+ - app/models/action_agent/github_connection.rb
178
186
  - app/models/action_agent/model_pricing.rb
179
187
  - app/models/action_agent/provider_key.rb
180
188
  - app/models/action_agent/recording_action.rb
@@ -190,6 +198,7 @@ files:
190
198
  - app/queries/action_agent/agent_executions.rb
191
199
  - app/queries/action_agent/metrics_report.rb
192
200
  - app/serializers/action_agent/agent_message_serializer.rb
201
+ - app/serializers/action_agent/evaluation_serializer.rb
193
202
  - app/serializers/action_agent/interaction_preview.rb
194
203
  - app/serializers/action_agent/telemetry_trace_serializer.rb
195
204
  - app/serializers/action_agent/trace_interaction_serializer.rb
@@ -200,19 +209,27 @@ files:
200
209
  - app/services/action_agent/agent_sync.rb
201
210
  - app/services/action_agent/agent_tool_roster.rb
202
211
  - app/services/action_agent/agent_toolbox.rb
212
+ - app/services/action_agent/claude_code_auth.rb
203
213
  - app/services/action_agent/dashboard_assistant_service.rb
204
214
  - app/services/action_agent/evaluation_evidence.rb
205
215
  - app/services/action_agent/evaluation_report_import.rb
206
216
  - app/services/action_agent/evaluation_runner_service.rb
207
217
  - app/services/action_agent/evaluation_tool_resolver.rb
218
+ - app/services/action_agent/github_client.rb
219
+ - app/services/action_agent/local_sandbox_backend.rb
220
+ - app/services/action_agent/local_sandbox_databases.rb
208
221
  - app/services/action_agent/mcp_catalog.rb
209
222
  - app/services/action_agent/mcp_client.rb
210
223
  - app/services/action_agent/mcp_recording_middleware.rb
211
224
  - app/services/action_agent/mcp_tool_dispatcher.rb
212
225
  - app/services/action_agent/mock_sandbox_backend.rb
226
+ - app/services/action_agent/ollama_host_probe.rb
227
+ - app/services/action_agent/payload_bounds.rb
213
228
  - app/services/action_agent/playwright_mcp_client.rb
229
+ - app/services/action_agent/sandbox_manifest.rb
214
230
  - app/services/action_agent/sandbox_orchestrator.rb
215
231
  - app/services/action_agent/scenario_evaluation_runner.rb
232
+ - app/services/action_agent/secret_scrubber.rb
216
233
  - app/services/action_agent/session_recording_service.rb
217
234
  - app/services/action_agent/tool_discovery.rb
218
235
  - app/views/action_agent/dashboard/index.html.erb
@@ -234,11 +251,16 @@ files:
234
251
  - lib/generators/action_agent/templates/add_agent_id_to_active_agent_telemetry_traces.rb.erb
235
252
  - lib/generators/action_agent/templates/add_agent_releases.rb.erb
236
253
  - lib/generators/action_agent/templates/add_evaluation_report_identity.rb.erb
254
+ - lib/generators/action_agent/templates/add_provider_key_api_key.rb.erb
255
+ - lib/generators/action_agent/templates/create_active_agent_code_sessions.rb.erb
237
256
  - lib/generators/action_agent/templates/create_active_agent_dashboard_tables.rb.erb
238
257
  - lib/generators/action_agent/templates/create_active_agent_evaluation_scenarios.rb.erb
258
+ - lib/generators/action_agent/templates/create_active_agent_github_connections.rb.erb
239
259
  - lib/generators/action_agent/templates/create_active_agent_telemetry_traces.rb.erb
240
260
  - lib/generators/action_agent/templates/ensure_agent_release_columns.rb.erb
241
261
  - lib/tasks/action_agent.rake
262
+ - lib/tasks/claude_code.rake
263
+ - lib/tasks/sandbox.rake
242
264
  homepage: https://activeagents.ai
243
265
  licenses:
244
266
  - MIT