Spaces:
Paused
Paused
Add Hugging Face Spaces deployment configuration (Dockerfile, supervisord, watcher)
Browse files
Dockerfile
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use the pre-built base image
|
| 2 |
+
FROM agent0ai/agent-zero-base:latest
|
| 3 |
+
|
| 4 |
+
# Set BRANCH to "local" if not provided
|
| 5 |
+
ARG BRANCH=local
|
| 6 |
+
ENV BRANCH=$BRANCH
|
| 7 |
+
|
| 8 |
+
# Copy filesystem files to root
|
| 9 |
+
COPY ./docker/run/fs/ /
|
| 10 |
+
|
| 11 |
+
# Overwrite supervisord conf with HF version
|
| 12 |
+
COPY ./docker/run/fs/etc/supervisor/conf.d/supervisord_hf.conf /etc/supervisor/conf.d/supervisord.conf
|
| 13 |
+
|
| 14 |
+
# Copy current development files to git
|
| 15 |
+
COPY ./ /git/agent-zero
|
| 16 |
+
|
| 17 |
+
# Create directory for data linking (HF Spaces usually mount /data if persistent storage is enabled, or we use a local folder)
|
| 18 |
+
RUN mkdir -p /knowledge_data
|
| 19 |
+
|
| 20 |
+
# Install A0
|
| 21 |
+
# We assume the base image has most things. We run the install scripts.
|
| 22 |
+
# Note: In HF Spaces, we might be user 1000.
|
| 23 |
+
# For now, let's try to run as root during build to set permissions, then switch user if needed.
|
| 24 |
+
# However, standard Agent Zero runs as root (internal to container). HF Spaces allows root in Docker spaces usually.
|
| 25 |
+
|
| 26 |
+
# Run pre-install steps
|
| 27 |
+
RUN bash /ins/pre_install.sh $BRANCH
|
| 28 |
+
|
| 29 |
+
# Install A0
|
| 30 |
+
RUN bash /ins/install_A0.sh $BRANCH
|
| 31 |
+
|
| 32 |
+
# Install watchdog for knowledge watcher
|
| 33 |
+
RUN uv pip install --python /opt/venv-a0/bin/python watchdog
|
| 34 |
+
|
| 35 |
+
# Install additional software
|
| 36 |
+
RUN bash /ins/install_additional.sh $BRANCH
|
| 37 |
+
|
| 38 |
+
# Cleanup and install A02
|
| 39 |
+
ARG CACHE_DATE=none
|
| 40 |
+
RUN echo "cache buster $CACHE_DATE" && bash /ins/install_A02.sh $BRANCH
|
| 41 |
+
|
| 42 |
+
# Post install
|
| 43 |
+
RUN bash /ins/post_install.sh $BRANCH
|
| 44 |
+
|
| 45 |
+
# Expose HF Spaces port
|
| 46 |
+
EXPOSE 7860
|
| 47 |
+
|
| 48 |
+
# We need to modify run_A0.sh or the app config to listen on 7860 instead of 80/50001
|
| 49 |
+
# Or we map 7860 to 80.
|
| 50 |
+
# Agent Zero likely listens on port 80 inside the container (from DockerfileLocal EXPOSE 80).
|
| 51 |
+
# We will use an environment variable or sed to change the port if needed.
|
| 52 |
+
# For now, let's assume we can map it or change it in the start script.
|
| 53 |
+
|
| 54 |
+
RUN chmod +x /exe/initialize.sh /exe/run_A0.sh /exe/run_A0_hf.sh /exe/run_searxng.sh /exe/run_tunnel_api.sh
|
| 55 |
+
|
| 56 |
+
# Initialize
|
| 57 |
+
CMD ["/exe/initialize.sh", "local"]
|
docker/run/fs/etc/supervisor/conf.d/supervisord_hf.conf
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[supervisord]
|
| 2 |
+
nodaemon=true
|
| 3 |
+
user=root
|
| 4 |
+
logfile=/dev/stdout
|
| 5 |
+
logfile_maxbytes=0
|
| 6 |
+
pidfile=/var/run/supervisord.pid
|
| 7 |
+
exitcodes=0,2
|
| 8 |
+
directory=/
|
| 9 |
+
|
| 10 |
+
[unix_http_server]
|
| 11 |
+
file=/var/run/supervisor.sock
|
| 12 |
+
chmod=0777
|
| 13 |
+
|
| 14 |
+
[rpcinterface:supervisor]
|
| 15 |
+
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
| 16 |
+
|
| 17 |
+
[supervisorctl]
|
| 18 |
+
serverurl=unix:///var/run/supervisor.sock
|
| 19 |
+
|
| 20 |
+
[program:run_searxng]
|
| 21 |
+
command=/exe/run_searxng.sh
|
| 22 |
+
environment=SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml
|
| 23 |
+
user=searxng
|
| 24 |
+
directory=/usr/local/searxng/searxng-src
|
| 25 |
+
stopwaitsecs=1
|
| 26 |
+
stdout_logfile=/dev/stdout
|
| 27 |
+
stdout_logfile_maxbytes=0
|
| 28 |
+
stderr_logfile=/dev/stderr
|
| 29 |
+
stderr_logfile_maxbytes=0
|
| 30 |
+
autorestart=true
|
| 31 |
+
startretries=3
|
| 32 |
+
stopasgroup=true
|
| 33 |
+
killasgroup=true
|
| 34 |
+
|
| 35 |
+
[program:run_ui]
|
| 36 |
+
command=/bin/bash /exe/run_A0_hf.sh
|
| 37 |
+
environment=
|
| 38 |
+
user=root
|
| 39 |
+
stopwaitsecs=60
|
| 40 |
+
stdout_logfile=/dev/stdout
|
| 41 |
+
stdout_logfile_maxbytes=0
|
| 42 |
+
stderr_logfile=/dev/stderr
|
| 43 |
+
stderr_logfile_maxbytes=0
|
| 44 |
+
autorestart=true
|
| 45 |
+
startretries=3
|
| 46 |
+
stopasgroup=true
|
| 47 |
+
killasgroup=true
|
| 48 |
+
|
| 49 |
+
[program:watch_knowledge]
|
| 50 |
+
command=/opt/venv-a0/bin/python /git/agent-zero/python/tools/watch_knowledge.py
|
| 51 |
+
environment=
|
| 52 |
+
user=root
|
| 53 |
+
stopwaitsecs=10
|
| 54 |
+
stdout_logfile=/dev/stdout
|
| 55 |
+
stdout_logfile_maxbytes=0
|
| 56 |
+
stderr_logfile=/dev/stderr
|
| 57 |
+
stderr_logfile_maxbytes=0
|
| 58 |
+
autorestart=true
|
| 59 |
+
startretries=3
|
| 60 |
+
stopasgroup=true
|
| 61 |
+
killasgroup=true
|
| 62 |
+
|
| 63 |
+
[eventlistener:the_listener]
|
| 64 |
+
command=python3 /exe/supervisor_event_listener.py
|
| 65 |
+
events=PROCESS_STATE_FATAL
|
| 66 |
+
stdout_logfile=/dev/stdout
|
| 67 |
+
stdout_logfile_maxbytes=0
|
| 68 |
+
stderr_logfile=/dev/stderr
|
| 69 |
+
stderr_logfile_maxbytes=0
|
docker/run/fs/exe/run_A0_hf.sh
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# Source setup scripts
|
| 4 |
+
. "/ins/setup_venv.sh" "$@"
|
| 5 |
+
. "/ins/copy_A0.sh" "$@"
|
| 6 |
+
|
| 7 |
+
# Run cleanups/preps
|
| 8 |
+
python /a0/prepare.py --dockerized=true
|
| 9 |
+
|
| 10 |
+
echo "Starting A0 on HF Port 7860..."
|
| 11 |
+
# Exec into python to run the UI
|
| 12 |
+
exec python /a0/run_ui.py \
|
| 13 |
+
--dockerized=true \
|
| 14 |
+
--port=7860 \
|
| 15 |
+
--host="0.0.0.0"
|
python/tools/watch_knowledge.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
import os
|
| 3 |
+
import shutil
|
| 4 |
+
import logging
|
| 5 |
+
from watchdog.observers import Observer
|
| 6 |
+
from watchdog.events import FileSystemEventHandler
|
| 7 |
+
|
| 8 |
+
# Configuration
|
| 9 |
+
WATCH_DIR = os.getenv("KNOWLEDGE_WATCH_DIR", "/knowledge_data")
|
| 10 |
+
# Agent Zero internal knowledge directory
|
| 11 |
+
TARGET_DIR = "/a0/knowledge/default" # 'default' knowledge base
|
| 12 |
+
|
| 13 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
|
| 14 |
+
logger = logging.getLogger(__name__)
|
| 15 |
+
|
| 16 |
+
class KnowledgeHandler(FileSystemEventHandler):
|
| 17 |
+
def on_created(self, event):
|
| 18 |
+
if event.is_directory:
|
| 19 |
+
return
|
| 20 |
+
|
| 21 |
+
filename = os.path.basename(event.src_path)
|
| 22 |
+
# unexpected files filter
|
| 23 |
+
if filename.startswith(".") or filename.endswith(".tmp"):
|
| 24 |
+
return
|
| 25 |
+
|
| 26 |
+
logger.info(f"New file detected: {event.src_path}")
|
| 27 |
+
|
| 28 |
+
# We wait a bit to ensure file write is complete
|
| 29 |
+
time.sleep(1)
|
| 30 |
+
|
| 31 |
+
try:
|
| 32 |
+
# Copy to Agent Zero knowledge directory
|
| 33 |
+
# This triggers Agent Zero's internal mechanisms if it has any auto-ingest,
|
| 34 |
+
# OR we simply place it there so it's available for the 'knowledge' tool.
|
| 35 |
+
# Agent Zero 0.9.7+ might need explicit embedding or indexing.
|
| 36 |
+
# However, simply having it in the folder makes it accessible to 'knowledge' tool usually.
|
| 37 |
+
|
| 38 |
+
target_path = os.path.join(TARGET_DIR, filename)
|
| 39 |
+
if os.path.exists(target_path):
|
| 40 |
+
logger.info(f"File already exists in knowledge base: {filename}")
|
| 41 |
+
return
|
| 42 |
+
|
| 43 |
+
shutil.copy2(event.src_path, target_path)
|
| 44 |
+
logger.info(f"Ingested {filename} into {target_path}")
|
| 45 |
+
|
| 46 |
+
# TODO: If explicit API call is needed to trigger embedding, do it here.
|
| 47 |
+
# For now, we assume A0 indexes on access or via background jobs.
|
| 48 |
+
|
| 49 |
+
except Exception as e:
|
| 50 |
+
logger.error(f"Error processing file {event.src_path}: {e}")
|
| 51 |
+
|
| 52 |
+
if __name__ == "__main__":
|
| 53 |
+
# Ensure directories exist
|
| 54 |
+
os.makedirs(WATCH_DIR, exist_ok=True)
|
| 55 |
+
os.makedirs(TARGET_DIR, exist_ok=True)
|
| 56 |
+
|
| 57 |
+
event_handler = KnowledgeHandler()
|
| 58 |
+
observer = Observer()
|
| 59 |
+
observer.schedule(event_handler, WATCH_DIR, recursive=False)
|
| 60 |
+
|
| 61 |
+
logger.info(f"Starting Knowledge Watcher on {WATCH_DIR} -> {TARGET_DIR}")
|
| 62 |
+
observer.start()
|
| 63 |
+
try:
|
| 64 |
+
while True:
|
| 65 |
+
time.sleep(1)
|
| 66 |
+
except KeyboardInterrupt:
|
| 67 |
+
observer.stop()
|
| 68 |
+
observer.join()
|