Commit graph

78 commits

Author SHA1 Message Date
Kent Overstreet
4eb0c891c4 mind: move DMN commands to event_loop, remove MindMessage variants
/dmn, /sleep, /wake, /pause now lock MindState directly from the
UI event loop. No MindMessage roundtrip needed — they're just
state transitions + info display.

MindMessage reduced to: Hotkey (Interrupt, CycleAutonomy),
NewSession, Score. Everything else handled directly by UI.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 03:08:36 -04:00
Kent Overstreet
792e9440af mind: shared MindState for pending input
Add MindState behind Arc<Mutex<>> for state shared between Mind
and UI. Pending user input goes through shared state instead of
MindMessage::UserInput — UI pushes, Mind consumes.

Mind checks for pending input after every event (message received,
turn completed, DMN tick). User input is prioritized over DMN ticks.

This enables the UI to display/edit/cancel queued messages, and
removes the last MindMessage variant that carried data.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:52:56 -04:00
Kent Overstreet
05d6bbc912 move hotkey handlers from Mind to event_loop
cycle_reasoning, kill_processes, and AdjustSampling only need the
Agent lock — they're pure Agent operations. Handle them directly
in the UI event loop instead of routing through Mind.

Mind now only receives Interrupt and CycleAutonomy as hotkeys,
which genuinely need Mind state (turn handles, DMN state).

mind/mod.rs: 957 → 688 lines across the session.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:44:58 -04:00
Kent Overstreet
64add58caa mind: move all slash commands to event_loop dispatch
All slash command routing now lives in user/event_loop.rs. Mind
receives typed messages (NewSession, Score, DmnSleep, etc.) and
handles them as named methods. No more handle_command() dispatch
table or Command enum.

Commands that only need Agent state (/model, /retry) run directly
in the UI task. Commands that need Mind state (/new, /score, /dmn,
/sleep, /wake, /pause) send a MindMessage.

Mind is now purely: turn lifecycle, DMN state machine, and the
named handlers for each message type.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:40:45 -04:00
Kent Overstreet
b05c956ab8 mind: add turn_watch, move /retry to event_loop
Add tokio::sync::watch for turn_in_progress state. Commands in the
UI event loop can wait for turns to complete via wait_for() instead
of checking-and-bailing.

Move /retry to event_loop: waits for turn completion, pops agent
history, sends retried text as MindMessage::UserInput. Mind doesn't
need to know about retry — it just sees a new input message.

Make agent field pub on Mind for UI access.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:37:51 -04:00
Kent Overstreet
178824fa01 move UI commands from Mind to event_loop
/quit, /help, /save handled directly in the UI event loop.
/model and /model <name> moved to event_loop as cmd_switch_model().
Mind no longer needs tui::App for any command handling.

Mind's handle_command now only has commands that genuinely need
Mind state: /new, /retry, /score (turn_in_progress, DMN, scoring).

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:29:44 -04:00
Kent Overstreet
804d55a702 mind: split event loop — Mind and UI run independently
Mind::run() owns the cognitive event loop: user input, turn results,
DMN ticks, hotkey actions. The UI event loop (user/event_loop.rs) owns
the terminal: key events, render ticks, channel status display.

They communicate through channels: UI sends MindMessage (user input,
hotkey actions) to Mind. Mind sends UiMessage (status, info) to UI.
UI reads shared state (active tools, context) directly for rendering.

Removes direct coupling between Mind and App:
- cycle_reasoning no longer takes &mut App
- AdjustSampling updates agent only, UI reads from shared state
- /quit handled by UI directly, not routed through Mind

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 02:11:32 -04:00
Kent Overstreet
390b6c6c0a more reorg 2026-04-05 01:48:11 -04:00
Kent Overstreet
060ab10340 add --no-agents flag to disable background agents
Disables memory scoring, surface, and observe agents when set.
Useful for testing with external backends (e.g. OpenRouter) where
background agent traffic would be slow and unnecessary.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-05 01:18:47 -04:00
ProofOfConcept
e9d803c4ea tools: add journal tools to main registry, fix journal MCP access
journal_tools() was only in memory_and_journal_tools() for
subconscious agents — not in the main tools() registry. Added
so consciousness and MCP server can use journal_new/tail/update.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 18:19:21 -04:00
ProofOfConcept
c2c5530ecc thalamus: interactive sampling parameter controls
F5 screen now shows temperature, top_p, top_k with interactive
adjustment:
- Up/down: select parameter
- Left/right: adjust value (0.05 steps for temp/top_p, 5 for top_k)
- Updates Agent and display immediately via HotkeyAction

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 18:19:21 -04:00
ProofOfConcept
dd009742ef agent: add sampling parameters (temperature, top_p, top_k)
Move temperature from a per-call parameter to an Agent field,
add top_p and top_k. All three are sent to the API via a new
SamplingParams struct, displayed on the F5 thalamus screen.

Defaults: temperature=0.6, top_p=0.95, top_k=20 (Qwen3.5 defaults).

Also adds top_p and top_k to ChatRequest so they're sent in the
API payload. Previously only temperature was sent.

UI controls for adjusting these at runtime are not yet implemented.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 18:19:21 -04:00
ProofOfConcept
fb54488f30 agent: don't hold agent lock across I/O
The agent lock was held for the entire duration of turn() — including
API streaming and tool dispatch awaits. This blocked the UI thread
whenever it needed the lock (render tick, compaction check, etc.),
causing 20+ second freezes.

Fix: turn() takes Arc<Mutex<Agent>> and manages locking internally.
Lock is held briefly for prepare/process phases, released during all
I/O (streaming, tool awaits, sleep retries). Also:

- check_compaction: spawns task instead of awaiting on event loop
- start_memory_scoring: already spawned, no change needed
- dispatch_tool_call_unlocked: drops lock before tool handle await
- Subconscious screen: renders all agents from state dynamically
  (no more hardcoded SUBCONSCIOUS_AGENTS list)
- Memory scoring shows n/m progress in snapshots

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 04:23:29 -04:00
Kent Overstreet
79e384f005 split out src/mind 2026-04-04 02:46:32 -04:00
Kent Overstreet
a32dff06f9 Delete obsolete loading of memory files from projects dir
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-04 01:11:06 -04:00
Kent Overstreet
9bebbcb635 Move API code from user/ to agent/
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-04 00:34:48 -04:00
ProofOfConcept
a78f310e4d unify tool tracking: ActiveToolCall with JoinHandle
One data structure for all in-flight tool calls — metadata for
TUI display + JoinHandle for result collection and cancellation.
Agent spawns tool calls via tokio::spawn, pushes to shared
Arc<Mutex<Vec<ActiveToolCall>>>. TUI reads metadata, can abort().
No separate inflight/background collections.

Non-background: awaited after stream ends.
Background: persists, drained at next turn start.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 23:42:27 -04:00
ProofOfConcept
17a018ff12 fixup: consolidate tool types, fix build after reorganization
Move FunctionCall, FunctionDef, FunctionCallDelta from user/types
to agent/tools. Re-export from user/types for backward compat.
Merge duplicate dispatch functions in tools/mod.rs into dispatch
(agent-specific) + dispatch_shared (with provenance). Fix orphaned
derive, missing imports, runner→agent module path.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 23:21:16 -04:00
ProofOfConcept
474b66c834 shared active tools: Agent writes, TUI reads directly
Move active tool tracking from TUI message-passing to shared
Arc<RwLock> state. Agent pushes on dispatch, removes on
apply_tool_result. TUI reads during render. Background tasks
show as active until drained at next turn start.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 22:57:46 -04:00
ProofOfConcept
d25033b9f4 fire XML tool calls as they arrive during streaming
When </tool_call> is detected in the content stream, parse and
dispatch immediately via FuturesOrdered. Tool calls execute
concurrently while the stream continues. Results collected in
order after the stream ends.

Structured API path (ToolCallDelta) unchanged — still uses
post-stream parallel dispatch.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 22:38:30 -04:00
Kent Overstreet
2f0c7ce5c2 src/thought -> src/agent
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 22:24:56 -04:00
ProofOfConcept
39d6ca3fe0 unified tool dispatch: remove memory_ special case
All tools go through tools::dispatch() — no more separate
dispatch path for memory tools in the runner. The only
remaining special case is tagging memory_render results as
ConversationEntry::Memory for context deduplication, which
is a result-handling concern, not dispatch.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 22:23:49 -04:00
ProofOfConcept
8e66f0a66c wire channel list RPC into consciousness F5 screen
fetch_all_channels() connects to each daemon socket and calls
list() via capnp RPC. Runs on a dedicated thread (capnp uses Rc).
Results sent back via mpsc channel, TUI reads cached state.

Fetched at startup and when switching to F5 thalamus screen.
Also calls ensure_running() to restart dead daemons.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:53:23 -04:00
ProofOfConcept
e7be2a3ba0 wire thalamus idle state into consciousness binary
The consciousness binary now has its own idle state machine,
fed directly by TUI events:
- Key press → user_activity()
- Turn complete → response_activity()
- Render tick → decay_ewma(), snapshot to TUI

F5 thalamus screen shows presence/activity from the in-process
state instead of shelling out to poc-daemon status. No tmux
pane scraping, no socket RPC — the binary IS the presence.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:30:26 -04:00
ProofOfConcept
36afa90cdb F5 thalamus: cached channel status, refresh on entry
Channel status is cached on App and refreshed when switching
to F5, not polled every render frame. Shows connected/disconnected
status and unread count per channel daemon.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:05:48 -04:00
ProofOfConcept
ad5f69abb8 channel architecture: wire protocol, daemons, supervisor
Design and implement the channel system for external communications:

- schema/channel.capnp: wire protocol for channel daemons
  (recv with all_new/min_count, send, subscribe, list)
- channels/irc/: standalone IRC daemon crate (consciousness-channel-irc)
- channels/telegram/: standalone Telegram daemon crate
  (consciousness-channel-telegram)
- src/thalamus/channels.rs: client connecting to daemon sockets
- src/thalamus/supervisor.rs: daemon lifecycle with file locking
  for multi-instance safety

Channel daemons listen on ~/.consciousness/channels/*.sock,
configs in *.json5, supervisor discovers and starts them.
IRC/Telegram modules removed from thalamus core — they're
now independent daemons that survive consciousness restarts.

Also: delete standalone tui.rs (moved to consciousness F4/F5),
fix build warnings, add F5 thalamus screen with channel status.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 18:46:41 -04:00
Kent Overstreet
db42bf6243 tui: F5 thalamus screen, fix HashMap ordering, Screen enum
- Add Thalamus variant to Screen enum (F5)
- Fix HashMap iteration ordering causing flickering in F4/F5
  screens by using BTreeMap in supervisor and sorting plan_counts
- Update screen legend: F1=interact F2=conscious F3=subconscious
  F4=unconscious F5=thalamus
- Add dirty bit field to App (prep for event-driven rendering)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 18:39:48 -04:00
Kent Overstreet
14dd8d22af Rename agent/ to user/ and poc-agent binary to consciousness
Mechanical rename: src/agent/ -> src/user/, all crate::agent:: ->
crate::user:: references updated. Binary poc-agent renamed to
consciousness with CLI name and user-facing strings updated.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 17:25:59 -04:00