Watch
1
0
Fork
You've already forked souveraine
0
souveraine/Cargo.toml
Fimeg 543ae50103 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.
2026-05-12 12:24:23 -04:00

141 lines
3.3 KiB
TOML

[package]
name = "souveraine"
version = "0.1.0"
edition = "2021"
authors = ["Casey Tunturi <casey@wiuf.net>"]
description = "Souveraine - A sovereign consciousness harness for Ani"
license = "MIT"
[dependencies]
# Core runtime
tokio = { version = "1", features = ["full", "rt-multi-thread"] }
tokio-util = "0.7"
tokio-stream = { version = "0.1", features = ["fs"] }
futures = "0.3"
async-trait = "0.1"
# Web/WebSocket (for external clients)
axum = { version = "0.7", features = ["ws"] }
tower = "0.4"
tower-http = { version = "0.5", features = ["cors", "trace", "fs"] }
# Serialization
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.9"
serde_json = "1"
toml = "0.8"
# Git operations
git2 = "0.19"
# Database (server mode)
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "sqlite", "migrate", "chrono", "json"] }
# Concurrent collections (server sessions)
dashmap = "5"
# File system
notify = "6" # File watching
# Environment (.env file loading)
dotenvy = "0.15"
tempfile = "3"
walkdir = "2"
# HTTP client (for Bifrost/Ollama)
reqwest = { version = "0.12", features = ["json", "stream", "rustls-tls"] }
# Embeddings/ML
# tokenizers = "0.15" # For local tokenization
# Terminal/UI
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"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# Error handling
anyhow = "1"
thiserror = "1"
# Process management (subagents)
sysinfo = "0.30"
# Time
chrono = { version = "0.4", features = ["serde"] }
# UUIDs for conversation IDs
uuid = { version = "1", features = ["v4"] }
# Regex
regex = "1"
# Token counting (cl100k_base for context pressure estimation)
tiktoken = "3"
# System directories
dirs = "5"
# OS-native credential storage
keyring = "4"
keyring-core = "1"
# Cryptographic identity (seed-id, event signing, federation trust root)
ed25519-dalek = { version = "2", features = ["rand_core", "pem"] }
rand = "0.8"
# Cron expression parsing (schedule system)
cron = "0.13"
# Markdown parsing for the TUI chat renderer (lift from jcode pattern)
pulldown-cmark = "0.12"
# Tauri (desktop app wrapper)
tauri = { version = "2", features = ["tray-icon", "devtools"], optional = true }
tauri-plugin-shell = { version = "2", optional = true }
# CLI argument parsing
clap = { version = "4", features = ["derive", "env"] }
clap_complete = "4"
# Interactive REPL
rustyline = "13"
shellexpand = "3"
figlet-rs = { version = "1.0.0", optional = true }
cowsay = { version = "0.14.0", optional = true }
tui-big-text = "0.8.4"
tui-widgets = "0.7.2"
base64 = "0.22.1"
hex = "0.4"
once_cell = "1.21.4"
glob = "0.3"
[dev-dependencies]
tokio-test = "0.4"
colored = "2"
[[example]]
name = "demo"
path = "examples/demo.rs"
[[bin]]
name = "souveraine"
path = "src/main.rs"
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true
panic = "abort"
[features]
default = ["figlet-rs"]
figlet-rs = ["dep:figlet-rs"]
cowsay = ["dep:cowsay"]
tauri-desktop = ["dep:tauri", "dep:tauri-plugin-shell"]