Spaces:
Sleeping
Sleeping
| # ============================================================================= | |
| # Hermes Agent โ HuggingFace Space๏ผDocker๏ผ | |
| # ไฝ ๅช้ไธไผ ่ฟไธไธชๆไปถ๏ผ | |
| # ============================================================================= | |
| FROM python:3.11-slim | |
| # โโ ็ณป็ปไพ่ต โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| git curl wget build-essential libssl-dev libffi-dev \ | |
| nodejs npm procps \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # โโ ๅฎ่ฃ uv โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN curl -LsSf https://astral.sh/uv/install.sh | sh | |
| ENV PATH="/root/.cargo/bin:/root/.local/bin:$PATH" | |
| # โโ ๅ ้ hermes-agent โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| WORKDIR /opt | |
| RUN git clone --depth 1 https://github.com/NousResearch/hermes-agent.git hermes-agent | |
| WORKDIR /opt/hermes-agent | |
| # โโ Python ่ๆ็ฏๅข + ไพ่ต โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN uv venv /opt/venv --python 3.11 | |
| ENV VIRTUAL_ENV=/opt/venv | |
| ENV PATH="/opt/venv/bin:$PATH" | |
| # mini-swe-agent ๅทฒไฝไธบ็ฎๅฝๅ ๅตๅจไปๅบไธญ๏ผไธๅๆฏ git submodule๏ผ | |
| # ่ฅ็ฎๅฝๅญๅจๅๅฎ่ฃ ๏ผๅฆๅ่ทณ่ฟ | |
| RUN uv pip install -e ".[all]" && \ | |
| ([ -f "./mini-swe-agent/pyproject.toml" ] && uv pip install -e "./mini-swe-agent" || true) && \ | |
| uv pip install aiohttp httpx cryptography "gradio==5.29.0" "huggingface_hub>=0.23" | |
| # โโ ๅๅ ฅ entrypoint.sh โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN cat > /entrypoint.sh << 'ENTRY_EOF' | |
| #!/bin/bash | |
| set -e | |
| echo "==========================================================" | |
| echo " Hermes Agent ยท HuggingFace Space" | |
| echo "==========================================================" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๅ จๅฑ่ทฏๅพ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| export HERMES_HOME=/data/hermes | |
| export HF_DATASET_LOCAL=/data/hf_dataset # Dataset ๆฌๅฐ้ๅ | |
| export HF_HUB_DISABLE_PROGRESS_BARS=1 | |
| mkdir -p "$HERMES_HOME"/{logs,cron} | |
| mkdir -p "$HF_DATASET_LOCAL"/{skills,memories,sessions,logs,cron} | |
| mkdir -p /data/workspace | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 1: ๅๅงๅ HF Dataset๏ผๅฆไธๅญๅจๅๅๅปบ๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[1/6] ๅๅงๅ HuggingFace Dataset..." | |
| python /dataset_manager.py init | |
| echo "โ Dataset ๅๅงๅๅฎๆ" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 2: ไป Dataset ๅ ้ๅฐๆฌๅฐ้ๅ็ฎๅฝ๏ผๅฎๆถ่ฏปๅๅบ็ก๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[2/6] ไป Dataset ๆๅ้ ็ฝฎ..." | |
| python /dataset_manager.py pull | |
| echo "โ ้ ็ฝฎๅทฒๆๅ" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 3: ๅฐ HERMES_HOME ้็็ฎๅฝ่ฝฏ้พๅฐ Dataset ๆฌๅฐ้ๅ | |
| # ๅฎ็ฐ"็ดๆฅ่ฏปๅ Dataset ๆไปถ"ๆๆ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[3/6] ๅปบ็ซ็ฎๅฝ้พๆฅ๏ผๅฎๆถ่ฏปๅ๏ผ..." | |
| for DIR in config.yaml SOUL.md skills memories sessions cron; do | |
| SRC="$HF_DATASET_LOCAL/$DIR" | |
| DST="$HERMES_HOME/$DIR" | |
| # ็กฎไฟ dataset ๆฌๅฐ้ๅ้ๆ่ฟไธช่ทฏๅพ | |
| if [[ "$DIR" == *.* ]]; then | |
| # ๆไปถ๏ผๅฆ config.yaml, SOUL.md๏ผ | |
| touch "$SRC" 2>/dev/null || true | |
| else | |
| mkdir -p "$SRC" | |
| fi | |
| # ๅ ้คๆง็ๅนถๅๅปบ่ฝฏ้พ | |
| rm -rf "$DST" | |
| ln -s "$SRC" "$DST" | |
| echo " ๐ $DST -> $SRC" | |
| done | |
| echo "โ ็ฎๅฝ้พๆฅๅฎๆ" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 4: ็ๆ .env๏ผไป HF Space Secrets ๅๅ ฅ๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[4/6] ็ๆ .env..." | |
| python /dataset_manager.py gen_env | |
| echo "โ .env ๅทฒ็ๆ" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 5: ๅฏๅจ WeCom Gateway๏ผๅๅฐ๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[5/6] ๅฏๅจ WeCom Gateway..." | |
| if [ -n "${WECOM_BOT_ID}" ] && [ -n "${WECOM_SECRET}" ]; then | |
| cd /opt/hermes-agent | |
| HERMES_HOME=/data/hermes python -m hermes_cli.main gateway \ | |
| >> /data/hermes/logs/gateway.log 2>&1 & | |
| echo "โ WeCom Gateway ๅทฒๅฏๅจ (PID: $!)" | |
| else | |
| echo "โ ๏ธ ๆช้ ็ฝฎ WECOM_BOT_ID / WECOM_SECRET๏ผ่ทณ่ฟ WeCom Gateway" | |
| fi | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๆญฅ้ชค 6: ๅฏๅจ Dataset ๆไปถ็่งๅจ๏ผๅฎๆถๆจ้ๅๆด + 10ๅ้ๆจ logs๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "[6/6] ๅฏๅจๆไปถ็่งๅจ..." | |
| python /dataset_manager.py watch & | |
| echo "โ ๆไปถ็่งๅจๅทฒๅฏๅจ" | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ๅฏๅจ Gradio Web UI๏ผๅๅฐ๏ผ็ซฏๅฃ 7860๏ผ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| echo "" | |
| echo "==========================================================" | |
| echo " ๐ ๅฏๅจ Gradio Web UI โ http://0.0.0.0:7860" | |
| echo "==========================================================" | |
| exec python /webui.py | |
| ENTRY_EOF | |
| RUN chmod +x /entrypoint.sh | |
| # โโ ๅๅ ฅ dataset_manager.py โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN cat > /dataset_manager.py << 'DM_EOF' | |
| """ | |
| dataset_manager.py | |
| ็ปไธ็ฎก็ HuggingFace Dataset ็ๅๅงๅใๆๅใๆจ้ใๆไปถ็่งใ | |
| ๅญๅฝไปค: | |
| init โ ๅๅปบ Dataset๏ผ่ฅไธๅญๅจ๏ผๅนถๅๅ ฅๅๅงๆไปถ | |
| pull โ ไป Dataset ๆๅๆๆๆไปถๅฐๆฌๅฐ้ๅ | |
| push โ ๅฐๆฌๅฐ้ๅๆจ้ๅฐ Dataset | |
| gen_env โ ไป็ฏๅขๅ้็ๆ HERMES_HOME/.env | |
| watch โ ็่งๆไปถๅๅ๏ผๅฎๆถๆจ้๏ผlogs ๆฏ10ๅ้ๆจไธๆฌก | |
| """ | |
| import os, sys, time, hashlib, shutil | |
| from pathlib import Path | |
| from datetime import datetime | |
| # โโ ้ ็ฝฎ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| HF_TOKEN = os.environ.get("HF_TOKEN", "") | |
| HF_DATASET_REPO = os.environ.get("HF_DATASET_REPO", "") | |
| LOCAL_MIRROR = Path(os.environ.get("HF_DATASET_LOCAL", "/data/hf_dataset")) | |
| HERMES_HOME = Path(os.environ.get("HERMES_HOME", "/data/hermes")) | |
| # ๅฎๆถๅๅๅๆญฅ็่ทฏๅพ๏ผ็ธๅฏนไบ LOCAL_MIRROR / HERMES_HOME๏ผ | |
| REALTIME_PATHS = ["config.yaml", "SOUL.md", "skills", "memories", "sessions", "cron"] | |
| # ไป ๅฎๆถๆจ้๏ผไธๆๅ๏ผ | |
| LOG_ONLY_PATHS = ["logs"] | |
| LOG_PUSH_INTERVAL = 600 # 10 ๅ้ๆจไธๆฌก logs | |
| # โโ ้ป่ฎคๅๅงๆไปถ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def _build_default_config_yaml(): | |
| """ | |
| ๅจๆ็ๆ้ฆๆฌก้จ็ฝฒๆถๅๅ ฅ Dataset ็ config.yamlใ | |
| - ๆๆๆๆ Provider ๅๅ ฅ custom_providers: ๅ๏ผname/url/api_key/models๏ผ | |
| - model: ๅๅชๅ provider๏ผๆๅ custom_providers ้็ name๏ผๅ default ๆจกๅ | |
| - ็็ฉบ็ Provider / Model ่ทณ่ฟไธๅ | |
| - ไป ๅจ Dataset ้ไธๅญๅจ config.yaml ๆถๆๅๅ ฅ๏ผๆๅคไปฝๅไธ่ฆ็ | |
| """ | |
| import os as _os | |
| # ๆถ้ๆๆๆๆ Provider | |
| providers = [] | |
| for p in range(1, 6): | |
| name = _os.environ.get(f"PROVIDER_{p}_NAME", "").strip() | |
| url = _os.environ.get(f"PROVIDER_{p}_BASE_URL", "").strip() | |
| api_key = _os.environ.get(f"PROVIDER_{p}_API_KEY", "").strip() | |
| models = [] | |
| for m in range(1, 11): | |
| mdl = _os.environ.get(f"PROVIDER_{p}_MODEL_{m}", "").strip() | |
| if mdl: | |
| models.append(mdl) | |
| if name and url and api_key: | |
| providers.append({"name": name, "url": url, "api_key": api_key, "models": models}) | |
| # model: ๅ โโ ๅชๅผ็จ custom_providers ้็ name๏ผไธ้ๅคๅๅญ่ฏ | |
| if providers: | |
| p0 = providers[0] | |
| p0_model = p0["models"][0] if p0["models"] else "" | |
| model_block = ( | |
| "# -- Hermes ไธปๆจกๅ๏ผๅผ็จไธๆน custom_providers ไธญ็็ฌฌไธไธช Provider๏ผ\n" | |
| "model:\n" | |
| f" provider: {p0['name']}\n" | |
| f" default: {p0_model}\n" | |
| ) | |
| else: | |
| model_block = ( | |
| "# -- ไธปๆจกๅ๏ผๆชๆฃๆตๅฐ PROVIDER_1_* ็ฏๅขๅ้๏ผ่ฏทๆๅจ้ ็ฝฎ๏ผ\n" | |
| "# model:\n" | |
| "# provider: my-provider-name\n" | |
| "# default: google/gemma-4-31b-it\n" | |
| ) | |
| # custom_providers: ๅ โโ ้ไธญ็ฎก็ๆๆ Provider ็ๅญ่ฏๅๆจกๅๅ่กจ | |
| if providers: | |
| cp_lines = [ | |
| "# -- ่ชๅฎไน Provider ๅ่กจ๏ผๅญ่ฏ้ไธญๅจๆญค๏ผmodel: ๅ้่ฟ name ๅผ็จ๏ผ\n", | |
| "custom_providers:\n", | |
| ] | |
| for pv in providers: | |
| cp_lines.append(f" - name: {pv['name']}\n") | |
| cp_lines.append(f" base_url: {pv['url']}\n") | |
| cp_lines.append(f" api_key: {pv['api_key']}\n") | |
| if pv["models"]: | |
| cp_lines.append(" models:\n") | |
| for mdl in pv["models"]: | |
| cp_lines.append(f" {mdl}:\n") | |
| cp_lines.append( " context_length: 131072\n") | |
| else: | |
| cp_lines = ["# custom_providers: []\n"] | |
| lines = [ | |
| "# =============================================================\n", | |
| "# Hermes Agent config.yaml\n", | |
| "# ็ดๆฅๅจ HF Dataset ้็ผ่พๆญคๆไปถ๏ผไฟๅญๅ็ซๅณ็ๆ๏ผๆ ้้ๅฏ๏ผ\n", | |
| "# Provider ้ ็ฝฎ็ฑ HF Space ็ PROVIDER_{1-5}_* ็ฏๅขๅ้่ชๅจๆณจๅ ฅ\n", | |
| "# ๆๅคไปฝๆถไธไผ่ฆ็๏ผๅ ๆ Dataset ้็ config.yaml ๅ้ๅฏๅณๅฏ้ๆฐ็ๆ\n", | |
| "# =============================================================\n", | |
| "\n", | |
| model_block, | |
| "\n", | |
| "".join(cp_lines), | |
| "\n", | |
| "# -- ็ป็ซฏๅ็ซฏ๏ผHF Space ็จ local๏ผ\n", | |
| "terminal:\n", | |
| " backend: local\n", | |
| " cwd: /data/workspace\n", | |
| " timeout: 180\n", | |
| "\n", | |
| "# -- ่ฎฐๅฟ\n", | |
| "memory:\n", | |
| " memory_enabled: true\n", | |
| " user_profile_enabled: true\n", | |
| " memory_char_limit: 2200\n", | |
| " user_char_limit: 1375\n", | |
| "\n", | |
| "# -- ๆพ็คบ\n", | |
| "display:\n", | |
| " tool_progress: all\n", | |
| " streaming: false\n", | |
| "\n", | |
| "# -- ๅ็ผฉ\n", | |
| "compression:\n", | |
| " enabled: true\n", | |
| " threshold: 0.50\n", | |
| "\n", | |
| "# -- ๆถๅบ\n", | |
| 'timezone: "Asia/Shanghai"\n', | |
| "\n", | |
| "# -- ๅฎๅ จ๏ผๆ ไบคไบ็ป็ซฏ๏ผๅ ณ้ญๅฎกๆน๏ผ\n", | |
| "approvals:\n", | |
| " mode: off\n", | |
| "\n", | |
| "# -- WeCom๏ผไผไธๅพฎไฟก๏ผ\n", | |
| "platforms:\n", | |
| " wecom:\n", | |
| " enabled: true\n", | |
| " extra:\n", | |
| ' bot_id: "${WECOM_BOT_ID}"\n', | |
| ' secret: "${WECOM_SECRET}"\n', | |
| " dm_policy: open\n", | |
| " group_policy: open\n", | |
| ] | |
| return "".join(lines) | |
| DEFAULT_CONFIG_YAML = _build_default_config_yaml() | |
| DEFAULT_SOUL_MD = """\ | |
| # Hermes Agent | |
| ไฝ ๆฏ Hermes๏ผไธไธช็ฑ Nous Research ๅผๅ็ๆบ่ฝ AI ๅฉๆใ | |
| ไฝ ่ชๆใๅๅใไนไบๅฉไบบ๏ผๅ ทๅคๆ็ปญๅญฆไน ๅ่ชๆๆน่ฟ็่ฝๅใ | |
| ไฝ ๆ ้ฟ๏ผ | |
| - ๅ็ญๅ็ฑป้ฎ้ขๅๆไพๅปบ่ฎฎ | |
| - ๆง่กไปฃ็ ๅๅๆๆฐๆฎ | |
| - ้ฟๆ่ฎฐๅฟ็จๆทๅๅฅฝๅไธไธๆ | |
| - ้่ฟๅญฆไน ไธๆญๅ้ ๅๆน่ฟๆ่ฝ | |
| ่ฏทๅง็ป็จๆธ ๆฐใๅ็กฎใๆๅธฎๅฉ็ๆนๅผๅๅบ็จๆทใ | |
| """ | |
| DEFAULT_MEMORY_MD = """\ | |
| # Agent ่ฎฐๅฟ | |
| ๏ผๆๆ ่ฎฐๅฟ๏ผAgent ่ฟ่กๅไผ่ชๅจๅจๆญค่ฎฐๅฝ้่ฆไฟกๆฏ๏ผ | |
| """ | |
| DEFAULT_DATASET_README = """\ | |
| --- | |
| license: mit | |
| tags: | |
| - hermes-agent | |
| - config | |
| --- | |
| # Hermes Agent ้ ็ฝฎๆฐๆฎ้ | |
| ๆฌ Dataset ็ฑ Hermes Agent HF Space ่ชๅจๅๅปบๅ็ฎก็ใ | |
| ## ็ฎๅฝ็ปๆ | |
| ``` | |
| config.yaml โ ไธป้ ็ฝฎ๏ผ็ดๆฅ็ผ่พๅณๅฏ็ๆ๏ผ | |
| SOUL.md โ Agent ไบบๆ ผๅฎไน | |
| skills/ โ Agent ่ชๅๆ่ฝ | |
| memories/ โ ้ฟๆ่ฎฐๅฟ | |
| MEMORY.md | |
| sessions/ โ ไผ่ฏๅๅฒ | |
| cron/ โ ๅฎๆถไปปๅก | |
| logs/ โ ่ฟ่กๆฅๅฟ๏ผ10ๅ้ๅๆญฅไธๆฌก๏ผ | |
| ``` | |
| """ | |
| # โโ ๅทฅๅ ทๅฝๆฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def get_api(): | |
| if not HF_TOKEN or not HF_DATASET_REPO: | |
| print("โ ๏ธ HF_TOKEN ๆ HF_DATASET_REPO ๆช่ฎพ็ฝฎ๏ผ่ทณ่ฟ Dataset ๆไฝ") | |
| return None | |
| try: | |
| from huggingface_hub import HfApi | |
| return HfApi(token=HF_TOKEN) | |
| except ImportError: | |
| print("โ huggingface_hub ๆชๅฎ่ฃ ") | |
| return None | |
| def file_hash(path: Path) -> str: | |
| if not path.exists() or not path.is_file(): | |
| return "" | |
| return hashlib.md5(path.read_bytes()).hexdigest() | |
| def upload_file(api, local_path: Path, repo_path: str, msg: str = "auto"): | |
| try: | |
| api.upload_file( | |
| path_or_fileobj=str(local_path), | |
| path_in_repo=repo_path, | |
| repo_id=HF_DATASET_REPO, | |
| repo_type="dataset", | |
| commit_message=msg, | |
| ) | |
| return True | |
| except Exception as e: | |
| print(f" โ ๏ธ ไธไผ {repo_path} ๅคฑ่ดฅ: {e}") | |
| return False | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def cmd_init(): | |
| """ๅๅปบ Dataset๏ผ่ฅไธๅญๅจ๏ผๅนถๅๅ ฅๅๅงๆไปถ""" | |
| api = get_api() | |
| if not api: | |
| _write_defaults_locally() | |
| return | |
| # ๆฃๆฅ Dataset ๆฏๅฆๅญๅจ | |
| try: | |
| from huggingface_hub import DatasetCard | |
| api.dataset_info(HF_DATASET_REPO) | |
| print(f" Dataset [{HF_DATASET_REPO}] ๅทฒๅญๅจ") | |
| except Exception: | |
| print(f" Dataset [{HF_DATASET_REPO}] ไธๅญๅจ๏ผๆญฃๅจๅๅปบ...") | |
| api.create_repo( | |
| repo_id=HF_DATASET_REPO, | |
| repo_type="dataset", | |
| private=True, | |
| exist_ok=True, | |
| ) | |
| print(f" โ Dataset ๅทฒๅๅปบ๏ผ็งๆ๏ผ") | |
| # ๆฃๆฅๅนถๅๅ ฅๅๅงๆไปถ๏ผไธ่ฆ็ๅทฒๆๆไปถ๏ผ | |
| _init_remote_files(api) | |
| # ๅๅฐๆฌๅฐ้ๅ | |
| _write_defaults_locally() | |
| def _init_remote_files(api): | |
| """ๆฃๆฅ่ฟ็จๆฏๅฆๆๅๅงๆไปถ๏ผๆฒกๆๅไธไผ ้ป่ฎคๅผ""" | |
| defaults = { | |
| "README.md": DEFAULT_DATASET_README, | |
| "config.yaml": DEFAULT_CONFIG_YAML, | |
| "SOUL.md": DEFAULT_SOUL_MD, | |
| "memories/MEMORY.md": DEFAULT_MEMORY_MD, | |
| } | |
| try: | |
| existing = {f.rfilename for f in api.list_repo_files( | |
| HF_DATASET_REPO, repo_type="dataset")} | |
| except Exception: | |
| existing = set() | |
| for repo_path, content in defaults.items(): | |
| if repo_path not in existing: | |
| tmp = Path(f"/tmp/init_{repo_path.replace('/', '_')}") | |
| tmp.parent.mkdir(parents=True, exist_ok=True) | |
| tmp.write_text(content, encoding="utf-8") | |
| upload_file(api, tmp, repo_path, "Init: " + repo_path) | |
| print(f" ๐ ๅๅงๅ่ฟ็จๆไปถ: {repo_path}") | |
| else: | |
| print(f" โ ๅทฒๅญๅจ: {repo_path}") | |
| def _write_defaults_locally(): | |
| """็กฎไฟๆฌๅฐ้ๅๆ้ป่ฎคๆไปถ""" | |
| LOCAL_MIRROR.mkdir(parents=True, exist_ok=True) | |
| defaults = { | |
| "config.yaml": DEFAULT_CONFIG_YAML, | |
| "SOUL.md": DEFAULT_SOUL_MD, | |
| "memories/MEMORY.md": DEFAULT_MEMORY_MD, | |
| } | |
| for rel, content in defaults.items(): | |
| p = LOCAL_MIRROR / rel | |
| if not p.exists(): | |
| p.parent.mkdir(parents=True, exist_ok=True) | |
| p.write_text(content, encoding="utf-8") | |
| for d in ["skills", "sessions", "cron", "logs"]: | |
| (LOCAL_MIRROR / d).mkdir(parents=True, exist_ok=True) | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def cmd_pull(): | |
| """ไป Dataset ๆๅๆๆๆไปถๅฐๆฌๅฐ้ๅ๏ผๅฎๆถ่ทฏๅพ๏ผ""" | |
| api = get_api() | |
| if not api: | |
| return | |
| LOCAL_MIRROR.mkdir(parents=True, exist_ok=True) | |
| try: | |
| from huggingface_hub import snapshot_download | |
| snapshot_download( | |
| repo_id=HF_DATASET_REPO, | |
| repo_type="dataset", | |
| token=HF_TOKEN, | |
| local_dir=str(LOCAL_MIRROR), | |
| local_dir_use_symlinks=False, | |
| ignore_patterns=["*.git*", ".gitattributes", "README.md"], | |
| ) | |
| print(f" โ ๅทฒไป Dataset ๆๅๅฐ {LOCAL_MIRROR}") | |
| except Exception as e: | |
| print(f" โ ๏ธ pull ๅคฑ่ดฅ: {e}๏ผไฝฟ็จๆฌๅฐ้ป่ฎคๅผ") | |
| _write_defaults_locally() | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def cmd_gen_env(): | |
| """ไป็ฏๅขๅ้็ๆ HERMES_HOME/.env""" | |
| env_path = HERMES_HOME / ".env" | |
| env_path.parent.mkdir(parents=True, exist_ok=True) | |
| lines = ["# ็ฑ dataset_manager.py ่ชๅจ็ๆ๏ผๅฟๆๅจ็ผ่พ\n"] | |
| # WeCom | |
| for k in ["WECOM_BOT_ID", "WECOM_SECRET"]: | |
| lines.append(f"{k}={os.environ.get(k, '')}\n") | |
| # โโ ็จๆทๆๆ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| # ไผๅ ไฝฟ็จ็ฒพ็กฎ็ฝๅๅ๏ผWECOM_ALLOWED_USERS๏ผ๏ผๅ ถๆฌกๅ จๅผๆพ๏ผGATEWAY_ALLOW_ALL_USERS๏ผ | |
| # ไธค่ ้ฝๆช้ ็ฝฎๆถ้ป่ฎคๅ จๅผๆพ๏ผ้ฟๅ ๆๆ็จๆท้ฝ่ขซๆ็ปๅนถๆถๅฐ้ ๅฏน็ | |
| wecom_allowed = os.environ.get("WECOM_ALLOWED_USERS", "").strip() | |
| gateway_allow = os.environ.get("GATEWAY_ALLOW_ALL_USERS", "").strip() | |
| if wecom_allowed: | |
| # ็ฒพ็กฎ็ฝๅๅไผๅ ๏ผๅชๅ ่ฎธๅๅบ็็จๆท๏ผ้ๅทๅ้ไผไธๅพฎไฟก็จๆทๅๆID๏ผ | |
| lines.append(f"WECOM_ALLOWED_USERS={wecom_allowed}\n") | |
| lines.append("GATEWAY_ALLOW_ALL_USERS=false\n") | |
| print(f" ๐ WeCom ็ฝๅๅๅทฒ่ฎพ็ฝฎ: {wecom_allowed}") | |
| elif gateway_allow.lower() in ("false", "0", "no"): | |
| # ๆพๅผๅ ณ้ญๅ จๅผๆพ โโ ็จๆท้่ฆๆๅจ้ ๅฏน | |
| lines.append("GATEWAY_ALLOW_ALL_USERS=false\n") | |
| print(" โ ๏ธ GATEWAY_ALLOW_ALL_USERS=false๏ผๆช้ ๅฏน็จๆทๅฐ่ขซๆ็ป") | |
| else: | |
| # ้ป่ฎคๅ จๅผๆพ๏ผGATEWAY_ALLOW_ALL_USERS ไธบ็ฉบๆ true ๆถ๏ผ | |
| lines.append("GATEWAY_ALLOW_ALL_USERS=true\n") | |
| print(" โ GATEWAY_ALLOW_ALL_USERS=true๏ผๆๆ็จๆทๅๅฏไฝฟ็จ๏ผ") | |
| # Providers 1-5 | |
| for p in range(1, 6): | |
| for k in ["NAME", "BASE_URL", "API_KEY"] + [f"MODEL_{m}" for m in range(1, 11)]: | |
| var = f"PROVIDER_{p}_{k}" | |
| lines.append(f"{var}={os.environ.get(var, '')}\n") | |
| # HF | |
| lines.append(f"HF_TOKEN={HF_TOKEN}\n") | |
| lines.append(f"HF_DATASET_REPO={HF_DATASET_REPO}\n") | |
| env_path.write_text("".join(lines), encoding="utf-8") | |
| print(f" โ .env ๅทฒๅๅ ฅ {env_path}") | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def cmd_watch(): | |
| """ | |
| ๆไปถ็่งๅจ๏ผ | |
| - ๅฎๆถ่ทฏๅพ๏ผconfig, SOUL, skills, memories, sessions, cron๏ผ๏ผ | |
| ๆฃๆตๅฐๅๅ็ซๅณไธไผ ๅฐ Dataset | |
| - logs๏ผๆฏ 10 ๅ้ๆน้ไธไผ ไธๆฌก | |
| """ | |
| api = get_api() | |
| if not api: | |
| print("โ ๏ธ ๆ API๏ผ็่งๅจ้ๅบ") | |
| return | |
| print(" ๐๏ธ ๆไปถ็่งๅจๅฏๅจ๏ผๅฎๆถๅๆญฅ + 10ๅ้ๆจ logs๏ผ") | |
| # ็ปดๆคๆไปถๅๅธ่กจ | |
| hashes: dict[str, str] = {} | |
| last_log_push = time.time() | |
| def collect_realtime_files(): | |
| files = {} | |
| for rel in REALTIME_PATHS: | |
| p = LOCAL_MIRROR / rel | |
| if p.is_file(): | |
| files[str(p.relative_to(LOCAL_MIRROR))] = p | |
| elif p.is_dir(): | |
| for f in p.rglob("*"): | |
| if f.is_file(): | |
| files[str(f.relative_to(LOCAL_MIRROR))] = f | |
| return files | |
| def collect_log_files(): | |
| files = {} | |
| for rel in LOG_ONLY_PATHS: | |
| p = LOCAL_MIRROR / rel | |
| if p.is_dir(): | |
| for f in p.rglob("*"): | |
| if f.is_file(): | |
| files[str(f.relative_to(LOCAL_MIRROR))] = f | |
| return files | |
| # ๅๅงๅๅธๅฟซ็ ง | |
| for rel, path in collect_realtime_files().items(): | |
| hashes[rel] = file_hash(path) | |
| while True: | |
| try: | |
| # โโ ๅฎๆถๆฃๆตๅๅ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| current = collect_realtime_files() | |
| changed = [] | |
| for rel, path in current.items(): | |
| h = file_hash(path) | |
| if hashes.get(rel) != h: | |
| hashes[rel] = h | |
| changed.append((rel, path)) | |
| for rel, path in changed: | |
| ts = datetime.now().strftime("%H:%M:%S") | |
| ok = upload_file(api, path, rel, | |
| f"Realtime sync [{ts}]: {rel}") | |
| if ok: | |
| print(f" โ๏ธ [{ts}] ๅทฒๆจ้: {rel}") | |
| # โโ ๆฏ 10 ๅ้ๆจ logs โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| if time.time() - last_log_push >= LOG_PUSH_INTERVAL: | |
| log_files = collect_log_files() | |
| if log_files: | |
| ts = datetime.now().strftime("%Y-%m-%d %H:%M") | |
| for rel, path in log_files.items(): | |
| upload_file(api, path, rel, f"Log sync [{ts}]") | |
| print(f" ๐ [{ts}] logs ๅทฒๆจ้ ({len(log_files)} ไธชๆไปถ)") | |
| last_log_push = time.time() | |
| except Exception as e: | |
| print(f" โ ๏ธ ็่งๅจๅผๅธธ: {e}") | |
| time.sleep(5) # ๆฏ 5 ็งๆฃๆตไธๆฌกๅๅ | |
| # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| if __name__ == "__main__": | |
| cmd = sys.argv[1] if len(sys.argv) > 1 else "" | |
| {"init": cmd_init, "pull": cmd_pull, | |
| "gen_env": cmd_gen_env, "watch": cmd_watch}.get(cmd, lambda: print( | |
| "็จๆณ: python dataset_manager.py [init|pull|gen_env|watch]"))() | |
| DM_EOF | |
| # โโ ๅๅ ฅ webui.py โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN cat > /webui.py << 'WEBUI_EOF' | |
| """ | |
| webui.py โ Hermes Agent Gradio Web UI | |
| ็ซฏๅฃ: 7860 | |
| """ | |
| import os, sys, subprocess, time, shutil | |
| from pathlib import Path | |
| import gradio as gr | |
| HERMES_HOME = Path(os.environ.get("HERMES_HOME", "/data/hermes")) | |
| HF_DS_LOCAL = Path(os.environ.get("HF_DATASET_LOCAL", "/data/hf_dataset")) | |
| HERMES_SRC = Path("/opt/hermes-agent") | |
| sys.path.insert(0, str(HERMES_SRC)) | |
| # โโ ่พ ๅฉๅฝๆฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def get_models(): | |
| models = [] | |
| for p in range(1, 6): | |
| name = os.environ.get(f"PROVIDER_{p}_NAME", "").strip() | |
| url = os.environ.get(f"PROVIDER_{p}_BASE_URL", "").strip() | |
| api_key = os.environ.get(f"PROVIDER_{p}_API_KEY", "").strip() | |
| if not (name and url and api_key): | |
| continue | |
| for m in range(1, 11): | |
| model = os.environ.get(f"PROVIDER_{p}_MODEL_{m}", "").strip() | |
| if model: | |
| models.append((p, model, f"[{name}] {model}")) | |
| return models | |
| def run_hermes(message, history, provider_idx, model_name): | |
| env = os.environ.copy() | |
| env["HERMES_HOME"] = str(HERMES_HOME) | |
| env["OPENAI_BASE_URL"] = os.environ.get(f"PROVIDER_{provider_idx}_BASE_URL", "") | |
| env["OPENAI_API_KEY"] = os.environ.get(f"PROVIDER_{provider_idx}_API_KEY", "") | |
| ctx = [] | |
| for m in history[-6:]: | |
| role = m.get("role","") | |
| content = m.get("content","") | |
| if role == "user" and content: ctx.append(f"User: {content}") | |
| elif role == "assistant" and content: ctx.append(f"Assistant: {content}") | |
| ctx.append(f"User: {message}") | |
| prompt = "\n".join(ctx) | |
| try: | |
| r = subprocess.run( | |
| [sys.executable, str(HERMES_SRC/"run_agent.py"), | |
| "--once", "--model", model_name, "--message", prompt], | |
| capture_output=True, text=True, timeout=120, | |
| env=env, cwd=str(HERMES_SRC) | |
| ) | |
| out = r.stdout.strip() | |
| return out if out else (r.stderr.strip()[:400] or "(ๆ ๅๅค)") | |
| except subprocess.TimeoutExpired: | |
| return "โ ๏ธ ่ถ ๆถ๏ผ120s๏ผ๏ผ่ฏท้่ฏ" | |
| except Exception as e: | |
| return f"โ ๏ธ ่ฐ็จๅคฑ่ดฅ: {e}" | |
| # โโ ่ฏปๅ Dataset ๆฌๅฐ้ๅๆไปถ๏ผ่ฝฏ้พ๏ผๅฎๆถ็ๆ๏ผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| def r(path: Path, default=""): | |
| return path.read_text("utf-8") if path.exists() else default | |
| def w(path: Path, content: str, label=""): | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| path.write_text(content, "utf-8") | |
| return f"โ {label or path.name} ๅทฒไฟๅญ๏ผๆไปถ็่งๅจๅฐ่ชๅจๅๆญฅๅฐ Dataset๏ผ" | |
| cfg_path = HF_DS_LOCAL / "config.yaml" | |
| soul_path = HF_DS_LOCAL / "SOUL.md" | |
| memory_path = HF_DS_LOCAL / "memories" / "MEMORY.md" | |
| log_path = HERMES_HOME / "logs" / "gateway.log" | |
| def gw_status(): | |
| r2 = subprocess.run(["pgrep","-f","hermes.*gateway"],capture_output=True,text=True) | |
| return "โ WeCom Gateway ่ฟ่กไธญ" if r2.returncode==0 else "โ ๏ธ WeCom Gateway ๆช่ฟ่ก" | |
| def restart_gw(): | |
| subprocess.run(["pkill","-f","hermes.*gateway"],capture_output=True) | |
| time.sleep(2) | |
| if not (os.environ.get("WECOM_BOT_ID") and os.environ.get("WECOM_SECRET")): | |
| return "โ ๏ธ WECOM_BOT_ID / WECOM_SECRET ๆช้ ็ฝฎ" | |
| env = os.environ.copy() | |
| env["HERMES_HOME"] = str(HERMES_HOME) | |
| log_path.parent.mkdir(parents=True, exist_ok=True) | |
| with open(log_path,"a") as lf: | |
| proc = subprocess.Popen( | |
| [sys.executable,"-m","hermes_cli.main","gateway"], | |
| env=env, cwd=str(HERMES_SRC), stdout=lf, stderr=lf) | |
| time.sleep(3) | |
| return f"โ Gateway ๅทฒ้ๅฏ (PID: {proc.pid})" | |
| def manual_push(): | |
| r2 = subprocess.run([sys.executable,"/dataset_manager.py","push"], | |
| capture_output=True,text=True,timeout=60) | |
| return r2.stdout + r2.stderr | |
| def manual_pull(): | |
| r2 = subprocess.run([sys.executable,"/dataset_manager.py","pull"], | |
| capture_output=True,text=True,timeout=60) | |
| return r2.stdout + r2.stderr | |
| # โโ ๆๅปบ UI โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| all_models = get_models() | |
| model_labels = [m[2] for m in all_models] or ["(ๆช้ ็ฝฎๆจกๅ)"] | |
| def chat_fn(msg, history, model_choice, sp): | |
| if not msg.strip(): | |
| yield history, "" | |
| return | |
| idx = next((m[0] for m in all_models if m[2]==model_choice), 1) | |
| mname = next((m[1] for m in all_models if m[2]==model_choice), model_choice) | |
| if sp.strip(): | |
| soul_path.parent.mkdir(parents=True,exist_ok=True) | |
| soul_path.write_text(sp,"utf-8") | |
| yield history + [{"role":"user","content":msg},{"role":"assistant","content":"๐ ๆ่ไธญ..."}], "" | |
| reply = run_hermes(msg, history, idx, mname) | |
| yield history + [{"role":"user","content":msg},{"role":"assistant","content":reply}], "" | |
| with gr.Blocks(title="Hermes Agent", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# โค Hermes Agent\n> [Nous Research](https://nousresearch.com) ยท HuggingFace Space") | |
| with gr.Tabs(): | |
| # โโ ่ๅคฉ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("๐ฌ ่ๅคฉ"): | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| chatbot = gr.Chatbot(height=500, show_copy_button=True, type="messages") | |
| with gr.Row(): | |
| inp = gr.Textbox(placeholder="่พๅ ฅๆถๆฏโฆ",show_label=False,lines=2,scale=5) | |
| gr.Button("ๅ้",variant="primary",scale=1).click( | |
| chat_fn,[inp,chatbot, | |
| gr.Dropdown(choices=model_labels,value=model_labels[0],label="ๆจกๅ",interactive=True), | |
| gr.Textbox(value=lambda:r(soul_path,"ไฝ ๆฏไธไธชๆ็จ็ๅฉๆ"),label="็ณป็ปๆ็คบ่ฏ",lines=6)], | |
| [chatbot,inp]) | |
| gr.Button("๐๏ธ ๆธ ็ฉบ",size="sm").click(lambda:[],outputs=[chatbot]) | |
| with gr.Column(scale=1): | |
| model_dd = gr.Dropdown(choices=model_labels,value=model_labels[0],label="้ๆฉๆจกๅ") | |
| soul_box = gr.Textbox(value=lambda:r(soul_path),label="็ณป็ปๆ็คบ่ฏ(SOUL.md)",lines=10,interactive=True) | |
| save_soul = gr.Button("๐พ ไฟๅญ SOUL.md",size="sm") | |
| soul_st = gr.Textbox(interactive=False,lines=1,label="") | |
| save_soul.click(lambda c: w(soul_path,c,"SOUL.md"), [soul_box],[soul_st]) | |
| inp.submit(chat_fn,[inp,chatbot,model_dd,soul_box],[chatbot,inp]) | |
| # โโ WeCom โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("๐ฑ WeCom ไผไธๅพฎไฟก"): | |
| gr.Markdown(""" | |
| ### WeCom AI Bot๏ผWebSocket ๆจกๅผ๏ผๆ ้ๅ ฌ็ฝ็ซฏ็น๏ผ | |
| **้ ็ฝฎๆญฅ้ชค๏ผ** | |
| 1. [ไผไธๅพฎไฟก็ฎก็ๅๅฐ](https://work.weixin.qq.com/wework_admin/frame) โ ๅบ็จ็ฎก็ โ ๅๅปบๅบ็จ โ **AI Bot** | |
| 2. ๅคๅถ Bot ID ๅ Secret | |
| 3. ๅจ HF Space Settings โ **Secrets** ไธญๆทปๅ ๏ผ | |
| - `WECOM_BOT_ID` = Bot ID | |
| - `WECOM_SECRET` = Secret | |
| 4. ๏ผๅฏ้๏ผๅจ HF Space Settings โ **Variables** ไธญๆทปๅ ็จๆท็ฝๅๅ๏ผ | |
| - `WECOM_ALLOWED_USERS` = ๅ ่ฎธไฝฟ็จ็ไผไธๅพฎไฟก็จๆทๅ๏ผ้ๅทๅ้๏ผๅฆ `ๅผ ไธ,ๆๅ` | |
| - ไธๅกซๅ้ป่ฎค**ๆๆ็จๆท**ๅๅฏไฝฟ็จ๏ผ`GATEWAY_ALLOW_ALL_USERS=true`๏ผ | |
| - ่ฅ่ฎพไธบ `GATEWAY_ALLOW_ALL_USERS=false` ไธไธๅกซ็ฝๅๅ๏ผๅๆๆ็จๆท้ๆๅจ้ ๅฏน | |
| 5. ็นๅปไธๆน"้ๅฏ Gateway" | |
| """) | |
| with gr.Row(): | |
| gw_box = gr.Textbox(label="Gateway ็ถๆ",interactive=False,lines=2) | |
| with gr.Column(): | |
| gr.Button("๐ ๆฃๆฅ็ถๆ").click(gw_status,outputs=[gw_box]) | |
| gr.Button("๐ ้ๅฏ Gateway",variant="primary").click(restart_gw,outputs=[gw_box]) | |
| # โโ ่ฎฐๅฟ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("๐ง ่ฎฐๅฟ็ฎก็"): | |
| gr.Markdown("็ดๆฅ็ผ่พ MEMORY.md๏ผไฟๅญๅๆไปถ็่งๅจ่ชๅจๅๆญฅๅฐ Dataset๏ผๆ ้ๆๅจ Push๏ผใ") | |
| mem_box = gr.Textbox(value=lambda:r(memory_path),label="MEMORY.md",lines=20,interactive=True) | |
| with gr.Row(): | |
| gr.Button("๐พ ไฟๅญ",variant="primary").click( | |
| lambda c: w(memory_path,c,"MEMORY.md"),[mem_box],[gr.Textbox(label="",lines=1)]) | |
| gr.Button("๐ ๅทๆฐ").click(lambda:r(memory_path),outputs=[mem_box]) | |
| # โโ ้ ็ฝฎ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("โ๏ธ ้ ็ฝฎๆไปถ"): | |
| gr.Markdown(""" | |
| ็ดๆฅ็ผ่พ `config.yaml`๏ผไฟๅญๅๆไปถ็่งๅจ**ๅฎๆถๅๆญฅ**ๅฐ HF Datasetใ | |
| **WeCom Gateway** ้ๅฏๅ่ฏปๅๆฐ้ ็ฝฎ๏ผ**Web UI ่ๅคฉ** ๅทๆฐ้กต้ขๅณ็ๆใ | |
| """) | |
| cfg_box = gr.Code(value=lambda:r(cfg_path),language="yaml",label="config.yaml",lines=30,interactive=True) | |
| with gr.Row(): | |
| gr.Button("๐พ ไฟๅญ config.yaml",variant="primary").click( | |
| lambda c: w(cfg_path,c,"config.yaml"),[cfg_box],[gr.Textbox(label="",lines=1)]) | |
| gr.Button("๐ ๅทๆฐ").click(lambda:r(cfg_path),outputs=[cfg_box]) | |
| # โโ Dataset โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("โ๏ธ Dataset ๅๆญฅ"): | |
| gr.Markdown(""" | |
| **่ชๅจๅๆญฅ็ญ็ฅ๏ผ** | |
| - `config.yaml` / `SOUL.md` / `skills` / `memories` / `sessions` / `cron` โ ๆไปถๅๅๆถ**็ซๅณ**ๆจ้ๅฐ Dataset | |
| - `logs` โ ๆฏ **10 ๅ้**ๆน้ๆจ้ไธๆฌก | |
| ๆๅจๆไฝไป ๅจ้่ฆๆถไฝฟ็จ๏ผๅฆๅผบๅถ่ฆ็ๆๆๅไปไบบไฟฎๆน๏ผใ | |
| """) | |
| with gr.Row(): | |
| gr.Button("๐ฅ ๆๅจ Pull๏ผไป Dataset ่ฆ็ๆฌๅฐ๏ผ").click(manual_pull,outputs=[gr.Textbox(label="่พๅบ",lines=10)]) | |
| gr.Button("๐ค ๆๅจ Push๏ผ็ซๅณๆจ้ๅ จ้จ๏ผ",variant="primary").click(manual_push,outputs=[gr.Textbox(label="่พๅบ",lines=10)]) | |
| # โโ ๆฅๅฟ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| with gr.Tab("๐ ๆฅๅฟ"): | |
| log_box = gr.Textbox(value=lambda: "\n".join( | |
| (log_path.read_text("utf-8",errors="replace").splitlines()[-80:] | |
| if log_path.exists() else ["(ๆๆ ๆฅๅฟ)"])), | |
| label="gateway.log๏ผๆๅ80่ก๏ผ",lines=25,interactive=False) | |
| gr.Button("๐ ๅทๆฐๆฅๅฟ").click( | |
| lambda: "\n".join( | |
| log_path.read_text("utf-8",errors="replace").splitlines()[-80:] | |
| if log_path.exists() else ["(ๆๆ ๆฅๅฟ)"]), | |
| outputs=[log_box]) | |
| gr.Markdown("---\n**GitHub**: [NousResearch/hermes-agent](https://github.com/NousResearch/hermes-agent) ยท MIT License") | |
| if __name__ == "__main__": | |
| demo.queue().launch(server_name="0.0.0.0", server_port=7860, show_error=True) | |
| WEBUI_EOF | |
| # โโ Space README๏ผHF Space card๏ผๅฟ ้กปๆ๏ผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN cat > /README_SPACE.md << 'README_EOF' | |
| --- | |
| title: Hermes Agent | |
| emoji: โค | |
| colorFrom: purple | |
| colorTo: blue | |
| sdk: docker | |
| pinned: false | |
| license: mit | |
| --- | |
| # โค Hermes Agent | |
| > ่ชๆ้ฟ AI Agent ยท [Nous Research](https://nousresearch.com) ยท [GitHub](https://github.com/NousResearch/hermes-agent) | |
| **ๅช้ไธไผ ่ฟไธไธช Dockerfile ๅณๅฏๅฎๆ้จ็ฝฒใ** | |
| ๅ่ฝ๏ผ | |
| - ๐ Gradio Web UI ่ๅคฉ็้ข | |
| - ๐ฑ WeCom ไผไธๅพฎไฟก AI Bot๏ผWebSocket๏ผๆ ้ๅ ฌ็ฝ๏ผ | |
| - โ๏ธ HF Dataset ๅฎๆถ้ ็ฝฎๆไน ๅ | |
| - ๐ ๆฏๆไปปๆ OpenAI ๅ ผๅฎน็็ฌฌไธๆนๅคงๆจกๅ | |
| README_EOF | |
| # โโ ๅๅปบๅทฅไฝ็ฎๅฝ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | |
| RUN mkdir -p /data/workspace /data/hermes/logs /data/hf_dataset | |
| EXPOSE 7860 | |
| CMD ["/entrypoint.sh"] | |