chuk-tool-processor 0.6__py3-none-any.whl → 0.6.2__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.
Potentially problematic release.
This version of chuk-tool-processor might be problematic. Click here for more details.
- chuk_tool_processor/execution/strategies/inprocess_strategy.py +107 -8
- chuk_tool_processor/execution/strategies/subprocess_strategy.py +110 -13
- chuk_tool_processor/mcp/mcp_tool.py +351 -149
- chuk_tool_processor/mcp/register_mcp_tools.py +80 -33
- chuk_tool_processor/mcp/stream_manager.py +319 -65
- chuk_tool_processor-0.6.2.dist-info/METADATA +697 -0
- {chuk_tool_processor-0.6.dist-info → chuk_tool_processor-0.6.2.dist-info}/RECORD +9 -9
- chuk_tool_processor-0.6.dist-info/METADATA +0 -830
- {chuk_tool_processor-0.6.dist-info → chuk_tool_processor-0.6.2.dist-info}/WHEEL +0 -0
- {chuk_tool_processor-0.6.dist-info → chuk_tool_processor-0.6.2.dist-info}/top_level.txt +0 -0
|
@@ -1,55 +1,57 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# chuk_tool_processor/mcp/register_mcp_tools.py
|
|
3
3
|
"""
|
|
4
|
-
Discover the remote MCP tools exposed by a
|
|
5
|
-
instance and register them in the local CHUK registry.
|
|
4
|
+
Discover the remote MCP tools exposed by a StreamManager and register them locally.
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
CLEAN & SIMPLE: Just the essentials - create MCPTool wrappers for remote tools.
|
|
8
7
|
"""
|
|
9
8
|
|
|
10
9
|
from __future__ import annotations
|
|
11
10
|
|
|
12
|
-
from typing import Any, Dict, List
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
13
12
|
|
|
14
13
|
from chuk_tool_processor.logging import get_logger
|
|
15
|
-
from chuk_tool_processor.mcp.mcp_tool import MCPTool
|
|
14
|
+
from chuk_tool_processor.mcp.mcp_tool import MCPTool, RecoveryConfig
|
|
16
15
|
from chuk_tool_processor.mcp.stream_manager import StreamManager
|
|
17
16
|
from chuk_tool_processor.registry.provider import ToolRegistryProvider
|
|
18
17
|
|
|
19
18
|
logger = get_logger("chuk_tool_processor.mcp.register")
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
# --------------------------------------------------------------------------- #
|
|
23
|
-
# public API
|
|
24
|
-
# --------------------------------------------------------------------------- #
|
|
25
21
|
async def register_mcp_tools(
|
|
26
22
|
stream_manager: StreamManager,
|
|
27
23
|
namespace: str = "mcp",
|
|
24
|
+
*,
|
|
25
|
+
# Optional resilience configuration
|
|
26
|
+
default_timeout: float = 30.0,
|
|
27
|
+
enable_resilience: bool = True,
|
|
28
|
+
recovery_config: Optional[RecoveryConfig] = None,
|
|
28
29
|
) -> List[str]:
|
|
29
30
|
"""
|
|
30
|
-
Pull the
|
|
31
|
-
async wrapper (:class:`MCPTool`) for each entry.
|
|
31
|
+
Pull the remote tool catalogue and create local MCPTool wrappers.
|
|
32
32
|
|
|
33
33
|
Parameters
|
|
34
34
|
----------
|
|
35
35
|
stream_manager
|
|
36
|
-
An
|
|
36
|
+
An initialised StreamManager.
|
|
37
37
|
namespace
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
Tools are registered under their original name in the specified namespace.
|
|
39
|
+
default_timeout
|
|
40
|
+
Default timeout for tool execution
|
|
41
|
+
enable_resilience
|
|
42
|
+
Whether to enable resilience features (circuit breaker, retries)
|
|
43
|
+
recovery_config
|
|
44
|
+
Optional custom recovery configuration
|
|
43
45
|
|
|
44
46
|
Returns
|
|
45
47
|
-------
|
|
46
48
|
list[str]
|
|
47
|
-
The
|
|
49
|
+
The tool names that were registered.
|
|
48
50
|
"""
|
|
49
51
|
registry = await ToolRegistryProvider.get_registry()
|
|
50
52
|
registered: List[str] = []
|
|
51
53
|
|
|
52
|
-
#
|
|
54
|
+
# Get the remote tool catalogue
|
|
53
55
|
mcp_tools: List[Dict[str, Any]] = stream_manager.get_all_tools()
|
|
54
56
|
|
|
55
57
|
for tool_def in mcp_tools:
|
|
@@ -67,9 +69,15 @@ async def register_mcp_tools(
|
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
try:
|
|
70
|
-
|
|
72
|
+
# Create MCPTool wrapper with optional resilience configuration
|
|
73
|
+
wrapper = MCPTool(
|
|
74
|
+
tool_name=tool_name,
|
|
75
|
+
stream_manager=stream_manager,
|
|
76
|
+
default_timeout=default_timeout,
|
|
77
|
+
enable_resilience=enable_resilience,
|
|
78
|
+
recovery_config=recovery_config,
|
|
79
|
+
)
|
|
71
80
|
|
|
72
|
-
# ── primary registration ──────────────────────────────────────
|
|
73
81
|
await registry.register_tool(
|
|
74
82
|
wrapper,
|
|
75
83
|
name=tool_name,
|
|
@@ -77,24 +85,63 @@ async def register_mcp_tools(
|
|
|
77
85
|
metadata=meta,
|
|
78
86
|
)
|
|
79
87
|
|
|
80
|
-
# ── mirror into "default" namespace with dotted name ──────────
|
|
81
|
-
dotted_name = f"{namespace}.{tool_name}"
|
|
82
|
-
await registry.register_tool(
|
|
83
|
-
wrapper,
|
|
84
|
-
name=dotted_name,
|
|
85
|
-
namespace="default",
|
|
86
|
-
metadata={**meta, "tags": meta["tags"] | {"namespaced"}},
|
|
87
|
-
)
|
|
88
|
-
|
|
89
88
|
registered.append(tool_name)
|
|
90
89
|
logger.debug(
|
|
91
|
-
"MCP tool '%s' registered
|
|
90
|
+
"MCP tool '%s' registered as '%s:%s'",
|
|
91
|
+
tool_name,
|
|
92
|
+
namespace,
|
|
92
93
|
tool_name,
|
|
93
|
-
f"{namespace}:{tool_name}",
|
|
94
|
-
f"default:{dotted_name}",
|
|
95
94
|
)
|
|
96
|
-
except Exception as exc:
|
|
95
|
+
except Exception as exc:
|
|
97
96
|
logger.error("Failed to register MCP tool '%s': %s", tool_name, exc)
|
|
98
97
|
|
|
99
98
|
logger.info("MCP registration complete - %d tool(s) available", len(registered))
|
|
100
99
|
return registered
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def update_mcp_tools_stream_manager(
|
|
103
|
+
namespace: str,
|
|
104
|
+
new_stream_manager: Optional[StreamManager],
|
|
105
|
+
) -> int:
|
|
106
|
+
"""
|
|
107
|
+
Update the StreamManager reference for all MCP tools in a namespace.
|
|
108
|
+
|
|
109
|
+
Useful for reconnecting tools after StreamManager recovery at the service level.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
namespace
|
|
114
|
+
The namespace containing MCP tools to update
|
|
115
|
+
new_stream_manager
|
|
116
|
+
The new StreamManager to use, or None to disconnect
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
int
|
|
121
|
+
Number of tools updated
|
|
122
|
+
"""
|
|
123
|
+
registry = await ToolRegistryProvider.get_registry()
|
|
124
|
+
updated_count = 0
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# List all tools in the namespace
|
|
128
|
+
all_tools = await registry.list_tools()
|
|
129
|
+
namespace_tools = [name for ns, name in all_tools if ns == namespace]
|
|
130
|
+
|
|
131
|
+
for tool_name in namespace_tools:
|
|
132
|
+
try:
|
|
133
|
+
tool = await registry.get_tool(tool_name, namespace)
|
|
134
|
+
if tool and hasattr(tool, 'set_stream_manager'):
|
|
135
|
+
tool.set_stream_manager(new_stream_manager)
|
|
136
|
+
updated_count += 1
|
|
137
|
+
logger.debug(f"Updated StreamManager for tool '{namespace}:{tool_name}'")
|
|
138
|
+
except Exception as e:
|
|
139
|
+
logger.warning(f"Failed to update StreamManager for tool '{namespace}:{tool_name}': {e}")
|
|
140
|
+
|
|
141
|
+
action = "connected" if new_stream_manager else "disconnected"
|
|
142
|
+
logger.info(f"StreamManager {action} for {updated_count} tools in namespace '{namespace}'")
|
|
143
|
+
|
|
144
|
+
except Exception as e:
|
|
145
|
+
logger.error(f"Failed to update tools in namespace '{namespace}': {e}")
|
|
146
|
+
|
|
147
|
+
return updated_count
|