chuk-tool-processor 0.15__tar.gz → 0.17__tar.gz
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.
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/PKG-INFO +106 -1
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/README.md +100 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/pyproject.toml +14 -1
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/__init__.py +14 -0
- chuk_tool_processor-0.17/src/chuk_tool_processor/config.py +576 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/core/__init__.py +15 -1
- chuk_tool_processor-0.17/src/chuk_tool_processor/core/exceptions.py +691 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/strategies/subprocess_strategy.py +50 -5
- chuk_tool_processor-0.17/src/chuk_tool_processor/execution/wrappers/__init__.py +107 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/wrappers/circuit_breaker.py +3 -3
- chuk_tool_processor-0.17/src/chuk_tool_processor/execution/wrappers/factory.py +503 -0
- chuk_tool_processor-0.17/src/chuk_tool_processor/execution/wrappers/redis_circuit_breaker.py +634 -0
- chuk_tool_processor-0.17/src/chuk_tool_processor/execution/wrappers/redis_rate_limiting.py +328 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/wrappers/retry.py +10 -3
- chuk_tool_processor-0.17/src/chuk_tool_processor/models/tool_result.py +300 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/decorators.py +3 -3
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/providers/__init__.py +24 -3
- chuk_tool_processor-0.17/src/chuk_tool_processor/registry/providers/redis.py +555 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor.egg-info/PKG-INFO +106 -1
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor.egg-info/SOURCES.txt +5 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor.egg-info/requires.txt +7 -0
- chuk_tool_processor-0.15/src/chuk_tool_processor/core/exceptions.py +0 -308
- chuk_tool_processor-0.15/src/chuk_tool_processor/execution/wrappers/__init__.py +0 -42
- chuk_tool_processor-0.15/src/chuk_tool_processor/models/tool_result.py +0 -120
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/setup.cfg +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/core/context.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/core/processor.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/bulkhead.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/code_sandbox.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/strategies/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/strategies/inprocess_strategy.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/tool_executor.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/wrappers/caching.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/execution/wrappers/rate_limiting.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/logging/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/logging/context.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/logging/formatter.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/logging/helpers.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/logging/metrics.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/mcp_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/middleware.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/models.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/register_mcp_tools.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/setup_mcp_http_streamable.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/setup_mcp_sse.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/setup_mcp_stdio.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/stream_manager.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/base_transport.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/http_streamable_transport.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/models.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/sse_transport.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/mcp/transport/stdio_transport.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/execution_strategy.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/return_order.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/streaming_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/tool_call.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/tool_export_mixin.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/tool_spec.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/models/validated_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/observability/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/observability/metrics.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/observability/setup.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/observability/tracing.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/discovery.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/base.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/function_call_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/json_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/openai_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/plugins/parsers/xml_tool.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/py.typed +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/auto_register.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/interface.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/metadata.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/provider.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/providers/memory.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/registry/tool_export.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/scheduling/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/scheduling/greedy_dag.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/scheduling/policy.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/scheduling/types.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/utils/__init__.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/utils/fast_json.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor/utils/validation.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor.egg-info/dependency_links.txt +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/src/chuk_tool_processor.egg-info/top_level.txt +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/tests/test_bulkhead.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/tests/test_execution_context.py +0 -0
- {chuk_tool_processor-0.15 → chuk_tool_processor-0.17}/tests/test_scoped_registry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chuk-tool-processor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17
|
|
4
4
|
Summary: Async-native framework for registering, discovering, and executing tools referenced in LLM responses
|
|
5
5
|
Author-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
6
6
|
Maintainer-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
@@ -27,8 +27,13 @@ Requires-Dist: pydantic>=2.11.3
|
|
|
27
27
|
Requires-Dist: uuid>=1.30
|
|
28
28
|
Provides-Extra: fast-json
|
|
29
29
|
Requires-Dist: orjson<4,>=3.10.0; extra == "fast-json"
|
|
30
|
+
Provides-Extra: redis
|
|
31
|
+
Requires-Dist: redis[hiredis]<6,>=5.0.0; extra == "redis"
|
|
30
32
|
Provides-Extra: full
|
|
31
33
|
Requires-Dist: orjson<4,>=3.10.0; extra == "full"
|
|
34
|
+
Provides-Extra: all
|
|
35
|
+
Requires-Dist: orjson<4,>=3.10.0; extra == "all"
|
|
36
|
+
Requires-Dist: redis[hiredis]<6,>=5.0.0; extra == "all"
|
|
32
37
|
|
|
33
38
|
# CHUK Tool Processor — A Tool Execution Runtime for AI Systems
|
|
34
39
|
|
|
@@ -182,6 +187,7 @@ results = await processor.process(json_output)
|
|
|
182
187
|
| **Rate Limiting** | Global and per-tool rate limits with sliding windows |
|
|
183
188
|
| **Caching** | Result caching with TTL and SHA256-based idempotency keys |
|
|
184
189
|
| **Circuit Breakers** | Prevent cascading failures with automatic recovery |
|
|
190
|
+
| **Structured Errors** | Machine-readable error categories with retry hints for planners |
|
|
185
191
|
|
|
186
192
|
### Multi-Tenant & Isolation
|
|
187
193
|
|
|
@@ -192,6 +198,7 @@ results = await processor.process(json_output)
|
|
|
192
198
|
| **Scoped Registries** | Isolated registries for multi-tenant apps and testing |
|
|
193
199
|
| **ExecutionContext** | Request-scoped metadata propagation (user, tenant, tracing, deadlines) |
|
|
194
200
|
| **Isolated Strategy** | Subprocess execution for untrusted code (zero crash blast radius) |
|
|
201
|
+
| **Redis Registry** | Distributed tool registry for multi-process/multi-machine deployments |
|
|
195
202
|
|
|
196
203
|
### Advanced Scheduling
|
|
197
204
|
|
|
@@ -365,6 +372,68 @@ result = await middleware.call_tool("notion.search", {"query": "docs"})
|
|
|
365
372
|
|
|
366
373
|
---
|
|
367
374
|
|
|
375
|
+
## Distributed Deployments (Redis)
|
|
376
|
+
|
|
377
|
+
For multi-process or multi-machine deployments, configure Redis backends via environment variables:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
# Enable Redis for everything
|
|
381
|
+
export CHUK_REGISTRY_BACKEND=redis
|
|
382
|
+
export CHUK_RESILIENCE_BACKEND=redis
|
|
383
|
+
export CHUK_REDIS_URL=redis://localhost:6379/0
|
|
384
|
+
|
|
385
|
+
# Enable resilience features
|
|
386
|
+
export CHUK_CIRCUIT_BREAKER_ENABLED=true
|
|
387
|
+
export CHUK_RATE_LIMIT_ENABLED=true
|
|
388
|
+
export CHUK_RATE_LIMIT_GLOBAL=100
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
from chuk_tool_processor import ProcessorConfig
|
|
393
|
+
|
|
394
|
+
# Load from environment and create fully-configured processor
|
|
395
|
+
config = ProcessorConfig.from_env()
|
|
396
|
+
processor = await config.create_processor()
|
|
397
|
+
|
|
398
|
+
async with processor:
|
|
399
|
+
results = await processor.process(llm_output)
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Or configure programmatically:
|
|
403
|
+
|
|
404
|
+
```python
|
|
405
|
+
from chuk_tool_processor import ProcessorConfig, RegistryConfig, BackendType
|
|
406
|
+
from chuk_tool_processor.config import CircuitBreakerConfig, RateLimitConfig
|
|
407
|
+
|
|
408
|
+
config = ProcessorConfig(
|
|
409
|
+
# Registry and resilience use Redis
|
|
410
|
+
registry=RegistryConfig(backend=BackendType.REDIS),
|
|
411
|
+
resilience_backend=BackendType.REDIS,
|
|
412
|
+
redis_url="redis://localhost:6379/0",
|
|
413
|
+
|
|
414
|
+
# Enable features
|
|
415
|
+
circuit_breaker=CircuitBreakerConfig(enabled=True, failure_threshold=5),
|
|
416
|
+
rate_limit=RateLimitConfig(enabled=True, global_limit=100),
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
processor = await config.create_processor()
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Key features:**
|
|
423
|
+
- **Distributed registry**: Tool metadata shared across processes
|
|
424
|
+
- **Distributed circuit breaker**: Failure counts shared (prevents cascading failures across instances)
|
|
425
|
+
- **Distributed rate limiting**: Global limits enforced across all instances
|
|
426
|
+
- **Multi-tenant isolation**: Key prefixes isolate data per tenant
|
|
427
|
+
|
|
428
|
+
**Installation:**
|
|
429
|
+
```bash
|
|
430
|
+
pip install chuk-tool-processor[redis] # or: uv add chuk-tool-processor[redis]
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
See [examples/02_production_features/distributed_config_demo.py](examples/02_production_features/distributed_config_demo.py) for a complete example.
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
368
437
|
## Observability
|
|
369
438
|
|
|
370
439
|
One-line setup for production monitoring:
|
|
@@ -391,6 +460,30 @@ See [OBSERVABILITY.md](docs/OBSERVABILITY.md) for complete setup guide.
|
|
|
391
460
|
|
|
392
461
|
---
|
|
393
462
|
|
|
463
|
+
## Structured Error Handling
|
|
464
|
+
|
|
465
|
+
Errors include machine-readable categories and retry hints for planner decision-making:
|
|
466
|
+
|
|
467
|
+
```python
|
|
468
|
+
from chuk_tool_processor.core.exceptions import ErrorCategory
|
|
469
|
+
|
|
470
|
+
results = await processor.process(llm_output)
|
|
471
|
+
for result in results:
|
|
472
|
+
if result.error_info:
|
|
473
|
+
match result.error_info.category:
|
|
474
|
+
case ErrorCategory.RATE_LIMIT:
|
|
475
|
+
await asyncio.sleep(result.retry_after_ms / 1000)
|
|
476
|
+
return await retry()
|
|
477
|
+
case ErrorCategory.CIRCUIT_OPEN:
|
|
478
|
+
return await use_fallback_tool()
|
|
479
|
+
case _ if not result.retryable:
|
|
480
|
+
return await report_permanent_failure()
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
394
487
|
## Documentation
|
|
395
488
|
|
|
396
489
|
| Document | Description |
|
|
@@ -421,6 +514,15 @@ python examples/02_production_features/production_patterns_demo.py
|
|
|
421
514
|
# Runtime features (return order, pattern bulkheads, scheduling)
|
|
422
515
|
python examples/02_production_features/runtime_features_demo.py
|
|
423
516
|
|
|
517
|
+
# Structured error handling for planners
|
|
518
|
+
python examples/02_production_features/structured_errors_demo.py
|
|
519
|
+
|
|
520
|
+
# Redis registry for distributed deployments
|
|
521
|
+
python examples/02_production_features/redis_registry_demo.py
|
|
522
|
+
|
|
523
|
+
# Distributed configuration (Redis registry + resilience)
|
|
524
|
+
python examples/02_production_features/distributed_config_demo.py
|
|
525
|
+
|
|
424
526
|
# Observability demo
|
|
425
527
|
python examples/02_production_features/observability_demo.py
|
|
426
528
|
|
|
@@ -458,6 +560,9 @@ pip install chuk-tool-processor[observability]
|
|
|
458
560
|
# With MCP support
|
|
459
561
|
pip install chuk-tool-processor[mcp]
|
|
460
562
|
|
|
563
|
+
# With Redis registry (distributed deployments)
|
|
564
|
+
pip install chuk-tool-processor[redis]
|
|
565
|
+
|
|
461
566
|
# With fast JSON (2-3x faster with orjson)
|
|
462
567
|
pip install chuk-tool-processor[fast-json]
|
|
463
568
|
|
|
@@ -150,6 +150,7 @@ results = await processor.process(json_output)
|
|
|
150
150
|
| **Rate Limiting** | Global and per-tool rate limits with sliding windows |
|
|
151
151
|
| **Caching** | Result caching with TTL and SHA256-based idempotency keys |
|
|
152
152
|
| **Circuit Breakers** | Prevent cascading failures with automatic recovery |
|
|
153
|
+
| **Structured Errors** | Machine-readable error categories with retry hints for planners |
|
|
153
154
|
|
|
154
155
|
### Multi-Tenant & Isolation
|
|
155
156
|
|
|
@@ -160,6 +161,7 @@ results = await processor.process(json_output)
|
|
|
160
161
|
| **Scoped Registries** | Isolated registries for multi-tenant apps and testing |
|
|
161
162
|
| **ExecutionContext** | Request-scoped metadata propagation (user, tenant, tracing, deadlines) |
|
|
162
163
|
| **Isolated Strategy** | Subprocess execution for untrusted code (zero crash blast radius) |
|
|
164
|
+
| **Redis Registry** | Distributed tool registry for multi-process/multi-machine deployments |
|
|
163
165
|
|
|
164
166
|
### Advanced Scheduling
|
|
165
167
|
|
|
@@ -333,6 +335,68 @@ result = await middleware.call_tool("notion.search", {"query": "docs"})
|
|
|
333
335
|
|
|
334
336
|
---
|
|
335
337
|
|
|
338
|
+
## Distributed Deployments (Redis)
|
|
339
|
+
|
|
340
|
+
For multi-process or multi-machine deployments, configure Redis backends via environment variables:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Enable Redis for everything
|
|
344
|
+
export CHUK_REGISTRY_BACKEND=redis
|
|
345
|
+
export CHUK_RESILIENCE_BACKEND=redis
|
|
346
|
+
export CHUK_REDIS_URL=redis://localhost:6379/0
|
|
347
|
+
|
|
348
|
+
# Enable resilience features
|
|
349
|
+
export CHUK_CIRCUIT_BREAKER_ENABLED=true
|
|
350
|
+
export CHUK_RATE_LIMIT_ENABLED=true
|
|
351
|
+
export CHUK_RATE_LIMIT_GLOBAL=100
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
from chuk_tool_processor import ProcessorConfig
|
|
356
|
+
|
|
357
|
+
# Load from environment and create fully-configured processor
|
|
358
|
+
config = ProcessorConfig.from_env()
|
|
359
|
+
processor = await config.create_processor()
|
|
360
|
+
|
|
361
|
+
async with processor:
|
|
362
|
+
results = await processor.process(llm_output)
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Or configure programmatically:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
from chuk_tool_processor import ProcessorConfig, RegistryConfig, BackendType
|
|
369
|
+
from chuk_tool_processor.config import CircuitBreakerConfig, RateLimitConfig
|
|
370
|
+
|
|
371
|
+
config = ProcessorConfig(
|
|
372
|
+
# Registry and resilience use Redis
|
|
373
|
+
registry=RegistryConfig(backend=BackendType.REDIS),
|
|
374
|
+
resilience_backend=BackendType.REDIS,
|
|
375
|
+
redis_url="redis://localhost:6379/0",
|
|
376
|
+
|
|
377
|
+
# Enable features
|
|
378
|
+
circuit_breaker=CircuitBreakerConfig(enabled=True, failure_threshold=5),
|
|
379
|
+
rate_limit=RateLimitConfig(enabled=True, global_limit=100),
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
processor = await config.create_processor()
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Key features:**
|
|
386
|
+
- **Distributed registry**: Tool metadata shared across processes
|
|
387
|
+
- **Distributed circuit breaker**: Failure counts shared (prevents cascading failures across instances)
|
|
388
|
+
- **Distributed rate limiting**: Global limits enforced across all instances
|
|
389
|
+
- **Multi-tenant isolation**: Key prefixes isolate data per tenant
|
|
390
|
+
|
|
391
|
+
**Installation:**
|
|
392
|
+
```bash
|
|
393
|
+
pip install chuk-tool-processor[redis] # or: uv add chuk-tool-processor[redis]
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
See [examples/02_production_features/distributed_config_demo.py](examples/02_production_features/distributed_config_demo.py) for a complete example.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
336
400
|
## Observability
|
|
337
401
|
|
|
338
402
|
One-line setup for production monitoring:
|
|
@@ -359,6 +423,30 @@ See [OBSERVABILITY.md](docs/OBSERVABILITY.md) for complete setup guide.
|
|
|
359
423
|
|
|
360
424
|
---
|
|
361
425
|
|
|
426
|
+
## Structured Error Handling
|
|
427
|
+
|
|
428
|
+
Errors include machine-readable categories and retry hints for planner decision-making:
|
|
429
|
+
|
|
430
|
+
```python
|
|
431
|
+
from chuk_tool_processor.core.exceptions import ErrorCategory
|
|
432
|
+
|
|
433
|
+
results = await processor.process(llm_output)
|
|
434
|
+
for result in results:
|
|
435
|
+
if result.error_info:
|
|
436
|
+
match result.error_info.category:
|
|
437
|
+
case ErrorCategory.RATE_LIMIT:
|
|
438
|
+
await asyncio.sleep(result.retry_after_ms / 1000)
|
|
439
|
+
return await retry()
|
|
440
|
+
case ErrorCategory.CIRCUIT_OPEN:
|
|
441
|
+
return await use_fallback_tool()
|
|
442
|
+
case _ if not result.retryable:
|
|
443
|
+
return await report_permanent_failure()
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
362
450
|
## Documentation
|
|
363
451
|
|
|
364
452
|
| Document | Description |
|
|
@@ -389,6 +477,15 @@ python examples/02_production_features/production_patterns_demo.py
|
|
|
389
477
|
# Runtime features (return order, pattern bulkheads, scheduling)
|
|
390
478
|
python examples/02_production_features/runtime_features_demo.py
|
|
391
479
|
|
|
480
|
+
# Structured error handling for planners
|
|
481
|
+
python examples/02_production_features/structured_errors_demo.py
|
|
482
|
+
|
|
483
|
+
# Redis registry for distributed deployments
|
|
484
|
+
python examples/02_production_features/redis_registry_demo.py
|
|
485
|
+
|
|
486
|
+
# Distributed configuration (Redis registry + resilience)
|
|
487
|
+
python examples/02_production_features/distributed_config_demo.py
|
|
488
|
+
|
|
392
489
|
# Observability demo
|
|
393
490
|
python examples/02_production_features/observability_demo.py
|
|
394
491
|
|
|
@@ -426,6 +523,9 @@ pip install chuk-tool-processor[observability]
|
|
|
426
523
|
# With MCP support
|
|
427
524
|
pip install chuk-tool-processor[mcp]
|
|
428
525
|
|
|
526
|
+
# With Redis registry (distributed deployments)
|
|
527
|
+
pip install chuk-tool-processor[redis]
|
|
528
|
+
|
|
429
529
|
# With fast JSON (2-3x faster with orjson)
|
|
430
530
|
pip install chuk-tool-processor[fast-json]
|
|
431
531
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "chuk-tool-processor"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.17"
|
|
8
8
|
description = "Async-native framework for registering, discovering, and executing tools referenced in LLM responses"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -55,11 +55,22 @@ fast-json = [
|
|
|
55
55
|
"orjson>=3.10.0,<4",
|
|
56
56
|
]
|
|
57
57
|
|
|
58
|
+
# Redis registry for distributed deployments
|
|
59
|
+
redis = [
|
|
60
|
+
"redis[hiredis]>=5.0.0,<6",
|
|
61
|
+
]
|
|
62
|
+
|
|
58
63
|
# Full feature set with performance optimizations
|
|
59
64
|
full = [
|
|
60
65
|
"orjson>=3.10.0,<4",
|
|
61
66
|
]
|
|
62
67
|
|
|
68
|
+
# All extras combined
|
|
69
|
+
all = [
|
|
70
|
+
"orjson>=3.10.0,<4",
|
|
71
|
+
"redis[hiredis]>=5.0.0,<6",
|
|
72
|
+
]
|
|
73
|
+
|
|
63
74
|
# Tell setuptools to look in src/ for your a2a package
|
|
64
75
|
[tool.setuptools.packages.find]
|
|
65
76
|
where = ["src"]
|
|
@@ -93,6 +104,8 @@ dev = [
|
|
|
93
104
|
"pre-commit>=3.8.0",
|
|
94
105
|
"coverage[toml]>=7.6.0",
|
|
95
106
|
"orjson>=3.10.0",
|
|
107
|
+
"redis[hiredis]>=5.0.0,<6",
|
|
108
|
+
"fakeredis[lua]>=2.32.1",
|
|
96
109
|
]
|
|
97
110
|
|
|
98
111
|
observability = [
|
|
@@ -26,6 +26,14 @@ from typing import TYPE_CHECKING
|
|
|
26
26
|
__version__ = "0.9.7"
|
|
27
27
|
|
|
28
28
|
# Core processor and context
|
|
29
|
+
# Configuration
|
|
30
|
+
from chuk_tool_processor.config import (
|
|
31
|
+
BackendType,
|
|
32
|
+
ProcessorConfig,
|
|
33
|
+
RegistryConfig,
|
|
34
|
+
ResilienceBackend,
|
|
35
|
+
create_executor,
|
|
36
|
+
)
|
|
29
37
|
from chuk_tool_processor.core.context import (
|
|
30
38
|
ContextHeader,
|
|
31
39
|
ContextKey,
|
|
@@ -151,6 +159,12 @@ __all__ = [
|
|
|
151
159
|
"setup_mcp_stdio",
|
|
152
160
|
"setup_mcp_sse",
|
|
153
161
|
"setup_mcp_http_streamable",
|
|
162
|
+
# Configuration
|
|
163
|
+
"BackendType",
|
|
164
|
+
"ProcessorConfig",
|
|
165
|
+
"RegistryConfig",
|
|
166
|
+
"ResilienceBackend",
|
|
167
|
+
"create_executor",
|
|
154
168
|
]
|
|
155
169
|
|
|
156
170
|
# Type checking exports (documentation only)
|