Skip to content

[AGE-3777] fix(frontend): close trace→playground gaps from #4426#4453

Open
ardaerzin wants to merge 2 commits into
fix/playground-open-from-trace-resolverfrom
fe-fix/age-3777-trace-playground-side-panel-links-broken-for-slug-only-refs
Open

[AGE-3777] fix(frontend): close trace→playground gaps from #4426#4453
ardaerzin wants to merge 2 commits into
fix/playground-open-from-trace-resolverfrom
fe-fix/age-3777-trace-playground-side-panel-links-broken-for-slug-only-refs

Conversation

@ardaerzin
Copy link
Copy Markdown
Contributor

Summary

Closes the trace→playground gaps reported in #4426, stacked on top of #4425 (the resolver). Five problems addressed:

Problem 1 — Slug-only refs render dead tags in the side panel. Lifts #4425's resolveTraceRefs into a TanStack-Query atom (resolvedTraceRefsAtomFamily) keyed by a stable encoding of the identifying refs. The trace drawer's side panel subscribes and falls back to resolved appId / revisionId when the raw refs are slug-only, so Application, Variant, and Environment tags now build proper hrefs.

Problem 3 — Evaluator spans open the graded app. #4425's resolver backfills refs.application_revision.id for any span carrying app refs. Evaluator spans always carry the graded app's refs alongside their own, so the application_revision branch fired before the evaluator_revision branch. Extracts the gate into a pure helper selectOpenFromTraceBranch(refs, isEvaluatorSpan) and skips the application branch for evaluator spans.

Problem 2d — Environment refs dropped. extractReferences now reads environment / environment_variant / environment_revision, the resolver forwards them to POST /workflows/revisions/retrieve (the Fern client already accepts these fields), and hasAppReference enables the Playground button for env-only traces. The side panel atom key includes env refs so env-only traces also resolve their environment-tag link.

Problem 2a / 2c — Ephemeral has no URI, config panel empty even when parameters exist. createEphemeralWorkflow now defaults the URI to agenta:builtin:completion:v0 or agenta:builtin:chat:v0 (chat detection mirrors the existing logic) for non-evaluator ephemerals, so the playground can fetch the schema and the parameters we already extract render against a real form. Evaluator ephemerals continue to take their URI from deriveBuiltinUriFromSpanName.

Problem 2b — "Create" spawns a disconnected new app. createWorkflowFromEphemeralAtom now reads meta.sourceRef and, when the ephemeral was opened from an existing application's trace, forks the source workflow as a new variant (seed v0 + data v1) instead of calling createWorkflow. Falls back to the new-workflow path when no source id is available (e.g. third-party traces with slug-only refs that didn't resolve).

Testing

Verified locally

  • pnpm test --run in web/packages/agenta-playground → 60/60 unit tests pass (35 existing + 25 new).
  • pnpm exec vitest run tests/unit in web/packages/agenta-entities → 344/344 unit tests pass (327 existing + 17 new).
  • pnpm lint-fix across the web/ workspace → clean.

Added or updated tests

  • web/packages/agenta-playground/tests/unit/traceRefResolution.test.ts — 13 new cases. hasAppReference with env refs; resolveTraceRefs forwarding env refs (single / variant / revision / combined with app); selectOpenFromTraceBranch covering app-revision, evaluator-revision, evaluator-with-also-app-revision (regression guard for Problem 3), and empty-string id handling.
  • web/packages/agenta-playground/tests/unit/resolvedTraceRefsAtom.test.ts — env-ref cache-key encoding (env-only produces a non-empty key, different env slugs produce different keys, app+env distinct from app-only).
  • web/packages/agenta-entities/tests/unit/retrieveWorkflowRevision.test.ts — env refs forwarded in the request body and treated as identifying refs.
  • web/packages/agenta-entities/tests/unit/createEphemeralWorkflow.test.ts (new file) — URI derivation for completion / chat / explicit / evaluator-without-uri cases plus parameter pass-through.

Problem 2b's fork-as-variant branch in createWorkflowFromEphemeralAtom has no dedicated unit test because the function's dependency surface (5+ atoms, 3+ API functions, callback registry) makes a focused mock setup prohibitive. The branching itself is straightforward — manual QA covers it.

QA follow-up

  • Problem 1 (slug-only side panel): open a trace emitted by a third-party instrumentation (or any trace where ag.refs.application.id is missing but slug is present). Confirm the Applications / Variants / Environments tags in the right side panel render with working links.
  • Problem 3 (evaluator routing): open a trace from an evaluator run that grades an application. Click "Open in Playground". Confirm you land on the evaluator's revision, not on the graded application.
  • Problem 2d (env refs): find a trace that carries only an ag.refs.environment.* reference (no application-side refs). Confirm the Playground button is enabled and clicking it resolves to the deployed revision.
  • Problem 2a / 2c (ephemeral config panel): open a trace that falls back to ephemeral (no resolvable revision) on a real workflow run. Confirm the config panel shows the parameters that were used at trace time, instead of "No configuration needed".
  • Problem 2b (fork as variant): open an ephemeral that came from an existing app's trace, edit the configuration, hit "Create". Confirm the new entity is a variant of the source app, not a brand-new app. Then confirm the fallback path: open an ephemeral from a third-party trace with no resolvable source app, hit "Create", confirm it creates a new app as before.

Demo

N/A for the data-layer changes (Problems 2a/2c/2d/3) — purely behavioral. Problem 1 and 2b have visible UI effects but no new components were added, so screenshots aren't substantially different from before/after the data wiring.

Checklist

  • I have included a video or screen recording for UI changes, or marked Demo as N/A
  • Relevant tests pass locally
  • Relevant linting and formatting pass locally
  • I have signed the CLA, or I will sign it when the bot prompts me

Contributor Resources

ardaerzin added 2 commits May 27, 2026 01:10
… links

The trace drawer's side panel renders application / variant / environment
tags with links built from the trace's references. When a trace is emitted
with slug-only refs (the common case for third-party instrumentations),
the raw ref objects carry no `id`, so the link templates collapse to empty
hrefs and the panel shows non-clickable text.

PR #4425 added an imperative resolver (`resolveTraceRefs`) that maps
slug-only refs back to concrete `{appId, revisionId}` via the backend's
`POST /workflows/revisions/retrieve` endpoint, but only the Playground
button consumed it. This change lifts that resolver into a TanStack-Query
atom (`resolvedTraceRefsAtomFamily`) so the side panel can subscribe to
the same resolved data and produce working links for application, variant,
and environment tags on slug-only traces.

The atom family is keyed by a stable encoding of the identifying refs
(`buildResolvedTraceRefsKey`) so two spans that share the same triple
share the same atom and the same query cache entry. A sentinel
`EMPTY_TRACE_REFS_KEY` keeps the atom disabled when no identifying ref is
present, so consumers can call it unconditionally without a no-op fetch.

Scope: application-side refs only. Evaluator slug resolution (different
backend endpoint) and ephemeral playground gaps (issue #4426 problems 2
and 3) are out of scope for this branch.

Tests cover key encoding, the empty-sentinel path, the disabled-state
shape (no projectId, no identifying ref), and the success path that
forwards refs to the underlying resolver.
Bundles fixes for the remaining four problems from issue #4426 (the
trace→playground flow) on top of #4425's resolver. Problem 1 (slug-only
side panel) shipped on the first commit of this branch.

Problem 3 — evaluator spans open the graded app (playgroundController.ts):
PR #4425's resolver backfills `refs.application_revision.id` for any
span carrying app refs. Evaluator spans always carry the graded app's
refs alongside the evaluator's, so the application_revision branch
fired before the evaluator_revision branch and the user landed on the
wrong entity. Extracts the branch-selection logic into a pure helper
`selectOpenFromTraceBranch(refs, isEvaluatorSpan)` and gates the
application branch on `!isEvaluatorSpan`. The helper is unit-tested in
isolation so the regression cannot reappear without a test failure.

Problem 2d — environment refs dropped (traceRefResolution.ts,
resolvedTraceRefsAtom.ts, retrieveWorkflowRevision):
Env refs (environment / environment_variant / environment_revision)
are now extracted by `extractReferences`, included in
`IDENTIFYING_REF_KEYS` so `hasAppReference` enables the Playground
button for env-only traces, forwarded to `POST /workflows/revisions/
retrieve` (the Fern client already accepts these fields), and included
in `buildResolvedTraceRefsKey` so the side panel atom resolves them
too. End result: env-only traces open the deployed revision instead of
disabling the button.

Problem 2a/2c — ephemeral has no URI, config panel empty
(store.ts createEphemeralWorkflow):
Without `data.uri` the playground cannot fetch an OpenAPI schema and
falls back to the empty "No configuration needed" state, hiding the
parameters we already extract. The constructor now defaults the URI
to `agenta:builtin:completion:v0` / `agenta:builtin:chat:v0` based on
detected chat mode for non-evaluator ephemerals — same builtin URIs
the runnable layer already uses. Evaluator ephemerals continue to take
their URI from `deriveBuiltinUriFromSpanName` at the call site.

Problem 2b — "Create" spawns a new app instead of forking the source
(commit.ts createWorkflowFromEphemeralAtom):
Reads `meta.sourceRef.type === "application"` and, when an app id is
available, forks the source workflow as a new variant (seed v0 + data
v1, mirroring `createWorkflowVariantAtom`) instead of calling
`createWorkflow`. Falls back to the new-workflow path when no source
id is available (third-party traces with slug-only refs that didn't
resolve). This branch lacks dedicated unit tests because the function's
dependency surface is heavy; manual QA covers the fork vs new-app
decision.

Tests
- traceRefResolution.test.ts: 13 new cases — `hasAppReference` with
  env refs, `resolveTraceRefs` forwarding env refs (single / combined
  / variant / revision), `selectOpenFromTraceBranch` (5 branch
  scenarios including the issue-#4426 problem-3 regression).
- resolvedTraceRefsAtom.test.ts: env refs included in the cache key
  and produce distinct keys from app-only refs.
- retrieveWorkflowRevision.test.ts: forwards env refs in the request
  body and treats an env ref as identifying.
- createEphemeralWorkflow.test.ts (new file): URI derivation for
  completion / chat / explicit / evaluator-without-uri cases, and
  parameter pass-through.
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 27, 2026

AGE-3777

@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment May 27, 2026 6:45am

Request Review

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 27, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2393a686-7edc-410f-8818-ddc32972ebcd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-fix/age-3777-trace-playground-side-panel-links-broken-for-slug-only-refs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-c0cd.up.railway.app/w
Project agenta-oss-pr-4453
Image tag pr-4453-9d0c9a0
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-05-27T06:58:00.524Z

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

Labels

Frontend size:L This PR changes 100-499 lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant