Skip to content

fix(desktop): persist agent avatar edits#1666

Open
andresuribe87 wants to merge 1 commit into
block:mainfrom
andresuribe87:fix/update-agent-avatar
Open

fix(desktop): persist agent avatar edits#1666
andresuribe87 wants to merge 1 commit into
block:mainfrom
andresuribe87:fix/update-agent-avatar

Conversation

@andresuribe87

Copy link
Copy Markdown

Problem

You can't update an existing agent's profile image. Creating an agent sets the image fine, but editing it does nothing — the avatar picker in the edit dialog is even hard-disabled with a comment noting the backend can't persist it.

Root cause

avatarUrl was missing from the entire update path — this was an unimplemented feature presenting as a bug:

  • The avatar picker in AgentInstanceEditDialog was disabled (comment: "UpdateManagedAgentInput has no avatarUrl field, so edits can't be persisted yet").
  • UpdateManagedAgentInput (TS IPC type) had no avatarUrl field — though CreateManagedAgentInput and UpdatePersonaInput both do.
  • The Rust UpdateManagedAgentRequest struct had no avatar_url field.
  • The update_managed_agent handler never wrote record.avatar_url, and only re-published the kind:0 profile when the name changed (re-using the old image even then).

So the create path carried the avatar; the edit path silently dropped it — hence the bug is specific to updating an agent.

Fix

Wire avatarUrl end to end:

  • Add avatarUrl?: string | null to UpdateManagedAgentInput (tri-state).
  • Resolve + send it from the edit dialog — base64 data URIs upload to a hosted URL, emoji SVGs pass through, mirroring the create path via resolveManagedAgentAvatarUrl — and enable the picker. On upload failure the helper falls back to the existing avatar, so a transient failure never clobbers the current image.
  • Add avatar_url: Option<Option<String>> to UpdateManagedAgentRequest (via double_option, matching provider).
  • Assign it to the record and re-publish the agent's kind:0 profile when the avatar changes (previously rename-only).

Tri-state semantics: absent = don't touch · null = clear to the harness default avatar · url = set.

Testing

  • New Rust tests: avatar_url deserialization tri-state (absent / null / value), mirroring the existing provider tests — pass.
  • pnpm typecheck (desktop) — clean.
  • biome check on changed files — clean.
  • Desktop JS unit tests (incl. managedAgentAvatar) — 11/11 pass.
  • cargo fmt --check and cargo clippy — clean for the changed files. (Two pre-existing clippy dead_code warnings in archive/store.rs + an unused import in agent_settings.rs are unrelated to this change.)

Manual verification steps

  1. Edit an existing managed agent, pick/upload a new avatar, Save.
  2. Confirm the avatar updates in the agent list and the change persists across restart.
  3. Clear the avatar → reverts to the harness default.

🤖 Generated with Claude Code

The edit-agent dialog dropped avatar changes silently: `avatarUrl` was
absent from the entire update path (UI submit -> UpdateManagedAgentInput ->
UpdateManagedAgentRequest -> handler), and the avatar picker was hard-disabled
with a comment noting the backend couldn't persist it. Creating an agent set
the image fine, so the bug was specific to updating an existing agent.

Wire `avatarUrl` end to end:
- add `avatarUrl?: string | null` to UpdateManagedAgentInput (tri-state)
- resolve + send it from the edit dialog (base64 data URIs upload to a hosted
  URL, emoji SVGs pass through, mirroring the create path) and enable the picker
- add `avatar_url: Option<Option<String>>` to UpdateManagedAgentRequest
- assign it to the record and re-publish the agent's kind:0 profile when the
  avatar changes (previously only on rename)

Tri-state semantics: absent = don't touch, null = clear to the harness default
avatar, url = set.

Tests: add avatar_url deserialization tri-state tests (mirroring provider).
Verified desktop typecheck, biome, JS unit tests, tauri crate tests, clippy,
and rustfmt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant