Per DESIGN-a2a-agents.md v2.1 §2-3b: models are the scarce queued
resource, version-controlled here rather than hardcoded in callers.
- model-registry.yaml: kimi (main reasoning, quota-gated), local-small
(ollama/gemma3:4b, always-on cheap tier), bge-m3 (embedder + routing
classifier, never-evict), tei-reranker (never-evict, interactive-
critical), paid-fallback (metered, opt-in only, unreachable by
default via empty routing.metered_opt_in). GPU residency policy
carries the never-evict set, co-residency groups, and measured
baseline (bge-m3+gemma3:4b+tei-reranker ~6.2/8GB on the GTX 1070).
- model_registry.py: resolve(tier) picks an available model without
the caller naming one, gated so a metered model is only reachable
with both allow_metered=True and an opted-in virtual key;
to_probe_config() bridges registry quota data into kb_worker.py's
existing Probe classes (no duplicated probe logic); preload_check()
expresses the §3b pre-load VRAM check purely from registry data.
Gap noted for follow-up: bge-m3 has no litellm-config.yaml model_list
entry yet (embedder there still points at ollama/nomic-embed-text on
a different port) — out of scope here, registry documents it as-is.
Per-stage LLM routing so Hindsight's high-volume background jobs stop burning
the rate-limited Kimi subscription:
- CONSOLIDATION + REFLECT -> ollama/gemma3:4b via LiteLLM :4000 (local GPU, free)
- RETAIN (fact extraction) stays on Kimi (hindsight-llm) for quality
Fixes the Kimi 5h window maxing at 100% from ~1100 background calls/3h (dropped
to ~38%). Documents the reasoning in HINDSIGHT-MIGRATION.md section 10:
frequent/mechanical/background stages -> cheap local model; user-facing,
quality-critical, low-volume -> Kimi.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Qg9gi7H7HtT8MncoXAB
The bridge advertised non-existent gateway actions ("click"/"type"), so Kimi
sent action="type" -> "Unknown action". Corrected to the real vocabulary:
interactions go through action="act" with args={kind, ref, text} (e.g.
{kind:"type", ref:"e59", text:"..."}, {kind:"click", ref}), plus the real
top-level actions (open/navigate/snapshot/screenshot/act/...). Verified Adolf
can now type/click in the browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Qg9gi7H7HtT8MncoXAB
- openclaw.json: browser.enabled + noSandbox (containers can't sandbox) +
ssrfPolicy.dangerouslyAllowPrivateNetwork (local *.alogins.net resolve to
the private host gateway); "browser" added to gateway.tools.allow.
- docker-compose.yml: extra_hosts family.alogins.net / wiki.alogins.net ->
host-gateway on both adolf and adolf-llm, so the gateway browser AND the
Kimi CLI's fetch reach the local wikis (hairpin-NAT dodge, like matrix).
Enables Adolf to open + log into the family wiki (kb#64). Root 401 on the
openclaw-tools bridge was a separate fix (empty ADOLF_GATEWAY_TOKEN -> just
recreate the bridge container; no file change).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Qg9gi7H7HtT8MncoXAB
H4 (kb#76) - Cognee -> Hindsight migration finished:
- New openai/hindsight-llm/ (clone of cognee-llm, :8012, own volume) so
Hindsight's Kimi LLM no longer depends on the cognee stack
- Repointed hindsight service LLM at hindsight-llm:8012 (+ depends_on)
- Removed cognee, cognee-mcp, cognee-llm services + cognee-llm-home volume
from openai/docker-compose.yml
- Removed the disabled cognee-memory plugin entry from openclaw.json
Vault access (kb#64): wired the shared agap-mcp (:3100, same MCP Claude uses)
into Adolf's registry - "agap" server in shared-mcp.json + openclaw.json
mcp.servers. Adolf can now fetch credentials from Vaultwarden (verified).
Note: agap-mcp/docker-compose.yml (repointed to the adolf46 account) is
deliberately NOT in this commit - it holds the master password in plaintext.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014t8Qg9gi7H7HtT8MncoXAB
Relocate the OpenClaw gateway config from openai/adolf/ to adolf/ at
the repo root, since it's shared config rather than part of the
openai/ compose project's own tree. Update the docker-compose.yml
bind-mount path (./adolf/openclaw.json -> ../adolf/openclaw.json) and
comments, plus README.md references, to match. Verified: adolf
container recreated healthy with the new bind-mount source resolving
to /home/alvis/agap_git/adolf/openclaw.json, and a fresh
openclaw.json.last-good snapshot confirms the config was accepted.
Replace nomic-embed-text (768-d) with bge-m3 (1024-d, GPU-served via the
same :11436 ollama) as cognee's embedding model, for better multilingual
recall. cognee's Qdrant collections held only P4 smoke-test fixtures (no
real conversation data — adolf-llm's cogneeSearch/cogneeAdd are still
stubs), so the stale 768-d collections were dropped and left for cognee
to recreate at 1024-d on next write, rather than migrated.
Verified: bge-m3 returns 1024-dim vectors via ollama /api/embed; after
recreating the cognee container, a remember/recall round trip (including
Russian text) produced correctly dimensioned (1024-d) Qdrant collections
and recalled the exact fact stored, then the test dataset was deleted.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Build adolf:local with the matrix extension bundled (OPENCLAW_EXTENSIONS),
route mtx.alogins.net to host-gateway to dodge hairpin NAT, and wire
ADOLF_KEY/Matrix creds through openai/.env (now gitignored + untracked;
it previously held Langfuse keys in cleartext git history). Runtime
openclaw.json + SOUL.md live in the adolf-state volume, not this repo.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
- adolf-llm/server.js now loads SHARED_MCP_SERVERS from the mounted
/shared-mcp.json instead of a hardcoded stub, so adding a shared MCP
server is a one-file change. Verified end-to-end: a real chat-completions
turn writes a session .mcp.json containing both cognee and openclaw-tools
entries (kimi itself still needs `kimi login` in adolf-llm-home, unrelated
to this change).
- Documented the Gate-1 transport reconciliation: decompiled the installed
@moonshot-ai/kimi-code package to confirm its .mcp.json schema keys remote
servers on `transport` ("stdio"/"http"/"sse", inferred as "http" from a
bare `url`, never "sse"), while OpenClaw's own canonical mcp.servers schema
uses different literals ("streamable-http"/"sse") for the same field name
and treats `type` as a CLI-native alias it normalizes itself. `type: "http"`
is the one shape both consumers tolerate, so shared-mcp.json keeps it.
- New openai/openclaw-tools/ service: a stateless MCP-over-Streamable-HTTP
bridge (Node, @modelcontextprotocol/sdk) exposing message_send, cron_create,
cron_list, nodes_invoke, and browser_invoke, each proxying to the OpenClaw
gateway's POST /tools/invoke. Verified initialize + tools/list handshake and
a tools/call against the not-yet-running `adolf` gateway returns a clean
isError content instead of breaking the MCP connection. Documented that
cron/nodes are hard-denied on that HTTP surface by default until P6 adds
them to gateway.tools.allow; message/browser are not similarly restricted.
- Wired openclaw-tools into docker-compose.yml (openai network, :8020) and
added its shared-mcp.json entry alongside cognee.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Resolves the 4 P4 blockers and wires cognee/cognee-mcp into the openai
compose stack:
- qdrant: container was gone (data intact under /mnt/ssd/dbs/qdrant);
brought back up, confirmed healthy on :6333.
- Embeddings: switched from a dead LiteLLM route to ollama directly
(host.docker.internal:11436, nomic-embed-text, 768-dim), using cognee's
dedicated OllamaEmbeddingEngine and its native /api/embed endpoint.
Requires extra_hosts: host.docker.internal:host-gateway since ollama
lives in a separate compose project.
- cognee-llm kimi auth: root cause was that cognee-llm had never been
started, so its kimi-agent-home-equivalent volume didn't exist yet.
Seeded cognee-llm-home from the already-authed kimi-agent-home volume
(read-only copy of config/credentials/oauth/device_id); cognee-llm now
serves real completions.
- mkdir'd cognee data/system dirs: confirmed present (done by user).
Also fixed three issues found only during a live end-to-end smoke test:
- VECTOR_DB_PROVIDER must be a real container env var, not just present in
the mounted cognee.env — the qdrant adapter's sitecustomize.py
registration hook reads os.environ directly, which pydantic-settings'
env_file parsing never populates.
- Baked the Kuzu/Ladybug JSON extension into the cognee image. This
deployment's egress to extension.ladybugdb.com is bandwidth-throttled to
~1.2 KB/s, so cognee's own runtime auto-download reliably timed out,
leaving /health permanently unhealthy and graph queries failing. Fetched
the ~827KB extension out-of-band (16-way parallel ranged GETs) and added
it to the image via COPY.
- LLM_ENDPOINT needed an explicit /v1 suffix (litellm appends
"/chat/completions" verbatim) and LLM_INSTRUCTOR_MODE=json_mode is
required since cognee-llm's Kimi wrapper is a text-only pass-through with
no real tool-calling support.
Verified with a full remember -> recall round trip through cognee-mcp's
MCP tool surface: stored a fact containing a codeword, recalled it via
GRAPH_COMPLETION search, got the exact codeword back. Exercises cognee-llm,
ollama embeddings, Qdrant, and Kuzu together.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Reverse the earlier 'default to LiteLLM' recommendation: per user intent,
cognee runs its LLM on the Kimi subscription via cognee-llm (the reason the
wrapper exists). Gate-5 latency is an accepted tradeoff; LiteLLM stays a
documented fallback. Embeddings remain on LiteLLM nomic-embed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Model backend for the Adolf gateway. OpenAI-compatible (model 'adolf'), real
SSE streaming, chat_id session-keying (parsed from OpenClaw's untrusted-metadata
block per SPIKE gate 2) -> 1:1 kimi -r resume, media persistence for the CLI's
ReadMediaFile, per-session project-root .mcp.json (gate 1; no --mcp-config-file).
Cognee auto-memory hooks and shared-MCP server list are non-blocking stubs with
TODO(P4/P5) markers. New service + workspace/home volumes in compose.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Stateless one-shot wrapper for Cognee batch cognify: fresh temp dir per
request, no resume, non-streaming, text-only, bounded concurrency (3).
Per SPIKE-FINDINGS gate 5, Cognee should default its LLM to LiteLLM; this is
the optional low-volume path. New service + cognee-llm-home volume in compose.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
New 'adolf' service builds ../../adolf (the OpenClaw fork), runs the gateway
(node dist/index.js gateway --bind lan --port 18789) with persistent
adolf-state volume. Skeleton only; Matrix/SOUL.md/model-provider config wired
in P6. Existing services untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Wrapper previously passed only the last user message to a fresh 'kimi -p'
per request, so both the OpenWebUI thread history and kimi's own session
state were dropped every turn.
Now each conversation is keyed by a content-hash chain over the messages
array (survives LiteLLM in between) and mapped to a persistent kimi session
resumed via 'kimi -r <id>', with the session_id captured from stream-json
meta. Each conversation also gets its own working dir under
/workspace/conversations/<id> so file state is isolated and persists across
turns. Map persisted to /workspace/.kimi-agent/sessions.json (LRU-capped);
falls back to full-transcript reseed if a mapping is missing.
Runs the kimi-code coding agent in its own container, exposed as an
OpenAI-compatible model ("kimi-agent") that LiteLLM/Open WebUI can call
directly. Backed by the user's own Kimi/Moonshot subscription via
`kimi login`, not the pay-per-token API. Mount is scoped to a dedicated
~/kimi-workspace directory rather than the full home dir.
Accumulated uncommitted infra changes:
- Caddyfile: repoint HA/Zabbix to 192.168.1.4/.3, add ~20 new site routes
- Immich: move media to /mnt/smsg, enable CUDA ML, mem limits, rewrite backup.sh
- Add service stacks: agap-mcp, anki, family, freshrss, iperf3, kanboard,
linkwarden, qbittorrent, radicale, syncthing, vikunja, windows
- openwebui: enable API keys; ollama: drop CPU fallback
- seafile/zabbix: extra_hosts entries; matrix: add user juris
- Remove pihole stack and stale wiki/migrate.py
- Ignore marketplace-mcp (standalone repo) and linkwarden runtime data
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
Move services out of the monolithic openai/docker-compose.yml:
- ollama/ — ollama GPU + CPU inference servers
- openwebui/ — open-webui chat UI (uses env var for ANTHROPIC_API_KEY)
- searxng/ — SearXNG container + searxng-mcp MCP server (port 3102)
openai/ now contains only: litellm, langfuse, qdrant, faster-whisper,
silero-tts, pipecat.
searxng-mcp exposes a single searxng_search tool via MCP HTTP on :3102.
Registered in ~/.claude.json as the "searxng" MCP server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LiteLLM proxy with langfuse callbacks, postgres backends, and OpenRouter fallbacks.
- Langfuse observability UI.
- Pipecat voice pipeline (LiveKit + STT + TTS + LLM) and Silero TTS build contexts.
- Ollama tuned for GPU (OLLAMA_NUM_GPU=999, mem_limit=4g, max 2 loaded models).
- open-webui wired to litellm + faster-whisper + silero for voice.
- litellm-config.yaml publishes oO's model aliases (tip-generator, embedder, judge)
pointing at the host ollama on :11434 so ml/serving can call them via LiteLLM.
.env skipped (secrets).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add CLAUDE.md with Gitea integration, development guidelines, and wiki interaction instructions
- Add comprehensive README.md with service overview, quick start, and configuration details
- Add service directories: gitea/, openai/, immich-app/, and setup scripts (install-cuda.sh, nvidia-docker-install.sh)
- Update docker-compose.yml structure and immich configuration
- Include restore example script for Immich database backups
This repository now serves as the source of truth for Docker Compose configurations and deployment automation for Agap home server services (Immich, Gitea, Open WebUI).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>