refactor: unify docstrings, add /resume command, simplify error msg

This commit is contained in:
Liang Jiaqing
2026-04-16 21:03:47 +08:00
parent e7e560715e
commit aa674655a8
3 changed files with 14 additions and 31 deletions

View File

@@ -17,13 +17,14 @@ def load_tool_schema(suffix=''):
TOOLS_SCHEMA = json.loads(TS if os.name == 'nt' else TS.replace('powershell', 'bash'))
load_tool_schema()
lang_suffix = '_en' if os.environ.get('GA_LANG', '') == 'en' else ''
mem_dir = os.path.join(script_dir, 'memory')
if not os.path.exists(mem_dir): os.makedirs(mem_dir)
mem_txt = os.path.join(mem_dir, 'global_mem.txt')
if not os.path.exists(mem_txt): open(mem_txt, 'w', encoding='utf-8').write('# [Global Memory - L2]\n')
mem_insight = os.path.join(mem_dir, 'global_mem_insight.txt')
if not os.path.exists(mem_insight):
t = os.path.join(script_dir, 'assets/global_mem_insight_template.txt')
t = os.path.join(script_dir, f'assets/global_mem_insight_template{lang_suffix}.txt')
open(mem_insight, 'w', encoding='utf-8').write(open(t, encoding='utf-8').read() if os.path.exists(t) else '')
cdp_cfg = os.path.join(script_dir, 'assets/tmwd_cdp_bridge/config.js')
if not os.path.exists(cdp_cfg):
@@ -33,8 +34,7 @@ if not os.path.exists(cdp_cfg):
except Exception as e: print(f'[WARN] CDP config init failed: {e} — advanced web features (tmwebdriver) will be unavailable.')
def get_system_prompt():
suffix = '_en' if os.environ.get('GA_LANG', '') == 'en' else ''
with open(os.path.join(script_dir, f'assets/sys_prompt{suffix}.txt'), 'r', encoding='utf-8') as f: prompt = f.read()
with open(os.path.join(script_dir, f'assets/sys_prompt{lang_suffix}.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
@@ -111,6 +111,8 @@ class GeneraticAgent:
setattr(self.llmclient.backend, k, v)
display_queue.put({'done': f"✅ session.{k} = {v!r}"})
self.task_queue.task_done(); continue
if raw_query.strip() == '/resume':
raw_query = '简单看看model_responses中的最近几次对话结尾部分(除了本次),分别简单总结一下让我选择,然后你简单阅读了解情况后作为我们接下来聊天的基础'
self.is_running = True
rquery = smart_format(raw_query.replace('\n', ' '), max_str_len=200)
self.history.append(f"[USER]: {rquery}")

View File

@@ -20,7 +20,7 @@ st.set_page_config(page_title="Cowork", layout="wide")
def init():
agent = GeneraticAgent()
if agent.llmclient is None:
st.error("⚠️ 未配置任何可用的 LLM 接口,请mykey.py 中添加 sider_cookie 或 oai_apikey+oai_apibase 等信息后重启")
st.error("⚠️ 未配置任何可用的 LLM 接口,请设置mykey.py。")
st.stop()
else: threading.Thread(target=agent.run, daemon=True).start()
return agent

35
ga.py
View File

@@ -12,8 +12,7 @@ def code_run(code, code_type="python", timeout=60, cwd=None, code_cwd=None, stop
"""代码执行器
python: 运行复杂的 .py 脚本(文件模式)
powershell/bash: 运行单行指令(命令模式)
优先使用python仅在必要系统操作时使用powershell
"""
优先使用python仅在必要系统操作时使用powershell"""
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"
script_dir = os.path.dirname(os.path.abspath(__file__))
@@ -90,9 +89,8 @@ def code_run(code, code_type="python", timeout=60, cwd=None, code_cwd=None, stop
if code_type == "python" and tmp_path and os.path.exists(tmp_path): os.remove(tmp_path)
def ask_user(question: str, candidates: list = None):
"""question: 向用户提出的问题。candidates: 可选的候选项列表。需要保证should_exit为True
"""
def ask_user(question, candidates=None):
"""question: 向用户提出的问题。candidates: 可选的候选项列表"""
return {"status": "INTERRUPT", "intent": "HUMAN_INTERVENTION",
"data": {"question": question, "candidates": candidates or []}}
@@ -165,21 +163,7 @@ def log_memory_access(path):
with open(stats_file, 'w', encoding='utf-8') as f: json.dump(stats, f, indent=2, ensure_ascii=False)
def web_execute_js(script, switch_tab_id=None, no_monitor=False):
"""
执行 JS 脚本来控制浏览器,并捕获结果和页面变化。
script: 要执行的 JavaScript 代码字符串。
return {
"status": "failed" if error_msg else "success",
"js_return": result,
"error": error_msg,
"transients": transients,
"environment": {
"newTabs": [],
"reloaded": reloaded
},
"diff": diff_summary,
}
"""
"""执行 JS 脚本来控制浏览器,并捕获结果和页面变化"""
global driver
try:
if driver is None: first_init_driver()
@@ -187,13 +171,12 @@ def web_execute_js(script, switch_tab_id=None, no_monitor=False):
if switch_tab_id: driver.default_session_id = switch_tab_id
result = simphtml.execute_js_rich(script, driver, no_monitor=no_monitor)
return result
except Exception as e:
return {"status": "error", "msg": format_error(e)}
except Exception as e: return {"status": "error", "msg": format_error(e)}
def expand_file_refs(text, base_dir=None):
"""展开文本中的 {{file:路径:起始行:结束行}} 引用为实际文件内容。
可与普通文本混排。展开失败抛 ValueError。
base_dir: 相对路径的基准目录,默认为进程 cwd"""
base_dir: 相对路径的基准目录,默认为进程 cwd"""
pattern = r'\{\{file:(.+?):(\d+):(\d+)\}\}'
def replacer(match):
path, start, end = match.group(1), int(match.group(2)), int(match.group(3))
@@ -205,8 +188,7 @@ def expand_file_refs(text, base_dir=None):
return re.sub(pattern, replacer, text)
def file_patch(path: str, old_content: str, new_content: str):
"""在文件中寻找唯一的 old_content 块并替换为 new_content
"""
"""在文件中寻找唯一的 old_content 块并替换为 new_content"""
path = str(Path(path).resolve())
try:
if not os.path.exists(path): return {"status": "error", "msg": "文件不存在"}
@@ -218,8 +200,7 @@ def file_patch(path: str, old_content: str, new_content: str):
updated_text = full_text.replace(old_content, new_content)
with open(path, 'w', encoding='utf-8') as f: f.write(updated_text)
return {"status": "success", "msg": "文件局部修改成功"}
except Exception as e:
return {"status": "error", "msg": str(e)}
except Exception as e: return {"status": "error", "msg": str(e)}
_read_dirs = set()
def _scan_files(base, depth=2):