diff --git a/ai/compose.yml b/ai/compose.yml index f699af1..971caf4 100644 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -185,6 +185,94 @@ services: - "traefik.http.services.paperclip.loadbalancer.server.port=3100" + # --------------------------------------------------------------------------- + # Honcho — Memory infrastructure for stateful AI agents + # Self-hosted memory server with pgvector for embedding storage. + # Defaults to Ollama for embeddings; configure LLM provider for full deriver + # and summarization support. + # + # API port: 8000 + # Web: https://honcho.lazyworkhorse.net + # Docs: https://github.com/plastic-labs/honcho + # --------------------------------------------------------------------------- + + honcho-db: + image: pgvector/pgvector:pg17-trixie + container_name: honcho-db + restart: unless-stopped + environment: + POSTGRES_DB: honcho + POSTGRES_USER: honcho + POSTGRES_PASSWORD: ${HONCHO_DB_PASSWORD:?HONCHO_DB_PASSWORD must be set} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U honcho -d honcho"] + interval: 5s + timeout: 5s + retries: 10 + volumes: + - /mnt/HoardingCow_docker_data/Honcho/pgdata:/var/lib/postgresql/data + - ./honcho/init.sql:/docker-entrypoint-initdb.d/init.sql + networks: + - ai_backend + + honcho: + build: + context: ./honcho + dockerfile: Dockerfile + container_name: honcho + restart: unless-stopped + ports: + - "127.0.0.1:8000:8000" + depends_on: + honcho-db: + condition: service_healthy + environment: + DB_CONNECTION_URI: postgresql+psycopg://honcho:${HONCHO_DB_PASSWORD:?HONCHO_DB_PASSWORD must be set}@honcho-db:5432/honcho + LOG_LEVEL: INFO + LLM_OPENAI_API_KEY: ${LLM_OPENAI_API_KEY:-ollama} + volumes: + - /mnt/HoardingCow_docker_data/Honcho/config.toml:/app/config.toml + networks: + - ai_backend + - ai_net + labels: + - "traefik.enable=true" + - "traefik.docker.network=ai_net" + + - "traefik.http.routers.honcho-http.rule=Host(`honcho.lazyworkhorse.net`)" + - "traefik.http.routers.honcho-http.entrypoints=web" + - "traefik.http.routers.honcho-http.middlewares=redirect-to-https" + + - "traefik.http.routers.honcho-https.rule=Host(`honcho.lazyworkhorse.net`)" + - "traefik.http.routers.honcho-https.entrypoints=websecure" + - "traefik.http.routers.honcho-https.tls=true" + - "traefik.http.routers.honcho-https.tls.certresolver=njalla" + + - "traefik.http.services.honcho.loadbalancer.server.port=8000" + + holographic-memory: + build: + context: ./holographic-memory + image: holographic-memory:latest + container_name: holographic-memory + restart: unless-stopped + ports: + - "127.0.0.1:8100:8100" + environment: + - HOLOGRAPHIC_DB_PATH=/data/holographic/memory_store.db + - HOLOGRAPHIC_PORT=8100 + - HOLOGRAPHIC_DEFAULT_TRUST=0.5 + volumes: + - /mnt/HoardingCow_docker_data/HolographicMemory:/data/holographic + networks: + - ai_backend + healthcheck: + test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8100/health')"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + networks: ai_net: external: true diff --git a/ai/honcho/Dockerfile b/ai/honcho/Dockerfile new file mode 100644 index 0000000..b799ff8 --- /dev/null +++ b/ai/honcho/Dockerfile @@ -0,0 +1,72 @@ +# Honcho — Memory infrastructure for stateful AI agents +# Builds the Honcho FastAPI server from the official GitHub repository. +# +# Usage: +# docker compose build honcho +# docker compose up honcho +# +# Reference: https://github.com/plastic-labs/honcho + +# --------------------------------------------------------------------------- +# Stage 1 — clone source & install dependencies +# --------------------------------------------------------------------------- +FROM python:3.13-slim-bookworm AS builder + +RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* + +COPY --from=ghcr.io/astral-sh/uv:0.9.24 /uv /bin/uv + +WORKDIR /src +RUN git clone --depth 1 --branch main https://github.com/plastic-labs/honcho.git . + +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy + +# Install project dependencies (frozen from lockfile, no dev) +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --frozen --no-install-project --no-group dev + +# --------------------------------------------------------------------------- +# Stage 2 — runtime image +# --------------------------------------------------------------------------- +FROM python:3.13-slim-bookworm AS runtime + +COPY --from=ghcr.io/astral-sh/uv:0.9.24 /uv /bin/uv + +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +ENV UV_COMPILE_BYTECODE=1 +ENV UV_LINK_MODE=copy +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 +ENV PATH="/app/.venv/bin:$PATH" +ENV HOME=/app +ENV UV_CACHE_DIR=/tmp/uv-cache + +# Copy the dependency layer from the builder +COPY --from=builder /src/uv.lock /src/pyproject.toml /app/ +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --frozen --no-group dev + +# Copy application source and config +COPY --from=builder /src/src/ /app/src/ +COPY --from=builder /src/migrations/ /app/migrations/ +COPY --from=builder /src/scripts/ /app/scripts/ +COPY --from=builder /src/docker/ /app/docker/ +COPY --from=builder /src/alembic.ini /app/alembic.ini + +# Create non-root user +RUN addgroup --system app && \ + adduser --system --ingroup app app && \ + mkdir -p /tmp/uv-cache && \ + chown -R app:app /app /tmp/uv-cache + +USER app +EXPOSE 8000 + +# The entrypoint.sh script runs database migrations then starts the FastAPI server +ENTRYPOINT ["sh", "docker/entrypoint.sh"] diff --git a/ai/honcho/init.sql b/ai/honcho/init.sql new file mode 100644 index 0000000..0aa0fc2 --- /dev/null +++ b/ai/honcho/init.sql @@ -0,0 +1 @@ +CREATE EXTENSION IF NOT EXISTS vector; diff --git a/build/honcho/config.toml b/build/honcho/config.toml new file mode 100644 index 0000000..4915eb5 --- /dev/null +++ b/build/honcho/config.toml @@ -0,0 +1,93 @@ +# Honcho Configuration +# Pre-configured for self-hosted deployment with Ollama embeddings. +# Mount this file at /app/config.toml in the Honcho container. +# +# Environment variables override these values at runtime +# (e.g. DB_CONNECTION_URI, DERIVER_*). + +[app] +LOG_LEVEL = "INFO" +NAMESPACE = "honcho" +SESSION_OBSERVERS_LIMIT = 10 +GET_CONTEXT_MAX_TOKENS = 16384 +EMBED_MESSAGES = true + +[db] +# Connection URI is set via environment variable DB_CONNECTION_URI +SCHEMA = "public" +POOL_SIZE = 10 +MAX_OVERFLOW = 20 +POOL_TIMEOUT = 30 +POOL_RECYCLE = 300 +POOL_PRE_PING = true +POOL_USE_LIFO = true +SQL_DEBUG = false + +[auth] +USE_AUTH = false + +[llm] +DEFAULT_MAX_TOKENS = 4096 + +[embedding] +VECTOR_DIMENSIONS = 768 +MAX_INPUT_TOKENS = 8192 +MAX_TOKENS_PER_REQUEST = 2048 + +[embedding.model_config] +transport = "openai" +model = "nomic-embed-text:latest" + +[embedding.model_config.overrides] +base_url = "http://ollama:11434/v1" +# Ollama does not require an API key; env var must be set to non-empty string +api_key_env = "LLM_OPENAI_API_KEY" + +[deriver] +ENABLED = false +WORKERS = 1 +POLLING_SLEEP_INTERVAL_SECONDS = 1.0 +STALE_SESSION_TIMEOUT_MINUTES = 5 +DEDUPLICATE = true +LOG_OBSERVATIONS = false + +[deriver.model_config] +transport = "openai" +model = "qwen3.6:27b-q4_K_M" + +[deriver.model_config.overrides] +base_url = "http://ollama:11434/v1" +api_key_env = "LLM_OPENAI_API_KEY" + +[summary] +ENABLED = false + +[summary.model_config] +transport = "openai" +model = "qwen3.6:27b-q4_K_M" + +[summary.model_config.overrides] +base_url = "http://ollama:11434/v1" +api_key_env = "LLM_OPENAI_API_KEY" + +[dream] +ENABLED = false + +[dialectic] +MAX_OUTPUT_TOKENS = 4096 +MAX_INPUT_TOKENS = 16384 + +[cache] +ENABLED = false + +[vector_store] +TYPE = "pgvector" + +[metrics] +ENABLED = false + +[telemetry] +ENABLED = false + +[sentry] +ENABLED = false diff --git a/env/.env.example.honcho b/env/.env.example.honcho new file mode 100644 index 0000000..3dc59bc --- /dev/null +++ b/env/.env.example.honcho @@ -0,0 +1,31 @@ +# Honcho Environment Variables +# Copy this file to your .env (at the compose root or docker-compose working directory) +# and fill in the secrets. +# +# cp env/.env.example.honcho .env +# +# Then reference it from compose.yml: +# env_file: +# - path: .env +# required: true + +# --------------------------------------------------------------------------- +# Database +# --------------------------------------------------------------------------- +# PostgreSQL connection string for Honcho. +# The password must match HONCHO_DB_PASSWORD below. +HONCHO_DB_PASSWORD=change_me_to_a_strong_random_password + +# --------------------------------------------------------------------------- +# LLM Provider +# --------------------------------------------------------------------------- +# Ollama does not require a real API key, but the env var must be set to a +# non-empty string for the OpenAI-compatible client to connect. +LLM_OPENAI_API_KEY=ollama + +# --------------------------------------------------------------------------- +# Honcho Server +# --------------------------------------------------------------------------- +# Honcho will pick up DB_CONNECTION_URI from the compose environment. +# You can override additional settings here if needed. +# LOG_LEVEL=INFO