feat: complete profile switcher — backend + frontend - #33973
Conversation
e4340ed to
b91e4f8
Compare
|
Branch updated (2026-05-29) Rebased on current Verified working on a live Debian 12 server running v0.15.1: profile switch, PTY reconnect, |
|
Hey @benbarclay and @austinpickett — would love a look when you have a moment. This touches Happy to adjust anything based on your feedback. |
b91e4f8 to
04fcbf4
Compare
There was a problem hiding this comment.
Pull request overview
Adds a dashboard profile switcher: a backend activate endpoint plus a public /api/active-profile, sticky-file consultation when spawning the chat PTY, and frontend wiring (new ProfilePickerDialog, sidebar active/switcher cards, channel-bump key) so the PTY reconnects under the new HERMES_HOME without a page reload.
Changes:
- Backend:
POST /api/profiles/{name}/activate(auth-gated), publicGET /api/active-profile, and sticky-profile resolution in_resolve_chat_argv(). - Frontend: new
ProfilePickerDialog, two sidebar cards (active + switcher) gated ondashboard.chat_by_agent_profile. - Wiring:
channelBumpKeyinApp.tsx→ChatPagechannel memo dep → PTY reconnect.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| hermes_cli/web_server.py | Adds activate endpoint, sticky-file consultation in PTY argv resolver, public active-profile endpoint |
| hermes_cli/dashboard_auth/public_paths.py | Allowlists /api/active-profile for unauthenticated reads |
| web/src/lib/api.ts | Adds api.activateProfile() client wrapper |
| web/src/components/ProfilePickerDialog.tsx | New modal listing profiles and triggering activation |
| web/src/components/ChatSidebar.tsx | Adds active-profile card and gated switcher card opening the dialog |
| web/src/pages/ChatPage.tsx | Threads new props through and includes channelBumpKey in channel memo deps |
| web/src/App.tsx | Reads chat sub-feature flags from config, owns channelBumpKey/bumpChannel |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- /api/active-profile added to PUBLIC_API_PATHS (public_paths.py, both gates)
- POST /api/profiles/{name}/activate endpoint with auth + validation
- Sticky file ~/.hermes/active_profile resolved in _resolve_chat_argv()
- ProfilePickerDialog component with profile list, activation, loading states
- chatByAgentProfile / channelBumpKey feature flags in App.tsx
- ChatSidebar integration with Crown icon and onProfileActivated callback
- ChatPage channelBumpKey mechanism restarts PTY on profile switch
04fcbf4 to
109b85b
Compare
|
@austinpickett Thanks for the Copilot review — all three addressed in the latest push:
|
|
Thanks for the profile-switcher work. An automated hermes-sweeper review found that the requested dashboard behavior is already implemented on current
This superseding implementation shipped in |
What this does
Adds a profile switcher to the dashboard chat sidebar so users can switch agent profiles from the UI -- no config edits, no restart.
POST /api/profiles/{name}/activate(auth), sticky file,GET /api/active-profile(public)ProfilePickerDialogmodal, read-only active card, clickable switcher cardchannelBumpKey-> PTY reconnects under newHERMES_HOMEin-placeScreenshots
Default Profile

Custom Profile

Profile Switcher Overlay

Architecture
Data flow -- profile switch
Files changed
hermes_cli/web_server.py/api/active-profileweb/src/components/ProfilePickerDialog.tsxweb/src/components/ChatSidebar.tsxhandleProfileActivatedweb/src/lib/api.tsapi.activateProfile()viafetchJSONweb/src/App.tsxchannelBumpKey,bumpChannel()web/src/pages/ChatPage.tsxKey details
_require_token(request), only dashboard sessions can switch_resolve_chat_argv()prevents../../etcescapesdashboard.chat_by_agent_profileinconfig.yaml, defaultstruebuildWsAuthParam()(ticket-based in gated mode, token-based in loopback)Testing
Closes
/api/active-profileProfilePickerDialog, sidebar cards, PTY reconnectRelated (open -- not fixed here)
ProfilePickerDialogPR -- 3 bugs found in testing, fixed here.hermespath mismatch, HOME env leak in profile resolutionHERMES_PROFILE-> cross-profile SIGKILLHOMEwith active profile home