AutoAgent holds config + walked state. Backend is ephemeral per run:
- run(): standalone, global API client (oneshot CLI)
- run_forked(): forks conscious agent, resolves prompt templates
with current memory_keys and walked state
Mind creates AutoAgents once at startup, takes them out for spawned
tasks, puts them back on completion (preserving walked state).
Removes {{seen_previous}}, {{input:walked}}, {{memory_ratio}} from
subconscious agent prompts. Walked keys are now a Vec on AutoAgent,
resolved via {{walked}} from in-memory state.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Lightweight resolver handles {{seen_current}}, {{seen_previous}}, and
{{input:KEY}} using the session_id and output_dir directly instead of
env vars. Runs in trigger_subconscious before creating AutoAgent.
Removes {{memory_ratio}} from surface-observe prompt — redundant with
existing budget mechanisms.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
subconscious-surface-observe, subconscious-journal, subconscious-reflect
are Mind's forked agents. The original surface-observe, journal, reflect
remain for the standalone CLI/hook path.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Mind now holds SubconsciousAgent state (surface-observe, journal,
reflect) and triggers them after conscious turns complete. Each
agent forks from the conscious agent's context via AutoAgent,
runs as an async task, and routes output (surfaced memories,
reflections) back into the conscious agent.
Replaces the synchronous AgentCycleState that spawned child
processes and blocked start_turn.
Also adds .agent2 files — simplified prompts for the forked model
that strip {{conversation}} and {{agent-context}} (already in the
forked context).
TODO: resolve remaining placeholders (seen_current, input:walked,
memory_ratio) in the .agent2 prompts.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
User and assistant names now come from config.user_name and
config.assistant_name throughout: system prompt, DMN prompts,
debug screen, and all agent files. Agent templates use
{user_name} and {assistant_name} placeholders.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Thread request priority through the API call chain to vLLM's
priority scheduler. Lower value = higher priority, with preemption.
Priority is set per-agent in the .agent header:
- interactive (runner): 0 (default, highest)
- surface-observe: 1 (near-realtime, watches conversation)
- all other agents: 10 (batch, default if not specified)
Requires vLLM started with --scheduling-policy priority.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal needs to find nodes (memory_search), read them
(memory_render), and track seen set (memory_used) to make
informed links. Still no memory_write — node creation is
observe's job.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal entries need to link to relevant memory nodes for graph
connectivity. Added memory_link_add to the journal agent's tool
whitelist alongside the journal tools.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal agent now only gets journal_tail, journal_new, journal_update.
Cannot create duplicate memory nodes via memory_write.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Agents must use native tool dispatch, not bash, for correct
provenance tracking. Bash access was leftover from old architecture.
All 12 agents cleaned up.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Remove journal tool from memory-instructions-core (only the journal
agent should write journal entries). Add explicit instruction to
journal agent: only use journal_tail/journal_new/journal_update,
not memory_write/render/search.
Prevents the journal agent from creating duplicate memory nodes
about events that surface-observe is already recording.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Agents are routed to Qwen by the runner, not by per-agent model
fields. The "model":"sonnet" was leftover from the Claude API days
and no longer used.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Reframe the observe role as librarian — factual, specific, organized.
Record what happened and why. Reflection belongs in the journal;
observe is for memory.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
memory_search is now spreading activation — the natural way to search
a graph. Give it seed node keys and it finds conceptually related nodes.
The old keyword-based memory_search and memory_search_content are
removed; memory_query can do everything they did.
Simpler tool set, better defaults. Agents don't need to be told "use
spread not search" — search IS spread now.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The agent was defaulting to keyword searches despite instructions to
use spreading activation first. Reframe instructions positively:
memory_spread is the default mode of operation. Search is available
for finding specific nodes by name.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Update surface-observe agent instructions to use memory_spread as the
primary search strategy — cast a wide net from conversation themes before
drilling in with graph walks.
Add explicit instruction to watch for behavioral patterns (avoidance,
rushing, explaining away data) and surface relevant feedback memories
in the moment.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal was step 5 of the surface-observe pipeline but never ran
because the bail check stopped the pipeline before reaching it.
Split into its own agent with:
- {{conversation:50000}} for recent conversation
- {{bash:poc-memory tail -p surface-observe 10}} for observe context
- {{latest_journal}} for previous entry continuity
Add generic {{bash:COMMAND}} placeholder to agent template resolver
so agents can include shell command output in their prompts.
Remove journal phase from surface-observe.agent (now 4 steps).
- Add "different nodes should be about different things" guard to observe
- Clarify journal prompt: write about conscious self, not agent work
- Add "write about what happened and how it felt" instruction
- Simplify surface prompt focus guidance
- Add memory_rename tool (in-place rename, preserves content and links)
- Update rename.agent prompt to use memory_rename() instead of text output
- Fix {{rename}} placeholder to respect --target keys when provided
- Add format_rename_targets() for targeted rename runs
Catchup throttle: when the agent is >50% behind the conversation
window (>25KB of transcript growth since last spawn), block and
wait up to 30s for the current agent to finish. Prevents the agent
from falling behind during heavy reading/studying.
Reflection agent: runs every 100KB of transcript growth. Reads
walked nodes from surface-observe, follows links in unexpected
directions, outputs a short dreamy insight. Previous reflections
are injected into the conversation context.
Updated reflect.agent prompt to use {{input:walked}} from
surface-observe state dir and {{conversation:20000}} for lighter
context.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Links to nodes created after the conversation window start are
tagged with (new) in memory_render output. The surface prompt
tells the agent not to surface these — they're its own recent
output, not prior memories. Observe can still see and update them.
POC_MEMORIES_OLDER_THAN env var set from the oldest message
timestamp in the conversation window.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
- journal_new(name, title, body): name becomes the node key,
title goes in the ## heading. Agent picks short searchable names.
- Auto-dedup: if the key exists, append -2, -3, etc.
- CLI journal write also requires a name argument now.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
- Remove unused now_secs(), parse_json_response, any_alive, Regex import
- Signal handler: replace Mutex with AtomicPtr<c_char> for signal safety
(Mutex::lock in a signal handler can deadlock if main thread holds it)
- PidGuard Drop reclaims the leaked CString; signal handler just unlinks
- scan_pid_files moved to knowledge.rs as pub helper
- setup_agent_state calls scan_pid_files to clean stale pids on startup
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
- Bail command moved from hardcoded closure to external script
specified in agent JSON header ("bail": "bail-no-competing.sh")
- Runner executes script between steps with pid file path as $1,
cwd = state dir. Non-zero exit stops the pipeline.
- PID files simplified to just the phase name (no JSON) for easy
bash inspection (cat pid-*)
- scan_pid_files helper deduplicates pid scanning logic
- Timeout check uses file mtime instead of embedded timestamp
- PID file cleaned up on bail/error (not just success)
- output() tool validates key names (rejects pid-*, /, ..)
- Agent log files append instead of truncate
- Fixed orphaned derive and doc comment on AgentStep/AgentDef
- Phase written after bail check passes, not before
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
agents/*.agent definitions and prompts/ now live under
src/subconscious/ alongside the code that uses them.
No more intermediate agents/ subdirectory.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
hippocampus/ — memory storage, retrieval, and consolidation:
store, graph, query, similarity, spectral, neuro, counters,
config, transcript, memory_search, lookups, cursor, migrate
subconscious/ — autonomous agents that process without being asked:
reflect, surface, consolidate, digest, audit, etc.
All existing crate::X paths preserved via re-exports in lib.rs.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>