Neuro Graph Memory

Graph-based Continual Learning Memory Engine

Architecture, Design & Development by Franz Ayestarán / Collaborative Pair Programming with GitHub Copilot in VS Code

Active Brain: aivillage.ngm

Neuro Graph Memory

Neuro Graph Memory is a Flask-based, graph-native continual memory workspace configured around the AIVillage world and its lore.

It models learning as connected experiences (paths), reinforces repeated links, decays weak memories over time, discovers memory regions, and supports recall + associative inference from a persistent .ngm brain file.


What Neuro Graph Memory is (and is not)

  • Is: a memory graph workspace for AIVillage, including its places, people, history, and stories.
  • Is not: an LLM chat model.

Everything is represented as concept paths drawn from AIVillage, for example:

  • AIVillage -> Oakwood -> Town Fountain
  • AIVillage -> Mount Anne -> 796m Climb
  • Oakwood -> Blake -> Village Quests

NGM → CLM: prototype to product

Continual Language Model (CLM) is the intended language-system product. Neuro Graph Memory (NGM) is prototyping its explicit, persistent memory foundation and may remain a component of that product, rather than a name to replace. NGM is not yet a complete CLM: language understanding, generation, and their integration with continual memory remain to be implemented and verified. Updating graph memory is not the same as training language-model weights.

The following is a working handoff list, not a settled CLM architecture. Revisit it as experiments establish which behaviours are useful:

Disposition NGM behaviours CLM direction
Inherit unchanged where validated Explicit, inspectable memory; learning new experiences without recreating the brain; reinforcement of repeated associations; persistent save/load. Preserve these memory behaviours, with regression tests demonstrating that language integration does not break them. This does not require preserving the current file format or implementation.
Redesign candidates Weight-only direct recall ranking and weight-driven spreading activation; heuristic text-to-path extraction. Evaluate context-aware retrieval and structured language-to-memory extraction. Do not treat association strength as factual confidence or an extracted path as a verified semantic relationship.
Prototype-only by default Hand-entered demo paths, artificial import-anchor stitching, and the current Flask/3D inspection workflow. Keep these as experiments and diagnostic tools unless evidence justifies a product role; do not make them requirements of the CLM architecture.
Evaluate before deciding Sleep/decay rules, dormant/forgotten states, and region consolidation. Test retention and retrieval effects before carrying the current heuristics into CLM unchanged.

Decision for the next workspace

Start the CLM in a clean workspace; use this repository as its behavioral reference, not as a codebase to copy wholesale. Carry forward these decisions:

  • CLM is the language system; NGM is a prototype of its explicit, persistent memory capability, not the CLM itself.
  • Keep learned knowledge separate from language-model weights in the first milestone. Learning new material should update persistent memory, not silently claim to train or update the language model.
  • Preserve inspectable memory, incremental learning, persistence across reloads, and retrieval of earlier as well as newly learned material as requirements to test.
  • Treat the graph/path memory as the initial memory baseline to evaluate, not a guaranteed final representation. Keep memory operations behind a replaceable interface so retrieval or storage can evolve without coupling them to the UI or language component.
  • Make the first end-to-end milestone small: add a piece of knowledge, ask a natural-language question about it, return an answer grounded in retrieved memory, restart/reload, and verify both the new knowledge and representative earlier knowledge remain retrievable. Include missing-evidence and ambiguous query cases; do not present association strength as factual confidence.
  • Bring forward NGM's tests and sample data only as fixtures and regression cases where they support that milestone. Reimplement or adapt the useful behavior deliberately rather than inheriting the current Flask app, 3D explorer, heuristic importer, artificial anchor, file format, or unvalidated decay/consolidation rules as CLM requirements.

The prototype has done its job when the handoff list is backed by measured results: retained behaviours pass regression tests, redesign candidates have evaluated replacements or documented limitations, and prototype-only shortcuts are not required for the product to work. End-to-end CLM evaluation should demonstrate that newly added knowledge persists across reloads, can be retrieved and used in language responses, and does not unacceptably degrade earlier knowledge. Success criteria and acceptable regression thresholds must be defined before claiming that outcome.


Core capabilities

1) Memory formation

  • Learns new experiences as paths.
  • Creates nodes/connections if missing.
  • Reinforces existing connections when paths repeat.
  • Tracks node activation and importance.

2) Memory maintenance (sleep)

  • Synaptic decay over time.
  • Node importance decay over time.
  • State transitions across active/inactive/dormant/forgotten.
  • Archives forgotten memories instead of hard-deleting.
  • Rebuilds and consolidates clusters (regions).

3) Recall and inference

  • Recall: strongest direct associations for a concept.
  • Think: spreading activation over multiple hops.
  • Recall supports exact matching with fuzzy assist suggestions.

4) Persistence

  • Save/load full brain state to .ngm.
  • The workspace's AIVillage brain is stored at brains/aivillage.ngm.

Tech stack

  • Python + Flask
  • NetworkX (graph model + region detection)
  • 3D Force Graph / Three.js (interactive 3D graph UI)
  • PyVis support in backend graph rendering paths

Project structure (key paths)


Quick start

Prerequisites

  • Python 3.10+ recommended
  • macOS/Linux shell (or equivalent environment)

Install

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Run

./launch.sh start

Open:

  • http://0.0.0.0:5025
  • http://localhost:5025

Stop / restart / status

./launch.sh stop
./launch.sh restart
./launch.sh status

Logs:

Reuse visit logging in another Flask app

See visitlog.md for installation, configuration, IP forwarding, and verification details.

Copy the visitlog/ package directory into the other project, then register the blueprint:

from visitlog import register_visitlog

register_visitlog(app)

Registration automatically forwards successful HTML GET page visits from Flask, using the original page request's Referer header. No browser tracking script is needed. Do not include visitlog.js in page templates: combining the legacy browser trigger with automatic server-side logging creates duplicate visits. API responses, static assets, downloads, redirects, errors, HEAD requests, and POST requests are not automatically logged.

By default, visit events are forwarded to http://127.0.0.1:5020/api/visit-trigger. Override the destination with app.config["VISITLOG_SERVICE_URL"]; set VISIT_TRIGGER_SECRET in the app configuration or environment to forward the optional shared secret. The client IP is taken from X-Forwarded-For using the configured trusted proxy count (default 1), then from X-Real-IP, and finally from the direct connection. Set VISITLOG_TRUSTED_PROXY_COUNT in app config or the environment to match the number of trusted proxies that append addresses to X-Forwarded-For. Configure those proxies to overwrite or correctly append forwarding headers; do not trust client-supplied forwarding headers when the app is directly internet-facing.


End-to-end usage guide

1) Dashboard

Page: /

Use it to:

  • View top-level memory stats:
  • active nodes/synapses
  • regions
  • experiences
  • dormant/forgotten counts
  • Run a memory maintenance cycle (Sleep).
  • Load the AIVillage brain.

On first startup, when no valid previous brain selection is saved, the app loads brains/aivillage.ngm if it is available. Later startups restore the saved selection. The active brain is shared by all visitors to the app.

2) Learn new experiences

Page: /learn

Enter a path (one concept per line or delimited flow), plus optional experience name and importance.

This writes directly into the active brain and reinforces graph structure.

3) Recall associations

Page: /recall

  • Query a concept.
  • Returns strongest direct neighbors ranked by synapse weight.
  • Supports exact/fuzzy-assist behavior for concept resolution.

Page: /think

  • Runs spreading activation from a concept.
  • Adjustable depth.
  • Returns indirectly related concepts ranked by propagated activation.

5) Manage experiences

Page: /experiences

  • Inspect recorded experiences.
  • Edit or delete experiences.
  • Uses rebuild-safe behavior to avoid orphaned graph artifacts.

AIVillage memory chat and before/after experiments

Page: /chat

  • Send a concept name or a message such as Tell me about Mount Anne.
  • The message input has a neutral placeholder, with no generated example prompts.
  • Fuzzy search is Off by default. Its On/Off selection persists across page refreshes using the existing browser page-state storage. When enabled, exact matches still take priority. Otherwise, chat removes common question prefixes (such as who is or tell me about) and compares the remaining text with active concept names. It requires at least three normalized characters and 80% text similarity; close competing matches are suggested rather than silently chosen. A fuzzy match is labelled explicitly. This is typo assistance, not semantic question understanding. Replays retain the original prompt's search mode; changing the selector applies to new prompts.
  • Chat produces deterministic, template-based responses from active graph experience paths mentioning the matched concept (including mentions within imported text fragments). Up to three distinct paths are shown, prioritizing fragments that start with the subject, then exact path concepts. Source paths are available under Source experience paths. These excerpts preserve stored context, not a generated semantic answer; conflicting memories are not resolved. Without relevant paths, chat falls back to associations. Direct weights and spreading-activation evidence remain visible. The default artificial text-import anchor is excluded from chat retrieval and traversal, preventing unrelated paths being connected through that anchor. Dormant, forgotten, or disconnected portions of experience paths are not quoted. Chat does not use an LLM, learn from messages, update access counters, or save memory.
  • Matching uses normalized concept names within the message, not semantic question understanding. When several names match, the longest is used (alphabetical tie-break); other mentioned names are displayed. Unknown names return an explicit no-match response with suggestions, not guessed facts.
  • Edit or learn memory in another page, then return and select Ask again / Compare on the original prompt. The original response stays fixed; the latest response appears alongside it with added/removed associations and changes to scores or ranks. A changed memory revision can still yield an unchanged response when the edit does not affect that query.
  • Saving a node rename with Graph → Save Node updates that concept in the active brain and its experience paths. A replay can therefore show the renamed text in Latest response and Source experience paths. This renames that graph node; it does not rewrite similar wording in separate text-fragment nodes.
  • Each replay uses the same prompt and inference depth but the currently active brain. Brain switches are labelled in the comparison. Edits must be loaded into the active brain to affect responses; editing a dataset alone does not update NGM memory.
  • Up to 20 original prompts and their latest comparisons are stored in browser-tab session storage, surviving navigation/reload but not tab closure. Clear history removes them. Prompts are independent, with no conversational context or pronoun resolution.

Association weights and activation scores are not factual confidence. This feature is an inspection experiment, not a complete CLM or a factual-answering system. The read-only JSON endpoint is POST /chat/respond with {"message": "Tell me about Mount Anne", "depth": 3, "fuzzy_search": false} (depth 1–8, message at most 1000 characters). Each response includes a SHA-256 memory revision for comparison.

Password-protected deletion

Every Delete button (experiences, regions, NGM brain files, and datasets) opens a confirmation dialog styled to match the app. Enter the password to delete, or use Cancel / Escape to leave the item unchanged. The eye icon toggles password visibility; each new prompt starts with the password hidden.

The server reads actions["agent.delete"]["password"] from passwords.json for each deletion. All four delete types require this password when that entry's enabled flag is true. Setting it to false disables password protection for deletion. Password changes take effect immediately without restarting. Missing, empty, or invalid configuration blocks deletion and displays an error, as does an incorrect password.

The configured password is never sent to the browser; entered passwords are not saved in page-state storage. Keep the configuration file private and use HTTPS when accessing the app over a network.

Password-protected editing

Edit/open-editor controls and saves, and graph Save Node, use the themed prompt with actions["agent.edit"]["password"] in passwords.json. Set this initially empty password to enable editing. Server checks also protect direct edit requests. See Password prompts for coverage and authorization lifetime. Opening the dataset editor and saving a dataset use separate authorization grants: actions["agent.dataset_save"]["password"] protects dataset saves, so granting editor access alone does not authorize a save. Saving an edited experience uses its own actions["agent.experience_save"]["password"] entry. Brain-file Rename uses the separate actions["agent.rename"]["password"] entry, and saving edited regions uses actions["agent.region_save"]["password"]. Creating a new NGM brain uses actions["agent.create"]["password"].

6) Manage regions (clusters)

Page: /regions

  • Inspect discovered regions.
  • Edit/delete region metadata safely.
  • Region changes trigger consistent rebuild behavior where applicable.

Dashboard maintenance password

The dashboard's Run brain.sleep() maintenance action uses actions["agent.sleep"] in passwords.json. When enabled is true, the button prompts for that entry's password and the server blocks unauthorized maintenance requests. Setting enabled to false skips the prompt. Changes take effect without restarting; missing or invalid settings block maintenance.

Learn password

The Learn page remains accessible. Its Learn Path submit button uses the separate actions["agent.learn"] entry in passwords.json. When enabled is true, the button prompts for the learn password, and the server protects learning submissions. Setting enabled to false skips the prompt.

7) 3D graph explorer

Page: /graph

Features:

  • Rotate/pan/zoom interactive 3D graph
  • Click node to open inspector
  • Node search (supports fuzzy matching)
  • Save edited node metadata (name/type/state/importance/activation)
  • Move view arrows
  • Reset View fits the node spheres to the available canvas with a small edge margin, preserving the current viewing angle and accounting for node size. It keeps the model fitted as the force layout settles or the canvas resizes; rotating, panning, zooming, moving the view, or focusing a node cancels this automatic fitting.
  • Export GLB with node spheres and connecting tubes. Export loads Three.js independently when the graph renderer does not expose it globally.
  • Strongest connection list for selected node
  • Built-in node color legend

Node color semantics:

  • Active: green
  • Inactive: gray
  • Dormant: amber
  • Forgotten: muted gray
  • Start Concept: purple (concept appears as first item in one or more experiences)

8) AIVillage brain file

Page: /files

The workspace uses brains/aivillage.ngm as its AIVillage memory. The page provides the controls for loading and managing the active brain file.

9) Dataset pipeline

Page: /datasets

The dataset workflow is intended for AIVillage source material and memory.

Export AIVillage memory → raw JSONL

  • Export graph memory to JSONL for downstream dataset workflows.
  • Supports min synapse weight + dormant/forgotten inclusion toggles.

Build training dataset v1

Produces:

  • *.raw.jsonl
  • *.tasks.jsonl
  • *.manifest.json

Manifest viewer is built in for split/task diagnostics.

Password scope:

  • actions["agent.export_dataset"] controls Export Dataset
  • actions["agent.build_training_v1"] controls Build Training Dataset v1
  • actions["agent.export"] controls Export GLB

Import AIVillage text → memory (TXT only)

Current import constraints:

  • Input must be .txt
  • Heuristic path extraction is used
  • Anchor stitching is applied to reduce disconnected components

Importance controls:

  • source or auto strategy
  • Importance sensitivity slider (0–100)
  • Presets:
  • Conservative
  • Balanced
  • Aggressive
  • Custom

Import UX:

  • Upload progress bar
  • Cancel import button
  • Inline success/error feedback

10) Inline dataset editor

Pages:

  • selector: /datasets/edit
  • editor: /datasets/edit/<filename>

Editor capabilities for JSONL datasets:

  • save
  • validate JSONL
  • data quality analysis
  • strict Q&A transformation
  • strict sentence transformation
  • conversion outputs (qa, sentence, tinyllama)
  • training consumption preview
  • line navigation + undo/redo + formatting helpers

.ngm memory model summary

Brains persist:

  • nodes
  • synapses
  • regions
  • experiences
  • dormant memories
  • forgotten memories

State lifecycle is designed around:

active -> inactive -> dormant -> forgotten

Forgotten memories are archived, not immediately erased.


Programmatic API (engine-level)

The brain engine supports:

  • brain.learn(path, experience_name, importance)
  • brain.sleep()
  • brain.recall(concept)
  • brain.think(concept, depth)
  • brain.save(path)
  • brain.load(path)

Implementation references:


Optional: seed starter brains

python seed_brains.py

This seeds included starter domains (if available) for immediate exploration.


Troubleshooting

  • If the app does not start, check:
  • logs/neurograph.log
  • .venv dependencies installed
  • If dataset import fails:
  • confirm file extension is .txt
  • inspect import feedback on /datasets (it reports parse/import outcomes)
  • If a brain file seems locked in workflow:
  • ensure it is not currently the active brain before deleting/renaming operations that require non-active status

Notes on reasoning quality

Recall and spread inference are currently weight-driven (synapse-centric).
Node importance still matters for lifecycle and visualization, but ranking behavior is dominated by edge weights and reinforcement history.

Confirm deletion

Enter the configured delete password to continue.