feat: allow side elements to opt out of automatic expansion - #3054
minwookshin wants to merge 3 commits into
Conversation
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
All reported issues were addressed across 7 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Only clear an empty side-element view when it still displays a side element tracked by the message hook. Preserve unrelated ElementSidebar state, including its title and key, when inline or page elements arrive or tracked content is replaced. Check display as well as ID so a reused ID cannot claim an inline view. Cover title-only and populated API sidebars, replacements with new or reused IDs, and cleanup of explicitly opened opt-out elements. Six preservation regressions fail before this change; all 44 frontend tests pass after it. Co-Authored-By: Codex <noreply@openai.com>
|
@codex review |
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Preserve API replacements while cleaning up message-owned panels after remounts and explicit side-element opens. Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
1 issue found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="frontend/tests/sideElementsNavigation.spec.tsx">
<violation number="1" location="frontend/tests/sideElementsNavigation.spec.tsx:110">
P3: These `AutoResumeThread` assertions always pass and guard nothing: with `useChatMessages` mocked to `threadId: 'active'`, every render is either the current thread (the `AutoResumeThread` branch in ThreadPage requires `!isCurrentThread`) or a `/share/...` route (it also requires `!isSharedRoute`), so the component can never mount in these tests. Either navigate to a non-current, non-shared route to actually exercise the resume path, or drop the assertion.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| act(() => result.current.navigate('/thread/active')); | ||
|
|
||
| expect(screen.getByText('Active thread')).toBeInTheDocument(); | ||
| expect(AutoResumeThread).not.toHaveBeenCalled(); |
There was a problem hiding this comment.
P3: These AutoResumeThread assertions always pass and guard nothing: with useChatMessages mocked to threadId: 'active', every render is either the current thread (the AutoResumeThread branch in ThreadPage requires !isCurrentThread) or a /share/... route (it also requires !isSharedRoute), so the component can never mount in these tests. Either navigate to a non-current, non-shared route to actually exercise the resume path, or drop the assertion.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/tests/sideElementsNavigation.spec.tsx, line 110:
<comment>These `AutoResumeThread` assertions always pass and guard nothing: with `useChatMessages` mocked to `threadId: 'active'`, every render is either the current thread (the `AutoResumeThread` branch in ThreadPage requires `!isCurrentThread`) or a `/share/...` route (it also requires `!isSharedRoute`), so the component can never mount in these tests. Either navigate to a non-current, non-shared route to actually exercise the resume path, or drop the assertion.</comment>
<file context>
@@ -0,0 +1,144 @@
+ act(() => result.current.navigate('/thread/active'));
+
+ expect(screen.getByText('Active thread')).toBeInTheDocument();
+ expect(AutoResumeThread).not.toHaveBeenCalled();
+ expect(result.current.panel).toBeUndefined();
+ });
</file context>
Addresses #2932.
A new or updated side element currently reopens a panel the user has closed. Add a keyword-only
auto_expand=Falseoption to elements, includingCustomElement, and carry it as the optionalautoExpandlive event hint.The frontend keeps a closed panel closed for opted-out arrivals, updates an already open panel, and still opens it when the user clicks the message reference. Existing callers keep automatic expansion by default. When no side elements remain, cleanup only closes a view still displaying a tracked side element; sidebars opened through
ElementSidebar.set_titleorset_elementsretain their contents, title and key across unrelated inline/page updates.Validation: All 938 backend tests on Python 3.13 and all 44 frontend tests pass. The seven new sidebar cases include six preservation regressions that fail before the cleanup fix, including a replacement reusing a tracked ID, and one explicit opt-out element cleanup case. Six API compatibility cases also pass on Python 3.10, covering Text, File and CustomElement with both values of auto_expand. The repository pre-commit checks, including full backend mypy, source/test lint and frontend/react-client typechecks, pass. Repository-wide ESLint/format checks and the embedded copilot build also pass. The production frontend Vite build passes with
NODE_OPTIONS=--max-old-space-size=4096; the default 2GB Node heap was insufficient on the validation machine. Existing sourcemap and chunk-size warnings remain. Chrome verification against the real backend covers default opening, quiet Text and CustomElement arrivals, and explicit opening of both kinds. Documentation includes the API and persistence boundary.The hint is intentionally not persisted; restored historical threads keep their current display behavior. Apply the option to each new or updated element that should remain quiet.
Summary by cubic
Fixes the side panel reopening on every side-element update (issue #2932). Elements can now opt out with
auto_expand=Falseand remain reachable only through their message reference.auto_expandapplies toElementandCustomElementand defaults toTrue.Written for commit 3077a9a. Summary will update on new commits.