feat:完成数据文件上传解析及测试

This commit is contained in:
2026-10-09 06:42:28 -07:00
parent bb6a9405db
commit 4a6ec6d28c
11 changed files with 393 additions and 38 deletions
+21 -9
View File
@@ -1,5 +1,7 @@
"""数据文件的本地工具:describe_data 查看列概况,query_data 执行只读 SQL;问答和 screen agent 共用
apply_actions 里的 $query 也通过 DataContext.query 执行,见 tools.py
工具只能看到 DataContext 里的表,也就是当前用户在本会话里未过期的文件,查询引擎也只为这些表建视图
工具通过 runtime.context.data 读取 DataContext,用到它们的 agent 上下文都要有 data 字段;
上下文类型因 agent 而异,所以写 ToolRuntime[Any](不写类型参数时按 None 处理,序列化会告警)
@@ -14,7 +16,7 @@ from langchain_core.messages import ToolMessage
from pydantic import Field
from app.config import settings
from app.datafiles.query import QueryError, run_query
from app.datafiles.query import MAX_ROWS, QueryError, QueryResult, run_query
from app.schemas.data_file import RequestDataFile, RequestDataTable
# 列超过这么多时,不指定 columns 只返回列名和类型,避免一次塞进太多概况
@@ -39,6 +41,22 @@ class DataContext:
for table in file.tables
}
def query(self, sql: str, *, max_rows: int = MAX_ROWS) -> QueryResult:
"""执行一条只读 SQL;失败时抛 QueryError,原因可以直接返回给模型修正"""
paths = self.paths()
# 任务执行期间被删除或清理的文件跳过,不影响查询其他表
existing = {name: path for name, path in paths.items() if path.exists()}
try:
return run_query(
sql, existing, timeout=settings.data_query_timeout, max_rows=max_rows
)
except QueryError as error:
if gone := [name for name in paths if name not in existing]:
raise QueryError(
f"{error};{'、'.join(gone)} 的文件已删除或过期,不能再查询"
) from None
raise
def _error(runtime: ToolRuntime, message: str) -> ToolMessage:
# 返回给模型修正,不中断 agent
@@ -111,16 +129,10 @@ def query_data(sql: str, runtime: ToolRuntime[Any]) -> dict[str, Any] | ToolMess
回答和图表里的数字以查询结果为准,不要自己心算
"""
data: DataContext = runtime.context.data
paths = data.paths()
# 任务执行期间被删除或清理的文件跳过,不影响查询其他表
existing = {name: path for name, path in paths.items() if path.exists()}
try:
return run_query(sql, existing, timeout=settings.data_query_timeout).to_dict()
return data.query(sql).to_dict()
except QueryError as error:
message = str(error)
if gone := [name for name in paths if name not in existing]:
message += f";{'、'.join(gone)} 的文件已删除或过期,不能再查询"
return _error(runtime, message)
return _error(runtime, str(error))
DATA_TOOLS = [describe_data, query_data]