Skip to content

Commit 66c62a0

Browse files
committed
feat: add Tool Unloading pattern tools (arango_advance_workflow_stage, arango_get_tool_usage_stats, arango_unload_tools)
1 parent 94d8091 commit 66c62a0

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

mcp_arangodb_async/handlers.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,6 +2136,175 @@ def handle_list_contexts(
21362136
}
21372137

21382138

2139+
# Pattern 3: Tool Unloading
2140+
# Define workflow stages and their tool sets
2141+
WORKFLOW_STAGES = {
2142+
"setup": {
2143+
"description": "Create collections, graphs, and schemas",
2144+
"tools": [
2145+
ARANGO_CREATE_COLLECTION, ARANGO_CREATE_GRAPH, ARANGO_CREATE_SCHEMA,
2146+
ARANGO_ADD_VERTEX_COLLECTION, ARANGO_ADD_EDGE_DEFINITION
2147+
]
2148+
},
2149+
"data_loading": {
2150+
"description": "Bulk insert and validate data",
2151+
"tools": [
2152+
ARANGO_BULK_INSERT, ARANGO_INSERT_WITH_VALIDATION,
2153+
ARANGO_VALIDATE_REFERENCES, ARANGO_INSERT
2154+
]
2155+
},
2156+
"analysis": {
2157+
"description": "Query, traverse, and analyze data",
2158+
"tools": [
2159+
ARANGO_QUERY, ARANGO_TRAVERSE, ARANGO_SHORTEST_PATH,
2160+
ARANGO_EXPLAIN_QUERY, ARANGO_QUERY_PROFILE, ARANGO_GRAPH_STATISTICS
2161+
]
2162+
},
2163+
"cleanup": {
2164+
"description": "Backup and finalize workflow",
2165+
"tools": [
2166+
ARANGO_BACKUP, ARANGO_BACKUP_GRAPH, ARANGO_BACKUP_NAMED_GRAPHS,
2167+
ARANGO_VALIDATE_GRAPH_INTEGRITY
2168+
]
2169+
}
2170+
}
2171+
2172+
# Global state for tool usage tracking (in production, this would be per-session)
2173+
_CURRENT_STAGE = "setup"
2174+
_TOOL_USAGE_STATS = {}
2175+
2176+
2177+
def _track_tool_usage(tool_name: str):
2178+
"""Track tool usage for unloading decisions."""
2179+
if tool_name not in _TOOL_USAGE_STATS:
2180+
_TOOL_USAGE_STATS[tool_name] = {
2181+
"first_used": datetime.now().isoformat(),
2182+
"last_used": datetime.now().isoformat(),
2183+
"use_count": 0,
2184+
"stage": _CURRENT_STAGE
2185+
}
2186+
2187+
_TOOL_USAGE_STATS[tool_name]["last_used"] = datetime.now().isoformat()
2188+
_TOOL_USAGE_STATS[tool_name]["use_count"] += 1
2189+
2190+
2191+
@handle_errors
2192+
@register_tool(
2193+
name=ARANGO_ADVANCE_WORKFLOW_STAGE,
2194+
description="Advance to the next workflow stage, automatically unloading tools from previous stage and loading tools for new stage. Enables Tool Unloading pattern.",
2195+
model=AdvanceWorkflowStageArgs,
2196+
)
2197+
def handle_advance_workflow_stage(
2198+
db: StandardDatabase, args: Dict[str, Any]
2199+
) -> Dict[str, Any]:
2200+
"""Advance to a new workflow stage with automatic tool unloading.
2201+
2202+
This tool enables the Tool Unloading pattern by automatically removing
2203+
tools from completed stages and loading tools for the new stage.
2204+
2205+
Args:
2206+
db: ArangoDB database instance (not used, but required for handler signature)
2207+
args: Validated AdvanceWorkflowStageArgs containing target stage
2208+
2209+
Returns:
2210+
Dictionary with stage transition details
2211+
"""
2212+
global _CURRENT_STAGE
2213+
2214+
new_stage = args["stage"]
2215+
old_stage = _CURRENT_STAGE
2216+
2217+
if new_stage not in WORKFLOW_STAGES:
2218+
return {
2219+
"error": f"Unknown stage: {new_stage}",
2220+
"available_stages": list(WORKFLOW_STAGES.keys())
2221+
}
2222+
2223+
old_tools = set(WORKFLOW_STAGES[old_stage]["tools"])
2224+
new_tools = set(WORKFLOW_STAGES[new_stage]["tools"])
2225+
2226+
tools_unloaded = list(old_tools - new_tools)
2227+
tools_loaded = list(new_tools - old_tools)
2228+
2229+
_CURRENT_STAGE = new_stage
2230+
2231+
return {
2232+
"from_stage": old_stage,
2233+
"to_stage": new_stage,
2234+
"description": WORKFLOW_STAGES[new_stage]["description"],
2235+
"tools_unloaded": tools_unloaded,
2236+
"tools_loaded": tools_loaded,
2237+
"active_tools": list(new_tools),
2238+
"total_active_tools": len(new_tools)
2239+
}
2240+
2241+
2242+
@handle_errors
2243+
@register_tool(
2244+
name=ARANGO_GET_TOOL_USAGE_STATS,
2245+
description="Get usage statistics for all tools, including use counts and last used timestamps. Useful for understanding tool usage patterns.",
2246+
model=GetToolUsageStatsArgs,
2247+
)
2248+
def handle_get_tool_usage_stats(
2249+
db: StandardDatabase, args: Optional[Dict[str, Any]] = None
2250+
) -> Dict[str, Any]:
2251+
"""Get tool usage statistics.
2252+
2253+
Args:
2254+
db: ArangoDB database instance (not used, but required for handler signature)
2255+
args: No arguments required
2256+
2257+
Returns:
2258+
Dictionary with tool usage statistics
2259+
"""
2260+
global _TOOL_USAGE_STATS, _CURRENT_STAGE
2261+
2262+
return {
2263+
"current_stage": _CURRENT_STAGE,
2264+
"tool_usage": _TOOL_USAGE_STATS,
2265+
"total_tools_used": len(_TOOL_USAGE_STATS),
2266+
"active_stage_tools": WORKFLOW_STAGES[_CURRENT_STAGE]["tools"]
2267+
}
2268+
2269+
2270+
@handle_errors
2271+
@register_tool(
2272+
name=ARANGO_UNLOAD_TOOLS,
2273+
description="Manually unload specific tools from the active context. Useful for fine-grained control over tool lifecycle.",
2274+
model=UnloadToolsArgs,
2275+
)
2276+
def handle_unload_tools(
2277+
db: StandardDatabase, args: Dict[str, Any]
2278+
) -> Dict[str, Any]:
2279+
"""Manually unload specific tools.
2280+
2281+
Args:
2282+
db: ArangoDB database instance (not used, but required for handler signature)
2283+
args: Validated UnloadToolsArgs containing tool names to unload
2284+
2285+
Returns:
2286+
Dictionary with unload results
2287+
"""
2288+
tool_names = args["tool_names"]
2289+
2290+
# In a real implementation, this would remove tools from the active context
2291+
# For now, we just track which tools would be unloaded
2292+
unloaded = []
2293+
not_found = []
2294+
2295+
for tool_name in tool_names:
2296+
if tool_name in TOOL_REGISTRY:
2297+
unloaded.append(tool_name)
2298+
else:
2299+
not_found.append(tool_name)
2300+
2301+
return {
2302+
"unloaded": unloaded,
2303+
"not_found": not_found,
2304+
"total_unloaded": len(unloaded)
2305+
}
2306+
2307+
21392308
# Register aliases for backward compatibility
21402309
from .tool_registry import ToolRegistration
21412310

0 commit comments

Comments
 (0)