You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf(frontend): load the trace drawer on demand in /m - #8050
Do not merge into v0.128.4. This goes into the next release.
Context
Every page in /m loads 263 KB gzip less JavaScript on first load. The app shell went from 1,241,531 to 972,022 bytes gzip, and the shell is the code every page loads. Before this change, the shell carried the trace drawer's body and its drill-in panel (the JSON tree with its editor), although most page visits never open a trace. The change is not behind a switch, so every user gets it.
Changes
The drawer body and the drill-in panel now load on demand, with next/dynamic.
TraceDrawer (in @agenta/observability-ui) loads TraceDrawerContent on the first open. The drawer panel still opens at once, and it shows a skeleton until the body arrives. /w already loads the whole drawer with next/dynamic, so its first load does not change.
registerTraceDrawerSlots registers the drill-in panel (TraceSpanPanel) as a dynamic component. The slot registrations stay in the shell, so the add-to-queue picker and the panels reach the drawer the same way as before, and also reach the annotation queue session, which renders the drawer's overview outside the drawer.
If either chunk fails to load, the skeleton changes to a load error with a "Try again" button, so the user does not wait on a skeleton that never ends.
There is one behaviour change. The first trace open in a page waits for one chunk. In live QA on a dev stack the skeleton showed for about 215 ms, and later opens in the same page show no skeleton.
The change also fixes a bug that production /m has today. The trace drawer showed annotation authors as raw user ids, because /m never gave the drawer a member list. While the drawer is open, /m now loads the workspace members (the same query that Settings uses) and binds them, so the drawer shows the author's user name. The member query also loads on demand, so the shell does not carry it.
First load, gzip, built on the same machine (release head cfbe8af2d1 against this branch):
Page
Before
After
Change
App shell (every page)
1,241,531
972,022
-263.2 KB
Observability
1,484,422
1,240,244
-238.5 KB
Apps
1,416,515
1,151,458
-258.8 KB
Sessions
1,851,822
1,839,662
-11.9 KB
One session (agent chat)
1,794,472
1,777,253
-16.8 KB
Annotation queue session
1,418,898
1,412,184
-6.6 KB
The session and queue pages drop less, because they already load the JSON tree for their own content. scripts/speed/budget.json now holds the new sizes, so a later change cannot add the weight back without failing speed:check. It also adds the routes that had no budget yet.
Tests
New traceDrawerLazy.render.test.tsx. It opens the drawer from a chat turn's "View trace" action and from a traces list row. The first open shows the loading panel and then the drawer, and the shell's add-to-queue slot renders inside the lazily loaded header. The author names resolve with no binding in the test, and the shell import does not load the drill-in panel.
New tests for both loading states: a failed load shows the error and calls retry, with no technical text.
/m types, /w types (@agenta/oss), @agenta/observability-ui types and tests, speed:check, and the antd route check (playground, observability, session, annotation queue session) pass. Full /m tests pass except four that fail on the release head too (testsetCommit, membersTabRoleChange).
A ?trace= link does not open the drawer on page load. The release branch does not do it either, because nothing in /m reads that parameter to open the drawer, so this PR leaves it as it is.
What to QA
Open Observability, Traces, and click a row on a fresh page load. The drawer slides in once and shows a short skeleton, then the trace. Close it and open another row. There is no skeleton.
Annotate a trace, reload the page, open that trace and hover the score. The author shows as a user name, not an id.
Open a trace from an annotation queue session ("Open trace"). The drawer opens, and the "Add annotation queue" button in its header works.
Regression: open a trace at phone width (390 px). The stacked layout and the Inputs and Outputs panels show as before.
🤖 The AI agent says: Live QA as a real user passed, with no bug found. I ran it on a fresh OSS dev stack built from this branch, in headless Chromium at 1440 px and 390 px, with SDK-traced Mistral runs and one annotation. The recording (checks 1, 5, 6 and 8 at 1440 px) is posted separately, because gh cannot attach a video.
Check
Result
What I saw
Traces table, first open on a fresh page
pass
The panel opened once, with no close and reopen and no second slide. The "Loading trace" skeleton appeared together with the panel and left about 215 ms later. With 1.5 s of added network latency, the skeleton was still on screen at 700 ms, and then the body arrived.
Second open
pass
No skeleton.
Annotation queue session, "Open trace"
pass
The skeleton showed on the first open only, and the queue page kept its state.
Author names
pass
On a fresh page load straight into Traces, the score popover in the drawer showed the user name, not the raw id.
State
pass
Switching spans, closing and reopening left no stuck skeleton. The traces table kept its scroll position and search.
Add to annotation queue button
pass
It renders in the drawer header and opens the shadcn picker. Picking a queue adds the trace.
Console
pass
Only the known noise. No chunk load errors, and no API errors during drawer steps.
Sessions tab
not applicable
The tab has no trace entry point on this branch.
Agent chat "View trace"
not tested live
The agent run could not reach the API on this stack, because I bound the stack port to localhost on purpose. A unit test covers this entry point. It uses the same open action as the table.
?trace= and ?span= links loaded directly
no change
No drawer opens. The release branch behaves the same, because nothing in /m reads these parameters to open the drawer.
Review loop result for head f3599a0fa3 (base cfbe8af2d1), 2 rounds, Codex. The later head f12dd6d785 only changes budget.json.
Lens
Final rating
Correctness
Low
Simplify
Low
Fixed: If the drawer body or the drill-in panel chunk failed to load, the skeleton stayed forever. Both loading states now show a load error with a retry (f3599a0). Left on purpose: The reviewer worried that members arriving after the annotations would leave raw ids. A store test showed the annotation query refetches when the member list changes, and the name resolves. Live QA on a fresh page load showed the name too.
Reviewing files that changed from the base of the PR and between d3e0e83 and d3e0e83.
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
Performance
Updated initial-load size budgets for existing routes and added budgets for annotations, archived apps, endpoints, evaluators, prompts, testsets, and variants.
User Experience
Trace drawer content now loads on demand, with loading placeholders and a retry option if loading fails.
The trace drawer content and mobile drill-in panel now load on demand and show loading or retry states. The mobile app binds workspace members while the drawer is open. The first-load gzip byte budgets are updated for the shell and routes.
GlobalDrawers mounts the workspace-member binding component only while the drawer is open. The drill-in panel loads dynamically with a skeleton fallback. Tests cover the loading flow, retry behavior, and rendering after load.
The shell and existing route byte budgets are updated. Budgets are added for annotations, archived apps, endpoints, evaluators, prompts, testsets, and variants.
The drawer now loads on demand and the reported bundle reduction is a real benefit. Remaining issues are small and recoverable: an annotation author may briefly appear as an ID, a chunk-load failure after a deployment may need a page reload, and one test is order-dependent. These can be fixed before or shortly after merge.
Pre-merge checks: 5
Check name
Status
Explanation
Title check
The title "perf(frontend): load the trace drawer on demand in /m" matches the main change. The PR defers the trace drawer body and drill-in panel (TraceSpanPanel) in /m with next/dynamic, which the ra…
Description check
The description explains the change. It covers the lazy loading of the drawer body and drill-in panel with next/dynamic, the skeleton and retry states, the workspace member binding that fixes raw user…
Docstring Coverage
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
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Full details: Title check
Explanation
The title "perf(frontend): load the trace drawer on demand in /m" matches the main change. The PR defers the trace drawer body and drill-in panel (TraceSpanPanel) in /m with next/dynamic, which the raw summary and objectives confirm. The title is specific and concise, and it uses a conventional commit prefix.
Full details: Description check
Explanation
The description explains the change. It covers the lazy loading of the drawer body and drill-in panel with next/dynamic, the skeleton and retry states, the workspace member binding that fixes raw user ids in annotation authors, the budget.json update, and the tests. The figures match the objectives. It also notes that the PR should not merge into v0.128.4.
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 13 files. (1 skipped: 1 unsupported.)
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.
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 2 remain after this review.
🤖 The AI agent says: /w also uses the package TraceDrawer, so the lazy drawer body reaches /w users too. I checked /w live on head f12dd6d785 at 1440 px, on a fresh OSS dev stack, and it passed with no bug.
Check
Result
What I saw
Traces table, first open on a fresh page
pass
The panel opened once and was never removed during the open. The "Loading trace" skeleton appeared with the panel and left 30 to 150 ms later.
Second open
pass
No skeleton and no flash.
Drawer tabs
pass
Overview, Raw Data, Linked Spans and Annotations all render content.
Session drawer, "Open trace"
pass
The trace opened once, and the skeleton showed for 69 ms. All four tabs render, and the annotated trace shows its annotation. The session drawer stays open after the trace closes, and a reopen shows no skeleton.
Evaluation run focus drawer
not tested
It needs an app, a test set and an evaluator, and the runner could not reach the API on this stack, because the stack port was bound to localhost.
Console
pass
Nothing new from the drawer and no chunk load errors. A Failed to fetch JWT message also appears on a page load with no drawer open, so the drawer does not cause it.
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.
…and in /m
The app shell carried the trace drawer's body and its drill-in panel
(the JSON tree and editor) on every page. Both now load on the first
trace open. The drawer panel still opens at once and shows a skeleton
until the body arrives.
While the drawer is open, /m loads the workspace members, so the
drawer names annotation authors instead of showing raw user ids.
The drawer body and the drill-in panel load on demand. If their chunk
failed, the skeleton stayed on screen with no way out. Both loading
states now show a load error with a Try again button.
The app shell is 263 KB gzip smaller now that the trace drawer body and
drill-in panel load on demand. The budget records the new sizes so a
later change cannot quietly add the weight back. It also adds the routes
that had no budget yet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Do not merge into v0.128.4. This goes into the next release.
Context
Every page in /m loads 263 KB gzip less JavaScript on first load. The app shell went from 1,241,531 to 972,022 bytes gzip, and the shell is the code every page loads. Before this change, the shell carried the trace drawer's body and its drill-in panel (the JSON tree with its editor), although most page visits never open a trace. The change is not behind a switch, so every user gets it.
Changes
The drawer body and the drill-in panel now load on demand, with
next/dynamic.TraceDrawer(in@agenta/observability-ui) loadsTraceDrawerContenton the first open. The drawer panel still opens at once, and it shows a skeleton until the body arrives. /w already loads the whole drawer withnext/dynamic, so its first load does not change.registerTraceDrawerSlotsregisters the drill-in panel (TraceSpanPanel) as a dynamic component. The slot registrations stay in the shell, so the add-to-queue picker and the panels reach the drawer the same way as before, and also reach the annotation queue session, which renders the drawer's overview outside the drawer.There is one behaviour change. The first trace open in a page waits for one chunk. In live QA on a dev stack the skeleton showed for about 215 ms, and later opens in the same page show no skeleton.
The change also fixes a bug that production /m has today. The trace drawer showed annotation authors as raw user ids, because /m never gave the drawer a member list. While the drawer is open, /m now loads the workspace members (the same query that Settings uses) and binds them, so the drawer shows the author's user name. The member query also loads on demand, so the shell does not carry it.
First load, gzip, built on the same machine (release head
cfbe8af2d1against this branch):The session and queue pages drop less, because they already load the JSON tree for their own content.
scripts/speed/budget.jsonnow holds the new sizes, so a later change cannot add the weight back without failingspeed:check. It also adds the routes that had no budget yet.Tests
traceDrawerLazy.render.test.tsx. It opens the drawer from a chat turn's "View trace" action and from a traces list row. The first open shows the loading panel and then the drawer, and the shell's add-to-queue slot renders inside the lazily loaded header. The author names resolve with no binding in the test, and the shell import does not load the drill-in panel.@agenta/oss),@agenta/observability-uitypes and tests,speed:check, and the antd route check (playground, observability, session, annotation queue session) pass. Full /m tests pass except four that fail on the release head too (testsetCommit,membersTabRoleChange).?trace=link does not open the drawer on page load. The release branch does not do it either, because nothing in /m reads that parameter to open the drawer, so this PR leaves it as it is.What to QA