feat(agentex-ui): account picker via same-origin BFF proxy#350
Open
erichwoo-scale wants to merge 9 commits into
Open
feat(agentex-ui): account picker via same-origin BFF proxy#350erichwoo-scale wants to merge 9 commits into
erichwoo-scale wants to merge 9 commits into
Conversation
3 tasks
Contributor
Author
|
Addressed the Greptile findings in
Also, per UX design feedback, moved the account picker out of the header/collapsed-top rail into the sidebar footer (below Give Feedback) — top of the sidebar is untouched. |
Route the SDK through a same-origin BFF (`/api/agentex`) instead of calling the agentex API directly from the browser, and add an account switcher. - BFF proxy + shared `applyBffCredentials` forward the request cookies and an `x-selected-account-id` header to the upstream (agentex + platform APIs). - The selected account is driven by the `account_id` query param — no cookie — and injected on every SDK request via a synchronous ref. - `/api/user-info` fetches the caller's accounts; the picker bootstraps to the first account when the param is missing/stale (the API needs one to resolve a principal). Single account renders as static context; collapsed rail shows an icon-only variant. - Gated on the platform API being configured (`SGP_API_URL` / `NEXT_PUBLIC_SGP_APP_URL`); no-op otherwise. Env: `NEXT_PUBLIC_AGENTEX_API_BASE_URL` → server-only `AGENTEX_API_URL`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oter Address Greptile review + UX design feedback. - BFF: drop any client-supplied `Authorization` in applyBffCredentials so a client can't inject its own bearer token to the upstream (P1); strip `Location` from upstream 3xx responses so internal redirect targets don't leak to the browser (P2). - UX: move the account picker out of the sidebar header / collapsed top rail into the footer, directly below Give Feedback (top of the sidebar now untouched). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the account picker's loading skeleton with a disabled, empty picker (building icon only) — a plain skeleton block read as odd once the picker moved into the footer between Give Feedback and Log out. Keeps the row stable and reads as "loading account selector". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…switch - Account picker: extract a shared `iconTile` (loading + single-account collapsed tiles) and a shared `options` element (the SelectContent list previously duplicated across the collapsed and expanded switchers); single change handler `onAccountChange`. - Provider: `setSelectedAccountId` now clears `task_id` on an explicit switch (the open task is account-scoped and 404s under a new account). This preserves the reset that previously lived in agentex-ui-root's validation effect, which #347 reworked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The STRIP_REQ comment previously read as if `authorization` went unmanaged. Spell out that applyBffCredentials deletes any client-supplied `cookie`/`authorization` and sets the server-managed values, so the stripping applies to every /api/* proxy — addressing the review note without moving credential logic out of the shared helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8eb5b47 to
5f243a0
Compare
Collaborator
|
Will we need to update the sgp repo to pass in the |
Contributor
Author
yup working on the corresponding sgp PR, and will hold off on merging until thats ready |
…e flash Switching accounts closes the open task (task_id cleared), which flips PrimaryContent from ChatView to HomeView immediately. HomeView rendered the agents list from the still-cached previous account (invalidateQueries keeps data during the refetch), so the new account briefly flashed the old account's agents before recalibrating. Use resetQueries instead: the previous account's agents/tasks are dropped on switch, so HomeView shows a loading state until the new account's data lands — never stale data. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
declan-scale
reviewed
Jul 8, 2026
declan-scale
approved these changes
Jul 8, 2026
Trim redundant/verbose comments across the account-picker BFF layer (drop lines that restate the code or repeat a docstring); no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…itch A selected agent is account-scoped, but its name persisted in the URL across a switch — so a same-named agent in the new account stayed selected (and #347's localStorage restore could reinstate it). On an account change, clear agent_name and the remembered agent so the view resets to the grid. task_id is already cleared by the switch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7530498 to
54e5b75
Compare
Cookie-auth backends (SGP's identity-service-auth) resolve the account from the `_jwt` access-profile cookie when it's present and only fall back to `x-selected-account-id` when it's absent — so forwarding `_jwt` pins requests to the account the user linked in with and silently ignores the account they switched to. Drop `_jwt` before forwarding (default/cookie mode) so the selected account wins; identity stays via `_identityJwt`. agentex is unaffected (it never reads `_jwt`), and auth mode drops all cookies anyway. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
First of a 2-PR stack bringing account scoping + OIDC login to agentex-ui. This base PR routes the SDK through a same-origin BFF and adds an account switcher. Chart + deploy side lives in scaleapi/sgp#3961.
/api/agentex) instead of calling the API directly from the browser — the upstream URL and credentials never reach client JS.applyBffCredentialsforwardsx-selected-account-id, drops any client-sentAuthorization, and strips the account-scoped_jwtcookie so SGP honors the selected account rather than the one you linked in with (identity stays via_identityJwt). The proxy also stripsLocationon upstream 3xx so internal redirect targets don't leak.account_idquery param (no cookie), injected on every SDK request via a synchronous ref. Switching accounts resets the open task + selected agent to the account's home grid, andresetQueriesdrops the previous account's cached data so it never briefly renders the old agents./api/user-infofetches the caller's accounts; the picker bootstraps to the first when the param is missing/stale, shows a disabled/empty loading state (not a skeleton), renders single-account as static context, and lives in the sidebar footer (collapsed → icon-only).SGP_API_URL/NEXT_PUBLIC_SGP_APP_URL); no-op otherwise.Env:
NEXT_PUBLIC_AGENTEX_API_BASE_URL→ server-onlyAGENTEX_API_URL.In this PR the BFF runs in default (cookie) mode — no auth dependency. The token-hiding Bearer path arrives in the stacked PR.
Demo
account_picker_demo.mov
Stack
mainTest plan
npm run typecheck/npm run lint— clean_jwtstrip); single / multi / no-account render; loading state; no stale-account flash🤖 Generated with Claude Code