-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtool_registry.py
More file actions
89 lines (70 loc) · 2.85 KB
/
tool_registry.py
File metadata and controls
89 lines (70 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# Tool Registry...
import importlib
from pathlib import Path
from dotenv import load_dotenv
from core.interrupts import OperationInterrupted
# Load config.env from ~/.lumakit/ first (user overrides), then repo-root .env
_user_env = Path.home() / ".lumakit" / "config.env"
if _user_env.exists():
load_dotenv(_user_env)
load_dotenv() # repo-root .env — won't override keys already set
class ToolRegistry:
def __init__(self):
self.tools = {}
def register(self, tool):
self.tools[tool['name']] = tool
def get(self, name):
return self.tools.get(name)
def list(self):
return [
{
'name': tool['name'],
'description': tool ['description']
}
for tool in self.tools.values()
]
def validate_inputs(self, inputs, schema):
if 'required' in schema:
for field in schema['required']:
if field not in inputs:
raise ValueError(f"Missing required input: {field}")
def execute(self, name, inputs=None):
if inputs is None:
inputs = {}
tool = self.get(name)
if tool is None:
return {'success': False, 'error': f"Tool not found: {name}"}
try:
self.validate_inputs(inputs, tool['inputSchema'])
result = tool['execute'](inputs)
return {'success': True, 'data': result}
except OperationInterrupted as e:
return {
'success': False,
'error': str(e),
'toolName': name,
'interrupted': True,
}
except Exception as e:
return {'success': False, 'error': str(e), 'toolName': name}
def load_tools_from_folder(self, folder_path='tools', skip_dirs=None):
base_path = Path(folder_path)
skip_dirs = set(skip_dirs or [])
if not base_path.exists():
print(f"Tools folder not found: {folder_path}")
return
search_root = base_path.parent if base_path.parent != Path('') else Path('.')
for module_path in sorted(base_path.rglob('*.py')):
if module_path.name == '__init__.py':
continue
if module_path.parent == base_path and module_path.name.endswith('_tools.py'):
continue
if any(part in skip_dirs for part in module_path.parts):
continue
import_path = ".".join(module_path.with_suffix('').relative_to(search_root).parts)
module = importlib.import_module(import_path)
for attr_name in dir(module):
if attr_name.startswith('get_') and attr_name.endswith('_tool'):
tool_func = getattr(module, attr_name)
tool = tool_func()
self.register(tool)