# Stack Ideas & Improvements Hardware baseline: **NUC 14 Pro** — Intel Core Ultra (Meteor Lake), Intel Arc iGPU (currently used for ComfyUI / XPU image gen), no NVIDIA, UNAS for media/bulk storage. --- ## 1. Document ingestion → LobeChat knowledge base + MCP **Goal**: ingest PDFs, Word, PPT, XLS → searchable in LobeChat chat + accessible via MCP. Qdrant is a nice-to-have, not a requirement (no live pipeline uses it yet). **LobeChat already has a built-in knowledge base** (`knowledge_base_files`, `chunks`, `embeddings` tables in Postgres). The missing piece is an ingest pipeline that feeds it. **Recommended architecture**: ``` Nextcloud folder / Paperless webhook → n8n trigger (already running) → Docling (PDF/DOCX/PPTX/XLSX → Markdown + structure) → LiteLLM /v1/embeddings (Mistral-embed / codestral-embed) → LobeChat knowledge base API ←— available in chat natively → Qdrant sidecar (optional, if multi-app search needed) ``` **Document conversion options**: | Tool | Docker image | Formats | NUC 14 CPU fit | |------|-------------|---------|----------------| | **Docling** (IBM, 2024) | `ghcr.io/ds4sd/docling` | PDF, DOCX, PPTX, XLSX, HTML, Markdown | ✅ CPU-only, 10-60s/doc | | **MinerU** (OpenDataLab) | `opendatalab/mineru` | PDF (layout-aware, OCR) | ✅ CPU mode; GPU optional for speed | | **Unstructured** | `quay.io/unstructured-io/unstructured-api` | Very broad (25+ formats) | ✅ lighter than Docling | | **Markitdown** (already in MCP gateway) | — | Office + PDFs → Markdown | ✅ ad-hoc only, not batch | **Docling vs MinerU**: Docling is better for structured Office/PDF with tables and figures. MinerU (OpenDataLab) is better for pure PDF optical layout analysis (e.g., academic papers, scanned documents). Both run on NUC 14 CPU. Start with Docling — single container, REST API, well-documented. **MCP access**: add a `knowledge-search` MCP tool to the gateway that calls LobeChat's knowledge base search API. Zero new infra — LobeChat is already on `shared_backend`. **IBM Granite embedding** (granite-embedding-30m-english) — good quality, tiny (30M params), runs CPU-only. Alternative to Mistral-embed if you want fully local embeddings. Not on LiteLLM yet but can add as a custom provider pointing at an Ollama/IPEX-LLM instance. --- ## 2. Document conversion pipeline **Problem**: No systematic ingestion path from raw docs (PDF, DOCX, HTML) into structured text for chunking/embedding. **Tools to consider**: | Tool | Docker image | Best for | |------|-------------|----------| | **Docling** (IBM, 2024) | `ghcr.io/ds4sd/docling` | PDFs with complex layout (tables, columns, figures); outputs Markdown | | **Unstructured** | `quay.io/unstructured-io/unstructured-api` | Wide format support (HTML, DOCX, PPTX, images with OCR); REST API | | **Gotenberg** | `gotenberg/gotenberg` | HTML/Office → PDF pre-processing stage; not a text extractor | | **Apache Tika** | `apache/tika` | Broad format support; outputs plain text; lower quality than Docling for PDFs | | **Markitdown MCP** | already in gateway | Ad-hoc on-demand conversion; not suitable for batch pipelines | **Recommended pipeline (n8n-orchestrated)**: ``` Nextcloud / Paperless webhook → Gotenberg (Office → PDF) → Docling (PDF → Markdown chunks) → LiteLLM /v1/embeddings (Mistral-embed) → Qdrant upsert ``` Docling runs CPU-only comfortably on the NUC. Unstructured is heavier but has a managed API if the self-hosted version is too slow. Paperless-ngx already OCRs documents — its full-text content is accessible via the REST API. An n8n workflow polling `/api/documents/?added__gt=` can extract and re-embed directly, without re-running OCR. --- ## 3. On-device LLM (Arc iGPU) The Arc iGPU is currently ComfyUI-only. Small language models can also run on it: - **IPEX-LLM** (Intel) + **Ollama** — Intel provides a patched Ollama build that uses IPEX-LLM for Arc acceleration. Supports Phi-3.5-mini, Gemma-2B, TinyLlama. Useful as a fast/cheap fallback when Groq/Mistral rate limits hit. - **llama.cpp with Vulkan** — alternative to IPEX-LLM; no Intel-specific driver, uses Vulkan compute. Less optimised for Arc but simpler to deploy. - **Practical constraint**: Arc iGPU shares system RAM; sustained LLM inference competes with other XPU workloads (e.g., ComfyUI). A model serving config that pauses one workload while the other runs is needed, or deploy them on separate CPU/GPU budgets. If a second NUC or small GPU box becomes available, this becomes the primary use case. --- ## 4. Arcane agents on NUC (central instance on Proxmox LXC) Arcane's central server moves to a **Proxmox LXC** (lightweight, stays responsive even if the Docker stack has issues). The NUC and any other Docker host runs the **Arcane agent** (headless worker), which connects back to the central instance. **Deployment**: - LXC: central Arcane server + observability stack (see §8) - NUC (`.40`) and `.49`: `arcane-agent` (headless) in compose, connects to LXC - Arcane agents reach Docker via either: - **TCP Docker socket + TLS certs** — most secure; requires cert generation per host - **SSH Docker contexts** — simpler; gateway mounts socket into agent via SSH tunnel **Observability co-located on the LXC** (see §8 — lightweight, OTEL-aware stack that survives Docker restarts). --- ## 5. AI memory / personalization **Mem0** (`mem0ai/mem0`) — persistent user memory layer that sits in front of LLM calls. Stores facts extracted from conversations into a vector DB (Qdrant backend supported). Can integrate with LobeChat or as an MCP tool. Lets the AI remember preferences, past context, and user-specific facts across sessions. Alternative: **Letta** (formerly MemGPT) — stateful agent framework with persistent memory; more opinionated. --- ## 6. Workflow / automation upgrades - **n8n → AI agent nodes**: n8n 1.x has native AI agent nodes (LangChain under the hood). Can build RAG, email triage, document processing workflows visually. - **Activepieces** — lighter-weight n8n alternative; good for simple integrations. Probably not worth adding since n8n is already running. - **Temporal** — durable workflow engine for long-running or retry-heavy pipelines (e.g., large document batch processing). Overkill unless pipelines become complex. --- ## 7. External services worth considering | Service | Purpose | Notes | |---------|---------|-------| | **Backblaze B2** | Off-site backup (already in todos) | rclone sync from Garage; restic for PG dumps | | **Cloudflare R2** | S3-compatible CDN-backed storage | Free egress; good for Lobe file serving | | **Resend** | Transactional email | 3K/mo free; better deliverability than self-hosted Postal | | **ntfy.sh (cloud)** | Push notifications fallback | Already running self-hosted ntfy; cloud as relay | | **Cloudflare Turnstile** | Bot protection for public endpoints | Free; no JS challenge | | **Novu** | Notification orchestration | Multi-channel (email, push, Slack); self-hostable | --- ## 8. Observability (on Proxmox LXC, alongside Arcane) **Runs on the LXC, not the NUC** — stays alive if the Docker stack misbehaves. Lightweight enough for a 2 vCPU / 4GB LXC. **Recommended stack** (all OTEL-aware, compose-based): | Component | Image | Role | |-----------|-------|------| | **OpenTelemetry Collector** | `otel/opentelemetry-collector-contrib` | Receives traces/metrics/logs from all services (OTLP gRPC+HTTP); fans out to backends | | **VictoriaMetrics** | `victoriametrics/victoria-metrics` | Prometheus-compatible TSDB; scrapes NUC exporters + receives from OTEL collector; lighter than Prometheus | | **Grafana** | `grafana/grafana` | Dashboards; datasource = VictoriaMetrics + Loki | | **Loki** | `grafana/loki` | Log aggregation; receives from OTEL collector | | **Uptime Kuma** | `louislam/uptime-kuma` | HTTP/TCP uptime checks for all public endpoints; alerts via ntfy | **OTEL receivers** from the NUC Docker stack: - **LiteLLM**: native OTEL export — traces every LLM call with token counts, model, latency - **n8n**: Prometheus `/metrics` endpoint - **Garage**: Prometheus `/metrics` - **mcp-gateway**: add `opentelemetry-sdk` instrumentation to `server.py` - **Docker host**: `node_exporter` + `cadvisor` on the NUC, scraped by VictoriaMetrics **NUC → LXC connectivity**: Both are on the same LAN. OTEL collector listens on the LXC's LAN IP (e.g., `192.168.1.X:4317` gRPC). Services push OTEL directly to it; Prometheus pull-scraping from VictoriaMetrics goes to NUC exporters over LAN. --- ## 9. Storage / S3 improvements - **Garage external S3** is currently non-responsive (tracked in todos). Fix or replace with **MinIO** (single-node, much better tooling/UI, easy migration). - **Lobe file serving via Cloudflare R2**: Lobe uploads to Garage → sync to R2 → serve from CDN. Reduces NUC egress for image-heavy sessions. - **Qdrant data on UNAS**: Mount `qdrant_data` from NAS for persistence across container re-creates (same pattern as arr-stack). --- ## 9. ComfyUI MCP — async queue + image-to-image + reference **Current problem**: MCP tool blocks until the image is done (~90-290s). LLMs time out at ~60s. The fix is a job-queue pattern: ``` generate_image(prompt) → returns {job_id, status: "queued"} immediately get_image_status(job_id) → returns {status, progress, image_url_when_done} list_queue() → shows all pending/running jobs cancel_job(job_id) → cancels a queued job (confirms with user first) ``` ComfyUI's own API is already async (`POST /prompt` → poll `/history/{id}`). The MCP server just needs to expose this model instead of blocking. **Image-to-image**: new workflow `flux-schnell-img2img-api.json`. Takes an init image URL + denoise strength. ComfyUI `LoadImageFromURL` node (or upload + `LoadImage`). **Reference tool**: `list_previous_images(n=5)` — queries ComfyUI `/history` API, returns recent job thumbnails + prompts. User can pick one to reference or iterate from. **Delivery to S3/Garage**: on completion, upload output PNG to Garage `comfyui-outputs` bucket → return a permanent URL. Avoids ComfyUI's ephemeral `/view` endpoint. --- ## 10. LiteLLM custom provider / LobeChat provider extension **Question**: build an adapter in LiteLLM to use models via "quasi API" (non-standard endpoints, auth, or routing)? **LiteLLM supports custom providers** via `custom_llm_provider` in config.yaml. You write a Python class that implements `completion()` and `async_completion()`. This is the right path for wrapping non-standard APIs (local models, proprietary endpoints, protocol bridges). Example use cases: - Wrap a Claude Max subscription via Anthropic's API (different billing model) - Add a local model served by IPEX-LLM on the Arc iGPU - Bridge a custom inference server that speaks a different protocol **LobeChat provider extension**: LobeChat's provider list is compiled into the app. Adding a new provider requires rebuilding LobeChat from source (fork + add to `src/config/aiModels/`). High effort; only worth it for a permanent/long-term provider. For ad-hoc needs, use LiteLLM as the adapter and point LobeChat at it via the existing `ai.nuclide.systems` OpenAI-compatible endpoint. --- ## 11. Dependency updates via Renovate Bot (Gitea Actions) Run **Renovate Bot** as a Gitea Actions workflow to automatically open PRs for outdated dependencies in MCP server repos (`mcp-comfyui`, `mcp-docling`, `mcp-shepard`, `mcp-upload-artifact`). Targets: `Dockerfile` base image tags + `requirements.txt` / `pyproject.toml` Python deps. Renovate supports Gitea natively via `platform: gitea` in `renovate.json`. The Gitea Actions runner (`ct111-runner`) already exists; add a scheduled workflow calling `renovate/renovate` Docker image once daily. --- ## 12. Egress firewall on UDM (UniFi) Enforce outbound allow-list on the UDM / UniFi gateway — block all non-approved egress by default. Goals: - Prevent exfiltration from compromised containers - Audit unexpected outbound connections (model providers, analytics, telemetry) - Approved: LiteLLM model provider endpoints, Jottacloud, UNAS internal, NTP, DNS Implementation: UDM firewall rules (WAN_OUT) + Threat Management IDS in monitor mode first. --- ## 13. Local LLM on Arc GPU via vllm / ollama for sensitive workloads Run a privacy-sensitive LLM locally on the Arc iGPU using **vllm** (with XPU/IPEX backend) or the Intel-patched **Ollama** build. Use cases: document classification in Paperless workflows, offline coding assistant, fallback when cloud rate limits hit. See §3 (On-device LLM) for implementation notes. This item tracks the specific motivation of *sensitive workload isolation* — i.e., running prompts that should not leave the LAN. --- ## Priority order (rough) 1. **ComfyUI MCP async queue** — fixes timeout; unblocks img2img + reference features 2. **Docling container + n8n ingest pipeline** — Nextcloud/Paperless → LobeChat knowledge base 3. **Arcane LXC + agents on NUC** — when ready to migrate 4. **Observability LXC** — OTEL collector + VictoriaMetrics + Grafana + Uptime Kuma, co-located 5. **Backblaze B2 off-site backup** — already in todos 6. **On-device LLM (Arc)** — depends on IPEX-LLM + Ollama Intel build stability 7. **Renovate Bot** — low-effort automation win for MCP repos 8. **Egress firewall** — security hygiene; plan before adding more external-facing services