fix:处理模型错误添加大量文本的bug
This commit is contained in:
@@ -51,5 +51,6 @@ class InputNode(BaseNode):
|
||||
updated_state["actions"] = None
|
||||
updated_state["clarification"] = None
|
||||
updated_state["answer"] = None
|
||||
updated_state["suggestions"] = None
|
||||
updated_state["status"] = "running"
|
||||
return updated_state
|
||||
|
||||
@@ -18,6 +18,9 @@ from app.processor.summary import data_file_summary
|
||||
|
||||
# 模型在一次回答里分几次输出文字(例如查询前后各说一段)时,段落之间空一行
|
||||
PARAGRAPH_BREAK = "\n\n"
|
||||
# 带数据的问答回答完后给的后续请求:意图判断会把"展示一下 9 月销售额"这类说法分到问答,
|
||||
# 用户其实想在大屏上看到;回答之后给一个按钮,点了按普通请求走大屏 agent,会话历史里有这次回答
|
||||
PUT_ON_SCREEN = "把上面的结果放到大屏上"
|
||||
|
||||
|
||||
class QANode(BaseNode):
|
||||
@@ -93,4 +96,6 @@ class QANode(BaseNode):
|
||||
|
||||
updated_state["answer"] = answer
|
||||
updated_state["status"] = "completed"
|
||||
if context.data_files:
|
||||
updated_state["suggestions"] = [PUT_ON_SCREEN]
|
||||
return updated_state
|
||||
|
||||
@@ -9,6 +9,7 @@ import json
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from app.actions.batch import mark_sample_data
|
||||
from app.agent.screen_agent import (
|
||||
AgentReply,
|
||||
finalize_reply,
|
||||
@@ -21,13 +22,19 @@ 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
|
||||
from app.schemas.component_resource import ComponentCatalog
|
||||
|
||||
# 评测按这句话识别"草稿因最后一次提交失败没有交付",单独核对草稿本身是否满足要求
|
||||
DRAFT_REJECTED = "修改没有通过校验,这次没有生效,可以换个说法再试"
|
||||
|
||||
|
||||
def reply_update(result: dict, *, limit_hit: bool = False) -> QueryState:
|
||||
"""把 agent 的运行结果转换成 QueryState 的更新"""
|
||||
def reply_update(
|
||||
result: dict, *, limit_hit: bool = False, catalog: ComponentCatalog | None = None
|
||||
) -> QueryState:
|
||||
"""把 agent 的运行结果转换成 QueryState 的更新
|
||||
|
||||
交付的新增组件按交付后的大屏定 sample_data:留着物料示例数据的也标为示例数据(mark_sample_data)
|
||||
"""
|
||||
reply: AgentReply | None = result.get("structured_response")
|
||||
if reply is None:
|
||||
# 收尾也没有给出合法的结论;按真实原因说明,不再一律说超出上限
|
||||
@@ -44,11 +51,10 @@ def reply_update(result: dict, *, limit_hit: bool = False) -> QueryState:
|
||||
if last_write_failed(result.get("messages", [])):
|
||||
return {"status": "failed", "answer": DRAFT_REJECTED}
|
||||
# 各次成功提交的动作按顺序拼接;clarify、unable 不交付,下次请求从原始大屏重新执行
|
||||
return {
|
||||
"status": "completed",
|
||||
"actions": result.get("actions") or [],
|
||||
"answer": reply.message,
|
||||
}
|
||||
actions = result.get("actions") or []
|
||||
if actions:
|
||||
actions = mark_sample_data(actions, result["working_screen"], catalog)
|
||||
return {"status": "completed", "actions": actions, "answer": reply.message}
|
||||
|
||||
|
||||
class ScreenAgentNode(BaseNode):
|
||||
@@ -91,5 +97,5 @@ class ScreenAgentNode(BaseNode):
|
||||
)
|
||||
reply = await finalize_reply(result, limit_hit=limit_hit)
|
||||
result = {**result, "structured_response": reply}
|
||||
updated_state.update(reply_update(result, limit_hit=limit_hit))
|
||||
updated_state.update(reply_update(result, limit_hit=limit_hit, catalog=catalog))
|
||||
return updated_state
|
||||
|
||||
@@ -28,6 +28,7 @@ class QueryState(TypedDict):
|
||||
ClarificationReply | None
|
||||
] # 待合并的用户回答或取消指令
|
||||
answer: NotRequired[str | None] # 问答回答,或 agent 给用户的说明
|
||||
suggestions: NotRequired[list[str] | None] # 可以一键发送的后续请求,前端显示成按钮
|
||||
status: NotRequired[
|
||||
Literal["running", "waiting_for_input", "completed", "cancelled", "failed"]
|
||||
] # 后端处理、等待补充、处理完成、用户取消或失败,完成不代表前端已执行
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
只描述本次请求;会话历史由各使用方另行传入,见 history.py
|
||||
"""
|
||||
|
||||
from app.resources.component import get_catalog_cache
|
||||
from app.resources.material_fields import identifying_texts
|
||||
from app.schemas.base import JsonObject
|
||||
from app.schemas.data_file import RequestDataFile
|
||||
from app.schemas.input_context import InputContext
|
||||
@@ -14,25 +16,16 @@ SUMMARY_COLUMNS = 30
|
||||
def request_summary(context: InputContext) -> JsonObject:
|
||||
"""用户输入、澄清记录、编辑上下文、附件、数据文件和大屏摘要"""
|
||||
nodes: list[JsonObject] = []
|
||||
catalog = get_catalog_cache()
|
||||
for node in context.screen.nodes:
|
||||
# 画面上的标题帮助判断用户指的是哪个组件:图表在 option.title,指标卡在 props.title;
|
||||
# 格式不符时按无标题处理
|
||||
option = node.props.get("option")
|
||||
title = option.get("title") if isinstance(option, dict) else None
|
||||
titles = title if isinstance(title, list) else [title]
|
||||
texts = [
|
||||
item["text"]
|
||||
for item in titles
|
||||
if isinstance(item, dict) and isinstance(item.get("text"), str)
|
||||
]
|
||||
if isinstance(node.props.get("title"), str) and node.props["title"]:
|
||||
texts.append(node.props["title"])
|
||||
nodes.append(
|
||||
{
|
||||
"id": node.id,
|
||||
"type": node.type,
|
||||
"name": node.name,
|
||||
"titles": texts,
|
||||
# 画面上的名字或内容帮助判断用户指的是哪个组件;取哪个字段由字段定义的 identifies 决定,
|
||||
# 新物料不用在这里加判断。物料目录没载入时为空
|
||||
"titles": identifying_texts(catalog, node.model_dump(mode="json")),
|
||||
"layout": node.layout.model_dump(mode="json", exclude_unset=True),
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user