Retain/extraction moved off the Kimi wrapper (hindsight-llm:8012) onto ollama/gemma3:4b via LiteLLM, joining consolidation + reflect which were already local (kb#88). Kimi is no longer in the Hindsight path at all, so the memory backend consumes zero quota and Adolf's 5h window is left entirely for conversation. Accepted tradeoff: kb#84/kb#88 kept retain on Kimi for fact quality, since gemma3:4b's Russian fluency was never verified and this bank is largely Russian. A dry-run extraction on Russian input after the change returned clean, parseable output but captured only one of two facts in the sample, so extraction is coherent but lossier. Revert this first if facts degrade. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
392 lines
18 KiB
YAML
392 lines
18 KiB
YAML
services:
|
|
litellm-db:
|
|
image: postgres:16-alpine
|
|
container_name: litellm-db
|
|
environment:
|
|
- POSTGRES_DB=litellm
|
|
- POSTGRES_USER=litellm
|
|
- POSTGRES_PASSWORD=litellm
|
|
volumes:
|
|
- /mnt/ssd/dbs/litellm/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
|
|
litellm:
|
|
image: ghcr.io/berriai/litellm:main-latest
|
|
container_name: litellm
|
|
ports:
|
|
- "4000:4000"
|
|
volumes:
|
|
- ./litellm-config.yaml:/app/config.yaml
|
|
environment:
|
|
- DATABASE_URL=postgresql://litellm:litellm@litellm-db:5432/litellm
|
|
- LITELLM_MASTER_KEY=sk-fjQC1BxAiGFSMs
|
|
- LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-changeme}
|
|
- LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-changeme}
|
|
- LANGFUSE_HOST=http://langfuse:3000
|
|
- OPENROUTER_API_KEY=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
|
|
command: ["--config", "/app/config.yaml", "--port", "4000"]
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
depends_on:
|
|
- litellm-db
|
|
- langfuse
|
|
restart: always
|
|
|
|
kimi-agent:
|
|
build: ./kimi-agent
|
|
container_name: kimi-agent
|
|
volumes:
|
|
- /home/alvis/kimi-workspace:/workspace
|
|
- kimi-agent-home:/root/.kimi-code
|
|
restart: unless-stopped
|
|
|
|
langfuse-db:
|
|
image: postgres:16-alpine
|
|
container_name: langfuse-db
|
|
environment:
|
|
- POSTGRES_DB=langfuse
|
|
- POSTGRES_USER=langfuse
|
|
- POSTGRES_PASSWORD=langfuse
|
|
volumes:
|
|
- /mnt/ssd/dbs/langfuse/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
|
|
langfuse:
|
|
image: ghcr.io/langfuse/langfuse:2
|
|
container_name: langfuse
|
|
ports:
|
|
- "3200:3000"
|
|
environment:
|
|
- DATABASE_URL=postgresql://langfuse:langfuse@langfuse-db:5432/langfuse
|
|
- NEXTAUTH_URL=https://lf.alogins.net
|
|
- NEXTAUTH_SECRET=532a746b24ac40afa39f9d317031cab94d4d6881107ea3b1209b28020f1a9761
|
|
- SALT=7927b3b0092afe4542274940b557becea6418a5fed79f7acd25c3a789349fdc9
|
|
- AUTH_DISABLE_SIGNUP=true
|
|
depends_on:
|
|
- langfuse-db
|
|
restart: always
|
|
|
|
qdrant:
|
|
image: qdrant/qdrant
|
|
container_name: qdrant
|
|
ports:
|
|
- "6333:6333"
|
|
- "6334:6334"
|
|
restart: always
|
|
volumes:
|
|
- /mnt/ssd/dbs/qdrant:/qdrant/storage:z
|
|
|
|
faster-whisper:
|
|
image: fedirz/faster-whisper-server:latest-cuda
|
|
container_name: faster-whisper
|
|
runtime: nvidia
|
|
ports:
|
|
- "8880:8000"
|
|
environment:
|
|
- WHISPER__MODEL=deepdml/faster-whisper-large-v3-turbo-ct2
|
|
- WHISPER__INFERENCE_DEVICE=cuda
|
|
- WHISPER__COMPUTE_TYPE=int8
|
|
- WHISPER__LANGUAGE=ru
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
volumes:
|
|
- /mnt/ssd/ai/faster-whisper:/root/.cache/huggingface
|
|
restart: always
|
|
|
|
silero-tts:
|
|
build: ./silero-tts
|
|
container_name: silero-tts
|
|
ports:
|
|
- "8881:8881"
|
|
volumes:
|
|
- /mnt/ssd/ai/silero-tts:/cache/torch
|
|
restart: always
|
|
|
|
pipecat:
|
|
build: ./pipecat
|
|
container_name: pipecat
|
|
ports:
|
|
- "8882:8882"
|
|
environment:
|
|
- LIVEKIT_URL=ws://host.docker.internal:7880
|
|
- LIVEKIT_PUBLIC_URL=wss://lk.alogins.net
|
|
- LIVEKIT_API_KEY=devkey
|
|
- LIVEKIT_SECRET=ef3ef4b903ca8469b09b2dd7ab6af529c4d2f3c95668f53832fc351cf67777a9
|
|
- ADOLF_URL=http://host.docker.internal:8000/v1
|
|
- STT_URL=http://host.docker.internal:8880/v1
|
|
- TTS_URL=http://host.docker.internal:8881/v1
|
|
- STT_MODEL=deepdml/faster-whisper-large-v3-turbo-ct2
|
|
- TTS_VOICE=onyx
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
restart: unless-stopped
|
|
|
|
# Adolf — OpenClaw fork (Matrix-first personal assistant). The OpenClaw
|
|
# gateway config (Matrix channel + allow-list, model provider ->
|
|
# adolf-llm:8010, MCP registry, gateway.tools.allow for cron/nodes) is
|
|
# version-controlled at agap_git/adolf/openclaw.json (repo root, alongside
|
|
# this openai/ project, not nested inside it) and bind-mounted read-only
|
|
# over the adolf-state volume (see volumes below), so git is the single
|
|
# source of truth — not a hand-edited volume file. The volume still
|
|
# holds runtime state only (Matrix crypto/devices, credentials, sessions,
|
|
# workspace/SOUL.md, logs). Matrix creds and ADOLF_KEY come from
|
|
# openai/.env (gitignored, never committed). Source tree: /home/alvis/adolf.
|
|
# To change config: edit ../adolf/openclaw.json + restart adolf.
|
|
adolf:
|
|
build:
|
|
context: ../../adolf
|
|
# Matrix is opt-in at build time (see adolf/Dockerfile); without this,
|
|
# the gateway logs "no-channel-owner" and channels.matrix is inert.
|
|
args:
|
|
OPENCLAW_EXTENSIONS: matrix
|
|
image: adolf:local
|
|
container_name: adolf
|
|
environment:
|
|
- HOME=/home/node
|
|
- OPENCLAW_HOME=/home/node
|
|
- OPENCLAW_STATE_DIR=/home/node/.openclaw
|
|
- OPENCLAW_CONFIG_PATH=/home/node/.openclaw/openclaw.json
|
|
- OPENCLAW_CONFIG_DIR=/home/node/.openclaw
|
|
- OPENCLAW_WORKSPACE_DIR=/home/node/.openclaw/workspace
|
|
- OPENCLAW_GATEWAY_TOKEN=${ADOLF_GATEWAY_TOKEN:-}
|
|
- ADOLF_KEY=${ADOLF_KEY:-}
|
|
- MATRIX_HOMESERVER=${MATRIX_HOMESERVER:-}
|
|
- MATRIX_USER_ID=${MATRIX_USER_ID:-}
|
|
- MATRIX_PASSWORD=${MATRIX_PASSWORD:-}
|
|
- MATRIX_DEVICE_NAME=${MATRIX_DEVICE_NAME:-Adolf OpenClaw Gateway}
|
|
# marketplace-mcp bearer token (kb task #61) -- referenced by
|
|
# openclaw.json's mcp.servers.marketplace.headers.Authorization via
|
|
# ${MARKETPLACE_MCP_TOKEN} substitution; never inlined into that file.
|
|
- MARKETPLACE_MCP_TOKEN=${MARKETPLACE_MCP_TOKEN:-}
|
|
- TZ=Europe/Riga
|
|
volumes:
|
|
# Runtime state only (Matrix crypto/devices, credentials, sessions,
|
|
# workspace, logs). The gateway config file itself is overlaid below.
|
|
- adolf-state:/home/node/.openclaw
|
|
# Version-controlled OpenClaw gateway config, mounted read-only on top
|
|
# of the state volume so it is the single source of truth. The gateway
|
|
# reads this JSONC file and snapshots its own .last-good/.rejected
|
|
# copies into the volume dir (writable) — it never rewrites this file,
|
|
# so read-only is safe. Edit the tracked file + restart to change config;
|
|
# runtime/UI edits are intentionally disabled by the ro mount.
|
|
- ../adolf/openclaw.json:/home/node/.openclaw/openclaw.json:ro
|
|
# quota-command plugin (kb #62) — same read-only-bind-over-volume
|
|
# pattern as openclaw.json above, applied to a single external plugin
|
|
# dir instead of the whole state tree. Previously the only precedent
|
|
# (cognee-memory) was docker cp'd straight into the adolf-state volume
|
|
# at runtime with no git backing; this plugin is small enough (no
|
|
# node_modules — only Node built-ins/global fetch) to just bind-mount
|
|
# its tracked source directly at its extensions/<id> path, so git stays
|
|
# the single source of truth the same way it already is for
|
|
# openclaw.json. Activated via plugins.entries.quota-command in that file.
|
|
- ./quota-command-openclaw-plugin:/home/node/.openclaw/extensions/quota-command:ro
|
|
# hindsight-memory plugin (kb #75, H3) — same read-only-bind-over-volume
|
|
# pattern as quota-command above. Structural successor to cognee-memory
|
|
# (still docker cp'd into the adolf-state volume, no git backing; that
|
|
# plugin's activation/container is decommissioned in H4, not here).
|
|
# Forced hooks (before_prompt_build recall / agent_end retain) against
|
|
# the hindsight service (see that service's block below), replacing
|
|
# Cognee as Adolf's memory backend. Activated via
|
|
# plugins.entries.hindsight-memory in openclaw.json.
|
|
- ./hindsight-openclaw-plugin:/home/node/.openclaw/extensions/hindsight-memory:ro
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
# mtx.alogins.net's public A record can't hairpin-NAT back through the
|
|
# router from inside a container; route it to the host gateway instead,
|
|
# matching matrix/docker-compose.yml's lk-jwt-service (same problem,
|
|
# same fix). Caddy on the host terminates TLS on :443 and proxies to
|
|
# synapse:8008.
|
|
- "mtx.alogins.net:host-gateway"
|
|
# Local *.alogins.net web services (family wiki / OtterWiki, РодоВики) —
|
|
# same hairpin-NAT dodge: the public A record can't loop back through the
|
|
# router from inside a container, so route the hostname to the host
|
|
# gateway where Caddy terminates TLS on :443 and proxies to the service.
|
|
# Lets Adolf's OpenClaw browser reach them with the real URL + the
|
|
# Vaultwarden creds. Add more *.alogins.net hosts here as needed.
|
|
- "family.alogins.net:host-gateway"
|
|
- "wiki.alogins.net:host-gateway"
|
|
cap_drop:
|
|
- NET_RAW
|
|
- NET_ADMIN
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
init: true
|
|
ports:
|
|
- "18789:18789"
|
|
- "18790:18790"
|
|
command:
|
|
["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789"]
|
|
restart: unless-stopped
|
|
|
|
# hindsight-llm — standalone clone of cognee-llm (kb#76, H4 option B): the
|
|
# dedicated Kimi-CLI wrapper that is now Hindsight's LLM, so the whole cognee
|
|
# stack (incl. cognee-llm) can be decommissioned. Own port (:8012) + own
|
|
# kimi-code volume; needs a one-time `kimi login` seeded into hindsight-llm-home.
|
|
hindsight-llm:
|
|
build: ./hindsight-llm
|
|
container_name: hindsight-llm
|
|
ports:
|
|
- "8012:8012"
|
|
volumes:
|
|
- hindsight-llm-home:/root/.kimi-code
|
|
restart: unless-stopped
|
|
|
|
# adolf-llm — conversational Kimi-CLI wrapper (:8010), the model backend for
|
|
# the Adolf OpenClaw gateway (P2). Real streaming (SSE), chat_id session-keying
|
|
# + 1:1 kimi resume, media, per-session .mcp.json sourced from the shared
|
|
# shared-mcp.json contract (cognee-mcp P4, openclaw-tools P5). Needs
|
|
# `kimi login` in adolf-llm-home.
|
|
adolf-llm:
|
|
build: ./adolf-llm
|
|
container_name: adolf-llm
|
|
ports:
|
|
- "8010:8010"
|
|
volumes:
|
|
- adolf-llm-workspace:/workspace
|
|
- adolf-llm-home:/root/.kimi-code
|
|
- ./shared-mcp.json:/shared-mcp.json:ro
|
|
extra_hosts:
|
|
# Needed to reach kanboard-mcp-adolf (:3104, network_mode: host, outside
|
|
# this compose project's network) via shared-mcp.json's "kanboard"
|
|
# entry — same host-gateway trick used by adolf/cognee/pipecat above.
|
|
- "host.docker.internal:host-gateway"
|
|
# Local *.alogins.net web services: the Kimi CLI's own web-fetch tool
|
|
# runs IN THIS container, so it needs the same hairpin-NAT dodge as the
|
|
# adolf gateway (the public A record can't loop back through the router).
|
|
# Route to the host gateway where Caddy terminates TLS on :443.
|
|
- "family.alogins.net:host-gateway"
|
|
- "wiki.alogins.net:host-gateway"
|
|
restart: unless-stopped
|
|
|
|
# hindsight — Adolf memory backend, replacing cognee/cognee-mcp/cognee-llm
|
|
# (kb#73, migration doc agap_git/adolf/HINDSIGHT-MIGRATION.md, H1). One
|
|
# container: REST API :8888 (also serves the built-in MCP at /mcp/{bank}/),
|
|
# UI :9999, built-in Postgres (pg0) bind-mounted to
|
|
# /mnt/ssd/dbs/hindsight/ (host dir created + chowned 1000:1000 to match
|
|
# the image's non-root `hindsight` user, confirmed via
|
|
# `docker run --entrypoint id`).
|
|
#
|
|
# LLM + embeddings reconfigured 2026-07-15 (kb#84) to fix two wrong H1
|
|
# choices for a Russian/multilingual use case:
|
|
#
|
|
# LLM -> hindsight-llm:8012 (dedicated Kimi-CLI wrapper cloned from the shim cognee
|
|
# uses — see cognee/cognee.env's LLM section for the full precedent,
|
|
# including why LLM_INSTRUCTOR_MODE=json_mode isn't needed here since
|
|
# Hindsight's own client doesn't go through `instructor`). Replaces the
|
|
# H1 choice of LiteLLM + ollama/gemma3:4b (a tiny local model): validated
|
|
# 2026-07-15 that cognee-llm returns clean, JSON-parseable structured
|
|
# extraction for Russian input (see kb#84 probe B) — gemma3:4b's fluency
|
|
# on Russian was never actually verified, it was picked only to dodge
|
|
# qwen3:8b's <think>-token empty-content bug. Kimi is also the flat-rate
|
|
# subscription already paid for, so this isn't a new cost.
|
|
#
|
|
# Embeddings -> ollama's bge-m3 on the GPU (host.docker.internal:11436,
|
|
# separate compose project, same extra_hosts trick as cognee/adolf-llm
|
|
# below), via ollama's OpenAI-compatible /v1/embeddings endpoint
|
|
# (confirmed 200 + 1024-dim vector 2026-07-15, kb#84 probe A). Replaces
|
|
# the H1 choice of Hindsight's built-in `local` provider
|
|
# (BAAI/bge-small-en-v1.5, English-only, 384-d, CPU-bound in-process
|
|
# SentenceTransformers). The hindsight image itself is CPU-only (torch
|
|
# +cpu build, no onnxruntime GPU provider — confirmed 2026-07-15), so its
|
|
# in-process local/onnx embedders can never reach the GPU; routing
|
|
# through ollama's `openai` embeddings provider (HTTP, not the bespoke
|
|
# cognee-style `ollama` provider Hindsight doesn't have) is how GPU
|
|
# serving happens here. Dimensions var matches cognee.env's own bge-m3
|
|
# swap (kb#60): 1024.
|
|
#
|
|
# Runs ALONGSIDE cognee/cognee-mcp/cognee-llm during the migration; those
|
|
# are untouched here and only decommissioned in H4, after H2/H3/H5 prove
|
|
# this service out. Not yet wired into openclaw.json/shared-mcp.json
|
|
# (that's H2, kb#74) — this block only stands the service up and proves
|
|
# retain/recall against a throwaway bank.
|
|
hindsight:
|
|
image: ghcr.io/vectorize-io/hindsight:latest
|
|
container_name: hindsight
|
|
restart: unless-stopped
|
|
environment:
|
|
# ALL stages on the local model (alvis, 2026-07-26): retain/extraction
|
|
# moved OFF Kimi (hindsight-llm:8012) onto ollama/gemma3:4b via LiteLLM,
|
|
# joining consolidation + reflect which were already local. Kimi is no
|
|
# longer in the Hindsight path at all, so the memory backend costs zero
|
|
# quota and Adolf's 5h window is left entirely for conversation.
|
|
#
|
|
# ⚠️ Accepted tradeoff: the kb#88/kb#84 rationale for keeping retain on
|
|
# Kimi was fact QUALITY — gemma3:4b's Russian fluency was never verified
|
|
# (it was originally picked only to dodge qwen3:8b's <think>-token bug),
|
|
# and this bank's content is largely Russian. Watch extraction quality on
|
|
# the next retains; if facts degrade, this is the first thing to revert.
|
|
- HINDSIGHT_API_LLM_PROVIDER=openai
|
|
- HINDSIGHT_API_LLM_BASE_URL=http://litellm:4000/v1
|
|
- HINDSIGHT_API_LLM_MODEL=ollama/gemma3:4b
|
|
- HINDSIGHT_API_LLM_API_KEY=sk-fjQC1BxAiGFSMs
|
|
- HINDSIGHT_API_CONSOLIDATION_LLM_PROVIDER=openai
|
|
- HINDSIGHT_API_CONSOLIDATION_LLM_BASE_URL=http://litellm:4000/v1
|
|
- HINDSIGHT_API_CONSOLIDATION_LLM_MODEL=ollama/gemma3:4b
|
|
- HINDSIGHT_API_CONSOLIDATION_LLM_API_KEY=sk-fjQC1BxAiGFSMs
|
|
- HINDSIGHT_API_REFLECT_LLM_PROVIDER=openai
|
|
- HINDSIGHT_API_REFLECT_LLM_BASE_URL=http://litellm:4000/v1
|
|
- HINDSIGHT_API_REFLECT_LLM_MODEL=ollama/gemma3:4b
|
|
- HINDSIGHT_API_REFLECT_LLM_API_KEY=sk-fjQC1BxAiGFSMs
|
|
- HINDSIGHT_API_EMBEDDINGS_PROVIDER=openai
|
|
- HINDSIGHT_API_EMBEDDINGS_OPENAI_BASE_URL=http://host.docker.internal:11436/v1
|
|
- HINDSIGHT_API_EMBEDDINGS_OPENAI_MODEL=bge-m3
|
|
- HINDSIGHT_API_EMBEDDINGS_OPENAI_DIMENSIONS=1024
|
|
# ollama doesn't check this value at all (no auth), but the openai
|
|
# embeddings client requires a non-empty key to construct.
|
|
- HINDSIGHT_API_EMBEDDINGS_OPENAI_API_KEY=ollama
|
|
# Stable worker id (compose service name), not the container hostname
|
|
# default -- without this, recreating the container orphans any
|
|
# in-flight async retain/consolidation tasks under the old hostname
|
|
# (startup log warns about exactly this).
|
|
- HINDSIGHT_API_WORKER_ID=hindsight
|
|
# Reranker -> multilingual (kb#84 follow-up). The TEMPR rerank stage
|
|
# defaulted to English cross-encoder/ms-marco-MiniLM, which ranks
|
|
# Russian/multilingual candidates poorly. jina v2 multilingual fixes
|
|
# that. Runs on CPU in this image (no CUDA torch) but only over the
|
|
# small recall candidate set. trust_remote_code: jina ships custom code.
|
|
- HINDSIGHT_API_RERANKER_PROVIDER=local
|
|
- HINDSIGHT_API_RERANKER_LOCAL_MODEL=jinaai/jina-reranker-v2-base-multilingual
|
|
- HINDSIGHT_API_RERANKER_LOCAL_TRUST_REMOTE_CODE=true
|
|
volumes:
|
|
- /mnt/ssd/dbs/hindsight:/home/hindsight/.pg0
|
|
# Persist HuggingFace/sentence-transformers model cache so the jina
|
|
# reranker (~1GB) doesn't re-download on every container recreate.
|
|
- /mnt/ssd/dbs/hindsight-cache:/home/hindsight/.cache
|
|
ports:
|
|
- "8888:8888"
|
|
- "9999:9999"
|
|
extra_hosts:
|
|
# Needed to resolve host.docker.internal from inside the container
|
|
# for the ollama embeddings call above — ollama lives in a separate
|
|
# compose project, same trick as cognee/adolf-llm elsewhere in this
|
|
# file.
|
|
- "host.docker.internal:host-gateway"
|
|
depends_on:
|
|
- hindsight-llm
|
|
|
|
# openclaw-tools — MCP bridge (P5) exposing a minimal slice of the Adolf
|
|
# OpenClaw gateway's agent tools (message/cron/nodes/browser) over MCP
|
|
# Streamable HTTP, so Kimi CLI sessions (adolf-llm) can call them instead of
|
|
# bypassing OpenClaw entirely. Proxies each MCP tool call to the gateway's
|
|
# `POST /tools/invoke` HTTP surface (http://adolf:18789). NOTE: `cron` and
|
|
# `nodes` are hard-denied on that surface by default until P6 adds them to
|
|
# `gateway.tools.allow` in the adolf openclaw.json — see openclaw-tools/
|
|
# server.js for the full gate writeup. Not useful until `adolf` (P6) is
|
|
# configured and running; safe to build/run standalone before that.
|
|
openclaw-tools:
|
|
build: ./openclaw-tools
|
|
container_name: openclaw-tools
|
|
environment:
|
|
- OPENCLAW_GATEWAY_URL=http://adolf:18789
|
|
- OPENCLAW_GATEWAY_TOKEN=${ADOLF_GATEWAY_TOKEN:-}
|
|
ports:
|
|
- "8020:8020"
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
kimi-agent-home:
|
|
adolf-state:
|
|
hindsight-llm-home:
|
|
adolf-llm-workspace:
|
|
adolf-llm-home:
|