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,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionAgent
4
+ module Api
5
+ # The key the owner's applications send traces with, for the Organization
6
+ # view to show and copy. The dashboard page does not carry it
7
+ # (DashboardController).
8
+ class TelemetryKeysController < BaseController
9
+ before_action :require_owner!
10
+
11
+ # GET /api/telemetry_key
12
+ #
13
+ # `telemetry_api_key` is the owner's `telemetry_api_key`, or null when
14
+ # the owner has none.
15
+ def show
16
+ response.headers["Cache-Control"] = "no-store"
17
+ render json: { telemetry_api_key: current_owner.try(:telemetry_api_key) }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -7,7 +7,15 @@ module ActionAgent
7
7
  # happens in the browser. Initial state is handed over as a JSON data
8
8
  # attribute rather than through Inertia, so the engine works in any host
9
9
  # app without adding a frontend framework to it.
10
+ #
11
+ # The props carry no credential, because anything that reads the page's
12
+ # markup reads them, a session recorder included. A view that shows a key
13
+ # fetches it from its own endpoint (Api::TelemetryKeysController).
10
14
  class DashboardController < ApplicationController
15
+ # The session recorder's bundle, imported by the dashboard while the Run
16
+ # Agent workbench is open.
17
+ RECORDER_BUNDLE = "action_agent_recorder.js"
18
+
11
19
  # The React dashboard brings its own chrome, so it does not use the
12
20
  # server-rendered layout the traces views share.
13
21
  layout -> { ActionAgent.layout || "action_agent/react" }
@@ -46,7 +54,14 @@ module ActionAgent
46
54
  assistantEnabled: ActionAgent.assistant_enabled?,
47
55
  multiTenant: ActionAgent.multi_tenant?,
48
56
  upgradeUrl: ActionAgent.upgrade_url,
49
- signOutPath: ActionAgent.sign_out_path
57
+ memberInviteUrl: ActionAgent.member_invite_url,
58
+ providerKeyScope: ActionAgent.provider_key_scope,
59
+ personalProviderKeys: ProviderKey.personal_keys_enabled?,
60
+ signOutPath: ActionAgent.sign_out_path,
61
+ # Named here rather than by the layout, so a host layout
62
+ # (ActionAgent.layout) does not have to know about it. Nil when the
63
+ # host turned capture off, and the dashboard then loads no recorder.
64
+ recorderUrl: (helpers.asset_path(RECORDER_BUNDLE) if ActionAgent.capture_dashboard_sessions?)
50
65
  }
51
66
  end
52
67
 
@@ -90,11 +105,7 @@ module ActionAgent
90
105
  def current_account_props
91
106
  return nil unless current_owner
92
107
 
93
- {
94
- id: current_owner.id,
95
- name: current_owner.try(:name),
96
- telemetry_api_key: current_owner.try(:telemetry_api_key)
97
- }
108
+ { id: current_owner.id, name: current_owner.try(:name) }
98
109
  end
99
110
 
100
111
  # Where the engine is mounted, so the React app can build API URLs
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionAgent
4
+ # Serves the document the dashboard's session player runs in. It holds the
5
+ # replay bundle and no data: the dashboard fetches a recording's events
6
+ # over its own API and posts them into the frame.
7
+ #
8
+ # The dashboard frames it with sandbox="allow-scripts allow-same-origin".
9
+ # rrweb's Replayer rebuilds the recorded page inside an iframe of its own,
10
+ # sandboxed to allow-same-origin only, and an iframe created inside an
11
+ # opaque-origin document gets an opaque origin of its own, which the
12
+ # Replayer cannot write into. A replayed page is kept inert by that inner
13
+ # sandbox and by this response's policy, which the inner frame inherits:
14
+ # no script but the bundle, and nothing loaded from the network.
15
+ class SessionPlayerController < ApplicationController
16
+ BUNDLE = "action_agent_replay.js"
17
+
18
+ layout false
19
+
20
+ # GET <mount>/session_player
21
+ def show
22
+ response.headers["Content-Security-Policy"] = self.class.policy(bundle_url)
23
+ response.headers["X-Frame-Options"] = "SAMEORIGIN"
24
+ response.headers["Referrer-Policy"] = "no-referrer"
25
+ render "action_agent/session_player/show", locals: { script_path: helpers.asset_path(BUNDLE) }
26
+ end
27
+
28
+ # The frame's Content-Security-Policy, allowing +script_url+ as its only
29
+ # script. A host's own policy is not merged in: the frame needs nothing
30
+ # from it. A source expression cannot carry a query, and matching
31
+ # ignores one, so the URL's query is left out.
32
+ # @return [String]
33
+ def self.policy(script_url)
34
+ source = URI(script_url).tap { |uri| uri.query = uri.fragment = nil }.to_s
35
+ [
36
+ "default-src 'none'",
37
+ "script-src #{source}",
38
+ "style-src 'unsafe-inline'",
39
+ "img-src data: blob:",
40
+ "font-src data:",
41
+ "base-uri 'none'",
42
+ "form-action 'none'",
43
+ "frame-ancestors 'self'"
44
+ ].join("; ")
45
+ end
46
+
47
+ private
48
+
49
+ # The bundle's absolute URL, for the policy: a CSP source naming a single
50
+ # file needs its scheme and host, and an asset host may serve it from
51
+ # another origin. The page loads the bundle by its asset path, so behind
52
+ # a proxy that does not report https the script keeps the page's scheme.
53
+ # An http source still matches the https URL.
54
+ def bundle_url
55
+ URI.join("#{request.base_url}/", helpers.asset_path(BUNDLE)).to_s
56
+ end
57
+ end
58
+ end
@@ -38,6 +38,7 @@ module ActionAgent
38
38
  action_prompts: agent.action_prompts,
39
39
  instruction_sets: agent.instruction_sets,
40
40
  tools: agent.tools,
41
+ approval_required_tools: agent.approval_required_tools,
41
42
  mcp_servers: agent.mcp_servers,
42
43
  model_config: agent.model_config,
43
44
  response_format: agent.response_format,