45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
"""统一收尾能力不足、资源缺失和动作修正失败
|
||
|
||
这里只整理内部失败原因,面向用户的说明由回答节点交给模型总结,代码中不写死给用户的文案
|
||
"""
|
||
|
||
from app.processor.base import BaseNode
|
||
from app.processor.state import QueryState
|
||
|
||
|
||
def failure_notice(state: QueryState) -> str:
|
||
"""汇总上游记录的失败原因、最近一次修正分析和校验错误,作为交给模型的事实说明"""
|
||
facts = []
|
||
if reason := state.get("failure_reason"):
|
||
facts.append(reason)
|
||
plan = state.get("repair_plan")
|
||
if plan is not None and plan.reason not in facts:
|
||
facts.append(f"失败分析:{plan.reason}")
|
||
if errors := state.get("validation_errors"):
|
||
facts.append("校验错误:" + ";".join(error.message for error in errors))
|
||
facts.append(f"已自动修正 {state.get('retry_count', 0)} 次")
|
||
detail = "\n".join(facts) if facts else "没有记录具体原因"
|
||
return f"本次修改请求没有执行,内部原因如下:\n{detail}"
|
||
|
||
|
||
class FallbackNode(BaseNode):
|
||
name = "fallback_node"
|
||
|
||
def process(self, state: QueryState) -> QueryState:
|
||
# 浅拷贝状态
|
||
updated_state: QueryState = state.copy()
|
||
notice = failure_notice(state)
|
||
self.logger.warning(notice)
|
||
|
||
# 将任务标记为最终失败,由回答节点向用户说明原因
|
||
updated_state["status"] = "failed"
|
||
updated_state["failure_reason"] = notice
|
||
updated_state["notice"] = notice
|
||
# 显式标记校验未通过,防止残留动作被当作可执行结果
|
||
updated_state["validation_passed"] = False
|
||
# 清空旧模拟快照,避免失败结果中仍携带之前的成功快照
|
||
updated_state["simulated_screen"] = None
|
||
|
||
# 返回统一的失败状态,保留原动作和错误信息供排查
|
||
return updated_state
|