tools.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. """历史固定服务的兼容工具,当前 Agent 默认注册 exploration_tools 中的自主工具。"""
  2. from typing import Any
  3. from langchain.tools import ToolRuntime
  4. from extensions import define_tool
  5. from extensions.main_fan.schemas import MainFanResult
  6. @define_tool(group="主通风机", label="检查主通风机材料目录")
  7. def inspect_main_fan_materials(materials: list[dict[str, Any]], mine_code: str = "",
  8. mine_name: str = "", fan_id: str = "") -> dict:
  9. """仅检查材料目录。实际初步筛查使用 analyze_main_fan,不能以目录检查代替业务研判。"""
  10. supplied = bool(materials)
  11. return MainFanResult(
  12. status="needs_materials",
  13. mine_code=mine_code, mine_name=mine_name,
  14. check_object=f"矿井主通风机 {fan_id}".strip(),
  15. result_title="主通风机材料检查",
  16. result=("已接收材料目录,需要通过 analyze_main_fan 提取、核验与初步筛查。仅目录检查无法形成正式研判结论。"
  17. if supplied else "尚未提供主通风机资料,无法形成正式研判结论。"),
  18. check_process="仅检查材料目录是否为空,未核验文件内容或运行参数。",
  19. missing_materials=[] if supplied else ["主通风机相关报告或运行资料"],
  20. ).model_dump(mode="json")
  21. @define_tool(group="主通风机", label="生成主通风机与备用风机一致性报告")
  22. async def analyze_main_fan(data: dict[str, Any] | str, runtime: ToolRuntime) -> dict:
  23. """执行主通风机与备用风机一致性七阶段流程,返回不可改写的结构化原件。
  24. 简短请求的data只需原目标文字或{"target":"众源煤业1号主通风机"};服务端解析身份、网关取数与识别策略。
  25. 完整data仍支持MainFanInput:mine_code/mine_name,fan_id/fan_name,devices/points/reports,
  26. materials 为当前会话 /workspace/ 文件路径;use_gateway=true 从已配置网关取数。
  27. 命名关联只产生候选,confirmed_bindings 仅录入用户实际提供的人工核验,禁止虚构。
  28. 不要猜测身份或向用户索要已配置的编码;未唯一匹配时返回待补充的业务对象信息。
  29. completed 表示筛查过程完成,不表示工程合格。
  30. """
  31. from extensions.main_fan.service import analyze
  32. from extensions.main_fan.targets import resolve_request, TargetResolutionError
  33. identity = runtime.config.get("configurable", {})
  34. if not identity.get("workspace_user") or not identity.get("workspace_session"):
  35. raise ValueError("业务工具缺少服务端会话身份")
  36. # 队列任务以服务端校验的输入为准,模型不能添加虚构测点或人工确认。
  37. trusted = identity.get("business_task_input") if identity.get("business_agent") == "main_fan" else None
  38. try:
  39. resolved = resolve_request(trusted if trusted is not None else data)
  40. except TargetResolutionError as exc:
  41. if trusted is not None:
  42. raise
  43. return MainFanResult(status="needs_materials", check_object="矿井主通风机",
  44. result_title="请明确研判对象", result=str(exc), check_process="目标身份解析未完成,尚未获取资料或进行研判。",
  45. missing_materials=[str(exc)]).model_dump(mode="json")
  46. result = await analyze(resolved,
  47. identity["workspace_user"], identity["workspace_session"], job_id=identity.get("business_task_id"),
  48. document_audit_dir=identity.get("document_audit_dir"))
  49. if (result.get("analysis") or {}).get("document_audits") or result.get('workflow_id'):
  50. # 大报告无需让编排模型重写全部数字和证据,结果验证器从数据库恢复原件。
  51. result = {**result, "analysis": None, "assessment":None, "clues": []}
  52. result["platform_payload"] = None
  53. # 只交给编排模型一份接收凭据,最终正文从数据库原件恢复。
  54. result["result"] = "整体研判报告已生成,最终正文由服务端恢复。"
  55. result["missing_materials"] = []
  56. return result
  57. def _component(workflow_id, runtime, name):
  58. from db.main_fan_store import workflow
  59. from extensions.main_fan.pipeline import component
  60. identity=runtime.config.get('configurable',{})
  61. if not identity.get('workspace_user') or not identity.get('workspace_session'):
  62. raise ValueError('阶段工具缺少服务端会话身份')
  63. return component(workflow(workflow_id,identity['workspace_user'],identity['workspace_session']),name)
  64. @define_tool(group="主通风机阶段",label="读取已解析的风机证据文档")
  65. def parse_fan_evidence_documents(workflow_id: str, runtime: ToolRuntime) -> dict:
  66. """读取本会话已执行流程的文档解析结果;新任务先调用analyze_main_fan实际取数识别。"""
  67. return _component(workflow_id,runtime,'parse_fan_evidence_documents')
  68. @define_tool(group="主通风机阶段",label="读取风机运行时序与切换记录")
  69. def query_fan_operating_data(workflow_id: str, runtime: ToolRuntime) -> dict:
  70. """读取已接入的原始运行时序、完整风机状态和切换记录;不生成默认数据。"""
  71. return _component(workflow_id,runtime,'query_fan_operating_data')
  72. @define_tool(group="主通风机阶段",label="读取双机身份和参数标准化结果")
  73. def normalize_and_validate_fan_data(workflow_id: str, runtime: ToolRuntime) -> dict:
  74. """读取同会话流程的双机身份、单位和基础参数比较结果。"""
  75. return _component(workflow_id,runtime,'normalize_and_validate_fan_data')
  76. @define_tool(group="主通风机阶段",label="读取两台风机性能数据差异")
  77. def analyze_fan_performance_curve(workflow_id: str, runtime: ToolRuntime) -> dict:
  78. """读取受控插值及曲线差异指标,区分同角度同频率可比与仅同频数据比较。"""
  79. return _component(workflow_id,runtime,'analyze_fan_performance_curve')
  80. @define_tool(group="主通风机阶段",label="读取切换前后稳定工况分析")
  81. def analyze_fan_switch_event(workflow_id: str, runtime: ToolRuntime) -> dict:
  82. """读取实际切换事件、前后稳定窗口、变化指标和恢复时间。"""
  83. return _component(workflow_id,runtime,'analyze_fan_switch_event')
  84. @define_tool(group="主通风机阶段",label="读取适用规则和阈值版本")
  85. def match_fan_rules_and_knowledge(workflow_id: str, runtime: ToolRuntime) -> dict:
  86. """读取本次已冻结的规则、阈值版本与各判定项;不以模型记忆改变阈值。"""
  87. return _component(workflow_id,runtime,'match_fan_rules_and_knowledge')
  88. @define_tool(group="主通风机阶段",label="读取主备风机综合一致性结果")
  89. def assess_fan_equivalent_capability(workflow_id: str, runtime: ToolRuntime) -> dict:
  90. """读取固定规则形成的综合结果,未评估项目不能自动视为通过。"""
  91. return _component(workflow_id,runtime,'assess_fan_equivalent_capability')
  92. @define_tool(group="主通风机阶段",label="读取结论与原始证据对应关系")
  93. def trace_fan_evidence_and_review(workflow_id: str, runtime: ToolRuntime) -> dict:
  94. """读取结果、参数、公式和原文件页码的证据索引及版本信息。"""
  95. return _component(workflow_id,runtime,'trace_fan_evidence_and_review')
  96. @define_tool(group="主通风机阶段",label="读取整体主备风机一致性报告")
  97. def render_fan_assessment_report(workflow_id: str, runtime: ToolRuntime) -> dict:
  98. """读取已生成的整体报告,正文仅包括实际参与比较的项目。"""
  99. return _component(workflow_id,runtime,'render_fan_assessment_report')
  100. @define_tool(group="主通风机",label="从指定阶段重跑主备风机研判")
  101. async def resume_main_fan_assessment(workflow_id: str, start_stage: int, runtime: ToolRuntime) -> dict:
  102. """重跑1~7中的指定阶段及下游阶段。原文件未变化时复用本次实际识别的结构化事实,不再次OCR。"""
  103. from extensions.main_fan.service import resume_assessment
  104. identity=runtime.config.get('configurable',{})
  105. if not identity.get('workspace_user') or not identity.get('workspace_session'):
  106. raise ValueError('阶段工具缺少服务端会话身份')
  107. result=await resume_assessment(workflow_id,start_stage,identity['workspace_user'],identity['workspace_session'],job_id=identity.get('business_task_id'))
  108. return {**result,'result':'整体报告已按指定阶段重新生成,正文由服务端恢复。','analysis':None,'assessment':None,'clues':[],'platform_payload':None}