mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-21 20:06:06 +00:00
refactor(tools): unify tool-detail normalization in ToolManager
Drop the PluginToolLoader.get_tool() override that returned a raw
ComponentManifest, so every loader's get_tool() now returns a uniform
resource_tool.LLMTool (PluginToolLoader.get_tools() already did this
conversion). This removes the only source of tool-shape heterogeneity.
- ToolManager.get_tool_schema(): drop the ComponentManifest-vs-LLMTool branch
- ToolManager.get_tool_detail(): new host-level shape {name, description,
human_desc, parameters}
- handler.py GET_TOOL_DETAIL: call tool_mgr.get_tool_detail(); delete the
handler-local _build_tool_detail + _i18n_to_dict/_i18n_to_text adapters and
the litellm TODO
- ToolLookupResult is now just LLMTool
The dropped label/spec fields were not consumed by any runner (local-agent
build_llm_tool and external harnesses use only name/description/parameters).
This commit is contained in:
@@ -86,66 +86,6 @@ def _pop_query_llm_usage(query: Any) -> dict[str, Any] | None:
|
||||
return None
|
||||
|
||||
|
||||
def _i18n_to_dict(value: Any) -> dict[str, Any]:
|
||||
"""Convert SDK i18n values to plain dictionaries."""
|
||||
if value is None:
|
||||
return {}
|
||||
if isinstance(value, dict):
|
||||
return value
|
||||
if hasattr(value, 'to_dict'):
|
||||
return value.to_dict()
|
||||
if hasattr(value, 'model_dump'):
|
||||
return value.model_dump()
|
||||
return {'en_US': str(value)}
|
||||
|
||||
|
||||
def _i18n_to_text(value: Any) -> str:
|
||||
"""Return a stable human-readable text from SDK i18n values."""
|
||||
data = _i18n_to_dict(value)
|
||||
for key in ('en_US', 'zh_Hans', 'zh_Hant'):
|
||||
text = data.get(key)
|
||||
if text:
|
||||
return str(text)
|
||||
for text in data.values():
|
||||
if text:
|
||||
return str(text)
|
||||
return ''
|
||||
|
||||
|
||||
def _build_tool_detail(tool: Any, requested_tool_name: str | None = None) -> dict[str, Any]:
|
||||
"""Normalize LLMTool and plugin ComponentManifest objects for tool detail APIs."""
|
||||
# TODO(litellm): This handler-local adapter is temporary. Once LiteLLM-backed
|
||||
# tool schema normalization owns tool detail generation, simplify GET_TOOL_DETAIL
|
||||
# and make ToolManager return one host-level tool detail shape.
|
||||
if hasattr(tool, 'metadata') and hasattr(tool, 'spec'):
|
||||
metadata = tool.metadata
|
||||
spec = tool.spec or {}
|
||||
description = spec.get('llm_prompt') or _i18n_to_text(getattr(metadata, 'description', None))
|
||||
parameters = spec.get('parameters') or {}
|
||||
|
||||
return {
|
||||
'name': requested_tool_name or getattr(metadata, 'name', ''),
|
||||
'label': _i18n_to_dict(getattr(metadata, 'label', None)),
|
||||
'description': description,
|
||||
'human_desc': description,
|
||||
'parameters': parameters,
|
||||
'spec': spec,
|
||||
}
|
||||
|
||||
name = getattr(tool, 'name', requested_tool_name or '')
|
||||
description = getattr(tool, 'description', None) or getattr(tool, 'human_desc', '') or ''
|
||||
parameters = getattr(tool, 'parameters', None) or {}
|
||||
|
||||
return {
|
||||
'name': name,
|
||||
'label': {},
|
||||
'description': description,
|
||||
'human_desc': getattr(tool, 'human_desc', description) or description,
|
||||
'parameters': parameters,
|
||||
'spec': {'parameters': parameters},
|
||||
}
|
||||
|
||||
|
||||
def _normalize_uuid_list(values: Any) -> list[str]:
|
||||
"""Normalize a user/config supplied UUID list while preserving order."""
|
||||
if not isinstance(values, list):
|
||||
@@ -831,14 +771,12 @@ class RuntimeConnectionHandler(handler.Handler):
|
||||
return error
|
||||
|
||||
try:
|
||||
tool = await self.ap.tool_mgr.get_tool_by_name(tool_name)
|
||||
if tool is None:
|
||||
tool_detail = await self.ap.tool_mgr.get_tool_detail(tool_name)
|
||||
if tool_detail is None:
|
||||
return handler.ActionResponse.error(
|
||||
message=f'Tool {tool_name} not found',
|
||||
)
|
||||
|
||||
tool_detail = _build_tool_detail(tool, requested_tool_name=tool_name)
|
||||
|
||||
return handler.ActionResponse.success(data={'tool': tool_detail})
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
Reference in New Issue
Block a user