feat: add --reflect mode with error handling + scheduler/autonomous scripts

This commit is contained in:
Jiaqing Liang
2026-03-02 23:25:31 +08:00
parent 5c3193f326
commit 9219042a8f
3 changed files with 52 additions and 1 deletions

View File

@@ -125,6 +125,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--scheduled', action='store_true', help='计划任务轮询模式') parser.add_argument('--scheduled', action='store_true', help='计划任务轮询模式')
parser.add_argument('--task', metavar='IODIR', help='一次性任务模式(文件IO)') parser.add_argument('--task', metavar='IODIR', help='一次性任务模式(文件IO)')
parser.add_argument('--reflect', metavar='SCRIPT', help='反射模式加载监控脚本check()触发时发任务')
parser.add_argument('--llm_no', type=int, default=0, help='LLM编号') parser.add_argument('--llm_no', type=int, default=0, help='LLM编号')
args = parser.parse_args() args = parser.parse_args()
@@ -149,7 +150,34 @@ if __name__ == '__main__':
os.remove(rp); break os.remove(rp); break
else: break else: break
nround = int(nround) + 1 if nround.isdigit() else 1 nround = int(nround) + 1 if nround.isdigit() else 1
elif args.scheduled: elif args.reflect:
import importlib.util
spec = importlib.util.spec_from_file_location('reflect_script', args.reflect)
mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
interval = getattr(mod, 'INTERVAL', 5)
once = getattr(mod, 'ONCE', False)
on_done = getattr(mod, 'on_done', None)
print(f'[Reflect] loaded {args.reflect}, interval={interval}s, once={once}')
while True:
time.sleep(interval)
try: task = mod.check()
except Exception as e:
print(f'[Reflect] check() error: {e}'); continue
if task is None: continue
print(f'[Reflect] triggered: {task[:80]}')
dq = agent.put_task(task, source='reflect')
try:
while 'done' not in (item := dq.get(timeout=120)): pass
result = item['done']
except Exception as e:
if once: raise
print(f'[Reflect] drain error: {e}'); result = f'[ERROR] {e}'
open('./temp/reflect.log', 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}]\n{result}\n\n')
if on_done:
try: on_done(result)
except Exception as e: print(f'[Reflect] on_done error: {e}')
if once: print('[Reflect] ONCE=True, exiting.'); break
elif args.scheduled:
def drain(dq, tag): def drain(dq, tag):
while 'done' not in (item := dq.get()): pass while 'done' not in (item := dq.get()): pass
open('./temp/scheduler.log', 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}] {tag}\n{item["done"]}\n\n') open('./temp/scheduler.log', 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}] {tag}\n{item["done"]}\n\n')

6
reflect/autonomous.py Normal file
View File

@@ -0,0 +1,6 @@
# reflect/autonomous.py
INTERVAL = 1800
ONCE = False
def check():
return "[AUTO]🤖 用户已经离开超过30分钟作为自主智能体请阅读自动化sop执行自动任务。"

17
reflect/scheduler.py Normal file
View File

@@ -0,0 +1,17 @@
import os, re
from datetime import datetime
INTERVAL = 60 # 原版 55+random*10
ONCE = False
PENDING = './sche_tasks/pending'
def check():
if not os.path.isdir(PENDING): return None
now = datetime.now()
for f in os.listdir(PENDING):
m = re.match(r'(\d{4}-\d{2}-\d{2})_(\d{4})_', f)
if m and now >= datetime.strptime(f'{m[1]} {m[2]}', '%Y-%m-%d %H%M'):
raw = open(f'{PENDING}/{f}', encoding='utf-8').read()
return f'按scheduled_task_sop执行任务文件 ../sche_tasks/pending/{f}立刻移到running\n内容:\n{raw}'
return None