ml-intern / Dockerfile
bep40's picture
Add dataset-context-restore patch to Dockerfile build order
80d646f verified
Raw History Blame Contribute Delete
7.77 kB
FROM node:20-alpine AS frontend-builder
RUN apk add --no-cache git python3
RUN git clone --depth 1 https://huggingface.co/spaces/smolagents/ml-intern /source || true
COPY patch_restore_full_app.py /tmp/patch_restore_full_app.py
RUN python3 /tmp/patch_restore_full_app.py || true
COPY patch_frontend.py /tmp/patch_frontend.py
RUN python3 /tmp/patch_frontend.py || true
COPY patch_space_bunny.py /tmp/patch_space_bunny.py
RUN python3 /tmp/patch_space_bunny.py || true
COPY patch_frontend_uploads.py /tmp/patch_frontend_uploads.py
RUN python3 /tmp/patch_frontend_uploads.py || true
COPY patch_frontend_multi.py /tmp/patch_frontend_multi.py
RUN python3 /tmp/patch_frontend_multi.py || true
COPY patch_frontend_new_models.py /tmp/patch_frontend_new_models.py
RUN python3 /tmp/patch_frontend_new_models.py || true
COPY patch_frontend_apodex_ling_beatapi.py /tmp/patch_frontend_apodex_ling_beatapi.py
RUN python3 /tmp/patch_frontend_apodex_ling_beatapi.py || true
COPY patch_frontend_xing_nemotron_vl.py /tmp/patch_frontend_xing_nemotron_vl.py
RUN python3 /tmp/patch_frontend_xing_nemotron_vl.py || true
COPY patch_catch_up_dataset_fallback.py /tmp/patch_catch_up_dataset_fallback.py
RUN python3 /tmp/patch_catch_up_dataset_fallback.py || true
# Run auto_continue patch BEFORE our frontend fix, since it also patches useAgentChat.ts
COPY patch_auto_continue_v17.py /tmp/patch_auto_continue_v17.py
RUN python3 /tmp/patch_auto_continue_v17.py || true
# Run our frontend catch-up fix AFTER all other frontend patches
COPY patch_catch_up_fix_frontend.py /tmp/patch_catch_up_fix_frontend.py
RUN python3 /tmp/patch_catch_up_fix_frontend.py || true
# v2: comprehensive catch-up fix + shareable URLs (frontend)
COPY patch_catch_up_fix_v2.py /tmp/patch_catch_up_fix_v2.py
RUN python3 /tmp/patch_catch_up_fix_v2.py || true
# v3: FIX THE BUILD — v2 left dead imports (_catchupDone, ShareIcon) and an
# untyped param that fail `npm run build` -> empty /app/static -> NO frontend.
# This MUST run after v2 so it can complete v2's half-applied patches.
COPY patch_catch_up_fix_v3.py /tmp/patch_catch_up_fix_v3.py
RUN python3 /tmp/patch_catch_up_fix_v3.py || true
WORKDIR /source/frontend
RUN npm config set fetch-timeout 120000 && npm config set fetch-retries 3 && npm install && npm run build || echo "FRONTEND BUILD FAILED"
# Guarantee the dist dir exists so COPY --from below never fails, even if npm failed.
RUN mkdir -p /source/frontend/dist
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN useradd -m -u 1000 user
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends git curl ca-certificates tesseract-ocr tesseract-ocr-eng tesseract-ocr-vie libreoffice-writer libreoffice-calc libreoffice-impress && rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 https://huggingface.co/spaces/smolagents/ml-intern /tmp/source && cp /tmp/source/pyproject.toml /tmp/source/uv.lock ./ && cp -r /tmp/source/agent ./agent && cp -r /tmp/source/backend ./backend && (cp /tmp/source/backend/document_parser.py ./backend/document_parser.py 2>/dev/null || true) && cp -r /tmp/source/configs ./configs && cp -r /tmp/source/scripts ./scripts && rm -rf /tmp/source
COPY scripts/build_kpis.py /tmp/build_kpis_patched.py
RUN cp /tmp/build_kpis_patched.py /app/scripts/build_kpis.py && python3 -c "import ast; ast.parse(open('/app/scripts/build_kpis.py').read())" || echo "KP FAILED"
COPY patch_restore_full_app.py /tmp/patch_restore_full_app.py
RUN python3 /tmp/patch_restore_full_app.py || true
RUN uv sync --no-dev --frozen || echo "UV SYNC FAILED"
COPY backend/session_logger.py /app/backend/session_logger.py
COPY backend/document_parser.py /app/backend/document_parser.py
COPY patch_models.py /tmp/patch_models.py
RUN python /tmp/patch_models.py || true
COPY patch_new_models.py /tmp/patch_new_models.py
RUN python /tmp/patch_new_models.py || true
COPY patch_apodex_ling_beatapi.py /tmp/patch_apodex_ling_beatapi.py
RUN python3 /tmp/patch_apodex_ling_beatapi.py || true
COPY patch_xing_nemotron_vl.py /tmp/patch_xing_nemotron_vl.py
RUN python3 /tmp/patch_xing_nemotron_vl.py || true
COPY patch_openrouter_fix.py /tmp/patch_openrouter_fix.py
RUN python3 /tmp/patch_openrouter_fix.py || true
COPY patch_beatapi_routing.py /tmp/patch_beatapi_routing.py
RUN python3 /tmp/patch_beatapi_routing.py || true
COPY patch_agent_backend.py /tmp/patch_agent_backend.py
RUN python3 /tmp/patch_agent_backend.py || true
COPY patch_document_upload.py /tmp/patch_document_upload.py
RUN python3 /tmp/patch_document_upload.py || true
COPY patch_multi_upload.py /tmp/patch_multi_upload.py
RUN python3 /tmp/patch_multi_upload.py || true
COPY patch_permanent_session_logging.py /tmp/patch_permanent_session_logging.py
RUN python3 /tmp/patch_permanent_session_logging.py || true
COPY patch_catch_up_fix_backend.py /tmp/patch_catch_up_fix_backend.py
RUN python3 /tmp/patch_catch_up_fix_backend.py || true
# v2: comprehensive catch-up fix + shareable URLs (backend — runs after all other backend patches)
COPY patch_catch_up_fix_v2.py /tmp/patch_catch_up_fix_v2.py
RUN python3 /tmp/patch_catch_up_fix_v2.py || true
# v3 backend: fix the event-row filter in session_logger.py that v2 broke
# (wrong indent -> SyntaxError -> filter never applied -> catch-up errors).
COPY patch_catch_up_fix_v3.py /tmp/patch_catch_up_fix_v3.py
RUN python3 /tmp/patch_catch_up_fix_v3.py || true
# === PATCH: fix 404 on root and /api when frontend build is missing ===
# Root cause: mkdir -p /app/static creates an empty dir; main.py mounts
# StaticFiles on the empty dir, shadowing ALL API routes with 404s.
COPY patch_fix_static_404.py /tmp/patch_fix_static_404.py
RUN python3 /tmp/patch_fix_static_404.py || echo "STATIC FIX PATCH WARN (BUILD CONTINUES)"
# === PATCH: lossless long-context memory (fix context loss for long sessions) ===
COPY patch_lossless_context.py /tmp/patch_lossless_context.py
RUN python /tmp/patch_lossless_context.py || echo "LOSSLESS CONTEXT PATCH WARN (BUILD CONTINUES)"
RUN python3 -c "import ast; [ast.parse(open(f).read()) for f in ['/app/agent/context_manager/manager.py','/app/agent/core/agent_loop.py','/app/agent/core/session.py','/app/agent/core/session_resume.py','/app/agent/config.py']]; print('ALL PATCHED FILES SYNTAX OK')" || echo "SYNTAX CHECK WARN"
# === PATCH: restore full session context from HF dataset ===
# Fixes: (1) "Catch me up" banner appears after every Space restart because
# NoopSessionStore never restores sessions; (2) context lost after catch-up
# because seed_from_summary only used a lossy summary. This patch makes the
# backend reload full conversations from the permanent sessions dataset.
COPY patch_catch_up_context_restore.py /tmp/patch_catch_up_context_restore.py
RUN python3 /tmp/patch_catch_up_context_restore.py || echo "CONTEXT RESTORE PATCH WARN (BUILD CONTINUES)"
RUN python3 -c "import ast; ast.parse(open('/app/backend/session_manager.py').read()); print('session_manager.py SYNTAX OK')" || echo "SESSION MANAGER SYNTAX CHECK WARN"
# Copy frontend dist from builder stage using COPY --from (multi-stage)
# The frontend-builder stage guarantees /source/frontend/dist exists (mkdir -p)
COPY --from=frontend-builder /source/frontend/dist /app/static
RUN echo "Static dir ready: $(ls /app/static 2>/dev/null | wc -l) files"
RUN mkdir -p /app/configs
RUN cp configs/frontend_agent_config.json /app/configs/frontend_agent_config.json 2>/dev/null || echo "No frontend config"
RUN grep -rl "where we here now" /app/static/ 2>/dev/null | xargs sed -i "s/where we here now//g" 2>/dev/null || true
RUN mkdir -p /app/session_logs && chown -R user:user /app
USER user
ENV HOME=/home/user PYTHONUNBUFFERED=1 PYTHONPATH=/app PATH="/app/.venv/bin:$PATH"
EXPOSE 7860
WORKDIR /app/backend
CMD ["bash", "start.sh"]