chuk-tool-processor 0.6.4__py3-none-any.whl → 0.9.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of chuk-tool-processor might be problematic. Click here for more details.

Files changed (66) hide show
  1. chuk_tool_processor/core/__init__.py +32 -1
  2. chuk_tool_processor/core/exceptions.py +225 -13
  3. chuk_tool_processor/core/processor.py +135 -104
  4. chuk_tool_processor/execution/strategies/__init__.py +6 -0
  5. chuk_tool_processor/execution/strategies/inprocess_strategy.py +142 -150
  6. chuk_tool_processor/execution/strategies/subprocess_strategy.py +202 -206
  7. chuk_tool_processor/execution/tool_executor.py +82 -84
  8. chuk_tool_processor/execution/wrappers/__init__.py +42 -0
  9. chuk_tool_processor/execution/wrappers/caching.py +150 -116
  10. chuk_tool_processor/execution/wrappers/circuit_breaker.py +370 -0
  11. chuk_tool_processor/execution/wrappers/rate_limiting.py +76 -43
  12. chuk_tool_processor/execution/wrappers/retry.py +116 -78
  13. chuk_tool_processor/logging/__init__.py +23 -17
  14. chuk_tool_processor/logging/context.py +40 -45
  15. chuk_tool_processor/logging/formatter.py +22 -21
  16. chuk_tool_processor/logging/helpers.py +28 -42
  17. chuk_tool_processor/logging/metrics.py +13 -15
  18. chuk_tool_processor/mcp/__init__.py +8 -12
  19. chuk_tool_processor/mcp/mcp_tool.py +158 -114
  20. chuk_tool_processor/mcp/register_mcp_tools.py +22 -22
  21. chuk_tool_processor/mcp/setup_mcp_http_streamable.py +57 -17
  22. chuk_tool_processor/mcp/setup_mcp_sse.py +57 -17
  23. chuk_tool_processor/mcp/setup_mcp_stdio.py +11 -11
  24. chuk_tool_processor/mcp/stream_manager.py +333 -276
  25. chuk_tool_processor/mcp/transport/__init__.py +22 -29
  26. chuk_tool_processor/mcp/transport/base_transport.py +180 -44
  27. chuk_tool_processor/mcp/transport/http_streamable_transport.py +505 -325
  28. chuk_tool_processor/mcp/transport/models.py +100 -0
  29. chuk_tool_processor/mcp/transport/sse_transport.py +607 -276
  30. chuk_tool_processor/mcp/transport/stdio_transport.py +597 -116
  31. chuk_tool_processor/models/__init__.py +21 -1
  32. chuk_tool_processor/models/execution_strategy.py +16 -21
  33. chuk_tool_processor/models/streaming_tool.py +28 -25
  34. chuk_tool_processor/models/tool_call.py +49 -31
  35. chuk_tool_processor/models/tool_export_mixin.py +22 -8
  36. chuk_tool_processor/models/tool_result.py +40 -77
  37. chuk_tool_processor/models/tool_spec.py +350 -0
  38. chuk_tool_processor/models/validated_tool.py +36 -18
  39. chuk_tool_processor/observability/__init__.py +30 -0
  40. chuk_tool_processor/observability/metrics.py +312 -0
  41. chuk_tool_processor/observability/setup.py +105 -0
  42. chuk_tool_processor/observability/tracing.py +345 -0
  43. chuk_tool_processor/plugins/__init__.py +1 -1
  44. chuk_tool_processor/plugins/discovery.py +11 -11
  45. chuk_tool_processor/plugins/parsers/__init__.py +1 -1
  46. chuk_tool_processor/plugins/parsers/base.py +1 -2
  47. chuk_tool_processor/plugins/parsers/function_call_tool.py +13 -8
  48. chuk_tool_processor/plugins/parsers/json_tool.py +4 -3
  49. chuk_tool_processor/plugins/parsers/openai_tool.py +12 -7
  50. chuk_tool_processor/plugins/parsers/xml_tool.py +4 -4
  51. chuk_tool_processor/registry/__init__.py +12 -12
  52. chuk_tool_processor/registry/auto_register.py +22 -30
  53. chuk_tool_processor/registry/decorators.py +127 -129
  54. chuk_tool_processor/registry/interface.py +26 -23
  55. chuk_tool_processor/registry/metadata.py +27 -22
  56. chuk_tool_processor/registry/provider.py +17 -18
  57. chuk_tool_processor/registry/providers/__init__.py +16 -19
  58. chuk_tool_processor/registry/providers/memory.py +18 -25
  59. chuk_tool_processor/registry/tool_export.py +42 -51
  60. chuk_tool_processor/utils/validation.py +15 -16
  61. chuk_tool_processor-0.9.7.dist-info/METADATA +1813 -0
  62. chuk_tool_processor-0.9.7.dist-info/RECORD +67 -0
  63. chuk_tool_processor-0.6.4.dist-info/METADATA +0 -697
  64. chuk_tool_processor-0.6.4.dist-info/RECORD +0 -60
  65. {chuk_tool_processor-0.6.4.dist-info → chuk_tool_processor-0.9.7.dist-info}/WHEEL +0 -0
  66. {chuk_tool_processor-0.6.4.dist-info → chuk_tool_processor-0.9.7.dist-info}/top_level.txt +0 -0
@@ -3,13 +3,11 @@
3
3
  Async-native tool registry package for managing and accessing tool implementations.
4
4
  """
5
5
 
6
- import asyncio
7
- from typing import Optional
8
-
6
+ from chuk_tool_processor.registry.decorators import discover_decorated_tools, ensure_registrations, register_tool
9
7
  from chuk_tool_processor.registry.interface import ToolRegistryInterface
10
- from chuk_tool_processor.registry.metadata import ToolMetadata, StreamingToolMetadata
8
+ from chuk_tool_processor.registry.metadata import StreamingToolMetadata, ToolMetadata
11
9
  from chuk_tool_processor.registry.provider import ToolRegistryProvider, get_registry
12
- from chuk_tool_processor.registry.decorators import register_tool, ensure_registrations, discover_decorated_tools
10
+
13
11
 
14
12
  # --------------------------------------------------------------------------- #
15
13
  # The default_registry is now an async function instead of direct property access
@@ -17,14 +15,15 @@ from chuk_tool_processor.registry.decorators import register_tool, ensure_regist
17
15
  async def get_default_registry() -> ToolRegistryInterface:
18
16
  """
19
17
  Get the default registry instance.
20
-
18
+
21
19
  This is a convenience function that calls ToolRegistryProvider.get_registry()
22
-
20
+
23
21
  Returns:
24
22
  The default tool registry
25
23
  """
26
24
  return await ToolRegistryProvider.get_registry()
27
25
 
26
+
28
27
  __all__ = [
29
28
  "ToolRegistryInterface",
30
29
  "ToolMetadata",
@@ -37,24 +36,25 @@ __all__ = [
37
36
  "get_registry",
38
37
  ]
39
38
 
39
+
40
40
  # --------------------------------------------------------------------------- #
41
41
  # Initialization helper that should be called at application startup
42
42
  # --------------------------------------------------------------------------- #
43
43
  async def initialize():
44
44
  """
45
45
  Initialize the registry system.
46
-
46
+
47
47
  This function should be called during application startup to:
48
48
  1. Ensure the registry is created
49
49
  2. Register all tools decorated with @register_tool
50
-
50
+
51
51
  Returns:
52
52
  The initialized registry
53
53
  """
54
54
  # Initialize registry
55
55
  registry = await get_default_registry()
56
-
56
+
57
57
  # Process all pending tool registrations
58
58
  await ensure_registrations()
59
-
60
- return registry
59
+
60
+ return registry
@@ -11,10 +11,9 @@ These tools will immediately show up in the global registry.
11
11
 
12
12
  from __future__ import annotations
13
13
 
14
- import asyncio
15
14
  import inspect
16
- import types
17
- from typing import Callable, ForwardRef, Type, get_type_hints, Any, Optional, Dict, Union
15
+ from collections.abc import Callable
16
+ from typing import Any, ForwardRef, get_type_hints
18
17
 
19
18
  import anyio
20
19
  from pydantic import BaseModel, create_model
@@ -25,16 +24,14 @@ except ModuleNotFoundError: # pragma: no cover
25
24
  BaseTool = None # noqa: N816 - keep the name for isinstance() checks
26
25
 
27
26
  # registry
28
- from .decorators import register_tool
29
27
  from .provider import ToolRegistryProvider
30
28
 
31
-
32
29
  # ────────────────────────────────────────────────────────────────────────────
33
30
  # internals - build a Pydantic schema from an arbitrary callable
34
31
  # ────────────────────────────────────────────────────────────────────────────
35
32
 
36
33
 
37
- def _auto_schema(func: Callable) -> Type[BaseModel]:
34
+ def _auto_schema(func: Callable) -> type[BaseModel]:
38
35
  """
39
36
  Turn a function signature into a `pydantic.BaseModel` subclass.
40
37
 
@@ -55,8 +52,7 @@ def _auto_schema(func: Callable) -> Type[BaseModel]:
55
52
  # couldn't resolve the type.
56
53
  hint: type = (
57
54
  raw_hint
58
- if raw_hint not in (inspect._empty, None, str)
59
- and not isinstance(raw_hint, (str, ForwardRef))
55
+ if raw_hint not in (inspect._empty, None, str) and not isinstance(raw_hint, str | ForwardRef)
60
56
  else str
61
57
  )
62
58
  fields[param.name] = (hint, ...) # "..." → required
@@ -78,7 +74,7 @@ async def register_fn_tool(
78
74
  ) -> None:
79
75
  """
80
76
  Register a plain function as a tool asynchronously.
81
-
77
+
82
78
  Args:
83
79
  func: The function to register (can be sync or async)
84
80
  name: Optional name for the tool (defaults to function name)
@@ -88,21 +84,23 @@ async def register_fn_tool(
88
84
  schema = _auto_schema(func)
89
85
  tool_name = name or func.__name__
90
86
  tool_description = (description or func.__doc__ or "").strip()
91
-
87
+
92
88
  # Create the tool wrapper class
93
89
  class _Tool: # noqa: D401, N801 - internal auto-wrapper
94
90
  """Auto-generated tool wrapper for function."""
95
-
91
+
96
92
  async def execute(self, **kwargs: Any) -> Any:
97
93
  """Execute the wrapped function."""
98
94
  if inspect.iscoroutinefunction(func):
99
95
  return await func(**kwargs)
100
96
  # off-load blocking sync work
101
- return await anyio.to_thread.run_sync(func, **kwargs)
102
-
97
+ import functools
98
+
99
+ return await anyio.to_thread.run_sync(functools.partial(func, **kwargs))
100
+
103
101
  # Set the docstring
104
102
  _Tool.__doc__ = tool_description
105
-
103
+
106
104
  # Get the registry and register directly
107
105
  registry = await ToolRegistryProvider.get_registry()
108
106
  await registry.register_tool(
@@ -115,7 +113,7 @@ async def register_fn_tool(
115
113
  "argument_schema": schema.model_json_schema(),
116
114
  "source": "function",
117
115
  "source_name": func.__qualname__,
118
- }
116
+ },
119
117
  )
120
118
 
121
119
 
@@ -133,7 +131,7 @@ async def register_langchain_tool(
133
131
  ) -> None:
134
132
  """
135
133
  Register a **LangChain** `BaseTool` instance asynchronously.
136
-
134
+
137
135
  Works with any object exposing `.run` / `.arun` methods.
138
136
 
139
137
  Args:
@@ -141,45 +139,39 @@ async def register_langchain_tool(
141
139
  name: Optional name for the tool (defaults to tool.name)
142
140
  description: Optional description (defaults to tool.description)
143
141
  namespace: Registry namespace (defaults to "default")
144
-
142
+
145
143
  Raises:
146
144
  RuntimeError: If LangChain isn't installed
147
145
  TypeError: If the object isn't a LangChain BaseTool
148
146
  """
149
147
  if BaseTool is None:
150
- raise RuntimeError(
151
- "register_langchain_tool() requires LangChain - "
152
- "install with `pip install langchain`"
153
- )
148
+ raise RuntimeError("register_langchain_tool() requires LangChain - install with `pip install langchain`")
154
149
 
155
150
  if not isinstance(tool, BaseTool): # pragma: no cover
156
- raise TypeError(
157
- "Expected a langchain.tools.base.BaseTool instance - got "
158
- f"{type(tool).__name__}"
159
- )
151
+ raise TypeError(f"Expected a langchain.tools.base.BaseTool instance - got {type(tool).__name__}")
160
152
 
161
153
  # Prefer async implementation if available
162
154
  fn = tool.arun if hasattr(tool, "arun") else tool.run
163
-
155
+
164
156
  tool_name = name or tool.name or tool.__class__.__name__
165
157
  tool_description = description or tool.description or (tool.__doc__ or "")
166
-
158
+
167
159
  await register_fn_tool(
168
160
  fn,
169
161
  name=tool_name,
170
162
  description=tool_description,
171
163
  namespace=namespace,
172
164
  )
173
-
165
+
174
166
  # Update the metadata to include LangChain info
175
167
  registry = await ToolRegistryProvider.get_registry()
176
168
  metadata = await registry.get_metadata(tool_name, namespace)
177
-
169
+
178
170
  if metadata:
179
171
  updated_metadata = metadata.model_copy()
180
172
  # Update source info
181
173
  updated_metadata.tags.add("langchain")
182
-
174
+
183
175
  # Re-register with updated metadata
184
176
  await registry.register_tool(
185
177
  await registry.get_tool(tool_name, namespace),