Error investigation (from restored monitoring) found 2 root causes: 1. 'Blocked: script path resolves outside scripts dir' (5+ cron jobs): Jul 17 symlink refactor replaced real scripts with symlinks; the hermes cron scheduler's security check (Path.resolve + relative_to) rejects symlink escape. ALL no_agent script jobs blocked since Jul 17 23:12. FIX: converted 102 symlinks to hardlinks (same inode, resolve() stays inside scripts_dir, single-source still works). Permanent structural fix. 2. HTTP 429 on default profile (知识研究/梦境循环/wiki-self-growth/ evolution-pulse/大脑任务执行): default gateway used ocg-key1 (weekly 100%). FIX: switched default profile to ocg-key6 + added missing provider block. LLM verified working (3.1s). auto_heal extended to actually cover these automatically next time: - PROFILES registry: zhiwei (8643, system svc) + default (8642, user svc) - current_provider/switch_key/_scan_agent_log parameterized by profile - health() now reports llm_provider_default (agent.log scan) - auto_heal: per-profile 429 detection -> best_key -> switch_key(profile) - _ensure_provider_block: injects missing provider credentials from zhiwei config (single source of truth) into target config
33 lines
1.0 KiB
Python
33 lines
1.0 KiB
Python
import os, sys
|
|
|
|
scripts_dir = '/home/hmo/.hermes/profiles/position-analyst/scripts'
|
|
fixed, skipped, errors = 0, 0, []
|
|
for name in os.listdir(scripts_dir):
|
|
p = os.path.join(scripts_dir, name)
|
|
if not os.path.islink(p):
|
|
skipped += 1
|
|
continue
|
|
target = os.path.realpath(p)
|
|
if not os.path.exists(target):
|
|
errors.append(f"{name}: broken symlink -> {target}")
|
|
continue
|
|
try:
|
|
os.unlink(p)
|
|
os.link(target, p) # hardlink: same inode, .resolve() stays in scripts_dir
|
|
fixed += 1
|
|
except Exception as e:
|
|
errors.append(f"{name}: {e}")
|
|
|
|
print(f"fixed: {fixed}, skipped (non-symlink): {skipped}, errors: {len(errors)}")
|
|
for e in errors:
|
|
print(' ', e)
|
|
|
|
# verify with the scheduler's own check
|
|
from pathlib import Path
|
|
scripts_resolved = Path(scripts_dir).resolve()
|
|
test = (Path(scripts_dir) / 'meta_growth.py').resolve()
|
|
try:
|
|
test.relative_to(scripts_resolved)
|
|
print('VERIFY OK: meta_growth.py now passes relative_to check')
|
|
except ValueError:
|
|
print('VERIFY FAIL: still resolves outside') |