# syntax=docker/dockerfile:1
# dockerfiles/Dockerfile.hermes-webui
FROM ghcr.io/nesquena/hermes-webui@sha256:a83a3893111dcb250e7aa7aa657d3d6f4570b0e2fd00d9b7569246fc5e7339b2 AS webui

FROM registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f

USER root

# Keep WebUI and Hermes pinned together. The WebUI imports Hermes internals,
# while the gateway remains the only process that owns an agent conversation.
COPY --from=webui /apptoo /opt/hermes-webui

# The account policy caps user-selected reasoning at xhigh even when a provider
# advertises a newer, more expensive level.
RUN /opt/hermes/.venv/bin/python - <<'PY'
from pathlib import Path

config = Path("/opt/hermes-webui/api/config.py")
source = config.read_text(encoding="utf-8")
before = 'VALID_REASONING_EFFORTS = ("minimal", "low", "medium", "high", "xhigh", "max")'
after = 'VALID_REASONING_EFFORTS = ("minimal", "low", "medium", "high", "xhigh")'
if before not in source:
    raise SystemExit("Hermes WebUI reasoning-effort patch context changed")
config.write_text(source.replace(before, after, 1), encoding="utf-8")

index = Path("/opt/hermes-webui/static/index.html")
source = index.read_text(encoding="utf-8")
before = '            <div class="reasoning-option" data-effort="max">Max</div>\n'
if before not in source:
    raise SystemExit("Hermes WebUI xhigh UI patch context changed")
index.write_text(source.replace(before, "", 1), encoding="utf-8")
PY

RUN /opt/hermes/.venv/bin/python -c 'import cryptography, yaml' \
    && grep -Fq 'VALID_REASONING_EFFORTS = ("minimal", "low", "medium", "high", "xhigh")' \
        /opt/hermes-webui/api/config.py \
    && ! grep -Fq 'data-effort="max"' /opt/hermes-webui/static/index.html

# Exercise the real server process in the target architecture before publish.
RUN set -eu; \
    mkdir -p /tmp/hermes-webui-smoke/home /tmp/hermes-webui-smoke/state /tmp/hermes-webui-smoke/workspace; \
    HERMES_HOME=/tmp/hermes-webui-smoke/home \
    HOME=/tmp/hermes-webui-smoke/home \
    HERMES_WEBUI_STATE_DIR=/tmp/hermes-webui-smoke/state \
    HERMES_WEBUI_DEFAULT_WORKSPACE=/tmp/hermes-webui-smoke/workspace \
    HERMES_WEBUI_HOST=127.0.0.1 \
    HERMES_WEBUI_PORT=18787 \
    HERMES_WEBUI_SKIP_ONBOARDING=1 \
    /opt/hermes/.venv/bin/python /opt/hermes-webui/server.py >/tmp/hermes-webui-smoke.log 2>&1 & \
    server_pid=$!; \
    ready=0; \
    for attempt in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do \
      if /opt/hermes/.venv/bin/python -c 'from urllib.request import urlopen; urlopen("http://127.0.0.1:18787/health", timeout=2).read()' >/dev/null 2>&1; then ready=1; break; fi; \
      sleep 1; \
    done; \
    kill "${server_pid}" 2>/dev/null || true; \
    wait "${server_pid}" 2>/dev/null || true; \
    if [ "${ready}" != "1" ]; then cat /tmp/hermes-webui-smoke.log; exit 1; fi; \
    rm -rf /tmp/hermes-webui-smoke /tmp/hermes-webui-smoke.log

ENV HERMES_WEBUI_AGENT_DIR=/opt/hermes \
    HERMES_WEBUI_HOST=0.0.0.0 \
    HERMES_WEBUI_PORT=8787 \
    HERMES_WEBUI_CHAT_BACKEND=gateway \
    HERMES_WEBUI_GATEWAY_BASE_URL=http://127.0.0.1:8642 \
    HERMES_WEBUI_GATEWAY_USE_RUNS_API=true \
    HERMES_WEBUI_SKIP_ONBOARDING=1 \
    HERMES_WEBUI_SECURE=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /opt/hermes-webui
USER 10000:10000
EXPOSE 8787
ENTRYPOINT ["/opt/hermes/.venv/bin/python", "/opt/hermes-webui/server.py"]
