#!/usr/bin/env python3 """Patch hermes-agent to support auto-detecting document file paths for native delivery. By default, extract_local_files() only detects image/video extensions (.png, .jpg, etc.) which means .md, .pdf, .docx, .xlsx and other document files created by the agent are NOT sent as attachments. This patch adds document extensions to _LOCAL_MEDIA_EXTS so that when Hermes creates a file like /tmp/weather_report.md, it gets automatically sent as a native attachment on Feishu and WeChat instead of appearing as a plain text path. """ import re import sys import os import glob def patch_file(filepath: str): with open(filepath, 'r') as f: content = f.read() # Find and replace _LOCAL_MEDIA_EXTS old = """\ _LOCAL_MEDIA_EXTS = ( '.png', '.jpg', '.jpeg', '.gif', '.webp', '.mp4', '.mov', '.avi', '.mkv', '.webm', )""" new = """\ _LOCAL_MEDIA_EXTS = ( # Images '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg', # Videos '.mp4', '.mov', '.avi', '.mkv', '.webm', # Audio '.ogg', '.opus', '.mp3', '.wav', '.m4a', '.silk', '.flac', # Documents '.md', '.txt', '.csv', '.json', '.xml', '.yaml', '.yml', '.toml', '.log', '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.html', '.htm', # Archives '.zip', '.tar', '.gz', '.7z', '.rar', )""" if old not in content: print(f"WARNING: Could not find _LOCAL_MEDIA_EXTS in {filepath}", file=sys.stderr) print("The upstream code may have changed. Skipping this patch.", file=sys.stderr) sys.exit(0) content = content.replace(old, new, 1) with open(filepath, 'w') as f: f.write(content) print(f"Patched {filepath}: added document/audio/archive extensions to _LOCAL_MEDIA_EXTS") if __name__ == "__main__": # hermes-agent is installed in editable mode (-e), so source is in /app/hermes-agent/ candidates = [ "/app/hermes-agent/gateway/platforms/base.py", ] # Also search venv site-packages as fallback candidates.extend(glob.glob("/app/venv/lib/**/gateway/platforms/base.py", recursive=True)) filepath = None for c in candidates: if os.path.isfile(c): filepath = c break if not filepath: print("WARNING: base.py not found in any candidate location", file=sys.stderr) print(f"Checked: {candidates}", file=sys.stderr) print("Skipping patch_file_delivery.", file=sys.stderr) sys.exit(0) patch_file(filepath)