fix(toolkit): 修复搜索工具参数与工具信息展示问题
1. 为web_search和tavily_search添加runtime默认值None 2. 重构工具参数提取逻辑,跳过runtime参数并适配pydantic v2字段 3. 调整工具包导入顺序与格式化 4. 为外部工具调用添加上下文透传日志字段
This commit is contained in:
parent
56022a9199
commit
44dcb028b9
@ -1,12 +1,14 @@
|
||||
# buildin 工具包
|
||||
from .install_skill import install_skill
|
||||
from .tools import ask_user_question, present_artifacts
|
||||
# Web 搜索与抓取工具(不依赖 LITE 模式,始终注册)
|
||||
from . import search # noqa: F401
|
||||
from . import crawl # noqa: F401
|
||||
from . import (
|
||||
crawl, # noqa: F401
|
||||
search, # noqa: F401
|
||||
)
|
||||
from .install_skill import install_skill
|
||||
|
||||
# 会话通信工具仅在非 LITE 模式下注册
|
||||
from .session_tools import _LITE_MODE as _session_lite_mode
|
||||
from .tools import ask_user_question, present_artifacts
|
||||
|
||||
if not _session_lite_mode:
|
||||
from .session_tools import get_agent_progress, get_session_history, list_sessions, send_to_session
|
||||
@ -18,9 +20,11 @@ __all__ = [
|
||||
]
|
||||
|
||||
if not _session_lite_mode:
|
||||
__all__.extend([
|
||||
"get_agent_progress",
|
||||
"get_session_history",
|
||||
"list_sessions",
|
||||
"send_to_session",
|
||||
])
|
||||
__all__.extend(
|
||||
[
|
||||
"get_agent_progress",
|
||||
"get_session_history",
|
||||
"list_sessions",
|
||||
"send_to_session",
|
||||
]
|
||||
)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
"""web_search 与 tavily_search 工具注册。"""
|
||||
|
||||
import json
|
||||
|
||||
from langgraph.prebuilt.tool_node import ToolRuntime
|
||||
@ -9,7 +10,6 @@ from .chain import build_provider_chain
|
||||
from .models import SearchResult
|
||||
from .rate_limiter import rate_limiter
|
||||
|
||||
|
||||
WEB_SEARCH_DESCRIPTION = """
|
||||
搜索互联网获取实时信息。
|
||||
|
||||
@ -104,7 +104,7 @@ async def _execute_web_search(query: str, max_results: int, runtime: ToolRuntime
|
||||
async def web_search(
|
||||
query: str,
|
||||
max_results: int = 5,
|
||||
runtime: ToolRuntime,
|
||||
runtime: ToolRuntime = None,
|
||||
) -> str:
|
||||
"""搜索互联网,返回结构化结果列表。"""
|
||||
return await _execute_web_search(query, max_results, runtime)
|
||||
@ -119,7 +119,7 @@ async def web_search(
|
||||
async def tavily_search(
|
||||
query: str,
|
||||
max_results: int = 5,
|
||||
runtime: ToolRuntime,
|
||||
runtime: ToolRuntime = None,
|
||||
) -> str:
|
||||
"""Tavily 网页搜索(兼容入口,内部委托 _execute_web_search)。"""
|
||||
return await _execute_web_search(query, max_results, runtime)
|
||||
|
||||
@ -19,16 +19,35 @@ def _extract_tool_info(tool_obj) -> dict:
|
||||
|
||||
if hasattr(tool_obj, "args_schema") and tool_obj.args_schema:
|
||||
schema = tool_obj.args_schema
|
||||
if hasattr(schema, "schema"):
|
||||
schema = schema.schema()
|
||||
for arg_name, arg_info in schema.get("properties", {}).items():
|
||||
info["args"].append(
|
||||
{
|
||||
"name": arg_name,
|
||||
"type": arg_info.get("type", ""),
|
||||
"description": arg_info.get("description", ""),
|
||||
}
|
||||
)
|
||||
# 优先从 pydantic v2 ``model_fields`` 提取参数信息,避免对
|
||||
# ``ToolRuntime`` 等含 callable 字段(如 ``stream_writer``)的注入式
|
||||
# 参数生成完整 JSON schema 时抛出 ``PydanticInvalidForJsonSchema``。
|
||||
# ``runtime`` 字段由 langgraph 自动注入,不属于用户输入参数,跳过展示。
|
||||
model_fields = getattr(schema, "model_fields", None)
|
||||
if model_fields:
|
||||
for arg_name, field_info in model_fields.items():
|
||||
if arg_name == "runtime":
|
||||
continue
|
||||
annotation = field_info.annotation
|
||||
info["args"].append(
|
||||
{
|
||||
"name": arg_name,
|
||||
"type": getattr(annotation, "__name__", str(annotation)),
|
||||
"description": field_info.description or "",
|
||||
}
|
||||
)
|
||||
elif hasattr(schema, "schema"):
|
||||
schema_dict = schema.schema()
|
||||
for arg_name, arg_info in schema_dict.get("properties", {}).items():
|
||||
if arg_name == "runtime":
|
||||
continue
|
||||
info["args"].append(
|
||||
{
|
||||
"name": arg_name,
|
||||
"type": arg_info.get("type", ""),
|
||||
"description": arg_info.get("description", ""),
|
||||
}
|
||||
)
|
||||
return info
|
||||
|
||||
|
||||
@ -146,15 +165,21 @@ async def resolve_configured_runtime_tools(context) -> list[Any]:
|
||||
if external_tool_names:
|
||||
async with pg_manager.get_async_session_context() as db:
|
||||
use_cases = create_use_cases_from_db(db)
|
||||
# 透传 agent 上下文(uid 作为 caller_id,run_id 作为 correlation_id),
|
||||
# 使 agent 调用外部工具时写入完整的可观测性字段
|
||||
thread_id = getattr(context, "thread_id", None)
|
||||
output = await use_cases.tool_service.build_runtime_tools(
|
||||
BuildRuntimeToolsInput(slugs=external_tool_names),
|
||||
BuildRuntimeToolsInput(
|
||||
slugs=external_tool_names,
|
||||
caller_id=getattr(context, "uid", None),
|
||||
correlation_id=getattr(context, "run_id", None),
|
||||
tags={"thread_id": thread_id} if thread_id else {},
|
||||
),
|
||||
)
|
||||
selected_tools.extend(output.items)
|
||||
selected_tool_names.update(tool.name for tool in output.items)
|
||||
# 构建失败的工具 slug 必须显式记录,避免用户配置的工具被静默丢失
|
||||
if output.failed_slugs:
|
||||
logger.warning(
|
||||
f"Failed to build external runtime tools, skipped: {output.failed_slugs}"
|
||||
)
|
||||
logger.warning(f"Failed to build external runtime tools, skipped: {output.failed_slugs}")
|
||||
|
||||
return selected_tools
|
||||
|
||||
Loading…
Reference in New Issue
Block a user