suna/TOOL_REFACTOR_COMPLETE.md

5.7 KiB

TOOL SYSTEM REFACTOR - COMPLETE

🎉 FULLY API-DRIVEN - NO STATIC DATA - NO BULLSHIT

All tool metadata is now auto-generated and fetched from API. Zero manual maintenance required.


📊 Stats

Files Deleted

  • backend/core/utils/tool_groups.py - 971 lines ELIMINATED
  • frontend/src/components/agents/tools/tool-groups-comprehensive.ts - 1,069 lines ELIMINATED

Total: 2,040 lines of duplicated legacy code DELETED 🔥

New Files (Clean, Auto-Generated)

  • backend/core/agentpress/tool.py - Enhanced with decorators (258 lines)
  • backend/core/utils/tool_discovery.py - Auto-discovery system (463 lines)
  • backend/core/tools_api.py - REST API endpoints (67 lines)
  • frontend/src/hooks/react-query/tools/use-tools-metadata.ts - React hook (61 lines)

Total: 849 lines of clean, maintainable code

Net Result

-1,191 lines while adding MORE functionality 📉


🚀 How It Works Now

Backend: Auto-Discovery

  1. Tool classes define their own metadata:
from core.agentpress.tool import Tool, tool_metadata, method_metadata, openapi_schema

@tool_metadata(
    display_name="File Operations",
    description="Create, read, edit, and manage files",
    icon="FolderOpen",
    color="bg-blue-100 dark:bg-blue-800/50"
)
class SandboxFilesTool(Tool):
    
    @method_metadata(
        display_name="Create File",
        description="Create new files with content"
    )
    @openapi_schema({...})
    def create_file(self, path: str, content: str):
        return self.success_response("File created!")
  1. Automatic discovery:

    • Scans backend/core/tools/ directory
    • Finds all Tool subclasses
    • Extracts metadata from decorators
    • Generates default metadata if decorators not present
  2. API endpoints:

    • GET /tools - All tools with full metadata
    • GET /tools/{tool_name} - Specific tool details

Frontend: API-Driven

  1. React Hook:
import { useToolsMetadata } from '@/hooks/react-query/tools/use-tools-metadata';

function MyComponent() {
  const { data, isLoading } = useToolsMetadata();
  
  if (data?.success) {
    const tools = data.tools;
    // All tool metadata available - auto-generated from backend
  }
}
  1. Component Integration:
    • GranularToolConfiguration now fetches from API
    • Shows loading state while fetching
    • All utility functions accept toolsData parameter
    • Zero static data

🎯 Key Features

1. Zero Manual Maintenance

  • Add a new tool → It's automatically discovered
  • No need to update any metadata files
  • No duplication between backend and frontend

2. Single Source of Truth

  • Tool classes ARE the metadata
  • Decorators make tools self-documenting
  • API serves as the bridge

3. Type Safety

  • Backend: Python type hints
  • Frontend: TypeScript interfaces
  • Auto-generated, always in sync

4. Backward Compatible

  • Works with existing tool configurations
  • tool_migration.py handles legacy configs
  • Naming remains agentpress_tools throughout

📝 Adding a New Tool

Old Way (MANUAL - SUCKED):

  1. Create tool class
  2. Update tool_groups.py (50+ lines)
  3. Update tool-groups-comprehensive.ts (50+ lines)
  4. Keep everything in sync manually
  5. Pray you didn't forget something

New Way (AUTOMATIC - AWESOME):

  1. Create tool class with decorators:
@tool_metadata(
    display_name="My New Tool",
    description="Does awesome stuff",
    icon="Sparkles"
)
class MyNewTool(Tool):
    @method_metadata(
        display_name="Do Thing",
        description="Does a thing"
    )
    @openapi_schema({...})
    def do_thing(self):
        return self.success_response("Done!")

THAT'S IT! The tool will automatically:

  • Be discovered by the system
  • Appear in API responses
  • Show up in the frontend
  • Have proper UI metadata
  • Work with all existing features

🔧 Updated Files

Backend

  • backend/core/agentpress/tool.py - Added decorators
  • backend/core/utils/tool_discovery.py - New auto-discovery
  • backend/core/tools_api.py - New API endpoints
  • backend/core/api.py - Registered new router
  • backend/core/run.py - Uses tool_discovery
  • backend/core/utils/tool_migration.py - Uses tool_discovery
  • backend/core/tools/agent_builder_tools/agent_config_tool.py - Uses tool_discovery

Frontend

  • frontend/src/hooks/react-query/tools/use-tools-metadata.ts - New hook
  • frontend/src/components/agents/tools/tool-groups.ts - Now API-driven wrapper
  • frontend/src/components/agents/tools/granular-tool-configuration.tsx - Fetches from API

🎊 Benefits Summary

Before After
2,040 lines of duplicated metadata Auto-generated from tool classes
Manual updates for every tool Zero manual maintenance
Static frontend files Dynamic API-driven
Out of sync issues Always in sync
2 sources of truth 1 source of truth
Hard to add tools Add tool → Done

🚨 Important Notes

  1. Naming Convention: We kept agentpress_tools naming throughout for consistency
  2. Backward Compatible: Existing configs work without changes
  3. No Breaking Changes: All existing functionality preserved
  4. Performance: Tools metadata cached for 1 hour in frontend
  5. Fallbacks: Components show loading state while fetching

🎯 Next Steps (Optional)

  1. Add decorators to existing tools for better UI
  2. Remove tool-groups.ts entirely once all components updated
  3. Add more metadata fields (categories, tags, etc.)
  4. Auto-generate tool documentation

CLEAN. SIMPLE. AUTO-GENERATED. NO LEGACY BULLSHIT.

For technical details, see: backend/core/utils/TOOL_SYSTEM_REFACTOR.md