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
|
model_responses.txt
|
||||||
|
|
||||||
|
# 任务调度目录
|
||||||
|
tasks/
|
||||||
|
|
||||||
*.zip
|
*.zip
|
||||||
|
|
||||||
# 存储敏感信息的记忆文件夹(除了公开的 SOP)
|
# 存储敏感信息的记忆文件夹(除了公开的 SOP)
|
||||||
@@ -42,6 +45,7 @@ memory/*
|
|||||||
# Allow tracking of specific SOPs
|
# Allow tracking of specific SOPs
|
||||||
!memory/web_setup_sop.md
|
!memory/web_setup_sop.md
|
||||||
!memory/autonomous_operation_sop.md
|
!memory/autonomous_operation_sop.md
|
||||||
|
!memory/scheduled_task_sop.md
|
||||||
|
|
||||||
# ljqCtrl related tools
|
# ljqCtrl related tools
|
||||||
!memory/ljqCtrl.py
|
!memory/ljqCtrl.py
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class BaseHandler:
|
|||||||
elif tool_name == 'bad_json':
|
elif tool_name == 'bad_json':
|
||||||
return StepOutcome(None, next_prompt=args.get('msg', 'bad_json'), should_exit=False)
|
return StepOutcome(None, next_prompt=args.get('msg', 'bad_json'), should_exit=False)
|
||||||
else:
|
else:
|
||||||
yield f"❌ 未知工具: {tool_name}\n"
|
yield f"未知工具: {tool_name}\n"
|
||||||
return StepOutcome(None, next_prompt=f"未知工具 {tool_name}", should_exit=False)
|
return StepOutcome(None, next_prompt=f"未知工具 {tool_name}", should_exit=False)
|
||||||
|
|
||||||
def json_default(o):
|
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")
|
if sys.stdout is None: sys.stdout = open(os.devnull, "w")
|
||||||
elif hasattr(sys.stdout, 'reconfigure'): sys.stdout.reconfigure(errors='replace')
|
elif hasattr(sys.stdout, 'reconfigure'): sys.stdout.reconfigure(errors='replace')
|
||||||
if sys.stderr is None: sys.stderr = open(os.devnull, "w")
|
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 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
|
return full_text
|
||||||
|
|
||||||
class ClaudeSession:
|
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.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()
|
self.raw_msgs, self.lock = [], threading.Lock()
|
||||||
def _trim_messages(self, messages):
|
def _trim_messages(self, messages):
|
||||||
|
|||||||
Reference in New Issue
Block a user