Watch
1
0
Fork
You've already forked souveraine
0

feat(tui): per-agent portrait loading from agent memfs assets/

Tier 2 of the Presence visual stack lands as PNG/JPEG → palette grid:
the same half-block renderer keeps working, but the source pixels now
come from a per-agent portrait file when one is present. Blink, yawn,
strain, processing, and affection overlays still paint from the
hand-crafted Annie palette (rows 6, 7, 10, 11) so the seven animation
states keep working regardless of which portrait is loaded underneath.

How it loads:
- `<memfs_root>/assets/portrait.png` (preferred)
- `<memfs_root>/assets/portrait.jpg`
- `<memfs_root>/assets/portrait.jpeg`

`assets/` is deliberately outside `system/`, which is the auto-pinned
context territory built by `src/core/prompt.rs`. Portrait bytes never
land in the agent's context window.

If no portrait exists, Presence falls back to the hand-crafted Annie
palette grid silently — no error, no warning. Same renderer, same
behavior; the visual identity just stays at Tier 1.

What's new:
- `image = "0.25"` (default-features off; only `png` and `jpeg` features).
- `portrait::PortraitSource` — pixel grid loaded from `from_path`. Uses
  `image::open` + `resize_exact(Lanczos3)` to downsample to the existing
  PORTRAIT_W × PORTRAIT_H grid.
- `portrait::pixel_color` — single resolution path: source-when-loaded
  for non-overlay pixels, hand-crafted palette for overlay rows.
- `Presence::load_portrait_from_memfs(root)` — looks for the three
  candidate filenames; silently no-ops when absent.
- App refreshes the portrait when the dashboard refresh walks the
  agent's memory repo (`local_repo.root()`).

Note on architecture: this is "Tier 2" via downsampled palette rather
than via terminal image protocols (kitty/sixel). It works in EVERY
terminal, costs no dependency on capability detection, and stays
consistent with the half-block aesthetic the rest of the TUI uses.
True image-protocol rendering can land later as a separate enhancement;
the data flow (per-agent PNG in agent memfs assets/) is already correct
for that future path.

Build clean.
This commit is contained in:
Fimeg 2026-05-12 12:24:23 -04:00
commit 543ae50103
4 changed files with 103 additions and 8 deletions

View file

@ -53,6 +53,7 @@ crossterm = "0.27" # Terminal control
ratatui = { version = "0.26", features = ["crossterm"] } # TUI framework with crossterm backend
unicode-width = "0.1"
colored = "2" # Color gradients and effects
image = { version = "0.25", default-features = false, features = ["png", "jpeg"] } # Per-agent portraits (assets/portrait.{png,jpg})
# Logging/tracing
tracing = "0.1"