Commit Graph
41 Commits
Author SHA1 Message Date
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 e2a79eab4a docs(research): LangChain+pgvector-direct vs litellm-pgvector for issue #25
Verdict: switch. See docs/research/langchain-pgvector-vs-litellm-pgvector.md
for full reasoning, LOC comparison, and a concrete replacement service spec.
Research/doc only — no compose/config/vendor changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 22:02:58 +02:00
haylanandClaude-Bot 7247674a9f fix(litellm-pgvector): vendor the source instead of a remote git build context
The server's Docker/BuildKit couldn't do a git-context build of a public
github.com repo (fails with "could not read Username ... terminal prompts
disabled" — an auth-shaped error for what should be an anonymous clone).
Rather than debug that, vendor litellm-pgvector's small source tree
directly (vendor/litellm-pgvector/, see VENDORED.md for provenance/update
steps) and build from the local path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:50:45 +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 a3ecbc0e02 docs(research): investigate LiteLLM knowledgebase/vector_store feature for #23
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:26:39 +02:00
haylanandClaude-Bot 8c42f2518b research: LiteLLM web-search + SearXNG wiring (issue #22)
Answers whether SearXNG is natively supported by LiteLLM's /v1/search
feature, whether it's a model-tool or automatic retrieval, what
docker-compose.yml networking change is needed for the litellm container
to reach the LAN's search.home host, and how it interacts with this
project's known-flaky Qwen3.8-27B tool-calling.

Research only — litellm-config.yaml and docker-compose.yml are unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:25:30 +02:00
haylan 949802fb2b Merge pull request 'fix(litellm): default max_tokens=4096 for the reasoning model' (#20) from fix/litellm-reasoning-max-tokens into main 2026-09-02 18:58:11 +00:00
haylanandClaude-Bot 100fed4274 fix(litellm): default max_tokens=4096 for the reasoning model
Qwen3 spends output tokens on reasoning_content before writing content.
Open WebUI's default chat request doesn't set max_tokens, so it fell
through to llama.cpp's low default and the model ran out mid-thought,
returning finish_reason=length with empty content — no reply shown in
Open WebUI. Confirmed via a manual /v1/chat/completions call: works with
max_tokens=2000, fails without it.

litellm_params.max_tokens is a default, not a cap — any caller (or Open
WebUI's per-model Advanced Params) that sets its own max_tokens still
overrides it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2CR8yawSf7pwAVYnjwFea
2026-09-02 20:55:39 +02:00
haylan 7609da7dad Merge pull request 'feat(litellm): add UI_USERNAME/UI_PASSWORD for the admin UI login' (#19) from fix/litellm-ui-admin-creds into main 2026-09-02 18:29:30 +00: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 7480a3e566 Merge remote-tracking branch 'origin/research/voidllm-evaluation' 2026-09-02 20:04:44 +02:00
haylan 9604a42e8b Merge remote-tracking branch 'origin/research/proxy-tool-choice' 2026-09-02 20:04:44 +02:00
haylan 705019bc1c Merge remote-tracking branch 'origin/research/proxy-shadow-pricing' 2026-09-02 20:04:44 +02:00
haylan f40a2cff65 Merge remote-tracking branch 'origin/research/connecting-cloud-providers' 2026-09-02 20:04:44 +02:00
haylan 64243c65d7 Merge pull request 'fix(downloader): run as root to fix permission denied on models volume' (#18) from fix/downloader-permission-denied into main
Reviewed-on: #18
2026-09-02 18:03:59 +00:00
haylanandClaude-Bot 7863b04787 fix(downloader): run as root to fix permission denied on models volume
The curlimages/curl image drops to non-root curl_user (uid 100) by
default, but the models named volume is created root-owned by Docker,
so writes into it failed with 'Permission denied'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2CR8yawSf7pwAVYnjwFea
2026-09-02 20:03:38 +02:00
haylan 2ac4e91862 feat(chore): impelmented seecret generation 2026-09-02 19:51:54 +02:00
haylanandClaude-Bot 993f11d6de research: Claude Pro subscription vs Anthropic API for gateway backends
Answers whether the $20/mo Claude Pro subscription can be used as a
LiteLLM backend instead of a pay-per-token Anthropic API key. Finding:
no — Pro/Max OAuth credentials are contractually restricted to Claude
Code / native Anthropic apps (Consumer ToS + Usage Policy, actively
enforced server-side since March 2026). Documents the supported path:
a separate Anthropic Console API key as a model_list entry, same shape
as the existing llama.cpp entry. Same pattern applies to other
providers (ChatGPT Plus, Gemini subscriptions).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 08:51:38 +02:00
haylanandClaude-Bot f300c5b034 research: evaluate voidllm as a LiteLLM proxy replacement
Verified against the live GitHub repo/docs (not secondhand): real,
active, functioning AI gateway, ~5 months old, effectively
single-maintainer, BSL 1.1. Fails two of the requirements from
docs/research/proxy-tool-choice.md / issue #9 — no Anthropic Messages
inbound endpoint (VoidLLM's own docs say Claude Code's LLM traffic
can't be routed through it) and no request-priority/queuing feature.
Recommendation: stay on LiteLLM.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 08:42:23 +02:00
haylan 487573c533 Add build plan documentation for 4x Radeon AI PRO R9700 rackmount LLM server 2026-08-25 07:20:58 +02:00
haylanandClaude-Bot 5cb34b19f3 Migrate Open WebUI and coding CLIs to the AI proxy (resolves #15)
Open WebUI now points at litellm instead of llama-server directly, using a
provisioned virtual key. llama-server's host port is dropped (internal-only
on the ai-stack network) since the proxy is the only intended entry point
now. docs/coding-cli-setup.md repointed at the proxy's endpoints/ports with
per-CLI virtual keys instead of the old shared dummy key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 07:18:03 +02:00
haylanandClaude-Bot 0aefb36a48 Author LiteLLM AI proxy service (resolves #14)
Adds litellm + litellm-db to docker-compose.yml, litellm-config.yaml with
custom shadow-cost pricing (Claude Sonnet 5 reference, per #11) and a
priority-scheduling stub (per #16, needs real-hardware smoke test), and
required LITELLM_MASTER_KEY/SALT_KEY/DB_PASSWORD env vars. Untested on real
hardware — that's #17. Open WebUI/coding CLIs still talk to llama.cpp
directly, migration is #15.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 07:11:15 +02:00
haylanandClaude-Bot 0342090e1c Document AI proxy request priority/queueing plan (resolves #16)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 07:07:20 +02:00
haylanandClaude-Bot 7e50e1867f Document AI proxy network exposure plan (resolves #13)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 07:05:01 +02:00
haylanandClaude-Bot 1c29e07762 Document AI proxy key onboarding process (resolves #12)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 06:56:51 +02:00
haylanandClaude-Bot a751e656e3 research: reference cloud pricing for LiteLLM shadow-cost estimate
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 06:49:38 +02:00
haylanandClaude-Bot a1c37de6b4 research: self-hosted AI gateway/proxy tool choice — recommend LiteLLM
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 06:45:10 +02:00
haylanandClaude-Bot c01ef8965d Fix docs: no localhost, wire up ai.home / ai.haylan.ch via existing NPM
Resolves wayfinder ticket #8. The stack is reached over LAN/WAN hostnames,
not localhost:
- Open WebUI: ai.home (LAN) and ai.haylan.ch (external, via DMZ) routed
  through the existing Nginx Proxy Manager instance to the published
  WEBUI_PORT — no new reverse-proxy service needed in this repo.
- llama.cpp's raw API stays LAN-only and unregistered in NPM (no auth of
  its own); coding CLIs reach it via the box's LAN IP or ai.home directly.

New docs/network-access.md documents the NPM proxy-host setup and the
LAN-only decision. coding-cli-setup.md and README updated to stop
referencing localhost.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 18:28:14 +02:00
haylanandClaude-Bot 7d8c9324b2 Write local-usage docs for Claude Code CLI, Kimi CLI, and OpenCode CLI
Resolves wayfinder ticket #6. Covers the two server endpoints (Anthropic
shim vs OpenAI-compatible), exact config for all three CLIs, and surfaces
the shared Qwen3.8-27B tool-calling risk plus OpenCode's own documented
local-backend brittleness up front rather than burying it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 18:19:56 +02:00
haylanandClaude-Bot b773d9cb8f research: OpenCode CLI install + local llama.cpp provider config
Answers issue #7. Confirms sst/opencode moved to anomalyco/opencode,
documents install methods, opencode.json provider config for a local
OpenAI-compatible server, and known tool-calling compatibility issues
against self-hosted backends (llama.cpp --jinja requirement, empty
tool_calls handling) plus Qwen3.8-27B-specific caveats.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 18:17:14 +02:00
haylanandClaude-Bot 408a1f16ae Ignore .claude/ worktree scratch dir
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 13:01:09 +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
haylan 19d62aefd3 Merge branch 'research/qwen3.8-27b-tool-calling' 2026-08-24 13:00:52 +02:00
haylanandClaude-Bot ce1ab05c3e docs: research Qwen3.8-27B Unsloth dynamic GGUF quant + VRAM budget
Resolves the wayfinder research question: unsloth/Qwen3.8-27B-GGUF ships
UD-Q4_K_XL.gguf (17.6GB) directly. Documents VRAM footprint on 32GB
RDNA4 (R9700/gfx1201) at 32K and 128K context via llama.cpp ROCm/HIP.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 12:16:42 +02:00
haylan a55fbcaa18 research: Qwen3.8-27B tool-calling compat with llama.cpp Anthropic shim 2026-08-24 12:16:09 +02:00
haylanandClaude-Bot 3d768181e3 Set up agent skills config and chart wayfinder map for local AI stack
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 12:13:21 +02:00