fix(ui): scope local assistant avatar override to agent ID (fixes #90890)#90932
fix(ui): scope local assistant avatar override to agent ID (fixes #90890)#90932xydigit-sj wants to merge 4 commits into
Conversation
…s (backend-delegated)
Local assistant avatar overrides were stored under a single global localStorage key, so setting an avatar for one agent changed it for all agents. - Make loadLocalAssistantIdentity / saveLocalAssistantIdentity accept an optional agentId and scope the storage key to the agent. - Thread state.assistantAgentId through all callers: app-render, assistant-identity controller, control-ui-bootstrap. - Preserve backward compatibility: when no agentId is provided the functions still use the legacy global key. Fixes openclaw#90890
|
Codex review: needs real behavior proof before merge. Reviewed June 15, 2026, 9:45 AM ET / 13:45 UTC. Summary PR surface: Source +15, Tests +83. Total +98 across 6 files. Reproducibility: yes. source inspection gives a high-confidence reproduction path. Current main and v2026.6.6 read and write every local assistant avatar override through one unscoped localStorage key, matching the linked multi-agent overwrite report. Review metrics: 2 noteworthy metrics.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land one canonical per-agent assistant-avatar storage fix that preserves legacy flat values on upgrade while blocking fallback after intentional scoped clears, with live Control UI proof for upload, switch, clear, and reload/bootstrap. Do we have a high-confidence way to reproduce the issue? Yes, source inspection gives a high-confidence reproduction path. Current main and v2026.6.6 read and write every local assistant avatar override through one unscoped localStorage key, matching the linked multi-agent overwrite report. Is this the best way to solve the issue? No, not as currently patched. Agent-scoped storage is the right layer, but this branch needs explicit scoped-clear semantics, live browser proof, and canonical-branch selection before it is the best merge path. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 66079161d72a. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +15, Tests +83. Total +98 across 6 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
… messages (backend-delegated)" This reverts commit 151b6f4.
|
Thanks @xydigit-sj for the focused fix work here. I am closing this PR as superseded by #91533 because both PRs track the same root cause from #90890: assistant avatar overrides were stored under one global localStorage key, so changing one agent's avatar affected other agents. #91533 is the canonical path now: #91533. This source PR remains part of the audit trail at #90932, and the contribution context will stay visible for attribution as maintainers finish validation there. If this branch has a different reproduction path or still shows a gap after #91533 lands, please reply and we can reopen or split it back out. |
Summary
Local assistant avatar overrides were stored under a single global
localStoragekey (openclaw.control.assistant.v1), so setting an avatar for one agent changed it for all agents. This PR scopes the override to the current agent ID and preserves legacy flat-key overrides created before this change.Changes
ui/src/ui/storage.tsloadLocalAssistantIdentity/saveLocalAssistantIdentitynow accept an optionalagentIdparameter. When provided, the storage key becomesopenclaw.control.assistant.v1:<agentId>.loadLocalAssistantIdentityfalls back to the legacy global key when no agent-scoped value exists, so existing avatar overrides are not silently lost after upgrade.ui/src/ui/controllers/assistant-identity.ts: Threadsstate.assistantAgentIdthroughloadAssistantIdentityandsetAssistantAvatarOverride.ui/src/ui/app-render.ts: Passesstate.assistantAgentIdwhen loading / saving the local avatar override.ui/src/ui/controllers/control-ui-bootstrap.ts: Applies the agent-scoped local override during bootstrap.ui/src/ui/controllers/assistant-identity.test.ts: Adds a regression test for the legacy flat-key fallback.Backward compatibility
When no
agentIdis provided, the functions still fall back to the legacy global key, preserving existing behavior for unscoped callers. When anagentIdis provided and no scoped override exists, the legacy global key is read so previously set avatars remain visible.Verification
pnpm test ui/src/ui/controllers/assistant-identity.test.ts --run— 7/7 pass.pnpm test ui/src/ui/app-render.assistant-avatar.test.ts --run— 16/16 pass.pnpm test ui/src/ui/views/config-quick.test.ts --run— 14/14 pass.pnpm test ui/src/ui/storage.node.test.ts --run— 20/20 pass.pnpm test ui/src/ui/controllers/control-ui-bootstrap.test.ts --run— 10/10 pass.Fixes #90890
Real behavior proof
Behavior addressed: Setting a local assistant avatar override for one agent overwrote the avatar for every agent because the override was stored under a single global
localStoragekey. Additionally, legacy overrides saved before per-agent scoping must not disappear after this change.Real environment tested: Local Linux checkout of this branch, Node v22.22.0, pnpm 11.2.2, jsdom (Control UI test environment).
Exact steps or command run after this patch:
The test suite exercises per-agent scoping, clearing overrides, and the legacy flat-key fallback using a real in-memory
localStorageimplementation.Evidence after fix:
Observed result after fix: Each agent gets its own
localStoragekey (openclaw.control.assistant.v1:<agentId>), changing the avatar for one agent leaves others unchanged, and a pre-existing legacy flat-key override is still honored when no scoped override exists.What was not tested: A live browser screenshot of the Control UI avatar settings panel; the scoping and fallback behavior is exercised directly against the real storage functions.