82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
"""调用 screen agent,按它的回复和最后一次提交的结果写回状态
|
|
|
|
kind 由模型决定;代码只在"回复 done 但最后一次提交失败"时不采纳,因为此时没有能交付的动作
|
|
"""
|
|
|
|
import json
|
|
|
|
from langchain_core.messages import HumanMessage
|
|
|
|
from app.agent.screen_agent import AgentReply, get_screen_agent
|
|
from app.agent.tools import ScreenAgentContext
|
|
from app.processor.base import BaseNode
|
|
from app.processor.history import history_messages
|
|
from app.processor.state import QueryState, run_data
|
|
from app.processor.summary import request_summary
|
|
from app.resources.component import get_catalog_cache
|
|
|
|
|
|
def reply_update(result: dict) -> QueryState:
|
|
"""把 agent 的运行结果转换成 QueryState 的更新"""
|
|
reply: AgentReply | None = result.get("structured_response")
|
|
if reply is None:
|
|
# 调用次数用尽等情况,agent 没有给出结论
|
|
return {
|
|
"status": "failed",
|
|
"answer": "处理步骤超出上限,这次没有完成,可以换个说法再试",
|
|
}
|
|
if reply.kind == "clarify":
|
|
return {"status": "waiting_for_input", "clarification": reply.clarification}
|
|
if reply.kind == "unable":
|
|
return {"status": "failed", "answer": reply.message}
|
|
if result.get("apply_error"):
|
|
return {
|
|
"status": "failed",
|
|
"answer": "修改没有通过校验,这次没有生效,可以换个说法再试",
|
|
}
|
|
return {
|
|
"status": "completed",
|
|
"actions": result.get("actions") or [],
|
|
"answer": reply.message,
|
|
}
|
|
|
|
|
|
class ScreenAgentNode(BaseNode):
|
|
name = "screen_agent_node"
|
|
|
|
async def process(self, state: QueryState) -> QueryState:
|
|
updated_state: QueryState = state.copy()
|
|
catalog = get_catalog_cache()
|
|
if catalog is None:
|
|
updated_state["status"] = "failed"
|
|
updated_state["answer"] = "物料目录未载入,暂时无法新建或修改大屏"
|
|
return updated_state
|
|
|
|
context = state["input_context"]
|
|
agent = await get_screen_agent(with_data=bool(context.data_files))
|
|
result = await agent.ainvoke(
|
|
{
|
|
# 会话历史作为此前的对话消息,本次请求是最后一条用户消息
|
|
"messages": [
|
|
*history_messages(context.history),
|
|
HumanMessage(
|
|
content=json.dumps(request_summary(context), ensure_ascii=False)
|
|
),
|
|
]
|
|
},
|
|
context=ScreenAgentContext(
|
|
screen=context.screen,
|
|
catalog=catalog,
|
|
data=run_data(),
|
|
),
|
|
)
|
|
if result.get("structured_response") is None:
|
|
last = result["messages"][-1]
|
|
self.logger.warning(
|
|
f"agent 没有给出结论: {last.type} {str(last.content)[:500]} "
|
|
f"tool_calls={getattr(last, 'tool_calls', None)} "
|
|
f"metadata={getattr(last, 'response_metadata', None)}"
|
|
)
|
|
updated_state.update(reply_update(result))
|
|
return updated_state
|