- agent/task_registry.py: file-based JSONL event registry (cross-process) - agent/task_worker.py: autonomous LLM loop with weather/time/memory/web tools - agent/dispatch_mcp.py: MCP tool exposing dispatch_task to the main agent - agent/agent.py: registers dispatch toolset, polls task events → room data - web: slide-out task panel (FAB button + badge), live step streaming via data channel topic 'tasks', status dots (running/completed/failed) - Dockerfile: copies new task_*.py and dispatch_mcp.py files The dispatch MCP runs in its own process; events flow through /tmp/tasks/events.jsonl which the main agent tails every second and forwards to the browser. Tasks run up to 10 LLM iterations with tool calls.
83 lines
3.2 KiB
Docker
83 lines
3.2 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# ── Stage 1: Build Python agent deps with uv ───────────────────────────────
|
|
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS build
|
|
|
|
ENV PYTHONUNBUFFERED=1
|
|
ENV UV_COMPILE_BYTECODE=1
|
|
|
|
WORKDIR /app
|
|
|
|
# Install build tools for native extensions (azure-cognitiveservices-speech)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
gcc g++ python3-dev libasound2-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY agent/pyproject.toml ./agent/
|
|
COPY agent/uv.lock ./agent/
|
|
RUN cd /app/agent && uv sync --frozen
|
|
|
|
# ── Stage 2: Runtime (use same base for Python compat) ─────────────────────
|
|
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS runtime
|
|
|
|
ENV PYTHONUNBUFFERED=1
|
|
# Fix SSL cert path for the slim base image (ca-certificates installs to /etc/ssl/certs)
|
|
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
|
|
|
# Install LiveKit server binary + supervisord + nginx
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl ca-certificates supervisor nginx libasound2 iproute2 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Download LiveKit server (latest stable)
|
|
ARG LIVEKIT_VERSION=v1.13.5
|
|
ARG LIVEKIT_TAG=1.13.5
|
|
RUN curl -sSL "https://github.com/livekit/livekit/releases/download/${LIVEKIT_VERSION}/livekit_${LIVEKIT_TAG}_linux_amd64.tar.gz" \
|
|
| tar xz -C /usr/local/bin/ livekit-server \
|
|
&& chmod +x /usr/local/bin/livekit-server \
|
|
&& ln -sf /usr/local/bin/livekit-server /usr/local/bin/livekit
|
|
|
|
# Copy Python agent + venv from build stage
|
|
COPY --from=build /app/agent/.venv /opt/voice-agent/.venv
|
|
COPY agent/agent.py /opt/voice-agent/agent.py
|
|
COPY agent/web_mcp.py /opt/voice-agent/web_mcp.py
|
|
COPY agent/weather_mcp.py /opt/voice-agent/weather_mcp.py
|
|
COPY agent/memory_mcp.py /opt/voice-agent/memory_mcp.py
|
|
COPY agent/skills_mcp.py /opt/voice-agent/skills_mcp.py
|
|
COPY agent/task_registry.py /opt/voice-agent/task_registry.py
|
|
COPY agent/task_worker.py /opt/voice-agent/task_worker.py
|
|
COPY agent/dispatch_mcp.py /opt/voice-agent/dispatch_mcp.py
|
|
|
|
# Copy web frontend + token endpoint
|
|
COPY web/index.html /var/www/voice/
|
|
COPY web/app.js /var/www/voice/
|
|
COPY web/style.css /var/www/voice/
|
|
COPY web/livekit-client.umd.js /var/www/voice/
|
|
COPY web/manifest.json /var/www/voice/
|
|
COPY web/favicon.svg /var/www/voice/
|
|
COPY web/token_server.py /opt/voice/token_server.py
|
|
|
|
# Config files
|
|
COPY livekit.yaml /etc/livekit.yaml
|
|
COPY supervisord.conf /etc/supervisor/conf.d/voice.conf
|
|
|
|
# Configure nginx to serve the voice UI on port 8090 over HTTPS.
|
|
# Browsers require a secure context (HTTPS or localhost) for microphone access.
|
|
# The self-signed cert (with the LAN IP in the SAN) is generated at container
|
|
# start by entrypoint.sh.
|
|
COPY nginx.conf /etc/nginx/sites-available/voice
|
|
RUN rm -f /etc/nginx/sites-enabled/default \
|
|
&& ln -sf /etc/nginx/sites-available/voice /etc/nginx/sites-enabled/voice \
|
|
&& mkdir -p /etc/voice/certs
|
|
|
|
# Create non-root user for agent
|
|
RUN useradd -m -s /bin/bash voiceuser || true
|
|
|
|
COPY entrypoint.sh /entrypoint.sh
|
|
RUN chmod +x /entrypoint.sh
|
|
|
|
EXPOSE 7880 7881 7882/udp 8090
|
|
|
|
ENTRYPOINT ["/entrypoint.sh"]
|
|
CMD ["supervisord", "-n", "-c", "/etc/supervisor/conf.d/voice.conf"]
|