feat: 添加定时任务调度器和相关配置
- 新增定时任务调度器(agentmain.py):支持基于时间戳的任务自动执行 - 添加scheduled_task_sop.md:定时任务执行流程文档 - 优化agent_loop.py:移除错误提示emoji - 调整sidercall.py:降低context_win至10000 - 更新.gitignore:忽略tasks目录,白名单scheduled_task_sop.md
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -33,6 +33,9 @@ auth.json
|
||||
# 忽略模型响应记录
|
||||
model_responses.txt
|
||||
|
||||
# 任务调度目录
|
||||
tasks/
|
||||
|
||||
*.zip
|
||||
|
||||
# 存储敏感信息的记忆文件夹(除了公开的 SOP)
|
||||
@@ -42,6 +45,7 @@ memory/*
|
||||
# Allow tracking of specific SOPs
|
||||
!memory/web_setup_sop.md
|
||||
!memory/autonomous_operation_sop.md
|
||||
!memory/scheduled_task_sop.md
|
||||
|
||||
# ljqCtrl related tools
|
||||
!memory/ljqCtrl.py
|
||||
|
||||
@@ -26,7 +26,7 @@ class BaseHandler:
|
||||
elif tool_name == 'bad_json':
|
||||
return StepOutcome(None, next_prompt=args.get('msg', 'bad_json'), should_exit=False)
|
||||
else:
|
||||
yield f"❌ 未知工具: {tool_name}\n"
|
||||
yield f"未知工具: {tool_name}\n"
|
||||
return StepOutcome(None, next_prompt=f"未知工具 {tool_name}", should_exit=False)
|
||||
|
||||
def json_default(o):
|
||||
|
||||
22
agentmain.py
22
agentmain.py
@@ -1,4 +1,4 @@
|
||||
import os, sys, threading, queue, time, json, re
|
||||
import os, sys, threading, queue, time, json, re, random
|
||||
if sys.stdout is None: sys.stdout = open(os.devnull, "w")
|
||||
elif hasattr(sys.stdout, 'reconfigure'): sys.stdout.reconfigure(errors='replace')
|
||||
if sys.stderr is None: sys.stderr = open(os.devnull, "w")
|
||||
@@ -110,3 +110,23 @@ class GeneraticAgent:
|
||||
if self.handler is not None: self.handler.code_stop_signal.append(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from datetime import datetime
|
||||
agent = GeneraticAgent()
|
||||
threading.Thread(target=agent.run, daemon=True).start()
|
||||
def drain(dq, tag):
|
||||
while True:
|
||||
item = dq.get(); txt = item.get('done') or item.get('next', '')
|
||||
open('./temp/scheduler_live.log', 'w', encoding='utf-8').write(txt)
|
||||
if 'done' in item: break
|
||||
open('./temp/scheduler.log', 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}] {tag}\n{txt}\n\n')
|
||||
while True:
|
||||
now = datetime.now()
|
||||
for f in os.listdir('./tasks/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'./tasks/pending/{f}', encoding='utf-8').read()
|
||||
dq = agent.put_task(f'按scheduled_task_sop执行任务文件 ./tasks/pending/{f}(立刻移到running)\n内容:\n{raw}', source='scheduler')
|
||||
threading.Thread(target=drain, args=(dq, f), daemon=True).start()
|
||||
break
|
||||
time.sleep(55 + random.random() * 10)
|
||||
11
memory/scheduled_task_sop.md
Normal file
11
memory/scheduled_task_sop.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# 定时任务 SOP
|
||||
|
||||
目录:`../tasks/{pending,running,done}/`
|
||||
文件名:`YYYY-MM-DD_HHMM_描述.md`,内容含prompt和schedule
|
||||
|
||||
## 流程
|
||||
1. [AUTO]唤醒 → `datetime.now()`取当前时间,`ls ../tasks/pending/`,文件名时间≤当前→到期,选择一个
|
||||
2. **立即rename到running/**(先占再读,防多进程重复领)
|
||||
3. 读文件执行
|
||||
4. 完成→移到done/,**在文件内追加执行报告**供用户查阅
|
||||
5. schedule非once→算下次时间,新建文件到pending/
|
||||
@@ -28,7 +28,7 @@ class SiderLLMSession:
|
||||
return full_text
|
||||
|
||||
class ClaudeSession:
|
||||
def __init__(self, api_key, api_base, model="claude-opus", context_win=12000):
|
||||
def __init__(self, api_key, api_base, model="claude-opus", context_win=10000):
|
||||
self.api_key, self.api_base, self.default_model, self.context_win = api_key, api_base.rstrip('/'), model, context_win
|
||||
self.raw_msgs, self.lock = [], threading.Lock()
|
||||
def _trim_messages(self, messages):
|
||||
|
||||
Reference in New Issue
Block a user