Skip to content

feat: profile asset store (profiles.set_asset/get_asset) for avatars - #85530

Merged
teknium1 merged 1 commit into
mainfrom
feat/profile-assets
Aug 13, 2026
Merged

feat: profile asset store (profiles.set_asset/get_asset) for avatars#85530
teknium1 merged 1 commit into
mainfrom
feat/profile-assets

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

What

Completes the server-side roster story from #85440: ui_meta syncs compact metadata (shape/color/title/pet selection) but is 64KB-capped because it rides every profiles.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 under assets/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: true deletes. Asset namespace currently just avatar; the param shape leaves room for more.
  • profiles.get_asset — returns the asset as a data URL (found: false soft result when absent, so UIs can probe cheaply).
  • profiles.list rows gain a cheap has_avatar boolean (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.listhas_avatar: true; GIF payload rejected (magic-byte check); 2.1MB payload rejected (cap); clear → removed, found: false, has_avatar back to false.

Consumer: Hermes-Bot-Mode uploads/generates avatars → set_asset; rosters on any client machine fetch via get_asset.

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.
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 458bb65 — feat: profile asset store (profiles.set_asset/get_asset) for

⚠️ Warnings

OSV vulnerability scan · View job

5 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 7m41s vs 7m2s (+9.2%). 10 job(s) slower, 11 faster, 3 unchanged.

  • Python tests / Run tests slice 3/12: +41.0s
  • Python tests / Run tests slice 6/12: -35.0s
  • Python tests / Run tests slice 12/12: -21.0s
  • Python tests / Run tests slice 10/12: +16.0s
  • Python tests / Run tests slice 9/12: +13.0s

@alt-glitch alt-glitch added type/feature New feature or request P4 Best-effort: we will get to it when we get to it (no commitment) comp/tui Terminal UI (ui-tui/ + tui_gateway/) area/profiles Multi-profile isolation, HERMES_HOME scoping labels Aug 13, 2026
@teknium1
teknium1 merged commit 7afac12 into main Aug 13, 2026
49 checks passed
@teknium1
teknium1 deleted the feat/profile-assets branch August 13, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping comp/tui Terminal UI (ui-tui/ + tui_gateway/) P4 Best-effort: we will get to it when we get to it (no commitment) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants