fix: preserve legacy plugin tool errors
This commit is contained in:
@@ -8,7 +8,7 @@ from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from nanobot.agent.tools.base import Tool
|
||||
from nanobot.agent.tools.base import Tool, ToolResult
|
||||
from nanobot.agent.tools.registry import ToolRegistry
|
||||
|
||||
_SKIP_MODULES = frozenset({
|
||||
@@ -96,6 +96,8 @@ class ToolLoader:
|
||||
if not tool_cls.enabled(ctx):
|
||||
continue
|
||||
tool = tool_cls.create(ctx)
|
||||
if is_plugin_source:
|
||||
tool = _LegacyErrorPrefixTool(tool)
|
||||
if registry.has(tool.name):
|
||||
if is_plugin_source and tool.name in builtin_names:
|
||||
logger.warning(
|
||||
@@ -114,3 +116,67 @@ class ToolLoader:
|
||||
except Exception:
|
||||
logger.exception("Failed to register tool: %s", cls_label)
|
||||
return registered
|
||||
|
||||
|
||||
class _LegacyErrorPrefixTool(Tool):
|
||||
"""Compatibility wrapper for external tools using the old error-string contract."""
|
||||
|
||||
_plugin_discoverable = False
|
||||
|
||||
def __init__(self, wrapped: Tool) -> None:
|
||||
self._wrapped = wrapped
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return self._wrapped.name
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return self._wrapped.description
|
||||
|
||||
@property
|
||||
def parameters(self) -> dict[str, Any]:
|
||||
return self._wrapped.parameters
|
||||
|
||||
@property
|
||||
def read_only(self) -> bool:
|
||||
return self._wrapped.read_only
|
||||
|
||||
@property
|
||||
def exclusive(self) -> bool:
|
||||
return self._wrapped.exclusive
|
||||
|
||||
@property
|
||||
def concurrency_safe(self) -> bool:
|
||||
return self._wrapped.concurrency_safe
|
||||
|
||||
@property
|
||||
def config_key(self) -> str:
|
||||
return getattr(self._wrapped, "config_key", "")
|
||||
|
||||
def set_context(self, ctx: Any) -> None:
|
||||
set_context = getattr(self._wrapped, "set_context", None)
|
||||
if callable(set_context):
|
||||
set_context(ctx)
|
||||
|
||||
def cast_params(self, params: dict[str, Any]) -> dict[str, Any]:
|
||||
return self._wrapped.cast_params(params)
|
||||
|
||||
def validate_params(self, params: dict[str, Any]) -> list[str]:
|
||||
return self._wrapped.validate_params(params)
|
||||
|
||||
def to_schema(self) -> dict[str, Any]:
|
||||
return self._wrapped.to_schema()
|
||||
|
||||
async def execute(self, **kwargs: Any) -> Any:
|
||||
result = await self._wrapped.execute(**kwargs)
|
||||
if (
|
||||
isinstance(result, str)
|
||||
and not isinstance(result, ToolResult)
|
||||
and result.startswith("Error:")
|
||||
):
|
||||
return ToolResult.error(result)
|
||||
return result
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
return getattr(self._wrapped, name)
|
||||
|
||||
@@ -445,9 +445,9 @@ class WebSearchTool(Tool):
|
||||
items = [{"title": answer_text or "Olostep answer", "url": "", "content": "\n".join(source_lines)}]
|
||||
return _format_results(query, items, n)
|
||||
except Olostep_BaseError as e:
|
||||
return f"Olostep search error: {type(e).__name__}: {e}"
|
||||
return ToolResult.error(f"Error: Olostep search error: {type(e).__name__}: {e}")
|
||||
except Exception as e:
|
||||
return f"Olostep search error: {type(e).__name__}: {e}"
|
||||
return ToolResult.error(f"Error: Olostep search error: {type(e).__name__}: {e}")
|
||||
|
||||
async def _search_brave(self, query: str, n: int) -> str:
|
||||
api_key = self.config.api_key or os.environ.get("BRAVE_API_KEY", "")
|
||||
|
||||
Reference in New Issue
Block a user