chuk-tool-processor 0.13__tar.gz → 0.14__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.14/PKG-INFO +402 -0
- chuk_tool_processor-0.14/README.md +370 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/pyproject.toml +1 -1
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/__init__.py +32 -2
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/core/__init__.py +16 -0
- chuk_tool_processor-0.14/src/chuk_tool_processor/core/context.py +439 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/core/processor.py +83 -12
- chuk_tool_processor-0.14/src/chuk_tool_processor/execution/__init__.py +23 -0
- chuk_tool_processor-0.14/src/chuk_tool_processor/execution/bulkhead.py +453 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/http_streamable_transport.py +0 -1
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/__init__.py +2 -1
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/provider.py +68 -0
- chuk_tool_processor-0.14/src/chuk_tool_processor.egg-info/PKG-INFO +402 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor.egg-info/SOURCES.txt +6 -1
- chuk_tool_processor-0.14/tests/test_bulkhead.py +498 -0
- chuk_tool_processor-0.14/tests/test_execution_context.py +354 -0
- chuk_tool_processor-0.14/tests/test_scoped_registry.py +245 -0
- chuk_tool_processor-0.13/PKG-INFO +0 -2727
- chuk_tool_processor-0.13/README.md +0 -2695
- chuk_tool_processor-0.13/src/chuk_tool_processor/execution/__init__.py +0 -6
- chuk_tool_processor-0.13/src/chuk_tool_processor.egg-info/PKG-INFO +0 -2727
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/setup.cfg +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/core/exceptions.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/code_sandbox.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/strategies/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/strategies/inprocess_strategy.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/strategies/subprocess_strategy.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/tool_executor.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/wrappers/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/wrappers/caching.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/wrappers/circuit_breaker.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/wrappers/rate_limiting.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/execution/wrappers/retry.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/logging/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/logging/context.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/logging/formatter.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/logging/helpers.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/logging/metrics.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/mcp_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/models.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/register_mcp_tools.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/setup_mcp_http_streamable.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/setup_mcp_sse.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/setup_mcp_stdio.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/stream_manager.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/base_transport.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/models.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/sse_transport.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/mcp/transport/stdio_transport.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/execution_strategy.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/streaming_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/tool_call.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/tool_export_mixin.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/tool_result.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/tool_spec.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/models/validated_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/observability/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/observability/metrics.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/observability/setup.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/observability/tracing.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/discovery.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/base.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/function_call_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/json_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/openai_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/plugins/parsers/xml_tool.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/py.typed +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/auto_register.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/decorators.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/interface.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/metadata.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/providers/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/providers/memory.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/registry/tool_export.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/utils/__init__.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/utils/fast_json.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor/utils/validation.py +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor.egg-info/dependency_links.txt +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor.egg-info/requires.txt +0 -0
- {chuk_tool_processor-0.13 → chuk_tool_processor-0.14}/src/chuk_tool_processor.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chuk-tool-processor
|
|
3
|
+
Version: 0.14
|
|
4
|
+
Summary: Async-native framework for registering, discovering, and executing tools referenced in LLM responses
|
|
5
|
+
Author-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
6
|
+
Maintainer-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: llm,tools,async,ai,openai,mcp,model-context-protocol,tool-calling,function-calling
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Classifier: Framework :: AsyncIO
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: chuk-mcp>=0.9
|
|
24
|
+
Requires-Dist: dotenv>=0.9.9
|
|
25
|
+
Requires-Dist: psutil>=7.0.0
|
|
26
|
+
Requires-Dist: pydantic>=2.11.3
|
|
27
|
+
Requires-Dist: uuid>=1.30
|
|
28
|
+
Provides-Extra: fast-json
|
|
29
|
+
Requires-Dist: orjson<4,>=3.10.0; extra == "fast-json"
|
|
30
|
+
Provides-Extra: full
|
|
31
|
+
Requires-Dist: orjson<4,>=3.10.0; extra == "full"
|
|
32
|
+
|
|
33
|
+
# CHUK Tool Processor — Production-grade execution for LLM tool calls
|
|
34
|
+
|
|
35
|
+
[](https://pypi.org/project/chuk-tool-processor/)
|
|
36
|
+
[](https://pypi.org/project/chuk-tool-processor/)
|
|
37
|
+
[](LICENSE)
|
|
38
|
+
[](https://www.python.org/dev/peps/pep-0561/)
|
|
39
|
+
[](https://pypi.org/project/chuk-tool-processor/)
|
|
40
|
+
[](docs/OBSERVABILITY.md)
|
|
41
|
+
|
|
42
|
+
**Reliable tool execution for LLMs — timeouts, retries, caching, rate limits, circuit breakers, and MCP integration — in one composable layer.**
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## The Missing Layer for Reliable Tool Execution
|
|
47
|
+
|
|
48
|
+
LLMs are good at *calling* tools. The hard part is **executing** those tools reliably.
|
|
49
|
+
|
|
50
|
+
**CHUK Tool Processor:**
|
|
51
|
+
- Parses tool calls from any model (Anthropic XML, OpenAI `tool_calls`, JSON)
|
|
52
|
+
- Executes them with **timeouts, retries, caching, rate limits, circuit breaker, observability**
|
|
53
|
+
- Runs tools locally, in **isolated subprocesses**, or **remote via MCP**
|
|
54
|
+
|
|
55
|
+
Works with OpenAI, Anthropic, local models (Ollama/MLX/vLLM), and any framework (LangChain, LlamaIndex, custom).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Architecture
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
LLM Output
|
|
63
|
+
↓
|
|
64
|
+
CHUK Tool Processor
|
|
65
|
+
↓
|
|
66
|
+
┌──────────────┬────────────────────┐
|
|
67
|
+
│ Local Tools │ Remote Tools (MCP) │
|
|
68
|
+
└──────────────┴────────────────────┘
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**How it works internally:**
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
LLM Output
|
|
75
|
+
↓
|
|
76
|
+
Parsers (XML / OpenAI / JSON)
|
|
77
|
+
↓
|
|
78
|
+
┌─────────────────────────────┐
|
|
79
|
+
│ Execution Middleware │
|
|
80
|
+
│ (Applied in this order) │
|
|
81
|
+
│ • Cache │
|
|
82
|
+
│ • Rate Limit │
|
|
83
|
+
│ • Retry (with backoff) │
|
|
84
|
+
│ • Circuit Breaker │
|
|
85
|
+
│ • Bulkhead │
|
|
86
|
+
└─────────────────────────────┘
|
|
87
|
+
↓
|
|
88
|
+
Execution Strategy
|
|
89
|
+
┌──────────────────────┐
|
|
90
|
+
│ • InProcess │ ← Fast, trusted
|
|
91
|
+
│ • Isolated/Subprocess│ ← Safe, untrusted
|
|
92
|
+
│ • Remote via MCP │ ← Distributed
|
|
93
|
+
└──────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick Start
|
|
99
|
+
|
|
100
|
+
### Installation
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install chuk-tool-processor
|
|
104
|
+
|
|
105
|
+
# Or with uv (recommended)
|
|
106
|
+
uv pip install chuk-tool-processor
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 60-Second Example
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
import asyncio
|
|
113
|
+
from chuk_tool_processor import ToolProcessor, tool
|
|
114
|
+
|
|
115
|
+
@tool(name="calculator")
|
|
116
|
+
class Calculator:
|
|
117
|
+
async def execute(self, operation: str, a: float, b: float) -> dict:
|
|
118
|
+
ops = {"add": a + b, "multiply": a * b, "subtract": a - b}
|
|
119
|
+
return {"result": ops.get(operation, 0)}
|
|
120
|
+
|
|
121
|
+
async def main():
|
|
122
|
+
async with ToolProcessor(enable_caching=True, enable_retries=True) as p:
|
|
123
|
+
# Works with OpenAI, Anthropic, or JSON formats
|
|
124
|
+
result = await p.process('<tool name="calculator" args=\'{"operation": "multiply", "a": 15, "b": 23}\'/>')
|
|
125
|
+
print(result[0].result) # {'result': 345}
|
|
126
|
+
|
|
127
|
+
asyncio.run(main())
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**That's it.** You now have production-ready tool execution with timeouts, retries, and caching.
|
|
131
|
+
|
|
132
|
+
### Works with Any LLM Format
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# Anthropic XML format
|
|
136
|
+
anthropic_output = '<tool name="search" args=\'{"query": "Python"}\'/>'
|
|
137
|
+
|
|
138
|
+
# OpenAI tool_calls format
|
|
139
|
+
openai_output = {
|
|
140
|
+
"tool_calls": [{
|
|
141
|
+
"type": "function",
|
|
142
|
+
"function": {"name": "search", "arguments": '{"query": "Python"}'}
|
|
143
|
+
}]
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Direct JSON
|
|
147
|
+
json_output = [{"tool": "search", "arguments": {"query": "Python"}}]
|
|
148
|
+
|
|
149
|
+
# All work identically
|
|
150
|
+
results = await processor.process(anthropic_output)
|
|
151
|
+
results = await processor.process(openai_output)
|
|
152
|
+
results = await processor.process(json_output)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Key Features
|
|
158
|
+
|
|
159
|
+
### Production Reliability
|
|
160
|
+
|
|
161
|
+
| Feature | Description |
|
|
162
|
+
|---------|-------------|
|
|
163
|
+
| **Timeouts** | Every tool execution has proper timeout handling |
|
|
164
|
+
| **Retries** | Automatic retry with exponential backoff and jitter |
|
|
165
|
+
| **Rate Limiting** | Global and per-tool rate limits with sliding windows |
|
|
166
|
+
| **Caching** | Result caching with TTL and SHA256-based idempotency keys |
|
|
167
|
+
| **Circuit Breakers** | Prevent cascading failures with automatic recovery |
|
|
168
|
+
|
|
169
|
+
### Multi-Tenant & Isolation
|
|
170
|
+
|
|
171
|
+
| Feature | Description |
|
|
172
|
+
|---------|-------------|
|
|
173
|
+
| **Bulkheads** | Per-tool/namespace concurrency limits to prevent resource starvation |
|
|
174
|
+
| **Scoped Registries** | Isolated registries for multi-tenant apps and testing |
|
|
175
|
+
| **ExecutionContext** | Request-scoped metadata propagation (user, tenant, tracing, deadlines) |
|
|
176
|
+
| **Isolated Strategy** | Subprocess execution for untrusted code (zero crash blast radius) |
|
|
177
|
+
|
|
178
|
+
### Integration & Observability
|
|
179
|
+
|
|
180
|
+
| Feature | Description |
|
|
181
|
+
|---------|-------------|
|
|
182
|
+
| **Multi-Format Parsing** | XML (Anthropic), OpenAI `tool_calls`, JSON — all work automatically |
|
|
183
|
+
| **MCP Integration** | Connect to remote tools via HTTP Streamable, STDIO, SSE |
|
|
184
|
+
| **OpenTelemetry** | Distributed tracing with automatic span creation |
|
|
185
|
+
| **Prometheus** | Metrics for error rates, latency, cache hits, circuit breaker state |
|
|
186
|
+
| **Type Safety** | PEP 561 compliant with full mypy support |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Production Configuration
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
async with ToolProcessor(
|
|
194
|
+
# Execution settings
|
|
195
|
+
default_timeout=30.0,
|
|
196
|
+
max_concurrency=20,
|
|
197
|
+
|
|
198
|
+
# Reliability features
|
|
199
|
+
enable_caching=True,
|
|
200
|
+
cache_ttl=600,
|
|
201
|
+
enable_rate_limiting=True,
|
|
202
|
+
global_rate_limit=100,
|
|
203
|
+
tool_rate_limits={"expensive_api": (5, 60)}, # 5 req/min
|
|
204
|
+
enable_retries=True,
|
|
205
|
+
max_retries=3,
|
|
206
|
+
enable_circuit_breaker=True,
|
|
207
|
+
circuit_breaker_threshold=5,
|
|
208
|
+
|
|
209
|
+
# Multi-tenant isolation
|
|
210
|
+
enable_bulkhead=True,
|
|
211
|
+
bulkhead_config=BulkheadConfig(
|
|
212
|
+
default_limit=10,
|
|
213
|
+
tool_limits={"slow_api": 2},
|
|
214
|
+
),
|
|
215
|
+
) as processor:
|
|
216
|
+
# Execute with request context
|
|
217
|
+
ctx = ExecutionContext(
|
|
218
|
+
request_id="req-123",
|
|
219
|
+
user_id="user-456",
|
|
220
|
+
tenant_id="acme-corp",
|
|
221
|
+
)
|
|
222
|
+
results = await processor.process(llm_output, context=ctx)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## MCP Integration
|
|
228
|
+
|
|
229
|
+
Connect to remote tool servers using the [Model Context Protocol](https://modelcontextprotocol.io):
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
from chuk_tool_processor.mcp import setup_mcp_http_streamable
|
|
233
|
+
|
|
234
|
+
# Cloud services (Notion, etc.)
|
|
235
|
+
processor, manager = await setup_mcp_http_streamable(
|
|
236
|
+
servers=[{
|
|
237
|
+
"name": "notion",
|
|
238
|
+
"url": "https://mcp.notion.com/mcp",
|
|
239
|
+
"headers": {"Authorization": f"Bearer {token}"}
|
|
240
|
+
}],
|
|
241
|
+
namespace="notion",
|
|
242
|
+
enable_caching=True,
|
|
243
|
+
enable_retries=True
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# Use remote tools
|
|
247
|
+
results = await processor.process(
|
|
248
|
+
'<tool name="notion.search_pages" args=\'{"query": "docs"}\'/>'
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Transport Options:**
|
|
253
|
+
|
|
254
|
+
| Transport | Use Case | Example |
|
|
255
|
+
|-----------|----------|---------|
|
|
256
|
+
| **HTTP Streamable** | Cloud SaaS with OAuth | Notion, custom APIs |
|
|
257
|
+
| **STDIO** | Local tools, databases | SQLite, file systems |
|
|
258
|
+
| **SSE** | Legacy MCP servers | Atlassian |
|
|
259
|
+
|
|
260
|
+
See [MCP_INTEGRATION.md](docs/MCP_INTEGRATION.md) for complete examples with OAuth token refresh.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Observability
|
|
265
|
+
|
|
266
|
+
One-line setup for production monitoring:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from chuk_tool_processor.observability import setup_observability
|
|
270
|
+
|
|
271
|
+
setup_observability(
|
|
272
|
+
service_name="my-tool-service",
|
|
273
|
+
enable_tracing=True, # → OpenTelemetry traces
|
|
274
|
+
enable_metrics=True, # → Prometheus metrics at :9090/metrics
|
|
275
|
+
metrics_port=9090
|
|
276
|
+
)
|
|
277
|
+
# Every tool execution is now automatically traced and metered
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**What you get:**
|
|
281
|
+
- Distributed traces (Jaeger, Zipkin, any OTLP collector)
|
|
282
|
+
- Prometheus metrics (error rate, latency P50/P95/P99, cache hit rate)
|
|
283
|
+
- Circuit breaker state monitoring
|
|
284
|
+
- Zero code changes to your tools
|
|
285
|
+
|
|
286
|
+
See [OBSERVABILITY.md](docs/OBSERVABILITY.md) for complete setup guide.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Documentation
|
|
291
|
+
|
|
292
|
+
| Document | Description |
|
|
293
|
+
|----------|-------------|
|
|
294
|
+
| [**GETTING_STARTED.md**](docs/GETTING_STARTED.md) | Creating tools, using the processor, ValidatedTool, StreamingTool |
|
|
295
|
+
| [**CORE_CONCEPTS.md**](docs/CORE_CONCEPTS.md) | Registry, strategies, wrappers, parsers, MCP overview |
|
|
296
|
+
| [**PRODUCTION_PATTERNS.md**](docs/PRODUCTION_PATTERNS.md) | Bulkheads, scoped registries, ExecutionContext, parallel execution |
|
|
297
|
+
| [**MCP_INTEGRATION.md**](docs/MCP_INTEGRATION.md) | HTTP Streamable, STDIO, SSE, OAuth token refresh |
|
|
298
|
+
| [**ADVANCED_TOPICS.md**](docs/ADVANCED_TOPICS.md) | Deferred loading, code sandbox, isolated strategy, testing |
|
|
299
|
+
| [**CONFIGURATION.md**](docs/CONFIGURATION.md) | All config options and environment variables |
|
|
300
|
+
| [**OBSERVABILITY.md**](docs/OBSERVABILITY.md) | OpenTelemetry, Prometheus, metrics reference |
|
|
301
|
+
| [**ERRORS.md**](docs/ERRORS.md) | Error codes and handling patterns |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Examples
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Getting started
|
|
309
|
+
python examples/01_getting_started/hello_tool.py
|
|
310
|
+
|
|
311
|
+
# Production patterns (bulkheads, context, scoped registries)
|
|
312
|
+
python examples/02_production_features/production_patterns_demo.py
|
|
313
|
+
|
|
314
|
+
# Observability demo
|
|
315
|
+
python examples/02_production_features/observability_demo.py
|
|
316
|
+
|
|
317
|
+
# MCP integration
|
|
318
|
+
python examples/04_mcp_integration/stdio_echo.py
|
|
319
|
+
python examples/04_mcp_integration/notion_oauth.py
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
See [examples/](examples/) for 20+ working examples.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Compatibility
|
|
327
|
+
|
|
328
|
+
| Component | Supported |
|
|
329
|
+
|-----------|-----------|
|
|
330
|
+
| **Python** | 3.11, 3.12, 3.13 |
|
|
331
|
+
| **Platforms** | macOS, Linux, Windows |
|
|
332
|
+
| **LLM Providers** | OpenAI, Anthropic, Local models (Ollama, MLX, vLLM) |
|
|
333
|
+
| **MCP Transports** | HTTP Streamable, STDIO, SSE |
|
|
334
|
+
| **MCP Spec** | 2025-11-25, 2025-06-18, 2025-03-26 |
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Installation Options
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Core package
|
|
342
|
+
pip install chuk-tool-processor
|
|
343
|
+
|
|
344
|
+
# With observability (OpenTelemetry + Prometheus)
|
|
345
|
+
pip install chuk-tool-processor[observability]
|
|
346
|
+
|
|
347
|
+
# With MCP support
|
|
348
|
+
pip install chuk-tool-processor[mcp]
|
|
349
|
+
|
|
350
|
+
# With fast JSON (2-3x faster with orjson)
|
|
351
|
+
pip install chuk-tool-processor[fast-json]
|
|
352
|
+
|
|
353
|
+
# All extras
|
|
354
|
+
pip install chuk-tool-processor[all]
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## When to Use This
|
|
360
|
+
|
|
361
|
+
**Use CHUK Tool Processor when:**
|
|
362
|
+
- Your LLM calls tools or APIs
|
|
363
|
+
- You need retries, timeouts, caching, or rate limits
|
|
364
|
+
- You need to run untrusted tools safely
|
|
365
|
+
- Your tools are local or remote (MCP)
|
|
366
|
+
- You need multi-tenant isolation
|
|
367
|
+
- You want production-grade observability
|
|
368
|
+
|
|
369
|
+
**Don't use this if:**
|
|
370
|
+
- You want an agent framework (this is the execution layer, not the agent)
|
|
371
|
+
- You want conversation flow/memory orchestration
|
|
372
|
+
|
|
373
|
+
> **Not a framework.** If LangChain/LlamaIndex help decide *which* tool to call, CHUK Tool Processor makes sure the tool call **actually succeeds**.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Contributing
|
|
378
|
+
|
|
379
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
# Development setup
|
|
383
|
+
git clone https://github.com/chrishayuk/chuk-tool-processor.git
|
|
384
|
+
cd chuk-tool-processor
|
|
385
|
+
uv pip install -e ".[dev]"
|
|
386
|
+
|
|
387
|
+
# Run tests
|
|
388
|
+
make check
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## License
|
|
394
|
+
|
|
395
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Related Projects
|
|
400
|
+
|
|
401
|
+
- [chuk-mcp](https://github.com/chrishayuk/chuk-mcp) - Low-level MCP protocol client
|
|
402
|
+
- [Model Context Protocol](https://modelcontextprotocol.io) - MCP specification
|