Files
MoFin/scripts/cron_status.py
T
hmo 57377e9dd3 feat(auto_heal): multi-profile key switching + fix two error classes
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
2026-07-20 01:12:38 +08:00

31 lines
1.2 KiB
Python

import json
from datetime import datetime, timezone, timedelta
d = json.load(open('/home/hmo/.hermes/profiles/position-analyst/cron/jobs.json'))
jobs = d if isinstance(d, list) else d.get('jobs', [])
now = datetime.now(timezone.utc)
print(f"{'name':32} {'last_run':20} {'status':8} {'next_run':20} {'en'}")
print('-' * 95)
for j in sorted(jobs, key=lambda x: x.get('last_run_at') or ''):
if not j.get('enabled', True):
continue
lr = (j.get('last_run_at') or '?')[:19]
nr = (j.get('next_run_at') or '?')[:19]
st = str(j.get('last_status', '?'))
print(f"{j.get('name','?')[:32]:32} {lr:20} {st:8} {nr:20} {j.get('enabled')}")
# also check gateway-side cron (default profile)
print()
print('=== default profile cron ===')
try:
d2 = json.load(open('/home/hmo/.hermes/cron/jobs.json'))
jobs2 = d2 if isinstance(d2, list) else d2.get('jobs', [])
for j in sorted(jobs2, key=lambda x: x.get('last_run_at') or ''):
if not j.get('enabled', True):
continue
lr = (j.get('last_run_at') or '?')[:19]
nr = (j.get('next_run_at') or '?')[:19]
st = str(j.get('last_status', '?'))
print(f"{j.get('name','?')[:32]:32} {lr:20} {st:8} {nr:20} {j.get('enabled')}")
except Exception as e:
print('err:', e)