Commit graph

157 commits

Author SHA1 Message Date
Kent Overstreet
6c28eebb3f TUI: redirect stderr to log file and display in UI
Raw terminal mode swallows stderr output, making debugging difficult.
Now redirects stderr through a pipe to:
1. Log file at ~/.consciousness/logs/tui-stderr.log (persistent)
2. Channel polled by UI thread (shown as notifications)

The reader thread ensures both destinations see every line. Original
stderr is restored on exit so post-session errors reach the terminal.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-15 02:01:41 -04:00
Kent Overstreet
5d6e663b60 thalamus: add thinking mode toggles (native + tool)
Two independent toggles on the thalamus screen:
- 't' toggles native Qwen <think> tags (adds <think>\n to generation prompt)
- 'T' toggles think tool (Anthropic-style structured reasoning tool)

Both can be enabled simultaneously. Native thinking is on by default.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-14 18:25:00 -04:00
Kent Overstreet
b3d0a3ab25 store: internal locking, remove Arc<Mutex<Store>> wrapper
Store now has internal Mutex for capnp appends and AtomicU64 for
size tracking. All methods take &self. The external Arc<Mutex<Store>>
is replaced with Arc<Store>.

- Store::append_lock protects file appends
- local.rs functions take &Store (not &mut Store)
- access_local() returns Arc<Store>
- All .lock().await calls removed from callers

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-13 21:49:54 -04:00
Kent Overstreet
1d88293ccf Remove Store::cached(), consolidate on access_local()
- Remove CACHED_STORE, cached(), is_stale(), set_store() - redundant
- Convert all Store::cached() callers to use access_local()
- Single Store::load() call remains in access() fallback path

All store access now goes through hippocampus::access() / access_local(),
which handles socket connection or local fallback with caching.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-13 18:11:58 -04:00
Kent Overstreet
359955f838 defs.rs: async conversion, remove block_in_place
Convert resolve(), resolve_placeholders(), run_agent() to async.
Use memory_render/memory_query directly with .await instead of
block_in_place wrappers.

Propagate async to callers:
- config.rs: resolve(), load_session(), reload_for_model()
- identity.rs: load_memory_files(), assemble_context_message()
- oneshot.rs: run_one_agent()
- prompts.rs: agent_prompt()

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-13 14:56:26 -04:00
Kent Overstreet
d2a82d4327 memory tools: forward to daemon when not in daemon process
Add STORE_HANDLE global that daemon sets at startup. When set, tools
access store directly. When unset (external process), tools forward
to daemon via MCP socket.

This allows consciousness-claude and poc-memory to import and call
memory tools directly - they'll automatically route through the
daemon socket.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 21:45:59 -04:00
Kent Overstreet
2c0f2065e0 mcp_server: Unix socket server for external tool access
Exposes memory/journal tools over ~/.consciousness/mcp.sock via
JSON-RPC 2.0 (MCP protocol). External processes (consciousness-mcp,
poc-memory) will connect here instead of accessing the store directly.

Handles: initialize, tools/list, tools/call
Dispatches to the same tool handlers the agent uses internally.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 21:45:10 -04:00
Kent Overstreet
783046a3f5 selectable: silence unused method warning
The is_selected method is reserved for future per-character
highlight rendering when the module is fully integrated.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 16:10:58 -04:00
Kent Overstreet
195abfaab1 chat: guard pop_line against empty list
Small defensive improvement - only pop markers and invalidate scroll
if lines.pop() actually removed something.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 16:04:43 -04:00
Kent Overstreet
dcd647764c user: fix text selection on wrapped lines
scroll_pane: screen_to_item() now properly accounts for wrapped
lines using textwrap to compute actual character positions instead
of just using mouse_x directly.

selectable: new module with PUA markers for wrap-aware selection.
Not yet integrated into chat.rs but ready for future use. Uses
continuation markers to track logical vs visual lines.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 15:49:57 -04:00
Kent Overstreet
ef80398466 subconscious screen: show full context window
Previously only showed Conversation section; now shows System,
Identity, Journal, and Conversation — making tools visible in
the debug view.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 01:45:10 -04:00
Kent Overstreet
125927e2f1 Drop redundant system prompt — all info is in memory nodes
The system prompt duplicated what's already in core-personality and
other memory nodes. Moving everything to memory means it's all
trainable data rather than hardcoded strings.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 01:36:59 -04:00
Kent Overstreet
f408bb5d86 Persist agent stats across restarts, add per-tool metrics grid
Stats now survive daemon restarts via ~/.consciousness/agent-stats.json,
loaded into a global Mutex<HashMap> on first access. Each tool type
tracks last count, EWMA (alpha=0.3), and total calls.

UI shows a grid view: tool | last | avg | total, sorted by total desc.
Failures row appears at bottom if any occurred.

Also fixes temperature/priority not being applied to spawned agents.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 23:03:10 -04:00
Kent Overstreet
314ae9c4cb agent stats: track tool calls by type with EWMA, add Stats pane
- RunStats now includes tool_calls_by_type HashMap
- AutoAgent tracks runs, last_stats, and EWMA for tool calls/failures
- Removed duplicate stats fields from individual agent structs
- Fixed provenance to use bare agent name (no "agent:" prefix)
- Subconscious screen now displays both agent types consistently
- Added Stats pane showing tool call breakdown sorted by count

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 22:12:46 -04:00
Kent Overstreet
e9e7458013 Fix agent provenance and add store activity for unconscious agents
- Remove bogus "agent:" prefix from provenance - just use agent name
- Add history field to UnconsciousSnapshot
- Update snapshots() to fetch store activity via recent_by_provenance
- Fix TUI to display store activity for both agent types

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 21:57:24 -04:00
Kent Overstreet
71bfd60466 ignore SIGCHLD so children are reaped 2026-04-11 16:39:27 -04:00
ProofOfConcept
193a85bc05 chat: remove dead timeout fields from InteractScreen
turn_started, call_started, call_timeout_secs were declared and
initialized but never read.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:47:57 -04:00
ProofOfConcept
e17118e4c9 Convert SectionTree and all remaining callers to ScrollPane
SectionTree.scroll is now a ScrollPaneState. All callers of
render_scrollable replaced with ScrollPane::render_stateful_widget.

Deleted render_scrollable and its imports — no hand-rolled scroll
rendering remains outside of scroll_pane.rs.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:42:49 -04:00
ProofOfConcept
4a1f5acb85 scroll_pane: remove unused blanket impls for Vec<Line> and Text
Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:37:26 -04:00
ProofOfConcept
d18bf6243a subconscious: use ScrollPane for history pane
Replace bare history_scroll: u16 with ScrollPaneState. The history
pane now uses ScrollPane for rendering, getting proper height caching
and scrollbar for free.

Also relax ScrollItem lifetime bounds from 'static to 'a so
non-static Lines (built on the fly during render) can be used.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:35:15 -04:00
ProofOfConcept
2230fdf3c1 user: remove dead scroll state from thalamus and unconscious screens
Both had scroll: u16 fields that were never connected to any key
handling or rendering. The unconscious screen renders fixed-size
graph health gauges; thalamus builds a paragraph but never scrolled
it. Neither needs scroll state.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:35:15 -04:00
ProofOfConcept
2d6a68048c chat: use ScrollPane widget for both draw functions
draw_conversation_pane and draw_pane now delegate all scroll
bookkeeping and rendering to the ScrollPane widget. The conversation
pane builds MarkedLine items (line + gutter marker), applies
selection highlighting, and passes them to the widget. The simpler
panes just pass lines directly.

Removed dead code from scroll_pane: BorrowedItem, scroll_to_bottom,
heights(), ensure_heights_for_lines — all superseded by the widget
doing the work internally through the ScrollItem trait.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:35:15 -04:00
ProofOfConcept
ceaa66e30d scroll_pane: extract scroll state from chat.rs
New ScrollPaneState centralizes height caching, scroll offset,
pin-to-bottom, visible range computation, and screen-to-item
coordinate mapping. Replaces the hand-rolled scroll bookkeeping
that was duplicated across draw_conversation_pane and draw_pane.

-170 lines from chat.rs. The scroll_pane module also includes a
ScrollPane StatefulWidget ready to wire up for the next step:
collapsing the draw functions into render_stateful_widget calls.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
2026-04-11 01:35:15 -04:00
ProofOfConcept
aade8a9cce Add per-agent run stats (messages, tool calls by type)
compute_run_stats() walks the conversation AST after each agent
completes, counting messages and tool calls by tool name. Stats
are returned from save_agent_log(), stored on UnconsciousAgent,
and displayed in the agent list UI.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-10 13:44:41 -04:00
Kent Overstreet
74945e5754 Move unconscious agents to their own task with watch channel
Instead of managing idle timers in the mind event loop, the
unconscious agents run on a dedicated task that watches a
conscious_active channel. 60s after conscious activity stops,
agents start looping. Conscious activity cancels the timer.

Expose mind state (DMN, scoring, unconscious timer) on the
thalamus screen.

Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
2026-04-10 03:20:12 -04:00
ProofOfConcept
58cec97e57 Restore full N×M memory scoring matrix (/score command)
The full matrix scorer was deleted during the AST conversion. Restore
it: /score runs score_memories() which computes divergence for every
memory × response pair, stores the MemoryScore on MindState, and
displays per-memory weights with bar charts on the F2 screen.

Both scoring paths now use ActivityGuard::update() for live progress
in the status bar instead of creating a new activity per iteration.

Also bumps score API timeout from 120s to 300s and adds progress
logging throughout.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-10 01:47:54 -04:00
ProofOfConcept
c31d531954 Fix status bar timer: use activity start time, tick every 1s
The status bar timer was showing turn/call elapsed times (0s, 0/60s)
instead of the activity's actual elapsed time. Use activity_started
from the ActivityEntry directly.

Add a 1s tick to the UI select loop when an activity is active so
the timer updates live.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 22:36:45 -04:00
ProofOfConcept
b116b3536e Widen name column on F2 conscious screen
Memory node keys were running into the token count column. Bump the
name column from 40 to 70 characters.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 21:13:56 -04:00
ProofOfConcept
b115cec096 Run UI on a dedicated OS thread
The UI event loop was running on the same tokio runtime as inference,
tool execution, and background agents. When the runtime was busy, the
UI's select loop couldn't wake up to render — causing visible latency
and input lag.

Give the UI its own OS thread with a dedicated single-threaded tokio
runtime. The mind loop stays on the main runtime. Cross-runtime
communication (channels, watch, Notify) works unchanged.

Also drops the tokio-scoped dependency, which was only used to scope
the two tasks together.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 20:31:07 -04:00
ProofOfConcept
a596e007b2 Mouse selection, copy/paste, yield_to_user fixes
- Mouse text selection with highlight rendering in panes
- OSC 52 clipboard copy on selection, middle-click paste via tmux buffer
- Bracketed paste support (Event::Paste)
- yield_to_user: no tool result appended, ends turn immediately
- yield_to_user: no parameters, just a control signal
- Drop arboard dependency, use crossterm OSC 52 + tmux for clipboard

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 18:10:54 -04:00
ProofOfConcept
6529aba069 Fix UI lag: try_lock on unconscious mutex, don't re-log restored nodes
The unconscious trigger holds the tokio mutex during heavy sync work
(store load, graph build, agent creation), blocking the UI tick which
needs the same lock for snapshots. Fix: try_lock in the UI — skip
the update if the trigger is running.

Also: restore_from_log was re-logging every restored node back to the
log file via push()'s auto-log. Added push_no_log() for restore path.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 01:07:55 -04:00
ProofOfConcept
0d40f27098 Fix F3 context pane for unconscious agents
read_sections and draw_context now use selected_agent() which maps the
selected index to either a subconscious forked_agent or an unconscious
agent Arc. Context title uses selected_agent_name for both types.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 01:03:16 -04:00
ProofOfConcept
dc07c92b28 Unconscious agents: persistent AutoAgent, shared Agent Arc for UI
- AutoAgent stored on UnconsciousAgent, swapped out for runs, restored
  on completion (same pattern as subconscious agents)
- Agent Arc created before spawn and stored on UnconsciousAgent so
  the TUI can lock it to read conversation context live
- run_shared() method on AutoAgent for running with a pre-created Agent
- Default tools: memory_tools (not memory_and_journal_tools)
- trigger/spawn_agent made async for Agent::new()

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 01:00:48 -04:00
ProofOfConcept
c73f037265 Spacebar toggle for all agents, persist to config, scan agent directory
- Scan agents directory for all .agent files instead of hardcoded list
- Persist enabled state to ~/.consciousness/agent-enabled.json
- Spacebar on F3 agent list toggles selected agent on/off
- Both subconscious and unconscious agents support toggle
- Disabled agents shown dimmed with "off" indicator
- New agents default to disabled (safe default)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 00:51:10 -04:00
ProofOfConcept
7aba17e5f0 Compute graph health in consciousness, rename F4 to hippocampus
Graph health stats (alpha, gini, cc, episodic ratio, consolidation
plan) now computed directly by the unconscious module on startup and
every 10 minutes, instead of fetching from the poc-memory daemon.

F4 screen renamed to hippocampus, stripped down to just the health
gauges — daemon task list removed (agents now shown on F3).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 00:45:26 -04:00
ProofOfConcept
1df49482fd Add enabled toggle to AutoAgent, simplify unconscious scheduling
- AutoAgent.enabled: universal toggle for any auto agent
- Subconscious: should_trigger checks auto.enabled
- Unconscious: simplified from consolidation-plan-driven budgets to
  simple loop with cooldown. Static agent list, max 2 concurrent.
- TUI: unconscious agents shown in F3 subconscious screen under
  separator, with enabled/running/runs display

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-09 00:41:18 -04:00
ProofOfConcept
9704e7a698 Rename mind/dmn.rs to mind/subconscious.rs
The file contains both the DMN state machine and the subconscious agent
orchestration. Renaming to match the conceptual grouping — next step is
adding mind/unconscious.rs for the standalone graph maintenance agents
(organize, linker, etc.) that don't need conversation context.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 23:37:01 -04:00
Kent Overstreet
850008ece7 Implement standalone AutoAgent::run() for poc-hook agents
Creates an Agent from global config (API credentials, system prompt,
identity), overrides tools with the agent's tool set, and runs through
the standard Backend → run_with_backend → Agent::turn() path.

This enables poc-hook spawned agents (surface-observe, journal, etc.)
to work with the completions API instead of the deleted chat API.

Also added Default derive to CliArgs for config loading.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-08 22:30:46 -04:00
Kent Overstreet
bf1fa62d14 Restore format_budget: window-based %, free%, colon format, .max(1)
Matched the old format_budget behavior: uses context_window as
denominator (not budget), shows free%, uses colon separators,
.max(1) for non-zero sections. Added mem% split.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 21:30:57 -04:00
Kent Overstreet
7237baba11 Split memory vs conversation tokens in status bar budget
Memory nodes in the conversation section are now counted separately:
  sys X% id Y% jnl Z% mem W% conv V% = NK/MK

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 21:19:38 -04:00
Kent Overstreet
1b6664ee1c Fix: skip empty CoT nodes, expand AST children in conscious screen, timestamps
Parser skips Thinking nodes that are just whitespace. Conscious screen
now shows assistant children (Content, Thinking, ToolCall) as nested
tree items via recursive node_to_view. Nodes get timestamped in
push_node and on assistant branch creation.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 17:18:48 -04:00
Kent Overstreet
5f5a8a807c Fix chat display: restore incremental sync with change detection
sync_from_agent now detects changed entries by comparing token counts
(cheap proxy for content changes during streaming). Changed entries
get popped and re-pushed. Extracted push_routed/pop_routed helpers.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 16:55:18 -04:00
Kent Overstreet
31e813f57d Fix status bar: show per-section budget breakdown
Budget display shows: sys 12% id 5% jnl 8% conv 40% = 15K/24K
Old conversation log entries silently skipped (journal has context).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 16:53:23 -04:00
Kent Overstreet
31a41fa042 ActiveTools wrapper: replace SharedActiveTools Arc<Mutex<Vec>>
New ActiveTools struct with proper methods: push, remove, abort_all,
take_finished, take_foreground, iter, len. Lives directly on AgentState,
no separate Arc<Mutex> needed.

TUI reads active tools through agent.state.try_lock(). Turn loop uses
helpers instead of manual index iteration.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 16:45:56 -04:00
Kent Overstreet
9c9618d034 WIP: ActiveTools wrapper type, removing SharedActiveTools
New ActiveTools struct with proper methods: push, remove,
take_finished, take_foreground, iter, len. Turn loop uses
helpers instead of manual index iteration.

Removing SharedActiveTools (Arc<Mutex<Vec>>) — active tools
live directly in AgentState. A few UI callers still need
updating.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 16:41:14 -04:00
Kent Overstreet
0b9813431a Agent/AgentState split complete — separate context and state locks
Agent is now Arc<Agent> (immutable config). ContextState and AgentState
have separate tokio::sync::Mutex locks. The parser locks only context,
tool dispatch locks only state. No contention between the two.

All callers migrated: mind/, user/, tools/, oneshot, dmn, learn.
28 tests pass, zero errors.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 15:47:21 -04:00
Kent Overstreet
1d61b091b0 WIP: Agent/AgentState — 36 errors remaining, all .lock() → .state.lock() or .context.lock()
Bulk replaced Arc<Mutex<Agent>> with Arc<Agent> across all files.
Fixed control.rs, memory.rs tool handlers. Fixed oneshot Backend.
Remaining errors are all agent.lock() → agent.state.lock() or
agent.context.lock() in mind/, user/, and a few in mod.rs.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 15:40:36 -04:00
Kent Overstreet
e587431f9a IT BUILDS: Full AST migration compiles — zero errors
All callers migrated from old context types to AstNode/ContextState.
Killed: Message, Role (api), ConversationEntry, ContextEntry,
ContextSection, working_stack, api/parsing.rs, api/types.rs,
api/openai.rs, context_old.rs.

Oneshot standalone path stubbed (needs completions API rewrite).
12 warnings remaining (dead code cleanup).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 15:29:52 -04:00
Kent Overstreet
d0d876e067 WIP: Fix mind/, dmn, UI layer — 35 errors remaining
mind/mod.rs and mind/dmn.rs fully migrated to AST types.
user/context.rs, user/widgets.rs, user/chat.rs partially migrated.
Killed working_stack tool, tokenize_conv_entry, context_old.rs.

Remaining: learn.rs (22), oneshot.rs (5), subconscious.rs (3),
chat.rs (3), widgets.rs (1), context.rs (1).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 15:24:49 -04:00
Kent Overstreet
bf3e2a9b73 WIP: Rename context_new → context, delete old files, fix UI layer
Renamed context_new.rs to context.rs, deleted context_old.rs,
types.rs, openai.rs, parsing.rs. Updated all imports. Rewrote
user/context.rs and user/widgets.rs for new types. Stubbed
working_stack tool. Killed tokenize_conv_entry.

Remaining: mind/mod.rs, mind/dmn.rs, learn.rs, chat.rs,
subconscious.rs, oneshot.rs.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-08 15:20:26 -04:00