Skip to content

# Nexa — Neural Nexus for Information & Automation

Repo: `https://git.nuclide.systems/fkrebs/nexa`
Stack location: CT104 `/opt/stacks/nexa/`
Status: Designed, partially implemented — Phase 1 workflows exist; not yet deployed end-to-end.

## Synopsis

Nexa is a personal AI middleware layer that sits between input sources and organisation tools. It is not a new app — it is a set of wired-together workflows running on top of services already deployed in nuclide.systems.

Mental model: - Memos = mouth and ear (voice interface, reply surface) - n8n = reflexes (workflow logic, classification, routing) - LiteLLM / SAIA = brain (language model gateway) - Qdrant = long-term memory (semantic recall) - Nextcloud = hands (tasks, calendar, files, mail)

The user types (or speaks) into Memos. A Memos webhook fires an n8n workflow. n8n classifies the input (Work vs. Personal, command vs. capture), calls LiteLLM for any reasoning, stores embeddings in Qdrant, and writes back a comment on the original memo. Side effects — task creation, calendar blocks, archive entries — go to Nextcloud.

### What Nexa is not

- A replacement for specialist UIs (Arcane, Dozzle, Grafana).
- An active document editor.
- A work-IT bridge (work mail/servers remain out of scope).

### Core goals

1. Cognitive offload — sort, filter, propose; don't just store.
2. Context separation — clean Work vs. Personal split enforced by LLM classification.
3. Single interaction point — Memos is the only interface the user must open.
4. Knowledge synergy — link ephemeral memos to deep Obsidian notes via semantic search.

## How Nexa maps to nuclide.systems

Every component Nexa depends on is already deployed. Nothing new needs to be provisioned for Phase 1–2.

Nexa concept | nuclide.systems service | Host | URL/port
--- | --- | --- | ---
Interface / voice | Memos | CT104 | `https://memos.nuclide.systems`
Workflow engine | n8n | CT104 | `http://192.168.1.40:15678`
LLM gateway (SAIA) | LiteLLM | CT104 | `https://ai.nuclide.systems` (internal :4000)
Vector memory | Qdrant (`qdrant_scientific`) | CT104 | internal :6333
File / task / calendar | Nextcloud | CT105 | `https://nc.nuclide.systems`
Link curation | Karakeep | CT104 | `https://hoarder.nuclide.systems`
Push alerts | ntfy | CT104 | `https://ntfy.nuclide.systems`
Note vault | Obsidian (via Nextcloud WebDAV) | CT105 | `nc.nuclide.systems/Notizen/`
Auth / SSO | Pocket-ID | CT110 | `https://id.nuclide.systems`
Reverse proxy | Zoraxy | CT108 | all `*.nuclide.systems`
Push notifications (alerts) | Gotify | CT104 | internal :10003
Social feed | Bluesky | external | API only
Mail | Nextcloud Mail (`fkrebs@nucli.de`) | CT105 | IMAP via NC
Web fetch (Phase 2.4) | crawl4ai MCP | CT104 | via MCP gateway
Search (Phase 2.4) | SearXNG (if deployed) | CT104 | internal

### What is genuinely missing

Missing component | Phase needed | Notes
--- | --- | ---
TEI (text-embeddings-inference) | Phase 3.1 | Self-hosted embeddings for Qdrant ingest. `bge-m3` model, CPU-only, ~1.1 GB RAM. Deploy as `nexa-embed` container on CT104.
Ontotext GraphDB | Phase 3.4 | SPARQL structural memory. Deferred until Phase 3.1–3.3 ship. Needs ~4 GB heap on CT104.
`nexa_knowledge_text` Qdrant collection | Phase 3.1 | One `curl -X PUT` against the existing `qdrant_scientific` instance.
n8n workflow import | Phase 1 | JSON exports are in `nexa-core/n8n-workflows/`. Import via n8n API or UI.
Memos → n8n webhook | Phase 1 | One URL field in Memos admin: `https://n8n.nuclide.systems/webhook/memos`.
LiteLLM virtual key for Nexa | Phase 1 | Create `nexa` user in LiteLLM admin, issue key scoped to one chat model.
SearXNG (optional) | Phase 2.4 | Web-search for `#nexa:ask --web`. Not deployed yet.
infinity (Phase 3.2 upgrade) | Phase 3.2 | Replaces TEI to add CLIP-family visual embeddings (`jina-clip-v2`).
`nexa_knowledge_visual` collection | Phase 3.2 | Second Qdrant collection for image embeddings. Schema already defined in repo.

## Phased roadmap (mapped to infrastructure)

### Phase 1 — The Spine (no new containers)

Wire existing services together. All components are already running.

1. Import `nexa-core/n8n-workflows/phase-1/` into n8n at `http://192.168.1.40:15678`.
2. Set Memos webhook URL → `https://n8n.nuclide.systems/webhook/memos`.
3. Create LiteLLM virtual key for `nexa` user (chat model only — no embeddings yet).
4. Fill `nexa-core/.env` with `MEMOS_API_KEY`, `SAIA_API_KEY`, `NC_APP_PASSWORD`, `QDRANT_API_KEY`.
5. Import `phase-2/2_1_email_butler.json` and attach Nextcloud Mail credentials in n8n.
6. Fire `#nexa:config` in Memos → confirms Nextcloud lists, calendar IDs, mail folder structure.

Milestone: Memos comment-back works. Work vs. Personal classification active. Email butler running.

### Phase 2 — Senses (SearXNG optional)

- 2.1 Email butler — already has an n8n workflow JSON. Needs credentials in n8n.
- 2.2 RSS digest — new n8n workflow polling feeds → daily summary memo.
- 2.3 Bluesky antenna — liked posts → `nexa_knowledge_text` entries once Qdrant collection exists.
- 2.4 Web fetch — `#nexa:ask --web`: SearXNG + `crawl4ai` MCP (already deployed via MCP gateway) + markitdown.
- SearXNG not yet deployed on CT104. Deploy if 2.4 is needed.

Milestone: Nexa reads the web, Bluesky, and daily RSS. Morning digest appears in Memos.

### Phase 3 — Memory (two new containers; rest is curl commands)

- 3.1 TEI + Qdrant collection — deploy `nexa-embed` container (CT104), create `nexa_knowledge_text`, wire TEI into LiteLLM as `nexa-embed` model, add Qdrant ingest step to n8n workflows.
- Storage: `/mnt/pve/unas/services/nexa/tei-cache` (NFS already mounted on CT104).
- 3.2 Visual collection — swap TEI → `infinity`, add `jina-clip-v2`, create `nexa_knowledge_visual`. Backfill image queue from GraphDB.
- 3.3 S3 archive — Qdrant snapshots to `s3.nuclide.systems` (Garage). Blocked on Q12/Q20 decision.
- 3.4 Ontotext GraphDB — SPARQL pillar. One new container on CT104, `GDB_JAVA_OPTS: -Xmx4g`. SPARQL Workbench optionally via Zoraxy → `graph.nuclide.systems`.

Milestone: `#nexa:ask` returns answers grounded in Obsidian notes, archived memos, mail threads.

### Phase 4 — Motor (no new infrastructure)

- Bidirectional NC Tasks sync (Memos checkboxes ↔ Nextcloud Tasks lists).
- Time-boxing agent: calendar-aware gap-finder in NC Calendar → proposes focus slots.
- Karakeep curation: scheduled review workflow flags stale saved links.

Milestone: Memos `- [ ]` items automatically appear in the right NC Tasks list.

### Phase 5 — Daily Integration (HA Voice only new piece)

- 5.1 HA Voice — Wyoming protocol bridge from HAOS (VM 100) to Nexa n8n endpoint. Needs Wyoming server container (small) or HA add-on.
- 5.2 System monitoring — Proxmox + Backrest alerts → ntfy → Memos system feed. Homelab watchdog already posts to Gotify; route a copy to Memos via n8n.
- 5.3 Morning digest — daily 07:00 n8n cron: mail summary + tasks + drift report + one open question from `docs/11`.

Milestone: Nexa speaks. Morning context summary lands in Memos without user action.

### Phase 6 — Homelab Steward (uses existing Arcane + Proxmox APIs)

- 6.1 Inventory sync — n8n polls Arcane API + Proxmox API + `docker ps` on a schedule → snapshot stored in GraphDB.
- 6.2 Drift detection — diff snapshot against documented desired state in `docs/` → Memos `[STEWARD]` comment.
- 6.3 Steward commands — `#nexa:retire <svc>`, `#nexa:document <svc>`, `#nexa:wishlist-status`.
- 6.4 Docs self-update — Nexa proposes `docs/11` diffs as PRs when the user answers open questions via Memos.

Milestone: Nexa replaces the manual "what's stale?" audit. The homelab docs update themselves.

## Tool realization: what's not deployed yet and the options

The docs are designed around a specific tool set, but several pieces have alternatives worth considering given the current nuclide.systems stack:

### Embeddings (Phase 3.1)

The plan calls for TEI + `bge-m3`. Alternatives:

Option | Pros | Cons
--- | --- | ---
TEI + bge-m3 (plan) | Lightest (~500 MB image, ~1.1 GB RAM), OpenAI-compatible, single model, no LLM runtime | CPU-only (fine for the workload)
Ollama (already on CT104?) | Already deployed if running | Heavier image, slower cold start, designed for chat not embedding throughput
LiteLLM pass-through to Claude | No new container | 10 req/min rate limit — unusable for Qdrant ingest (2k Obsidian notes = 3 h)
infinity (skip straight to Phase 3.2) | Supports both text and visual models simultaneously | Slightly more complex setup; Phase 3.2 is not urgent

Lean: deploy TEI now, swap to infinity when Phase 3.2 visual collection is needed.

### Web search (Phase 2.4)

The plan calls for SearXNG (not yet deployed):

Option | Pros | Cons
--- | --- | ---
SearXNG (plan) | Self-hosted, no API key, privacy-preserving | New container to maintain
Exa MCP (already in MCP gateway) | Already wired, no new container | Paid/rate-limited external service
crawl4ai alone | Already deployed (Phase 2.4 fetch step) | No search, only direct-URL fetch
Brave Search API | Simple, fast | API key + cost

Lean: use Exa MCP for Phase 2.4 (already available in the gateway), deploy SearXNG only if privacy or rate limits become a concern.

### GraphDB (Phase 3.4)

The plan calls for Ontotext GraphDB:

Option | Pros | Cons
--- | --- | ---
Ontotext GraphDB (plan) | Full SPARQL 1.1, production-grade, free Community Edition | ~4 GB heap; heavyweight for a homelab
Apache Jena Fuseki | Lighter, Apache licensed, same SPARQL interface | Less tooling, fewer connectors
Oxigraph | Tiny Rust binary (~50 MB), OpenAPI + SPARQL | Newer, smaller community
Skip GraphDB entirely | Qdrant alone covers 80% of the Phase 3 value | Phase 6 steward commands lose structural query capability

Lean: defer until Phase 3.1–3.3 are running. Then re-evaluate Oxigraph vs. GraphDB based on RAM budget at that time.

## Open items

- [ ] Import Phase 1 n8n workflows (manual step — credentials required in n8n UI).
- [ ] Wire Memos webhook → n8n.
- [ ] Create LiteLLM `nexa` virtual key.
- [ ] Deploy TEI container on CT104 (Phase 3.1 prerequisite).
- [ ] Create `nexa_knowledge_text` Qdrant collection.
- [ ] Decide SearXNG vs. Exa MCP for Phase 2.4.

See `docs/11-open-questions.md` in the Nexa repo for all design decisions and their resolution status.