Commit Graph
15 Commits
Author SHA1 Message Date
haylan 124053cf89 feat(scripts): auto-register memory-and-notes in litellm's DB for the Admin UI
The vector_store_registry block in litellm-config.yaml only seeds the
store into litellm's in-memory registry at boot — the Admin UI's Vector
Stores page (/ui/vector-stores) reads litellm's own DB
(LiteLLM_ManagedVectorStoresTable) instead, via /vector_store/list. A
config-only entry there gets silently deleted from memory the first time
anyone loads that page, since /vector_store/list treats the DB as the
source of truth and removes anything not also present there.

update.sh now registers it in the DB too, via POST /vector_store/new
(idempotent, same pattern as the existing virtual-key minting) — with the
literal resolved key, not the os.environ/... form used in
litellm-config.yaml, since the management API doesn't do config.yaml-style
substitution on request bodies.

Found in the process: /vector_store/update in this litellm version can't
touch litellm_params at all (VectorStoreUpdateRequest has no such field,
so PGVECTOR_API_KEY sent through it is silently dropped) — worth knowing
if this key ever needs rotating; documented in update.sh's comment.

Verified live: registered via the API, confirmed the row appears in
/vector_store/list (what the Admin UI page reads) with the real key, and
re-verified search still works end-to-end afterward.
2026-09-02 21:51:02 +00:00
haylan 7e8b5069d4 fix(scripts): update.sh never applied litellm-pgvector's db schema
litellm-pgvector's Dockerfile only runs 'prisma generate' (codegen) at
build time — nothing ever ran 'prisma db push' against pgvector-db, so the
vector_stores/embeddings tables plain didn't exist on a fresh deploy. Every
vector store call failed with 'relation "vector_stores" does not exist'.

update.sh now runs the push itself after bringing litellm-pgvector up.
2026-09-02 21:32:33 +00:00
haylan eaf11b6d4b fix(scripts): ingest-memory.sh never actually computed embeddings
Two bugs, either one fatal:
- litellm-pgvector's embeddings endpoints take a precomputed vector per
  chunk (they don't call the embedding model themselves) — the script
  posted {content, metadata} with no embedding field, guaranteed 422.
- The batch endpoint expects {"embeddings": [...]}; the script posted a
  bare JSON array as the body.

Now embeds each file's chunks via LiteLLM's /v1/embeddings first (using
LITELLM_PGVECTOR_EMBEDDING_KEY, already minted for exactly this) before
batch-inserting. Also made both source files optional — a missing file is
skipped, not a hard failure, since neither exists in this checkout yet.
2026-09-02 21:32:29 +00:00
haylanandClaude-Bot e2dd106f74 feat(scripts): fold model downloads into update.sh, skip if already present
Today's embedding-server crash-loop (missing nomic-embed-text GGUF) was a
manual step nobody ran. update.sh now runs both downloader profiles
itself, every time, before bringing services up -- no separate command to
remember.

- docker-compose.yml: downloader/downloader-embedding commands gain a
  `test -f ... && skip || curl ...` guard, so re-running update.sh never
  re-downloads an existing model file.
- scripts/update.sh: runs both profiles after image pull/build, before
  service recreation.
- scripts/download-model.sh removed -- folded in, redundant standalone
  script.
- README.md / docs/memory-knowledgebase.md updated accordingly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WHfjWrSEcGhCoeu6dQfDa
2026-09-02 23:07:53 +02:00
haylanandClaude-Bot c7848f356a chore(scripts): mark update.sh executable
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WHfjWrSEcGhCoeu6dQfDa
2026-09-02 22:47:53 +02:00
haylanandClaude-Bot e7983f0710 Revert "feat(knowledgebase): replace litellm-pgvector connector with memory-retrieval"
This reverts commit abeadc49c8.

Restores vendor/litellm-pgvector/ and the vector_store_registry wiring
(in-band file_search tool-call support) at the user's request, after
re-confirming against docs.litellm.ai/docs/completion/knowledgebase and
litellm-pgvector's own README that pg_vector is still not an in-process
vector_store_registry backend -- it requires this same standalone
connector service either way, so there is no simpler 'native' path that
was missed. Trading back in: 793 lines of vendored code, the untested
Prisma migration, and the git-context build risk noted in VENDORED.md
(all flagged as unverified against real hardware in issue #24), in
exchange for the file_search in-band tool call memory-retrieval did not
support.

Conflicts resolved on top of later commits (Redis, update.sh key-minting
fold-in):
- .env.example / docs/memory-knowledgebase.md: kept the auto-mint-via-
  update.sh language, renamed MEMORY_RETRIEVAL_* back to
  LITELLM_PGVECTOR_*.
- scripts/generate-secrets.sh: left deleted -- its job was folded into
  update.sh in 24d749b, unrelated to this revert.
- scripts/update.sh: renamed the MEMORY_RETRIEVAL_* secret/mint calls to
  LITELLM_PGVECTOR_* to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WHfjWrSEcGhCoeu6dQfDa
2026-09-02 22:45:08 +02:00
haylanandClaude-Bot b4dc83949e feat(litellm): add Redis for router state/rate-limits/budgets/cache
New redis service (redis:7-alpine, password-protected, no persistence
volume — everything it holds is cache/coordination state). litellm gets
REDIS_HOST/REDIS_PORT/REDIS_PASSWORD, which is all LiteLLM needs to use it
for router state, rate limits/budgets, and cache invalidation — no
litellm-config.yaml block required (docs.litellm.ai/docs/proxy/caching).
REDIS_PASSWORD added to .env.example and update.sh's auto-generated
secrets.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 22:28:25 +02:00
haylanandClaude-Bot b996b1fe88 fix(scripts): update.sh now appends vars missing from .env, not just blank ones
set_if_blank/mint_key_if_blank used sed -i "s|^KEY=.*|...|", which only
replaces an existing KEY= line — a no-op if the line isn't there at all.
Any .env created before a var was added to .env.example (SEARXNG_LAN_IP,
PGVECTOR_DB_PASSWORD, MEMORY_RETRIEVAL_*, etc.) silently never got that var
filled in. Both helpers now check for "line missing" as a third case and
append it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 22:21:50 +02:00
haylanandClaude-Bot 24d749b2e0 feat(scripts): fold generate-secrets.sh into update.sh, auto-mint virtual keys
update.sh now creates .env from .env.example if missing, idempotently fills
in every random secret (same logic generate-secrets.sh had, now removed),
resolves SEARXNG_LAN_IP from search.home via the host's own DNS, and mints
OPENWEBUI_LITELLM_KEY / MEMORY_RETRIEVAL_EMBEDDING_KEY through LiteLLM's own
/key/generate API once litellm is up — no more manual Admin UI step for the
stack's own two workload keys. Docs updated to point at update.sh as the
one command; docs/proxy-key-onboarding.md keeps the manual/API steps as the
fallback and for onboarding other workloads.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 22:18:11 +02:00
haylanandClaude-Bot abeadc49c8 feat(knowledgebase): replace litellm-pgvector connector with memory-retrieval
Per docs/research/langchain-pgvector-vs-litellm-pgvector.md (issue #25):
the vendored litellm-pgvector connector (793 lines, Prisma migrations, a
fragile git-context build) is replaced by a ~90-line FastAPI service
(services/memory-retrieval/) wrapping langchain_postgres.PGVector directly
against pgvector-db. Same gateway boundary — it still calls litellm for
embeddings, nothing talks to Postgres or the model directly except this
service.

- New services/memory-retrieval/ (main.py, Dockerfile, requirements.txt):
  POST /ingest, POST /query, GET /health.
- docker-compose.yml: litellm-pgvector service replaced by memory-retrieval;
  pgvector-db and embedding-server untouched.
- litellm-config.yaml: vector_store_registry block removed (no
  langchain_postgres provider exists to register against; callers query
  memory-retrieval directly instead of an in-band file_search tool call —
  that mechanism was never confirmed working per issue #24 anyway).
- scripts/ingest-memory.sh rewritten for the new /ingest endpoint (same
  per-line chunking, no dedup).
- .env vars renamed: LITELLM_PGVECTOR_API_KEY/LITELLM_PGVECTOR_EMBEDDING_KEY
  -> MEMORY_RETRIEVAL_API_KEY/MEMORY_RETRIEVAL_EMBEDDING_KEY.
- vendor/litellm-pgvector/ removed entirely.
- docs/memory-knowledgebase.md updated for the new setup/query flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 22:09:25 +02:00
haylanandClaude-Bot b0e37b2f4c chore(scripts): add update.sh, hook it into agent/deploy workflow
One script to bring the running stack in sync after any change: git pull,
validate compose config, rebuild the litellm-pgvector local build, re-pull
images, recreate what changed. Documented in README's quickstart, and
CLAUDE.md now tells agents to run it after touching compose/config/scripts
rather than just describing a change as done.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:44:26 +02:00
haylanandClaude-Bot f508f5670a feat(litellm): wire SearXNG search, pgvector knowledgebase, and memory ingestion
- search_tools block in litellm-config.yaml (SearXNG as a first-class
  search_provider, standalone /v1/search endpoint, not a model tool) plus
  extra_hosts on the litellm service so it can resolve search.home.
- New embedding-server (nomic-embed-text-v1.5 on a second llama.cpp
  instance), pgvector-db, and litellm-pgvector services — LiteLLM's native
  knowledgebase feature has no Qdrant backend, so this is the only
  self-hosted path (docs/research/litellm-knowledgebase.md).
- vector_store_registry + local-embedding model entry in
  litellm-config.yaml, wiring it together.
- scripts/ingest-memory.sh to load data/memory.md and
  data/claude-legacy-memory.md into the knowledgebase.
- docs/memory-knowledgebase.md documenting the whole setup; data/
  gitignored (personal memory content, not meant to be committed).
- New .env vars (SEARXNG_LAN_IP, PGVECTOR_DB_PASSWORD,
  LITELLM_PGVECTOR_API_KEY, LITELLM_PGVECTOR_EMBEDDING_KEY,
  EMBEDDING_MODEL_FILE) and generate-secrets.sh support for the
  auto-generatable ones.

Resolves #22 and #23 (wayfinder map #21). Not yet verified on real
hardware — see #24.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:38:16 +02:00
haylanandClaude-Bot ee7ebfd8e1 feat(litellm): add UI_USERNAME/UI_PASSWORD for the admin UI login
Without these, LiteLLM's /ui falls back to username 'admin' and the
master key as the password, forcing the master key to be typed into
a browser. generate-secrets.sh now fills UI_PASSWORD like the other
secrets.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2CR8yawSf7pwAVYnjwFea
2026-09-02 20:29:00 +02:00
haylan 2ac4e91862 feat(chore): impelmented seecret generation 2026-09-02 19:51:54 +02:00
haylanandClaude-Bot f0e473048d Author docker-compose stack: llama.cpp (ROCm) + Open WebUI + Qdrant + Lazytainer
Resolves wayfinder ticket #4. Wires up the locked decisions from the map:
- llama.cpp (ghcr.io/ggml-org/llama.cpp:server-rocm, gfx1201) serving
  Qwen3.8-27B-UD-Q4_K_XL.gguf, port published for direct Claude Code CLI /
  Kimi CLI access alongside Open WebUI.
- Open WebUI with WEBUI_AUTH on, RAG+Memory wired to a standalone Qdrant
  service.
- Lazytainer labels on llama-server for a 15 min idle-stop.
- Named Docker volumes only (models, qdrant-data, openwebui-data) — no host
  bind-mounts.
- One-off 'downloader' compose profile instead of a host-side script with
  its own dependencies, wrapped by scripts/download-model.sh.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 13:01:00 +02:00