feat: add --reflect mode with error handling + scheduler/autonomous scripts
This commit is contained in:
28
agentmain.py
28
agentmain.py
@@ -125,6 +125,7 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--scheduled', action='store_true', help='计划任务轮询模式')
|
||||
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编号')
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -149,6 +150,33 @@ if __name__ == '__main__':
|
||||
os.remove(rp); break
|
||||
else: break
|
||||
nround = int(nround) + 1 if nround.isdigit() else 1
|
||||
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):
|
||||
while 'done' not in (item := dq.get()): pass
|
||||
|
||||
6
reflect/autonomous.py
Normal file
6
reflect/autonomous.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# reflect/autonomous.py
|
||||
INTERVAL = 1800
|
||||
ONCE = False
|
||||
|
||||
def check():
|
||||
return "[AUTO]🤖 用户已经离开超过30分钟,作为自主智能体,请阅读自动化sop,执行自动任务。"
|
||||
17
reflect/scheduler.py
Normal file
17
reflect/scheduler.py
Normal 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
|
||||
Reference in New Issue
Block a user