Skip to content

fix(frontend): fix five /w playground and prompts bugs found in live QA - #8108

Merged
mmabrouk merged 5 commits into
release/v0.128.8from
fix/w-bugs-from-live-qa
Nov 5, 2026
Merged

mmabrouk merged 5 commits into
release/v0.128.8from
fix/w-bugs-from-live-qa

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Nov 4, 2026

Copy link
Copy Markdown
Member

Five bugs in the /w app that live QA found. Each one is old (also on main), and each fix is its own commit with a test that fails before the fix.

What users saw

  1. A reload after closing an evaluator drawer lost the test set and the drafts. In the /w playground, open an evaluator drawer (header "Evaluator" > Create new, or New Evaluation > Create new evaluator) and close it. The URL lost ?revisions= and the #pgSnapshot hash, so a reload showed one empty row and no test set.
  2. The /w evaluator playground let you leave with unsaved edits. The app playground asks before the page unloads; the evaluator playground did not.
  3. /w compare mode logged "Maximum update depth exceeded" 100 to 400 times per load or run.
  4. The /w Prompts row menu logged "Maximum call stack size exceeded" when Move, Rename or Delete (folder) opened its dialog. The action still worked.
  5. /w "Add all matching to queue" Retry sent the traces that were already queued again. The API does not drop duplicate trace ids, so the queue got duplicate scenarios.

Why, and what changed

  1. Closing the drawer cleared revisionId from the URL even when it was not there. That navigation rebuilds the URL from the Next router query, which does not know about ?revisions= and the hash, because the playground writes those with history.replaceState. useQueryParamState now does nothing when it clears a param that is not in the URL.
  2. ConfigureEvaluator now calls useLocalDraftWarning, like Playground.tsx.
  3. PanelSessionInspectorButton (one per compare column) called executionController.selectors.backendSessionId(...) in render. That atom family keys on an object, so every render got a new atom, and useAtomValue rendered again without end. The atom is now kept with useMemo.
  4. The row menu (Radix, from @agenta/ui/table) traps the focus until it closes, and the antd dialog traps it too. The dialog opened while the menu still held the trap, and the two traps moved the focus back and forth. The four menu items that open an antd dialog now open it one tick later, after the menu has closed. App Rename and Archive did not show the loop and are unchanged.
  5. The hook now keeps the ids that each run added. Retry passes them as excludeTraceIds (the scan already supports it), lowers the per-run cap by their number, and the toasts count them. This is the /w half of what fix(frontend): queue scan stops on a failed trace read, Retry sends only the rest, live filter drops annotation fields #8098 does for /m.

No shared package changes, so /m does not change.

Tests

Each test fails on main and passes with the fix:

  • state/appState/hooks.test.tsx: clearing an absent param does not navigate; clearing a present one still does.
  • ConfigureEvaluator/index.test.tsx: the page uses the leave warning.
  • PanelSessionInspectorButton.test.tsx: counts commits; 103 before the fix, under 5 after.
  • usePromptsColumns.test.tsx: Move (app and folder), Rename and Delete call their handler only after the menu has closed.
  • useBatchAddTracesToQueue.test.tsx: real scan and real queue add with HTTP mocked; after a failed second batch, Retry sends only the 50 traces that failed.

Checks: @agenta/oss and @agenta/mobile type checks pass, lint has 0 errors.

Live check

On a fresh OSS dev stack, before and after the fix:

Bug Before After
1 Close drawer: revisions gone, hash empty; reload shows no test set URL kept; reload keeps the test set and 2 rows (header path and New Evaluation path)
2 Unsaved evaluator edit: beforeunload not prevented prevented
3 Click Compare: 243 "Maximum update depth" errors 0
4 Each Move/Rename/Delete dialog: 10 page errors 0; a real move still lands in the target folder
5 Not run live (needs a failing queue add); covered by the unit test

Not fixed here

  • If the drawer's prev/next writes revisionId into the playground URL, closing it still rebuilds the URL from the router query. The playground drawers do not use prev/next today.
  • The object-keyed atom families in @agenta/playground (backendSessionIdAtomFamily and others) have no key comparator, so every inline call builds a new atom. A comparator there would remove this kind of loop at the source; it is a shared-package change for a later PR.

Agenta Product Agent added 5 commits November 4, 2026 21:45
Closing the drawer cleared revisionId even when the URL had none. That
navigation rebuilt the URL from the router query, which lacks the
?revisions= and #pgSnapshot that the playground writes itself, so a
reload lost the connected test set and the drafts. Clearing a param that
is not in the URL is now a no-op.
…ved edits

ConfigureEvaluator now calls useLocalDraftWarning, as the app playground
does.
PanelSessionInspectorButton read executionController.selectors.backendSessionId
inline. Its atom family keys on an object, so each render got a new atom,
and useAtomValue rendered again without end ("Maximum update depth
exceeded" 100 to 400 times per load). The atom is now memoized per panel.
The row menu (Radix) and the antd dialogs both trap the focus. Move,
Rename and Delete opened their dialog while the menu still trapped it,
and the two traps moved the focus back and forth until "Maximum call
stack size exceeded". These items now open the dialog on the next tick.
Retry ran the whole scan again and sent the traces that the failed run had
already added, which made duplicate scenarios in the queue. The hook now
keeps the ids each run added, skips them on Retry, lowers the per-run cap
by their number, and counts them in the toasts.
@mmabrouk

mmabrouk commented Nov 4, 2026

Copy link
Copy Markdown
Member Author

🤖 The AI agent says:

Review loop result for head df8860523c (base d1c6dd2e67), 1 round (Opus and Codex on slop and simplify; Codex on correctness).

Lens Final rating
Slop Low (Codex Low; Opus Low, one item it marked Medium)
Simplify Low
Correctness Low

Fixed: the "Queue add incomplete" toast now counts the same way as the other toasts (earlier runs plus this run). The comment on afterMenuCloses now says why it is a timeout and which items do not need it.
Left on purpose: app Rename and Archive are not deferred: a live check of both dialogs showed no focus loop. useDeferredMenuSelect is not reused: the menu lives in @agenta/ui and has no per-item close callback, and this PR does not change shared packages. If drawer prev/next writes revisionId into the playground URL, closing it still rebuilds the URL from the router query; the playground drawers do not use prev/next today. A key comparator for the object-keyed atom families in @agenta/playground is a later shared-package change.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

Run configuration

Commits

Reviewing files that changed from the base of the PR and between df88605 and df88605.

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
Summary

Summary by CodeRabbit

  • New Features
    • Added a warning when leaving evaluator configuration with unsaved changes.
  • Bug Fixes
    • Batch trace retries now skip traces already added and account for them in progress and limits.
    • Prompt actions that open dialogs now wait for their menus to close.
    • Improved session inspector rendering stability and prevented unnecessary navigation when clearing an absent revision parameter.

This pull request updates five web behaviors: evaluator draft warnings, session inspector selector creation, trace queue retries, prompt row actions, and query parameter navigation. It also adds tests for these changes.

Changes: Evaluator draft warning

Layer / File(s) Summary
Configure evaluator draft warning
web/oss/src/components/Evaluators/components/ConfigureEvaluator/index.tsx, web/oss/src/components/Evaluators/components/ConfigureEvaluator/index.test.tsx
ConfigureEvaluatorPageInner calls useLocalDraftWarning(). A test checks that the hook is called when the page renders.

Session inspector selector

Layer / File(s) Summary
Memoize the session selector
web/oss/src/components/SessionInspector/PanelSessionInspectorButton.tsx, web/oss/src/components/SessionInspector/PanelSessionInspectorButton.test.tsx
The button memoizes the backend session ID selector atom using loadableId and entityId. A profiler test checks the render commit count.

Trace queue retries

Layer / File(s) Summary
Carry added trace IDs across retries
web/oss/src/components/pages/observability/components/ObservabilityHeader/useBatchAddTracesToQueue.tsx, web/oss/src/components/pages/observability/components/ObservabilityHeader/useBatchAddTracesToQueue.test.tsx
Retries reuse successfully added trace IDs, exclude them from later scans, and include them in progress and notification counts. The test checks trace IDs and notifications after a failed batch and retry.

Prompt row actions

Layer / File(s) Summary
Defer actions until the menu closes
web/oss/src/components/pages/prompts/hooks/usePromptsColumns.tsx, web/oss/src/components/pages/prompts/hooks/usePromptsColumns.test.tsx
Folder Rename, Move, and Delete actions and app Move defer their callbacks until the menu closes. Tests check that the menu is closed when the callbacks run.

Query parameter navigation

Layer / File(s) Summary
Skip navigation for absent parameters
web/oss/src/state/appState/hooks.ts, web/oss/src/state/appState/hooks.test.tsx
useQueryParamState skips navigation when both the resolved and current values are nullish. Tests cover clearing absent and present revisionId parameters.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant useBatchAddTracesToQueue
  participant TraceQuery
  participant QueueAdd
  participant Notification
  User->>useBatchAddTracesToQueue: Start trace queue run
  useBatchAddTracesToQueue->>TraceQuery: Scan traces, excluding previously added IDs
  TraceQuery-->>useBatchAddTracesToQueue: Return trace IDs
  useBatchAddTracesToQueue->>QueueAdd: Submit trace IDs
  QueueAdd-->>useBatchAddTracesToQueue: Return failure
  useBatchAddTracesToQueue->>Notification: Show retry notification
  User->>useBatchAddTracesToQueue: Retry
  useBatchAddTracesToQueue->>TraceQuery: Scan remaining traces
  TraceQuery-->>useBatchAddTracesToQueue: Return remaining trace IDs
  useBatchAddTracesToQueue->>QueueAdd: Submit remaining trace IDs
  QueueAdd-->>useBatchAddTracesToQueue: Return success
  useBatchAddTracesToQueue->>Notification: Show success count
Loading

Possibly related issues

Possibly related PRs

  • Agenta-AI/agenta#8070: Changes the shared useLocalDraftWarning hook; this pull request calls that hook from ConfigureEvaluatorPageInner.
  • Agenta-AI/agenta#8012: Adds the shared playground leave guard and changes the dirty-state contract used by useLocalDraftWarning.
  • Agenta-AI/agenta#8075: Changes playground URL selection and snapshot restoration, related to this pull request's handling of absent revisionId query parameters.
Merge Risk: Minimal · up to df886

The fixes can merge after normal checks. Shorten the two focus-trap comments to comply with the frontend guidance.

Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title clearly identifies a frontend fix covering five bugs in the playground and Prompts areas.
Description check Passed The description directly explains all five fixes, their causes, tests, validation results, and out-of-scope items.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 10 files.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick comments: 2
web/oss/src/components/pages/prompts/hooks/usePromptsColumns.test.tsx: 1

32-37: Trivial · Maintainability & Code Quality · Quick win

Shorten the focus-trap comment to two sentences.

The ordering constraint is genuinely surprising, so the guidance permits more than one short line. It permits only up to two sentences, however.

Suggested fix
-/**
- * The row menu (Radix) and the antd dialogs both trap the focus. When Move, Rename or Delete
- * opened its dialog while the menu was still open, each trap moved the focus back in turn, and the
- * /w Prompts page logged "Maximum call stack size exceeded". A dialog must open only after the
- * menu has closed.
- */
+/**
+ * Radix and antd both trap focus, so opening a dialog before the menu closes can cause a focus loop
+ * and log "Maximum call stack size exceeded" on the /w Prompts page. Open dialogs only after the
+ * menu closes.
+ */
web/oss/src/components/pages/prompts/hooks/usePromptsColumns.tsx: 1

20-27: Trivial · Maintainability & Code Quality · Quick win

Shorten the focus-trap comment.

The focus-trap ordering and missing callback contract justify a longer comment, but five sentences exceed the two-sentence limit. Keep both points concise.

Suggested fix
-/**
- * The row menu traps the focus until it has closed, and an antd dialog traps it too. A dialog
- * opened from the menu's click handler made the two move the focus back and forth without end
- * ("Maximum call stack size exceeded"). So the menu items that open an antd dialog wait one tick,
- * until the menu has closed. A timeout, because the menu lives in `@agenta/ui` and gives no close
- * callback per item. The app Rename and Archive dialogs do not show the loop, so they open
- * directly.
- */
+// Both the row menu and antd dialogs trap focus, so defer dialog-opening actions until the menu closes.
+// `ActionItem` exposes no per-item close callback, so `setTimeout(..., 0)` supplies the ordering.
Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between d1c6dd2 and df88605.

Files selected for processing: 10
  • web/oss/src/components/Evaluators/components/ConfigureEvaluator/index.test.tsx
  • web/oss/src/components/Evaluators/components/ConfigureEvaluator/index.tsx
  • web/oss/src/components/SessionInspector/PanelSessionInspectorButton.test.tsx
  • web/oss/src/components/SessionInspector/PanelSessionInspectorButton.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityHeader/useBatchAddTracesToQueue.test.tsx
  • web/oss/src/components/pages/observability/components/ObservabilityHeader/useBatchAddTracesToQueue.tsx
  • web/oss/src/components/pages/prompts/hooks/usePromptsColumns.test.tsx
  • web/oss/src/components/pages/prompts/hooks/usePromptsColumns.tsx
  • web/oss/src/state/appState/hooks.test.tsx
  • web/oss/src/state/appState/hooks.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 2 remain after this review.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Item Value
Status stopped
Commit df8860523c54223b6a10366374df74e97d7b58c8
Manual expiry (UTC) Not granted
CI deadline (UTC) Not granted
Workflow https://github.com/Agenta-AI/agenta/actions/runs/41911290018

Preview use finished or expired. Environment absence verified; retained storage requires separate provider accounting.

Post /preview as a new comment to request a one-hour preview. Repeating it while active does not extend the hour.
Preview data is disposable. Expiry is enforced by the next successful cleanup sweep, not an exact timer.
Environment deletion stops its compute. Provider-retained storage and permanent services may still be billed.

@mmabrouk
mmabrouk changed the base branch from main to release/v0.128.8 November 5, 2026 16:11
@mmabrouk
mmabrouk merged commit ce3c478 into release/v0.128.8 Nov 5, 2026
93 of 99 checks passed
@mmabrouk mmabrouk mentioned this pull request Nov 5, 2026
7 of 8 tasks
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.

1 participant