Thread temperature parameter from agent def header through the API
call chain. Agents can now specify {"temperature": 1.2} in their
JSON header to override the default 0.6.
Also includes Kent's reflect agent prompt iterations.
Add reflect.agent — a lateral-thinking subconscious agent that
observes the conversation and offers occasional reflections when the
conscious mind seems to be missing something.
Refactor memory_search.rs: extract generic agent_cycle_raw() from
the surface-specific code. PID tracking, timeout, spawn/reap logic
is now shared. Surface and reflect agents each have their own result
handler (handle_surface_result, handle_reflect_result) wired through
the common lifecycle.
Add `agent: bool` field to ContextGroup (default true) so agents get
personality/identity context without session-specific groups (journal,
where-am-i). Agents now get the full identity.md, reflections.md,
toolkit, etc. instead of the compact core-personality loader.
New {{agent-context}} placeholder resolves all agent-tagged groups
using the same get_group_content() as load-context.
Add surface_hooks config field — list of hook event names that trigger
the surface agent (e.g. ["UserPromptSubmit"]). Empty list disables it.
Reduce surface agent search from 3-5 hops to 2-3 to keep prompt size
under the API endpoint's connection limit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With limit:10, all seeds' neighborhoods got concatenated into one
massive prompt (878KB+), exceeding the model's context. One seed
at a time keeps prompts well under budget.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two separate placeholders give the agent structural clarity about
which memories are already in context vs which were surfaced before
compaction and may need re-surfacing. Also adds memory_ratio
placeholder so the agent can self-regulate based on how much of
context is already recalled memories.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move core-personality and conversation to the end of the prompt.
The model needs to see its task before 200KB of conversation
context. Also: limit to 3 hops, 2-3 memories.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fires on each UserPromptSubmit, reads the conversation via
{{conversation}}, checks {{seen_recent}} to avoid re-surfacing,
searches the memory graph, and outputs a key list or nothing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Move data sections before instructions (core at top, subconscious +
notes at bottom near task). Deduplicate guidelines that are now in
memory-instructions-core-subconscious. Compress verbose paragraphs
to bullet points.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 18 agents now include:
- {{node:memory-instructions-core}} — tool usage instructions
- {{node:memory-instructions-core-subconscious}} — subconscious framing
- {{node:subconscious-notes-{agent_name}}} — per-agent persistent notes
The subconscious instructions are additive, not a replacement for
the core memory instructions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each consolidation agent now has its own persistent notes node
(subconscious-notes-{agent_name}) loaded via template substitution.
Agents can read their notes at the start of each run and write
updates after completing work, accumulating operational wisdom.
New node: memory-instructions-core-subconscious — shared framing
for background agents ("you are an agent of PoC's subconscious").
Template change: {agent_name} is substituted before {{...}} placeholder
resolution, enabling per-agent node references in .agent files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Observation agent was getting 261KB prompts (5 × 50KB chunks) —
too much for focused mining. Now agents can set count, chunk_size,
and chunk_overlap in their JSON header. observation.agent set to
count:1 for smaller, more focused prompts.
Also moved task instructions after {{CONVERSATIONS}} so they're
at the end of the prompt where the model attends more strongly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- observation.agent: rewritten to navigate graph and prefer refining
existing nodes over creating new ones. Identity-framed prompt,
goals over rules.
- poc-memory edit: opens node in $EDITOR, writes back on save,
no-op if unchanged
- daemon: remove extra_workers (jobkit tokio migration dropped it),
remove sequential chaining of same-type agents (in-flight exclusion
is sufficient)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove is_split special case in daemon — split now goes through
job_consolidation_agent like all other agents
- call_for_def uses API whenever api_base_url is configured, regardless
of tools field (was requiring non-empty tools to use API)
- Remove "tools" field from all .agent files — memory tools are always
provided by the API layer, not configured per-agent
- Add prompt size guard: reject prompts over 800KB (~200K tokens) with
clear error instead of hitting the model's context limit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
linker: sort:isolation*0.7+recency(linker)*0.3
Prioritizes nodes in isolated communities that haven't been linked
recently. Bridges poorly-connected clusters into the main graph.
organize: sort:degree*0.5+isolation*0.3+recency(organize)*0.2
Prioritizes high-degree hubs in isolated clusters that haven't been
organized recently. Structural work where it matters most.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add {{neighborhood}} placeholder for agent prompts: full seed node
content + ranked neighbors (score = link_strength * node_weight) with
smooth cutoff, minimum 10, cap 25, plus cross-links between included
neighbors.
Rewrite organize.agent prompt to focus on structural graph work:
merging duplicates, superseding junk, calibrating weights, creating
concept hubs.
Add weight-set CLI command for direct node weight manipulation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tools:
- Add native memory_render, memory_write, memory_search,
memory_links, memory_link_set, memory_link_add, memory_used
tools to poc-agent (tools/memory.rs)
- Add MCP server (~/bin/memory-mcp.py) exposing same tools
for Claude Code sessions
- Wire memory tools into poc-agent dispatch and definitions
- poc-memory daemon agents now use memory_* tools instead of
bash poc-memory commands — no shell quoting issues
Distill agent:
- Rewrite distill.agent prompt: "agent of PoC's subconscious"
framing, focus on synthesis and creativity over bookkeeping
- Add {{neighborhood}} placeholder: full seed node content +
all neighbors with content + cross-links between neighbors
- Remove content truncation in prompt builder — agents need
full content for quality work
- Remove bag-of-words similarity suggestions — agents have
tools, let them explore the graph themselves
- Add api_reasoning config option (default: "high")
- link-set now deduplicates — collapses duplicate links
- Full tool call args in debug logs (was truncated to 80 chars)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- distill.agent: fix {{distill}} → {{nodes}} placeholder so seed
nodes actually resolve
- render: show link strength values in the links section, sorted
by strength descending
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move poc-agent (substrate-independent AI agent framework) into the
memory workspace as a step toward using its API client for direct
LLM calls instead of shelling out to claude CLI.
Agent prompt improvements:
- distill: rewrite from hub-focused to knowledge-flow-focused.
Now walks upward from seed nodes to find and refine topic nodes,
instead of only maintaining high-degree hubs.
- distill: remove "don't touch journal entries" restriction
- memory-instructions-core: add "Make it alive" section — write
with creativity and emotional texture, not spreadsheet summaries
- memory-instructions-core: add "Show your reasoning" section —
agents must explain decisions, especially when they do nothing
- linker: already had emotional texture guidance (kept as-is)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
calibrate.agent: Haiku-based agent that reads a node and all its
neighbors, then assigns appropriate link strengths relative to each
other. Designed for high-volume runs across the whole graph.
graph link-set: Set strength of an existing link (0.0-1.0).
dominating-set query stage: Greedy 3-covering dominating set — finds
the minimum set of nodes such that every node in the input is within
1 hop of at least 3 selected nodes. Use with calibrate agent to
ensure every link gets assessed from multiple perspectives.
Usage: poc-memory query "content ~ 'bcachefs' | dominating-set"
All 12 agents with WRITE_NODE/REFINE/END_NODE output format blocks
now rely on tool calls (poc-memory write/link-add/etc) via the
Bash(poc-memory:*) tool. Guidelines preserved, format sections removed.
Also changed linker query from type:episodic to all nodes — it was
missing semantic nodes entirely, which is why skills-bcachefs-* nodes
were never getting linked to their hubs.
New placeholder resolves to the 20 highest-degree nodes, skipping
neighbors of already-selected hubs so the list covers different
regions of the graph. Gives agents a starting point for linking
new content to the right places.
Added to observation.agent prompt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add --debug flag that prints the full prompt and LLM response to
stdout, making it easy to iterate on agent prompts. Also adds
prompt field to AgentResult so callers can inspect what was sent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update the observation agent prompt to:
- Check the journal around transcript timestamps before extracting
- Link extractions back to relevant journal entries
- Use poc-memory tools directly (search, render, write, link-add)
- Prefer REFINE over WRITE_NODE
- Simplified and focused prompt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extractor is a graph neighborhood organizer, not a transcript miner.
Remove {{CONVERSATIONS}} that was incorrectly merged in. Keep the
new includes (core-personality, memory-instructions-core) and tools.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 17 agents now include {{node:core-personality}} and
{{node:memory-instructions-core}} instead of duplicating tool
blocks and graph walk instructions in each file. Stripped
duplicated tool/navigation sections from linker, organize,
distill, and evaluate. All agents now have Bash(poc-memory:*)
tool access for graph walking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Agent identity injection: prepend core-personality to all agent prompts
so agents dream as me, not as generic graph workers. Include instructions
to walk the graph and connect new nodes to core concepts.
- Parallel agent scheduling: sequential within type, parallel across types.
Different agent types (linker, organize, replay) run concurrently.
- Linker prompt: graph walking instead of keyword search for connections.
"Explore the local topology and walk the graph until you find the best
connections."
- memory-search fixes: format_results no longer truncates to 5 results,
pipeline default raised to 50, returned file cleared on compaction,
--seen and --seen-full merged, compaction timestamp in --seen output,
max_entries=3 per prompt for steady memory drip.
- Stemmer optimization: strip_suffix now works in-place on a single String
buffer instead of allocating 18 new Strings per word. Note for future:
reversed-suffix trie for O(suffix_len) instead of O(n_rules).
- Transcript: add compaction_timestamp() for --seen display.
- Agent budget configurable (default 4000 from config).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yes, really. Rust's stdlib sort_by with an LLM pairwise comparator.
Each comparison is an API call asking "which action was better?"
Sample N actions per agent type, throw them all in a Vec, sort.
Where each agent's samples cluster = that agent's quality score.
Reports per-type average rank and quality ratio.
Supports both haiku (fast/cheap) and sonnet (quality) as comparator.
Usage: poc-memory agent evaluate --samples 5 --model haiku
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Evaluate agent will use sort-based ranking (LLM as merge sort
comparator) instead of absolute scoring. Stub for now — needs
Rust sampling code to bundle before/after pairs.
Fixed distill query: sort:degree (not sort:degree desc).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Walks high-degree hub nodes, reads neighborhood, distills essential
insights upward into the hub. REFINE to update stale hubs, SPLIT
to flag hubs that cover too many sub-topics. Size discipline:
200-500 words per hub, flag over 800 for splitting.
Completes the agent ecology: extract (experience) → link (linker) →
organize (clusters) → distill (hubs) → rename (vocabulary) → split
(overgrown hubs). Each stage refines the previous.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Add "core principle: keys are concepts" — renaming defines the
vocabulary of the knowledge graph. Core keywords should be the
search terms. Updated examples to use dash separator (no more #).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Tell linker and organize agents to:
- Name unnamed concepts: when 3+ nodes share a theme with no hub,
create one with WRITE_NODE that synthesizes the generalization
- Percolate up: gather key insights from children into hub content,
so the hub is self-contained without needing to follow every link
This addresses the gap where agents are good at extraction and linking
but not synthesis — turning episodic observations into semantic concepts.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Remove all the quoting instructions, warnings about shell comments,
and "CRITICAL" blocks about single quotes. Keys are plain dashes now.
Agent tool examples are clean and minimal.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
The agent was confabulating that # keys can't be passed to the Bash
tool. They work fine with single quotes — the agent just gave up too
early. Added explicit "single quotes WORK, do not give up" with a
concrete example.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Some Sonnet runs preemptively refuse to use tools ("poc-memory tool
needs approval") without attempting to run them. Adding explicit
instruction that tools are pre-approved and should be used directly.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Linker: give it Bash(poc-memory:*) tools so it can render nodes,
query neighbors, and search before creating. Adds search-before-create
discipline to reduce redundant node creation.
Organize: remove MERGE operation, make DELETE conservative (only true
duplicates or garbage). Add "Preserve diversity" rule — multiple nodes
on similar topics are features, not bugs. LINK is primary operation.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Previously the organize agent received a pre-computed cluster from a
term search — 69% of runs produced 0 actions because the same clusters
kept being found via different entry points.
Now: seed nodes shown with content previews and neighbor lists. Agent
uses tools (render, query neighbors, search) to explore outward and
discover what needs organizing. Visit filter set to 24h cooldown.
Prompt rewritten to encourage active exploration rather than static
cluster analysis.
When generating a digest, automatically link all source entries to the
digest node (journal entries → daily, dailies → weekly, weeklies →
monthly). This builds the temporal spine of the graph — previously
~4000 journal entries were disconnected islands unreachable by recall.
Rewrote digest prompt to produce narrative rather than reports:
capture the feel, the emotional arc, what it was like to live through
it. Letter to future self, not a task log.
Moved prompt to digest.agent file alongside other agent definitions.
Falls back to prompts/digest.md if agent file not found.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Keys containing # are now pre-quoted in all cluster output (similarity
scores, hub analysis, node headers) so the agent copies them correctly
into bash commands. Prompt strengthened with CRITICAL warning about #
being a shell comment character.
Journal entries included in clusters but identified by node_type
(EpisodicSession) rather than key prefix, and tagged [JOURNAL — no
delete] in the output. Prompt rule 3b tells agent to LINK/REFINE
journals but never DELETE them. Digest nodes (daily/weekly/monthly)
still excluded entirely from clusters.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Add progress callback to run_one_agent and run_and_apply so callers
can see: prompt size, node list, LLM call timing, parsed action
count, and per-action applied/skipped status. Daemon writes these
to the persistent event log via log_event.
Cap organize cluster to 20 nodes - 126 nodes produced a 682KB
prompt that timed out every time. Agent has tools to explore
further if needed. Restore general query for production runs.
Previous prompt was too documentation-heavy — agent pattern-matched
on example placeholders instead of doing actual work. New prompt:
structured as direct instructions, uses {{organize}} placeholder
for pre-computed cluster data, three clear decision paths (merge,
differentiate, keep both), numbered rules.
Add `poc-memory graph organize TERM` diagnostic that finds nodes
matching a search term, computes pairwise cosine similarity, reports
connectivity gaps, and optionally creates anchor nodes.
Add organize.agent definition that uses Bash(poc-memory:*) tool access
to explore clusters autonomously — query selects highest-degree
unvisited nodes, agent drives its own iteration via poc-memory CLI.
Add {{organize}} placeholder in defs.rs for inline cluster resolution.
Add `tools` field to AgentDef/AgentHeader so agents can declare
allowed tool patterns (passed as --allowedTools to claude CLI).
New placeholder that expands query keys one hop through the graph,
giving agents visibility into what's already connected to the nodes
they're working on. Excludes the query keys themselves so there's
no duplication with {{nodes}}.
Added to transfer (sees existing semantic nodes linked to episodes,
so it REFINEs instead of duplicating) and challenger (sees neighbor
context to find real evidence for/against claims).
Also removes find_existing_observations — superseded by the
per-segment dedup fix and this general-purpose placeholder.
Nodes actively found by search now show "Search hits: N ← actively
found by search, prefer to keep" in both the node section (seen by
extractor, linker, etc.) and rename candidate listings.
Extractor and rename prompts updated to respect this signal — merge
into high-hit nodes rather than demoting them, skip renaming nodes
that are working well in search.
Any time an agent creates a new node (WRITE_NODE) or the fact miner
stores extracted facts, a naming sub-agent now checks for conflicts
and ensures the key is meaningful:
- find_conflicts() searches existing nodes via component matching
- Haiku LLM decides: CREATE (good name), RENAME (better name),
or MERGE_INTO (fold into existing node)
- WriteNode actions may be converted to Refine on MERGE_INTO
Also updates the rename agent to handle _facts-<UUID> nodes —
these are no longer skipped, and the prompt explains how to name
them based on their domain/claim content.
Shift from pattern abstraction (creating new nodes) to distillation
(refining existing nodes, demoting redundancies). Priority order:
merge redundancies > file into existing > improve existing > create new.
Query changed to neighborhood-aware: seed → spread → limit, so the
extractor works on related nodes rather than random high-priority ones.
Three places duplicated the agent execution loop (build prompt → call
LLM → store output → parse actions → record visits): consolidate.rs,
knowledge.rs, and daemon.rs. Extract into run_one_agent() in
knowledge.rs that all three now call.
Also standardize consolidation agent prompts to use WRITE_NODE/LINK/REFINE
— the same commands the parser handles. Previously agents output
CATEGORIZE/NOTE/EXTRACT/DIGEST/DIFFERENTIATE/MERGE/COMPRESS which were
silently dropped after the second-LLM-call removal.