feat: profile asset store (profiles.set_asset/get_asset) for avatars - #85530
Merged
Conversation
ui_meta (#85440) syncs compact roster metadata but is 64KB-capped because it rides every profiles.list — image avatars stayed per-client. set_asset writes a validated image (data URL or base64; PNG/JPEG/WebP by magic bytes, 2MB cap, atomic write) to assets/avatar.<ext> in the profile dir; get_asset returns it as a data URL on demand; profiles.list gains a cheap has_avatar flag so rosters know to fetch without probing. Server-side, so every client machine paints the same profile picture.
Contributor
૮ >ﻌ< ა ci reviewran on 458bb65 — feat: profile asset store (profiles.set_asset/get_asset) for
|
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.
What
Completes the server-side roster story from #85440:
ui_metasyncs compact metadata (shape/color/title/pet selection) but is 64KB-capped because it rides everyprofiles.list— so uploaded/generated avatar images stayed per-client. Requested for Hermes-Bot-Mode: profile pictures should follow the profile, not the machine.profiles.set_asset— stores a validated image underassets/avatar.<ext>in the profile dir. Accepts data URL or raw base64; format decided by magic bytes (PNG/JPEG/WebP only), 2MB decoded cap, atomic tmp+replace write, one canonical file per asset (other extensions cleared).clear: truedeletes. Asset namespace currently justavatar; the param shape leaves room for more.profiles.get_asset— returns the asset as a data URL (found: falsesoft result when absent, so UIs can probe cheaply).profiles.listrows gain a cheaphas_avatarboolean (three stat calls) so a roster knows which profiles to fetch — image bytes never ride the list call.Both pool-dispatched. No new config, no new files outside the profile dir.
Verification
Against the real registry on a live named profile: set (PNG data URL) →
{ok, size: 70}; get → byte-identical data URL round-trip, correct mime;profiles.list→has_avatar: true; GIF payload rejected (magic-byte check); 2.1MB payload rejected (cap); clear → removed,found: false,has_avatarback to false.Consumer: Hermes-Bot-Mode uploads/generates avatars → set_asset; rosters on any client machine fetch via get_asset.