fix(ui): scope avatar storage per agent ID#91533
Conversation
|
Thanks for the context here. I did a careful shell check against current Current main already fixes the linked assistant-avatar overwrite bug via the merged canonical PR, and this open branch now carries an alternate older localStorage layout rather than unique remaining work. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. So I’m closing this as already implemented rather than keeping a duplicate issue open. Review detailsBest possible solution: Keep the merged current-main per-agent avatar map from #93712 and close this alternate branch instead of merging a second localStorage scheme. Do we have a high-confidence way to reproduce the issue? Yes for the original bug on the PR base and latest shipped release: the old storage shape used one unscoped assistant-avatar key. No current-main failure remains because the merged fix now stores and reads overrides by agent ID. Is this the best way to solve the issue? No for this branch now. The best fix has already landed in #93712 with broader render/controller/test coverage and a cleaner one-key per-agent map migration. Security review: Security review cleared: No concrete security or supply-chain concern was found; the obsolete diff is limited to Control UI localStorage handling and adjacent Vitest tests. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against ec3f76b3806a; fix evidence: commit 4aba273939e8, main fix timestamp 2026-06-16T18:53:35Z. |
ff6e8f9 to
865c48b
Compare
865c48b to
2207c0a
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
@clawsweeper re-review |
5da32e7 to
67b92ee
Compare
af9cded to
2dd5cc3
Compare
The avatar storage used a single global localStorage key, causing setting an avatar for one agent to overwrite it for all agents. Scope the localStorage key per agent ID with backward compatibility: existing global avatars are used as fallback when no agent-specific avatar exists. Fixes openclaw#90890 Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Regression test for openclaw#90890: verifies that avatar storage is scoped per agent ID so setting an avatar for one agent does not overwrite another agent's avatar, and that the global key is used as fallback when no agent-specific avatar exists. Co-Authored-By: Claude Opus 4.8 <[email protected]>
When clearing a scoped agent avatar, store null explicitly in the scoped key instead of removing it. This prevents loadLocalAssistantIdentity from falling back to the legacy global key after a user explicitly clears an agent's avatar. Also adds regression coverage for the legacy global key upgrade scenario: seeded legacy global → scoped set → scoped clear → other agent still sees legacy global. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Adds proof-avatar-per-agent.proof.test.ts that exercises the real loadLocalAssistantIdentity and saveLocalAssistantIdentity functions from storage.ts against an in-memory localStorage mock. Covers 6 scenarios: per-agent scoping, clear isolation, global fallback, scoped clear blocks legacy fallback, explicit null storage, and localStorage key naming convention. All 12 tests pass (6 regression + 6 proof). Co-Authored-By: Claude <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Fixes oxlint error: Replace single-line if body with braced block. Co-Authored-By: Claude Opus 4.8 <[email protected]>
2dd5cc3 to
70a0b54
Compare
|
ClawSweeper applied the proposed close for this PR.
|
Summary
openclaw.control.assistant.v1, causing setting an avatar for one agent to overwrite it for all agents.main,worker) cannot set different avatars for each agent. Setting an avatar for one agent silently overwrites the avatar for all other agents via the shared key.openclaw.control.assistant.v1:{agentId}. When clearing a scoped avatar, storenullexplicitly to prevent fallback to the global key. Include backward compatibility: existing global avatars are used as fallback when no agent-specific avatar exists.localAssistantIdentityKey()function correctly scopes keys, whether the explicit null prevents legacy fallback, and whether the global fallback is preserved for new agents.Linked context
Closes #90890
Real behavior proof
fix/90890-avatar-per-agent.npx vitest run ui/src/ui/controllers/assistant-identity.test.ts ui/src/ui/controllers/proof-avatar-per-agent.proof.test.ts --config test/vitest/vitest.ui.config.ts --reporter verbose. The proof test (proof-avatar-per-agent.proof.test.ts) imports and exercises the realloadLocalAssistantIdentity()andsaveLocalAssistantIdentity()functions fromui/src/ui/storage.tsagainst an in-memory localStorage mock viavi.stubGlobal("localStorage", createStorageMock()). The regression test (assistant-identity.test.ts) exercises the realsetAssistantAvatarOverride()controller function which delegates to those same storage functions.mainandworkerhave independent avatars. Clearing one agent does not affect others. New agents without scoped keys fall back to the global key. Scoped clears store explicit{\"avatar\":null}to prevent legacy fallback. ThesetAssistantAvatarOverridecontroller correctly passesstate.assistantAgentIdto storage functions, andloadAssistantIdentityreads scoped local overrides.Tests and validation
ui/src/ui/controllers/assistant-identity.test.ts-- 6/6 passedui/src/ui/controllers/proof-avatar-per-agent.proof.test.ts-- 6/6 passedRisk checklist