91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
"""
|
|
Tool Description Generator
|
|
|
|
Generates AI-friendly tool descriptions for LLM consumption.
|
|
"""
|
|
|
|
from typing import Dict, List, Any, Optional
|
|
|
|
|
|
def generate_tool_description(manifest: dict) -> str:
|
|
"""Generate AI-friendly tool description from manifest"""
|
|
lines = [
|
|
f"## {manifest.get('display_name', manifest.get('name', 'Unknown'))}",
|
|
f"{manifest.get('description', 'No description available')}",
|
|
"",
|
|
"### Available Commands:",
|
|
]
|
|
|
|
commands = manifest.get("commands", [])
|
|
if not commands:
|
|
return "\n".join(lines[:-2]) # Remove the "Available Commands" line
|
|
|
|
for cmd in commands:
|
|
lines.append(f"#### {cmd.get('name', 'unnamed')}")
|
|
lines.append(cmd.get("description", "No description"))
|
|
lines.append("")
|
|
|
|
if cmd.get("example"):
|
|
lines.append("**Example:**")
|
|
lines.append(f"```\n{cmd['example']}\n```")
|
|
lines.append("")
|
|
|
|
parameters = cmd.get("parameters", {})
|
|
if parameters:
|
|
lines.append("**Parameters:**")
|
|
props = parameters.get("properties", {})
|
|
for param_name, param_info in props.items():
|
|
param_type = param_info.get("type", "any")
|
|
param_desc = param_info.get("description", "")
|
|
lines.append(f"- `{param_name}` ({param_type}): {param_desc}")
|
|
lines.append("")
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
def generate_tools_for_llm(registry: Any) -> str:
|
|
"""Generate tool list for LLM from registry"""
|
|
import asyncio
|
|
|
|
async def _generate():
|
|
tools = await registry.list_enabled()
|
|
|
|
sections = ["## Available Tools\n"]
|
|
|
|
for tool in tools:
|
|
try:
|
|
manifest_path = f"tools/manifests/{tool.name}.yaml"
|
|
import yaml
|
|
from pathlib import Path
|
|
|
|
manifest_file = Path(__file__).parent / "manifests" / f"{tool.name}.yaml"
|
|
if manifest_file.exists():
|
|
with open(manifest_file, encoding="utf-8") as f:
|
|
manifest_data = yaml.safe_load(f)
|
|
sections.append(generate_tool_description(manifest_data))
|
|
else:
|
|
sections.append(f"## {tool.display_name}\n{tool.description}\n")
|
|
sections.append("\n---\n")
|
|
except Exception:
|
|
sections.append(f"## {tool.display_name}\n{tool.description}\n")
|
|
sections.append("\n---\n")
|
|
|
|
return "\n".join(sections)
|
|
|
|
return asyncio.get_event_loop().run_until_complete(_generate())
|
|
|
|
|
|
def generate_command_reference(manifest: dict) -> str:
|
|
"""Generate compact command reference for quick lookup"""
|
|
commands = manifest.get("commands", [])
|
|
lines = [f"### {manifest.get('name', 'tool')} Commands\n"]
|
|
|
|
for cmd in commands:
|
|
params = cmd.get("parameters", {}).get("required", [])
|
|
param_str = ", ".join(params) if params else ""
|
|
lines.append(
|
|
f"- `{cmd.get('name', 'cmd')}({param_str})`: {cmd.get('description', '')[:50]}..."
|
|
)
|
|
|
|
return "\n".join(lines)
|