Spaces:
Running
Running
File size: 4,360 Bytes
9d9a46e 460aac4 9d9a46e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #!/usr/bin/env python3
"""Patch hermes-agent gateway to auto-resolve relative media paths.
ROOT CAUSE: When the LLM uses write_file, it often saves files with relative
paths like "广东天气预报.md" or "/tmp/广东天气预报.md", then puts
"MEDIA:广东天气预报.md" in the response. The gateway's extract_media()
parses this bare filename, but the subsequent send_document() call fails
because the path is relative and os.path.isfile() returns False.
FIX: After extract_media() returns the media_files list, scan each path:
1. If already absolute and exists → keep as-is
2. If relative → search well-known directories (/tmp/, /data/hermes/uploads/,
current working directory, HERMES_HOME) for a file with that name
3. Replace the path with the resolved absolute path
4. If still not found → keep the original (will fail with clear error)
This is a surgical patch to the _deliver_response() method in base.py,
inserted right after the "media_files, response = self.extract_media(response)"
line.
"""
import re
import sys
import os
import glob
def patch_file(filepath: str):
with open(filepath, 'r') as f:
content = f.read()
# Find the insertion point: right after extract_media() call
old = """\
# Extract MEDIA:<path> tags (from TTS tool) before other processing
media_files, response = self.extract_media(response)"""
new = """\
# Extract MEDIA:<path> tags (from TTS tool) before other processing
media_files, response = self.extract_media(response)
# Auto-resolve relative media paths to absolute paths.
# The LLM often uses bare filenames in MEDIA: tags (e.g. "report.md")
# which fail because send_document() can't find them.
_media_search_dirs = ['/tmp', '/data/hermes/uploads', '/data', os.getcwd()]
_hermes_home = os.path.expanduser('~/.hermes')
if _hermes_home not in _media_search_dirs:
_media_search_dirs.append(_hermes_home)
_resolved_media = []
for _mpath, _mvoice in media_files:
if os.path.isabs(_mpath) and os.path.isfile(_mpath):
_resolved_media.append((_mpath, _mvoice))
continue
# Try to find the file in well-known directories
_basename = os.path.basename(_mpath)
_found = None
for _search_dir in _media_search_dirs:
_candidate = os.path.join(_search_dir, _basename)
if os.path.isfile(_candidate):
_found = _candidate
break
if _found:
logger.info("[%s] Resolved relative media path '%s' -> '%s'", self.name, _mpath, _found)
_resolved_media.append((_found, _mvoice))
else:
# Keep original — will fail with a clear error message
_resolved_media.append((_mpath, _mvoice))
logger.warning("[%s] Could not resolve media path '%s' — searched %s", self.name, _mpath, _media_search_dirs)
media_files = _resolved_media"""
if old not in content:
print(f"WARNING: Could not find insertion point 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}: auto-resolve relative media paths before sending")
if __name__ == "__main__":
candidates = [
"/app/hermes-agent/gateway/platforms/base.py",
]
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_resolve_media_paths.", file=sys.stderr)
sys.exit(0)
patch_file(filepath)
|