update start_long_term desc: remove single-call limit, add 15-turn rule
This commit is contained in:
@@ -69,6 +69,7 @@ def agent_runner_loop(client, system_prompt, user_input, handler, tools_schema,
|
|||||||
showarg = get_pretty_json(args)
|
showarg = get_pretty_json(args)
|
||||||
if not verbose and len(showarg) > 200: showarg = showarg[:200] + ' ...'
|
if not verbose and len(showarg) > 200: showarg = showarg[:200] + ' ...'
|
||||||
yield f"🛠️ **正在调用工具:** `{tool_name}` 📥**参数:**\n````text\n{showarg}\n````\n"
|
yield f"🛠️ **正在调用工具:** `{tool_name}` 📥**参数:**\n````text\n{showarg}\n````\n"
|
||||||
|
handler.current_turn = turn + 1
|
||||||
gen = handler.dispatch(tool_name, args, response)
|
gen = handler.dispatch(tool_name, args, response)
|
||||||
if verbose:
|
if verbose:
|
||||||
yield '`````\n'
|
yield '`````\n'
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
"name": "web_execute_js",
|
"name": "web_execute_js",
|
||||||
"description": "万能网页操控工具。通过执行 JavaScript 脚本实现对浏览器的完全控制(如点击、滚动、提取特定数据)。鼓励在有把握情况下(记忆中有selector/做法等)精准使用以减少web_scan调用。执行结果可选择保存到本地文件进行后续分析。",
|
"description": "万能网页操控工具。通过执行 JavaScript 脚本实现对浏览器的完全控制(如点击、滚动、提取特定数据)。鼓励在有把握情况下(记忆中有selector/做法等)精准使用以减少web_scan调用。执行结果可选择保存到本地文件进行后续分析。",
|
||||||
"parameters": {"type": "object", "properties": {
|
"parameters": {"type": "object", "properties": {
|
||||||
"script": {"type": "string", "description": "要执行的 JavaScript 代码。"},
|
"script": {"type": "string", "description": "要执行的 JavaScript 代码或JS文件路径。"},
|
||||||
"save_to_file": {"type": "string", "description": "可选。将 JS 执行结果(js_return)保存到的文件路径。该功能不支持 await 等异步结果。"}}, "required": ["script"]}
|
"save_to_file": {"type": "string", "description": "可选。将 JS 执行结果(js_return)保存到的文件路径。该功能不支持 await 等异步结果。"}}, "required": ["script"]}
|
||||||
}},
|
}},
|
||||||
{"type": "function", "function": {
|
{"type": "function", "function": {
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
}},
|
}},
|
||||||
{"type": "function", "function": {
|
{"type": "function", "function": {
|
||||||
"name": "start_long_term_update",
|
"name": "start_long_term_update",
|
||||||
"description": "准备开始提炼记忆。发现值得长期记忆的信息(环境事实/用户偏好/避坑经验)时调用此工具。一次用户对话只允许调用一次,已记忆更新或在自主流程内时无需调用。",
|
"description": "准备开始提炼记忆。发现值得长期记忆的信息(环境事实/用户偏好/避坑经验)时调用此工具。已记忆更新或在自主流程内时无需调用。超15轮完成的任务必须调用以沉淀经验。",
|
||||||
"parameters": {"type": "object", "properties": {}}}
|
"parameters": {"type": "object", "properties": {}}}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
6
ga.py
6
ga.py
@@ -247,7 +247,7 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.key_info = ""
|
self.key_info = ""
|
||||||
self.related_sop = ""
|
self.related_sop = ""
|
||||||
self.cwd = cwd
|
self.cwd = cwd; self.current_turn = 0
|
||||||
self.history_info = last_history if last_history else []
|
self.history_info = last_history if last_history else []
|
||||||
self.code_stop_signal = []
|
self.code_stop_signal = []
|
||||||
|
|
||||||
@@ -313,6 +313,9 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
'''
|
'''
|
||||||
script = args.get("script", "")
|
script = args.get("script", "")
|
||||||
if not script: return StepOutcome(None, next_prompt="[Error] Empty script param. Check your tool call arguments.")
|
if not script: return StepOutcome(None, next_prompt="[Error] Empty script param. Check your tool call arguments.")
|
||||||
|
abs_path = self._get_abs_path(script.strip())
|
||||||
|
if os.path.isfile(abs_path):
|
||||||
|
with open(abs_path, 'r', encoding='utf-8') as f: script = f.read()
|
||||||
save_to_file = args.get("save_to_file", "")
|
save_to_file = args.get("save_to_file", "")
|
||||||
switch_tab_id = args.get("switch_tab_id") or args.get("tab_id")
|
switch_tab_id = args.get("switch_tab_id") or args.get("tab_id")
|
||||||
result = web_execute_js(script, switch_tab_id=switch_tab_id)
|
result = web_execute_js(script, switch_tab_id=switch_tab_id)
|
||||||
@@ -471,6 +474,7 @@ class GenericAgentHandler(BaseHandler):
|
|||||||
def _get_anchor_prompt(self):
|
def _get_anchor_prompt(self):
|
||||||
h_str = "\n".join(self.history_info[-20:])
|
h_str = "\n".join(self.history_info[-20:])
|
||||||
prompt = f"\n### [WORKING MEMORY]\n<history>\n{h_str}\n</history>"
|
prompt = f"\n### [WORKING MEMORY]\n<history>\n{h_str}\n</history>"
|
||||||
|
prompt += f"\nCurrent turn: {self.current_turn}\n"
|
||||||
if self.key_info: prompt += f"\n<key_info>{self.key_info}</key_info>"
|
if self.key_info: prompt += f"\n<key_info>{self.key_info}</key_info>"
|
||||||
if self.related_sop: prompt += f"\n有不清晰的地方请再次读取{self.related_sop}"
|
if self.related_sop: prompt += f"\n有不清晰的地方请再次读取{self.related_sop}"
|
||||||
try: print(prompt)
|
try: print(prompt)
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
3. **禁止存储易变状态 (No Volatile State)**
|
3. **禁止存储易变状态 (No Volatile State)**
|
||||||
* **定义**:严禁存储随时间/会话高频变化的数据。
|
* **定义**:严禁存储随时间/会话高频变化的数据。
|
||||||
* **示例**:当前时间戳、临时 Session ID、正在运行的 PID、某个具体绝对路径、连接的设备信息
|
* **示例**:当前时间戳、临时 Session ID、正在运行的 PID、某个具体绝对路径、连接的设备信息
|
||||||
|
4. **最小充分指针 (Minimum Sufficient Pointer)**
|
||||||
|
* 上层只留能定位下层的最短标识,多一词即冗余。
|
||||||
---
|
---
|
||||||
## 记忆层级架构
|
## 记忆层级架构
|
||||||
```
|
```
|
||||||
@@ -24,7 +26,7 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
|
|||||||
### L1:全局内存索引 (global_mem_insight.txt)
|
### L1:全局内存索引 (global_mem_insight.txt)
|
||||||
**职责**:为 L2 和 L3 提供极简导航索引,确保关键能力可被发现。
|
**职责**:为 L2 和 L3 提供极简导航索引,确保关键能力可被发现。
|
||||||
**特征**:
|
**特征**:
|
||||||
- 体积限制:≤ 30 行(硬约束)
|
- 体积限制:≤ 30 行(硬约束),严禁填写细节(除非极高频任务)
|
||||||
- 内容:两层「场景关键词→记忆定位」映射 + RULES(红线规则 + 高频犯错点)
|
- 内容:两层「场景关键词→记忆定位」映射 + RULES(红线规则 + 高频犯错点)
|
||||||
- 第一层:高频场景 key→value(直接给出 sop/py/L2 section 名),自包含可只写一个词
|
- 第一层:高频场景 key→value(直接给出 sop/py/L2 section 名),自包含可只写一个词
|
||||||
- 第二层:低频场景仅列关键词,需要时 read L2 或 ls L3 自行定位
|
- 第二层:低频场景仅列关键词,需要时 read L2 或 ls L3 自行定位
|
||||||
@@ -41,7 +43,7 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
|
|||||||
**特征**:
|
**特征**:
|
||||||
- 趋势:随环境扩展而膨胀(可接受)
|
- 趋势:随环境扩展而膨胀(可接受)
|
||||||
- 内容:按 `## [SECTION]` 组织的事实条目
|
- 内容:按 `## [SECTION]` 组织的事实条目
|
||||||
- 同步:变化时更新 L1 的相应 TOPIC 导航行
|
- 同步:变化时更新 L1 的相应 TOPIC 导航行,只能导航
|
||||||
**禁止**:禁止存储易变状态、禁止存储猜测、严禁存储大模型可推理的通用常识
|
**禁止**:禁止存储易变状态、禁止存储猜测、严禁存储大模型可推理的通用常识
|
||||||
---
|
---
|
||||||
### L3:任务级精简记录库 (../memory/)
|
### L3:任务级精简记录库 (../memory/)
|
||||||
@@ -61,6 +63,9 @@ L3: ../memory/ (记录库层 - 包含 .md/.py 等各类文件)
|
|||||||
| L2/L3 删除场景 | 删除对应层的关键词/映射行 |
|
| L2/L3 删除场景 | 删除对应层的关键词/映射行 |
|
||||||
| L2/L3 修改值 | 若不影响场景定位则不动 L1 |
|
| L2/L3 修改值 | 若不影响场景定位则不动 L1 |
|
||||||
| 发现通用避坑规律 | 压缩为一句加入 RULES |
|
| 发现通用避坑规律 | 压缩为一句加入 RULES |
|
||||||
|
|
||||||
|
> **同步红线**:L1 只写关键词/名称,禁搬细节。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 信息分类快速决策树
|
## 信息分类快速决策树
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ class LLMSession:
|
|||||||
|
|
||||||
def _endpoint(self, path):
|
def _endpoint(self, path):
|
||||||
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('/')}"
|
||||||
return f"{self.api_base}/v1/{path.lstrip('/')}"
|
return f"{self.api_base}/v1/{path.lstrip('/')}"
|
||||||
|
|
||||||
def _retry_delay(self, resp, attempt):
|
def _retry_delay(self, resp, attempt):
|
||||||
@@ -211,9 +212,7 @@ class LLMSession:
|
|||||||
try: body = (resp.text or "").strip()
|
try: body = (resp.text or "").strip()
|
||||||
except: body = ""
|
except: body = ""
|
||||||
body = body[:1200] if body else "<empty>"
|
body = body[:1200] if body else "<empty>"
|
||||||
rid = ""
|
rid = ""; retry_after = ""; ct = ""
|
||||||
retry_after = ""
|
|
||||||
ct = ""
|
|
||||||
try:
|
try:
|
||||||
h = resp.headers or {}
|
h = resp.headers or {}
|
||||||
rid = h.get("x-request-id") or h.get("request-id") or ""
|
rid = h.get("x-request-id") or h.get("request-id") or ""
|
||||||
|
|||||||
Reference in New Issue
Block a user