chuk-tool-processor 0.1.0__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.

Files changed (37) hide show
  1. chuk_tool_processor/__init__.py +1 -0
  2. chuk_tool_processor/core/__init__.py +1 -0
  3. chuk_tool_processor/core/exceptions.py +45 -0
  4. chuk_tool_processor/core/processor.py +268 -0
  5. chuk_tool_processor/execution/__init__.py +0 -0
  6. chuk_tool_processor/execution/strategies/__init__.py +0 -0
  7. chuk_tool_processor/execution/strategies/inprocess_strategy.py +206 -0
  8. chuk_tool_processor/execution/strategies/subprocess_strategy.py +103 -0
  9. chuk_tool_processor/execution/tool_executor.py +46 -0
  10. chuk_tool_processor/execution/wrappers/__init__.py +0 -0
  11. chuk_tool_processor/execution/wrappers/caching.py +234 -0
  12. chuk_tool_processor/execution/wrappers/rate_limiting.py +149 -0
  13. chuk_tool_processor/execution/wrappers/retry.py +176 -0
  14. chuk_tool_processor/models/__init__.py +1 -0
  15. chuk_tool_processor/models/execution_strategy.py +19 -0
  16. chuk_tool_processor/models/tool_call.py +7 -0
  17. chuk_tool_processor/models/tool_result.py +49 -0
  18. chuk_tool_processor/plugins/__init__.py +1 -0
  19. chuk_tool_processor/plugins/discovery.py +205 -0
  20. chuk_tool_processor/plugins/parsers/__init__.py +1 -0
  21. chuk_tool_processor/plugins/parsers/function_call_tool.py +105 -0
  22. chuk_tool_processor/plugins/parsers/json_tool.py +17 -0
  23. chuk_tool_processor/plugins/parsers/xml_tool.py +41 -0
  24. chuk_tool_processor/registry/__init__.py +20 -0
  25. chuk_tool_processor/registry/decorators.py +42 -0
  26. chuk_tool_processor/registry/interface.py +79 -0
  27. chuk_tool_processor/registry/metadata.py +36 -0
  28. chuk_tool_processor/registry/provider.py +44 -0
  29. chuk_tool_processor/registry/providers/__init__.py +41 -0
  30. chuk_tool_processor/registry/providers/memory.py +165 -0
  31. chuk_tool_processor/utils/__init__.py +0 -0
  32. chuk_tool_processor/utils/logging.py +260 -0
  33. chuk_tool_processor/utils/validation.py +192 -0
  34. chuk_tool_processor-0.1.0.dist-info/METADATA +293 -0
  35. chuk_tool_processor-0.1.0.dist-info/RECORD +37 -0
  36. chuk_tool_processor-0.1.0.dist-info/WHEEL +5 -0
  37. chuk_tool_processor-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,293 @@
1
+ Metadata-Version: 2.4
2
+ Name: chuk-tool-processor
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: pydantic>=2.11.3
8
+
9
+ # CHUK Tool Processor
10
+
11
+ A robust framework for detecting, executing, and managing tool calls in LLM responses.
12
+
13
+ ## Overview
14
+
15
+ The CHUK Tool Processor is a Python library designed to handle the execution of tools referenced in the output of Large Language Models (LLMs). It provides a flexible and extensible architecture for:
16
+
17
+ 1. **Parsing tool calls** from different formats (JSON, XML, function calls)
18
+ 2. **Executing tools** with proper isolation and error handling
19
+ 3. **Managing tool executions** with retry logic, caching, and rate limiting
20
+ 4. **Monitoring tool usage** with comprehensive logging
21
+
22
+ ## Features
23
+
24
+ - **Multiple Parser Support**: Extract tool calls from JSON, XML, or OpenAI-style function call formats
25
+ - **Flexible Execution Strategies**: Choose between in-process or subprocess execution for different isolation needs
26
+ - **Namespace Support**: Organize tools in logical namespaces
27
+ - **Concurrency Control**: Set limits on parallel tool executions
28
+ - **Validation**: Type validation for tool arguments and results
29
+ - **Caching**: Cache tool results to improve performance for repeated calls
30
+ - **Rate Limiting**: Prevent overloading external services with configurable rate limits
31
+ - **Retry Logic**: Automatically retry transient failures with exponential backoff
32
+ - **Structured Logging**: Comprehensive logging system for debugging and monitoring
33
+ - **Plugin Discovery**: Dynamically discover and load plugins from packages
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ # Clone the repository
39
+ git clone https://github.com/your-org/chuk-tool-processor.git
40
+ cd chuk-tool-processor
41
+
42
+ # Install with pip
43
+ pip install -e .
44
+
45
+ # Or with uv
46
+ uv pip install -e .
47
+ ```
48
+
49
+ ## Quick Start
50
+
51
+ ### Registering Tools
52
+
53
+ ```python
54
+ from chuk_tool_processor.registry import register_tool
55
+
56
+ @register_tool(name="calculator", namespace="math")
57
+ class CalculatorTool:
58
+ def execute(self, operation: str, a: float, b: float):
59
+ if operation == "add":
60
+ return a + b
61
+ elif operation == "multiply":
62
+ return a * b
63
+ # ... other operations
64
+ ```
65
+
66
+ ### Processing Tool Calls
67
+
68
+ ```python
69
+ import asyncio
70
+ from chuk_tool_processor.core.processor import ToolProcessor
71
+
72
+ async def main():
73
+ # Create a processor with default settings
74
+ processor = ToolProcessor()
75
+
76
+ # Process text with potential tool calls
77
+ llm_response = """
78
+ To calculate that, I'll use the calculator tool.
79
+
80
+ {
81
+ "function_call": {
82
+ "name": "calculator",
83
+ "arguments": {"operation": "multiply", "a": 123.45, "b": 67.89}
84
+ }
85
+ }
86
+ """
87
+
88
+ results = await processor.process_text(llm_response)
89
+
90
+ # Handle results
91
+ for result in results:
92
+ print(f"Tool: {result.tool}")
93
+ print(f"Result: {result.result}")
94
+ print(f"Error: {result.error}")
95
+ print(f"Duration: {(result.end_time - result.start_time).total_seconds()}s")
96
+
97
+ if __name__ == "__main__":
98
+ asyncio.run(main())
99
+ ```
100
+
101
+ ## Advanced Usage
102
+
103
+ ### Using Decorators for Tool Configuration
104
+
105
+ ```python
106
+ from chuk_tool_processor.registry import register_tool
107
+ from chuk_tool_processor.utils.validation import with_validation
108
+ from chuk_tool_processor.execution.wrappers.retry import retryable
109
+ from chuk_tool_processor.execution.wrappers.caching import cacheable
110
+ from chuk_tool_processor.execution.wrappers.rate_limiting import rate_limited
111
+ from typing import Dict, Any, Optional
112
+
113
+ @register_tool(name="weather", namespace="data")
114
+ @retryable(max_retries=3)
115
+ @cacheable(ttl=3600) # Cache for 1 hour
116
+ @rate_limited(limit=100, period=60.0) # 100 requests per minute
117
+ @with_validation
118
+ class WeatherTool:
119
+ def execute(self, location: str, units: str = "metric") -> Dict[str, Any]:
120
+ # Implementation that calls a weather API
121
+ return {
122
+ "temperature": 22.5,
123
+ "conditions": "Partly Cloudy",
124
+ "humidity": 65
125
+ }
126
+ ```
127
+
128
+ ### Using Validated Tool Base Class
129
+
130
+ ```python
131
+ from chuk_tool_processor.utils.validation import ValidatedTool
132
+ from chuk_tool_processor.registry import register_tool
133
+ from pydantic import BaseModel
134
+ from typing import Optional
135
+
136
+ @register_tool(namespace="data")
137
+ class WeatherTool(ValidatedTool):
138
+ class Arguments(BaseModel):
139
+ location: str
140
+ units: str = "metric" # Default to metric
141
+
142
+ class Result(BaseModel):
143
+ temperature: float
144
+ conditions: str
145
+ humidity: Optional[int] = None
146
+
147
+ def _execute(self, location: str, units: str = "metric"):
148
+ # Implementation
149
+ return {
150
+ "temperature": 22.5,
151
+ "conditions": "Sunny",
152
+ "humidity": 65
153
+ }
154
+ ```
155
+
156
+ ### Custom Execution Strategy
157
+
158
+ ```python
159
+ from chuk_tool_processor.registry.providers.memory import InMemoryToolRegistry
160
+ from chuk_tool_processor.execution.tool_executor import ToolExecutor
161
+ from chuk_tool_processor.execution.inprocess_strategy import InProcessStrategy
162
+
163
+ # Create registry and register tools
164
+ registry = InMemoryToolRegistry()
165
+ registry.register_tool(MyTool(), name="my_tool")
166
+
167
+ # Create executor with custom strategy
168
+ executor = ToolExecutor(
169
+ registry,
170
+ strategy=InProcessStrategy(
171
+ registry,
172
+ default_timeout=5.0,
173
+ max_concurrency=10
174
+ )
175
+ )
176
+
177
+ # Execute tool calls
178
+ results = await executor.execute([call1, call2])
179
+ ```
180
+
181
+ ### Custom Parser Plugins
182
+
183
+ ```python
184
+ from chuk_tool_processor.models.tool_call import ToolCall
185
+ from chuk_tool_processor.plugins.discovery import plugin_registry
186
+ import re
187
+ from typing import List
188
+
189
+ # Create a custom parser for a bracket syntax
190
+ class BracketToolParser:
191
+ """Parser for [tool:name arg1=val1 arg2="val2"] syntax"""
192
+
193
+ def try_parse(self, raw: str) -> List[ToolCall]:
194
+ calls = []
195
+ # Regex to match [tool:name arg1=val1 arg2="val2"]
196
+ pattern = r"\[tool:([^\s\]]+)([^\]]*)\]"
197
+ matches = re.finditer(pattern, raw)
198
+
199
+ for match in matches:
200
+ tool_name = match.group(1)
201
+ args_str = match.group(2).strip()
202
+
203
+ # Parse arguments
204
+ args = {}
205
+ if args_str:
206
+ # Match key=value pairs, handling quoted values
207
+ args_pattern = r'([^\s=]+)=(?:([^\s"]+)|"([^"]*)")'
208
+ for arg_match in re.finditer(args_pattern, args_str):
209
+ key = arg_match.group(1)
210
+ # Either group 2 (unquoted) or group 3 (quoted)
211
+ value = arg_match.group(2) if arg_match.group(2) else arg_match.group(3)
212
+ args[key] = value
213
+
214
+ calls.append(ToolCall(tool=tool_name, arguments=args))
215
+
216
+ return calls
217
+
218
+ # Register plugin manually
219
+ plugin_registry.register_plugin("parser", "BracketToolParser", BracketToolParser())
220
+ ```
221
+
222
+ ### Structured Logging
223
+
224
+ ```python
225
+ from chuk_tool_processor.utils.logging import get_logger, log_context_span
226
+
227
+ logger = get_logger("my_module")
228
+
229
+ # Create a context span for timing operations
230
+ with log_context_span("operation_name", {"extra": "context"}):
231
+ logger.info("Starting operation")
232
+ # Do something
233
+ logger.info("Operation completed")
234
+ ```
235
+
236
+ ## Architecture
237
+
238
+ The tool processor has several key components organized into a modular structure:
239
+
240
+ 1. **Registry**: Stores tool implementations and metadata
241
+ - `registry/interface.py`: Defines the registry interface
242
+ - `registry/providers/memory.py`: In-memory implementation
243
+ - `registry/providers/redis.py`: Redis-backed implementation
244
+
245
+ 2. **Models**: Core data structures
246
+ - `models/tool_call.py`: Represents a tool call from an LLM
247
+ - `models/tool_result.py`: Represents the result of a tool execution
248
+
249
+ 3. **Execution**: Tool execution strategies and wrappers
250
+ - `execution/tool_executor.py`: Main executor interface
251
+ - `execution/inprocess_strategy.py`: Same-process execution
252
+ - `execution/subprocess_strategy.py`: Isolated process execution
253
+ - `execution/wrappers/`: Enhanced executors (caching, retries, etc.)
254
+
255
+ 4. **Plugins**: Extensible plugin system
256
+ - `plugins/discovery.py`: Plugin discovery mechanism
257
+ - `plugins/parsers/`: Parser plugins for different formats
258
+
259
+ 5. **Utils**: Shared utilities
260
+ - `utils/logging.py`: Structured logging system
261
+ - `utils/validation.py`: Argument and result validation
262
+
263
+ 6. **Core**: Central components
264
+ - `core/processor.py`: Main processor for handling tool calls
265
+ - `core/exceptions.py`: Exception hierarchy
266
+
267
+ ## Examples
268
+
269
+ The repository includes several example scripts:
270
+
271
+ - `examples/tool_registry_example.py`: Demonstrates tool registration and usage
272
+ - `examples/plugin_example.py`: Shows how to create and use custom plugins
273
+ - `examples/tool_calling_example_usage.py`: Basic example demonstrating tool execution
274
+
275
+ Run examples with:
276
+
277
+ ```bash
278
+ # Registry example
279
+ uv run examples/tool_registry_example.py
280
+
281
+ # Plugin example
282
+ uv run examples/plugin_example.py
283
+
284
+ # Tool execution example
285
+ uv run examples/tool_calling_example_usage.py
286
+
287
+ # Enable debug logging
288
+ LOGLEVEL=DEBUG uv run examples/tool_calling_example_usage.py
289
+ ```
290
+
291
+ ## License
292
+
293
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,37 @@
1
+ chuk_tool_processor/__init__.py,sha256=a4pDi8hta4hjhijLGcv3vlWL8iu3F9EynkmB3si7-hg,33
2
+ chuk_tool_processor/core/__init__.py,sha256=slM7pZna88tyZrF3KtN22ApYyCqGNt5Yscv-knsLOOA,38
3
+ chuk_tool_processor/core/exceptions.py,sha256=h4zL1jpCY1Ud1wT8xDeMxZ8GR8ttmkObcv36peUHJEA,1571
4
+ chuk_tool_processor/core/processor.py,sha256=wRVFLHMWikanFb8Zo8Hdp1XDnBmxzVYaNdWYnCyKI44,10164
5
+ chuk_tool_processor/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ chuk_tool_processor/execution/tool_executor.py,sha256=e1EHE-744uJuB1XeZZF_6VT25Yg1RCd8XI3v8uOrOSo,1794
7
+ chuk_tool_processor/execution/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ chuk_tool_processor/execution/strategies/inprocess_strategy.py,sha256=i0wsauDOij0w5VP2chmSx5EOPXsuPcDLM7bQ8-CYLIM,7305
9
+ chuk_tool_processor/execution/strategies/subprocess_strategy.py,sha256=Ev3brLfKF6ylH0Ck20ahML9_miFq9vu33DeER2ntf2k,3792
10
+ chuk_tool_processor/execution/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ chuk_tool_processor/execution/wrappers/caching.py,sha256=dA2OULPQ9xCZj-r3ev5LtsCDFDPgoz8tr70YCX5A4Wg,7714
12
+ chuk_tool_processor/execution/wrappers/rate_limiting.py,sha256=pFqD1vLzOtJzsWzpEI7J786gOAbdFY0gVeiO7ElBXbA,4991
13
+ chuk_tool_processor/execution/wrappers/retry.py,sha256=tRIuT5iNAYUY3r9y3shouWCxJZB5VONkBC9qPBaaVdc,6386
14
+ chuk_tool_processor/models/__init__.py,sha256=TC__rdVa0lQsmJHM_hbLDPRgToa_pQT_UxRcPZk6iVw,40
15
+ chuk_tool_processor/models/execution_strategy.py,sha256=s4yGAlVn_tqzpaqQPTTociOWhu6fxQWsd9BxoMhb4yU,511
16
+ chuk_tool_processor/models/tool_call.py,sha256=RZOnx2YczkJN6ym2PLiI4CRzP2qU_5hpMtHxMcFOxY4,298
17
+ chuk_tool_processor/models/tool_result.py,sha256=fqHuRC8bLek1PAwyhLOoKjRCLhpSm-mhDgLpsItjZ60,1532
18
+ chuk_tool_processor/plugins/__init__.py,sha256=QO_ipvlsWG-rbaqGzj6-YtD7zi7Lx26hw-Cqha4MuWc,48
19
+ chuk_tool_processor/plugins/discovery.py,sha256=K0sncdDmswH2tS_k-siJYLfEHzwMlU4iQVPX5kb6SZU,6370
20
+ chuk_tool_processor/plugins/parsers/__init__.py,sha256=QO_ipvlsWG-rbaqGzj6-YtD7zi7Lx26hw-Cqha4MuWc,48
21
+ chuk_tool_processor/plugins/parsers/function_call_tool.py,sha256=h7hbw25j-H961Pe7VVM0tSoPyP0IaprETmtDKSB2Teg,3945
22
+ chuk_tool_processor/plugins/parsers/json_tool.py,sha256=20maA7jyEe6NFY7Efg_HqKhBkIQ5JhuAIKNfvjytEds,573
23
+ chuk_tool_processor/plugins/parsers/xml_tool.py,sha256=QhywgQFEfticAf6LOfMTgzHN37lgZBqLFGXzNqGK5v8,1255
24
+ chuk_tool_processor/registry/__init__.py,sha256=mLV6J2e7dcPva7S2gE6X3G1OElTXO0iTMzDC6-jL1SI,647
25
+ chuk_tool_processor/registry/decorators.py,sha256=WecmzWK2RliMO0xmWEifj7xBqACoGfm2rz1hxcgtkrI,1346
26
+ chuk_tool_processor/registry/interface.py,sha256=40KFbMKzjnwf6iki9aeWBx5c3Dq3Tadr78y-Ko-IYsM,2299
27
+ chuk_tool_processor/registry/metadata.py,sha256=zoSv8QnncqMtvEo7nj_pGKKQohw6maBVDiInXBoNaxY,1744
28
+ chuk_tool_processor/registry/provider.py,sha256=lsolfDqKelvxEkZR_qbHPe9iDZFHobnk5sm_LvSTdTU,1318
29
+ chuk_tool_processor/registry/providers/__init__.py,sha256=_0dg4YhyfAV0TXuR_i4ewXPU8fY7odFd1RJWCmHIXmk,1326
30
+ chuk_tool_processor/registry/providers/memory.py,sha256=Re5B0PPRETJOUVz6_gwMEJDBmYQulTtqkfnZacgxC8s,5552
31
+ chuk_tool_processor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ chuk_tool_processor/utils/logging.py,sha256=cr3N3EMr7EqLj6SW-N-i4LJTegodUDtl3BxGvZbc26Q,7846
33
+ chuk_tool_processor/utils/validation.py,sha256=kincqcVrYl2XUU3BHwqPAcQa6L-Cx0Oees4L8qwOK54,5994
34
+ chuk_tool_processor-0.1.0.dist-info/METADATA,sha256=SRLHsrpXRZeFHvWYu3XWtWOgKaoXG6l1g9VhjSBVskM,9221
35
+ chuk_tool_processor-0.1.0.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
36
+ chuk_tool_processor-0.1.0.dist-info/top_level.txt,sha256=7lTsnuRx4cOW4U2sNJWNxl4ZTt_J1ndkjTbj3pHPY5M,20
37
+ chuk_tool_processor-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (79.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ chuk_tool_processor