chuk-tool-processor 0.6.4__py3-none-any.whl → 0.9.7__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/core/__init__.py +32 -1
- chuk_tool_processor/core/exceptions.py +225 -13
- chuk_tool_processor/core/processor.py +135 -104
- chuk_tool_processor/execution/strategies/__init__.py +6 -0
- chuk_tool_processor/execution/strategies/inprocess_strategy.py +142 -150
- chuk_tool_processor/execution/strategies/subprocess_strategy.py +202 -206
- chuk_tool_processor/execution/tool_executor.py +82 -84
- chuk_tool_processor/execution/wrappers/__init__.py +42 -0
- chuk_tool_processor/execution/wrappers/caching.py +150 -116
- chuk_tool_processor/execution/wrappers/circuit_breaker.py +370 -0
- chuk_tool_processor/execution/wrappers/rate_limiting.py +76 -43
- chuk_tool_processor/execution/wrappers/retry.py +116 -78
- chuk_tool_processor/logging/__init__.py +23 -17
- chuk_tool_processor/logging/context.py +40 -45
- chuk_tool_processor/logging/formatter.py +22 -21
- chuk_tool_processor/logging/helpers.py +28 -42
- chuk_tool_processor/logging/metrics.py +13 -15
- chuk_tool_processor/mcp/__init__.py +8 -12
- chuk_tool_processor/mcp/mcp_tool.py +158 -114
- chuk_tool_processor/mcp/register_mcp_tools.py +22 -22
- chuk_tool_processor/mcp/setup_mcp_http_streamable.py +57 -17
- chuk_tool_processor/mcp/setup_mcp_sse.py +57 -17
- chuk_tool_processor/mcp/setup_mcp_stdio.py +11 -11
- chuk_tool_processor/mcp/stream_manager.py +333 -276
- chuk_tool_processor/mcp/transport/__init__.py +22 -29
- chuk_tool_processor/mcp/transport/base_transport.py +180 -44
- chuk_tool_processor/mcp/transport/http_streamable_transport.py +505 -325
- chuk_tool_processor/mcp/transport/models.py +100 -0
- chuk_tool_processor/mcp/transport/sse_transport.py +607 -276
- chuk_tool_processor/mcp/transport/stdio_transport.py +597 -116
- chuk_tool_processor/models/__init__.py +21 -1
- chuk_tool_processor/models/execution_strategy.py +16 -21
- chuk_tool_processor/models/streaming_tool.py +28 -25
- chuk_tool_processor/models/tool_call.py +49 -31
- chuk_tool_processor/models/tool_export_mixin.py +22 -8
- chuk_tool_processor/models/tool_result.py +40 -77
- chuk_tool_processor/models/tool_spec.py +350 -0
- chuk_tool_processor/models/validated_tool.py +36 -18
- chuk_tool_processor/observability/__init__.py +30 -0
- chuk_tool_processor/observability/metrics.py +312 -0
- chuk_tool_processor/observability/setup.py +105 -0
- chuk_tool_processor/observability/tracing.py +345 -0
- chuk_tool_processor/plugins/__init__.py +1 -1
- chuk_tool_processor/plugins/discovery.py +11 -11
- chuk_tool_processor/plugins/parsers/__init__.py +1 -1
- chuk_tool_processor/plugins/parsers/base.py +1 -2
- chuk_tool_processor/plugins/parsers/function_call_tool.py +13 -8
- chuk_tool_processor/plugins/parsers/json_tool.py +4 -3
- chuk_tool_processor/plugins/parsers/openai_tool.py +12 -7
- chuk_tool_processor/plugins/parsers/xml_tool.py +4 -4
- chuk_tool_processor/registry/__init__.py +12 -12
- chuk_tool_processor/registry/auto_register.py +22 -30
- chuk_tool_processor/registry/decorators.py +127 -129
- chuk_tool_processor/registry/interface.py +26 -23
- chuk_tool_processor/registry/metadata.py +27 -22
- chuk_tool_processor/registry/provider.py +17 -18
- chuk_tool_processor/registry/providers/__init__.py +16 -19
- chuk_tool_processor/registry/providers/memory.py +18 -25
- chuk_tool_processor/registry/tool_export.py +42 -51
- chuk_tool_processor/utils/validation.py +15 -16
- chuk_tool_processor-0.9.7.dist-info/METADATA +1813 -0
- chuk_tool_processor-0.9.7.dist-info/RECORD +67 -0
- chuk_tool_processor-0.6.4.dist-info/METADATA +0 -697
- chuk_tool_processor-0.6.4.dist-info/RECORD +0 -60
- {chuk_tool_processor-0.6.4.dist-info → chuk_tool_processor-0.9.7.dist-info}/WHEEL +0 -0
- {chuk_tool_processor-0.6.4.dist-info → chuk_tool_processor-0.9.7.dist-info}/top_level.txt +0 -0
|
@@ -8,15 +8,17 @@ to enable true item-by-item streaming behavior, while preventing duplicates.
|
|
|
8
8
|
|
|
9
9
|
Proper timeout precedence - respects strategy's default_timeout when available.
|
|
10
10
|
"""
|
|
11
|
+
|
|
11
12
|
import asyncio
|
|
12
|
-
from
|
|
13
|
-
from
|
|
13
|
+
from collections.abc import AsyncIterator
|
|
14
|
+
from datetime import UTC, datetime
|
|
15
|
+
from typing import Any
|
|
14
16
|
|
|
17
|
+
from chuk_tool_processor.logging import get_logger
|
|
15
18
|
from chuk_tool_processor.models.execution_strategy import ExecutionStrategy
|
|
16
19
|
from chuk_tool_processor.models.tool_call import ToolCall
|
|
17
20
|
from chuk_tool_processor.models.tool_result import ToolResult
|
|
18
21
|
from chuk_tool_processor.registry.interface import ToolRegistryInterface
|
|
19
|
-
from chuk_tool_processor.logging import get_logger
|
|
20
22
|
|
|
21
23
|
logger = get_logger("chuk_tool_processor.execution.tool_executor")
|
|
22
24
|
|
|
@@ -24,23 +26,23 @@ logger = get_logger("chuk_tool_processor.execution.tool_executor")
|
|
|
24
26
|
class ToolExecutor:
|
|
25
27
|
"""
|
|
26
28
|
Async-native executor that selects and uses a strategy for tool execution.
|
|
27
|
-
|
|
29
|
+
|
|
28
30
|
This class provides a unified interface for executing tools using different
|
|
29
31
|
execution strategies, with special support for streaming tools.
|
|
30
|
-
|
|
32
|
+
|
|
31
33
|
FIXED: Proper timeout handling that respects strategy's default_timeout.
|
|
32
34
|
"""
|
|
33
35
|
|
|
34
36
|
def __init__(
|
|
35
37
|
self,
|
|
36
|
-
registry:
|
|
37
|
-
default_timeout:
|
|
38
|
-
strategy:
|
|
39
|
-
strategy_kwargs:
|
|
38
|
+
registry: ToolRegistryInterface | None = None,
|
|
39
|
+
default_timeout: float | None = None, # Made optional to allow strategy precedence
|
|
40
|
+
strategy: ExecutionStrategy | None = None,
|
|
41
|
+
strategy_kwargs: dict[str, Any] | None = None,
|
|
40
42
|
) -> None:
|
|
41
43
|
"""
|
|
42
44
|
Initialize the tool executor.
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
Args:
|
|
45
47
|
registry: Tool registry to use for tool lookups
|
|
46
48
|
default_timeout: Default timeout for tool execution (optional)
|
|
@@ -49,28 +51,28 @@ class ToolExecutor:
|
|
|
49
51
|
strategy_kwargs: Additional arguments for the strategy constructor
|
|
50
52
|
"""
|
|
51
53
|
self.registry = registry
|
|
52
|
-
|
|
54
|
+
|
|
53
55
|
# Create strategy if not provided
|
|
54
56
|
if strategy is None:
|
|
55
57
|
# Lazy import to allow for circular imports
|
|
56
58
|
import chuk_tool_processor.execution.strategies.inprocess_strategy as _inprocess_mod
|
|
57
|
-
|
|
59
|
+
|
|
58
60
|
if registry is None:
|
|
59
61
|
raise ValueError("Registry must be provided if strategy is not")
|
|
60
|
-
|
|
62
|
+
|
|
61
63
|
strategy_kwargs = strategy_kwargs or {}
|
|
62
|
-
|
|
64
|
+
|
|
63
65
|
# If no default_timeout specified, use a reasonable default for the strategy
|
|
64
66
|
strategy_timeout = default_timeout if default_timeout is not None else 30.0
|
|
65
|
-
|
|
67
|
+
|
|
66
68
|
strategy = _inprocess_mod.InProcessStrategy(
|
|
67
69
|
registry,
|
|
68
70
|
default_timeout=strategy_timeout,
|
|
69
71
|
**strategy_kwargs,
|
|
70
72
|
)
|
|
71
|
-
|
|
73
|
+
|
|
72
74
|
self.strategy = strategy
|
|
73
|
-
|
|
75
|
+
|
|
74
76
|
# Set default timeout with proper precedence:
|
|
75
77
|
# 1. Explicit default_timeout parameter
|
|
76
78
|
# 2. Strategy's default_timeout (if available and not None)
|
|
@@ -78,7 +80,7 @@ class ToolExecutor:
|
|
|
78
80
|
if default_timeout is not None:
|
|
79
81
|
self.default_timeout = default_timeout
|
|
80
82
|
logger.debug(f"Using explicit default_timeout: {self.default_timeout}s")
|
|
81
|
-
elif hasattr(strategy,
|
|
83
|
+
elif hasattr(strategy, "default_timeout") and strategy.default_timeout is not None:
|
|
82
84
|
self.default_timeout = strategy.default_timeout
|
|
83
85
|
logger.debug(f"Using strategy's default_timeout: {self.default_timeout}s")
|
|
84
86
|
else:
|
|
@@ -92,74 +94,77 @@ class ToolExecutor:
|
|
|
92
94
|
|
|
93
95
|
async def execute(
|
|
94
96
|
self,
|
|
95
|
-
calls:
|
|
96
|
-
timeout:
|
|
97
|
-
use_cache: bool = True,
|
|
98
|
-
) ->
|
|
97
|
+
calls: list[ToolCall],
|
|
98
|
+
timeout: float | None = None,
|
|
99
|
+
use_cache: bool = True, # noqa: ARG002
|
|
100
|
+
) -> list[ToolResult]:
|
|
99
101
|
"""
|
|
100
102
|
Execute tool calls using the configured strategy.
|
|
101
|
-
|
|
103
|
+
|
|
102
104
|
Args:
|
|
103
105
|
calls: List of tool calls to execute
|
|
104
106
|
timeout: Optional timeout for execution (overrides all defaults)
|
|
105
107
|
use_cache: Whether to use cached results (for caching wrappers)
|
|
106
|
-
|
|
108
|
+
|
|
107
109
|
Returns:
|
|
108
110
|
List of tool results in the same order as calls
|
|
109
111
|
"""
|
|
110
112
|
if not calls:
|
|
111
113
|
return []
|
|
112
|
-
|
|
114
|
+
|
|
113
115
|
# Timeout precedence:
|
|
114
116
|
# 1. Explicit timeout parameter (highest priority)
|
|
115
117
|
# 2. Executor's default_timeout (which already considers strategy's timeout)
|
|
116
118
|
effective_timeout = timeout if timeout is not None else self.default_timeout
|
|
117
|
-
|
|
118
|
-
logger.debug(
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
|
|
120
|
+
logger.debug(
|
|
121
|
+
f"Executing {len(calls)} tool calls with timeout {effective_timeout}s (explicit: {timeout is not None})"
|
|
122
|
+
)
|
|
123
|
+
|
|
121
124
|
# Delegate to the strategy
|
|
122
125
|
return await self.strategy.run(calls, timeout=effective_timeout)
|
|
123
|
-
|
|
126
|
+
|
|
124
127
|
async def stream_execute(
|
|
125
128
|
self,
|
|
126
|
-
calls:
|
|
127
|
-
timeout:
|
|
129
|
+
calls: list[ToolCall],
|
|
130
|
+
timeout: float | None = None,
|
|
128
131
|
) -> AsyncIterator[ToolResult]:
|
|
129
132
|
"""
|
|
130
133
|
Execute tool calls and yield results as they become available.
|
|
131
|
-
|
|
134
|
+
|
|
132
135
|
For streaming tools, this directly accesses their stream_execute method
|
|
133
136
|
to yield individual results as they are produced, rather than collecting
|
|
134
137
|
them into lists.
|
|
135
|
-
|
|
138
|
+
|
|
136
139
|
Args:
|
|
137
140
|
calls: List of tool calls to execute
|
|
138
141
|
timeout: Optional timeout for execution
|
|
139
|
-
|
|
142
|
+
|
|
140
143
|
Yields:
|
|
141
144
|
Tool results as they become available
|
|
142
145
|
"""
|
|
143
146
|
if not calls:
|
|
144
147
|
return
|
|
145
|
-
|
|
148
|
+
|
|
146
149
|
# Use the same timeout precedence as execute()
|
|
147
150
|
effective_timeout = timeout if timeout is not None else self.default_timeout
|
|
148
|
-
|
|
149
|
-
logger.debug(
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
|
|
152
|
+
logger.debug(
|
|
153
|
+
f"Stream executing {len(calls)} tool calls with timeout {effective_timeout}s "
|
|
154
|
+
f"(explicit: {timeout is not None})"
|
|
155
|
+
)
|
|
156
|
+
|
|
152
157
|
# There are two possible ways to handle streaming:
|
|
153
158
|
# 1. Use the strategy's stream_run if available
|
|
154
159
|
# 2. Use direct streaming for streaming tools
|
|
155
160
|
# We'll choose one approach based on the tool types to avoid duplicates
|
|
156
|
-
|
|
161
|
+
|
|
157
162
|
# Check if strategy supports streaming
|
|
158
163
|
if hasattr(self.strategy, "stream_run") and self.strategy.supports_streaming:
|
|
159
164
|
# Check for streaming tools
|
|
160
165
|
streaming_tools = []
|
|
161
166
|
non_streaming_tools = []
|
|
162
|
-
|
|
167
|
+
|
|
163
168
|
for call in calls:
|
|
164
169
|
# Check if the tool is a streaming tool
|
|
165
170
|
tool_impl = await self.registry.get_tool(call.tool, call.namespace)
|
|
@@ -167,63 +172,62 @@ class ToolExecutor:
|
|
|
167
172
|
# Tool not found - treat as non-streaming
|
|
168
173
|
non_streaming_tools.append(call)
|
|
169
174
|
continue
|
|
170
|
-
|
|
175
|
+
|
|
171
176
|
# Instantiate if class
|
|
172
177
|
tool = tool_impl() if callable(tool_impl) else tool_impl
|
|
173
|
-
|
|
178
|
+
|
|
174
179
|
# Check for streaming support
|
|
175
180
|
if hasattr(tool, "supports_streaming") and tool.supports_streaming and hasattr(tool, "stream_execute"):
|
|
176
181
|
streaming_tools.append((call, tool))
|
|
177
182
|
else:
|
|
178
183
|
non_streaming_tools.append(call)
|
|
179
|
-
|
|
184
|
+
|
|
180
185
|
# If we have streaming tools, handle them directly
|
|
181
186
|
if streaming_tools:
|
|
182
187
|
# Create a tracking queue for all results
|
|
183
188
|
queue = asyncio.Queue()
|
|
184
|
-
|
|
189
|
+
|
|
185
190
|
# Track processing to avoid duplicates
|
|
186
191
|
processed_calls = set()
|
|
187
|
-
|
|
192
|
+
|
|
188
193
|
# For streaming tools, create direct streaming tasks
|
|
189
194
|
pending_tasks = set()
|
|
190
195
|
for call, tool in streaming_tools:
|
|
191
196
|
# Add to processed list to avoid duplication
|
|
192
197
|
processed_calls.add(call.id)
|
|
193
|
-
|
|
198
|
+
|
|
194
199
|
# Create task for direct streaming
|
|
195
|
-
task = asyncio.create_task(self._direct_stream_tool(
|
|
196
|
-
call, tool, queue, effective_timeout
|
|
197
|
-
))
|
|
200
|
+
task = asyncio.create_task(self._direct_stream_tool(call, tool, queue, effective_timeout))
|
|
198
201
|
pending_tasks.add(task)
|
|
199
202
|
task.add_done_callback(pending_tasks.discard)
|
|
200
|
-
|
|
203
|
+
|
|
201
204
|
# For non-streaming tools, use the strategy's stream_run
|
|
202
205
|
if non_streaming_tools:
|
|
206
|
+
|
|
203
207
|
async def strategy_streamer():
|
|
204
208
|
async for result in self.strategy.stream_run(non_streaming_tools, timeout=effective_timeout):
|
|
205
209
|
await queue.put(result)
|
|
206
|
-
|
|
210
|
+
|
|
207
211
|
strategy_task = asyncio.create_task(strategy_streamer())
|
|
208
212
|
pending_tasks.add(strategy_task)
|
|
209
213
|
strategy_task.add_done_callback(pending_tasks.discard)
|
|
210
|
-
|
|
214
|
+
|
|
211
215
|
# Yield results as they arrive in the queue
|
|
212
216
|
while pending_tasks:
|
|
213
217
|
try:
|
|
214
218
|
# Wait a short time for a result, then check task status
|
|
215
219
|
result = await asyncio.wait_for(queue.get(), 0.1)
|
|
216
220
|
yield result
|
|
217
|
-
except
|
|
221
|
+
except TimeoutError:
|
|
218
222
|
# Check if tasks have completed
|
|
219
223
|
if not pending_tasks:
|
|
220
224
|
break
|
|
221
|
-
|
|
225
|
+
|
|
222
226
|
# Check for completed tasks
|
|
223
227
|
done, pending_tasks = await asyncio.wait(
|
|
224
228
|
pending_tasks, timeout=0, return_when=asyncio.FIRST_COMPLETED
|
|
225
229
|
)
|
|
226
|
-
|
|
230
|
+
|
|
227
231
|
# Handle any exceptions
|
|
228
232
|
for task in done:
|
|
229
233
|
try:
|
|
@@ -239,35 +243,29 @@ class ToolExecutor:
|
|
|
239
243
|
results = await self.execute(calls, timeout=effective_timeout)
|
|
240
244
|
for result in results:
|
|
241
245
|
yield result
|
|
242
|
-
|
|
243
|
-
async def _direct_stream_tool(
|
|
244
|
-
self,
|
|
245
|
-
call: ToolCall,
|
|
246
|
-
tool: Any,
|
|
247
|
-
queue: asyncio.Queue,
|
|
248
|
-
timeout: Optional[float]
|
|
249
|
-
) -> None:
|
|
246
|
+
|
|
247
|
+
async def _direct_stream_tool(self, call: ToolCall, tool: Any, queue: asyncio.Queue, timeout: float | None) -> None:
|
|
250
248
|
"""
|
|
251
249
|
Stream results directly from a streaming tool.
|
|
252
|
-
|
|
250
|
+
|
|
253
251
|
Args:
|
|
254
252
|
call: Tool call to execute
|
|
255
253
|
tool: Tool instance
|
|
256
254
|
queue: Queue to put results into
|
|
257
255
|
timeout: Optional timeout in seconds
|
|
258
256
|
"""
|
|
259
|
-
start_time = datetime.now(
|
|
257
|
+
start_time = datetime.now(UTC)
|
|
260
258
|
machine = "direct-stream"
|
|
261
259
|
pid = 0
|
|
262
|
-
|
|
260
|
+
|
|
263
261
|
logger.debug(f"Direct streaming {call.tool} with timeout {timeout}s")
|
|
264
|
-
|
|
262
|
+
|
|
265
263
|
# Create streaming task with timeout
|
|
266
264
|
async def stream_with_timeout():
|
|
267
265
|
try:
|
|
268
266
|
async for result in tool.stream_execute(**call.arguments):
|
|
269
267
|
# Create a ToolResult for each result
|
|
270
|
-
end_time = datetime.now(
|
|
268
|
+
end_time = datetime.now(UTC)
|
|
271
269
|
tool_result = ToolResult(
|
|
272
270
|
tool=call.tool,
|
|
273
271
|
result=result,
|
|
@@ -275,12 +273,12 @@ class ToolExecutor:
|
|
|
275
273
|
start_time=start_time,
|
|
276
274
|
end_time=end_time,
|
|
277
275
|
machine=machine,
|
|
278
|
-
pid=pid
|
|
276
|
+
pid=pid,
|
|
279
277
|
)
|
|
280
278
|
await queue.put(tool_result)
|
|
281
279
|
except Exception as e:
|
|
282
280
|
# Handle errors
|
|
283
|
-
end_time = datetime.now(
|
|
281
|
+
end_time = datetime.now(UTC)
|
|
284
282
|
error_result = ToolResult(
|
|
285
283
|
tool=call.tool,
|
|
286
284
|
result=None,
|
|
@@ -288,10 +286,10 @@ class ToolExecutor:
|
|
|
288
286
|
start_time=start_time,
|
|
289
287
|
end_time=end_time,
|
|
290
288
|
machine=machine,
|
|
291
|
-
pid=pid
|
|
289
|
+
pid=pid,
|
|
292
290
|
)
|
|
293
291
|
await queue.put(error_result)
|
|
294
|
-
|
|
292
|
+
|
|
295
293
|
try:
|
|
296
294
|
if timeout:
|
|
297
295
|
await asyncio.wait_for(stream_with_timeout(), timeout)
|
|
@@ -299,12 +297,12 @@ class ToolExecutor:
|
|
|
299
297
|
else:
|
|
300
298
|
await stream_with_timeout()
|
|
301
299
|
logger.debug(f"Direct streaming {call.tool} completed (no timeout)")
|
|
302
|
-
except
|
|
300
|
+
except TimeoutError:
|
|
303
301
|
# Handle timeout
|
|
304
|
-
end_time = datetime.now(
|
|
302
|
+
end_time = datetime.now(UTC)
|
|
305
303
|
actual_duration = (end_time - start_time).total_seconds()
|
|
306
304
|
logger.debug(f"Direct streaming {call.tool} timed out after {actual_duration:.3f}s (limit: {timeout}s)")
|
|
307
|
-
|
|
305
|
+
|
|
308
306
|
timeout_result = ToolResult(
|
|
309
307
|
tool=call.tool,
|
|
310
308
|
result=None,
|
|
@@ -312,14 +310,14 @@ class ToolExecutor:
|
|
|
312
310
|
start_time=start_time,
|
|
313
311
|
end_time=end_time,
|
|
314
312
|
machine=machine,
|
|
315
|
-
pid=pid
|
|
313
|
+
pid=pid,
|
|
316
314
|
)
|
|
317
315
|
await queue.put(timeout_result)
|
|
318
316
|
except Exception as e:
|
|
319
317
|
# Handle other errors
|
|
320
|
-
end_time = datetime.now(
|
|
318
|
+
end_time = datetime.now(UTC)
|
|
321
319
|
logger.exception(f"Error in direct streaming {call.tool}: {e}")
|
|
322
|
-
|
|
320
|
+
|
|
323
321
|
error_result = ToolResult(
|
|
324
322
|
tool=call.tool,
|
|
325
323
|
result=None,
|
|
@@ -327,16 +325,16 @@ class ToolExecutor:
|
|
|
327
325
|
start_time=start_time,
|
|
328
326
|
end_time=end_time,
|
|
329
327
|
machine=machine,
|
|
330
|
-
pid=pid
|
|
328
|
+
pid=pid,
|
|
331
329
|
)
|
|
332
330
|
await queue.put(error_result)
|
|
333
|
-
|
|
331
|
+
|
|
334
332
|
async def shutdown(self) -> None:
|
|
335
333
|
"""Enhanced shutdown for ToolExecutor with strategy coordination."""
|
|
336
334
|
logger.debug("Finalizing ToolExecutor operations")
|
|
337
|
-
|
|
335
|
+
|
|
338
336
|
if hasattr(self.strategy, "shutdown") and callable(self.strategy.shutdown):
|
|
339
337
|
try:
|
|
340
338
|
await self.strategy.shutdown()
|
|
341
339
|
except Exception as e:
|
|
342
|
-
logger.debug(f"Strategy finalization completed: {e}")
|
|
340
|
+
logger.debug(f"Strategy finalization completed: {e}")
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# chuk_tool_processor/execution/wrappers/__init__.py
|
|
2
|
+
"""Execution wrappers for adding production features to tool execution."""
|
|
3
|
+
|
|
4
|
+
from chuk_tool_processor.execution.wrappers.caching import (
|
|
5
|
+
CacheInterface,
|
|
6
|
+
CachingToolExecutor,
|
|
7
|
+
InMemoryCache,
|
|
8
|
+
cacheable,
|
|
9
|
+
)
|
|
10
|
+
from chuk_tool_processor.execution.wrappers.circuit_breaker import (
|
|
11
|
+
CircuitBreakerConfig,
|
|
12
|
+
CircuitBreakerExecutor,
|
|
13
|
+
CircuitState,
|
|
14
|
+
)
|
|
15
|
+
from chuk_tool_processor.execution.wrappers.rate_limiting import (
|
|
16
|
+
RateLimitedToolExecutor,
|
|
17
|
+
RateLimiter,
|
|
18
|
+
)
|
|
19
|
+
from chuk_tool_processor.execution.wrappers.retry import (
|
|
20
|
+
RetryableToolExecutor,
|
|
21
|
+
RetryConfig,
|
|
22
|
+
retryable,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
# Caching
|
|
27
|
+
"CacheInterface",
|
|
28
|
+
"CachingToolExecutor",
|
|
29
|
+
"InMemoryCache",
|
|
30
|
+
"cacheable",
|
|
31
|
+
# Circuit breaker
|
|
32
|
+
"CircuitBreakerConfig",
|
|
33
|
+
"CircuitBreakerExecutor",
|
|
34
|
+
"CircuitState",
|
|
35
|
+
# Rate limiting
|
|
36
|
+
"RateLimitedToolExecutor",
|
|
37
|
+
"RateLimiter",
|
|
38
|
+
# Retry
|
|
39
|
+
"RetryableToolExecutor",
|
|
40
|
+
"RetryConfig",
|
|
41
|
+
"retryable",
|
|
42
|
+
]
|