feat: subagent SOP, autonomous SOP overhaul, ga.py try-block fix, launch llm_no param, agentmain streamline

This commit is contained in:
Liang Jiaqing
2026-02-16 19:08:55 +08:00
parent df478d81e1
commit 32ad26f4ce
6 changed files with 130 additions and 61 deletions

View File

@@ -18,11 +18,10 @@ def get_system_prompt():
if not os.path.exists('memory/global_mem.txt'):
with open('memory/global_mem.txt', 'w', encoding='utf-8') as f: f.write('')
if not os.path.exists('memory/global_mem_insight.txt'):
content = "## Global Memory Index (Logic)\n\n[CONSTITUTION]\n1. 改我自身源码前必须先问用户\n\n[STORES]\n- global_mem: ../memory/global_mem.txt\n\n[ACCESS]\n- global_mem: 按 TOPIC 检索索引\n\n[TOPICS.GLOBAL_MEM]"
if os.path.exists('assets/global_mem_insight_template.txt'):
with open('assets/global_mem_insight_template.txt', 'r', encoding='utf-8') as f: content = f.read()
with open('memory/global_mem_insight.txt', 'w', encoding='utf-8') as f: f.write(content)
t = 'assets/global_mem_insight_template.txt'
open('memory/global_mem_insight.txt', 'w', encoding='utf-8').write(open(t, encoding='utf-8').read() if os.path.exists(t) else '')
with open('assets/sys_prompt.txt', 'r', encoding='utf-8') as f: prompt = f.read()
prompt += f"\nToday: {time.strftime('%Y-%m-%d %a')}\n"
prompt += get_global_memory()
return prompt
@@ -37,18 +36,14 @@ class GeneraticAgent:
["gemini-3.0-flash", "claude-haiku-4.5", "kimi-k2"]]
for cfg in oai_configs.values():
llm_sessions += [LLMSession(api_key=cfg['apikey'], api_base=cfg['apibase'], model=cfg['model'])]
if len(llm_sessions) > 0:
self.llmclient = ToolClient(llm_sessions, auto_save_tokens=True)
else:
self.llmclient = None
if len(llm_sessions) > 0: self.llmclient = ToolClient(llm_sessions, auto_save_tokens=True)
else: self.llmclient = None
self.lock = threading.Lock()
self.history = []
self.task_queue = queue.Queue()
self.last_active_time = time.time()
self.is_running = False
self.is_running, self.stop_sig = False, False
self.llm_no = 0
self.stop_sig = False
self.current_source = 'none'
self.inc_out = False
self.handler = None
self.verbose = True
@@ -75,9 +70,6 @@ class GeneraticAgent:
task = self.task_queue.get()
self.is_running = True
raw_query, source, display_queue = task["query"], task["source"], task["output"]
self.current_source = source
self.last_active_time = time.time()
rquery = smart_format(raw_query.replace('\n', ' '), max_str_len=200)
self.history.append(f"[USER]: {rquery}")
@@ -88,45 +80,74 @@ class GeneraticAgent:
gen = agent_runner_loop(self.llmclient, sys_prompt, raw_query,
handler, TOOLS_SCHEMA, max_turns=40, verbose=self.verbose)
try:
full_response = ""; last_pos = 0
full_resp = ""; last_pos = 0
for chunk in gen:
if self.stop_sig: break
full_response += chunk
if len(full_response) - last_pos > 50:
display_queue.put({'next': f'{full_response}', 'source': source})
last_pos = len(full_response)
if '</summary>' in full_response: full_response = full_response.replace('</summary>', '</summary>\n\n')
if '</file_content>' in full_response: full_response = re.sub(r'<file_content>\s*(.*?)\s*</file_content>', r'\n````\n<file_content>\n\1\n</file_content>\n````', full_response, flags=re.DOTALL)
display_queue.put({'done': full_response, 'source': source})
full_resp += chunk
if len(full_resp) - last_pos > 50:
display_queue.put({'next': full_resp[last_pos:] if self.inc_out else full_resp, 'source': source})
last_pos = len(full_resp)
if '</summary>' in full_resp: full_resp = full_resp.replace('</summary>', '</summary>\n\n')
if '</file_content>' in full_resp: full_resp = re.sub(r'<file_content>\s*(.*?)\s*</file_content>', r'\n````\n<file_content>\n\1\n</file_content>\n````', full_resp, flags=re.DOTALL)
display_queue.put({'done': full_resp, 'source': source})
self.history = handler.history_info
except Exception as e:
print(f"Backend Error: {format_error(e)}")
display_queue.put({'done': full_response + f'\n```\n{format_error(e)}\n```', 'source': source})
display_queue.put({'done': full_resp + f'\n```\n{format_error(e)}\n```', 'source': source})
finally:
self.is_running = False
self.stop_sig = False
self.current_source = 'none'
self.is_running = self.stop_sig = False
self.task_queue.task_done()
if self.handler is not None: self.handler.code_stop_signal.append(1)
if __name__ == '__main__':
import argparse
from datetime import datetime
parser = argparse.ArgumentParser()
parser.add_argument('--scheduled', action='store_true', help='计划任务轮询模式')
parser.add_argument('--task', metavar='IODIR', help='一次性任务模式(文件IO)')
parser.add_argument('--llm_no', type=int, default=0, help='LLM编号')
args = parser.parse_args()
agent = GeneraticAgent()
agent.llm_no = args.llm_no
agent.verbose = False
threading.Thread(target=agent.run, daemon=True).start()
def drain(dq, tag):
if args.task:
d = f'temp/{args.task}'; rp = f'{d}/reply.txt'
with open(f'{d}/input.txt', encoding='utf-8') as f: raw = f.read()
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)
dq = agent.put_task(raw, source='task')
while 'done' not in (item := dq.get()): pass
with open(f'{d}/output.txt', 'w', encoding='utf-8') as f: f.write(item['done'])
for _ in range(300): # 等reply.txt5分钟超时
time.sleep(1)
if os.path.exists(rp):
with open(rp, encoding='utf-8') as f: raw = f.read()
os.remove(rp); break
else: break
elif args.scheduled:
def drain(dq, tag):
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')
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)
else:
agent.inc_out = True
while True:
q = input('> ').strip()
if not q: continue
dq = agent.put_task(q, source='user')
while True:
item = dq.get()
if 'next' in item: print(item['next'], end='', flush=True)
if 'done' in item: print(); break