Files
inquiry_robot/inquiry-agent/agent/llm/mode_attachment_text.py
T

107 lines
3.1 KiB
Python

"""
千问:整理 Excel/PDF 抽出的原文。
本文件职责:把抽文本结果交给 qwen-plus,只整理看得见的字,不填询价字段。
属于 llm 包。单测注入 chat_fn。禁止算最终缺项、禁止发明港口/箱型。
"""
from __future__ import annotations
import logging
from typing import Any, Optional
from agent.llm.modes import LlmMode
logger = logging.getLogger(__name__)
MODE = LlmMode.ATTACHMENT_TEXT
ATTACH_SYSTEM = (
"下面是从 Excel 或 PDF 抽出来的原文。请整理成一段可读的询价口播:"
"只保留材料里已经出现的文字和数字,原样保留港口、机场三字码、箱型、重量。"
"看不清或没出现的不要猜,不要补询价缺项,不要发明港口、重量或日期。"
"材料完全没有询价信息时输出空。"
)
def mode_meta() -> dict[str, Any]:
return {
"mode": MODE.value,
"provider": "qwen",
"purpose": "attachment_text",
"implemented": True,
}
def _pack_text(text: str, *, stub: bool = False) -> dict[str, Any]:
body = (text or "").strip()
return {
"ok": True,
"stub": stub,
"mode": MODE.value,
"text": body,
"empty": not bool(body),
"error": "",
}
def invoke_shell(*, payload: dict[str, Any]) -> dict[str, Any]:
"""
无网/单测入口:优先 assistant_text;否则把 raw_text 当整理结果。
"""
data = dict(payload or {})
if "assistant_text" in data:
return _pack_text(str(data.get("assistant_text") or ""), stub=True)
if "raw_text" in data:
return _pack_text(str(data.get("raw_text") or ""), stub=True)
return {
"ok": False,
"stub": True,
"mode": MODE.value,
"text": "",
"empty": True,
"error": "attachment_text_shell_not_implemented",
"echo_keys": sorted(data.keys()),
}
def invoke_attachment_text(
*,
payload: dict[str, Any],
chat_fn: Optional[Any] = None,
allow_network: bool = False,
) -> dict[str, Any]:
"""
整理一份抽出原文。chat_fn 单测注入;无网走 invoke_shell。
"""
data = dict(payload or {})
raw = str(data.get("raw_text") or "")
if chat_fn is None and not allow_network:
return invoke_shell(payload=data)
if not raw.strip():
return _pack_text("", stub=chat_fn is None)
if chat_fn is None:
from agent.llm.http_client import LlmHttpClient
client = LlmHttpClient.from_settings()
chat_fn = client.chat
messages = [
{"role": "system", "content": ATTACH_SYSTEM},
{"role": "user", "content": raw.strip()},
]
result = chat_fn(mode=MODE, messages=messages)
if not getattr(result, "ok", False):
err = str(getattr(result, "error", "") or "attachment_text_failed")
logger.info("attachment_text 失败 err=%s", err)
return {
"ok": False,
"stub": False,
"mode": MODE.value,
"text": "",
"empty": True,
"error": err,
}
packed = _pack_text(str(getattr(result, "content", "") or ""))
packed["stub"] = False
return packed