chuk-tool-processor 0.17__tar.gz → 0.19__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.17 → chuk_tool_processor-0.19}/PKG-INFO +124 -1
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/README.md +123 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/pyproject.toml +1 -1
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/__init__.py +172 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/discovery/__init__.py +77 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/discovery/dynamic_provider.py +629 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/discovery/search.py +883 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/discovery/searchable.py +97 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/discovery/synonyms.py +752 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/__init__.py +7 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/execution/wrappers/observable.py +417 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/__init__.py +246 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/assumption_trace.py +445 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/base.py +140 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/budget.py +201 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/chain.py +275 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/concurrency.py +208 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/contract_guard.py +250 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/models.py +202 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/network_policy.py +306 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/output_size.py +290 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/per_tool.py +121 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/plan_shape.py +349 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/precondition.py +177 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/provenance.py +276 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/retry_safety.py +335 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/runaway.py +129 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/saturation.py +215 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/schema_strictness.py +350 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/sensitive_data.py +283 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/side_effect.py +273 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/timeout_budget.py +261 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/guards/unresolved.py +139 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/models/__init__.py +94 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/models/execution_span.py +651 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/models/execution_trace.py +571 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/models/sandbox_policy.py +552 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/models/tool_contract.py +552 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/tool_spec.py +80 -1
- chuk_tool_processor-0.19/src/chuk_tool_processor/observability/__init__.py +68 -0
- chuk_tool_processor-0.19/src/chuk_tool_processor/observability/trace_sink.py +677 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor.egg-info/PKG-INFO +124 -1
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor.egg-info/SOURCES.txt +33 -0
- chuk_tool_processor-0.17/src/chuk_tool_processor/models/__init__.py +0 -21
- chuk_tool_processor-0.17/src/chuk_tool_processor/observability/__init__.py +0 -30
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/setup.cfg +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/config.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/core/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/core/context.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/core/exceptions.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/core/processor.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/bulkhead.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/code_sandbox.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/strategies/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/strategies/inprocess_strategy.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/strategies/subprocess_strategy.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/tool_executor.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/caching.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/circuit_breaker.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/factory.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/rate_limiting.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/redis_circuit_breaker.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/redis_rate_limiting.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/execution/wrappers/retry.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/logging/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/logging/context.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/logging/formatter.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/logging/helpers.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/logging/metrics.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/mcp_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/middleware.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/models.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/register_mcp_tools.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/setup_mcp_http_streamable.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/setup_mcp_sse.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/setup_mcp_stdio.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/stream_manager.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/base_transport.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/http_streamable_transport.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/models.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/sse_transport.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/mcp/transport/stdio_transport.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/execution_strategy.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/return_order.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/streaming_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/tool_call.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/tool_export_mixin.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/tool_result.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/models/validated_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/observability/metrics.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/observability/setup.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/observability/tracing.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/discovery.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/base.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/function_call_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/json_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/openai_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/plugins/parsers/xml_tool.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/py.typed +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/auto_register.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/decorators.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/interface.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/metadata.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/provider.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/providers/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/providers/memory.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/providers/redis.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/registry/tool_export.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/scheduling/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/scheduling/greedy_dag.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/scheduling/policy.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/scheduling/types.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/utils/__init__.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/utils/fast_json.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor/utils/validation.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor.egg-info/dependency_links.txt +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor.egg-info/requires.txt +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/src/chuk_tool_processor.egg-info/top_level.txt +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/tests/test_bulkhead.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/tests/test_execution_context.py +0 -0
- {chuk_tool_processor-0.17 → chuk_tool_processor-0.19}/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.19
|
|
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>
|
|
@@ -208,6 +208,32 @@ results = await processor.process(json_output)
|
|
|
208
208
|
| **SchedulerPolicy** | DAG-based scheduling with dependencies, deadlines, pool limits |
|
|
209
209
|
| **GreedyDagScheduler** | Built-in scheduler with topological sort and deadline-aware skipping |
|
|
210
210
|
|
|
211
|
+
### Runtime Guards (Constitution Layer)
|
|
212
|
+
|
|
213
|
+
| Guard | Description |
|
|
214
|
+
|-------|-------------|
|
|
215
|
+
| **SchemaStrictnessGuard** | Validates arguments against JSON schemas, optional type coercion |
|
|
216
|
+
| **SensitiveDataGuard** | Detects and blocks/redacts secrets (API keys, JWTs, private keys) |
|
|
217
|
+
| **NetworkPolicyGuard** | SSRF defense — blocks private IPs, metadata endpoints, enforces HTTPS |
|
|
218
|
+
| **SideEffectGuard** | Labels tools as read_only/write/destructive, enforces policies |
|
|
219
|
+
| **ConcurrencyGuard** | Limits simultaneous in-flight calls (global, per-tool, per-namespace) |
|
|
220
|
+
| **TimeoutBudgetGuard** | Enforces wall-clock time budgets with soft/hard limits |
|
|
221
|
+
| **OutputSizeGuard** | Prevents pathological payloads from blowing up context |
|
|
222
|
+
| **RetrySafetyGuard** | Guards retry behavior (backoff, idempotency keys, non-retryable errors) |
|
|
223
|
+
| **ProvenanceGuard** | Tracks output attribution and lineage |
|
|
224
|
+
| **PlanShapeGuard** | Detects pathological patterns (fan-out explosions, long chains) |
|
|
225
|
+
| **SaturationGuard** | Detects degenerate statistical outputs (extreme Z-scores, saturated CDFs) |
|
|
226
|
+
|
|
227
|
+
### Dynamic Tool Discovery
|
|
228
|
+
|
|
229
|
+
| Feature | Description |
|
|
230
|
+
|---------|-------------|
|
|
231
|
+
| **Intelligent Search** | Natural language queries find tools ("gaussian" → "normal_cdf") |
|
|
232
|
+
| **Synonym Expansion** | Built-in synonyms for math, statistics, file ops, networking |
|
|
233
|
+
| **Fuzzy Matching** | Typo tolerance ("multipley" finds "multiply") |
|
|
234
|
+
| **Session Boosting** | Recently used tools rank higher in search results |
|
|
235
|
+
| **Dynamic Provider** | Base class for LLM-driven tool discovery and execution |
|
|
236
|
+
|
|
211
237
|
### Integration & Observability
|
|
212
238
|
|
|
213
239
|
| Feature | Description |
|
|
@@ -434,6 +460,95 @@ See [examples/02_production_features/distributed_config_demo.py](examples/02_pro
|
|
|
434
460
|
|
|
435
461
|
---
|
|
436
462
|
|
|
463
|
+
## Runtime Guards
|
|
464
|
+
|
|
465
|
+
Protect your tool execution with composable guards that enforce safety policies:
|
|
466
|
+
|
|
467
|
+
```python
|
|
468
|
+
from chuk_tool_processor.guards import (
|
|
469
|
+
GuardChain,
|
|
470
|
+
SchemaStrictnessGuard,
|
|
471
|
+
SensitiveDataGuard,
|
|
472
|
+
NetworkPolicyGuard,
|
|
473
|
+
ConcurrencyGuard,
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
# Create individual guards
|
|
477
|
+
schema_guard = SchemaStrictnessGuard(get_schema=my_schema_getter)
|
|
478
|
+
sensitive_guard = SensitiveDataGuard() # Detects API keys, JWTs, etc.
|
|
479
|
+
network_guard = NetworkPolicyGuard(block_private_ips=True)
|
|
480
|
+
concurrency_guard = ConcurrencyGuard(global_max=50, per_tool_max={"heavy_api": 2})
|
|
481
|
+
|
|
482
|
+
# Compose into a chain
|
|
483
|
+
chain = GuardChain([schema_guard, sensitive_guard, network_guard, concurrency_guard])
|
|
484
|
+
|
|
485
|
+
# Check before execution
|
|
486
|
+
result = await chain.check_all_async("api.fetch", {"url": "https://example.com"})
|
|
487
|
+
if result.blocked:
|
|
488
|
+
print(f"Blocked by {result.stopped_at}: {result.reason}")
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**Key Guards:**
|
|
492
|
+
- **SchemaStrictnessGuard** — Validate args against JSON schemas, auto-coerce types
|
|
493
|
+
- **SensitiveDataGuard** — Block or redact secrets (API keys, JWTs, private keys)
|
|
494
|
+
- **NetworkPolicyGuard** — SSRF defense (block localhost, private IPs, metadata endpoints)
|
|
495
|
+
- **SideEffectGuard** — Enforce read-only mode, block destructive ops in production
|
|
496
|
+
- **ConcurrencyGuard** — Limit in-flight calls globally, per-tool, or per-namespace
|
|
497
|
+
- **TimeoutBudgetGuard** — Enforce wall-clock budgets with soft/hard limits
|
|
498
|
+
- **OutputSizeGuard** — Prevent pathological payloads (size, depth, array length)
|
|
499
|
+
- **SaturationGuard** — Detect degenerate statistical outputs (extreme Z-scores, saturated CDFs)
|
|
500
|
+
|
|
501
|
+
See [GUARDS.md](docs/GUARDS.md) for complete documentation and examples.
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## Dynamic Tool Discovery
|
|
506
|
+
|
|
507
|
+
When you have hundreds of tools, LLMs can't load all schemas upfront. The discovery module provides intelligent search and on-demand tool loading:
|
|
508
|
+
|
|
509
|
+
```python
|
|
510
|
+
from chuk_tool_processor.discovery import ToolSearchEngine, BaseDynamicToolProvider
|
|
511
|
+
|
|
512
|
+
# Create a search engine for your tools
|
|
513
|
+
engine = ToolSearchEngine()
|
|
514
|
+
engine.set_tools(my_tools)
|
|
515
|
+
|
|
516
|
+
# Natural language search with synonym expansion
|
|
517
|
+
results = engine.search("gaussian distribution") # Finds "normal_cdf"
|
|
518
|
+
results = engine.search("find the average") # Finds "calculate_mean"
|
|
519
|
+
results = engine.search("multipley") # Finds "multiply" (typo tolerance)
|
|
520
|
+
|
|
521
|
+
# Session boosting - recently used tools rank higher
|
|
522
|
+
engine.record_tool_use("calculate_mean", success=True)
|
|
523
|
+
engine.advance_turn()
|
|
524
|
+
results = engine.search("calculate") # "calculate_mean" now boosted
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Dynamic Provider Pattern** — give LLMs meta-tools for discovery:
|
|
528
|
+
|
|
529
|
+
```python
|
|
530
|
+
class MyToolProvider(BaseDynamicToolProvider):
|
|
531
|
+
async def get_all_tools(self) -> list[Tool]:
|
|
532
|
+
return self._tools
|
|
533
|
+
|
|
534
|
+
async def execute_tool(self, name: str, args: dict) -> dict:
|
|
535
|
+
return await self._tools[name].execute(**args)
|
|
536
|
+
|
|
537
|
+
provider = MyToolProvider()
|
|
538
|
+
|
|
539
|
+
# LLM gets 4 meta-tools: list_tools, search_tools, get_tool_schema, call_tool
|
|
540
|
+
tools_for_llm = provider.get_dynamic_tools()
|
|
541
|
+
|
|
542
|
+
# LLM workflow: search → get schema → call
|
|
543
|
+
results = await provider.search_tools("calculate average")
|
|
544
|
+
schema = await provider.get_tool_schema("calculate_mean")
|
|
545
|
+
result = await provider.call_tool("calculate_mean", {"values": [1, 2, 3]})
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
See [DISCOVERY.md](docs/DISCOVERY.md) for complete documentation.
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
437
552
|
## Observability
|
|
438
553
|
|
|
439
554
|
One-line setup for production monitoring:
|
|
@@ -491,6 +606,8 @@ See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
|
491
606
|
| [**GETTING_STARTED.md**](docs/GETTING_STARTED.md) | Creating tools, using the processor, ValidatedTool, StreamingTool |
|
|
492
607
|
| [**CORE_CONCEPTS.md**](docs/CORE_CONCEPTS.md) | Registry, strategies, wrappers, parsers, MCP overview |
|
|
493
608
|
| [**PRODUCTION_PATTERNS.md**](docs/PRODUCTION_PATTERNS.md) | Bulkheads, scoped registries, ExecutionContext, parallel execution |
|
|
609
|
+
| [**DISCOVERY.md**](docs/DISCOVERY.md) | Dynamic tool discovery, intelligent search, synonym expansion |
|
|
610
|
+
| [**GUARDS.md**](docs/GUARDS.md) | Runtime guards for safety, validation, and resource management |
|
|
494
611
|
| [**MCP_INTEGRATION.md**](docs/MCP_INTEGRATION.md) | HTTP Streamable, STDIO, SSE, OAuth, Middleware Stack |
|
|
495
612
|
| [**ADVANCED_TOPICS.md**](docs/ADVANCED_TOPICS.md) | Deferred loading, code sandbox, isolated strategy, testing |
|
|
496
613
|
| [**CONFIGURATION.md**](docs/CONFIGURATION.md) | All config options and environment variables |
|
|
@@ -505,6 +622,9 @@ See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
|
505
622
|
# Getting started
|
|
506
623
|
python examples/01_getting_started/hello_tool.py
|
|
507
624
|
|
|
625
|
+
# Dynamic tool discovery (search, synonyms, fuzzy matching)
|
|
626
|
+
python examples/07_discovery/dynamic_tools_demo.py
|
|
627
|
+
|
|
508
628
|
# Hero demo: 8 tools, 5-second deadline, 3 pools (DAG + bulkheads + context)
|
|
509
629
|
python examples/02_production_features/hero_runtime_demo.py
|
|
510
630
|
|
|
@@ -517,6 +637,9 @@ python examples/02_production_features/runtime_features_demo.py
|
|
|
517
637
|
# Structured error handling for planners
|
|
518
638
|
python examples/02_production_features/structured_errors_demo.py
|
|
519
639
|
|
|
640
|
+
# Runtime guards (validation, security, resource limits)
|
|
641
|
+
python examples/guards_demo.py
|
|
642
|
+
|
|
520
643
|
# Redis registry for distributed deployments
|
|
521
644
|
python examples/02_production_features/redis_registry_demo.py
|
|
522
645
|
|
|
@@ -171,6 +171,32 @@ results = await processor.process(json_output)
|
|
|
171
171
|
| **SchedulerPolicy** | DAG-based scheduling with dependencies, deadlines, pool limits |
|
|
172
172
|
| **GreedyDagScheduler** | Built-in scheduler with topological sort and deadline-aware skipping |
|
|
173
173
|
|
|
174
|
+
### Runtime Guards (Constitution Layer)
|
|
175
|
+
|
|
176
|
+
| Guard | Description |
|
|
177
|
+
|-------|-------------|
|
|
178
|
+
| **SchemaStrictnessGuard** | Validates arguments against JSON schemas, optional type coercion |
|
|
179
|
+
| **SensitiveDataGuard** | Detects and blocks/redacts secrets (API keys, JWTs, private keys) |
|
|
180
|
+
| **NetworkPolicyGuard** | SSRF defense — blocks private IPs, metadata endpoints, enforces HTTPS |
|
|
181
|
+
| **SideEffectGuard** | Labels tools as read_only/write/destructive, enforces policies |
|
|
182
|
+
| **ConcurrencyGuard** | Limits simultaneous in-flight calls (global, per-tool, per-namespace) |
|
|
183
|
+
| **TimeoutBudgetGuard** | Enforces wall-clock time budgets with soft/hard limits |
|
|
184
|
+
| **OutputSizeGuard** | Prevents pathological payloads from blowing up context |
|
|
185
|
+
| **RetrySafetyGuard** | Guards retry behavior (backoff, idempotency keys, non-retryable errors) |
|
|
186
|
+
| **ProvenanceGuard** | Tracks output attribution and lineage |
|
|
187
|
+
| **PlanShapeGuard** | Detects pathological patterns (fan-out explosions, long chains) |
|
|
188
|
+
| **SaturationGuard** | Detects degenerate statistical outputs (extreme Z-scores, saturated CDFs) |
|
|
189
|
+
|
|
190
|
+
### Dynamic Tool Discovery
|
|
191
|
+
|
|
192
|
+
| Feature | Description |
|
|
193
|
+
|---------|-------------|
|
|
194
|
+
| **Intelligent Search** | Natural language queries find tools ("gaussian" → "normal_cdf") |
|
|
195
|
+
| **Synonym Expansion** | Built-in synonyms for math, statistics, file ops, networking |
|
|
196
|
+
| **Fuzzy Matching** | Typo tolerance ("multipley" finds "multiply") |
|
|
197
|
+
| **Session Boosting** | Recently used tools rank higher in search results |
|
|
198
|
+
| **Dynamic Provider** | Base class for LLM-driven tool discovery and execution |
|
|
199
|
+
|
|
174
200
|
### Integration & Observability
|
|
175
201
|
|
|
176
202
|
| Feature | Description |
|
|
@@ -397,6 +423,95 @@ See [examples/02_production_features/distributed_config_demo.py](examples/02_pro
|
|
|
397
423
|
|
|
398
424
|
---
|
|
399
425
|
|
|
426
|
+
## Runtime Guards
|
|
427
|
+
|
|
428
|
+
Protect your tool execution with composable guards that enforce safety policies:
|
|
429
|
+
|
|
430
|
+
```python
|
|
431
|
+
from chuk_tool_processor.guards import (
|
|
432
|
+
GuardChain,
|
|
433
|
+
SchemaStrictnessGuard,
|
|
434
|
+
SensitiveDataGuard,
|
|
435
|
+
NetworkPolicyGuard,
|
|
436
|
+
ConcurrencyGuard,
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
# Create individual guards
|
|
440
|
+
schema_guard = SchemaStrictnessGuard(get_schema=my_schema_getter)
|
|
441
|
+
sensitive_guard = SensitiveDataGuard() # Detects API keys, JWTs, etc.
|
|
442
|
+
network_guard = NetworkPolicyGuard(block_private_ips=True)
|
|
443
|
+
concurrency_guard = ConcurrencyGuard(global_max=50, per_tool_max={"heavy_api": 2})
|
|
444
|
+
|
|
445
|
+
# Compose into a chain
|
|
446
|
+
chain = GuardChain([schema_guard, sensitive_guard, network_guard, concurrency_guard])
|
|
447
|
+
|
|
448
|
+
# Check before execution
|
|
449
|
+
result = await chain.check_all_async("api.fetch", {"url": "https://example.com"})
|
|
450
|
+
if result.blocked:
|
|
451
|
+
print(f"Blocked by {result.stopped_at}: {result.reason}")
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Key Guards:**
|
|
455
|
+
- **SchemaStrictnessGuard** — Validate args against JSON schemas, auto-coerce types
|
|
456
|
+
- **SensitiveDataGuard** — Block or redact secrets (API keys, JWTs, private keys)
|
|
457
|
+
- **NetworkPolicyGuard** — SSRF defense (block localhost, private IPs, metadata endpoints)
|
|
458
|
+
- **SideEffectGuard** — Enforce read-only mode, block destructive ops in production
|
|
459
|
+
- **ConcurrencyGuard** — Limit in-flight calls globally, per-tool, or per-namespace
|
|
460
|
+
- **TimeoutBudgetGuard** — Enforce wall-clock budgets with soft/hard limits
|
|
461
|
+
- **OutputSizeGuard** — Prevent pathological payloads (size, depth, array length)
|
|
462
|
+
- **SaturationGuard** — Detect degenerate statistical outputs (extreme Z-scores, saturated CDFs)
|
|
463
|
+
|
|
464
|
+
See [GUARDS.md](docs/GUARDS.md) for complete documentation and examples.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Dynamic Tool Discovery
|
|
469
|
+
|
|
470
|
+
When you have hundreds of tools, LLMs can't load all schemas upfront. The discovery module provides intelligent search and on-demand tool loading:
|
|
471
|
+
|
|
472
|
+
```python
|
|
473
|
+
from chuk_tool_processor.discovery import ToolSearchEngine, BaseDynamicToolProvider
|
|
474
|
+
|
|
475
|
+
# Create a search engine for your tools
|
|
476
|
+
engine = ToolSearchEngine()
|
|
477
|
+
engine.set_tools(my_tools)
|
|
478
|
+
|
|
479
|
+
# Natural language search with synonym expansion
|
|
480
|
+
results = engine.search("gaussian distribution") # Finds "normal_cdf"
|
|
481
|
+
results = engine.search("find the average") # Finds "calculate_mean"
|
|
482
|
+
results = engine.search("multipley") # Finds "multiply" (typo tolerance)
|
|
483
|
+
|
|
484
|
+
# Session boosting - recently used tools rank higher
|
|
485
|
+
engine.record_tool_use("calculate_mean", success=True)
|
|
486
|
+
engine.advance_turn()
|
|
487
|
+
results = engine.search("calculate") # "calculate_mean" now boosted
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Dynamic Provider Pattern** — give LLMs meta-tools for discovery:
|
|
491
|
+
|
|
492
|
+
```python
|
|
493
|
+
class MyToolProvider(BaseDynamicToolProvider):
|
|
494
|
+
async def get_all_tools(self) -> list[Tool]:
|
|
495
|
+
return self._tools
|
|
496
|
+
|
|
497
|
+
async def execute_tool(self, name: str, args: dict) -> dict:
|
|
498
|
+
return await self._tools[name].execute(**args)
|
|
499
|
+
|
|
500
|
+
provider = MyToolProvider()
|
|
501
|
+
|
|
502
|
+
# LLM gets 4 meta-tools: list_tools, search_tools, get_tool_schema, call_tool
|
|
503
|
+
tools_for_llm = provider.get_dynamic_tools()
|
|
504
|
+
|
|
505
|
+
# LLM workflow: search → get schema → call
|
|
506
|
+
results = await provider.search_tools("calculate average")
|
|
507
|
+
schema = await provider.get_tool_schema("calculate_mean")
|
|
508
|
+
result = await provider.call_tool("calculate_mean", {"values": [1, 2, 3]})
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
See [DISCOVERY.md](docs/DISCOVERY.md) for complete documentation.
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
400
515
|
## Observability
|
|
401
516
|
|
|
402
517
|
One-line setup for production monitoring:
|
|
@@ -454,6 +569,8 @@ See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
|
454
569
|
| [**GETTING_STARTED.md**](docs/GETTING_STARTED.md) | Creating tools, using the processor, ValidatedTool, StreamingTool |
|
|
455
570
|
| [**CORE_CONCEPTS.md**](docs/CORE_CONCEPTS.md) | Registry, strategies, wrappers, parsers, MCP overview |
|
|
456
571
|
| [**PRODUCTION_PATTERNS.md**](docs/PRODUCTION_PATTERNS.md) | Bulkheads, scoped registries, ExecutionContext, parallel execution |
|
|
572
|
+
| [**DISCOVERY.md**](docs/DISCOVERY.md) | Dynamic tool discovery, intelligent search, synonym expansion |
|
|
573
|
+
| [**GUARDS.md**](docs/GUARDS.md) | Runtime guards for safety, validation, and resource management |
|
|
457
574
|
| [**MCP_INTEGRATION.md**](docs/MCP_INTEGRATION.md) | HTTP Streamable, STDIO, SSE, OAuth, Middleware Stack |
|
|
458
575
|
| [**ADVANCED_TOPICS.md**](docs/ADVANCED_TOPICS.md) | Deferred loading, code sandbox, isolated strategy, testing |
|
|
459
576
|
| [**CONFIGURATION.md**](docs/CONFIGURATION.md) | All config options and environment variables |
|
|
@@ -468,6 +585,9 @@ See [ERRORS.md](docs/ERRORS.md) for complete error taxonomy.
|
|
|
468
585
|
# Getting started
|
|
469
586
|
python examples/01_getting_started/hello_tool.py
|
|
470
587
|
|
|
588
|
+
# Dynamic tool discovery (search, synonyms, fuzzy matching)
|
|
589
|
+
python examples/07_discovery/dynamic_tools_demo.py
|
|
590
|
+
|
|
471
591
|
# Hero demo: 8 tools, 5-second deadline, 3 pools (DAG + bulkheads + context)
|
|
472
592
|
python examples/02_production_features/hero_runtime_demo.py
|
|
473
593
|
|
|
@@ -480,6 +600,9 @@ python examples/02_production_features/runtime_features_demo.py
|
|
|
480
600
|
# Structured error handling for planners
|
|
481
601
|
python examples/02_production_features/structured_errors_demo.py
|
|
482
602
|
|
|
603
|
+
# Runtime guards (validation, security, resource limits)
|
|
604
|
+
python examples/guards_demo.py
|
|
605
|
+
|
|
483
606
|
# Redis registry for distributed deployments
|
|
484
607
|
python examples/02_production_features/redis_registry_demo.py
|
|
485
608
|
|
|
@@ -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.19"
|
|
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"
|
|
@@ -44,6 +44,20 @@ from chuk_tool_processor.core.context import (
|
|
|
44
44
|
)
|
|
45
45
|
from chuk_tool_processor.core.processor import ToolProcessor
|
|
46
46
|
|
|
47
|
+
# Discovery (tool search and dynamic providers)
|
|
48
|
+
from chuk_tool_processor.discovery import (
|
|
49
|
+
BaseDynamicToolProvider,
|
|
50
|
+
DynamicToolName,
|
|
51
|
+
SearchableTool,
|
|
52
|
+
SearchResult,
|
|
53
|
+
SessionToolStats,
|
|
54
|
+
ToolSearchEngine,
|
|
55
|
+
find_tool_by_alias,
|
|
56
|
+
find_tool_exact,
|
|
57
|
+
get_search_engine,
|
|
58
|
+
search_tools,
|
|
59
|
+
)
|
|
60
|
+
|
|
47
61
|
# Execution strategies and bulkhead
|
|
48
62
|
from chuk_tool_processor.execution.bulkhead import (
|
|
49
63
|
Bulkhead,
|
|
@@ -56,6 +70,75 @@ from chuk_tool_processor.execution.strategies.inprocess_strategy import InProces
|
|
|
56
70
|
from chuk_tool_processor.execution.strategies.subprocess_strategy import SubprocessStrategy
|
|
57
71
|
from chuk_tool_processor.execution.strategies.subprocess_strategy import SubprocessStrategy as IsolatedStrategy
|
|
58
72
|
|
|
73
|
+
# Guards
|
|
74
|
+
from chuk_tool_processor.guards import (
|
|
75
|
+
BaseGuard,
|
|
76
|
+
BudgetGuard,
|
|
77
|
+
BudgetGuardConfig,
|
|
78
|
+
BudgetState,
|
|
79
|
+
BudgetStatus,
|
|
80
|
+
ConcurrencyConfig,
|
|
81
|
+
ConcurrencyGuard,
|
|
82
|
+
ConcurrencyLimitExceeded,
|
|
83
|
+
ConcurrencyState,
|
|
84
|
+
DegradeAction,
|
|
85
|
+
EnforcementLevel,
|
|
86
|
+
Environment,
|
|
87
|
+
ErrorClass,
|
|
88
|
+
ExecutionMode,
|
|
89
|
+
Guard,
|
|
90
|
+
GuardChain,
|
|
91
|
+
GuardChainResult,
|
|
92
|
+
GuardResult,
|
|
93
|
+
GuardVerdict,
|
|
94
|
+
NetworkPolicyConfig,
|
|
95
|
+
NetworkPolicyGuard,
|
|
96
|
+
NetworkViolation,
|
|
97
|
+
NetworkViolationType,
|
|
98
|
+
OutputSizeConfig,
|
|
99
|
+
OutputSizeGuard,
|
|
100
|
+
PerToolGuard,
|
|
101
|
+
PerToolGuardConfig,
|
|
102
|
+
PlanShapeConfig,
|
|
103
|
+
PlanShapeGuard,
|
|
104
|
+
PlanShapeState,
|
|
105
|
+
PlanShapeViolation,
|
|
106
|
+
PlanShapeViolationType,
|
|
107
|
+
PreconditionGuard,
|
|
108
|
+
PreconditionGuardConfig,
|
|
109
|
+
ProvenanceConfig,
|
|
110
|
+
ProvenanceGuard,
|
|
111
|
+
ProvenanceRecord,
|
|
112
|
+
RedactMode,
|
|
113
|
+
RetrySafetyConfig,
|
|
114
|
+
RetrySafetyGuard,
|
|
115
|
+
RetryState,
|
|
116
|
+
RunawayGuard,
|
|
117
|
+
RunawayGuardConfig,
|
|
118
|
+
SchemaStrictnessConfig,
|
|
119
|
+
SchemaStrictnessGuard,
|
|
120
|
+
SchemaValidationResult,
|
|
121
|
+
SchemaViolation,
|
|
122
|
+
SchemaViolationType,
|
|
123
|
+
SensitiveDataConfig,
|
|
124
|
+
SensitiveDataGuard,
|
|
125
|
+
SensitiveDataType,
|
|
126
|
+
SensitiveMatch,
|
|
127
|
+
SideEffectClass,
|
|
128
|
+
SideEffectConfig,
|
|
129
|
+
SideEffectGuard,
|
|
130
|
+
SizeViolation,
|
|
131
|
+
SizeViolationType,
|
|
132
|
+
TimeoutBudgetConfig,
|
|
133
|
+
TimeoutBudgetGuard,
|
|
134
|
+
TimeoutBudgetState,
|
|
135
|
+
ToolClassification,
|
|
136
|
+
TruncatedResult,
|
|
137
|
+
TruncationMode,
|
|
138
|
+
UnresolvedReferenceGuard,
|
|
139
|
+
UnresolvedReferenceGuardConfig,
|
|
140
|
+
)
|
|
141
|
+
|
|
59
142
|
# MCP setup helpers
|
|
60
143
|
from chuk_tool_processor.mcp import (
|
|
61
144
|
setup_mcp_http_streamable,
|
|
@@ -165,6 +248,95 @@ __all__ = [
|
|
|
165
248
|
"RegistryConfig",
|
|
166
249
|
"ResilienceBackend",
|
|
167
250
|
"create_executor",
|
|
251
|
+
# Guards - Base
|
|
252
|
+
"BaseGuard",
|
|
253
|
+
"Guard",
|
|
254
|
+
"GuardResult",
|
|
255
|
+
"GuardVerdict",
|
|
256
|
+
"EnforcementLevel",
|
|
257
|
+
"ToolClassification",
|
|
258
|
+
# Guards - Chain
|
|
259
|
+
"GuardChain",
|
|
260
|
+
"GuardChainResult",
|
|
261
|
+
# Guards - Original
|
|
262
|
+
"BudgetGuard",
|
|
263
|
+
"BudgetGuardConfig",
|
|
264
|
+
"BudgetState",
|
|
265
|
+
"PerToolGuard",
|
|
266
|
+
"PerToolGuardConfig",
|
|
267
|
+
"PreconditionGuard",
|
|
268
|
+
"PreconditionGuardConfig",
|
|
269
|
+
"RunawayGuard",
|
|
270
|
+
"RunawayGuardConfig",
|
|
271
|
+
"UnresolvedReferenceGuard",
|
|
272
|
+
"UnresolvedReferenceGuardConfig",
|
|
273
|
+
# Guards - Schema Strictness
|
|
274
|
+
"SchemaStrictnessGuard",
|
|
275
|
+
"SchemaStrictnessConfig",
|
|
276
|
+
"SchemaValidationResult",
|
|
277
|
+
"SchemaViolation",
|
|
278
|
+
"SchemaViolationType",
|
|
279
|
+
# Guards - Output Size
|
|
280
|
+
"OutputSizeGuard",
|
|
281
|
+
"OutputSizeConfig",
|
|
282
|
+
"SizeViolation",
|
|
283
|
+
"SizeViolationType",
|
|
284
|
+
"TruncatedResult",
|
|
285
|
+
"TruncationMode",
|
|
286
|
+
# Guards - Sensitive Data
|
|
287
|
+
"SensitiveDataGuard",
|
|
288
|
+
"SensitiveDataConfig",
|
|
289
|
+
"SensitiveDataType",
|
|
290
|
+
"SensitiveMatch",
|
|
291
|
+
"RedactMode",
|
|
292
|
+
# Guards - Concurrency
|
|
293
|
+
"ConcurrencyGuard",
|
|
294
|
+
"ConcurrencyConfig",
|
|
295
|
+
"ConcurrencyState",
|
|
296
|
+
"ConcurrencyLimitExceeded",
|
|
297
|
+
# Guards - Network Policy
|
|
298
|
+
"NetworkPolicyGuard",
|
|
299
|
+
"NetworkPolicyConfig",
|
|
300
|
+
"NetworkViolation",
|
|
301
|
+
"NetworkViolationType",
|
|
302
|
+
# Guards - Side Effect
|
|
303
|
+
"SideEffectGuard",
|
|
304
|
+
"SideEffectConfig",
|
|
305
|
+
"SideEffectClass",
|
|
306
|
+
"ExecutionMode",
|
|
307
|
+
"Environment",
|
|
308
|
+
# Guards - Timeout Budget
|
|
309
|
+
"TimeoutBudgetGuard",
|
|
310
|
+
"TimeoutBudgetConfig",
|
|
311
|
+
"TimeoutBudgetState",
|
|
312
|
+
"BudgetStatus",
|
|
313
|
+
"DegradeAction",
|
|
314
|
+
# Guards - Retry Safety
|
|
315
|
+
"RetrySafetyGuard",
|
|
316
|
+
"RetrySafetyConfig",
|
|
317
|
+
"RetryState",
|
|
318
|
+
"ErrorClass",
|
|
319
|
+
# Guards - Provenance
|
|
320
|
+
"ProvenanceGuard",
|
|
321
|
+
"ProvenanceConfig",
|
|
322
|
+
"ProvenanceRecord",
|
|
323
|
+
# Guards - Plan Shape
|
|
324
|
+
"PlanShapeGuard",
|
|
325
|
+
"PlanShapeConfig",
|
|
326
|
+
"PlanShapeState",
|
|
327
|
+
"PlanShapeViolation",
|
|
328
|
+
"PlanShapeViolationType",
|
|
329
|
+
# Discovery
|
|
330
|
+
"BaseDynamicToolProvider",
|
|
331
|
+
"DynamicToolName",
|
|
332
|
+
"ToolSearchEngine",
|
|
333
|
+
"SearchResult",
|
|
334
|
+
"SearchableTool",
|
|
335
|
+
"SessionToolStats",
|
|
336
|
+
"get_search_engine",
|
|
337
|
+
"search_tools",
|
|
338
|
+
"find_tool_exact",
|
|
339
|
+
"find_tool_by_alias",
|
|
168
340
|
]
|
|
169
341
|
|
|
170
342
|
# Type checking exports (documentation only)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# chuk_tool_processor/discovery/__init__.py
|
|
2
|
+
"""Tool discovery and search capabilities.
|
|
3
|
+
|
|
4
|
+
This module provides intelligent tool search with:
|
|
5
|
+
- Tokenized OR semantics (any matching keyword scores)
|
|
6
|
+
- Synonym expansion ("gaussian" finds "normal", "cdf" finds "cumulative")
|
|
7
|
+
- Fuzzy matching fallback for typos
|
|
8
|
+
- Namespace aliasing ("math.normal_cdf" finds "normal_cdf")
|
|
9
|
+
- Always returns results (fallback to popular tools)
|
|
10
|
+
- Session boosting (recently used tools rank higher)
|
|
11
|
+
|
|
12
|
+
It also provides a base class for dynamic tool providers that allow LLMs
|
|
13
|
+
to discover and execute tools on-demand.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from chuk_tool_processor.discovery.dynamic_provider import (
|
|
17
|
+
BaseDynamicToolProvider,
|
|
18
|
+
DynamicToolName,
|
|
19
|
+
)
|
|
20
|
+
from chuk_tool_processor.discovery.search import (
|
|
21
|
+
SearchResult,
|
|
22
|
+
SessionToolStats,
|
|
23
|
+
ToolSearchEngine,
|
|
24
|
+
extract_keywords,
|
|
25
|
+
find_tool_by_alias,
|
|
26
|
+
find_tool_exact,
|
|
27
|
+
fuzzy_score,
|
|
28
|
+
get_search_engine,
|
|
29
|
+
levenshtein_distance,
|
|
30
|
+
normalize_tool_name,
|
|
31
|
+
score_token_match,
|
|
32
|
+
search_tools,
|
|
33
|
+
tokenize,
|
|
34
|
+
)
|
|
35
|
+
from chuk_tool_processor.discovery.searchable import SearchableTool
|
|
36
|
+
from chuk_tool_processor.discovery.synonyms import (
|
|
37
|
+
DOMAIN_INDICATORS,
|
|
38
|
+
STOPWORDS,
|
|
39
|
+
SYNONYMS,
|
|
40
|
+
compute_domain_penalty,
|
|
41
|
+
detect_query_domain,
|
|
42
|
+
detect_tool_domain,
|
|
43
|
+
expand_with_synonyms,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
# Dynamic provider
|
|
48
|
+
"BaseDynamicToolProvider",
|
|
49
|
+
"DynamicToolName",
|
|
50
|
+
# Core search
|
|
51
|
+
"ToolSearchEngine",
|
|
52
|
+
"SearchResult",
|
|
53
|
+
"SessionToolStats",
|
|
54
|
+
"get_search_engine",
|
|
55
|
+
"search_tools",
|
|
56
|
+
"find_tool_exact",
|
|
57
|
+
# Protocol
|
|
58
|
+
"SearchableTool",
|
|
59
|
+
# Token processing
|
|
60
|
+
"tokenize",
|
|
61
|
+
"extract_keywords",
|
|
62
|
+
"expand_with_synonyms",
|
|
63
|
+
# Scoring
|
|
64
|
+
"score_token_match",
|
|
65
|
+
"fuzzy_score",
|
|
66
|
+
"levenshtein_distance",
|
|
67
|
+
# Name aliasing
|
|
68
|
+
"normalize_tool_name",
|
|
69
|
+
"find_tool_by_alias",
|
|
70
|
+
# Synonyms and domain detection
|
|
71
|
+
"SYNONYMS",
|
|
72
|
+
"DOMAIN_INDICATORS",
|
|
73
|
+
"STOPWORDS",
|
|
74
|
+
"detect_query_domain",
|
|
75
|
+
"detect_tool_domain",
|
|
76
|
+
"compute_domain_penalty",
|
|
77
|
+
]
|