--- /dev/null
+#!/bin/bash
+cd "${0%/*}"; if [ "$1" != "T" ]; then gnome-terminal -e "'$0' T"; exit; fi;
+
+cd ..
+
+# Function to export org to html using emacs in batch mode
+export_org_to_html() {
+ local org_file=$1
+ local dir=$(dirname "$org_file")
+ local base=$(basename "$org_file" .org)
+ (
+ cd "$dir" || return 1
+ local html_file="${base}.html"
+ if [ -f "$html_file" ]; then
+ rm -f "$html_file"
+ fi
+ echo "Exporting: $org_file → $dir/$html_file"
+ emacs --batch -l ~/.emacs --visit="${base}.org" --funcall=org-html-export-to-html --kill
+ if [ $? -eq 0 ]; then
+ echo "✓ Successfully exported $org_file"
+ else
+ echo "✗ Failed to export $org_file"
+ return 1
+ fi
+ )
+}
+
+export_org_files_to_html() {
+ echo "🔍 Searching for .org files in doc/ ..."
+ echo "======================================="
+
+ mapfile -t ORG_FILES < <(find doc -type f -name "*.org" | sort)
+
+ if [ ${#ORG_FILES[@]} -eq 0 ]; then
+ echo "❌ No .org files found!"
+ return 1
+ fi
+
+ echo "Found ${#ORG_FILES[@]} .org file(s):"
+ printf '%s\n' "${ORG_FILES[@]}"
+ echo "======================================="
+
+ SUCCESS_COUNT=0
+ FAILED_COUNT=0
+
+ for org_file in "${ORG_FILES[@]}"; do
+ export_org_to_html "$org_file"
+ if [ $? -eq 0 ]; then
+ ((SUCCESS_COUNT++))
+ else
+ ((FAILED_COUNT++))
+ fi
+ done
+
+ echo "======================================="
+ echo "📊 SUMMARY:"
+ echo " ✓ Successful: $SUCCESS_COUNT"
+ echo " ✗ Failed: $FAILED_COUNT"
+ echo " Total: $((SUCCESS_COUNT + FAILED_COUNT))"
+ echo ""
+}
+
+# Publish Emacs org-mode files into HTML format
+export_org_files_to_html
+
+# Upload assembled documentation to server
+SERVER_DIR="n0@www3.svjatoslav.eu:/mnt/big/projects/retinue/"
+
+echo "📤 Uploading to $SERVER_DIR ..."
+rsync -avz --delete -e 'ssh -p 10006' doc/ "$SERVER_DIR"
+
+if [ $? -eq 0 ]; then
+ echo "✓ Upload completed successfully!"
+else
+ echo "✗ Upload failed!"
+fi
+
+echo ""
+echo "Press ENTER to close this window."
+read
:ID: ee70e32d-0ead-4236-bbc2-9dc321dc6a92
:END:
#+SETUPFILE: ~/.emacs.d/org-styles/html/darksun.theme
-#+TITLE: Retinue — Native memory provider plugin for Hermes Agent
+#+TITLE: Retinue — Memory provider plugin for Hermes Agent
#+LANGUAGE: en
#+LATEX_HEADER: \usepackage[margin=1.0in]{geometry}
#+LATEX_HEADER: \usepackage{parskip}
:ID: a22b19b1-bc50-4368-a0c0-ae349f732df1
:END:
-Retinue is a native *Hermes Agent memory provider plugin* that adds
+[[file:logo.png]]
+
+*Retinue* is a [[https://hermes-agent.nousresearch.com/][Hermes Agent]] memory provider plugin that adds
persistent, semantic memory to every Hermes session. Once installed
and configured, it becomes Hermes' external memory backend.
+Note: While Hermes already has multiple built-in memory systems, I did
+not find a solution that:
+- Runs fully locally, and
+- Offers semantic memory retrieval (find memories by meaning, not by the
+ exact keyword used), and
+- Is lightweight (runs fast using CPU-only compute, with no need for a
+ GPU)
+
It is built on =model2vec= static embeddings and =sqlite-vec=, so it
runs offline, requires no server, and stores everything in a single
SQLite database.
:ID: d77ed683-4da0-4cf1-84ee-73544b93f28b
:END:
+This section explains in more detail how this plugin works, in case
+you are a software developer and want to troubleshoot or improve it.
+
+*This program is free software: released under Creative Commons Zero
+(CC0) license*
+
+*Program author:*
+- Svjatoslav Agejenko
+- Homepage: https://svjatoslav.eu
+- Email: mailto://svjatoslav@svjatoslav.eu
+- See also: [[https://www.svjatoslav.eu/projects/][Other software projects hosted at svjatoslav.eu]]
+
+*Getting the source code:*
+- [[https://www2.svjatoslav.eu/gitweb/?p=retinue.git;a=snapshot;h=HEAD;sf=tgz][Download latest source code snapshot in TAR GZ format]]
+- [[https://www2.svjatoslav.eu/gitweb/?p=retinue.git;a=summary][Browse Git repository online]]
+- Clone Git repository using command:
+ : git clone https://www3.svjatoslav.eu/git/retinue.git
+
+
** Architecture
:PROPERTIES:
:CUSTOM_ID: architecture
*"memories" virtual table:*
-| Column | Type | Meaning |
-|-------------+-------------------+------------------------------------------------------------------|
-| =rowid= | INTEGER | Auto-increment primary key. Stable ID used for delete. |
-| =embedding= | float[MODEL_DIM] | The model2vec embedding vector for =content=. |
-| =content= | TEXT | The full text of the memory/fact. |
-| =created= | TEXT | ISO 8601 UTC timestamp when the row was inserted. |
+| Column | Type | Meaning |
+|-------------+------------------+----------------------------------------------------------|
+| =rowid= | INTEGER | Auto-increment primary key. Stable ID used for deletion. |
+| =embedding= | float[MODEL_DIM] | The model2vec embedding vector for =content=. |
+| =content= | TEXT | The full text of the memory/fact. |
+| =created= | TEXT | ISO 8601 UTC timestamp when the row was inserted. |
=MODEL_DIM= depends on the model (hardcoded to
=minishlab/potion-multilingual-128M=). The table is created with
| =sync_turn(user, assistant, *, session_id="", messages=None)= | Persist a completed turn (must be non-blocking) |
| =on_session_end(messages)= | Flush/extract at conversation end |
| =on_pre_compress(messages) -> str= | Capture insights before context compression |
-| =on_memory_write(action, target, content, metadata=None)= | Mirror built-in =memory= writes to the provider |
+| =on_memory_write(action, target, content, metadata=None)= | Mirror built-in =memory= writes to the provider |
| =on_delegation(task, result, **kwargs)= | Observe subagent work from the parent |
-| =shutdown()= | Clean up connections/threads |
+| =shutdown()= | Clean up connections/threads |
| =backup_paths() -> list[str]= | Extra on-disk paths outside =HERMES_HOME= for =hermes backup= |
*** Memory save
| Path | Trigger | What the provider receives |
|----------------------+---------------------------------------------+------------------------------------------------------|
| Provider tools | LLM calls one of =get_tool_schemas()= tools | Tool name + structured arguments |
-| Built-in memory tool | LLM calls =memory= | =on_memory_write(action, target, content, metadata)= |
+| Built-in memory tool | LLM calls =memory= | =on_memory_write(action, target, content, metadata)= |
| Turn sync | Hermes after every completed turn | =sync_turn(user, assistant, session_id, messages)= |
*** Memory retrieval
#+end_src
This uses a project-local =.venv= and caches downloaded models in
-=.hf-cache=, both of which are excluded from deployment by =install.sh=.
\ No newline at end of file
+=.hf-cache=, both of which are excluded from deployment by =install.sh=.