M5.2: agent memory
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m48s
CI / e2e (pull_request) Successful in 4m33s

remember(name, description, fact) and forget(name, why): control tools for
the driver (before the go-ahead too) and conversations, writing only the
agent's own vault folder, one note per fact with its provenance. No one
agrees first; each change is a line in the thread. The harness keeps the
index and puts it into the transcript once per item, with a hash.

At an item's close, completed or abandoned, a bounded memory pass (the
driver's model, its own transcript and view) records what was decided and
learned; it never holds the close up (tuning.memory.max_turns).

With the operator: corrections may be paraphrased (L6 changed), the model
forgets on its own, and nothing limits what may prompt a note. The walk
remembers and forgets, and checks nothing lands outside the agent's folder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
This commit is contained in:
dongarandClaude Opus 5.5 committed 2026-10-08 23:05:45 +00:00
1 parent 2a35475eec
commit 2b26f0cff5
16 files changed
+604 -16

No files matched your search

+14 -4
View File
@@ -24,6 +24,7 @@ from nisse_dev.loop.help import Helpers
from nisse_dev.loop.milestones import Milestones
from nisse_dev.loop.reader import GoAheadReader
from nisse_dev.matrix import MatrixTransport
from nisse_dev.memory import Memory
from nisse_dev.oplog import OpLog
from nisse_dev.state import StateStore
from nisse_dev.tools import Workspace
@@ -36,6 +37,7 @@ from nisse_dev.worker import SerialWorker
SHUTDOWN_WAIT_S = 10.0
TOOL_DRIVING_ROLES = ("driver", "helper")
MEMORY_FOLDER = "memory/nisse-dev" # L10: the agent's own, in its vault
def discover_models(config: AgentConfig, oplog: OpLog) -> ModelCatalog:
@@ -298,6 +300,11 @@ def build_loop_agent(
profiles=config.profiles,
)
transport = MatrixTransport(config.matrix)
vault = (
Vault(config.vault.root, config.vault.folders, ignore=config.vault.ignore)
if config.vault
else None
)
loop = LoopAgent(
store,
transport,
@@ -334,12 +341,15 @@ def build_loop_agent(
general_idle_s=config.tuning.loop.general_idle_s,
vm_retry_s=config.tuning.build_vm.retry_s,
vm_settle_s=config.tuning.build_vm.settle_s,
# L10: the knowledge vault, when configured.
vault=(
Vault(config.vault.root, config.vault.folders, ignore=config.vault.ignore)
if config.vault
# L10: the knowledge vault, when configured; L6.4: the agent's
# memory, when its own folder in it is read-write.
vault=vault,
memory=(
Memory(vault, MEMORY_FOLDER)
if vault and vault.folders().get(MEMORY_FOLDER) == "rw"
else None
),
memory_turns=config.tuning.memory.max_turns,
)
return RunningLoop(
config=config,