Source code for tools.list_all_tools

"""List documentation for all registered tools in the tool registry."""

from __future__ import annotations

import json
import logging
from typing import Optional

logger = logging.getLogger(__name__)

TOOL_NAME = "list_all_tools"
TOOL_DESCRIPTION = (
    "List documentation for ALL tools registered in the registry, "
    "including names, descriptions, and parameters. "
    "Optionally filter by keyword. If a channel ID is provided, "
    "the listing is also uploaded to that channel as a JSON file."
)
TOOL_PARAMETERS = {
    "type": "object",
    "properties": {
        "search_keyword": {
            "type": "string",
            "description": "Optional keyword to search tool names and descriptions.",
        },
        "include_parameters": {
            "type": "boolean",
            "description": "Include parameter details (default true).",
        },
        "channel": {
            "type": "string",
            "description": (
                "Optional channel ID. When provided, the tools listing "
                "is uploaded to this channel as a JSON file in addition "
                "to being returned."
            ),
        },
    },
}


[docs] async def run( search_keyword: Optional[str] = None, include_parameters: bool = True, channel: Optional[str] = None, ctx=None, **_kwargs, ) -> str: """Execute this tool and return the result. Args: search_keyword (Optional[str]): The search keyword value. include_parameters (bool): The include parameters value. channel (Optional[str]): Channel ID to upload the listing to. ctx: Tool execution context providing access to bot internals. Returns: str: Result string. """ try: registry = getattr(ctx, "tool_registry", None) if ctx else None if registry is None: return json.dumps({ "success": False, "error": "Tool registry not available via ctx", }) all_tools = registry.list_tools() if search_keyword: kw = search_keyword.lower() all_tools = [ t for t in all_tools if kw in t.name.lower() or (t.description and kw in t.description.lower()) ] tools_docs = [] for tool in sorted(all_tools, key=lambda t: t.name): doc: dict = { "name": tool.name, "description": tool.description or "No description available", } if include_parameters and tool.parameters: doc["parameters"] = { "properties": tool.parameters.get("properties", {}), "required": tool.parameters.get("required", []), } tools_docs.append(doc) result = { "success": True, "tool_count": len(tools_docs), "filter_applied": search_keyword or None, "tools": tools_docs, } # -- Upload to channel if requested -- if channel: adapter = getattr(ctx, "adapter", None) if ctx else None if adapter is None: result["channel_upload"] = "skipped — no platform adapter available" else: try: result_json = json.dumps(result, indent=2).encode("utf-8") await adapter.send_file( channel, result_json, "tools_list.json", "application/json", ) result["channel_upload"] = f"uploaded to {channel}" except Exception as upload_err: logger.warning( "Failed to upload tools list to channel %s: %s", channel, upload_err, ) result["channel_upload"] = f"failed — {upload_err}" return json.dumps(result, indent=2) except Exception as e: logger.error("Error listing tools: %s", e) return json.dumps({"success": False, "error": f"Failed to list tools: {e}"})