Skip to main content

In-memory working-memory graph CLI for LLM agents (goldfish brain scratch space)

Project description

MemNet

Pure in-memory working-memory graph for LLM "goldfish brains" — structured state an agent writes once and re-reads each turn because the model forgets.

MemNet is scratch memory for the current task, not a durable knowledge base or vector store. Sessions live in RAM, expire by TTL, and disappear on session close. There is no automatic disk state; persistence is explicit and user-controlled via session save / session load.

The problem it solves

LLMs lose track of entities, state, and rules between tool calls. MemNet gives the agent a small, typed, atomised knowledge graph it can:

  • atomise state into many small @TAG: rows and @EDG links (one idea per row — the most important discipline),
  • add facts, tasks, and relations once; update them when state changes,
  • pull back only the live slice on the next turn (query warm --anchor),
  • settle or expire missions so they stop polluting the prompt,
  • keep hard limits and produce machine-readable warnings instead of silent bloat.

The pipe wire format is intentionally token-efficient: warm reads inject a connected subgraph, not JSON dumps or prose blobs.

Installation

pip install memnet-llm

From source (development):

pip install -e ".[dev]"

The CLI command is still memnet. PyPI package name is memnet-llm (the name memnet on PyPI is a different project — memristive neural networks).

Requires Python ≥ 3.11.

Quick start

You need two terminals. One runs the in-memory server that holds the graph; the other runs the CLI client.

Terminal 1 (server):

memnet serve
# prints: MEMNET_SERVE=127.0.0.1:18765

Terminal 2 (client):

# See the cheat sheet
memnet guide --loose

# Start a session with the bundled schema
memnet session open --map-file src/memnet/examples/schema.example.txt
# stderr also prints: MEMNET_SESSION=mn_xxxxxxxx
$env:MEMNET_SESSION = "mn_xxxxxxxx"

# Ingest a small world (LAW rules + world state + missions)
memnet add --file src/memnet/examples/workflow.example.txt

# Preferred read for the next LLM turn: only live mission state
memnet query warm --anchor PLR01

# When done
memnet session close $env:MEMNET_SESSION

Without memnet serve running, any stateful command returns @ERR: serve_required.

For one-off scripting or tests you can set MEMNET_TEST_INLINE=1 to run in-process (no server), but this is not the normal multi-turn agent mode.

LLM agents: read LLM-GUIDE.md (in this repo) for the full agent playbook, the goldfish loop, settlement pattern, and disciplines. It is written to be consumed by models.

Atomisation (required)

MemNet is a knowledge graph, not a document store. Atomisation — breaking state into many small nodes and explicit @EDG edges — is the discipline that makes query warm token-efficient.

Do Don't
One fact / entity / task per @TAG: row Paragraphs or merged facts in one field
Wire relations with @EDG "A helps B and also C" in a single row
Short fields: ids, codes, keys, paths Prose, markdown, full file contents
Batch many lines in one add --stdin One giant row instead of many atoms
# Good — three atoms + one edge
memnet add --stdin @"
@TSK: T01|Clear warehouse|1|in_progress|persistent
@NPC: N03|helper|labour|1|0|0|active|persistent
@EDG: E01|N03|helps|T01|labour|persistent
"@

See LLM-GUIDE.md for the full agent playbook. Application notes (novel, SysML, MUD) show domain-specific tag maps — all use the same atomisation rule.

The goldfish loop (recommended pattern)

A typical agent turn:

  1. add new rows or update existing ones — atomised @TAG: lines (batch via --stdin or --file is best).
  2. query warm --anchor <focus> — returns only active (non-recyclable) rows, always includes LAW.
  3. Paste the wire lines into the prompt, reason, decide on next adds/updates or a mission settle.
  4. On mission complete: update the TSK (or equivalent) with both status=settled and recycle=delete_on_settle. Mission edges usually use delete_on_expire or delete_on_settle.
  5. Optionally housekeep prune stale --apply to physically remove settled rows.
  6. Next turn starts again at step 1 with a (usually new) anchor.

query context (cold) returns everything and emits @WRN: stale_in_store|… on stderr when recyclable rows exist. Prefer warm.

Wire format

Token-efficient pipe rows — one graph atom per line (pair with atomisation above):

@TAG: field|field|...
  • One record = one idea — split compound state into more rows + @EDG, not longer fields.
  • Pipe inside a value must be escaped: note\|extra (or \\| in some shells).
  • Always quote the whole line in PowerShell or bash when it contains special characters.
  • Reserved output tags: @SESSION, @ERR, @WRN, @STAT, @REL, @DEL.
  • Errors and advisories go to stderr; data rows to stdout.

Example multi-line ingest (PowerShell):

memnet add --stdin @"
@NPC: N01|Shen Tiexin|female(12)|0|traditional|80|active|persistent
@EDG: E01|N01|seeks_help|PLR01|unlock|delete_on_expire
"@

memnet update --stdin @"
@NPC: N01|Shen Tiexin|female(12)|0|traditional|90|active|persistent
"@

See memnet guide, memnet examples map, and memnet tagmap fields --tag <TAG> for the current schema.

Commands

Run any command with --help for full flags.

Session lifecycle

Command Purpose
session open --map-file Create a new session (prints @SESSION: and MEMNET_SESSION=... on stderr)
session resume <id> Attach to an existing session
session current Show the id from $env:MEMNET_SESSION (or "none")
session list List live sessions (id, expires, minutes left, last modified)
session save --file Optional export of the current graph to a user-chosen snapshot file (wire format)
session load --file Restore a snapshot into RAM (new session id by default; --keep-id to reuse)
session close <id> Destroy the session (graph is gone)

Default TTL is 60 minutes (MEMNET_SESSION_TTL_MINUTES or --ttl).

Add, update & delete

  • add [line] [--file PATH] [--stdin] [--dry-run] [--allow-new-relation] [--agent NAME] [--session]
    • Create new rows only. Fails with id_exists if the id is already in the graph.
  • update [line] [--file PATH] [--stdin] [--dry-run] [--allow-new-relation] [--agent NAME] [--session]
    • Replace existing rows only. Fails with not_found if the id is missing (catches update typos).
  • Batch via --stdin or --file is strongly preferred. --dry-run parses without mutating.
  • delete --id ID

Query (graph reads)

  • query warm --anchor ID [--depth N] [--max-rows M]the normal read for agents. active_only is forced; anchor is required. LAW rows are always included.
  • query context [--anchor] [--depth] [--max-rows] [--active-only] — cold/full view (use for audit; warns on stale rows).
  • query neighbors <id> [--depth]
  • query path <src> <dst>

Direct reads

  • read list [--tag T] [--active-only] [--where field=value ...]
  • read get --id ID [--tag T]

--where filters by field value (exact match). Repeat for AND. Use * or ? wildcards for glob match (e.g. --where name=*Tiexin*).

Housekeeping

  • housekeep stats@STAT rows + caps for rows/edges/relations/orphans/dangling/recyclable/modified.
  • housekeep stale|orphans|dangling|recyclable — list the respective sets.
  • housekeep prune stale|... --apply — actually delete (emits @DEL lines and a summary on stderr).

stale = recyclable + dangling + orphans.

Schema & relations

  • tagmap fields [--tag T] / map fields — reference field lists.
  • tagmap show / map show — current session's effective tag map.
  • relations list — allowed EDG relation names for this session.
  • New relations are rejected unless add or update uses --allow-new-relation (subject to max_relations).

Examples & server

  • examples map|workflow|add <tag>|path
  • serve [--host] [--port] — the in-memory graph host. Required for normal CLI use across processes.
  • version, guide, guide --loose

Session model & optional snapshots

  • One session open per task. Agents should resume rather than open duplicates.
  • The graph is RAM only while the session is live.
  • session save --file my.snap writes a plain-text wire-format snapshot that you own. session load --file my.snap brings it back into a (usually new) RAM session.
  • On close or TTL expiry the session is dropped from the server; no server-side files remain.
  • Snapshots are a user convenience, not MemNet's durability layer.

Housekeeping, warnings, and signals

On every stateful command the server emits advisory @WRN lines on stderr (capped per call):

  • near_cap*, ttl_expiring
  • stale_in_store, stale_dangling, stale_orphans, stale_graph
  • mission_settled
  • fanout_clamped, dangling_endpoint, etc.

@STAT lines report counts vs caps. @DEL lines are emitted after successful prune --apply or delete.

Environment variables

Variable Effect
MEMNET_SESSION Default session id when --session is omitted
MEMNET_SESSION_TTL_MINUTES Default TTL for new sessions (1..1440)
MEMNET_AGENT Default agent name stamped on written records
MEMNET_SERVE_HOST, MEMNET_SERVE_PORT Bind address for memnet serve (client discovery is implicit via the same vars)
MEMNET_MAX_ROWS / MAX_LAW / MAX_RELATIONS / ... Hard caps (see Caps in config)
MEMNET_TEST_INLINE When set, CLI runs in-process (tests, one-off scripts). Not for normal agent use.

All caps have MEMNET_MAX_* names; see source for the full list and defaults.

Architecture (one minute)

  • tagMap — merged fixed + user schema loaded at session open. Drives parsing and field order on output.
  • memStore — in-memory nodes + directed edges (EDG). Write-order index, simple BFS for neighbours / paths / warm packs.
  • LAW rows — special, usually exempt from orphan/dangling accounting and always surface in warm reads.
  • recycle field — persistent (default for active world) vs delete_on_settle / delete_on_expire (missions). query warm hides the latter.
  • Server holds a registry of live SessionEntrys. CLI is a stateless client that talks over localhost TCP (or in-process in tests).

No JSON on the wire for LLM consumption — only the @TAG: lines plus a handful of control records on stderr.

Application notes

Seven self-contained worked examples live under application-notes/ — each shows a complete MemNet pattern (schema, seed, 6-step loop, domain LAW rows). Ordered by typical adoption path, not release date.

# Note Pattern
1 llm-software-development.md Multi-turn coding in Cursor@MOD/@SYM/@TSK/@USR/@DEC, verified locators, v0.2.12 session_load/session_save retrospective; complements grep/LSP/git and Cursor codebase indexing
2 llm-daily-news.md Batch RSS digest (~100 articles/day) — run-scoped working memory (120-min TTL), @KYWD hub salience, @CLU/@SYN layers, Python bridge via send_command
3 llm-tech-docs-decomposition.md Instrument manual / SCPI remote mode — R&S RTO rev 29, 4 584 @CMD, procedure layers with precedes/requires, two driver turns; scripts/extract_rto_scpi.py
4 llm-sysml-v2-modeling.md SysML v2 textual modeling — 6U CubeSat PDU, @PKG cross-file refs, allocations/ports/traceability from rows, runtime behaviour budgeting
5 llm-novel-writer.md Interactive novel / RPG — 6-step read → context → user-input-as-data → analyse → update → loop; @LORE/@SCN/@STEP, chapter merge
6 llm-mud.md Multiplayer text MUD — server-side world agent + client prose agents, Alice in Wonderland sample; tiered atomisation, scripts/load_test_mud.py
7 llm-build-on-memnet.md Builder guide — author your own MCP server (FastMCP + run_memnet bridge, JSON envelope, LAW supplementation) and Cursor skill pack (SKILL.md frontmatter, references/ split, mcp.json registration); worked example = mcp-memnet skill + novel-mcp application split

Supplement: novel-initial-state.md — bootstrap rows for the novel writer MCP pipeline.

Development

.\scripts\dev.ps1          # setup / test / lint / fmt / cli
pytest

Tests run with MEMNET_TEST_INLINE=1 so they do not require a separate serve process.

MCP (optional)

Install the MCP adapter:

pip install memnet-llm[mcp]

Prerequisites: memnet serve running in another terminal (same as normal multi-command CLI use).

# Terminal 1
memnet serve

# Terminal 2 — stdio MCP server for Cursor / other hosts
memnet-mcp

Set MEMNET_SESSION to your open session id. Example Cursor MCP config:

{
  "mcpServers": {
    "memnet": {
      "command": "memnet-mcp",
      "env": {
        "MEMNET_SESSION": "mn_your_session_id"
      }
    }
  }
}

Tools (v1): serve_status, session_open, session_current, query_warm, add, update, read_get, housekeep_stats. Each returns a JSON envelope with stdout / stderr wire lines, exit_code, session_id, and errors[] (from @ERR: lines). session_open auto-seeds LAW01–LAW05 on every new session (prepended on each query_warm); optional seed_lines adds @CFG anchors and domain @LAW rows in the same call. See LLM-GUIDE.md.

Licence

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memnet_llm-0.2.17.tar.gz (146.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memnet_llm-0.2.17-py3-none-any.whl (151.5 kB view details)

Uploaded Python 3

File details

Details for the file memnet_llm-0.2.17.tar.gz.

File metadata

  • Download URL: memnet_llm-0.2.17.tar.gz
  • Upload date:
  • Size: 146.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for memnet_llm-0.2.17.tar.gz
Algorithm Hash digest
SHA256 29f7ee5cdb2cafd90291fc8a7c5539f09be06c667c28e923598400d81a4c18f0
MD5 c62b8df3d734e98827703c45c6f98d1f
BLAKE2b-256 090939e4d5b89195edd88df88a69b6e4d111dc245c6e082b540ca55f36f4563b

See more details on using hashes here.

File details

Details for the file memnet_llm-0.2.17-py3-none-any.whl.

File metadata

  • Download URL: memnet_llm-0.2.17-py3-none-any.whl
  • Upload date:
  • Size: 151.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for memnet_llm-0.2.17-py3-none-any.whl
Algorithm Hash digest
SHA256 2d80b9cefcb112b1480f5ab96b422b43e39ca1a304db6b5b3a9c7bea6192ca9a
MD5 2bf0951a5bcf2c5d146bfd866de9f243
BLAKE2b-256 fecf86ca00536050283a33f904cb9accc68f725a5a43d91a9dcee094904bc0ec

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page