The Problem Agents that need long‑term or short‑term memory usually rely on cloud‑hosted vector stores or heavyweight frameworks. That adds latency, cost, and data‑privacy concerns for on‑premise or edge deployments.
What This Does LocalRecall implements a pure‑Go REST API that stores documents and their embeddings in a local vector database (Chromem) or a PostgreSQL instance with pgvector. The core of the service lives in the rag/ package; rag/persistency.go (32 functions) handles DB/file I/O, while pkg/client/client.go (10 functions) exposes the API to callers. A lightweight Web UI (static/index.html + static/js/collectionManager.js) lets users upload Markdown, plain‑text, or PDF files. The project ships with Docker support (Dockerfile, docker-compose.yml) for containerised runs and a Makefile for local builds.
How It Is Wired
Entry point – main.go (main at line 95) starts the HTTP server via startAPI.
API wiring – startAPI registers routes (registerAPIRoutes) defined in routes.go. The most used handler is RegisterCollection, which calls updateSource in rag/source_manager.go and ultimately writes files (os.WriteFile).
Persistence – rag/persistency.go provides NewPersistentCollectionKB, Search, and related helpers. It is invoked by the collection factory in rag/collection.go (NewPersistentChromeCollection, NewPersistentPostgresCollection).
Database engines –
- Chromem engine (
rag/engine/chromem.go) implementsCount,Reset,GetEmbeddingDimensions, and the coreembeddingfunction. - Postgres engine (
rag/engine/postgres.go) suppliesNewPostgresDBCollection, connection helpers (execNoStatementTimeout,applyConnTimeouts), and vector index creation.
External interactions –
- Model inference is called through
openai.DefaultConfig(traced frommain → startAPI). - Filesystem writes occur in
rag/source_manager.go → updateSource. - Network calls happen inside the client (
pkg/client/client.go) when it talks to the underlying vector store or model endpoint.
Hot‑spot functions – findEntryKey (called 6 times) and NewPersistentCollectionKB (5 callers) are the most widely referenced; changes here have the broadest impact. The internal call graph shows 180 intra‑repo edges, with StoreOrReplace → Count executed four times, indicating the store‑replace path is a frequent mutation point.
How To Use It
# Clone the repository
git clone https://github.com/moses-y/LocalRecall
cd LocalRecall
# Build a native binary
go build -o localrecall
# Run the server (default ports 8080/8081)
./localrecall
Docker – the Dockerfile builds a Go 1.26 image. A typical run (mirroring the README) is:
docker build -t localrecall .
docker run -ti -v $(pwd)/state:/state \
-e COLLECTION_DB_PATH=/state/db \
-e EMBEDDING_MODEL=granite-embedding-107m-multilingual \
-e FILE_ASSETS=/state/assets \
localrecall
The UI becomes reachable at http://localhost:8080. No additional configuration files are required; environment variables control DB path and embedding model as shown above.
Real‑World Use A chatbot running on an edge device can start localrecall locally, ingest the latest logs or user transcripts via the UI, and query the /search endpoint to retrieve relevant context. Because the vector store lives on the same host, latency stays sub‑second and no external API keys are needed.
Code Health & Issues
- Critical – pinned dependencies with known CVEs (
golang.org/x/crypto@0.50.0,github.com/jackc/pgx/v5@5.8.0). Upgrade to fixed versions. - High – GitHub Actions use mutable tags (
docker/setup-qemu-action@masteretc.). Pin to commit SHAs. - High – additional vulnerable Go modules (
github.com/go-git/go-billy/v5@5.6.2,github.com/go-git/go-git/v5@5.16.0). Upgrade. - Medium – missing least‑privilege
GITHUB_TOKENpermissions in CI. - Medium – no Dependabot/Renovate configuration; add
.github/dependabot.yml. - Medium – Docker base image (
golang:1.26) is not pinned by digest. Usegolang@sha256:<digest>. - Medium – CI lacks a dependency‑vulnerability gate. Add
dependency-review-actionorosv-scanner. - Medium –
actions/checkoutpersists the token; setpersist-credentials: false. - Medium – container runs as root; create a non‑root user in the Dockerfile.
- Low – workflow jobs have no
timeout-minutes; set appropriate limits.
Additional static findings: duplicated test helpers across multiple *_test.go files, deep nesting (up to 6 levels) in several test and source files, and oversized modules (rag/engine/postgres.go, rag/persistency.go) that would benefit from refactoring.
The Bottom Line LocalRecall delivers a functional, container‑ready local vector store with a simple REST API and UI, suitable for on‑premise AI agents. The codebase is mostly healthy but contains critical dependency vulnerabilities and several CI hygiene gaps that must be addressed before production use. Teams comfortable with Go and Docker can adopt it quickly, provided they patch the listed security issues.