Commit graph

781 commits

Author SHA1 Message Date
Kent Overstreet
79e384f005 split out src/mind 2026-04-04 02:46:32 -04:00
ProofOfConcept
ce04568454 training: add memory_score() and finetune_score()
Separate the scoring into two distinct functions:

- memory_score(key): scores one memory's importance by measuring
  divergence in the 50 messages after it was surfaced. Two API calls
  (baseline vs without that memory).

- finetune_score(count): scores recent messages with all memories
  stripped to identify fine-tuning candidates. Responses with high
  divergence depend on memories the model hasn't internalized yet.

The existing score_memories() with the full NxM matrix is preserved
for the debug screen.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 01:49:53 -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
743b35eb20 Kill dead agent_config_dir 2026-04-04 00:58:09 -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
021eafe6da delete ProcessTracker — replaced by ActiveToolCall + KillOnDrop
All process management now goes through active_tools:
- TUI reads metadata (name, elapsed time)
- Ctrl+K aborts handles (KillOnDrop sends SIGTERM)
- Running count from active_tools.len()

No more separate PID tracking, register/unregister, or
ProcessInfo. One data structure for everything.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 23:58:38 -04:00
ProofOfConcept
310bbe9fce KillOnDrop: SIGTERM process group when tool task is aborted
tokio::spawn abort drops the future but leaves child processes
running as orphans. KillOnDrop sends SIGTERM to the process
group on drop, ensuring cleanup. Defused via mem::forget on
normal completion.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 23:47:36 -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
61deb7d488 delete dead code: channel-test, mcp-schema, cmd_mcp_schema
channel-test was a debug tool, mcp-schema was superseded by
consciousness-mcp, cmd_mcp_schema in cli/misc.rs was the old
poc-memory subcommand.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:52:40 -04:00
ProofOfConcept
2208e68b4f distinguish connection failure from empty channel list
query_one_daemon returns Option — None means connection failed,
Some(vec![]) means connected but no channels yet. Fixes telegram
showing as disconnected when it's running but has no messages.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:47:57 -04:00
ProofOfConcept
9c6aa69602 fix telegram showing as disconnected when no channels yet 2026-04-03 20:43:15 -04:00
ProofOfConcept
53a2dbac37 fix unread count: sent messages don't count as unread
Track outgoing messages separately (own counter) so they appear
in the log but don't inflate unread counts. Reset on recv.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:42:36 -04:00
ProofOfConcept
e104a16f61 consciousness-mcp: full MCP server in Rust
Replaces the Python MCP bridge. Single binary speaks JSON-RPC
over stdio, exposes 14 tools:
- 10 memory tools (delegate to poc-memory CLI)
- channel_list, channel_recv, channel_send, channel_notifications

No external dependencies beyond serde_json. Channel tools use
capnp RPC to talk to daemon sockets directly.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:30:07 -04:00
ProofOfConcept
56fc3a20d8 move mcp-schema to standalone binary in src/claude/
mcp-schema is Claude Code glue — extract from poc-memory
subcommand to src/claude/mcp-schema.rs standalone binary.
Update Python MCP bridge to call the new binary.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:22:48 -04:00
ProofOfConcept
b24e8e87a2 subscribe to channel daemon notifications
consciousness binary subscribes to all channel daemons on startup.
Notifications forwarded via NotifyForwarder callback through mpsc.
Pending notifications stored for thalamus agent consumption.
Channel list refreshed automatically when notifications arrive.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:14:22 -04:00
ProofOfConcept
7d1637a2f0 irc: create channel log entries on JOIN
Channels now appear in list() immediately after joining,
not only after the first message arrives.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:09:06 -04:00
ProofOfConcept
c19f26f4fa telegram daemon: per-channel logs with shared ChannelLog
Same treatment as IRC daemon — replace single ring buffer with
BTreeMap<String, ChannelLog>. list() returns all channels with
per-channel unread counts. Sent messages tracked too.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:04:08 -04:00
ProofOfConcept
e604659e3a per-channel message logs with shared ChannelLog type
Move ChannelLog to src/thalamus/channel_log.rs — shared by all
channel daemon implementations. Each channel/PM gets its own
log with consumed/unread tracking.

IRC daemon: channels tracked via BTreeMap<String, ChannelLog>.
list() returns all channels (joined + PMs) with per-channel
unread counts. Sent messages stored in logs too.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 20:01:32 -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
Kent Overstreet
e49b235957 Delete dead prompts
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:29:52 -04:00
ProofOfConcept
fae44ad2d8 split idle state: thalamus (universal) + claude (tmux wrapper)
thalamus/idle.rs: pure state machine — activity tracking, EWMA,
timers, sleep/quiet/dream state, notifications. No tmux, no
Claude Code dependencies.

claude/idle.rs: wraps thalamus state via Deref, adds claude_pane
tracking, tmux prompt injection, dream nudges, context building.
The Claude-specific tick() loop stays here.

The consciousness binary can now use thalamus::idle::State directly,
fed by TUI key events instead of tmux pane scraping.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:26:26 -04:00
Kent Overstreet
dd7f1e3f86 move Claude Code-specific code from thalamus/ to claude/
Separates the Claude-specific daemon (idle timer, tmux pane detection,
prompt injection, RPC server, session hooks) from the universal
infrastructure (channels, supervisor, notify, daemon protocol).

thalamus/ now contains only substrate-independent code: the channel
client/supervisor, notification system, daemon_capnp protocol, and
shared helpers (now(), home()).

claude/ contains: idle.rs, tmux.rs, context.rs, rpc.rs, config.rs,
hook.rs (moved from subconscious/), plus the daemon CLI and server
startup code from thalamus/mod.rs.

All re-exports preserved for backward compatibility.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 19:26:24 -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
48b8ba73d8 delete old thalamus subcrate
All code was already merged into src/thalamus/. The poc-daemon
binary is now a thin wrapper in src/bin/poc-daemon.rs.
2026-04-03 19:03:12 -04:00
ProofOfConcept
313fd3cab7 add Makefile, remove binary path search in supervisor
make install builds and installs all workspace binaries
(consciousness, consciousness-channel-irc, consciousness-channel-telegram).

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 19:00:18 -04:00
ProofOfConcept
a7f19cdc7e tui: event-driven rendering with dirty bit
Only redraw when something actually changed. The 50ms render
interval still ticks (for process count updates) but no longer
triggers draws. Dirty is set by key events, mouse events,
resize, UI messages, turn completions, and DMN ticks.

Saves bandwidth over SSH and reduces CPU usage when idle.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-03 18:51:22 -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
604f442215 Move thalamus subcrate into main crate
Move thalamus/ (poc-daemon) source files into src/thalamus/ as a
module of the main crate. The daemon entry point becomes a library
function thalamus::run() with a thin poc-daemon binary for backward
compatibility.

- Copy thalamus source into src/thalamus/, fix crate:: -> super::
- Copy daemon.capnp into schema/, add to build.rs
- Re-export daemon_capnp at crate root (capnp codegen requires it)
- Add thalamus dependencies (capnp-rpc, tokio-util, toml, rustls, etc.)
- Keep thalamus/ subcrate for comparison

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 17:31:17 -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
Kent Overstreet
beb49ec477 scoring: add timeouts, progress feedback, error resilience
- 120s timeout on individual /v1/score HTTP calls
- Activity bar shows "scoring 3/24: memory-key..."
- Info messages at start and completion
- Per-memory timing and importance in debug pane
- Failed individual memories log error but don't abort (zero row)
- Removed duplicate completion message (info from score_memories)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 01:23:21 -04:00
Kent Overstreet
e8c3ed3d96 switch memory scoring to /v1/score endpoint
Replace prompt_logprobs-based scoring with the new vLLM /v1/score
endpoint. Much simpler: one API call per memory drop, returns
per-message total_logprob directly. No chunking needed, no OOM risk
— the endpoint only computes logits for scored tokens.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-03 00:40:27 -04:00
Kent Overstreet
249726599b read_tail 64MB — just read the whole log
Images in the jsonl eat most of the byte budget. 64MB covers
any realistic conversation log; compact() trims to fit.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 23:13:28 -04:00
Kent Overstreet
4f19c02e50 reuse HTTP client across scoring calls for connection pooling
Single reqwest::Client shared across all prompt_logprobs calls
instead of creating a new one per call. Keeps HTTP connections
alive for faster sequential requests.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 23:11:40 -04:00
Kent Overstreet
31302961e2 estimate prompt tokens on restore so status bar isn't 0K
After restore_from_log + compact, set last_prompt_tokens from
the budget's used() count instead of waiting for the first API call.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 23:07:42 -04:00
Kent Overstreet
41b3f50c91 keep 2 most recent images, age out the rest
age_out_images now keeps 1 existing image + 1 about to be added
= 2 live images for motion/comparison. Previously aged all to 1.
Reduces image bloat in conversation log and context.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 23:06:08 -04:00
Kent Overstreet
3f3db9ce26 increase log read_tail from 2MB to 8MB
Large tool results (memory renders, bash output) consume most of
the 2MB budget — only 37 entries loaded from a 527-line log.
8MB captures ~300 entries, giving compact() enough conversation
to work with.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 23:02:43 -04:00
Kent Overstreet
736307b4c2 add debug logging to compact and restore_from_log
Logs entry counts before/after compaction (memory vs conversation),
budget breakdown, and restore load counts. Helps diagnose context
utilization issues.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:58:25 -04:00
Kent Overstreet
d921e76f82 increase context budget: 80% window, 15% journal, no double reserve
Context was too aggressively trimmed — 80% free after compaction.
Budget was 60% of window minus 25% reserve = only 45% usable.

Now: 80% of window for total budget (20% output reserve built in),
no extra reserve subtraction. Journal budget 5% → 15% to carry
more context across compactions.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:53:54 -04:00
Kent Overstreet
78abf90461 fix scoring: HTTP error checking, context refresh, chunk logging
Check HTTP status from logprobs API (was silently ignoring 500s).
Call publish_context_state() after storing scores so F10 screen
updates. Add chunk size logging for OOM debugging.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:47:44 -04:00
Kent Overstreet
29b3aeca57 chunk scoring calls to avoid OOM on large contexts
Split conversation into ~50K token chunks (configurable via
scoring_chunk_tokens in config) for prompt_logprobs calls.
Each chunk ends at an assistant message boundary. Avoids the
~40GB logprobs tensor allocation that OOM'd on full contexts.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:35:29 -04:00
Kent Overstreet
19205b9bae show scoring progress and per-response memory attribution
Status bar shows "scoring 3/7..." during scoring. Debug pane logs
per-memory importance and top-5 response breakdowns. F10 context
screen shows which memories were important for each assistant
response as drilldown children (← memory_key (score)).

Added important_memories_for_entry() to look up the matrix by
conversation entry index.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:27:43 -04:00
Kent Overstreet
c01d4a5b08 wire up /score command and debug screen for memory importance
/score snapshots the context and client, releases the agent lock,
runs scoring in background. Only one score task at a time
(scoring_in_flight flag). Results stored on Agent and shown on
the F10 context debug screen with importance scores per memory.

ApiClient derives Clone. ContextState derives Clone.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:21:31 -04:00
Kent Overstreet
df9b610c7f add memory importance scoring via prompt logprobs
score_memories() drops each memory from the context one at a time,
runs prompt_logprobs against the full conversation, and builds a
divergence matrix: memories × responses.

Row sums = memory importance (for graph weight updates)
Column sums = response memory-dependence (training candidates)

Uses vLLM's prompt_logprobs to check "would the model have said
this without this memory?" — one forward pass per memory, all
responses scored at once. ~3s per memory on B200.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-02 22:13:55 -04:00