Spaces:
Sleeping
Sleeping
| # Marimo Zero - Official Agent Zero + Marimo + OmniRoute | |
| # Uses frdel/agent-zero-exe base image | |
| FROM frdel/agent-zero-exe:latest | |
| USER root | |
| # 1. Install dependencies | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| curl jq python3-pip \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN pip install --no-cache-dir --break-system-packages marimo fastapi uvicorn requests httpx | |
| # 2. Install OmniRoute | |
| RUN npm install -g omniroute | |
| # 3. Setup directories | |
| WORKDIR /app | |
| RUN mkdir -p /app/marimo /app/workspace /app/.omniroute && chmod -R 777 /app | |
| # 4. Copy Marimo notebook | |
| COPY marimo_sandbox.py /app/marimo/marimo_sandbox.py | |
| # 5. Create startup script | |
| RUN cat > /app/start.sh << 'EOF' | |
| #!/bin/bash | |
| set -e | |
| echo "π Starting Marimo Zero..." | |
| # Parse API keys | |
| if [ -n "$API_KEYS_JSON" ]; then | |
| echo "π Loading API keys..." | |
| export OPENAI_API_KEY=$(echo $API_KEYS_JSON | jq -r '.openai // empty') | |
| export ANTHROPIC_API_KEY=$(echo $API_KEYS_JSON | jq -r '.anthropic // empty') | |
| fi | |
| # Start OmniRoute | |
| echo "π‘ Starting OmniRoute..." | |
| cat > /app/.omniroute/accounts.json << ACCOUNTS | |
| {"accounts": [{"name": "openai", "provider": "openai", "api_key": "${OPENAI_API_KEY:-dummy}", "default": true}]} | |
| ACCOUNTS | |
| omniroute start --port 20128 --accounts /app/.omniroute/accounts.json & | |
| sleep 2 | |
| # Start Agent Zero Web UI | |
| echo "π€ Starting Agent Zero Web UI..." | |
| cd /app && python3 run_ui.py & | |
| sleep 5 | |
| # Start Marimo | |
| echo "π Starting Marimo..." | |
| marimo run /app/marimo/marimo_sandbox.py --host 0.0.0.0 --port 8081 --headless & | |
| sleep 3 | |
| # Start proxy | |
| echo "π Starting proxy..." | |
| python3 << 'PROXY' | |
| from fastapi import FastAPI, Request | |
| from fastapi.responses import StreamingResponse | |
| import httpx | |
| app = FastAPI() | |
| client = httpx.AsyncClient(timeout=120.0) | |
| @app.get("/health") | |
| async def health(): | |
| return {"status": "healthy"} | |
| @app.get("/marimo") | |
| async def marimo_redir(): | |
| from fastapi.responses import RedirectResponse | |
| return RedirectResponse(url="/marimo/") | |
| @app.api_route("/marimo/{path:path}", methods=["GET","POST","PUT","DELETE","PATCH"]) | |
| async def marimo_proxy(request: Request, path: str): | |
| url = f"http://localhost:8081/{path}" | |
| h = dict(request.headers) | |
| h.pop("host", None) | |
| b = await request.body() if request.method in ["POST","PUT","PATCH"] else None | |
| r = await client.request(request.method, url, headers=h, content=b) | |
| return StreamingResponse(r.aiter_bytes(), status_code=r.status_code, headers=dict(r.headers)) | |
| @app.api_route("/{path:path}", methods=["GET","POST","PUT","DELETE","PATCH"]) | |
| async def az_proxy(request: Request, path: str): | |
| url = f"http://localhost:80/{path}" if path else "http://localhost:80" | |
| h = dict(request.headers) | |
| h.pop("host", None) | |
| b = await request.body() if request.method in ["POST","PUT","PATCH"] else None | |
| r = await client.request(request.method, url, headers=h, content=b) | |
| return StreamingResponse(r.aiter_bytes(), status_code=r.status_code, headers=dict(r.headers)) | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |
| PROXY | |
| echo "β Ready!" | |
| echo " Agent Zero: http://localhost:7860" | |
| echo " Marimo: http://localhost:7860/marimo/" | |
| wait | |
| EOF | |
| RUN chmod +x /app/start.sh | |
| # 6. Environment | |
| ENV HF_SPACE=true | |
| ENV WORKSPACE=/app/workspace | |
| # 7. Port | |
| EXPOSE 7860 | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ | |
| CMD curl -f http://localhost:7860/health || exit 1 | |
| ENTRYPOINT ["/app/start.sh"] | |