actionagent 1.3.0 → 1.5.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.
- checksums.yaml +4 -4
- data/app/assets/builds/action_agent.css +1 -1
- data/app/assets/builds/action_agent.js +70 -48
- data/app/controllers/action_agent/api/agent_runs_controller.rb +3 -1
- data/app/controllers/action_agent/api/agents_controller.rb +116 -9
- data/app/controllers/action_agent/api/dashboard_assistant_controller.rb +83 -0
- data/app/controllers/action_agent/api/evaluations_controller.rb +22 -7
- data/app/controllers/action_agent/api/interaction_messages_controller.rb +98 -0
- data/app/controllers/action_agent/dashboard_controller.rb +1 -0
- data/app/models/action_agent/agent.rb +60 -18
- data/app/models/action_agent/agent_run.rb +99 -0
- data/app/models/action_agent/evaluation_run.rb +14 -6
- data/app/models/action_agent/evaluation_scenario_result.rb +24 -4
- data/app/models/action_agent/telemetry_trace.rb +16 -1
- data/app/serializers/action_agent/agent_message_serializer.rb +1 -0
- data/app/services/action_agent/agent_execution_service.rb +294 -16
- data/app/services/action_agent/agent_registrar.rb +7 -6
- data/app/services/action_agent/agent_toolbox.rb +45 -3
- data/app/services/action_agent/dashboard_assistant_service.rb +342 -0
- data/app/services/action_agent/evaluation_evidence.rb +234 -0
- data/app/services/action_agent/evaluation_runner_service.rb +13 -3
- data/app/services/action_agent/evaluation_tool_resolver.rb +10 -2
- data/app/services/action_agent/mcp_client.rb +167 -0
- data/app/services/action_agent/mcp_tool_dispatcher.rb +116 -0
- data/app/services/action_agent/playwright_mcp_client.rb +11 -126
- data/app/services/action_agent/scenario_evaluation_runner.rb +49 -15
- data/config/routes.rb +11 -1
- data/lib/action_agent/assistant_request_filter.rb +22 -0
- data/lib/action_agent/engine.rb +5 -0
- data/lib/action_agent/version.rb +1 -1
- data/lib/action_agent.rb +32 -0
- data/lib/generators/action_agent/templates/action_agent.rb.erb +12 -0
- metadata +10 -6
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ActionAgent
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# Minimal MCP client (streamable HTTP transport) for a Playwright MCP
|
|
8
|
-
# server — typically `npx @playwright/mcp --port 8931` running beside the
|
|
9
|
-
# app in development, or a sandbox-provisioned browser container in
|
|
10
|
-
# production. Speaks just enough JSON-RPC for tools/call: initialize once
|
|
11
|
-
# per process, then call tools under the session id the server hands back.
|
|
12
|
-
class PlaywrightMCPClient
|
|
4
|
+
# The Playwright MCP server as one configured MCPClient: a process-wide
|
|
5
|
+
# instance pointed at the url PLAYWRIGHT_MCP_URL names.
|
|
6
|
+
class PlaywrightMCPClient < MCPClient
|
|
13
7
|
DEFAULT_URL = ENV.fetch("PLAYWRIGHT_MCP_URL", "http://host.orb.internal:8931/mcp")
|
|
14
|
-
OPEN_TIMEOUT_SECONDS = 5
|
|
15
|
-
READ_TIMEOUT_SECONDS = 60
|
|
16
|
-
|
|
17
|
-
class Error < StandardError; end
|
|
18
8
|
|
|
19
9
|
def self.instance
|
|
20
10
|
@instance ||= new
|
|
@@ -25,124 +15,19 @@ module ActionAgent
|
|
|
25
15
|
end
|
|
26
16
|
|
|
27
17
|
def initialize(url: DEFAULT_URL)
|
|
28
|
-
|
|
29
|
-
@mutex = Mutex.new
|
|
18
|
+
super(url: url, label: "Playwright")
|
|
30
19
|
end
|
|
31
20
|
|
|
32
|
-
#
|
|
21
|
+
# Restarting the shared instance on an unreachable server is this
|
|
22
|
+
# subclass's concern: the next call re-initializes rather than reusing a
|
|
23
|
+
# session the server has forgotten. The message names the local fix.
|
|
33
24
|
def call_tool(name, arguments = {})
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
response = post(
|
|
37
|
-
{ jsonrpc: "2.0", id: next_id, method: "tools/call",
|
|
38
|
-
params: { name: name, arguments: arguments } },
|
|
39
|
-
session: @session_id
|
|
40
|
-
)
|
|
41
|
-
result = response["result"]
|
|
42
|
-
unless result
|
|
43
|
-
Rails.logger.warn("[PlaywrightMCPClient] #{name} unexpected response: #{response.inspect[0, 500]}")
|
|
44
|
-
raise Error, (response.dig("error", "message") || "empty MCP response")
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
text = Array(result["content"]).filter_map { |block| block["text"] }.join("\n")
|
|
48
|
-
{ text: text, is_error: result["isError"] ? true : false }
|
|
49
|
-
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Net::OpenTimeout, SocketError => e
|
|
25
|
+
super
|
|
26
|
+
rescue MCPClient::Error => e
|
|
50
27
|
self.class.reset!
|
|
51
|
-
raise Error, "
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
def ensure_session!
|
|
57
|
-
@mutex.synchronize do
|
|
58
|
-
next if @session_id
|
|
59
|
-
|
|
60
|
-
_body, response = post_raw(
|
|
61
|
-
{ jsonrpc: "2.0", id: next_id, method: "initialize",
|
|
62
|
-
params: { protocolVersion: "2025-03-26", capabilities: {},
|
|
63
|
-
clientInfo: { name: "activeagents", version: "1.0" } } }
|
|
64
|
-
)
|
|
65
|
-
@session_id = response["mcp-session-id"]
|
|
66
|
-
raise Error, "MCP server did not return a session id" unless @session_id
|
|
67
|
-
|
|
68
|
-
post({ jsonrpc: "2.0", method: "notifications/initialized" }, session: @session_id)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def post(payload, session: nil)
|
|
73
|
-
body, _response = post_raw(payload, session: session)
|
|
74
|
-
body
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def post_raw(payload, session: nil)
|
|
78
|
-
# Tool calls run inside the provider SDK's streaming enumerator — a
|
|
79
|
-
# fiber, where Net::HTTP reads of SSE bodies misbehave (headers arrive,
|
|
80
|
-
# body comes back empty). A dedicated thread always does real blocking
|
|
81
|
-
# IO outside any fiber/scheduler context.
|
|
82
|
-
Thread.new { blocking_post_raw(payload, session: session) }.value
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def blocking_post_raw(payload, session: nil)
|
|
86
|
-
http = Net::HTTP.new(@uri.host, @uri.port)
|
|
87
|
-
# Container->host bridge hostnames (host.orb.internal) publish an IPv6
|
|
88
|
-
# address whose path doesn't reach the server; dual-stack connects then
|
|
89
|
-
# fail intermittently. Pin to IPv4 while keeping the Host header.
|
|
90
|
-
if (ipv4 = ipv4_address)
|
|
91
|
-
http.ipaddr = ipv4
|
|
92
|
-
end
|
|
93
|
-
http.open_timeout = OPEN_TIMEOUT_SECONDS
|
|
94
|
-
http.read_timeout = READ_TIMEOUT_SECONDS
|
|
95
|
-
request = Net::HTTP::Post.new(@uri.request_uri)
|
|
96
|
-
request["Content-Type"] = "application/json"
|
|
97
|
-
request["Accept"] = "application/json, text/event-stream"
|
|
98
|
-
request["Mcp-Session-Id"] = session if session
|
|
99
|
-
request.body = payload.to_json
|
|
100
|
-
|
|
101
|
-
response = http.request(request)
|
|
102
|
-
Rails.logger.debug(
|
|
103
|
-
"[PlaywrightMCPClient] #{payload[:method]} -> #{response.code} " \
|
|
104
|
-
"ct=#{response['Content-Type']} bytes=#{response.body.to_s.bytesize} session=#{session ? 'yes' : 'no'}"
|
|
105
|
-
)
|
|
106
|
-
unless response.code.to_i.between?(200, 299)
|
|
107
|
-
Rails.logger.warn("[PlaywrightMCPClient] HTTP #{response.code}: #{response.body.to_s[0, 300]}")
|
|
108
|
-
raise Error, "MCP server returned HTTP #{response.code}"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
parsed = parse_body(response)
|
|
112
|
-
if parsed.empty? && payload[:id]
|
|
113
|
-
Rails.logger.warn("[PlaywrightMCPClient] unparsed body (#{response['Content-Type']}): #{response.body.to_s[0, 500]}")
|
|
114
|
-
end
|
|
115
|
-
[ parsed, response ]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Streamable HTTP answers as plain JSON or as an SSE stream whose data:
|
|
119
|
-
# lines carry the JSON-RPC response — accept both.
|
|
120
|
-
def parse_body(response)
|
|
121
|
-
body = response.body.to_s
|
|
122
|
-
return {} if body.empty?
|
|
123
|
-
|
|
124
|
-
if response["Content-Type"].to_s.include?("text/event-stream")
|
|
125
|
-
body.lines
|
|
126
|
-
.select { |line| line.start_with?("data:") }
|
|
127
|
-
.filter_map { |line| JSON.parse(line.delete_prefix("data:").strip) rescue nil }
|
|
128
|
-
.find { |json| json["result"] || json["error"] } || {}
|
|
129
|
-
else
|
|
130
|
-
JSON.parse(body)
|
|
131
|
-
end
|
|
132
|
-
rescue JSON::ParserError
|
|
133
|
-
{}
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def ipv4_address
|
|
137
|
-
return @ipv4_address if defined?(@ipv4_address)
|
|
138
|
-
|
|
139
|
-
@ipv4_address = Resolv.getaddresses(@uri.host).find { |address| address =~ Resolv::IPv4::Regex }
|
|
140
|
-
rescue Resolv::ResolvError
|
|
141
|
-
@ipv4_address = nil
|
|
142
|
-
end
|
|
28
|
+
raise Error, "#{e.message}: start it with `npx @playwright/mcp --port 8931`" if e.message.include?("unreachable")
|
|
143
29
|
|
|
144
|
-
|
|
145
|
-
@id = (@id || 0) + 1
|
|
30
|
+
raise
|
|
146
31
|
end
|
|
147
32
|
end
|
|
148
33
|
end
|
|
@@ -45,21 +45,35 @@ module ActionAgent
|
|
|
45
45
|
return run
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
ensure_judge_defined_kpis! if @evaluation.judge_defined?
|
|
49
|
-
|
|
50
48
|
records = scenarios.index_by(&:key)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
tasks = scenarios.map { |scenario| Evals::Scenario.from_hash(scenario.as_json_summary) }
|
|
50
|
+
expected = tasks.product(specs).map { |task, spec| [ task.key, spec.label ] }
|
|
51
|
+
# Every result tests membership twice, so look the pairs up in a set;
|
|
52
|
+
# `expected` stays an array for the completeness comparison below, and
|
|
53
|
+
# `persisted` sorts the same way either way.
|
|
54
|
+
allowed = expected.to_set
|
|
55
|
+
persisted = Set.new
|
|
56
|
+
on_result = lambda do |result|
|
|
57
|
+
pair = [ result.scenario.key, result.label ]
|
|
58
|
+
raise ArgumentError, "unexpected or duplicate scenario evaluation result" unless allowed.include?(pair) && !persisted.include?(pair)
|
|
59
|
+
|
|
60
|
+
persist(run, records.fetch(result.scenario.key), result)
|
|
61
|
+
persisted << pair
|
|
62
|
+
end
|
|
63
|
+
adapter = ActionAgent.scenario_evaluation_adapter_resolver&.call(@evaluation)
|
|
64
|
+
report = if adapter
|
|
65
|
+
raise ArgumentError, "scenario evaluation adapter must be callable" unless adapter.respond_to?(:call)
|
|
66
|
+
|
|
67
|
+
adapter.call(evaluation: @evaluation, owner: owner, scenarios: tasks, models: specs, on_result: on_result)
|
|
68
|
+
else
|
|
69
|
+
ensure_judge_defined_kpis! if @evaluation.judge_defined?
|
|
70
|
+
default_report(tasks, specs, on_result)
|
|
71
|
+
end
|
|
72
|
+
raise ArgumentError, "scenario evaluation adapter must return an ActiveAgent::Evals::Report" unless report.is_a?(Evals::Report)
|
|
73
|
+
reported = report.results.map { |result| [ result.scenario.key, result.label ] }
|
|
74
|
+
unless reported.sort == expected.sort && persisted.sort == expected.sort
|
|
75
|
+
raise ArgumentError, "scenario evaluation adapter must report and persist every selected scenario and model"
|
|
76
|
+
end
|
|
63
77
|
|
|
64
78
|
run.update!(
|
|
65
79
|
status: :complete,
|
|
@@ -76,6 +90,21 @@ module ActionAgent
|
|
|
76
90
|
|
|
77
91
|
private
|
|
78
92
|
|
|
93
|
+
def default_report(tasks, specs, on_result)
|
|
94
|
+
Evals::Runner.new(
|
|
95
|
+
scenarios: tasks,
|
|
96
|
+
models: specs,
|
|
97
|
+
criteria: sample_criteria,
|
|
98
|
+
judge: evals_judge,
|
|
99
|
+
available_tools: tool_roster,
|
|
100
|
+
instructions: @evaluation.agent.instructions,
|
|
101
|
+
agent_name: @evaluation.agent.name,
|
|
102
|
+
threshold: PASS_THRESHOLD,
|
|
103
|
+
replay: ->(scenario, spec) { replay(scenario, spec) },
|
|
104
|
+
on_result: on_result
|
|
105
|
+
).call
|
|
106
|
+
end
|
|
107
|
+
|
|
79
108
|
# --- selection --------------------------------------------------------
|
|
80
109
|
|
|
81
110
|
def selected_scenarios
|
|
@@ -184,7 +213,10 @@ module ActionAgent
|
|
|
184
213
|
cost: result.replay.cost,
|
|
185
214
|
fault: result.fault,
|
|
186
215
|
recommendation: result.recommendation,
|
|
187
|
-
diagnosis: result.diagnosis || {}
|
|
216
|
+
diagnosis: (result.diagnosis || {}).merge(
|
|
217
|
+
"_replay_metadata" => result.replay.metadata,
|
|
218
|
+
"_scenario_snapshot" => result.scenario.to_h.merge(expectations: result.scenario.expectations)
|
|
219
|
+
),
|
|
188
220
|
error_message: result.replay.error
|
|
189
221
|
)
|
|
190
222
|
end
|
|
@@ -195,6 +227,8 @@ module ActionAgent
|
|
|
195
227
|
scores["_recommendations"] = report.recommendations
|
|
196
228
|
scores["_verdict"] = report.verdict if report.comparing?
|
|
197
229
|
scores["_selection"] = run.selection
|
|
230
|
+
scores["_metadata"] = report.metadata
|
|
231
|
+
scores["_judge_label"] = report.judge_label || report.judge&.label
|
|
198
232
|
scores
|
|
199
233
|
end
|
|
200
234
|
|
data/config/routes.rb
CHANGED
|
@@ -20,6 +20,8 @@ ActionAgent::Engine.routes.draw do
|
|
|
20
20
|
|
|
21
21
|
# The dashboard's own JSON API, read and written by the React app.
|
|
22
22
|
namespace :api do
|
|
23
|
+
resource :dashboard_assistant, only: [ :show, :create ], controller: "dashboard_assistant"
|
|
24
|
+
|
|
23
25
|
# Telemetry ingestion, relative to wherever the engine is mounted:
|
|
24
26
|
# <mount>/api/traces (e.g. /activeagents/api/traces at the default mount).
|
|
25
27
|
# Authenticated with a bearer token, not a session.
|
|
@@ -36,6 +38,10 @@ ActionAgent::Engine.routes.draw do
|
|
|
36
38
|
post :duplicate
|
|
37
39
|
get :export
|
|
38
40
|
get :analytics
|
|
41
|
+
# The runner's conversation picker: this agent's persisted contexts,
|
|
42
|
+
# and a fresh one to pin a first message to.
|
|
43
|
+
get :conversations
|
|
44
|
+
post :conversations, action: :create_conversation
|
|
39
45
|
end
|
|
40
46
|
collection do
|
|
41
47
|
get :presets
|
|
@@ -111,7 +117,11 @@ ActionAgent::Engine.routes.draw do
|
|
|
111
117
|
resource :metrics, only: [ :show ], controller: "metrics"
|
|
112
118
|
|
|
113
119
|
# Conversations (contexts, messages, generations) behind Interactions.
|
|
114
|
-
|
|
120
|
+
# The runner edits a conversation in place — seeds, fixes or drops a
|
|
121
|
+
# turn — so the next run sees exactly the history it should.
|
|
122
|
+
resources :interactions, only: [ :index, :show ] do
|
|
123
|
+
resources :messages, only: [ :create, :update, :destroy ], controller: "interaction_messages"
|
|
124
|
+
end
|
|
115
125
|
|
|
116
126
|
# Agent output evaluations. A scenario suite also manages its scenarios
|
|
117
127
|
# here, and exposes each run's per-scenario, per-model results.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActionAgent
|
|
4
|
+
# Runs before Rails' request logger, including for requests later rejected by
|
|
5
|
+
# authentication, consent or CSRF. Match the endpoint under any engine mount;
|
|
6
|
+
# leave the host application's unrelated message/history parameters alone.
|
|
7
|
+
class AssistantRequestFilter
|
|
8
|
+
PATH = %r{/api/dashboard_assistant(?:\.[^/]+)?/?\z}
|
|
9
|
+
PARAMETERS = [ /\Amessage\z/i, /\Ahistory\z/i ].freeze
|
|
10
|
+
|
|
11
|
+
def initialize(app)
|
|
12
|
+
@app = app
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call(env)
|
|
16
|
+
if PATH.match?(env["PATH_INFO"].to_s)
|
|
17
|
+
env["action_dispatch.parameter_filter"] = Array(env["action_dispatch.parameter_filter"]) + PARAMETERS
|
|
18
|
+
end
|
|
19
|
+
@app.call(env)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/action_agent/engine.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "assistant_request_filter"
|
|
4
|
+
|
|
3
5
|
module ActionAgent
|
|
4
6
|
# Rails engine for the Active Agent dashboard: the agent builder, runs,
|
|
5
7
|
# conversations, evaluations, traces, metrics, sandboxes and session
|
|
@@ -19,6 +21,8 @@ module ActionAgent
|
|
|
19
21
|
# rather than relying on the host to register one.
|
|
20
22
|
INFLECTION_OVERRIDES = {
|
|
21
23
|
"mcp_catalog" => "MCPCatalog",
|
|
24
|
+
"mcp_client" => "MCPClient",
|
|
25
|
+
"mcp_tool_dispatcher" => "MCPToolDispatcher",
|
|
22
26
|
"mcp_controller" => "MCPController",
|
|
23
27
|
"mcp_recording_middleware" => "MCPRecordingMiddleware",
|
|
24
28
|
"mcp_servers_controller" => "MCPServersController",
|
|
@@ -35,6 +39,7 @@ module ActionAgent
|
|
|
35
39
|
}.freeze
|
|
36
40
|
|
|
37
41
|
config.action_agent = ActiveSupport::OrderedOptions.new
|
|
42
|
+
config.app_middleware.insert_before Rails::Rack::Logger, ActionAgent::AssistantRequestFilter
|
|
38
43
|
|
|
39
44
|
# Whether a request is a browser asking for a page, as opposed to an API
|
|
40
45
|
# or MCP client: the routes use it to tell the dashboard's client-side
|
data/lib/action_agent/version.rb
CHANGED
data/lib/action_agent.rb
CHANGED
|
@@ -236,6 +236,25 @@ module ActionAgent
|
|
|
236
236
|
# @return [Boolean]
|
|
237
237
|
attr_accessor :execution_enabled
|
|
238
238
|
|
|
239
|
+
# Whether the "Ask ActiveAgents" assistant is available.
|
|
240
|
+
#
|
|
241
|
+
# The assistant is a tool for developing and CI-ing agents: it sends
|
|
242
|
+
# recorded prompts, outputs and evaluation report excerpts to a model
|
|
243
|
+
# provider, which is the right trade in a development or CI workspace
|
|
244
|
+
# and a decision nobody should inherit by default in production. Left
|
|
245
|
+
# unset it is on in development and test only. Set it to true to run it
|
|
246
|
+
# somewhere else deliberately, or false to remove it everywhere.
|
|
247
|
+
# @return [Boolean, nil]
|
|
248
|
+
attr_accessor :assistant_enabled
|
|
249
|
+
|
|
250
|
+
# Resolves a host application's runner for one scenario evaluation.
|
|
251
|
+
# Return nil for the engine's normal Agent#test_execute path, or a callable
|
|
252
|
+
# accepting evaluation:, owner:, scenarios:, models:, on_result: and
|
|
253
|
+
# returning an ActiveAgent::Evals::Report. The host runs its own agent and
|
|
254
|
+
# judge and yields every result to on_result for dashboard persistence.
|
|
255
|
+
# @return [Proc, nil]
|
|
256
|
+
attr_accessor :scenario_evaluation_adapter_resolver
|
|
257
|
+
|
|
239
258
|
# Where the dashboard's upgrade CTAs should send people. Unset in a
|
|
240
259
|
# self-hosted install, where there is nothing to upgrade, and the CTAs
|
|
241
260
|
# say so instead of linking nowhere.
|
|
@@ -332,6 +351,16 @@ module ActionAgent
|
|
|
332
351
|
@execution_enabled != false
|
|
333
352
|
end
|
|
334
353
|
|
|
354
|
+
# Returns whether the dashboard assistant is available. Unconfigured, it
|
|
355
|
+
# follows the environment: development and test yes, everywhere else no.
|
|
356
|
+
#
|
|
357
|
+
# @return [Boolean]
|
|
358
|
+
def assistant_enabled?
|
|
359
|
+
return @assistant_enabled == true unless @assistant_enabled.nil?
|
|
360
|
+
|
|
361
|
+
Rails.env.local?
|
|
362
|
+
end
|
|
363
|
+
|
|
335
364
|
# Tells the host app that +owner+ performed +kind+. Never raises: a
|
|
336
365
|
# bookkeeping failure must not fail the action that was already taken.
|
|
337
366
|
def record_usage(owner, kind)
|
|
@@ -452,6 +481,9 @@ module ActionAgent
|
|
|
452
481
|
@provider_credentials_resolver = nil
|
|
453
482
|
@sandbox_backends = {}
|
|
454
483
|
@execution_enabled = true
|
|
484
|
+
@assistant_enabled = nil
|
|
485
|
+
|
|
486
|
+
@scenario_evaluation_adapter_resolver = nil
|
|
455
487
|
@table_name_prefix = "active_agent_"
|
|
456
488
|
@agent_polymorphic_name = nil
|
|
457
489
|
@encrypt_credentials = true
|
|
@@ -70,6 +70,18 @@ ActionAgent.configure do |config|
|
|
|
70
70
|
# nothing rather than everything. An empty dashboard for a signed-in user
|
|
71
71
|
# means the resolver above returned nil.
|
|
72
72
|
|
|
73
|
+
# ==========================================================================
|
|
74
|
+
# Ask ActiveAgents assistant
|
|
75
|
+
# ==========================================================================
|
|
76
|
+
#
|
|
77
|
+
# A tool for developing and CI-ing agents. Answering a question sends
|
|
78
|
+
# recorded prompts, outputs and evaluation report excerpts to a model
|
|
79
|
+
# provider, so the page and its API are on in development and test only.
|
|
80
|
+
# Set it to true to run it in another environment deliberately, or false
|
|
81
|
+
# to remove it everywhere.
|
|
82
|
+
#
|
|
83
|
+
# config.assistant_enabled = true
|
|
84
|
+
|
|
73
85
|
# ==========================================================================
|
|
74
86
|
# UI
|
|
75
87
|
# ==========================================================================
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: actionagent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Bowen
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activeagent
|
|
@@ -129,8 +128,10 @@ files:
|
|
|
129
128
|
- app/controllers/action_agent/api/analytics_controller.rb
|
|
130
129
|
- app/controllers/action_agent/api/api_keys_controller.rb
|
|
131
130
|
- app/controllers/action_agent/api/base_controller.rb
|
|
131
|
+
- app/controllers/action_agent/api/dashboard_assistant_controller.rb
|
|
132
132
|
- app/controllers/action_agent/api/evaluations_controller.rb
|
|
133
133
|
- app/controllers/action_agent/api/instance_tiers_controller.rb
|
|
134
|
+
- app/controllers/action_agent/api/interaction_messages_controller.rb
|
|
134
135
|
- app/controllers/action_agent/api/interactions_controller.rb
|
|
135
136
|
- app/controllers/action_agent/api/mcp_controller.rb
|
|
136
137
|
- app/controllers/action_agent/api/mcp_servers_controller.rb
|
|
@@ -193,10 +194,14 @@ files:
|
|
|
193
194
|
- app/services/action_agent/agent_registrar.rb
|
|
194
195
|
- app/services/action_agent/agent_scorecard.rb
|
|
195
196
|
- app/services/action_agent/agent_toolbox.rb
|
|
197
|
+
- app/services/action_agent/dashboard_assistant_service.rb
|
|
198
|
+
- app/services/action_agent/evaluation_evidence.rb
|
|
196
199
|
- app/services/action_agent/evaluation_runner_service.rb
|
|
197
200
|
- app/services/action_agent/evaluation_tool_resolver.rb
|
|
198
201
|
- app/services/action_agent/mcp_catalog.rb
|
|
202
|
+
- app/services/action_agent/mcp_client.rb
|
|
199
203
|
- app/services/action_agent/mcp_recording_middleware.rb
|
|
204
|
+
- app/services/action_agent/mcp_tool_dispatcher.rb
|
|
200
205
|
- app/services/action_agent/mock_sandbox_backend.rb
|
|
201
206
|
- app/services/action_agent/playwright_mcp_client.rb
|
|
202
207
|
- app/services/action_agent/sandbox_orchestrator.rb
|
|
@@ -212,6 +217,7 @@ files:
|
|
|
212
217
|
- app/views/layouts/action_agent/react.html.erb
|
|
213
218
|
- config/routes.rb
|
|
214
219
|
- lib/action_agent.rb
|
|
220
|
+
- lib/action_agent/assistant_request_filter.rb
|
|
215
221
|
- lib/action_agent/compatibility.rb
|
|
216
222
|
- lib/action_agent/engine.rb
|
|
217
223
|
- lib/action_agent/version.rb
|
|
@@ -231,7 +237,6 @@ metadata:
|
|
|
231
237
|
documentation_uri: https://docs.activeagents.ai/framework/self-hosted-observability
|
|
232
238
|
source_code_uri: https://github.com/activeagents/activeagent
|
|
233
239
|
rubygems_mfa_required: 'true'
|
|
234
|
-
post_install_message:
|
|
235
240
|
rdoc_options: []
|
|
236
241
|
require_paths:
|
|
237
242
|
- lib
|
|
@@ -246,8 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
246
251
|
- !ruby/object:Gem::Version
|
|
247
252
|
version: '0'
|
|
248
253
|
requirements: []
|
|
249
|
-
rubygems_version:
|
|
250
|
-
signing_key:
|
|
254
|
+
rubygems_version: 4.0.16
|
|
251
255
|
specification_version: 4
|
|
252
256
|
summary: The Active Agent dashboard, as a mountable Rails engine
|
|
253
257
|
test_files: []
|