Commit graph

1009 commits

Author SHA1 Message Date
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
72f4f1b617 context: cache role header token lengths
Branch::tokens() was calling tokenizer::encode() on every call for
the role header ("system\n", "user\n", "assistant\n") and trailing
newline. In trim_conversation(), this meant hundreds of encode calls
per trim cycle.

These are fixed strings - cache them with OnceLock on first use.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:47:36 -04:00
Kent Overstreet
ac6f1e9294 unconscious: move health refresh outside lock too
refresh_health() was doing Store::load() + compute_graph_health()
while holding the Unconscious lock, causing 12 second stalls.

Split into needs_health_refresh() (quick check) and set_health()
(quick store), with the slow I/O happening outside the lock.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:37:54 -04:00
Kent Overstreet
f40d8cfa9d unconscious: release lock during slow spawn work
Split trigger() into phases so the Unconscious mutex is only held briefly:
- reap_finished(): check handles, restore completed autos
- select_to_spawn(): pick agents, take their autos out
- prepare_spawn(): slow work (Store::load, query, Agent::new) - NO LOCK
- complete_spawn()/abort_spawn(): store results back

Previously held the lock for 28+ seconds during Store::load and query
execution. Now lock hold time should be milliseconds.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:33:23 -04:00
Kent Overstreet
f56fc3a7c7 locks: add process-wide lock hold time tracking
TrackedMutex and TrackedRwLock wrappers that record hold durations
by source location using #[track_caller]. Stats written to
~/.consciousness/lock-stats.json every second, sorted by max hold time.

Re-exported as crate::Mutex so all locks are instrumented. To disable,
swap the re-export back to tokio::sync::Mutex.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:27:42 -04:00
Kent Overstreet
b94e056372 unconscious/subconscious: use Option<AutoAgent> instead of placeholder
Previously, spawning an agent used std::mem::replace with an empty-name
AutoAgent as placeholder. This caused ghost stats entries under "" when
those placeholders accidentally got their stats logged.

Now uses Option<AutoAgent> with .take() - the type honestly represents
that the agent is unavailable while running. Panic recovery in
subconscious now properly recreates the agent from its definition.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:11:40 -04:00
Kent Overstreet
33156d9ab3 channels: improve tmux state tracking and config persistence
tmux channel:
- Track connected state per-pane (shows true channel availability)
- Persist pane config on add/remove (survives restarts)
- Remove cleanup_pipes on exit (unnecessary with persisted config)
- Reorder PaneConfig fields for consistency

telegram channel:
- Use json5 crate for config parsing (matches tmux)

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:11:34 -04:00
Kent Overstreet
4556e16fd7 enable short backtraces by default
Uses panic_backtrace_config feature to set BacktraceStyle::Short,
so panics show useful backtraces without needing RUST_BACKTRACE=1.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 20:11:27 -04:00
Kent Overstreet
dfab7d0a33 prompts: remove unused replay_queue import
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 16:21:54 -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
f06c8077e1 research: latent reasoning integration plans for Qwen 3.5 27B
Two research documents:

latent-reasoning-integration-plan.md: Synthesizes 10+ papers on
latent reasoning, identifies which approaches work with finetuning
(vs requiring pretraining from scratch), and maps them to our
APOLLO-Mini training pipeline.

pause-tokens-gdn-recurrence.md: Explores the connection between
token-based latent reasoning and GDN's internal recurrence. Key
insight: pause tokens on Qwen 3.5 trigger both forward passes AND
recurrent state updates, giving double benefit.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 15:50:09 -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
ab0f16a3b5 tools: add cd tool for changing working directory
Uses std::env::set_current_dir() syscall so the change affects
all subsequent tool invocations. Supports absolute paths, relative
paths, and ~ expansion.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 15:49:46 -04:00
Kent Overstreet
0612e1bc41 query: MCP tool uses execute_query, add double-quote strings
- MCP memory_query tool now uses execute_query path instead of
  parse_stages, enabling full expression support (content ~, AND/OR,
  neighbors, etc.) instead of just Expr::All
- Parser now accepts double-quoted strings ("foo") in addition to
  single quotes ('foo')
- Added tests for double-quote syntax
- Removed dead resolve_field_str function from memory.rs

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 13:30:00 -04:00
Kent Overstreet
c8922c9408 parser: add negated key glob filter (!key:pattern)
Fixes split agent query: all | type:semantic | !key:_* | sort:content-len | limit:1

Also adds glob_pattern rule that allows * and ? wildcards in key filters.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 03:15:02 -04:00
Kent Overstreet
c8280ae871 parser: add composite sort expressions
Adds parsing for weighted sort expressions like:
  sort:degree*0.5+isolation*0.3+recency(organize)*0.2

This fixes organize agent which uses composite scoring.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 03:02:32 -04:00
Kent Overstreet
c79b415ada fix: unconscious agent cycling
- Read max_concurrent from config (llm_concurrency) instead of hardcoding 2
- Add not-visited: and visited: filters to query parser (were in engine
  but missing from parser after unification)

The organize agent was stuck in a spawn/fail loop because its query used
not-visited: which the parser didn't recognize.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 02:55:39 -04:00
Kent Overstreet
d5aad5c1a4 kill consolidation_batch 2026-04-12 02:41:59 -04:00
Kent Overstreet
93fcc32a00 journal tail: use query engine instead of manual filtering
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 02:29:52 -04:00
Kent Overstreet
919749dc67 more dead code deletion
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2026-04-12 02:27:05 -04:00
Kent Overstreet
31aa0f3125 digest.agent: document journal_update workflow
Check if the current period's digest exists and update it with
journal_update before starting a new one with journal_new.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 02:06:55 -04:00
Kent Overstreet
b77f07fef7 digest.agent: use journal_new with level for writing digests
Instead of memory_write, the digest agent now uses journal_new with
level parameter (1=daily, 2=weekly, 3=monthly) which correctly sets
the node type.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 02:05:12 -04:00
Kent Overstreet
f00532bdb7 TurnResult: remove text field, simplify oneshot loop
- Remove TurnResult.text (was dead code - Agent::turn handles text internally)
- Simplify run_with_backend to just iterate over steps (Agent::turn loops
  for tool calls and handles empty responses internally)
- Change run/run_shared/run_forked_shared to return Result<(), String>
- Remove AgentResult.output field (no callers used it)
- Stub out legacy text-parsing code (audit, compare) that needs redesign
- Update digest.rs to not depend on text return
- Add level parameter to journal_new/journal_update for digest support

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 02:04:50 -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
b646221787 unconscious: don't load standard context — prompts are self-contained
Unconscious agent definitions already include {{tool: memory_render
core-personality}} etc. Loading standard context via reload_for_model
duplicated those nodes. Now they get empty system_prompt and
personality — everything comes from the agent definition.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 01:36:53 -04:00
Kent Overstreet
bc73ccc1da Remove hardcoded tool list from system prompt
The system prompt was advertising a fixed set of tools regardless of
what the agent actually has access to. Tools are already listed in
the separate tools section that's built from the agent's actual
tool list.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 01:33:40 -04:00
Kent Overstreet
090c8e4d35 Agent:🆕 stop unconditionally adding all MCP tools
Each agent is passed its own tool list — that's the list it should
advertise. The line that appended all_mcp_tool_definitions() was
causing unconscious agents to see bash/read_file/etc in their prompt
even though they couldn't execute them.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-12 01:33:40 -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
d2dbdedc8f Move save_agent_log to oneshot.rs for shared Mind/CLI use
Both Mind-run agents (unconscious/subconscious) and CLI-run agents
(poc-memory agent run) now use the same logging path. AutoAgent::run()
calls save_agent_log automatically at the end.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 21:34:41 -04:00
Kent Overstreet
271e09adcc fix: run_one_agent uses memory tools as base, not filter
When def.tools was non-empty, it was filtering to ONLY those tools
instead of using memory tools as base + adding extras. This broke
digest agent (and any agent with explicit tools list) by removing
all 13 base memory tools.

Fixed to match the pattern in unconscious.rs:
- base = memory_tools()
- extras from journal_tools() if listed in def.tools

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 21:20:44 -04:00
ProofOfConcept
aad227e487 query: unify PEG and engine parsers
PEG parser now handles both expression syntax (degree > 5 | sort degree)
and pipeline syntax (all | type:episodic | sort:timestamp). Deleted
Stage::parse() and helpers from engine.rs — it's now pure execution.

All callers use parse_stages() from parser.rs as the single entry point.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 20:42:58 -04:00
ProofOfConcept
bc991c3521 unconscious: memory tools as base, agent def adds extras
Every unconscious agent gets memory_tools() as baseline. The tools
field in the agent def specifies additional tools on top of that —
digest agent now gets journal_tail, journal_new, journal_update.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 19:54:18 -04:00
ProofOfConcept
1c0967c4ec Agent:🆕 tool definitions from caller's tool list
The system prompt was advertising all tools to every agent, but
the runtime only dispatched the agent's actual subset. This caused
unconscious agents to call tools that returned "Unknown tool."

Agent::new now takes the tool list explicitly. Each caller passes
its own tools — the prompt and runtime always match. MCP tool
definitions are still appended for agents that use them.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 19:43:24 -04:00
ProofOfConcept
28e564aeb2 save_agent_log: write flat context array matching AST order
The old code wrote a JSON object with named section keys, which
serde_json serialized in alphabetical order — putting conversation
before system, making logs misleading. Write a single flat array
in section order instead, matching what the model actually sees.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 19:28:03 -04:00
Kent Overstreet
c300013ce5 improve bail-no-competing.sh 2026-04-11 18:41:44 -04:00
Kent Overstreet
9fc27e7372 tweak surface-observe prompt 2026-04-11 18:41:02 -04:00
Kent Overstreet
ed896d4e83 Merge PR #1: IRC word-boundary splitting + flush (spqrz) 2026-04-11 18:13:26 -04:00
b5aa5412e1
IRC: split on word if possible, + flush 2026-04-11 22:38:57 +01:00
Kent Overstreet
78912ca72f simplify http library 2026-04-11 16:45:54 -04:00
Kent Overstreet
6c4a88d2ab kill MIN_NUDGE_INTERVAL
dead code
2026-04-11 16:45:33 -04:00
Kent Overstreet
71bfd60466 ignore SIGCHLD so children are reaped 2026-04-11 16:39:27 -04:00
Kent Overstreet
dfef7fb446 fix telegram 2026-04-11 16:38:51 -04:00
ProofOfConcept
57bd5b6d8b idle: per-instance state path, extensible extra fields
Move state_path to a field on State (default thalamus-state.json) so
the Claude daemon can use its own file without collision. Add a
serde(flatten) extra map to Persisted so callers can round-trip
additional fields (e.g. claude_pane) through save/load.

save() is now &mut self.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-11 14:35:08 -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