Skip to content

Finish the trace view gaps: dark-mode tools and time window, bounded console limit - #635

Open
yorzi wants to merge 1394 commits into
activeagents:mainfrom
yorzi:fix/trace-view-gaps
Open

yorzi wants to merge 1394 commits into
activeagents:mainfrom
yorzi:fix/trace-view-gaps

Conversation

@yorzi

@yorzi yorzi commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Closes #384. This covers the two findings still open: the dark-mode TracesView gaps and the console's unbounded, mis-documented list limit. The other findings already landed: window totals and the truncation notice in #615, the offline console in #631, and the tool_usage key fallback in d7b31ac.

What changes

  • Tools view in dark mode. The dark layout offered a Tools button but rendered nothing under it. The light table is now renderToolsBreakdown(dark), next to renderSpansBreakdown, and both themes call it. Colors come from telemetryColors. Counts, failure counts, total/avg/slowest durations, the share bar, sort order and the empty state are unchanged. The table gets a 520px minimum width and scrolls horizontally on narrow screens instead of crushing its columns.
  • Time window in dark mode. The dark header now mounts the shared TimeWindowSelector, which already resolves the theme palette, next to the view-mode toggle. That includes the agent page (embedded) and empty windows. Both header rows wrap.
  • Console list limit (TracesController#fetch_traces). traces.limit(params[:limit] || 50) passed the raw value through: 0 showed no rows, -1 or a huge value loaded everything, and some malformed values raised. The limit now goes through Integer(params[:limit], 10, exception: false), falls back to 50 when invalid, and is clamped to 1–1000. Agent, service, status and date filters still apply first.
  • Docs. The controller comment no longer claims pagination. self-hosted-observability.md describes the bounded recent list and notes that the 24-hour summary tiles don't depend on the limit. CHANGELOG entries are under Unreleased.

Checks

  • actionagent/frontend/test/traceControlsViews.test.mjs (new, 8 tests, both themes): tool rows with aggregated calls, failures and durations; the empty state; a window change that refetches with minutes/bucket_seconds, keeps agent_id and replaces the tool rows; zoom stopping at the shortest and longest windows. Against main's TracesView.jsx, every dark-mode test fails.
  • actionagent/test/trace_console_test.rb (4 new tests): default 50 and a smaller limit in newest-first order; 0, -1, 1000 and an oversized integer clamped; blank, abc, 3oops, 1.5, array and hash values falling back to 50; filters applied before the limit while the summary keeps the full count.
  • Frontend: npm test, 719 pass. A fresh npm run build:js and build:css matches the committed app/assets/builds byte for byte.
  • bin/test: 4111 runs, 0 failures. The 182 errors are all Missing credentials from the OpenAI client when no OPENAI_API_KEY is set. They reproduce on main and are unrelated. bin/rubocop reports no offenses.

TonsOfFun and others added 30 commits October 3, 2026 15:48
…credentials

The explorer and a project's evaluation replays need the app signed in,
and the credentials typed into the app must never pass through a model,
a log, a span or a recording. A project secret now has a kind: env (what
a boot hands the app, as before), sign_in (login URL, login, password and
optional field selectors) or storage_state (a browser's saved sign-in).
Only env secrets reach the sandbox's environment, and a sign-in secret
joins the scrub lists part by part, so its password and each saved cookie
value are masked on their own. Migration template 024 adds the column.

BrowserSignIn fills the login form from the Rails process through a
second MCP session on the sandbox's browser (SandboxBrowserDriver) and
answers only whether the browser left the login page; it empties the
password field when it did not, since a page snapshot shows what a
password field holds. A login page without a password field is reported
as unsupported. The test account step gets session endpoints to set the
credentials, check them, keep the running browser's sign-in, or remove
both, all asked of the permission checker as :manage_project_secrets.
A browser started for a project starts with its saved sign-in.

Sandbox apps write mail to files: backends set
ACTION_AGENT_SANDBOX_MAIL_DIR, the engine switches Action Mailer to
file delivery when it is set, and SandboxMail reads the newest message
for an address through the backend's read_file verb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A project could collect candidate scenarios only from an agent outside
the dashboard. The engine now walks the project's app itself:
POST /api/projects/:id/explorations asks the host's quota about
:exploration first (402 and nothing started on a denial), gives the
project's ready sandbox a browser (headless with the saved sign-in when
none runs, asked as :browser_minutes), creates the explorer's run and the
exploration, records :exploration once and queues ExplorationJob.

The explorer is an ordinary AgentRun of a project-owned agent, so it is
traced and its browser actions land on the browser's recording.
ExplorerExecutionService offers it an allowlist of the sidecar's browser
tools without their file arguments, plus sign_in (by secret reference,
done in the Rails process), read_last_email, propose_candidate (through
Exploration#add_candidates!, with the pages, steps and recording range
since the last candidate filled in server-side) and finish. Navigation
off the app is refused before it reaches the browser, and every browser
result is scrubbed of the project's secrets. Its instructions list the
target agent's real tools, and candidates are checked against them with
the sandbox and its browser attached.

The budget (minutes, browser steps, optional cost from the run's own
generations) is checked after every tool call. Running out, or Stop and
review, ends the walk in review with its candidates; a model that keeps
calling tools after that is cut short; a crash fails the exploration and
keeps what it found. A browser the start launched is stopped afterwards.

AgentExecutionService gains the seams this needs: tool dispatch in its
own method, extra generation options (the explorer raises
max_tool_turns), and a provider class override.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scenarios found by walking an app's pages are replayed by an agent that
may need the same browser. A run of a project's evaluation now gives
every replay the sandbox's browser beside the sandbox: one already
running, or one started headless with the project's saved sign-in before
the first replay, recording to the dashboard the run was started from.
Each replay's browser opens at the project's start URL, the diagnosis
roster lists the browser's tools, and the run's selection records both
server keys. A browser that cannot start fails the run before any replay,
the way a sandbox that is no longer live does. On a backend that runs no
browsers the replays reach the sandbox alone, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dashboard guide gains sections on starting the explorer and what it
is offered, the test account step and its endpoints, the sandbox's mail,
and the browser a project's evaluation runs reach; the secrets section
names the new secret kinds and the permissions table the sign-in
endpoints. The browser sessions page says a project's browser starts with
its saved sign-in. CHANGELOG entries are under Unreleased.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t page

The explorer and the test account step had only endpoints. The Project
page's Explorations tab now starts with an "Explore the app" panel (an
optional budget of minutes, browser steps and a cost cap, and the reason
a start was refused) and a Sign-in panel: save a seeded account's
credentials and check them, open the sandbox's browser in a window to
sign in by hand and keep that sign-in, or use no sign-in. A check that
finds no password field says the app's sign-in is not supported in the
sandbox. The Environment tab lists only the secrets that reach the
sandbox's environment, and a review says in words why a walk stopped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A browser tool the sandbox's browser did not answer for fell through to
AgentToolbox, which on a single-tenant install drives the process-wide
Playwright browser, outside the sandbox and its recording. The explorer
now answers such a call with an error. Its run also uses the agent the
run was created for, rather than looking the project's explorer agent up
again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema tools generator writes every column commented out, so a
person reviews the allowlist by editing the file. Something that has
already made that judgement elsewhere, such as a dashboard where a
developer ticked the columns, had no way to write the result.

--filterable and --returns now declare exactly the named columns after
id, in place of the commented suggestions. A column that looks like a
secret, or that the model's table lacks, is left out with a note. The
secret-column pattern moves to ActiveAgent::SchemaTools::SECRET_COLUMNS
so the dashboard can apply the same rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A project's install pull request carries files the dashboard writes
itself (the sandbox.yml that booted the project, its evaluation suite),
and allows engine migrations by their whole name after any timestamp,
which a File.fnmatch pattern cannot say.

DraftPullRequestPublisher now takes generated_files: content offered for
a path in place of anything the sandbox wrote there, compared with the
checkout commit and filtered and scanned like the sandbox's own changes.
An allowlist entry may be a Regexp the whole path must match.

A file holding one of the project's secrets is refused: the secret scan
reads SandboxSession#secret_values, which now includes the secrets of the
project the sandbox was booted for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tab's count included the sign-in secrets, which the tab does not
list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A project's secrets form asks for what discovery can find before the
first boot. A boot that fails for anything else left the developer
reading logs by hand. The setup assistant is an agent the engine defines
for each project, started once per failed boot (or on request), whose
runs have exactly four tools whatever the agent record names:

- read_step_log: the failed boot's steps, and scrubbed log pages
- set_env: a value that is not secret, stored as a project secret with
  the source setup_assistant and passed as boot env, unmasked; it
  refuses the names project secrets refuse, and values a person set
- request_secret: a secret a person types in, stored as a project
  secret; the model never sees it
- retry_boot: resume the kept boot from the failed step, once per run

It has no shell, no file reads and no code session, so a log written by
the repository's code can steer it no further than those tools. A run
counts only when the project recorded it (agent id and run id in its
settings, which only engine code writes), so the same agent run from the
agents API gets none of them. Agent#execute yields the run before
enqueuing it, so the record exists when the job starts.

SecretRequests handlers can now refuse a name before anyone is asked,
word the question (who asks, the repository, the variable, and that the
value is handed to the repository's code), and decide who may answer:
answering the setup assistant also needs :manage_project_secrets. The
handler is told the tool call's id when it takes one, to record who
answered.

Automatic runs stop after three in a row without a good boot, can be
switched off per project, and are executions for the quota checker.
GET /api/projects/:id/input_requests lists what the project's agents
are waiting on, and the project summary counts it. A boot spec that
does not apply to a checkout now hands it its env as well as its
secrets, so set_env values reach installed repositories too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A repository without its own agents is evaluated with the App assistant,
whose tools are whatever the sandbox's MCP facade serves. A fresh
install serves no schema tools, so the assistant had nothing app-specific
to read, and writing the tools meant editing the checkout by hand.

The sandbox manifest now lists the app's models under app/models with
their columns, leaving out id and the columns that look like secrets; a
backend reports them as app_models and the project keeps the last list.
A developer picks models and the columns the assistant may filter on and
read back (GET /api/projects/:id/app_models,
PUT /api/projects/:id/schema_tools), checked against that list. Every
later boot runs a trusted schema_tools step after db_prepare, built by
the engine from the stored choices, which writes
app/agent_tools/<model>_tools.rb through the schema tools generator's
--filterable and --returns. The choices therefore survive a sandbox
expiring; apply: true replaces the running sandbox with a new boot at
once. The assistant's sandbox server has no allowlist, so it lists the
new tools as soon as the facade serves them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Once a project's sandbox has installed the engine, the developer still
had to redo the install by hand to keep it. The install pull request
publishes it from the dashboard through DraftPullRequestPublisher: from
the project's live sandbox (booting one first, answering 202), with a
token minted at publish time, after the dialog shows the exact diff, and
only on an explicit request that needs :publish_pull_request.

ProjectInstallPullRequest#allowlist lets through only the Gemfile and
lock, the engine's initializer and routes, the framework's config and
application agent when the bootstrap generated them, the migrations
action_agent:install emits matched by their whole name after the
timestamp (several, such as add_agent_releases, do not mention
active_agent), the schema, and the chosen schema tools. It also
generates .activeagents/sandbox.yml (the setup that booted the project
and the names of its secrets, never their values) and
.activeagents/evals/<project>.yml (the project evaluation's enabled
scenarios as a suite ActiveAgent::Evals::Suite.load reads). Anything
else, .github/, and files holding a project secret are refused.

While the pull request is open, every boot checks out its branch and
runs SandboxBootSpec.installed, the bootstrap without the steps that
install the engine. An update from a later sandbox of that branch goes
on top of the branch as the sandbox checked it out. A branch GitHub
would not open as a draft can be opened as a regular pull request. When
the status poll reports the pull request merged, the project is
installed and boots its own branch; a closed one leaves it
bootstrapping again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Project page showed a failed boot and its log tail, and nothing to do
about it but the Environment tab. It now carries the rest of the setup:

- Waiting for you: the requests for input the project's agents are
  waiting on, answered in place through the input requests API, with a
  masked field for a secret; the boot status reads "Waiting for you: N".
- Setup assistant: whether it can run and why not, whether a failed boot
  starts it, its latest run, and Ask the setup assistant on a failed boot.
- Choose what the assistant may read: for an App assistant project, the
  models the last boot listed with a filter and a read box per column,
  saved, or saved and booted again.
- Install pull request: its status (read again every minute while open),
  Open install PR and Update draft PR through the publish dialog, which
  takes a patch link of its own, and what the allowlist lets through.

The page also polls while the setup assistant works or a request waits,
and the Environment tab names values the assistant set. The pure logic
is in utils/projectSetup.mjs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dashboard guide gains the setup assistant (its four tools, automatic
and requested runs, who may answer its secret requests), requests for
input on the Project page, choosing what the App assistant may read, and
the install pull request with its allowlist and how boots follow its
branch. The manifest section documents the models field, the boot spec
section the extra steps, SandboxBootSpec.installed and the schema tools
step, and the permissions table the actions these endpoints ask about.
The CHANGELOG notes both entries under Unreleased.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…plorer

Three paths let a sign-in secret escape the browser it was typed into:

- MCPClient#call_tool logs every call's arguments at debug level, so the
  password and login BrowserSignIn typed landed in a development log.
  call_tool now takes log_arguments: false, which logs only the argument
  keys, and SandboxBrowserDriver#type uses it.
- browser_network_request answers a request's body, and a page's request
  list keeps the sign-in POST until the next navigation, so the explorer
  could read the form body. Scrubbing only caught passwords of 8 or more
  characters, and none in their JSON-escaped form. The network tools are
  dropped from the explorer's allowlist, and SecretScrubber.with_encodings
  adds the JSON-escaped forms.
- A sign-in was judged by whether the path changed, so an app that renders
  a failure on its form's POST path counted as signed in, and the typed
  password stayed in the field for the next snapshot. BrowserSignIn now
  judges by whether a password field is still shown, which also lets an
  app whose signed-in page shares the login path sign in.

The sentinel test now also checks a debug-level log, and the failed
sign-in test uses a password too short to scrub, so it checks the field
is emptied rather than relying on the scrubber.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…started

A project evaluation run started the sandbox's browser when none ran and
never stopped it, so it ran headless until the sandbox expired, metering
browser minutes for up to two hours. It was also started before the
empty-selection check, so a run with nothing to replay started one too.

The runner now records whether it started the browser, stops it in an
ensure once the run completes or fails, and starts it only after the
scenarios are known. A browser that was already running is left alone,
as ExplorationJob does.

ExplorationJob returned before its ensure when the exploration was no
longer pending (Stop and review before the job ran) or its run was gone,
leaving the browser the start launched running. Those returns now sit
inside the ensure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… names

ProjectSecret#scrub_parts listed every cookie and localStorage value of a
saved storage state, and the sign-in's login. Those lists feed every
scrubber of the project's output and the owner's MCP tool results, so
ordinary values ("accepted", "expanded", a time zone) were redacted from
every page snapshot, and the test account's address was redacted from
every page and candidate, which kept the explorer from reading that
account's mail.

A storage state now contributes only the values that look like a
credential: httpOnly cookies, and any value of at least
STORAGE_SECRET_MIN_LENGTH (20) characters, which session ids and tokens
are. The login is an account name the app shows and mails, so it is no
longer scrubbed; the password still is.

An env secret named APP_SIGN_IN or APP_STORAGE_STATE could be created,
and then blocked the sign-in step with "Kind cannot change". Both names
are now refused for env secrets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… blank

Project#assign_sign_in stripped every field, the password included, while
the Sign-in panel deliberately sends the password as typed. A password
with leading or trailing spaces was stored without them and signed in as
"failed" with no clue why. The password is now kept as typed.

With credentials saved, the panel's password field is empty, and Save
stayed disabled with no explanation until the password was typed again,
although the placeholder suggested a blank field kept it. A blank
password now keeps the saved one on the server, the panel sends the form
without it, says so in the placeholder, and shows why Save is disabled
whenever it is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urn-Path

SandboxMail.last_raw_message found where each message starts by a blank
line followed by "Date: ". Mail puts a Return-Path (or Received) header
ahead of Date, so for an app that sets return_path no start was found,
the whole file parsed as one message, and read_last_email answered the
oldest message's subject and links rather than the newest's.

A message may now start at any header line after the blank line Mail's
file delivery appends, and the Message-ID check still rejects a blank
line inside a body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rflows

Every browser action answers with a page snapshot, which the sidecar
inlines up to 256 KB, and every result stays in the explorer's
conversation. Within the default budget of 150 steps the request would
outgrow a model's context window, and the provider error then failed the
walk instead of ending it in review with its candidates.

Each browser result the explorer sees is now cut to RESULT_TEXT_LIMIT
(24,000) characters, and once the results it was answered with add up to
CONVERSATION_LIMIT (400,000 characters, about 100,000 tokens) the walk
ends like a spent budget, with stop_reason "budget_context". The
dashboard names that reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AgentExecutionService#prompt_provider_class and the provider_class:
keyword on ExplorerExecutionService existed only so a test could run the
explorer on a scripted model. The test now stubs the mock provider's
constant, which the explorer agent's provider resolves to, and the hook
leaves production code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Project#summary's secret_count counted the sign-in and saved-sign-in
secrets as well, while the Environment tab lists environment secrets
only, so the two disagreed once a sign-in was set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… built

The dashboard guide and the changelog now say what the review fixes
changed: the network request tools are not offered, results are cut and
a full conversation ends the walk as "budget_context", a sign-in is
judged by the password field and never logged, which values of a sign-in
are scrubbed, that a blank password keeps the saved one, that the two
sign-in names are refused for environment secrets, and that an
evaluation run stops the browser it started. It also corrects the claim
that a run started outside the project page reaches no browser: it uses
one that is already running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built from the current frontend sources with npm run build, for the
Sign-in panel's saved-password handling and the budget_context stop
reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nages

A dashboard project writes app/agent_tools/<model>_tools.rb for the models
its App assistant may read, on every boot. To change or take back a
choice, the boot has to rewrite or remove the files it wrote, and only
those: a repository can have tools files of its own.

`active_agent:schema_tools --managed` heads the file with
ActiveAgent::SchemaTools::MANAGED_MARKER, which the project's boots look
for. Deleting the header hands the file back to whoever edits it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…COLUMNS

The sandbox manifest runs inside the checkout, against the activeagent
release the checkout locks. The engine allows activeagent >= 1.4, so a
repository that already locked an older framework keeps it when the
bootstrap adds the engine. There ActiveAgent::SchemaTools::SECRET_COLUMNS
is undefined, every model's listing raised NameError inside its rescue,
and the manifest listed no models, leaving the schema tools chooser
empty.

SandboxManifest::SECRET_COLUMNS is the framework's pattern when it has
one, and the same pattern spelled out otherwise. Reading a manifest and
checking a schema tools choice use it too, since the dashboard's own
framework can be as old.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hat fit

Three problems with how a project's schema tool choices reached a boot:

- Once a checkout locked the engine (after the install pull request
  merged, or a repository that already bundled it), its boot spec did
  not apply and the checkout booted from its own sandbox.yml. That boot
  dropped the spec's steps, so PUT /schema_tools answered 200 and the
  tools were never written.
- Every chosen model went into one command, which a boot step caps at
  4096 characters, and the cap was checked only when a boot built the
  spec. A dozen models with their columns saved fine and then failed
  every later boot, starting setup runs that could not fix it.
- Taking a model off the list left its tools file in any checkout that
  already held it, so the App assistant kept those tools. --force also
  overwrote a tools file the repository wrote itself.

A boot spec step can now be marked `always`: it runs whether the spec
applies or not, after the checkout's own sandbox.yml setup when it does
not. The local backend's config boot runs those steps.

SandboxBootSpec.schema_tools_steps replaces schema_tools_step. It first
removes every app/agent_tools file headed by the managed marker, then
writes each chosen model's file with --managed unless a file the
dashboard did not write is there. The commands are packed into steps of
at most 4096 characters (schema_tools, schema_tools_2, ...), up to ten.
Choices that need more, or one model whose command alone is too long,
are refused when they are chosen (422), not at boot. A project that
emptied its list still gets the removing step. The project records
every model it was ever given, for the install pull request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lowlist

While the install pull request is open, every boot checks out its branch
with a spec that installs nothing. The publish dialog let a person untick
any file, so a branch without its Gemfile.lock, routes or initializer
could not load the engine, every boot failed, and "Update draft PR"
needed a live sandbox that could no longer boot.

- A publish, opening or updating, must take every Gemfile, Gemfile.lock,
  initializer, routes, schema and engine migration the sandbox changed.
  Leaving one out answers 422 incomplete_install, naming the files.
  DraftPullRequestPublisher#changed_paths lists them without reading.
- The allowlist covers the tools file of every model the App assistant
  was ever given, so a file a boot removed after the model was taken off
  the list is removed on the branch too. Setup commands in the generated
  sandbox.yml leave out every schema tools step, however many.
- The generated sandbox.yml names only real secrets under `secrets:`.
  Values the setup assistant set are not secrets, stay with the project
  and are passed to every boot.
- The install patch is limited to the allowlist even when paths are
  named (DraftPullRequestPublisher#patch takes allowlist:).
- Asking to open a new pull request while the branch is published
  without one says to open one for the branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the Project page's button checked whether a setup run was already at
work. A second POST /setup, or a boot that failed again while the first
run waited for a secret, started another run: two runs asked for the same
secrets and raced to retry the boot.

ProjectSetup.active_run is the project's last setup run while it is
pending, running, or waiting on a request that has not expired (expired
requests are settled first, which fails the run they paused). start!
raises Unavailable while there is one, so POST /setup answers 409, and an
automatic run after a failed boot is skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A value the setup assistant sets is not secret: a boot passes it unmasked
as env, it is left out of scrub lists and the publisher's secret scan,
and set_env may overwrite it. The secrets API passed any source through,
so a person could store a real secret with the source "setup_assistant"
and lose all of that protection.

POST /api/projects, PUT /api/projects/:id/secrets and PUT
/api/projects/:id/secrets/:name now refuse any source but "entered" and
"organization_key" with 422 invalid_source.

Since those values are not secret, the secrets API lists them with their
value, so a person can see what the setup assistant changed. A secret's
value is still never returned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TonsOfFun and others added 29 commits October 21, 2026 16:14
…e provider

feat: add Opper as an OpenAI-compatible provider
…o the dashboard catalog

Add opt-in Parallel Search MCP to the dashboard catalog
… cache token fields

Recognise Anthropic usage by its cache token fields
…s and examples

Replace retired model ids in docs and examples
…tistics

Resolved on main: the changelog bullet joins a new Fixed section under
Unreleased, and the dashboard bundle is rebuilt from main's frontend
with this change rather than taken from the branch.
… to its provider

Resolved on main: the changelog bullet joins the Fixed section under
Unreleased, and the dashboard bundle is rebuilt from main's frontend
with this change rather than taken from the branch.
…s that carry no index

Resolved on main: the changelog bullet joins the Fixed section under
Unreleased.
…eneration stopped

Carries activeagents#610 (a streamed generation reports why it stopped). Resolved on
main: the changelog bullets join the Fixed section under Unreleased.
…he Anthropic usage fix

Merged from activeagents#583, activeagents#575 and activeagents#611 without entries.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVSMckjfmJy2QWSb4wRrGh
…SON, HTML, Markdown) and Copy as Markdown (1.9.3)

Export evaluation run reports (JSON, HTML, Markdown) and Copy as Markdown
…4m5ap6

# Conflicts:
#	actionagent/app/assets/builds/action_agent.js
Say what 1.9.3 releases, and what changes for a host upgrading.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVSMckjfmJy2QWSb4wRrGh
…d code conversations, report export, provider and evaluation fixes

1.9.3 release: browser upload and code conversations, report export, provider and evaluation fixes
The agent cards carried a light-only Tailwind status pill and an ad-hoc
provider chip; Agent Interactions and the sandbox runner each kept a
status color map of their own; the conversation stream's role pills had
their colors inline per theme. Each is now the dashboard's Badge (soft
tint, strong mono text, radius 4, theme tokens), with one status tone
map (statusTone) and one role map (roleBadge) in primitives, so the same
word reads the same on every surface and in both themes. roleBubble keeps
its shape for the callers that read its colors, over the shared tones.
Two tones join the tokens for the system and developer roles.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVSMckjfmJy2QWSb4wRrGh
The evaluation report paints with ActiveAgent::Evals::DesignTokens, which
the parity test holds equal to the dashboard's tokens.css; the two tones
added there for the message roles go here too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVSMckjfmJy2QWSb4wRrGh
…role badge through the shared Badge

Render every status and message role badge through the shared Badge
ActionAgent.user_menu_links takes an Array of { label:, href: } or a Proc
receiving the signed-in user and the current owner; the header lists the
result above Sign out. A hosted platform points them at its workspace,
members and account settings pages and shows its admin pages to admins.
Malformed entries are dropped and a raising Proc is logged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmKPEAPx8CWA9PNKDAgEKT
* Make generated agent previews discoverable and callable

Write previews to the directory the Railtie searches and use current
preview URLs. Forward preview parameters to the generated agent call.

Look for new preview files on each discovery, and leave generation
objects intact in the mail-specific image interceptor. Cover the
original failures and retain inline-image handling for mail objects.

* Restore Rails browser preview and download endpoints

The Railtie registers preview routes but ships no controller for them.
Render escaped Markdown requests, list namespaced previews and download
only declared preview actions. Apply Rails diagnostic-page access rules.

Register default, legacy and configured preview directories with the
Rails reloader. Exercise generated previews in fresh framework-only
hosts, including reloads, disabled routes and refused remote requests.
The tests fail if a preview executes the mock provider.

* Clarify preview access and initialization behavior
* Keep the trace console usable without external assets

The server-rendered fallback loads Tailwind, Turbo and Stimulus from
CDNs, so expanding a trace needs a network and JavaScript. Ship small
console-scoped styles and use native details with standalone links.

Make refresh opt-in through bounded HTML refresh intervals, preserving
filters without interpreting query parameters as routing options.
Cover list, detail, metrics, empty states and escaped trace contents.

Refs activeagents#384

* Drop the console's CDN caveat from the docs and initializer

The self-hosted observability guide and the generated initializer still
said the trace console loads Tailwind, Turbo and Stimulus from CDNs and
recommended a custom layout to avoid them. Neither is true any longer,
and a custom layout now drops the console's built-in styles.

---------

Co-authored-by: Justin Bowen <JusBowen@gmail.com>
…r menu

Dashboard: host links in the user menu
…iew and test generator fixes

Bump activeagent, actionagent and the browser sidecar to 1.9.4 and date
the changelog section. No engine migrations since 1.9.3.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QmKPEAPx8CWA9PNKDAgEKT
The dark Traces view offered a Tools button without rendering the
results. Reuse one themed renderer for calls, durations, failures and
empty results in both layouts, including narrow table scrolling.

Refs activeagents#384
Mount the shared themed selector in the dark header as well as the
light one. Keep the chosen window, zoom bounds and agent scope when
refreshing results, and allow the header controls to wrap.

Refs activeagents#384
Raw limits could hide every row, raise on malformed input or load an
unbounded number of traces. Parse decimal integers, default invalid
input to 50, and clamp the result to 1 through 1000 after filtering.

Describe the bounded recent list accurately: it has no pagination,
and its row limit does not narrow the 24-hour summary.

Refs activeagents#384
Moving the tool table into renderToolsBreakdown dropped the comments
that explain why it exists, why it uses flexbox rather than the 12-col
grid (those classes are not in the compiled Tailwind build), and what
the bar measures. Restore them and note why the table has a minimum
width. Minified output is unchanged.

Refs activeagents#384
Tailwind compiles every class name it finds in the source, comments
included. Naming the 12-column grid class in the restored comment
added that rule to action_agent.css, so the committed bundle no longer
matched its source. Describe the constraint without naming the class.

Refs activeagents#384

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Traces read/console: 500-row cap w/o pagination, dark-mode TracesView gaps, console CDN deps, tool_usage key drift

7 participants