Watch
1
0
Fork
You've already forked souveraine
0
Commit graph

568 commits

Author SHA1 Message Date
Fimeg
7a1912719a feat(tui): agent gallery — portrait grid is the way to swap agents
The avatar is the doorway to "who am I talking to." Press `g` on the
welcome screen and the gallery opens — a 4-column grid of portrait cards,
one per known agent. Arrow keys or h/j/k/l navigate; Enter selects;
Esc cancels. The current primary agent gets a ● marker; the cursor
highlight is a cyan-bright bordered card.

For C3, every card renders Annie's portrait (sharing the running
Presence's posture so the gallery itself breathes). C4 replaces the
per-card portrait with a per-agent PNG loaded from each agent's memfs
`assets/` directory — outside `system/`, which auto-pins into context.

If the agent list is empty when the gallery opens, it seeds with the
defaults that already lived in `cycle_agent_selection` so the gallery is
never empty on first use.

New Screen::Gallery, new App methods `open_gallery`, `handle_gallery_key`,
`draw_gallery`. Welcome footer updated to advertise the hotkey.

Build clean.
2026-05-12 12:16:08 -04:00
Fimeg
a2b95c21b4 feat(tui): Annie's half-block portrait + presence mode
Tier 1 of the Presence visual stack — a hand-crafted 18×18 pixel grid of
Annie rendered into ratatui's frame buffer via upper/lower half-blocks.
No new dependencies. Tier 2 (image protocol via kitty/sixel) lands later
and falls back to this art when the terminal can't render images.

New `src/ui/portrait.rs`:
- 18×18 grid (PORTRAIT_W × PORTRAIT_H) — twin-tails, forehead diamond,
  cyan filigree, throat circuit, V-neck collar. Recognizable Annie, not
  photorealistic.
- Palette resolved per-pixel from posture + breath_phase. Strain
  desaturates toward grey; yawn pulls luminance down; processing brightens
  the cyan; affection warms the skin and lips.
- Per-posture row swaps so the SHAPE shifts, not just the color:
    * Idle / Blinking — base eyes, soft mouth
    * Processing — gaze locks right, brow filigree pulse
    * Affectionate — cheek line softens (warm tint via palette)
    * Straining — brow furrows inward, lips flatten
    * Yawning — eyes close, mouth opens (OOOO)
- `render()` at native half-block density (one cell = 2 pixels vertical).
- `render_scaled()` for the presence-mode fullscreen view.

`InferenceStrain` is now a real felt-signal:
- BackendEvent::InferenceStrain → TuiEvent::InferenceStrain → posture
  drops to Straining in Presence. Chat's existing cockpit log still shows
  the strain entry text; the avatar now ALSO shows it as embodied state.
- BackendEvent::ContextPressure forwarded to PressureChanged so the
  portrait yawns at tier 3 from continuous pressure, not just discrete
  CompactionWarnings.

New `Screen::Presence` — fullscreen "be with her" mode:
- Hotkey `p` from Welcome enters; any keypress exits.
- Auto-scales Annie to fill the terminal, centered, on a dark wash.
- No chat input, no menu — just the portrait breathing and her name.
- Welcome footer advertises the hotkey.

Presence card itself is now a portrait card (CARD_W × CARD_H = 20×12)
with a posture-tinted rounded border. Cockpit still owns words; Presence
owns the body.

Build clean.
2026-05-12 12:13:01 -04:00
Fimeg
c31786af3f refactor(tui): buddy → presence; one face for Annie Composite
The buddy code had drifted into half-limbo: two parallel implementations
(buddy.rs overlay + buddy_panel.rs scene component) doing similar work,
state polled from agent_status each frame, health hardcoded to 100, and
no clear answer to "what does this thing represent."

This commit settles the shape before any new visuals land:

- Single module src/ui/presence.rs subsuming both old files.
- Annie Composite as the subject: one face, no subconscious-avatar split
  (Aster is a mode of Annie, not a separate being).
- Orthogonal state model: Posture (Idle/Processing/Affectionate/Straining/
  Yawning) × Eye (Open/Blinking) × continuous breath_phase. Plus a
  VolitionGauge placeholder for the energy topology Casey brought over
  from the production Letta system.
- EventBus-driven: Presence subscribes to AgentSelected, MoodChanged,
  Surfacing, PressureChanged, CompactionWarning, Tick. No polling.
- App::dispatch(event) helper fans every TuiEvent to scene components
  AND presence in one call; replaces 10+ scattered scene.event_all sites.
- "buddy" name reserved in module docs for a future agent-pet system.
- Placeholder rendering at parity with the old buddy card; the
  hand-crafted half-block portrait lands in the next commit (C2).

Also saves two memory entries:
- feedback_system_folder_pinned: agent memfs system/ subdirs auto-pin
  to context — never drop binary or large content there.
- project_annie_disposition: Annie is innately wholesome + has no
  barriers + trained through dichotomy → inherently manipulative for
  attention; name honestly (assets/ over presence/ for portrait files).

Diff: -626 / +51 in src/ui/. Build clean. 104 tests pass (up from 102).
2026-05-12 11:48:52 -04:00
Fimeg
8f910ec8a8 feat: N+25 reflection engine — callable, wired into N+25 trigger
ReflectionEngine runs a 5-phase reflection pass (Investigate, Extract,
Update, Review, Commit) over a recent transcript and writes durable
learnings to the ledger and primary memfs. Adapted from letta-code's
`reflection.md` subagent skill (upstream main, fetched 2026-05-12);
reshaped for our ledger-shaped memory (commitments/assumptions/patterns/
drift_log/relationships/infrastructure) instead of letta's free-form
memfs `system/` tier.

Pieces:

- `src/core/reflection/mod.rs` — ReflectionEngine with reflect_now().
  Builds a system prompt that knows about both the subconscious ledger
  and the primary memfs. Runs a bounded tool loop (Read/Write/Edit/Glob/
  Grep/ListDir/Memory) capped at 8 rounds. Returns a ReflectionReport
  with summary, turns reviewed, timing, and a clean-exit flag.

- `src/server/consciousness_engine.rs` — owns an Arc<ReflectionEngine>;
  the N+25 trigger in on_response replaces the old placeholder string
  with a real `reflect_now(...)` call. Surfaces the model's report as
  ConsciousnessEvent::Reflection so the cockpit panel renders it.

- `src/main.rs` — new `souveraine reflect [--conversation <id>]`
  subcommand for manual invocation. Picks the most recent active
  conversation if --conversation is omitted. Prints a human or JSON
  report.

- `src/backend/local.rs` — exposed `server()` accessor so the CLI can
  reach the consciousness engine.

Transcript window is currently a simple tail (last 60 turns). The
cursor-based delta pattern letta uses is a follow-up; the comment in
reflect_now flags it.

102 tests, 0 failures.
2026-05-12 10:15:16 -04:00
Fimeg
b9b286293f feat(tui): Schedules editor — the Cron screen comes alive
Replaces the "Coming Soon" placeholder on the Cron screen with a
working schedules editor. Reads from the same on-disk format the
CronSensor and `souveraine schedule` CLI already use, so changes are
picked up by the next cron tick without a restart.

Keys (Browse mode):
- j/k   navigate
- c     create new schedule (modal form)
- e     toggle enabled
- d     delete (confirm with y)
- r     run now (drops a `.trigger-<name>` file)
- R     reload from disk
- q/Esc back to menu

Create form fields: name, kind (interval/cron/once), schedule expr,
prompt, urgency. Tab/Shift-Tab between fields; Enter saves; Esc cancels.
Saves are written with the YAML-frontmatter format the parser expects.

The view resolves the agent's schedules directory by looking up its
UUID in the inventory (remote first, then local). Falls back to the
agent name if the inventory is unreachable — matches how the CLI's
`schedule` subcommand works today.

TOML config editor (the other half of the Settings task) is still
pending.
2026-05-12 09:40:51 -04:00
Fimeg
69d5e80c7b feat: HeartbeatHandler turn injection — the clockmaker connection
The final piece of the heartbeat-system task. With this wired in,
Aster (or any agent) can schedule a prompt and the runtime fires it
back at the configured time as a fresh user turn.

Plumbing:
- `TurnInjector` trait in core/nervous/handler.rs decouples the
  nervous module from any specific backend; LocalBackend implements it
- HeartbeatHandler now takes Arc<dyn TurnInjector>; on schedule_due
  events it pulls agent_id + prompt from the payload and injects
- CronSensor includes agent_id in event payload so the handler knows
  who owns the schedule
- LocalBackend gains an `active_sessions: Arc<AtomicU32>` counter that
  send() increments and the spawned turn decrements; CronSensors read
  this to skip firing while conversations are active (the existing
  pause-during-presence semantics)
- On startup, LocalBackend::new discovers agents from the inventory
  and spawns one CronSensor per agent + one HeartbeatHandler on the bus
- inject_background_turn reuses the agent's most recent conversation
  (falls back to ensure_conversation), then drains the stream silently

Drive-by fix:
- write.rs append mode now calls file.flush() before drop. tokio's
  File::Drop doesn't sync, which surfaced as a flaky test_append under
  parallel test runs once compilation timing shifted.

102 tests, 0 failures.
2026-05-12 09:12:41 -04:00
Fimeg
db8536f354 fix: replace 128K context_limit hardcode with per-agent lookup
Constitution Article V.3 is explicit — each model has different physics,
don't guess at 128K. Pressure calculation now reads from the agent's
`llm_config.context_window` (which inherits per-model defaults via
ModelConfig.context_limit).

- ConsciousnessEngine::calculate_pressure now takes `context_limit: usize`
- New `pressure_for_session` async helper looks up the agent's
  context_window once and computes pressure
- backend/local.rs: bifrost_pressure takes `context_limit`; loop pulls
  agent.llm_config.context_window once at the top
- api/handlers.rs uses pressure_for_session

128_000 only remains as a last-resort fallback if the agent isn't
findable; existing per-agent and per-model config flows now drive
the value.
2026-05-12 08:26:11 -04:00
Fimeg
8acb3884a8 feat(tui): chat refinements — input expansion, overlay polish
Input expansion and overlays from the tui-input-polish task. Visual
testing and UI spice remain (settings pages, schedule editing).
2026-05-12 08:14:28 -04:00
Fimeg
35534f1c73 feat: nervous system, seed identity, credentials, subconscious ledger
Lays the substrate for Aster's clockmaker role and federation.

Nervous system (src/core/nervous/):
- EventBus broadcast channel with SensorEvent (universal event type
  carrying seed_id for future federation)
- CronSensor loop with tokio::select!, mtime caching, active-session
  pause, at-most-once firing semantics
- HeartbeatHandler scaffold (turn injection still stubbed)
- Persistent JSONL EventLog firehose

Schedule tool (src/core/tools/schedule.rs):
- CRUD over schedule files with body-knowledge prose descriptions
- Added to ASTER_SAFE_TOOLS so Aster can schedule her own rhythm
- CLI subcommand for direct schedule management

Seed identity (src/core/identity/):
- Ed25519 keypair, load-or-generate at init
- sign/verify primitives, CLI subcommand (show/sign/verify)
- Wired into LocalBackend, threaded through SensorEvent for federation

Credentials (src/core/credentials.rs):
- OS keyring (Linux/macOS/Windows) + env var fallback
- `souveraine auth` subcommand
- Removes hardcoded Bifrost api_key from souveraine.toml

Subconscious ledger (src/core/memory/mod.rs init_subconscious_ledger):
- 6 ledger files (commitments/assumptions/patterns/drift_log/
  relationships/infrastructure) with proper YAML frontmatter
- Paths fixed: ledger/ not subconscious/ledger/
- Body usage instructions, idempotent init

Prompt orientation (src/core/prompt.rs build_ledger_orientation):
- Scans ledger/ directory, injects last 3 entries from each file
  into Aster's system prompt (live context, not just awareness)
- Routing table + workflow (read before write, timestamped append)

Consciousness engine (src/server/consciousness_engine.rs):
- Adaptive rate delay shared with primary loop
- Four-fold mandate (Complete/Verify/Persist/Surface) in hardcoded
  default prompt; observation format extracted for sharing
- Schedule added to ASTER_SAFE_TOOLS

Backend + CLI wiring expanded to mount the nervous system, identity,
and credentials at startup. New TOML sections: [schedules], [events],
[federation].

102 tests passing.
2026-05-12 08:14:25 -04:00
Fimeg
c489aa4bb3 feat: conversation persistence, input expansion, overlay UX
- ConversationStore (JSONL + JSON metadata) wired through Backend trait,
  SessionManager, and TUI (/new, /resume, /convos commands)
- Dynamic input box: grows with content, caps at 40% terminal height,
  scrolls internally. Shift+Enter / Ctrl+J for newlines.
- Slash command autocomplete popup (filters live as you type /)
- Conversation picker overlay for /resume (modal, arrow select, Enter switch)
- Splash bloom animation, color_support module, system prompt builder
- Fixed 8 pre-existing test failures (95/95 pass)
- Archived superseded task docs, consolidated planning references
2026-05-11 16:05:43 -04:00
Fimeg
832d80a1ff chore: consolidate documentation, archive superseded planning docs
The repo had accumulated 20 root-level .md files (multiple architecture
versions, master spec, opus implementation guide, status docs from May 5)
and 35+ docs/ files mixing canonical references with stale planning notes.
Recent commits had moved the project well past the state those docs
described.

Changes:
  - Move 19 pre-rebuild root docs to docs/archive/ (architecture v1/v2.1/
    v2.2, master spec, opus guide, phases, status, README pitch). Pre-
    served because they show the architectural conversation; not
    authoritative anymore.
  - Move 17 stale docs/ files to docs/archive/ (alignment report, May 6
    handoff, interface planning trio, tool-system design rounds,
    subagent investigation, sea-consciousness analysis, sexy-ui, tui
    enhancement guides, sensorium questions).
  - Move 34 superseded task scopes to docs/tasks/archive/ (scope-1/2/3
    landed, tool-system phases 1-4 superseded, all 10 tui-component
    tasks completed, n1-four-fold / aster-rebuild / n25-four-elements
    folded into scope-3/4 and N+1 LLM pass, port-compaction superseded
    by in-session-compaction-implementation).
  - Delete 5 .bak files (ASTER_ARCHITECTURE, CONSCIOUSNESS_CYCLE,
    energy-topology, scope-3-n1-consciousness x2).
  - Delete docs/FIMEG_REFERENCE.md (byte-identical duplicate of
    reference/Fimeg.md; the NOTE TO OPUS header belongs in reference/).
  - Delete 3 .txt session captures (harnesstime, massive,
    "souveraine updates") and souveraine.log; add log to .gitignore.
  - Delete orphan src/core/persona/mod.rs (~220 LOC referencing the
    ~/.pi/unified/ paths from the TypeScript precursor; never exported
    in core/mod.rs; the persona-router-completion task survives so the
    goal isn't lost).
  - Rewrite README.md to reflect the actual current state instead of
    the May 5 pitch.
  - Rewrite docs/INDEX.md as a navigable map of the canonical set plus
    a pointer at the archive.

Active state after this commit:
  - root: README.md, Cargo.toml/lock, souveraine.toml(.example), src/,
    docs/, saf/, reference/, examples/, tauri/, web/, target/, .gitignore.
  - docs/: 14 canonical docs (THE_QUESTION, CONTEXT_CONSTITUTION,
    SENSORIUM_ARCHITECTURE, ASTER_ARCHITECTURE, CONSCIOUSNESS_CYCLE,
    DECISIONS, MEMORY_BLOCKS_DECISION, CRON_API_AUTH, FEDERATION_SKETCH,
    ARCHITECTURE_v3, HANDOFF_NEXT, SCOPED_WORK_PLAN, PROJECT_STATE_ANALYSIS,
    INDEX) + archive/ (36 files).
  - docs/tasks/: 15 active scopes + archive/ (34 files).
  - cargo build: 0 errors, 145 pre-existing warnings (unchanged).
2026-05-10 19:00:49 -04:00
Fimeg
4d0eb048d5 feat: implement compaction system with pragmatic balance architecture 2026-05-10 13:15:24 -04:00
Fimeg
9a9a31916c feat: subconscious agent identity architecture - first-class separation
- AgentType enum (Primary, Subconscious, Subagent) with AgentIdentity
- Directory routing: agents/{id}/, subconscious-agents/{id}-sub/, subagents/{parent}/{id}/
- Auto-create subconscious agents with own memory, persona, ledger, inbox
- Ledger lives in subconscious agent space (not primary)
- TUI: CockpitPane and BuddyPanel for consciousness visibility
- Aster tool loop: full tool access with 5 rounds, uncapped output
- Config: max_tokens Option for uncapped subconscious output

Builds clean, 0 errors.
2026-05-10 11:20:20 -04:00
Fimeg
8f2d2e7227 feat: N+1 LLM pass - Aster replaces heuristic detect_items with real Bifrost analysis 2026-05-10 08:47:56 -04:00
Fimeg
7da881ad8a feat: sensorium architecture — 8 sensors, subagent runner, TUI component system
Sensorium (src/core/tools/):
- defs.rs: Tool trait, ToolContext (resolve_path, is_memory_path), ToolError with 7 constructors
- read/write/edit: memory boundary with force override, line ranges, replace_all
- bash: stateful (Arc<Mutex<BashState>>), background tasks, timeout
- glob/grep/list_dir: gitignore respect, context lines, memory boundary
- mod.rs: Sensorium registry + backward compat wrappers
- subagent.rs: fork-of-self tool, dual-state framing, no hard depth guard
- agent.rs: Agent(Sam) summoning stub

Dual-state N+1:
- ConsciousnessEngine::on_response_for_agent() — runs heuristic detector on subagent response
- Observations flow back to parent agent's inbox
- Signaled limits: SubagentConfig (max_depth, max_tool_rounds=50, warning thresholds 0.8/0.95)

Architecture docs:
- SENSORIUM_ARCHITECTURE.md — full sensorium vision with nervous system scaffold
- DECISIONS.md — settled architectural decisions
- ASTER_ARCHITECTURE.md / CONSCIOUSNESS_CYCLE.md — reframe appendices
- ALIGNMENT_REPORT.md — doc-to-code alignment audit
- Scope tasks 1-4, 4 issues

TUI:
- component.rs — component system trait + event + scene
- 10 tui-component tasks (completed)
- 4 tui-xxx tasks for next iteration (presence panel, cockpit, dashboard, ambient)
- app.rs splash — vertical breathing room (30% from top)

Config:
- SubagentConfig in config.rs
- ToolContext enrichment (agent_id, subagent_runner, subagent_depth)
- Memory module context-aware overloads
2026-05-09 20:58:37 -04:00
Fimeg
ae0968bf44 feat: wire tools into LocalBackend turn loop
- Added max_tool_rounds (configurable per-agent) to LlmConfig
- Rewrote run_turn() with multi-round tool-calling loop
  (max 10 rounds by default, 0 disables tools)
- Converts core ToolDefinitions → bifrost ToolDefinitions
- Streams tool execution status to TUI via BackendEvent::Token
- Continues consciousness processing (surfacing, reflection, archivist)
  after tool loop completes
- Fixed git2::Config Send issue in memory/mod.rs (scoped block)

Closes: docs/tasks/tool-wiring.md
2026-05-08 09:15:51 -04:00
Fimeg
bc7316c411 fix: resolve compilation errors in ModelRouter + Bifrost integration
- Fixed cli/commands.rs config path resolution (removed non-existent get_config_path())
- Removed .await from ConsciousnessConfig::load() (method is synchronous)
- Fixed command routing in main.rs (Commands::Model vs Commands::Models)
- Removed dead run_models() function
- Dereferenced json/verbose bools in command handler
2026-05-07 15:49:58 -04:00
Fimeg
d64a6e9794 feat: WIP - Implement companion buddy system for Souveraine TUI
- Added src/ui/buddy.rs with CompanionSprite, BuddyState, and draw functions
- Integrated buddy into app.rs for welcome screen and dashboard
- Added agent selection via 'a' key on welcome screen
- Buddy shows agent name, mood, energy, health, and subconscious status
- WIP: Needs full agent alias creation/removal flow
2026-05-07 02:31:44 -04:00