|
|
@@ -106,8 +106,9 @@ class RunConfig:
|
|
|
tools: Optional[List[str]] = None # None = 全部已注册工具
|
|
|
side_branch_max_turns: int = 5 # 侧分支最大轮次(压缩/反思)
|
|
|
|
|
|
- # --- 强制侧分支(用于 API 手动触发)---
|
|
|
- force_side_branch: Optional[Literal["compression", "reflection"]] = None
|
|
|
+ # --- 强制侧分支(用于 API 手动触发或自动压缩流程)---
|
|
|
+ # 使用列表作为侧分支队列,每次完成一个侧分支后 pop(0) 取下一个
|
|
|
+ force_side_branch: Optional[List[Literal["compression", "reflection"]]] = None
|
|
|
|
|
|
# --- 框架层参数 ---
|
|
|
agent_type: str = "default"
|
|
|
@@ -781,8 +782,9 @@ class AgentRunner:
|
|
|
return history, head_seq, sequence, False
|
|
|
|
|
|
# 知识提取:在任何压缩发生前,用完整 history 做反思(进入反思侧分支)
|
|
|
- if config.knowledge.enable_extraction:
|
|
|
- # 返回标志,让主循环进入反思侧分支
|
|
|
+ if config.knowledge.enable_extraction and not config.force_side_branch:
|
|
|
+ # 设置侧分支队列:先反思,再压缩
|
|
|
+ config.force_side_branch = ["reflection", "compression"]
|
|
|
return history, head_seq, sequence, True
|
|
|
|
|
|
# Level 1 压缩:GoalTree 过滤
|
|
|
@@ -824,7 +826,10 @@ class AgentRunner:
|
|
|
"Level 1 后仍超阈值 (消息数=%d/%d, token=%d/%d),需要进入压缩侧分支",
|
|
|
msg_count_after, compression_config.max_messages, token_count_after, max_tokens,
|
|
|
)
|
|
|
- # 返回标志,让主循环进入压缩侧分支
|
|
|
+ # 如果还没有设置侧分支(说明没有启用知识提取),直接进入压缩
|
|
|
+ if not config.force_side_branch:
|
|
|
+ config.force_side_branch = ["compression"]
|
|
|
+ # 返回标志,让主循环进入侧分支
|
|
|
return history, head_seq, sequence, True
|
|
|
|
|
|
# 压缩完成后,输出最终发给模型的消息列表
|
|
|
@@ -1011,12 +1016,12 @@ class AgentRunner:
|
|
|
|
|
|
# 进入侧分支
|
|
|
if needs_enter_side_branch and not side_branch_ctx:
|
|
|
- # 判断侧分支类型
|
|
|
- if config.force_side_branch:
|
|
|
- # API 强制触发
|
|
|
- branch_type = config.force_side_branch
|
|
|
+ # 从队列中取出第一个侧分支类型
|
|
|
+ if config.force_side_branch and isinstance(config.force_side_branch, list) and len(config.force_side_branch) > 0:
|
|
|
+ branch_type = config.force_side_branch.pop(0)
|
|
|
+ logger.info(f"从队列取出侧分支: {branch_type}, 剩余队列: {config.force_side_branch}")
|
|
|
elif config.knowledge.enable_extraction:
|
|
|
- # 自动触发:反思
|
|
|
+ # 兼容旧的单值模式(如果 force_side_branch 是字符串)
|
|
|
branch_type = "reflection"
|
|
|
else:
|
|
|
# 自动触发:压缩
|
|
|
@@ -1240,6 +1245,12 @@ class AgentRunner:
|
|
|
|
|
|
# 清除侧分支状态
|
|
|
trace.context.pop("active_side_branch", None)
|
|
|
+
|
|
|
+ # 队列中如果还有侧分支,保持 force_side_branch;否则清空
|
|
|
+ if not config.force_side_branch or len(config.force_side_branch) == 0:
|
|
|
+ config.force_side_branch = None
|
|
|
+ logger.info("反思超时,队列为空")
|
|
|
+
|
|
|
if self.trace_store:
|
|
|
await self.trace_store.update_trace(
|
|
|
trace_id, context=trace.context
|
|
|
@@ -1321,6 +1332,9 @@ class AgentRunner:
|
|
|
|
|
|
logger.info(f"压缩侧分支完成,history 长度: {len(history)}")
|
|
|
|
|
|
+ # 清除侧分支队列
|
|
|
+ config.force_side_branch = None
|
|
|
+
|
|
|
elif side_branch_ctx.type == "reflection":
|
|
|
# 反思侧分支:直接恢复主路径
|
|
|
logger.info("反思侧分支完成")
|
|
|
@@ -1332,6 +1346,11 @@ class AgentRunner:
|
|
|
history = [m.to_llm_dict() for m in main_path_messages]
|
|
|
head_seq = side_branch_ctx.start_head_seq
|
|
|
|
|
|
+ # 队列中如果还有侧分支,保持 force_side_branch;否则清空
|
|
|
+ if not config.force_side_branch or len(config.force_side_branch) == 0:
|
|
|
+ config.force_side_branch = None
|
|
|
+ logger.info("反思完成,队列为空")
|
|
|
+
|
|
|
# 清除侧分支状态
|
|
|
trace.context.pop("active_side_branch", None)
|
|
|
if self.trace_store:
|
|
|
@@ -1341,8 +1360,8 @@ class AgentRunner:
|
|
|
head_sequence=head_seq,
|
|
|
)
|
|
|
|
|
|
- # 清除强制侧分支配置(避免影响后续续跑)
|
|
|
- config.force_side_branch = None
|
|
|
+ # 注意:不在这里清除 force_side_branch,因为反思侧分支可能已经设置了下一个侧分支
|
|
|
+ # force_side_branch 的清除由各个分支类型自己处理
|
|
|
|
|
|
side_branch_ctx = None
|
|
|
continue
|