actionagent 1.8.1 → 1.9.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 (159) 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 +76 -73
  4. data/app/assets/builds/action_agent_recorder.js +78 -0
  5. data/app/assets/builds/action_agent_replay.js +226 -0
  6. data/app/controllers/action_agent/api/agent_runs_controller.rb +3 -1
  7. data/app/controllers/action_agent/api/agents_controller.rb +1 -0
  8. data/app/controllers/action_agent/api/api_keys_controller.rb +12 -2
  9. data/app/controllers/action_agent/api/base_controller.rb +63 -2
  10. data/app/controllers/action_agent/api/claude_logins_controller.rb +93 -0
  11. data/app/controllers/action_agent/api/code_sessions_controller.rb +53 -6
  12. data/app/controllers/action_agent/api/dashboard_assistant_controller.rb +2 -2
  13. data/app/controllers/action_agent/api/draft_pull_requests_controller.rb +248 -0
  14. data/app/controllers/action_agent/api/evaluation_fixes_controller.rb +27 -0
  15. data/app/controllers/action_agent/api/evaluations_controller.rb +9 -4
  16. data/app/controllers/action_agent/api/explorations_controller.rb +213 -0
  17. data/app/controllers/action_agent/api/github_app_manifests_controller.rb +125 -0
  18. data/app/controllers/action_agent/api/github_connections_controller.rb +40 -2
  19. data/app/controllers/action_agent/api/github_installations_controller.rb +280 -0
  20. data/app/controllers/action_agent/api/input_requests_controller.rb +77 -0
  21. data/app/controllers/action_agent/api/mcp_controller.rb +46 -12
  22. data/app/controllers/action_agent/api/members_controller.rb +36 -0
  23. data/app/controllers/action_agent/api/project_explorations_controller.rb +80 -0
  24. data/app/controllers/action_agent/api/project_install_pull_requests_controller.rb +305 -0
  25. data/app/controllers/action_agent/api/project_secrets_controller.rb +96 -0
  26. data/app/controllers/action_agent/api/project_setup_controller.rb +151 -0
  27. data/app/controllers/action_agent/api/project_sign_ins_controller.rb +112 -0
  28. data/app/controllers/action_agent/api/projects_controller.rb +512 -0
  29. data/app/controllers/action_agent/api/provider_keys_controller.rb +176 -24
  30. data/app/controllers/action_agent/api/provider_models_controller.rb +37 -15
  31. data/app/controllers/action_agent/api/recording_event_ingest_controller.rb +67 -0
  32. data/app/controllers/action_agent/api/sandbox_browser_tickets_controller.rb +50 -0
  33. data/app/controllers/action_agent/api/sandbox_browsers_controller.rb +65 -0
  34. data/app/controllers/action_agent/api/sandboxes_controller.rb +140 -8
  35. data/app/controllers/action_agent/api/scenario_catalog_entries_controller.rb +188 -0
  36. data/app/controllers/action_agent/api/scenario_catalogs_controller.rb +302 -0
  37. data/app/controllers/action_agent/api/session_recordings_controller.rb +165 -34
  38. data/app/controllers/action_agent/api/sessions_controller.rb +111 -0
  39. data/app/controllers/action_agent/api/telemetry_keys_controller.rb +21 -0
  40. data/app/controllers/action_agent/dashboard_controller.rb +17 -6
  41. data/app/controllers/action_agent/session_player_controller.rb +58 -0
  42. data/app/controllers/concerns/action_agent/api/agent_serialization.rb +1 -0
  43. data/app/controllers/concerns/action_agent/api/mcp_dashboard_tools.rb +623 -18
  44. data/app/controllers/concerns/action_agent/api/project_browser.rb +46 -0
  45. data/app/controllers/concerns/action_agent/api/project_secret_authorization.rb +57 -0
  46. data/app/jobs/action_agent/agent_execution_job.rb +9 -39
  47. data/app/jobs/action_agent/agent_resume_job.rb +84 -0
  48. data/app/jobs/action_agent/code_session_job.rb +26 -2
  49. data/app/jobs/action_agent/draft_pull_request_job.rb +43 -0
  50. data/app/jobs/action_agent/exploration_job.rb +80 -0
  51. data/app/jobs/action_agent/input_request_expiry_job.rb +22 -0
  52. data/app/jobs/action_agent/project_evaluation_job.rb +59 -0
  53. data/app/jobs/action_agent/project_setup_job.rb +21 -0
  54. data/app/jobs/action_agent/sandbox_cleanup_job.rb +20 -3
  55. data/app/jobs/action_agent/sandbox_provision_job.rb +77 -10
  56. data/app/jobs/action_agent/sandbox_run_job.rb +9 -37
  57. data/app/jobs/action_agent/verify_evaluation_fix_job.rb +37 -0
  58. data/app/models/action_agent/agent.rb +39 -26
  59. data/app/models/action_agent/agent_run.rb +134 -23
  60. data/app/models/action_agent/agent_template.rb +35 -1
  61. data/app/models/action_agent/api_key.rb +14 -0
  62. data/app/models/action_agent/catalog_scenario.rb +75 -0
  63. data/app/models/action_agent/code_session.rb +16 -4
  64. data/app/models/action_agent/draft_pull_request.rb +131 -0
  65. data/app/models/action_agent/evaluation.rb +84 -0
  66. data/app/models/action_agent/exploration.rb +847 -0
  67. data/app/models/action_agent/github_installation.rb +159 -0
  68. data/app/models/action_agent/input_request.rb +291 -0
  69. data/app/models/action_agent/project.rb +789 -0
  70. data/app/models/action_agent/project_secret.rb +339 -0
  71. data/app/models/action_agent/provider_key.rb +200 -3
  72. data/app/models/action_agent/recording_event.rb +145 -0
  73. data/app/models/action_agent/recording_snapshot.rb +7 -7
  74. data/app/models/action_agent/sandbox_session.rb +297 -14
  75. data/app/models/action_agent/scenario_catalog.rb +172 -0
  76. data/app/models/action_agent/scenario_product.rb +57 -0
  77. data/app/models/action_agent/scenario_set.rb +138 -0
  78. data/app/models/action_agent/session_recording.rb +121 -14
  79. data/app/models/action_agent/telemetry_trace.rb +74 -19
  80. data/app/models/concerns/action_agent/ownable.rb +84 -13
  81. data/app/serializers/action_agent/input_request_serializer.rb +47 -0
  82. data/app/serializers/action_agent/scenario_catalog_serializer.rb +23 -0
  83. data/app/serializers/action_agent/session_summary_serializer.rb +146 -0
  84. data/app/services/action_agent/agent_execution_service.rb +450 -72
  85. data/app/services/action_agent/agent_sync.rb +5 -2
  86. data/app/services/action_agent/agent_tool_roster.rb +19 -4
  87. data/app/services/action_agent/agent_toolbox.rb +215 -9
  88. data/app/services/action_agent/browser_live_ticket.rb +78 -0
  89. data/app/services/action_agent/browser_sidecar.rb +213 -0
  90. data/app/services/action_agent/browser_sign_in.rb +163 -0
  91. data/app/services/action_agent/browser_tool_redaction.rb +92 -0
  92. data/app/services/action_agent/claude_code_auth.rb +70 -4
  93. data/app/services/action_agent/dashboard_assistant_service.rb +24 -10
  94. data/app/services/action_agent/draft_pull_request_publisher.rb +719 -0
  95. data/app/services/action_agent/evaluation_fix.rb +101 -0
  96. data/app/services/action_agent/evaluation_fix_comparison.rb +66 -0
  97. data/app/services/action_agent/evaluation_runner_service.rb +4 -5
  98. data/app/services/action_agent/evaluation_standing.rb +15 -8
  99. data/app/services/action_agent/explorer_execution_service.rb +517 -0
  100. data/app/services/action_agent/github_client.rb +405 -64
  101. data/app/services/action_agent/live_updates.rb +31 -0
  102. data/app/services/action_agent/local_sandbox_backend.rb +1218 -83
  103. data/app/services/action_agent/local_sandbox_claude_login.rb +151 -0
  104. data/app/services/action_agent/mcp_client.rb +6 -2
  105. data/app/services/action_agent/mcp_recording_middleware.rb +104 -145
  106. data/app/services/action_agent/mcp_tool_dispatcher.rb +36 -13
  107. data/app/services/action_agent/mock_sandbox_backend.rb +3 -1
  108. data/app/services/action_agent/playwright_mcp_client.rb +7 -0
  109. data/app/services/action_agent/project_boot_fix.rb +309 -0
  110. data/app/services/action_agent/project_capabilities.rb +200 -0
  111. data/app/services/action_agent/project_install_pull_request.rb +225 -0
  112. data/app/services/action_agent/project_preflight.rb +178 -0
  113. data/app/services/action_agent/project_secret_discovery.rb +142 -0
  114. data/app/services/action_agent/project_setup.rb +429 -0
  115. data/app/services/action_agent/provider_credentials.rb +102 -0
  116. data/app/services/action_agent/recording_event_ingest.rb +181 -0
  117. data/app/services/action_agent/runtime_tool_roster.rb +52 -0
  118. data/app/services/action_agent/sample_data/conference_ticket.rb +516 -0
  119. data/app/services/action_agent/sandbox_boot_spec.rb +558 -0
  120. data/app/services/action_agent/sandbox_browser.rb +299 -0
  121. data/app/services/action_agent/sandbox_browser_driver.rb +85 -0
  122. data/app/services/action_agent/sandbox_credential_paths.rb +26 -0
  123. data/app/services/action_agent/sandbox_mail.rb +103 -0
  124. data/app/services/action_agent/sandbox_manifest.rb +166 -13
  125. data/app/services/action_agent/sandbox_orchestrator.rb +276 -22
  126. data/app/services/action_agent/sandbox_patch.rb +253 -0
  127. data/app/services/action_agent/scenario_catalog_import.rb +255 -0
  128. data/app/services/action_agent/scenario_catalog_repository_import.rb +81 -0
  129. data/app/services/action_agent/scenario_evaluation_runner.rb +119 -16
  130. data/app/services/action_agent/secret_scrubber.rb +33 -4
  131. data/app/services/action_agent/session_index.rb +270 -0
  132. data/app/services/action_agent/session_recording_service.rb +11 -0
  133. data/app/services/action_agent/session_timeline.rb +505 -0
  134. data/app/views/action_agent/github_app_manifests/created.html.erb +55 -0
  135. data/app/views/action_agent/session_player/show.html.erb +19 -0
  136. data/config/routes.rb +152 -1
  137. data/lib/action_agent/claude_login_process.rb +107 -0
  138. data/lib/action_agent/engine.rb +55 -5
  139. data/lib/action_agent/secret_requests.rb +80 -0
  140. data/lib/action_agent/version.rb +1 -1
  141. data/lib/action_agent.rb +507 -22
  142. data/lib/generators/action_agent/install_generator.rb +37 -0
  143. data/lib/generators/action_agent/templates/action_agent.rb.erb +158 -0
  144. data/lib/generators/action_agent/templates/migrations/015_add_provider_key_scope.rb.erb +72 -0
  145. data/lib/generators/action_agent/templates/migrations/016_create_active_agent_input_requests.rb.erb +85 -0
  146. data/lib/generators/action_agent/templates/migrations/017_create_active_agent_recording_events.rb.erb +57 -0
  147. data/lib/generators/action_agent/templates/migrations/018_add_browser_to_active_agent_sandbox_sessions.rb.erb +25 -0
  148. data/lib/generators/action_agent/templates/migrations/019_create_active_agent_projects.rb.erb +79 -0
  149. data/lib/generators/action_agent/templates/migrations/020_add_github_app_installations.rb.erb +62 -0
  150. data/lib/generators/action_agent/templates/migrations/021_create_active_agent_explorations.rb.erb +63 -0
  151. data/lib/generators/action_agent/templates/migrations/023_create_active_agent_draft_pull_requests.rb.erb +75 -0
  152. data/lib/generators/action_agent/templates/migrations/024_add_kind_to_active_agent_project_secrets.rb.erb +14 -0
  153. data/lib/generators/action_agent/templates/migrations/025_create_active_agent_scenario_catalogs.rb.erb +110 -0
  154. data/lib/generators/action_agent/templates/migrations/026_add_evaluation_fixes_to_code_sessions.rb.erb +21 -0
  155. data/lib/tasks/action_agent.rake +33 -0
  156. data/lib/tasks/browser.rake +22 -0
  157. data/lib/tasks/sandbox.rake +1 -1
  158. data/lib/tasks/scenario_catalogs.rake +71 -0
  159. metadata +96 -2
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Draft pull requests opened from a checkout sandbox's changes (Settings ->
4
+ # Integrations -> Open draft PR), and the state GitHub last reported for each.
5
+ #
6
+ # Table names follow ActionAgent.table_name_prefix, and JSON columns are
7
+ # jsonb on PostgreSQL and json elsewhere, the same way as
8
+ # create_active_agent_dashboard_tables.
9
+ class CreateActiveAgentDraftPullRequests < ActiveRecord::Migration<%= migration_version %>
10
+ def change
11
+ prefix = ActionAgent.table_name_prefix
12
+
13
+ create_table "#{prefix}draft_pull_requests" do |t|
14
+ t.bigint :sandbox_session_id, null: false
15
+ # "owner/name" on GitHub.
16
+ t.string :repository, null: false
17
+ # The branch the pull request merges into, and the branch published.
18
+ t.string :base_branch
19
+ t.string :branch, null: false
20
+ # The commit the sandbox checked out, and the last commit published.
21
+ t.string :base_commit, null: false
22
+ t.string :head_commit
23
+ t.string :title, null: false
24
+ t.text :body
25
+ # The message of the last update's commit.
26
+ t.text :commit_message
27
+ # The files of the last publish, each { path, status, mode, digest }.
28
+ t.column :files, json_type, **json_default([])
29
+ # What the last publish did ("create", "update", "open_draft",
30
+ # "open_regular") and how it went ("queued", "publishing", "published",
31
+ # "draft_refused", "failed").
32
+ t.string :operation, null: false, default: "create"
33
+ t.string :status, null: false, default: "queued"
34
+ # Why the last publish failed: a word the dashboard acts on (see
35
+ # DraftPullRequestPublisher::Refused), and a message for the user.
36
+ t.string :error_code
37
+ t.text :error_message
38
+ # "app" (a GitHub App installation) or "oauth" (the OAuth connection).
39
+ t.string :credential_kind
40
+ t.integer :number
41
+ t.string :url
42
+ t.string :compare_url
43
+ # "open", "closed" or "merged", and whether it is a draft, as GitHub
44
+ # last reported them.
45
+ t.string :state
46
+ t.boolean :draft
47
+ t.datetime :last_checked_at
48
+ # The user who published, and the owner.
49
+ t.bigint :user_id
50
+ t.bigint :account_id
51
+ t.timestamps
52
+ t.index :sandbox_session_id, name: "index_#{prefix}draft_pull_requests_on_sandbox_session"
53
+ t.index :account_id, name: "index_#{prefix}draft_pull_requests_on_account"
54
+ t.index :user_id, name: "index_#{prefix}draft_pull_requests_on_user"
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def json_type
61
+ @json_type ||= postgres? ? :jsonb : :json
62
+ end
63
+
64
+ # MySQL rejects a default on a JSON column outright, so the column is
65
+ # created without one there.
66
+ def json_default(value, null: nil)
67
+ return {} unless postgres?
68
+
69
+ null.nil? ? { default: value } : { default: value, null: null }
70
+ end
71
+
72
+ def postgres?
73
+ connection.adapter_name.to_s.downcase.include?("postgres")
74
+ end
75
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Project secrets of three kinds: an environment variable a boot hands to
4
+ # the app ("env", every secret before this migration), the credentials the
5
+ # explorer signs in with ("sign_in"), and a browser's saved sign-in
6
+ # ("storage_state"). Only env secrets reach the sandbox's environment.
7
+ #
8
+ # Table names follow ActionAgent.table_name_prefix, the same way as
9
+ # create_active_agent_dashboard_tables.
10
+ class AddKindToActiveAgentProjectSecrets < ActiveRecord::Migration<%= migration_version %>
11
+ def change
12
+ add_column "#{ActionAgent.table_name_prefix}project_secrets", :kind, :string, null: false, default: "env"
13
+ end
14
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Scenario catalogs: the YAML catalogs of evaluation scenarios an owner keeps
4
+ # in the dashboard, each a set of products (an agent or a project under test)
5
+ # with named sets of scenarios. A catalog remembers the document it was
6
+ # imported from and its digest, so a re-import of the same file changes
7
+ # nothing, and a set remembers the evaluation it was last materialized as.
8
+ #
9
+ # Table names follow ActionAgent.table_name_prefix, and JSON columns are
10
+ # jsonb on PostgreSQL and json elsewhere, the same way as
11
+ # create_active_agent_dashboard_tables.
12
+ class CreateActiveAgentScenarioCatalogs < ActiveRecord::Migration<%= migration_version %>
13
+ def change
14
+ prefix = ActionAgent.table_name_prefix
15
+
16
+ create_table "#{prefix}scenario_catalogs" do |t|
17
+ t.string :key, null: false
18
+ t.string :name, null: false
19
+ t.text :description
20
+ # upload: pasted or uploaded YAML; repository: read from a connected
21
+ # repository at a ref; api: built through the API or MCP tools.
22
+ t.string :source_kind, null: false, default: "upload"
23
+ # For a repository: "owner/name@ref:path".
24
+ t.string :source_path
25
+ # SHA-256 of the canonical document, and the document itself.
26
+ t.string :digest
27
+ t.text :document
28
+ # When the document was last written to Active Storage, and the digest
29
+ # it carried then.
30
+ t.datetime :synced_at
31
+ t.string :synced_digest
32
+ t.column :metadata, json_type, **json_default({})
33
+ t.bigint :account_id
34
+ t.bigint :user_id
35
+ t.timestamps
36
+ t.index :key
37
+ t.index :account_id
38
+ t.index :user_id
39
+ end
40
+
41
+ create_table "#{prefix}scenario_products" do |t|
42
+ t.bigint :scenario_catalog_id, null: false
43
+ t.string :key, null: false
44
+ t.string :name, null: false
45
+ t.text :description
46
+ # What the product's sets run against: a dashboard agent, a project
47
+ # (whose sandbox the replays reach), or neither yet. agent_name keeps
48
+ # the document's `agent:` reference for an agent that is not here.
49
+ t.bigint :agent_id
50
+ t.bigint :project_id
51
+ t.string :agent_name
52
+ t.integer :position
53
+ t.column :metadata, json_type, **json_default({})
54
+ t.timestamps
55
+ t.index [ :scenario_catalog_id, :key ], unique: true
56
+ t.index :agent_id
57
+ t.index :project_id
58
+ end
59
+
60
+ create_table "#{prefix}scenario_sets" do |t|
61
+ t.bigint :scenario_product_id, null: false
62
+ t.string :key, null: false
63
+ t.string :name, null: false
64
+ t.text :description
65
+ # { kind, model }: the judge of the evaluation the set becomes.
66
+ t.column :judge, json_type, **json_default({})
67
+ t.column :criteria, json_type, **json_default([])
68
+ t.column :metadata, json_type, **json_default({})
69
+ # The evaluation this set was last materialized as, if any.
70
+ t.bigint :evaluation_id
71
+ t.integer :position
72
+ t.timestamps
73
+ t.index [ :scenario_product_id, :key ], unique: true
74
+ t.index :evaluation_id
75
+ end
76
+
77
+ create_table "#{prefix}catalog_scenarios" do |t|
78
+ t.bigint :scenario_set_id, null: false
79
+ t.string :key, null: false
80
+ t.text :prompt, null: false
81
+ t.text :notes
82
+ t.column :expectations, json_type, **json_default({})
83
+ t.column :tags, json_type, **json_default([])
84
+ t.column :params, json_type, **json_default({})
85
+ t.boolean :production_only, null: false, default: false
86
+ t.boolean :enabled, null: false, default: true
87
+ t.integer :position
88
+ t.timestamps
89
+ t.index [ :scenario_set_id, :key ], unique: true
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def json_type
96
+ @json_type ||= postgres? ? :jsonb : :json
97
+ end
98
+
99
+ # MySQL rejects a default on a JSON column outright, so the column is
100
+ # created without one there.
101
+ def json_default(value, null: nil)
102
+ return {} unless postgres?
103
+
104
+ null.nil? ? { default: value } : { default: value, null: null }
105
+ end
106
+
107
+ def postgres?
108
+ connection.adapter_name.to_s.downcase.include?("postgres")
109
+ end
110
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Links a Claude Code session to the evaluation fix it implements (the run,
4
+ # the fix card, the follow-up it retries) and to the run that verified it,
5
+ # and records which user signed in to Claude Code inside a sandbox.
6
+ class AddEvaluationFixesToCodeSessions < ActiveRecord::Migration<%= migration_version %>
7
+ def change
8
+ sessions = "#{ActionAgent.table_name_prefix}code_sessions"
9
+ sandboxes = "#{ActionAgent.table_name_prefix}sandbox_sessions"
10
+ add_column sessions, :evaluation_run_id, :bigint
11
+ add_column sessions, :verification_run_id, :bigint
12
+ add_column sessions, :previous_code_session_id, :bigint
13
+ # jsonb on PostgreSQL and json elsewhere, like the dashboard tables.
14
+ add_column sessions, :fix_item, connection.adapter_name.to_s.downcase.include?("postgres") ? :jsonb : :json
15
+ add_column sessions, :credential_mode, :string
16
+ add_column sessions, :verification_error, :text
17
+ add_index sessions, :evaluation_run_id
18
+ add_index sessions, :verification_run_id
19
+ add_column sandboxes, :claude_login_user_id, :bigint
20
+ end
21
+ end
@@ -6,6 +6,39 @@ namespace :action_agent do
6
6
  ActionAgent::AgentTemplate.seed_defaults!
7
7
  puts "Agent template library: #{ActionAgent::AgentTemplate.count} templates"
8
8
  end
9
+
10
+ # Sample data a workspace can show before it has run anything of its own.
11
+ # On a multi-tenant install name the workspace: ACCOUNT_ID=<id> (or
12
+ # USER_ID=<id> where agents belong to users).
13
+ namespace :sample do
14
+ desc "Seed the conference-ticket sample: an agent, a week of runs and traces, a replayable handoff, and an evaluation history"
15
+ task conference_ticket: :environment do
16
+ ActionAgent::AgentTemplate.seed_defaults!
17
+ agent = ActionAgent::SampleData::ConferenceTicket.seed!(owner: action_agent_sample_owner)
18
+ traces = ActionAgent.trace_model.where(agent_id: agent.id).count
19
+ evaluation = agent.evaluations.find_by(name: ActionAgent::SampleData::ConferenceTicket::EVALUATION_NAME)
20
+ puts "Conference ticket sample: agent ##{agent.id} (#{agent.slug})"
21
+ puts " #{agent.agent_runs.count} runs, #{traces} traces, " \
22
+ "#{ActionAgent::SessionRecording.where(agent_run_id: agent.agent_runs.select(:id)).count} session recording"
23
+ puts " evaluation \"#{evaluation&.name}\": #{evaluation&.evaluation_runs&.count} runs over #{evaluation&.scenarios&.count} scenarios"
24
+ end
25
+
26
+ desc "Remove the conference-ticket sample and everything it created"
27
+ task clear: :environment do
28
+ removed = ActionAgent::SampleData::ConferenceTicket.clear!(owner: action_agent_sample_owner)
29
+ puts removed.zero? ? "No conference ticket sample to remove" : "Conference ticket sample removed"
30
+ end
31
+ end
32
+ end
33
+
34
+ # The workspace the sample belongs to, from ACCOUNT_ID or USER_ID; nil on a
35
+ # single-user install.
36
+ def action_agent_sample_owner
37
+ if ENV["ACCOUNT_ID"].present?
38
+ ActionAgent.account_class.to_s.constantize.find(ENV["ACCOUNT_ID"])
39
+ elsif ENV["USER_ID"].present?
40
+ ActionAgent.user_class.to_s.constantize.find(ENV["USER_ID"])
41
+ end
9
42
  end
10
43
 
11
44
  namespace :action_agent do
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :action_agent do
4
+ namespace :browser do
5
+ desc "Install the browser sidecar and its Chromium for the :local sandbox backend, under the local sandbox root"
6
+ task install: :environment do
7
+ ActionAgent::BrowserSidecar.install!
8
+ puts "Installed the browser sidecar under #{ActionAgent::BrowserSidecar.root}"
9
+ rescue ActionAgent::BrowserSidecar::Error => e
10
+ abort "action_agent:browser:install: #{e.message}"
11
+ end
12
+
13
+ desc "Check that a sandbox's browser can start on this machine: Node.js, the browser sidecar and Chromium"
14
+ task doctor: :environment do
15
+ checks = ActionAgent::BrowserSidecar.checks
16
+ checks.each { |check| puts "#{check.ok ? '[ok] ' : '[missing]'} #{check.name}: #{check.message}" }
17
+ abort "Browser sessions cannot start on this machine yet." unless checks.all?(&:ok)
18
+
19
+ puts "Browser sessions can start on this machine."
20
+ end
21
+ end
22
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  namespace :action_agent do
4
4
  namespace :sandbox do
5
- desc "Write this app's checkout sandbox runtime manifest ({mcp_path, mcp_token}) to " \
5
+ desc "Write this app's checkout sandbox runtime manifest ({mcp_path, mcp_token, models}) to " \
6
6
  "$ACTION_AGENT_SANDBOX_MANIFEST, or print it"
7
7
  task manifest: :environment do
8
8
  manifest = JSON.generate(ActionAgent::SandboxManifest.generate)
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Scenario catalogs from the command line, for a repository that keeps its
4
+ # scenarios in YAML. On a multi-tenant install name the workspace with
5
+ # ACCOUNT_ID=<id> (or USER_ID=<id> where catalogs belong to users).
6
+ #
7
+ # bin/rails action_agent:catalogs:import FILE=config/evals/support.yml
8
+ # bin/rails action_agent:catalogs:export KEY=support FILE=tmp/support.yml
9
+ # bin/rails action_agent:catalogs:run KEY=support PRODUCT=triage SET=smoke [AGENT_ID=1 | PROJECT_ID=2]
10
+ namespace :action_agent do
11
+ namespace :catalogs do
12
+ desc "Import a scenario catalog from a YAML file (FILE=path); re-importing the same file changes nothing"
13
+ task import: :environment do
14
+ path = ENV.fetch("FILE") { abort "Name the file: FILE=config/evals/support.yml" }
15
+ abort "No file at #{path}" unless File.file?(path)
16
+
17
+ owner = action_agent_catalog_owner
18
+ catalog = ActionAgent::ScenarioCatalogImport.new(
19
+ owner: owner, document: File.read(path), name: File.basename(path, File.extname(path)),
20
+ source_kind: "upload", source_path: path,
21
+ agents: ActionAgent.agents_for(owner), projects: ActionAgent::Project.for_owner(owner)
22
+ ).call
23
+ puts "Catalog #{catalog.key}: #{catalog.products.count} products, #{catalog.scenario_count} scenarios" \
24
+ "#{catalog.synced? ? ', synced to Active Storage' : ''}"
25
+ rescue ActionAgent::ScenarioCatalogImport::Invalid => e
26
+ abort "Import refused: #{e.message}"
27
+ end
28
+
29
+ desc "Write a catalog's canonical YAML (KEY=catalog key, FILE=path; standard output without FILE)"
30
+ task export: :environment do
31
+ catalog = action_agent_catalog!
32
+ yaml = catalog.export_yaml
33
+ if ENV["FILE"].present?
34
+ File.write(ENV["FILE"], yaml)
35
+ puts "Wrote #{catalog.key} (#{catalog.scenario_count} scenarios) to #{ENV['FILE']}"
36
+ else
37
+ puts yaml
38
+ end
39
+ end
40
+
41
+ desc "Run one set of a catalog (KEY, PRODUCT, SET) against AGENT_ID or PROJECT_ID, or the product's own target"
42
+ task run: :environment do
43
+ catalog = action_agent_catalog!
44
+ product = catalog.products.find_by!(key: ENV.fetch("PRODUCT") { abort "Name the product: PRODUCT=<key>" })
45
+ set = product.sets.find_by!(key: ENV.fetch("SET") { abort "Name the set: SET=<key>" })
46
+ agent = ENV["AGENT_ID"].present? ? ActionAgent::Agent.find(ENV["AGENT_ID"]) : nil
47
+ project = ENV["PROJECT_ID"].present? ? ActionAgent::Project.find(ENV["PROJECT_ID"]) : nil
48
+
49
+ run = set.run!(agent: agent, project: project)
50
+ puts "Run ##{run.id} of #{set.evaluation_name} is #{run.status} (evaluation ##{run.evaluation_id})"
51
+ rescue ActionAgent::ScenarioSet::NoAgent => e
52
+ abort e.message
53
+ end
54
+ end
55
+ end
56
+
57
+ # The workspace a catalog belongs to, from ACCOUNT_ID or USER_ID; nil on a
58
+ # single-user install.
59
+ def action_agent_catalog_owner
60
+ if ENV["ACCOUNT_ID"].present?
61
+ ActionAgent.account_class.to_s.constantize.find(ENV["ACCOUNT_ID"])
62
+ elsif ENV["USER_ID"].present?
63
+ ActionAgent.user_class.to_s.constantize.find(ENV["USER_ID"])
64
+ end
65
+ end
66
+
67
+ def action_agent_catalog!
68
+ key = ENV.fetch("KEY") { abort "Name the catalog: KEY=<catalog key>" }
69
+ ActionAgent::ScenarioCatalog.for_owner(action_agent_catalog_owner).find_by(key: key) ||
70
+ abort("No catalog #{key.inspect}#{ENV['ACCOUNT_ID'].present? || ENV['USER_ID'].present? ? ' in that workspace' : ''}")
71
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.9.0
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-01 00:00:00.000000000 Z
11
+ date: 2026-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activeagent
@@ -124,26 +124,49 @@ files:
124
124
  - README.md
125
125
  - app/assets/builds/action_agent.css
126
126
  - app/assets/builds/action_agent.js
127
+ - app/assets/builds/action_agent_recorder.js
128
+ - app/assets/builds/action_agent_replay.js
127
129
  - app/controllers/action_agent/api/agent_runs_controller.rb
128
130
  - app/controllers/action_agent/api/agents_controller.rb
129
131
  - app/controllers/action_agent/api/analytics_controller.rb
130
132
  - app/controllers/action_agent/api/api_keys_controller.rb
131
133
  - app/controllers/action_agent/api/base_controller.rb
134
+ - app/controllers/action_agent/api/claude_logins_controller.rb
132
135
  - app/controllers/action_agent/api/code_sessions_controller.rb
133
136
  - app/controllers/action_agent/api/dashboard_assistant_controller.rb
137
+ - app/controllers/action_agent/api/draft_pull_requests_controller.rb
138
+ - app/controllers/action_agent/api/evaluation_fixes_controller.rb
134
139
  - app/controllers/action_agent/api/evaluation_reports_controller.rb
135
140
  - app/controllers/action_agent/api/evaluations_controller.rb
141
+ - app/controllers/action_agent/api/explorations_controller.rb
142
+ - app/controllers/action_agent/api/github_app_manifests_controller.rb
136
143
  - app/controllers/action_agent/api/github_connections_controller.rb
144
+ - app/controllers/action_agent/api/github_installations_controller.rb
145
+ - app/controllers/action_agent/api/input_requests_controller.rb
137
146
  - app/controllers/action_agent/api/instance_tiers_controller.rb
138
147
  - app/controllers/action_agent/api/interaction_messages_controller.rb
139
148
  - app/controllers/action_agent/api/interactions_controller.rb
140
149
  - app/controllers/action_agent/api/mcp_controller.rb
141
150
  - app/controllers/action_agent/api/mcp_servers_controller.rb
151
+ - app/controllers/action_agent/api/members_controller.rb
142
152
  - app/controllers/action_agent/api/metrics_controller.rb
153
+ - app/controllers/action_agent/api/project_explorations_controller.rb
154
+ - app/controllers/action_agent/api/project_install_pull_requests_controller.rb
155
+ - app/controllers/action_agent/api/project_secrets_controller.rb
156
+ - app/controllers/action_agent/api/project_setup_controller.rb
157
+ - app/controllers/action_agent/api/project_sign_ins_controller.rb
158
+ - app/controllers/action_agent/api/projects_controller.rb
143
159
  - app/controllers/action_agent/api/provider_keys_controller.rb
144
160
  - app/controllers/action_agent/api/provider_models_controller.rb
161
+ - app/controllers/action_agent/api/recording_event_ingest_controller.rb
162
+ - app/controllers/action_agent/api/sandbox_browser_tickets_controller.rb
163
+ - app/controllers/action_agent/api/sandbox_browsers_controller.rb
145
164
  - app/controllers/action_agent/api/sandboxes_controller.rb
165
+ - app/controllers/action_agent/api/scenario_catalog_entries_controller.rb
166
+ - app/controllers/action_agent/api/scenario_catalogs_controller.rb
146
167
  - app/controllers/action_agent/api/session_recordings_controller.rb
168
+ - app/controllers/action_agent/api/sessions_controller.rb
169
+ - app/controllers/action_agent/api/telemetry_keys_controller.rb
147
170
  - app/controllers/action_agent/api/templates_controller.rb
148
171
  - app/controllers/action_agent/api/tools_controller.rb
149
172
  - app/controllers/action_agent/api/trace_reports_controller.rb
@@ -151,21 +174,31 @@ files:
151
174
  - app/controllers/action_agent/api/usage_controller.rb
152
175
  - app/controllers/action_agent/application_controller.rb
153
176
  - app/controllers/action_agent/dashboard_controller.rb
177
+ - app/controllers/action_agent/session_player_controller.rb
154
178
  - app/controllers/action_agent/traces_controller.rb
155
179
  - app/controllers/concerns/action_agent/api/agent_serialization.rb
156
180
  - app/controllers/concerns/action_agent/api/evaluation_run_starting.rb
157
181
  - app/controllers/concerns/action_agent/api/ingest_authentication.rb
158
182
  - app/controllers/concerns/action_agent/api/mcp_dashboard_tools.rb
183
+ - app/controllers/concerns/action_agent/api/project_browser.rb
184
+ - app/controllers/concerns/action_agent/api/project_secret_authorization.rb
159
185
  - app/controllers/concerns/action_agent/api/run_sandbox.rb
160
186
  - app/jobs/action_agent/agent_execution_job.rb
187
+ - app/jobs/action_agent/agent_resume_job.rb
161
188
  - app/jobs/action_agent/application_job.rb
162
189
  - app/jobs/action_agent/code_session_job.rb
190
+ - app/jobs/action_agent/draft_pull_request_job.rb
163
191
  - app/jobs/action_agent/evaluation_run_job.rb
192
+ - app/jobs/action_agent/exploration_job.rb
193
+ - app/jobs/action_agent/input_request_expiry_job.rb
164
194
  - app/jobs/action_agent/process_telemetry_traces_job.rb
195
+ - app/jobs/action_agent/project_evaluation_job.rb
196
+ - app/jobs/action_agent/project_setup_job.rb
165
197
  - app/jobs/action_agent/sandbox_cleanup_job.rb
166
198
  - app/jobs/action_agent/sandbox_provision_job.rb
167
199
  - app/jobs/action_agent/sandbox_run_job.rb
168
200
  - app/jobs/action_agent/trace_retention_job.rb
201
+ - app/jobs/action_agent/verify_evaluation_fix_job.rb
169
202
  - app/models/action_agent/agent.rb
170
203
  - app/models/action_agent/agent_context.rb
171
204
  - app/models/action_agent/agent_generation.rb
@@ -177,19 +210,30 @@ files:
177
210
  - app/models/action_agent/agent_version.rb
178
211
  - app/models/action_agent/api_key.rb
179
212
  - app/models/action_agent/application_record.rb
213
+ - app/models/action_agent/catalog_scenario.rb
180
214
  - app/models/action_agent/code_session.rb
215
+ - app/models/action_agent/draft_pull_request.rb
181
216
  - app/models/action_agent/evaluation.rb
182
217
  - app/models/action_agent/evaluation_run.rb
183
218
  - app/models/action_agent/evaluation_scenario.rb
184
219
  - app/models/action_agent/evaluation_scenario_result.rb
220
+ - app/models/action_agent/exploration.rb
185
221
  - app/models/action_agent/github_connection.rb
222
+ - app/models/action_agent/github_installation.rb
223
+ - app/models/action_agent/input_request.rb
186
224
  - app/models/action_agent/model_pricing.rb
225
+ - app/models/action_agent/project.rb
226
+ - app/models/action_agent/project_secret.rb
187
227
  - app/models/action_agent/provider_key.rb
188
228
  - app/models/action_agent/recording_action.rb
229
+ - app/models/action_agent/recording_event.rb
189
230
  - app/models/action_agent/recording_snapshot.rb
190
231
  - app/models/action_agent/sandbox_instance_tier.rb
191
232
  - app/models/action_agent/sandbox_run.rb
192
233
  - app/models/action_agent/sandbox_session.rb
234
+ - app/models/action_agent/scenario_catalog.rb
235
+ - app/models/action_agent/scenario_product.rb
236
+ - app/models/action_agent/scenario_set.rb
193
237
  - app/models/action_agent/session_recording.rb
194
238
  - app/models/action_agent/telemetry_trace.rb
195
239
  - app/models/concerns/action_agent/adapter_aware.rb
@@ -199,7 +243,10 @@ files:
199
243
  - app/queries/action_agent/metrics_report.rb
200
244
  - app/serializers/action_agent/agent_message_serializer.rb
201
245
  - app/serializers/action_agent/evaluation_serializer.rb
246
+ - app/serializers/action_agent/input_request_serializer.rb
202
247
  - app/serializers/action_agent/interaction_preview.rb
248
+ - app/serializers/action_agent/scenario_catalog_serializer.rb
249
+ - app/serializers/action_agent/session_summary_serializer.rb
203
250
  - app/serializers/action_agent/telemetry_trace_serializer.rb
204
251
  - app/serializers/action_agent/trace_interaction_serializer.rb
205
252
  - app/services/action_agent/agent_execution_service.rb
@@ -209,17 +256,27 @@ files:
209
256
  - app/services/action_agent/agent_sync.rb
210
257
  - app/services/action_agent/agent_tool_roster.rb
211
258
  - app/services/action_agent/agent_toolbox.rb
259
+ - app/services/action_agent/browser_live_ticket.rb
260
+ - app/services/action_agent/browser_sidecar.rb
261
+ - app/services/action_agent/browser_sign_in.rb
262
+ - app/services/action_agent/browser_tool_redaction.rb
212
263
  - app/services/action_agent/claude_code_auth.rb
213
264
  - app/services/action_agent/codex_session_events.rb
214
265
  - app/services/action_agent/dashboard_assistant_service.rb
266
+ - app/services/action_agent/draft_pull_request_publisher.rb
215
267
  - app/services/action_agent/evaluation_evidence.rb
268
+ - app/services/action_agent/evaluation_fix.rb
269
+ - app/services/action_agent/evaluation_fix_comparison.rb
216
270
  - app/services/action_agent/evaluation_report_import.rb
217
271
  - app/services/action_agent/evaluation_run_cost.rb
218
272
  - app/services/action_agent/evaluation_runner_service.rb
219
273
  - app/services/action_agent/evaluation_standing.rb
220
274
  - app/services/action_agent/evaluation_tool_resolver.rb
275
+ - app/services/action_agent/explorer_execution_service.rb
221
276
  - app/services/action_agent/github_client.rb
277
+ - app/services/action_agent/live_updates.rb
222
278
  - app/services/action_agent/local_sandbox_backend.rb
279
+ - app/services/action_agent/local_sandbox_claude_login.rb
223
280
  - app/services/action_agent/local_sandbox_databases.rb
224
281
  - app/services/action_agent/mcp_catalog.rb
225
282
  - app/services/action_agent/mcp_client.rb
@@ -229,13 +286,35 @@ files:
229
286
  - app/services/action_agent/ollama_host_probe.rb
230
287
  - app/services/action_agent/payload_bounds.rb
231
288
  - app/services/action_agent/playwright_mcp_client.rb
289
+ - app/services/action_agent/project_boot_fix.rb
290
+ - app/services/action_agent/project_capabilities.rb
291
+ - app/services/action_agent/project_install_pull_request.rb
292
+ - app/services/action_agent/project_preflight.rb
293
+ - app/services/action_agent/project_secret_discovery.rb
294
+ - app/services/action_agent/project_setup.rb
295
+ - app/services/action_agent/provider_credentials.rb
296
+ - app/services/action_agent/recording_event_ingest.rb
297
+ - app/services/action_agent/runtime_tool_roster.rb
298
+ - app/services/action_agent/sample_data/conference_ticket.rb
299
+ - app/services/action_agent/sandbox_boot_spec.rb
300
+ - app/services/action_agent/sandbox_browser.rb
301
+ - app/services/action_agent/sandbox_browser_driver.rb
302
+ - app/services/action_agent/sandbox_credential_paths.rb
303
+ - app/services/action_agent/sandbox_mail.rb
232
304
  - app/services/action_agent/sandbox_manifest.rb
233
305
  - app/services/action_agent/sandbox_orchestrator.rb
306
+ - app/services/action_agent/sandbox_patch.rb
307
+ - app/services/action_agent/scenario_catalog_import.rb
308
+ - app/services/action_agent/scenario_catalog_repository_import.rb
234
309
  - app/services/action_agent/scenario_evaluation_runner.rb
235
310
  - app/services/action_agent/secret_scrubber.rb
311
+ - app/services/action_agent/session_index.rb
236
312
  - app/services/action_agent/session_recording_service.rb
313
+ - app/services/action_agent/session_timeline.rb
237
314
  - app/services/action_agent/tool_discovery.rb
238
315
  - app/views/action_agent/dashboard/index.html.erb
316
+ - app/views/action_agent/github_app_manifests/created.html.erb
317
+ - app/views/action_agent/session_player/show.html.erb
239
318
  - app/views/action_agent/traces/_trace_detail.html.erb
240
319
  - app/views/action_agent/traces/index.html.erb
241
320
  - app/views/action_agent/traces/metrics.html.erb
@@ -245,8 +324,10 @@ files:
245
324
  - config/routes.rb
246
325
  - lib/action_agent.rb
247
326
  - lib/action_agent/assistant_request_filter.rb
327
+ - lib/action_agent/claude_login_process.rb
248
328
  - lib/action_agent/compatibility.rb
249
329
  - lib/action_agent/engine.rb
330
+ - lib/action_agent/secret_requests.rb
250
331
  - lib/action_agent/version.rb
251
332
  - lib/actionagent.rb
252
333
  - lib/generators/action_agent/install_generator.rb
@@ -262,9 +343,22 @@ files:
262
343
  - lib/generators/action_agent/templates/create_active_agent_github_connections.rb.erb
263
344
  - lib/generators/action_agent/templates/create_active_agent_telemetry_traces.rb.erb
264
345
  - lib/generators/action_agent/templates/ensure_agent_release_columns.rb.erb
346
+ - lib/generators/action_agent/templates/migrations/015_add_provider_key_scope.rb.erb
347
+ - lib/generators/action_agent/templates/migrations/016_create_active_agent_input_requests.rb.erb
348
+ - lib/generators/action_agent/templates/migrations/017_create_active_agent_recording_events.rb.erb
349
+ - lib/generators/action_agent/templates/migrations/018_add_browser_to_active_agent_sandbox_sessions.rb.erb
350
+ - lib/generators/action_agent/templates/migrations/019_create_active_agent_projects.rb.erb
351
+ - lib/generators/action_agent/templates/migrations/020_add_github_app_installations.rb.erb
352
+ - lib/generators/action_agent/templates/migrations/021_create_active_agent_explorations.rb.erb
353
+ - lib/generators/action_agent/templates/migrations/023_create_active_agent_draft_pull_requests.rb.erb
354
+ - lib/generators/action_agent/templates/migrations/024_add_kind_to_active_agent_project_secrets.rb.erb
355
+ - lib/generators/action_agent/templates/migrations/025_create_active_agent_scenario_catalogs.rb.erb
356
+ - lib/generators/action_agent/templates/migrations/026_add_evaluation_fixes_to_code_sessions.rb.erb
265
357
  - lib/tasks/action_agent.rake
358
+ - lib/tasks/browser.rake
266
359
  - lib/tasks/claude_code.rake
267
360
  - lib/tasks/sandbox.rake
361
+ - lib/tasks/scenario_catalogs.rake
268
362
  homepage: https://activeagents.ai
269
363
  licenses:
270
364
  - MIT