actionagent 1.9.5 → 1.9.7
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 +4 -4
- data/app/assets/builds/action_agent.css +1 -1
- data/app/assets/builds/action_agent.js +62 -61
- data/app/controllers/action_agent/api/agents_controller.rb +15 -6
- data/app/controllers/action_agent/api/base_controller.rb +3 -2
- data/app/controllers/action_agent/api/mcp_server_configs_controller.rb +114 -0
- data/app/controllers/action_agent/api/mcp_servers_controller.rb +7 -4
- data/app/controllers/action_agent/api/metrics_controller.rb +5 -4
- data/app/controllers/action_agent/api/projects_controller.rb +29 -4
- data/app/controllers/action_agent/api/provider_keys_controller.rb +1 -1
- data/app/controllers/action_agent/api/provider_models_controller.rb +17 -5
- data/app/controllers/action_agent/api/sandboxes_controller.rb +31 -6
- data/app/controllers/action_agent/traces_controller.rb +3 -2
- data/app/controllers/concerns/action_agent/api/mcp_dashboard_tools.rb +4 -2
- data/app/jobs/action_agent/agent_execution_job.rb +26 -6
- data/app/jobs/action_agent/evaluation_judge_job.rb +3 -2
- data/app/models/action_agent/catalog_scenario.rb +8 -2
- data/app/models/action_agent/evaluation_run.rb +11 -3
- data/app/models/action_agent/evaluation_scenario_result.rb +12 -3
- data/app/models/action_agent/mcp_server_config.rb +273 -0
- data/app/models/action_agent/model_pricing.rb +135 -24
- data/app/models/action_agent/telemetry_trace.rb +35 -14
- data/app/queries/action_agent/agent_executions.rb +4 -1
- data/app/queries/action_agent/metrics_report.rb +1 -1
- data/app/serializers/action_agent/telemetry_trace_serializer.rb +1 -0
- data/app/services/action_agent/agent_execution_service.rb +4 -2
- data/app/services/action_agent/agent_scorecard.rb +16 -12
- data/app/services/action_agent/agent_tool_roster.rb +5 -2
- data/app/services/action_agent/evaluation_fix_comparison.rb +7 -3
- data/app/services/action_agent/evaluation_report_import.rb +14 -2
- data/app/services/action_agent/evaluation_run_cost.rb +6 -5
- data/app/services/action_agent/evaluation_tool_resolver.rb +35 -7
- data/app/services/action_agent/mcp_client.rb +36 -4
- data/app/services/action_agent/mcp_host_guard.rb +129 -0
- data/app/services/action_agent/mcp_tool_dispatcher.rb +15 -5
- data/app/services/action_agent/ollama_host_probe.rb +36 -4
- data/app/services/action_agent/scenario_catalog_import.rb +2 -0
- data/app/services/action_agent/scenario_evaluation_runner.rb +69 -13
- data/app/services/action_agent/tool_discovery.rb +5 -1
- data/config/routes.rb +6 -0
- data/lib/action_agent/engine.rb +10 -0
- data/lib/action_agent/version.rb +1 -1
- data/lib/action_agent.rb +17 -0
- data/lib/generators/action_agent/templates/action_agent.rb.erb +11 -0
- data/lib/generators/action_agent/templates/migrations/030_add_evaluation_scoring_leases.rb.erb +8 -0
- data/lib/generators/action_agent/templates/migrations/031_add_catalog_scenario_metadata.rb.erb +24 -0
- data/lib/generators/action_agent/templates/migrations/032_create_active_agent_mcp_server_configs.rb.erb +53 -0
- metadata +8 -2
|
@@ -41,6 +41,7 @@ module ActionAgent
|
|
|
41
41
|
# any replay, and one started here is stopped once the run ends.
|
|
42
42
|
class ScenarioEvaluationRunner < EvaluationRunnerService
|
|
43
43
|
Evals = ActiveAgent::Evals
|
|
44
|
+
JUDGE_LEASE_DURATION = 30.minutes
|
|
44
45
|
|
|
45
46
|
# The providers a candidate model name resolves against. `mock` is the
|
|
46
47
|
# framework's test double, accepted so the test suite can compare cohorts
|
|
@@ -187,17 +188,20 @@ module ActionAgent
|
|
|
187
188
|
# A job delivered again for a result that is already scored, or that a
|
|
188
189
|
# concurrent delivery has claimed, scores nothing. It still checks
|
|
189
190
|
# whether the run is complete: the earlier delivery may have stored the
|
|
190
|
-
# last result and stopped before completing the run.
|
|
191
|
+
# last result and stopped before completing the run. A result another
|
|
192
|
+
# delivery holds a live lease on is tried again when the lease expires
|
|
193
|
+
# (see #wait_for_claim!).
|
|
191
194
|
def judge_result!(row)
|
|
192
195
|
run = row.evaluation_run
|
|
193
196
|
return unless run.running?
|
|
194
|
-
return finish_fan_out!(run) unless row.pending?
|
|
197
|
+
return finish_fan_out!(run) unless row.pending?
|
|
198
|
+
return wait_for_claim!(row, run) unless claim_result!(row)
|
|
195
199
|
|
|
196
200
|
spec = fan_out_specs(run).fetch([ row.provider.to_s, row.model ]) do
|
|
197
201
|
Evals::ModelSpec.new(label: row.model, provider: row.provider.to_s, model: row.model)
|
|
198
202
|
end
|
|
199
203
|
result = fan_out_scorer(run).evaluate(Evals::Scenario.from_hash(row.evaluated_scenario), spec, replay_from(row))
|
|
200
|
-
|
|
204
|
+
store_claimed_result!(row,
|
|
201
205
|
status: result.status,
|
|
202
206
|
score: result.score,
|
|
203
207
|
scores: result.scores,
|
|
@@ -227,7 +231,15 @@ module ActionAgent
|
|
|
227
231
|
row = stored_result(run, scenario, spec)
|
|
228
232
|
task = Evals::Scenario.from_hash(scenario.as_json_summary)
|
|
229
233
|
row ||= store_replay(run, scenario, task, spec, Evals::Replay.failed(error))
|
|
230
|
-
|
|
234
|
+
attributes = { status: :errored, error_message: row.error_message.presence || error_text(error) }
|
|
235
|
+
if scoring_leases?
|
|
236
|
+
# Another replay delivery may fail while this result is being
|
|
237
|
+
# scored. Only an unclaimed replay belongs to this failure path.
|
|
238
|
+
EvaluationScenarioResult.where(id: row.id, status: :pending, scoring_token: nil)
|
|
239
|
+
.update_all(attributes.merge(updated_at: Time.current))
|
|
240
|
+
elsif row.pending?
|
|
241
|
+
row.update!(attributes)
|
|
242
|
+
end
|
|
231
243
|
end
|
|
232
244
|
end
|
|
233
245
|
finish_fan_out!(run)
|
|
@@ -237,7 +249,7 @@ module ActionAgent
|
|
|
237
249
|
# still completes.
|
|
238
250
|
def fail_judging!(row, error)
|
|
239
251
|
run = row.evaluation_run
|
|
240
|
-
|
|
252
|
+
store_claimed_result!(row, status: :errored, error_message: [ row.error_message.presence, "Scoring failed: #{error_text(error)}" ].compact.join(" ")) if row.pending?
|
|
241
253
|
finish_fan_out!(run)
|
|
242
254
|
end
|
|
243
255
|
|
|
@@ -331,15 +343,59 @@ module ActionAgent
|
|
|
331
343
|
@evaluation.scenarios.where(id: ids).count * specs.size
|
|
332
344
|
end
|
|
333
345
|
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
#
|
|
337
|
-
#
|
|
338
|
-
#
|
|
339
|
-
#
|
|
340
|
-
#
|
|
346
|
+
# A timestamp comparison alone only rejects a stale reader. A duplicate
|
|
347
|
+
# delivered after that write reads the new timestamp and could score too.
|
|
348
|
+
# The lease excludes fresh readers as well, without holding a database
|
|
349
|
+
# lock across a provider call. A redelivery can reclaim an expired lease.
|
|
350
|
+
#
|
|
351
|
+
# Without the lease columns (migration 030 not yet run) the claim is the
|
|
352
|
+
# timestamp comparison alone, as before the lease.
|
|
341
353
|
def claim_result!(row)
|
|
342
|
-
|
|
354
|
+
now = Time.current
|
|
355
|
+
claim = EvaluationScenarioResult.where(id: row.id, status: :pending, updated_at: row.updated_at)
|
|
356
|
+
return claim.update_all(updated_at: now) == 1 unless scoring_leases?
|
|
357
|
+
|
|
358
|
+
token = SecureRandom.uuid
|
|
359
|
+
claimed = claim.where("scoring_token IS NULL OR scoring_expires_at <= ?", now)
|
|
360
|
+
.update_all(scoring_token: token, scoring_expires_at: now + JUDGE_LEASE_DURATION, updated_at: now)
|
|
361
|
+
@scoring_token = token if claimed == 1
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
# A claim lost to another delivery leaves the result pending, and that
|
|
365
|
+
# delivery may be a worker that stopped: the queue's redelivery of its
|
|
366
|
+
# job lands here, inside the lease the stopped worker still holds. So the
|
|
367
|
+
# job is enqueued again for when that lease expires. If the holder stores
|
|
368
|
+
# the result first, the later delivery finds it scored and only checks
|
|
369
|
+
# whether the run is complete. A result left pending with no live lease
|
|
370
|
+
# (the claim raced another write to the row) is tried again at once.
|
|
371
|
+
# Without the lease columns a lost claim is a concurrent delivery that is
|
|
372
|
+
# scoring the result now, as before.
|
|
373
|
+
def wait_for_claim!(row, run)
|
|
374
|
+
current = EvaluationScenarioResult.find_by(id: row.id) if scoring_leases?
|
|
375
|
+
if current&.pending?
|
|
376
|
+
retry_at = [ current.scoring_expires_at, Time.current ].compact.max
|
|
377
|
+
EvaluationJudgeJob.set(wait_until: retry_at).perform_later(row.id, @selection.to_h, run.id)
|
|
378
|
+
end
|
|
379
|
+
finish_fan_out!(run)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Fence late successes and failures: after a lease is reclaimed, the old
|
|
383
|
+
# worker cannot overwrite its successor. Only the current owner releases
|
|
384
|
+
# the lease. A failure before claiming may mark an unclaimed row errored.
|
|
385
|
+
def store_claimed_result!(row, **attributes)
|
|
386
|
+
return row.update!(attributes) unless scoring_leases?
|
|
387
|
+
|
|
388
|
+
row.assign_attributes(attributes)
|
|
389
|
+
row.validate!
|
|
390
|
+
EvaluationScenarioResult.where(id: row.id, status: :pending, scoring_token: @scoring_token)
|
|
391
|
+
.update_all(attributes.merge(scoring_token: nil, scoring_expires_at: nil, updated_at: Time.current))
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Whether migration 030's lease columns are installed. A host that
|
|
395
|
+
# upgraded the gem without running the generator keeps scoring with the
|
|
396
|
+
# timestamp claim instead of failing every judge job on a missing column.
|
|
397
|
+
def scoring_leases?
|
|
398
|
+
(%w[scoring_token scoring_expires_at] - EvaluationScenarioResult.column_names).empty?
|
|
343
399
|
end
|
|
344
400
|
|
|
345
401
|
# What Evals::Runner does with a replay that raises: an errored replay,
|
|
@@ -37,7 +37,9 @@ module ActionAgent
|
|
|
37
37
|
# rules (single-user, per-user, or multi-tenant) decide what is visible.
|
|
38
38
|
# The same goes for checkout sandbox runtimes: the caller hands in the live
|
|
39
39
|
# ones it may see (SandboxSession.runtime_server_listings), and they are
|
|
40
|
-
# listed beside the catalog under their "sandbox:<session_id>" keys.
|
|
40
|
+
# listed beside the catalog under their "sandbox:<session_id>" keys. The
|
|
41
|
+
# servers the owner added (MCPServerConfig.listings) are handed in the same
|
|
42
|
+
# way, under their "custom:<id>" keys.
|
|
41
43
|
class ToolDiscovery
|
|
42
44
|
DEFAULT_WINDOW_HOURS = 24 * 7
|
|
43
45
|
MAX_WINDOW_HOURS = 24 * 90
|
|
@@ -543,6 +545,8 @@ module ActionAgent
|
|
|
543
545
|
# from traffic is real but undocumented here, and the view says so.
|
|
544
546
|
known: !catalog.nil?,
|
|
545
547
|
runtime: runtime,
|
|
548
|
+
# A server the owner added on the MCP Services page ("custom:<id>").
|
|
549
|
+
custom: MCPServerConfig.key?(key),
|
|
546
550
|
status: server_status(calls, configured, catalog),
|
|
547
551
|
calls: calls,
|
|
548
552
|
errors: bucket ? bucket[:errors] : 0,
|
data/config/routes.rb
CHANGED
|
@@ -193,6 +193,12 @@ ActionAgent::Engine.routes.draw do
|
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
+
# The caller's own remote MCP servers, enabled on agents as
|
|
197
|
+
# "custom:<id>". Header values are write-only; test runs tools/list.
|
|
198
|
+
resources :mcp_server_configs, only: [ :index, :create, :update, :destroy ] do
|
|
199
|
+
post :test, on: :member
|
|
200
|
+
end
|
|
201
|
+
|
|
196
202
|
resources :instance_tiers, only: [ :index, :show ] do
|
|
197
203
|
collection do
|
|
198
204
|
get :recommend
|
data/lib/action_agent/engine.rb
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# The class body below reads Zeitwerk's inflector. Rails requires Zeitwerk
|
|
4
|
+
# only when an application sets up its autoloaders, which is after
|
|
5
|
+
# Bundler.require has loaded this file; a host that reaches it earlier does so
|
|
6
|
+
# by chance (Action Cable's engine loads it as a side effect). So the constant
|
|
7
|
+
# has to come from here. Zeitwerk is a dependency of Active Support, so it is
|
|
8
|
+
# always installed.
|
|
9
|
+
require "zeitwerk"
|
|
3
10
|
require_relative "assistant_request_filter"
|
|
4
11
|
|
|
5
12
|
module ActionAgent
|
|
@@ -25,7 +32,10 @@ module ActionAgent
|
|
|
25
32
|
"mcp_tool_dispatcher" => "MCPToolDispatcher",
|
|
26
33
|
"mcp_controller" => "MCPController",
|
|
27
34
|
"mcp_dashboard_tools" => "MCPDashboardTools",
|
|
35
|
+
"mcp_host_guard" => "MCPHostGuard",
|
|
28
36
|
"mcp_recording_middleware" => "MCPRecordingMiddleware",
|
|
37
|
+
"mcp_server_config" => "MCPServerConfig",
|
|
38
|
+
"mcp_server_configs_controller" => "MCPServerConfigsController",
|
|
29
39
|
"mcp_servers_controller" => "MCPServersController",
|
|
30
40
|
"playwright_mcp_client" => "PlaywrightMCPClient"
|
|
31
41
|
}.freeze
|
data/lib/action_agent/version.rb
CHANGED
data/lib/action_agent.rb
CHANGED
|
@@ -887,6 +887,22 @@ module ActionAgent
|
|
|
887
887
|
# @return [Array<Hash>]
|
|
888
888
|
attr_accessor :mcp_catalog
|
|
889
889
|
|
|
890
|
+
# Whether a dashboard user's own MCP server (MCPServerConfig, added on the
|
|
891
|
+
# MCP Services page) may point at a loopback, private, link-local or
|
|
892
|
+
# otherwise non-public address. Off by default: those servers are reached
|
|
893
|
+
# from the dashboard's own network, so a URL such as
|
|
894
|
+
# http://169.254.169.254/ or http://10.0.0.5/admin would let any user make
|
|
895
|
+
# the dashboard call an address only it can reach. MCPHostGuard refuses
|
|
896
|
+
# such a URL when it is saved, and refuses a host name that resolves to
|
|
897
|
+
# one when it is called. Turn it on for local development, where the
|
|
898
|
+
# server under test runs on localhost, or for a single-user install whose
|
|
899
|
+
# user already has that network access.
|
|
900
|
+
#
|
|
901
|
+
# Host registrations (+mcp_catalog+) and checkout sandbox runtimes are the
|
|
902
|
+
# host app's own configuration and are not affected.
|
|
903
|
+
# @return [Boolean]
|
|
904
|
+
attr_accessor :allow_private_mcp_hosts
|
|
905
|
+
|
|
890
906
|
# Host-declared ActiveAgent::SchemaTools subclasses whose generated tools
|
|
891
907
|
# are offered alongside AgentToolbox's built-ins: each generated tool is
|
|
892
908
|
# individually selectable in the agent editor, dispatched by name at
|
|
@@ -1358,6 +1374,7 @@ module ActionAgent
|
|
|
1358
1374
|
@user_menu_links = nil
|
|
1359
1375
|
@sign_in_path = nil
|
|
1360
1376
|
@mcp_catalog = []
|
|
1377
|
+
@allow_private_mcp_hosts = false
|
|
1361
1378
|
@agent_actor_resolver = nil
|
|
1362
1379
|
@schema_tools = nil
|
|
1363
1380
|
@schema_tools_path = "app/agent_tools"
|
|
@@ -317,6 +317,17 @@ ActionAgent.configure do |config|
|
|
|
317
317
|
# Expired sandboxes are stopped by `bin/rails action_agent:sandbox:reap`.
|
|
318
318
|
# Schedule it every few minutes.
|
|
319
319
|
|
|
320
|
+
# ==========================================================================
|
|
321
|
+
# MCP servers
|
|
322
|
+
# ==========================================================================
|
|
323
|
+
#
|
|
324
|
+
# Users add their own remote MCP servers on the MCP Services page. Their
|
|
325
|
+
# URLs may not reach a loopback, private or link-local address unless this
|
|
326
|
+
# is on: those servers are called from the dashboard's own network. Turn it
|
|
327
|
+
# on in development to test a server running on localhost.
|
|
328
|
+
#
|
|
329
|
+
# config.allow_private_mcp_hosts = Rails.env.development?
|
|
330
|
+
|
|
320
331
|
# ==========================================================================
|
|
321
332
|
# UI
|
|
322
333
|
# ==========================================================================
|
data/lib/generators/action_agent/templates/migrations/030_add_evaluation_scoring_leases.rb.erb
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddEvaluationScoringLeases < ActiveRecord::Migration<%= migration_version %>
|
|
4
|
+
def change
|
|
5
|
+
add_column "#{ActionAgent.table_name_prefix}evaluation_scenario_results", :scoring_token, :string
|
|
6
|
+
add_column "#{ActionAgent.table_name_prefix}evaluation_scenario_results", :scoring_expires_at, :datetime
|
|
7
|
+
end
|
|
8
|
+
end
|
data/lib/generators/action_agent/templates/migrations/031_add_catalog_scenario_metadata.rb.erb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddCatalogScenarioMetadata < ActiveRecord::Migration<%= migration_version %>
|
|
4
|
+
def up
|
|
5
|
+
return unless table_exists?(scenarios_table)
|
|
6
|
+
return if column_exists?(scenarios_table, :metadata)
|
|
7
|
+
|
|
8
|
+
type = connection.adapter_name.to_s.downcase.include?("postgres") ? :jsonb : :json
|
|
9
|
+
add_column scenarios_table, :metadata, type
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def down
|
|
13
|
+
return unless table_exists?(scenarios_table)
|
|
14
|
+
return unless column_exists?(scenarios_table, :metadata)
|
|
15
|
+
|
|
16
|
+
remove_column scenarios_table, :metadata
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def scenarios_table
|
|
22
|
+
"#{ActionAgent.table_name_prefix}catalog_scenarios"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# MCP servers a dashboard user adds on the MCP Services page
|
|
4
|
+
# (ActionAgent::MCPServerConfig): a remote server's URL, its request headers
|
|
5
|
+
# (encrypted at rest, in secret_headers), and what the last connection test
|
|
6
|
+
# found. Each row belongs to an account or a user, as provider keys do.
|
|
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 CreateActiveAgentMCPServerConfigs < ActiveRecord::Migration<%= migration_version %>
|
|
12
|
+
def change
|
|
13
|
+
prefix = ActionAgent.table_name_prefix
|
|
14
|
+
|
|
15
|
+
create_table "#{prefix}mcp_server_configs" do |t|
|
|
16
|
+
t.string :name, null: false
|
|
17
|
+
t.text :description
|
|
18
|
+
t.string :url, null: false, limit: 2048
|
|
19
|
+
# A JSON object of header name => value, encrypted.
|
|
20
|
+
t.text :secret_headers
|
|
21
|
+
t.boolean :enabled, null: false, default: true
|
|
22
|
+
t.datetime :last_tested_at
|
|
23
|
+
# "ok" or "failed", and the error of a failed test.
|
|
24
|
+
t.string :last_test_status
|
|
25
|
+
t.text :last_test_error
|
|
26
|
+
# The tool names the last successful test listed.
|
|
27
|
+
t.column :tool_names, json_type, **json_default([])
|
|
28
|
+
t.bigint :account_id
|
|
29
|
+
t.bigint :user_id
|
|
30
|
+
t.timestamps
|
|
31
|
+
t.index :account_id, name: "index_#{prefix}mcp_server_configs_on_account"
|
|
32
|
+
t.index :user_id, name: "index_#{prefix}mcp_server_configs_on_user"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def json_type
|
|
39
|
+
@json_type ||= postgres? ? :jsonb : :json
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# MySQL rejects a default on a JSON column outright, so the column is
|
|
43
|
+
# created without one there.
|
|
44
|
+
def json_default(value, null: nil)
|
|
45
|
+
return {} unless postgres?
|
|
46
|
+
|
|
47
|
+
null.nil? ? { default: value } : { default: value, null: null }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def postgres?
|
|
51
|
+
connection.adapter_name.to_s.downcase.include?("postgres")
|
|
52
|
+
end
|
|
53
|
+
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.9.
|
|
4
|
+
version: 1.9.7
|
|
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-
|
|
11
|
+
date: 2026-11-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activeagent
|
|
@@ -150,6 +150,7 @@ files:
|
|
|
150
150
|
- app/controllers/action_agent/api/interaction_messages_controller.rb
|
|
151
151
|
- app/controllers/action_agent/api/interactions_controller.rb
|
|
152
152
|
- app/controllers/action_agent/api/mcp_controller.rb
|
|
153
|
+
- app/controllers/action_agent/api/mcp_server_configs_controller.rb
|
|
153
154
|
- app/controllers/action_agent/api/mcp_servers_controller.rb
|
|
154
155
|
- app/controllers/action_agent/api/members_controller.rb
|
|
155
156
|
- app/controllers/action_agent/api/metrics_controller.rb
|
|
@@ -229,6 +230,7 @@ files:
|
|
|
229
230
|
- app/models/action_agent/github_webhook_delivery.rb
|
|
230
231
|
- app/models/action_agent/input_request.rb
|
|
231
232
|
- app/models/action_agent/interaction_feedback.rb
|
|
233
|
+
- app/models/action_agent/mcp_server_config.rb
|
|
232
234
|
- app/models/action_agent/model_pricing.rb
|
|
233
235
|
- app/models/action_agent/project.rb
|
|
234
236
|
- app/models/action_agent/project_secret.rb
|
|
@@ -297,6 +299,7 @@ files:
|
|
|
297
299
|
- app/services/action_agent/local_sandbox_databases.rb
|
|
298
300
|
- app/services/action_agent/mcp_catalog.rb
|
|
299
301
|
- app/services/action_agent/mcp_client.rb
|
|
302
|
+
- app/services/action_agent/mcp_host_guard.rb
|
|
300
303
|
- app/services/action_agent/mcp_recording_middleware.rb
|
|
301
304
|
- app/services/action_agent/mcp_tool_dispatcher.rb
|
|
302
305
|
- app/services/action_agent/mock_sandbox_backend.rb
|
|
@@ -377,6 +380,9 @@ files:
|
|
|
377
380
|
- lib/generators/action_agent/templates/migrations/027_create_active_agent_interaction_feedbacks.rb.erb
|
|
378
381
|
- lib/generators/action_agent/templates/migrations/028_add_conversations_to_code_sessions.rb.erb
|
|
379
382
|
- lib/generators/action_agent/templates/migrations/029_create_active_agent_github_webhook_deliveries.rb.erb
|
|
383
|
+
- lib/generators/action_agent/templates/migrations/030_add_evaluation_scoring_leases.rb.erb
|
|
384
|
+
- lib/generators/action_agent/templates/migrations/031_add_catalog_scenario_metadata.rb.erb
|
|
385
|
+
- lib/generators/action_agent/templates/migrations/032_create_active_agent_mcp_server_configs.rb.erb
|
|
380
386
|
- lib/tasks/action_agent.rake
|
|
381
387
|
- lib/tasks/browser.rake
|
|
382
388
|
- lib/tasks/claude_code.rake
|