3
.gitignore
vendored
3
.gitignore
vendored
@@ -68,4 +68,5 @@ restore_commit.txt
|
|||||||
sche_tasks/
|
sche_tasks/
|
||||||
QUICK_START.md
|
QUICK_START.md
|
||||||
# CDP Bridge 密钥配置(首次运行自动生成)
|
# CDP Bridge 密钥配置(首次运行自动生成)
|
||||||
assets/tmwd_cdp_bridge/config.js
|
assets/tmwd_cdp_bridge/config.js
|
||||||
|
**log.*
|
||||||
|
|||||||
33
agentmain.py
33
agentmain.py
@@ -9,7 +9,8 @@ from sidercall import SiderLLMSession, LLMSession, ToolClient, ClaudeSession, Xa
|
|||||||
from agent_loop import agent_runner_loop, StepOutcome, BaseHandler
|
from agent_loop import agent_runner_loop, StepOutcome, BaseHandler
|
||||||
from ga import GenericAgentHandler, smart_format, get_global_memory, format_error
|
from ga import GenericAgentHandler, smart_format, get_global_memory, format_error
|
||||||
|
|
||||||
with open('assets/tools_schema.json', 'r', encoding='utf-8') as f:
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(os.path.join(script_dir, 'assets/tools_schema.json'), 'r', encoding='utf-8') as f:
|
||||||
TS = f.read()
|
TS = f.read()
|
||||||
TOOLS_SCHEMA = json.loads(TS if os.name == 'nt' else TS.replace('powershell', 'bash'))
|
TOOLS_SCHEMA = json.loads(TS if os.name == 'nt' else TS.replace('powershell', 'bash'))
|
||||||
|
|
||||||
@@ -24,14 +25,16 @@ if not os.path.exists('assets/tmwd_cdp_bridge/config.js'):
|
|||||||
f.write(f"const TID = '__ljq_{hex(random.randint(0, 99999999))[2:8]}';")
|
f.write(f"const TID = '__ljq_{hex(random.randint(0, 99999999))[2:8]}';")
|
||||||
|
|
||||||
def get_system_prompt():
|
def get_system_prompt():
|
||||||
with open('assets/sys_prompt.txt', 'r', encoding='utf-8') as f: prompt = f.read()
|
with open(os.path.join(script_dir, 'assets/sys_prompt.txt'), 'r', encoding='utf-8') as f: prompt = f.read()
|
||||||
prompt += f"\nToday: {time.strftime('%Y-%m-%d %a')}\n"
|
prompt += f"\nToday: {time.strftime('%Y-%m-%d %a')}\n"
|
||||||
prompt += get_global_memory()
|
prompt += get_global_memory()
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
class GeneraticAgent:
|
class GeneraticAgent:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if not os.path.exists('temp'): os.makedirs('temp')
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
temp_dir = os.path.join(script_dir, 'temp')
|
||||||
|
if not os.path.exists(temp_dir): os.makedirs(temp_dir)
|
||||||
from sidercall import mykeys
|
from sidercall import mykeys
|
||||||
llm_sessions = []
|
llm_sessions = []
|
||||||
for k, cfg in mykeys.items():
|
for k, cfg in mykeys.items():
|
||||||
@@ -89,7 +92,8 @@ class GeneraticAgent:
|
|||||||
self.history.append(f"[USER]: {rquery}")
|
self.history.append(f"[USER]: {rquery}")
|
||||||
|
|
||||||
sys_prompt = get_system_prompt()
|
sys_prompt = get_system_prompt()
|
||||||
handler = GenericAgentHandler(None, self.history, './temp')
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
handler = GenericAgentHandler(None, self.history, os.path.join(script_dir, 'temp'))
|
||||||
if self.handler and self.handler.key_info:
|
if self.handler and self.handler.key_info:
|
||||||
handler.key_info = self.handler.key_info
|
handler.key_info = self.handler.key_info
|
||||||
if '清除工作记忆' not in handler.key_info:
|
if '清除工作记忆' not in handler.key_info:
|
||||||
@@ -136,8 +140,9 @@ if __name__ == '__main__':
|
|||||||
threading.Thread(target=agent.run, daemon=True).start()
|
threading.Thread(target=agent.run, daemon=True).start()
|
||||||
|
|
||||||
if args.task:
|
if args.task:
|
||||||
d = f'temp/{args.task}'; rp = f'{d}/reply.txt'; nround = ''
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
with open(f'{d}/input.txt', encoding='utf-8') as f: raw = f.read()
|
d = os.path.join(script_dir, f'temp/{args.task}'); rp = os.path.join(d, 'reply.txt'); nround = ''
|
||||||
|
with open(os.path.join(d, 'input.txt'), encoding='utf-8') as f: raw = f.read()
|
||||||
while True:
|
while True:
|
||||||
dq = agent.put_task(raw, source='task')
|
dq = agent.put_task(raw, source='task')
|
||||||
while 'done' not in (item := dq.get(timeout=120)):
|
while 'done' not in (item := dq.get(timeout=120)):
|
||||||
@@ -173,23 +178,27 @@ if __name__ == '__main__':
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
if once: raise
|
if once: raise
|
||||||
print(f'[Reflect] drain error: {e}'); result = f'[ERROR] {e}'
|
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')
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
open(os.path.join(script_dir, './temp/reflect.log'), 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}]\n{result}\n\n')
|
||||||
if on_done:
|
if on_done:
|
||||||
try: on_done(result)
|
try: on_done(result)
|
||||||
except Exception as e: print(f'[Reflect] on_done error: {e}')
|
except Exception as e: print(f'[Reflect] on_done error: {e}')
|
||||||
if once: print('[Reflect] ONCE=True, exiting.'); break
|
if once: print('[Reflect] ONCE=True, exiting.'); break
|
||||||
elif args.scheduled:
|
elif args.scheduled:
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
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(os.path.join(script_dir, './temp/scheduler.log'), 'a', encoding='utf-8').write(f'[{datetime.now():%m-%d %H:%M}] {tag}\n{item["done"]}\n\n')
|
||||||
while True:
|
while True:
|
||||||
time.sleep(55 + random.random() * 10)
|
time.sleep(55 + random.random() * 10)
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
if not os.path.isdir('./sche_tasks/pending'): continue
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
for f in os.listdir('./sche_tasks/pending'):
|
sche_tasks_dir = os.path.join(script_dir, './sche_tasks/pending')
|
||||||
|
if not os.path.isdir(sche_tasks_dir): continue
|
||||||
|
for f in os.listdir(sche_tasks_dir):
|
||||||
m = re.match(r'(\d{4}-\d{2}-\d{2})_(\d{4})_', f)
|
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'):
|
if m and now >= datetime.strptime(f'{m[1]} {m[2]}', '%Y-%m-%d %H%M'):
|
||||||
raw = open(f'./sche_tasks/pending/{f}', encoding='utf-8').read()
|
raw = open(os.path.join(sche_tasks_dir, f), encoding='utf-8').read()
|
||||||
dq = agent.put_task(f'按scheduled_task_sop执行任务文件 ../sche_tasks/pending/{f}(立刻移到running)\n内容:\n{raw}', source='scheduler')
|
dq = agent.put_task(f'按scheduled_task_sop执行任务文件 ../sche_tasks/pending/{f}(立刻移到running)\n内容:\n{raw}', source='scheduler')
|
||||||
threading.Thread(target=drain, args=(dq, f), daemon=True).start()
|
threading.Thread(target=drain, args=(dq, f), daemon=True).start()
|
||||||
break
|
break
|
||||||
@@ -206,4 +215,4 @@ if __name__ == '__main__':
|
|||||||
if 'done' in item: print(); break
|
if 'done' in item: print(); break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
agent.abort()
|
agent.abort()
|
||||||
print('\n[Interrupted]')
|
print('\n[Interrupted]')
|
||||||
@@ -15,7 +15,8 @@ def generate_tool_schema():
|
|||||||
"""
|
"""
|
||||||
通过代码内省,将 Handler 的逻辑映射为高语义的工具描述。
|
通过代码内省,将 Handler 的逻辑映射为高语义的工具描述。
|
||||||
"""
|
"""
|
||||||
with open('../ga.py', 'r', encoding='utf-8') as f:
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(os.path.join(script_dir, '../ga.py'), 'r', encoding='utf-8') as f:
|
||||||
ga_code = f.read()
|
ga_code = f.read()
|
||||||
# 极简且具备高度概括能力的元 Prompt
|
# 极简且具备高度概括能力的元 Prompt
|
||||||
meta_prompt = f"""
|
meta_prompt = f"""
|
||||||
@@ -69,7 +70,8 @@ def generate_tool_schema():
|
|||||||
final_schema = json.loads(clean_json)
|
final_schema = json.loads(clean_json)
|
||||||
|
|
||||||
if final_schema:
|
if final_schema:
|
||||||
with open('tools_schema.json', 'w', encoding='utf-8') as f:
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(os.path.join(script_dir, 'tools_schema.json'), 'w', encoding='utf-8') as f:
|
||||||
json.dump(final_schema, f, indent=2, ensure_ascii=False)
|
json.dump(final_schema, f, indent=2, ensure_ascii=False)
|
||||||
print("✅ 成功从代码内省生成 Schema 并持久化。")
|
print("✅ 成功从代码内省生成 Schema 并持久化。")
|
||||||
return final_schema
|
return final_schema
|
||||||
@@ -79,7 +81,10 @@ def generate_tool_schema():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def make_system_prompt(ga_code_path='../ga.py'):
|
def make_system_prompt(ga_code_path=None):
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
if ga_code_path is None:
|
||||||
|
ga_code_path = os.path.join(script_dir, '../ga.py')
|
||||||
with open(ga_code_path, 'r', encoding='utf-8') as f:
|
with open(ga_code_path, 'r', encoding='utf-8') as f:
|
||||||
ga_code = f.read()
|
ga_code = f.read()
|
||||||
|
|
||||||
@@ -117,7 +122,7 @@ def make_system_prompt(ga_code_path='../ga.py'):
|
|||||||
print("📝 生成的 System Prompt 内容如下:\n")
|
print("📝 生成的 System Prompt 内容如下:\n")
|
||||||
print(system_prompt_content)
|
print(system_prompt_content)
|
||||||
clean_content = re.sub(r'<[^>]+>', '', system_prompt_content)
|
clean_content = re.sub(r'<[^>]+>', '', system_prompt_content)
|
||||||
with open('sys_prompt.txt', 'w', encoding='utf-8') as f:
|
with open(os.path.join(script_dir, 'sys_prompt.txt'), 'w', encoding='utf-8') as f:
|
||||||
f.write(clean_content)
|
f.write(clean_content)
|
||||||
return clean_content
|
return clean_content
|
||||||
|
|
||||||
|
|||||||
11
ga.py
11
ga.py
@@ -16,7 +16,8 @@ def code_run(code, code_type="python", timeout=60, cwd=None, code_cwd=None, stop
|
|||||||
"""
|
"""
|
||||||
preview = (code[:60].replace('\n', ' ') + '...') if len(code) > 60 else code.strip()
|
preview = (code[:60].replace('\n', ' ') + '...') if len(code) > 60 else code.strip()
|
||||||
yield f"[Action] Running {code_type} in {os.path.basename(cwd)}: {preview}\n"
|
yield f"[Action] Running {code_type} in {os.path.basename(cwd)}: {preview}\n"
|
||||||
cwd = cwd or os.path.join(os.getcwd(), 'temp'); tmp_path = None
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
cwd = cwd or os.path.join(script_dir, 'temp'); tmp_path = None
|
||||||
if code_type == "python":
|
if code_type == "python":
|
||||||
tmp_file = tempfile.NamedTemporaryFile(suffix=".ai.py", delete=False, mode='w', encoding='utf-8', dir=code_cwd)
|
tmp_file = tempfile.NamedTemporaryFile(suffix=".ai.py", delete=False, mode='w', encoding='utf-8', dir=code_cwd)
|
||||||
tmp_file.write(code)
|
tmp_file.write(code)
|
||||||
@@ -150,7 +151,8 @@ def format_error(e):
|
|||||||
|
|
||||||
def log_memory_access(path):
|
def log_memory_access(path):
|
||||||
if 'memory' not in path: return
|
if 'memory' not in path: return
|
||||||
stats_file = 'memory/file_access_stats.json'
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
stats_file = os.path.join(script_dir, 'memory/file_access_stats.json')
|
||||||
try:
|
try:
|
||||||
with open(stats_file, 'r', encoding='utf-8') as f: stats = json.load(f)
|
with open(stats_file, 'r', encoding='utf-8') as f: stats = json.load(f)
|
||||||
except: stats = {}
|
except: stats = {}
|
||||||
@@ -493,8 +495,9 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
def get_global_memory():
|
def get_global_memory():
|
||||||
prompt = "\n"
|
prompt = "\n"
|
||||||
try:
|
try:
|
||||||
with open('memory/global_mem_insight.txt', 'r', encoding='utf-8') as f: insight = f.read()
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
with open('assets/insight_fixed_structure.txt', 'r', encoding='utf-8') as f: structure = f.read()
|
with open(os.path.join(script_dir, 'memory/global_mem_insight.txt'), 'r', encoding='utf-8') as f: insight = f.read()
|
||||||
|
with open(os.path.join(script_dir, 'assets/insight_fixed_structure.txt'), 'r', encoding='utf-8') as f: structure = f.read()
|
||||||
prompt += f"\n[Memory]\n"
|
prompt += f"\n[Memory]\n"
|
||||||
prompt += f'cwd = {os.path.abspath("./temp")} (用./引用)\n'
|
prompt += f'cwd = {os.path.abspath("./temp")} (用./引用)\n'
|
||||||
prompt += structure + '\n../memory/global_mem_insight.txt:\n'
|
prompt += structure + '\n../memory/global_mem_insight.txt:\n'
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ def get_screen_width():
|
|||||||
|
|
||||||
def start_streamlit(port):
|
def start_streamlit(port):
|
||||||
global proc
|
global proc
|
||||||
cmd = [sys.executable, "-m", "streamlit", "run", "stapp.py", "--server.port", str(port), "--server.address", "localhost", "--server.headless", "true", "--theme.base", "dark"] # 暗黑模式
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
cmd = [sys.executable, "-m", "streamlit", "run", os.path.join(script_dir, "stapp.py"), "--server.port", str(port), "--server.address", "localhost", "--server.headless", "true", "--theme.base", "dark"] # 暗黑模式
|
||||||
proc = subprocess.Popen(cmd)
|
proc = subprocess.Popen(cmd)
|
||||||
atexit.register(proc.kill)
|
atexit.register(proc.kill)
|
||||||
|
|
||||||
@@ -72,7 +73,8 @@ if __name__ == '__main__':
|
|||||||
threading.Thread(target=start_streamlit, args=(port,), daemon=True).start()
|
threading.Thread(target=start_streamlit, args=(port,), daemon=True).start()
|
||||||
|
|
||||||
if args.tg:
|
if args.tg:
|
||||||
tgproc = subprocess.Popen([sys.executable, "tgapp.py"], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0)
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
tgproc = subprocess.Popen([sys.executable, os.path.join(script_dir, "tgapp.py")], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0)
|
||||||
atexit.register(tgproc.kill)
|
atexit.register(tgproc.kill)
|
||||||
print('[Launch] Telegram Bot started')
|
print('[Launch] Telegram Bot started')
|
||||||
else: print('[Launch] Telegram Bot not enabled (use --tg to start)')
|
else: print('[Launch] Telegram Bot not enabled (use --tg to start)')
|
||||||
@@ -80,7 +82,8 @@ if __name__ == '__main__':
|
|||||||
if not args.no_sched:
|
if not args.no_sched:
|
||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM); sock.bind(('127.0.0.1', 45762)); sock.listen(1)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM); sock.bind(('127.0.0.1', 45762)); sock.listen(1)
|
||||||
scheduler_proc = subprocess.Popen([sys.executable, "agentmain.py", "--scheduled", "--llm_no", str(args.llm_no)], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0);
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
scheduler_proc = subprocess.Popen([sys.executable, os.path.join(script_dir, "agentmain.py"), "--scheduled", "--llm_no", str(args.llm_no)], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0);
|
||||||
atexit.register(lambda: (scheduler_proc.kill(), sock.close()))
|
atexit.register(lambda: (scheduler_proc.kill(), sock.close()))
|
||||||
print('[Launch] Task Scheduler started')
|
print('[Launch] Task Scheduler started')
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ from datetime import datetime
|
|||||||
INTERVAL = 60 # 原版 55+random*10
|
INTERVAL = 60 # 原版 55+random*10
|
||||||
ONCE = False
|
ONCE = False
|
||||||
|
|
||||||
PENDING = './sche_tasks/pending'
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
PENDING = os.path.join(script_dir, '../sche_tasks/pending')
|
||||||
|
|
||||||
def check():
|
def check():
|
||||||
if not os.path.isdir(PENDING): return None
|
if not os.path.isdir(PENDING): return None
|
||||||
@@ -12,6 +13,6 @@ def check():
|
|||||||
for f in os.listdir(PENDING):
|
for f in os.listdir(PENDING):
|
||||||
m = re.match(r'(\d{4}-\d{2}-\d{2})_(\d{4})_', f)
|
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'):
|
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()
|
raw = open(os.path.join(PENDING, f), encoding='utf-8').read()
|
||||||
return f'按scheduled_task_sop执行任务文件 ../sche_tasks/pending/{f}(立刻移到running)\n内容:\n{raw}'
|
return f'按scheduled_task_sop执行任务文件 ../sche_tasks/pending/{f}(立刻移到running)\n内容:\n{raw}'
|
||||||
return None
|
return None
|
||||||
15
sidercall.py
15
sidercall.py
@@ -37,7 +37,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=10000):
|
def __init__(self, api_key, api_base, model="claude-opus", context_win=9000):
|
||||||
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):
|
||||||
@@ -51,7 +51,7 @@ class ClaudeSession:
|
|||||||
else: break
|
else: break
|
||||||
if current > self.context_win * 3.6: print(f'[DEBUG] {len(result)} contexts, whole length {current//4} tokens.')
|
if current > self.context_win * 3.6: print(f'[DEBUG] {len(result)} contexts, whole length {current//4} tokens.')
|
||||||
return result[::-1] or messages[-2:]
|
return result[::-1] or messages[-2:]
|
||||||
def raw_ask(self, messages, model=None, temperature=0.5, max_tokens=6144):
|
def raw_ask(self, messages, model=None, temperature=0.5, max_tokens=4096):
|
||||||
model = model or self.default_model
|
model = model or self.default_model
|
||||||
headers = {"x-api-key": self.api_key, "Content-Type": "application/json", "anthropic-version": "2023-06-01"}
|
headers = {"x-api-key": self.api_key, "Content-Type": "application/json", "anthropic-version": "2023-06-01"}
|
||||||
payload = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, "stream": True}
|
payload = {"model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, "stream": True}
|
||||||
@@ -100,6 +100,9 @@ class LLMSession:
|
|||||||
else: self.api_mode = "chat_completions"
|
else: self.api_mode = "chat_completions"
|
||||||
|
|
||||||
def _endpoint(self, path):
|
def _endpoint(self, path):
|
||||||
|
# 处理火山引擎API,它已经包含完整路径
|
||||||
|
if 'ark.cn-beijing.volces.com' in self.api_base or 'ark.cn-shanghai.volces.com' in self.api_base:
|
||||||
|
return f"{self.api_base}/{path.lstrip('/')}"
|
||||||
if self.api_base.endswith('/v1'): return f"{self.api_base}/{path.lstrip('/')}"
|
if self.api_base.endswith('/v1'): return f"{self.api_base}/{path.lstrip('/')}"
|
||||||
if self.api_base.endswith('$'): return f"{self.api_base.rstrip('$')}/{path.lstrip('/')}"
|
if self.api_base.endswith('$'): return f"{self.api_base.rstrip('$')}/{path.lstrip('/')}"
|
||||||
return f"{self.api_base}/v1/{path.lstrip('/')}"
|
return f"{self.api_base}/v1/{path.lstrip('/')}"
|
||||||
@@ -387,7 +390,8 @@ class ToolClient:
|
|||||||
def chat(self, messages, tools=None):
|
def chat(self, messages, tools=None):
|
||||||
full_prompt = self._build_protocol_prompt(messages, tools)
|
full_prompt = self._build_protocol_prompt(messages, tools)
|
||||||
print("Full prompt length:", len(full_prompt), 'chars')
|
print("Full prompt length:", len(full_prompt), 'chars')
|
||||||
with open(f'./temp/model_responses_{os.getpid()}.txt', 'a', encoding='utf-8', errors="replace") as f:
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(os.path.join(script_dir, f'./temp/model_responses_{os.getpid()}.txt'), 'a', encoding='utf-8', errors="replace") as f:
|
||||||
f.write(f"=== Prompt === {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n{full_prompt}\n")
|
f.write(f"=== Prompt === {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n{full_prompt}\n")
|
||||||
gen = self.backend.ask(full_prompt, stream=True)
|
gen = self.backend.ask(full_prompt, stream=True)
|
||||||
raw_text = ''; summarytag = '[NextWillSummary]'
|
raw_text = ''; summarytag = '[NextWillSummary]'
|
||||||
@@ -397,7 +401,8 @@ class ToolClient:
|
|||||||
print('Complete response received.')
|
print('Complete response received.')
|
||||||
if raw_text.endswith(summarytag):
|
if raw_text.endswith(summarytag):
|
||||||
self.last_tools = ''; raw_text = raw_text[:-len(summarytag)]
|
self.last_tools = ''; raw_text = raw_text[:-len(summarytag)]
|
||||||
with open(f'./temp/model_responses_{os.getpid()}.txt', 'a', encoding='utf-8', errors="replace") as f:
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
with open(os.path.join(script_dir, f'./temp/model_responses_{os.getpid()}.txt'), 'a', encoding='utf-8', errors="replace") as f:
|
||||||
f.write(f"=== Response === {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n{raw_text}\n\n")
|
f.write(f"=== Response === {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n{raw_text}\n\n")
|
||||||
return self._parse_mixed_response(raw_text)
|
return self._parse_mixed_response(raw_text)
|
||||||
|
|
||||||
@@ -538,4 +543,4 @@ if __name__ == "__main__":
|
|||||||
response = get_final(llmclient.chat(
|
response = get_final(llmclient.chat(
|
||||||
messages=[{"role": "user", "content": "<tool_result>10.176.45.12</tool_result>"}]
|
messages=[{"role": "user", "content": "<tool_result>10.176.45.12</tool_result>"}]
|
||||||
))
|
))
|
||||||
print(response.content)
|
print(response.content)
|
||||||
9
stapp.py
9
stapp.py
@@ -80,18 +80,19 @@ def agent_backend_stream(prompt):
|
|||||||
|
|
||||||
if "messages" not in st.session_state: st.session_state.messages = []
|
if "messages" not in st.session_state: st.session_state.messages = []
|
||||||
for msg in st.session_state.messages:
|
for msg in st.session_state.messages:
|
||||||
with st.chat_message(msg["role"]): st.markdown(msg["content"])
|
with st.chat_message(msg["role"]): st.markdown(msg["content"], unsafe_allow_html=True)
|
||||||
|
|
||||||
if prompt := st.chat_input("请输入指令"):
|
if prompt := st.chat_input("请输入指令"):
|
||||||
st.session_state.messages.append({"role": "user", "content": prompt})
|
st.session_state.messages.append({"role": "user", "content": prompt})
|
||||||
with st.chat_message("user"): st.markdown(prompt)
|
#允许消息内容中包含 HTML 代码并直接渲染,但注意这会有 XSS 安全风险,仅在内容可信时使用
|
||||||
|
with st.chat_message("user"): st.markdown(prompt, unsafe_allow_html=True)
|
||||||
|
|
||||||
with st.chat_message("assistant"):
|
with st.chat_message("assistant"):
|
||||||
message_placeholder = st.empty()
|
message_placeholder = st.empty()
|
||||||
response = ''
|
response = ''
|
||||||
for response in agent_backend_stream(prompt):
|
for response in agent_backend_stream(prompt):
|
||||||
message_placeholder.markdown(response + "▌")
|
message_placeholder.markdown(response + "▌", unsafe_allow_html=True)
|
||||||
message_placeholder.markdown(response)
|
message_placeholder.markdown(response, unsafe_allow_html=True)
|
||||||
st.session_state.messages.append({"role": "assistant", "content": response})
|
st.session_state.messages.append({"role": "assistant", "content": response})
|
||||||
st.session_state.last_reply_time = int(time.time())
|
st.session_state.last_reply_time = int(time.time())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user