onetool-mcp 1.0.0rc2__py3-none-any.whl → 1.0.0rc3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- onetool/cli.py +2 -0
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/METADATA +26 -33
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/RECORD +31 -33
- ot/config/__init__.py +90 -48
- ot/config/global_templates/__init__.py +2 -2
- ot/config/global_templates/diagram-templates/api-flow.mmd +33 -33
- ot/config/global_templates/diagram-templates/c4-context.puml +30 -30
- ot/config/global_templates/diagram-templates/class-diagram.mmd +87 -87
- ot/config/global_templates/diagram-templates/feature-mindmap.mmd +70 -70
- ot/config/global_templates/diagram-templates/microservices.d2 +81 -81
- ot/config/global_templates/diagram-templates/project-gantt.mmd +37 -37
- ot/config/global_templates/diagram-templates/state-machine.mmd +42 -42
- ot/config/global_templates/diagram.yaml +167 -167
- ot/config/global_templates/onetool.yaml +2 -0
- ot/config/global_templates/prompts.yaml +102 -102
- ot/config/global_templates/security.yaml +1 -4
- ot/config/global_templates/servers.yaml +1 -1
- ot/config/global_templates/tool_templates/__init__.py +7 -7
- ot/config/loader.py +226 -869
- ot/config/models.py +735 -0
- ot/config/secrets.py +243 -192
- ot/executor/tool_loader.py +10 -1
- ot/executor/validator.py +11 -1
- ot/meta.py +338 -33
- ot/prompts.py +228 -218
- ot/proxy/manager.py +168 -8
- ot/registry/__init__.py +199 -189
- ot/config/dynamic.py +0 -121
- ot/config/mcp.py +0 -149
- ot/config/tool_config.py +0 -125
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/WHEEL +0 -0
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/entry_points.txt +0 -0
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/licenses/LICENSE.txt +0 -0
- {onetool_mcp-1.0.0rc2.dist-info → onetool_mcp-1.0.0rc3.dist-info}/licenses/NOTICE.txt +0 -0
ot/meta.py
CHANGED
|
@@ -21,9 +21,12 @@ from __future__ import annotations
|
|
|
21
21
|
|
|
22
22
|
import asyncio
|
|
23
23
|
import fnmatch
|
|
24
|
+
import getpass
|
|
24
25
|
import inspect
|
|
26
|
+
import os
|
|
27
|
+
import platform
|
|
25
28
|
import sys
|
|
26
|
-
import time
|
|
29
|
+
import time
|
|
27
30
|
from collections.abc import (
|
|
28
31
|
Callable as _Callable, # noqa: TC003 - used at runtime in timed()
|
|
29
32
|
)
|
|
@@ -43,6 +46,9 @@ from ot.proxy import get_proxy_manager
|
|
|
43
46
|
|
|
44
47
|
_T = _TypeVar("_T")
|
|
45
48
|
|
|
49
|
+
# Track when module was first loaded (OneTool start time)
|
|
50
|
+
_MODULE_LOAD_TIME = time.time()
|
|
51
|
+
|
|
46
52
|
# Alias for cleaner logging calls in this module
|
|
47
53
|
log = LogSpan
|
|
48
54
|
|
|
@@ -75,6 +81,7 @@ def resolve_ot_path(path: str) -> Path:
|
|
|
75
81
|
|
|
76
82
|
# Info level type for discovery functions
|
|
77
83
|
InfoLevel = Literal["list", "min", "full"]
|
|
84
|
+
ServerInfoLevel = Literal["list", "min", "full", "resources", "prompts"]
|
|
78
85
|
|
|
79
86
|
# Pack name for dot notation: ot.tools(), ot.packs(), etc.
|
|
80
87
|
PACK_NAME = "ot"
|
|
@@ -95,6 +102,7 @@ __all__ = [
|
|
|
95
102
|
"PACK_NAME",
|
|
96
103
|
"aliases",
|
|
97
104
|
"config",
|
|
105
|
+
"debug",
|
|
98
106
|
"get_ot_pack_functions",
|
|
99
107
|
"health",
|
|
100
108
|
"help",
|
|
@@ -123,6 +131,203 @@ def version() -> str:
|
|
|
123
131
|
return __version__
|
|
124
132
|
|
|
125
133
|
|
|
134
|
+
def _get_version_info() -> dict[str, Any]:
|
|
135
|
+
"""Get version information from package metadata."""
|
|
136
|
+
return {"version": __version__}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _get_paths_info() -> dict[str, Any]:
|
|
140
|
+
"""Get all relevant path information."""
|
|
141
|
+
install_path = Path(__file__).parent.parent.resolve()
|
|
142
|
+
global_dir = get_global_dir()
|
|
143
|
+
cfg = get_config()
|
|
144
|
+
|
|
145
|
+
paths: dict[str, Any] = {
|
|
146
|
+
"install": str(install_path),
|
|
147
|
+
"global_dir": str(global_dir),
|
|
148
|
+
"cwd": str(resolve_cwd_path(".")),
|
|
149
|
+
"python": sys.executable,
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if cfg._config_dir:
|
|
153
|
+
paths["config_file"] = str(cfg._config_dir / "onetool.yaml")
|
|
154
|
+
paths["config_dir"] = str(cfg._config_dir)
|
|
155
|
+
|
|
156
|
+
paths["log_dir"] = str(cfg.get_log_dir_path())
|
|
157
|
+
|
|
158
|
+
if cfg.stats.enabled:
|
|
159
|
+
paths["stats_file"] = str(cfg.get_stats_file_path())
|
|
160
|
+
|
|
161
|
+
paths["result_store"] = str(cfg.get_result_store_path())
|
|
162
|
+
|
|
163
|
+
return paths
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _get_config_info(verbose: bool = False) -> dict[str, Any]:
|
|
167
|
+
"""Get configuration summary."""
|
|
168
|
+
from ot.executor.tool_loader import load_tool_registry
|
|
169
|
+
|
|
170
|
+
cfg = get_config()
|
|
171
|
+
registry = load_tool_registry()
|
|
172
|
+
|
|
173
|
+
info: dict[str, Any] = {
|
|
174
|
+
"version": cfg.version,
|
|
175
|
+
"servers": list(cfg.servers.keys()),
|
|
176
|
+
"packs_loaded": len(registry.packs),
|
|
177
|
+
"aliases": len(cfg.alias) if cfg.alias else 0,
|
|
178
|
+
"snippets": len(cfg.snippets) if cfg.snippets else 0,
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if verbose:
|
|
182
|
+
info["includes"] = cfg.include
|
|
183
|
+
info["tools_dir"] = cfg.tools_dir
|
|
184
|
+
info["stats_enabled"] = cfg.stats.enabled
|
|
185
|
+
info["log_verbose"] = cfg.log_verbose
|
|
186
|
+
|
|
187
|
+
return info
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _get_python_info() -> dict[str, Any]:
|
|
191
|
+
"""Get Python environment information."""
|
|
192
|
+
return {
|
|
193
|
+
"version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
|
194
|
+
"implementation": sys.implementation.name,
|
|
195
|
+
"platform": sys.platform,
|
|
196
|
+
"executable": sys.executable,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _get_system_info() -> dict[str, Any]:
|
|
201
|
+
"""Get OS/system information."""
|
|
202
|
+
info = {
|
|
203
|
+
"platform": platform.system(),
|
|
204
|
+
"machine": platform.machine(),
|
|
205
|
+
"user": getpass.getuser(),
|
|
206
|
+
"pid": os.getpid(),
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
# Add memory usage if psutil available
|
|
210
|
+
try:
|
|
211
|
+
import psutil # type: ignore[import-untyped]
|
|
212
|
+
|
|
213
|
+
process = psutil.Process(os.getpid())
|
|
214
|
+
mem_info = process.memory_info()
|
|
215
|
+
info["memory"] = {
|
|
216
|
+
"rss_mb": round(mem_info.rss / 1024 / 1024, 2),
|
|
217
|
+
"vms_mb": round(mem_info.vms / 1024 / 1024, 2),
|
|
218
|
+
"percent": round(process.memory_percent(), 2),
|
|
219
|
+
}
|
|
220
|
+
except ImportError:
|
|
221
|
+
pass
|
|
222
|
+
|
|
223
|
+
return info
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _get_runtime_info() -> dict[str, Any]:
|
|
227
|
+
"""Get current runtime state."""
|
|
228
|
+
from ot.executor.tool_loader import load_tool_registry
|
|
229
|
+
from ot.executor.worker_proxy import WorkerPackProxy
|
|
230
|
+
from ot.proxy import get_proxy_manager
|
|
231
|
+
|
|
232
|
+
registry = load_tool_registry()
|
|
233
|
+
proxy = get_proxy_manager()
|
|
234
|
+
cfg = get_config()
|
|
235
|
+
|
|
236
|
+
# Count local tools
|
|
237
|
+
tool_count = 0
|
|
238
|
+
for funcs in registry.packs.values():
|
|
239
|
+
if isinstance(funcs, WorkerPackProxy):
|
|
240
|
+
tool_count += len(funcs.functions)
|
|
241
|
+
else:
|
|
242
|
+
tool_count += len(funcs)
|
|
243
|
+
|
|
244
|
+
# Count proxy connections
|
|
245
|
+
connected = sum(1 for name in cfg.servers if proxy.get_connection(name))
|
|
246
|
+
disconnected = len(cfg.servers) - connected
|
|
247
|
+
|
|
248
|
+
# Timing information
|
|
249
|
+
current_time = time.time()
|
|
250
|
+
uptime_seconds = current_time - _MODULE_LOAD_TIME
|
|
251
|
+
start_time = datetime.fromtimestamp(_MODULE_LOAD_TIME, tz=UTC)
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
"packs_loaded": len(registry.packs),
|
|
255
|
+
"tools_local": tool_count,
|
|
256
|
+
"tools_proxied": proxy.tool_count,
|
|
257
|
+
"servers_configured": len(cfg.servers),
|
|
258
|
+
"servers_connected": connected,
|
|
259
|
+
"servers_disconnected": disconnected,
|
|
260
|
+
"start_time": start_time.isoformat(),
|
|
261
|
+
"uptime_seconds": round(uptime_seconds, 2),
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def debug(
|
|
266
|
+
*,
|
|
267
|
+
verbose: bool = False,
|
|
268
|
+
env_vars: bool = False,
|
|
269
|
+
dependencies: bool = False,
|
|
270
|
+
) -> dict[str, Any]:
|
|
271
|
+
"""Get comprehensive debug information about this OneTool installation.
|
|
272
|
+
|
|
273
|
+
Essential for multi-version development - clearly identifies which
|
|
274
|
+
version is running and where it's configured.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
verbose: Include detailed configuration information
|
|
278
|
+
env_vars: Include relevant environment variables
|
|
279
|
+
dependencies: Include dependency versions
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
Structured debug information with sections:
|
|
283
|
+
- version: Package version
|
|
284
|
+
- paths: All relevant file paths
|
|
285
|
+
- config: Configuration summary
|
|
286
|
+
- python: Python environment details
|
|
287
|
+
- system: OS/platform information
|
|
288
|
+
- runtime: Current runtime state (packs, servers, tools, timing)
|
|
289
|
+
|
|
290
|
+
Example:
|
|
291
|
+
ot.debug()
|
|
292
|
+
ot.debug(verbose=True, env_vars=True)
|
|
293
|
+
"""
|
|
294
|
+
with log(span="ot.debug", verbose=verbose) as s:
|
|
295
|
+
result: dict[str, Any] = {
|
|
296
|
+
"version": _get_version_info(),
|
|
297
|
+
"paths": _get_paths_info(),
|
|
298
|
+
"config": _get_config_info(verbose=verbose),
|
|
299
|
+
"python": _get_python_info(),
|
|
300
|
+
"system": _get_system_info(),
|
|
301
|
+
"runtime": _get_runtime_info(),
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if env_vars:
|
|
305
|
+
# Include relevant environment variables
|
|
306
|
+
result["env"] = {
|
|
307
|
+
"OT_GLOBAL_DIR": os.getenv("OT_GLOBAL_DIR"),
|
|
308
|
+
"ONETOOL_CONFIG": os.getenv("ONETOOL_CONFIG"),
|
|
309
|
+
"OT_CWD": os.getenv("OT_CWD"),
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if dependencies:
|
|
313
|
+
# Include dependency versions
|
|
314
|
+
from importlib.metadata import PackageNotFoundError
|
|
315
|
+
from importlib.metadata import version as get_version
|
|
316
|
+
|
|
317
|
+
deps = {}
|
|
318
|
+
for pkg in ["fastmcp", "pydantic", "pyyaml", "loguru", "requests", "openai"]:
|
|
319
|
+
try:
|
|
320
|
+
deps[pkg] = get_version(pkg)
|
|
321
|
+
except PackageNotFoundError:
|
|
322
|
+
deps[pkg] = "not installed"
|
|
323
|
+
result["dependencies"] = deps
|
|
324
|
+
|
|
325
|
+
version_str = result["version"].get("version", "unknown")
|
|
326
|
+
s.add("version", version_str)
|
|
327
|
+
|
|
328
|
+
return result
|
|
329
|
+
|
|
330
|
+
|
|
126
331
|
def security(*, check: str = "") -> dict[str, Any]:
|
|
127
332
|
"""Check security rules for code validation.
|
|
128
333
|
|
|
@@ -176,9 +381,9 @@ def timed(func: _Callable[..., _T], **kwargs: Any) -> dict[str, Any]:
|
|
|
176
381
|
ot.timed(brave.search, query="AI news")
|
|
177
382
|
# Returns: {"ms": 234, "result": {...}}
|
|
178
383
|
"""
|
|
179
|
-
start =
|
|
384
|
+
start = time.perf_counter()
|
|
180
385
|
result = func(**kwargs)
|
|
181
|
-
elapsed =
|
|
386
|
+
elapsed = time.perf_counter() - start
|
|
182
387
|
|
|
183
388
|
return {
|
|
184
389
|
"ms": round(elapsed * 1000),
|
|
@@ -199,6 +404,7 @@ def get_ot_pack_functions() -> dict[str, Any]:
|
|
|
199
404
|
"aliases": aliases,
|
|
200
405
|
"snippets": snippets,
|
|
201
406
|
"config": config,
|
|
407
|
+
"debug": debug,
|
|
202
408
|
"health": health,
|
|
203
409
|
"help": help,
|
|
204
410
|
"result": result,
|
|
@@ -472,7 +678,8 @@ def _format_search_results(
|
|
|
472
678
|
for snippet in snippets_results:
|
|
473
679
|
if isinstance(snippet, str):
|
|
474
680
|
# For info="min", format is "name: description"
|
|
475
|
-
|
|
681
|
+
snippet_name = snippet.split(":")[0] if ":" in snippet else snippet
|
|
682
|
+
lines.append(f"- ${snippet_name}")
|
|
476
683
|
else:
|
|
477
684
|
lines.append(f"- ${snippet}")
|
|
478
685
|
lines.append("")
|
|
@@ -933,7 +1140,7 @@ def packs(
|
|
|
933
1140
|
def servers(
|
|
934
1141
|
*,
|
|
935
1142
|
pattern: str = "",
|
|
936
|
-
info:
|
|
1143
|
+
info: ServerInfoLevel = "min",
|
|
937
1144
|
) -> list[dict[str, Any] | str]:
|
|
938
1145
|
"""List configured MCP proxy servers with optional filtering.
|
|
939
1146
|
|
|
@@ -942,17 +1149,22 @@ def servers(
|
|
|
942
1149
|
|
|
943
1150
|
Args:
|
|
944
1151
|
pattern: Filter servers by name pattern (case-insensitive substring)
|
|
945
|
-
info: Output verbosity level
|
|
946
|
-
|
|
1152
|
+
info: Output verbosity level:
|
|
1153
|
+
- "list": names only
|
|
1154
|
+
- "min": name + status + tool_count (default)
|
|
1155
|
+
- "full": detailed info with instructions and tools
|
|
1156
|
+
- "resources": list resources per server
|
|
1157
|
+
- "prompts": list prompts per server
|
|
947
1158
|
|
|
948
1159
|
Returns:
|
|
949
|
-
List of server names (info="list") or server dicts/strings (info="min"/"full")
|
|
1160
|
+
List of server names (info="list") or server dicts/strings (info="min"/"full"/"resources"/"prompts")
|
|
950
1161
|
|
|
951
1162
|
Example:
|
|
952
1163
|
ot.servers()
|
|
953
1164
|
ot.servers(pattern="github")
|
|
954
1165
|
ot.servers(info="full")
|
|
955
|
-
ot.servers(
|
|
1166
|
+
ot.servers(info="resources")
|
|
1167
|
+
ot.servers(pattern="devtools", info="prompts")
|
|
956
1168
|
"""
|
|
957
1169
|
proxy = get_proxy_manager()
|
|
958
1170
|
cfg = get_config()
|
|
@@ -991,6 +1203,25 @@ def servers(
|
|
|
991
1203
|
elif server_cfg.type == "stdio" and server_cfg.command:
|
|
992
1204
|
cmd = f"{server_cfg.command} {' '.join(server_cfg.args)}"
|
|
993
1205
|
lines.append(f"**Command:** {cmd}")
|
|
1206
|
+
|
|
1207
|
+
# Add resource and prompt counts if connected
|
|
1208
|
+
if conn:
|
|
1209
|
+
try:
|
|
1210
|
+
if proxy._loop and proxy._loop.is_running():
|
|
1211
|
+
future_res = asyncio.run_coroutine_threadsafe(
|
|
1212
|
+
proxy.list_resources(server_name), proxy._loop
|
|
1213
|
+
)
|
|
1214
|
+
future_pmt = asyncio.run_coroutine_threadsafe(
|
|
1215
|
+
proxy.list_prompts(server_name), proxy._loop
|
|
1216
|
+
)
|
|
1217
|
+
resource_count = len(future_res.result(timeout=5))
|
|
1218
|
+
prompt_count = len(future_pmt.result(timeout=5))
|
|
1219
|
+
lines.append(f"**Resources:** {resource_count}")
|
|
1220
|
+
lines.append(f"**Prompts:** {prompt_count}")
|
|
1221
|
+
except Exception:
|
|
1222
|
+
# Silently skip if resources/prompts not supported
|
|
1223
|
+
pass
|
|
1224
|
+
|
|
994
1225
|
lines.append("")
|
|
995
1226
|
|
|
996
1227
|
# Show instructions if configured
|
|
@@ -1024,6 +1255,92 @@ def servers(
|
|
|
1024
1255
|
s.add("count", len(results))
|
|
1025
1256
|
return results
|
|
1026
1257
|
|
|
1258
|
+
# info="resources" - list resources per server
|
|
1259
|
+
if info == "resources":
|
|
1260
|
+
results_resources: list[dict[str, Any] | str] = []
|
|
1261
|
+
|
|
1262
|
+
for server_name in all_server_names:
|
|
1263
|
+
conn = proxy.get_connection(server_name)
|
|
1264
|
+
if not conn:
|
|
1265
|
+
results_resources.append({
|
|
1266
|
+
"server": server_name,
|
|
1267
|
+
"status": "disconnected",
|
|
1268
|
+
"resources": [],
|
|
1269
|
+
})
|
|
1270
|
+
continue
|
|
1271
|
+
|
|
1272
|
+
try:
|
|
1273
|
+
# Run async list_resources using ProxyManager's event loop
|
|
1274
|
+
if proxy._loop and proxy._loop.is_running():
|
|
1275
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
1276
|
+
proxy.list_resources(server_name),
|
|
1277
|
+
proxy._loop,
|
|
1278
|
+
)
|
|
1279
|
+
resources = future.result(timeout=10)
|
|
1280
|
+
else:
|
|
1281
|
+
# No event loop available - server not initialized
|
|
1282
|
+
resources = []
|
|
1283
|
+
|
|
1284
|
+
results_resources.append({
|
|
1285
|
+
"server": server_name,
|
|
1286
|
+
"status": "connected",
|
|
1287
|
+
"resource_count": len(resources),
|
|
1288
|
+
"resources": resources,
|
|
1289
|
+
})
|
|
1290
|
+
except Exception as e:
|
|
1291
|
+
results_resources.append({
|
|
1292
|
+
"server": server_name,
|
|
1293
|
+
"status": "error",
|
|
1294
|
+
"error": str(e),
|
|
1295
|
+
"resources": [],
|
|
1296
|
+
})
|
|
1297
|
+
|
|
1298
|
+
s.add("count", len(results_resources))
|
|
1299
|
+
return results_resources
|
|
1300
|
+
|
|
1301
|
+
# info="prompts" - list prompts per server
|
|
1302
|
+
if info == "prompts":
|
|
1303
|
+
results_prompts: list[dict[str, Any] | str] = []
|
|
1304
|
+
|
|
1305
|
+
for server_name in all_server_names:
|
|
1306
|
+
conn = proxy.get_connection(server_name)
|
|
1307
|
+
if not conn:
|
|
1308
|
+
results_prompts.append({
|
|
1309
|
+
"server": server_name,
|
|
1310
|
+
"status": "disconnected",
|
|
1311
|
+
"prompts": [],
|
|
1312
|
+
})
|
|
1313
|
+
continue
|
|
1314
|
+
|
|
1315
|
+
try:
|
|
1316
|
+
# Run async list_prompts using ProxyManager's event loop
|
|
1317
|
+
if proxy._loop and proxy._loop.is_running():
|
|
1318
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
1319
|
+
proxy.list_prompts(server_name),
|
|
1320
|
+
proxy._loop,
|
|
1321
|
+
)
|
|
1322
|
+
prompts = future.result(timeout=10)
|
|
1323
|
+
else:
|
|
1324
|
+
# No event loop available - server not initialized
|
|
1325
|
+
prompts = []
|
|
1326
|
+
|
|
1327
|
+
results_prompts.append({
|
|
1328
|
+
"server": server_name,
|
|
1329
|
+
"status": "connected",
|
|
1330
|
+
"prompt_count": len(prompts),
|
|
1331
|
+
"prompts": prompts,
|
|
1332
|
+
})
|
|
1333
|
+
except Exception as e:
|
|
1334
|
+
results_prompts.append({
|
|
1335
|
+
"server": server_name,
|
|
1336
|
+
"status": "error",
|
|
1337
|
+
"error": str(e),
|
|
1338
|
+
"prompts": [],
|
|
1339
|
+
})
|
|
1340
|
+
|
|
1341
|
+
s.add("count", len(results_prompts))
|
|
1342
|
+
return results_prompts
|
|
1343
|
+
|
|
1027
1344
|
# info="min" (default) - summary for each server
|
|
1028
1345
|
servers_list: list[dict[str, Any] | str] = []
|
|
1029
1346
|
|
|
@@ -1295,25 +1612,25 @@ def reload() -> str:
|
|
|
1295
1612
|
import sys
|
|
1296
1613
|
|
|
1297
1614
|
with log(span="ot.reload") as s:
|
|
1298
|
-
|
|
1299
|
-
import ot.config
|
|
1615
|
+
# Import modules
|
|
1616
|
+
import ot.config
|
|
1300
1617
|
import ot.executor.param_resolver
|
|
1301
1618
|
import ot.executor.tool_loader
|
|
1619
|
+
import ot.executor.validator
|
|
1302
1620
|
import ot.prompts
|
|
1303
1621
|
import ot.proxy
|
|
1304
1622
|
import ot.registry
|
|
1305
1623
|
|
|
1306
|
-
# Clear
|
|
1307
|
-
ot.config.
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
ot.
|
|
1624
|
+
# Clear in dependency order (config first, others depend on it)
|
|
1625
|
+
ot.config.reset() # Clears both config and secrets
|
|
1626
|
+
ot.prompts.reset()
|
|
1627
|
+
ot.registry.reset()
|
|
1628
|
+
ot.executor.tool_loader.reset()
|
|
1629
|
+
ot.executor.validator.reset()
|
|
1311
1630
|
|
|
1312
|
-
# Clear
|
|
1313
|
-
ot.
|
|
1314
|
-
|
|
1315
|
-
# Clear tool loader module cache
|
|
1316
|
-
ot.executor.tool_loader._module_cache.clear()
|
|
1631
|
+
# Clear param resolver cache
|
|
1632
|
+
ot.executor.param_resolver.get_tool_param_names.cache_clear()
|
|
1633
|
+
ot.executor.param_resolver._mcp_param_cache.clear()
|
|
1317
1634
|
|
|
1318
1635
|
# Clean up dynamically loaded tool modules from sys.modules
|
|
1319
1636
|
# Tool loader uses "tools.{stem}" naming pattern
|
|
@@ -1322,18 +1639,6 @@ def reload() -> str:
|
|
|
1322
1639
|
del sys.modules[mod_name]
|
|
1323
1640
|
s.add("toolModulesCleared", len(tool_modules))
|
|
1324
1641
|
|
|
1325
|
-
# Clear tool registry cache (will rescan on next access)
|
|
1326
|
-
ot.registry._registry = None
|
|
1327
|
-
|
|
1328
|
-
# Clear param resolver cache (depends on registry)
|
|
1329
|
-
ot.executor.param_resolver.get_tool_param_names.cache_clear()
|
|
1330
|
-
ot.executor.param_resolver._mcp_param_cache.clear()
|
|
1331
|
-
|
|
1332
|
-
# Clear security validator caches (depends on config and registry)
|
|
1333
|
-
import ot.executor.validator
|
|
1334
|
-
ot.executor.validator._get_tool_namespaces.cache_clear()
|
|
1335
|
-
ot.executor.validator._get_security_config.cache_clear()
|
|
1336
|
-
|
|
1337
1642
|
# Reload config to validate and report stats
|
|
1338
1643
|
cfg = get_config()
|
|
1339
1644
|
|