provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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.
- provide/foundation/__init__.py +36 -10
- provide/foundation/archive/__init__.py +1 -1
- provide/foundation/archive/base.py +15 -14
- provide/foundation/archive/bzip2.py +40 -40
- provide/foundation/archive/gzip.py +42 -42
- provide/foundation/archive/operations.py +93 -96
- provide/foundation/archive/tar.py +33 -31
- provide/foundation/archive/zip.py +52 -50
- provide/foundation/asynctools/__init__.py +20 -0
- provide/foundation/asynctools/core.py +126 -0
- provide/foundation/cli/__init__.py +2 -2
- provide/foundation/cli/commands/deps.py +15 -9
- provide/foundation/cli/commands/logs/__init__.py +3 -3
- provide/foundation/cli/commands/logs/generate.py +2 -2
- provide/foundation/cli/commands/logs/query.py +4 -4
- provide/foundation/cli/commands/logs/send.py +3 -3
- provide/foundation/cli/commands/logs/tail.py +3 -3
- provide/foundation/cli/decorators.py +11 -11
- provide/foundation/cli/main.py +1 -1
- provide/foundation/cli/testing.py +2 -40
- provide/foundation/cli/utils.py +21 -18
- provide/foundation/config/__init__.py +35 -2
- provide/foundation/config/base.py +2 -2
- provide/foundation/config/converters.py +477 -0
- provide/foundation/config/defaults.py +67 -0
- provide/foundation/config/env.py +6 -20
- provide/foundation/config/loader.py +10 -4
- provide/foundation/config/sync.py +8 -6
- provide/foundation/config/types.py +5 -5
- provide/foundation/config/validators.py +4 -4
- provide/foundation/console/input.py +5 -5
- provide/foundation/console/output.py +36 -14
- provide/foundation/context/__init__.py +8 -4
- provide/foundation/context/core.py +88 -110
- provide/foundation/crypto/certificates/__init__.py +9 -5
- provide/foundation/crypto/certificates/base.py +2 -2
- provide/foundation/crypto/certificates/certificate.py +48 -19
- provide/foundation/crypto/certificates/factory.py +26 -18
- provide/foundation/crypto/certificates/generator.py +24 -23
- provide/foundation/crypto/certificates/loader.py +24 -16
- provide/foundation/crypto/certificates/operations.py +17 -10
- provide/foundation/crypto/certificates/trust.py +21 -21
- provide/foundation/env/__init__.py +28 -0
- provide/foundation/env/core.py +218 -0
- provide/foundation/errors/__init__.py +3 -3
- provide/foundation/errors/decorators.py +0 -234
- provide/foundation/errors/types.py +0 -98
- provide/foundation/eventsets/display.py +13 -14
- provide/foundation/eventsets/registry.py +61 -31
- provide/foundation/eventsets/resolver.py +50 -46
- provide/foundation/eventsets/sets/das.py +8 -8
- provide/foundation/eventsets/sets/database.py +14 -14
- provide/foundation/eventsets/sets/http.py +21 -21
- provide/foundation/eventsets/sets/llm.py +16 -16
- provide/foundation/eventsets/sets/task_queue.py +13 -13
- provide/foundation/eventsets/types.py +7 -7
- provide/foundation/file/directory.py +14 -23
- provide/foundation/file/lock.py +4 -3
- provide/foundation/hub/components.py +75 -389
- provide/foundation/hub/config.py +157 -0
- provide/foundation/hub/discovery.py +63 -0
- provide/foundation/hub/handlers.py +89 -0
- provide/foundation/hub/lifecycle.py +195 -0
- provide/foundation/hub/manager.py +7 -4
- provide/foundation/hub/processors.py +49 -0
- provide/foundation/integrations/__init__.py +11 -0
- provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
- provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/client.py +14 -14
- provide/foundation/{observability → integrations}/openobserve/commands.py +12 -12
- provide/foundation/integrations/openobserve/config.py +37 -0
- provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/otlp.py +2 -2
- provide/foundation/{observability → integrations}/openobserve/search.py +2 -3
- provide/foundation/{observability → integrations}/openobserve/streaming.py +5 -5
- provide/foundation/logger/__init__.py +0 -1
- provide/foundation/logger/config/base.py +1 -1
- provide/foundation/logger/config/logging.py +69 -299
- provide/foundation/logger/config/telemetry.py +39 -121
- provide/foundation/logger/factories.py +2 -2
- provide/foundation/logger/processors/main.py +12 -10
- provide/foundation/logger/ratelimit/limiters.py +4 -4
- provide/foundation/logger/ratelimit/processor.py +1 -1
- provide/foundation/logger/setup/coordinator.py +39 -25
- provide/foundation/logger/setup/processors.py +3 -3
- provide/foundation/logger/setup/testing.py +14 -0
- provide/foundation/logger/trace.py +5 -5
- provide/foundation/metrics/__init__.py +1 -1
- provide/foundation/metrics/otel.py +3 -1
- provide/foundation/observability/__init__.py +3 -3
- provide/foundation/process/__init__.py +9 -0
- provide/foundation/process/exit.py +48 -0
- provide/foundation/process/lifecycle.py +69 -46
- provide/foundation/resilience/__init__.py +36 -0
- provide/foundation/resilience/circuit.py +166 -0
- provide/foundation/resilience/decorators.py +236 -0
- provide/foundation/resilience/fallback.py +208 -0
- provide/foundation/resilience/retry.py +327 -0
- provide/foundation/serialization/__init__.py +16 -0
- provide/foundation/serialization/core.py +70 -0
- provide/foundation/streams/config.py +78 -0
- provide/foundation/streams/console.py +4 -5
- provide/foundation/streams/core.py +5 -2
- provide/foundation/streams/file.py +12 -2
- provide/foundation/testing/__init__.py +29 -9
- provide/foundation/testing/archive/__init__.py +7 -7
- provide/foundation/testing/archive/fixtures.py +58 -54
- provide/foundation/testing/cli.py +30 -20
- provide/foundation/testing/common/__init__.py +13 -15
- provide/foundation/testing/common/fixtures.py +27 -57
- provide/foundation/testing/file/__init__.py +15 -15
- provide/foundation/testing/file/content_fixtures.py +289 -0
- provide/foundation/testing/file/directory_fixtures.py +107 -0
- provide/foundation/testing/file/fixtures.py +42 -516
- provide/foundation/testing/file/special_fixtures.py +145 -0
- provide/foundation/testing/logger.py +89 -8
- provide/foundation/testing/mocking/__init__.py +21 -21
- provide/foundation/testing/mocking/fixtures.py +80 -67
- provide/foundation/testing/process/__init__.py +23 -23
- provide/foundation/testing/process/async_fixtures.py +414 -0
- provide/foundation/testing/process/fixtures.py +48 -571
- provide/foundation/testing/process/subprocess_fixtures.py +210 -0
- provide/foundation/testing/threading/__init__.py +17 -17
- provide/foundation/testing/threading/basic_fixtures.py +105 -0
- provide/foundation/testing/threading/data_fixtures.py +101 -0
- provide/foundation/testing/threading/execution_fixtures.py +278 -0
- provide/foundation/testing/threading/fixtures.py +32 -502
- provide/foundation/testing/threading/sync_fixtures.py +100 -0
- provide/foundation/testing/time/__init__.py +11 -11
- provide/foundation/testing/time/fixtures.py +95 -83
- provide/foundation/testing/transport/__init__.py +9 -9
- provide/foundation/testing/transport/fixtures.py +54 -54
- provide/foundation/time/__init__.py +18 -0
- provide/foundation/time/core.py +63 -0
- provide/foundation/tools/__init__.py +2 -2
- provide/foundation/tools/base.py +68 -67
- provide/foundation/tools/cache.py +69 -74
- provide/foundation/tools/downloader.py +68 -62
- provide/foundation/tools/installer.py +51 -57
- provide/foundation/tools/registry.py +38 -45
- provide/foundation/tools/resolver.py +70 -68
- provide/foundation/tools/verifier.py +39 -50
- provide/foundation/tracer/spans.py +2 -14
- provide/foundation/transport/__init__.py +26 -33
- provide/foundation/transport/base.py +32 -30
- provide/foundation/transport/client.py +44 -49
- provide/foundation/transport/config.py +36 -107
- provide/foundation/transport/errors.py +13 -27
- provide/foundation/transport/http.py +69 -55
- provide/foundation/transport/middleware.py +113 -114
- provide/foundation/transport/registry.py +29 -27
- provide/foundation/transport/types.py +6 -6
- provide/foundation/utils/deps.py +17 -14
- provide/foundation/utils/parsing.py +49 -4
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
- provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
- provide_foundation-0.0.0.dev1.dist-info/RECORD +0 -200
- /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
- /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -5,11 +5,10 @@ Handles extraction and installation of tools from different
|
|
5
5
|
archive formats (zip, tar, gz, etc.) and binary files.
|
6
6
|
"""
|
7
7
|
|
8
|
+
from pathlib import Path
|
8
9
|
import shutil
|
9
10
|
import tarfile
|
10
|
-
import tempfile
|
11
11
|
import zipfile
|
12
|
-
from pathlib import Path
|
13
12
|
|
14
13
|
from provide.foundation.errors import FoundationError
|
15
14
|
from provide.foundation.logger import get_logger
|
@@ -20,43 +19,43 @@ log = get_logger(__name__)
|
|
20
19
|
|
21
20
|
class InstallError(FoundationError):
|
22
21
|
"""Raised when installation fails."""
|
23
|
-
|
22
|
+
|
24
23
|
pass
|
25
24
|
|
26
25
|
|
27
26
|
class ToolInstaller:
|
28
27
|
"""
|
29
28
|
Handle tool installation from various artifact formats.
|
30
|
-
|
29
|
+
|
31
30
|
Supports:
|
32
31
|
- ZIP archives
|
33
32
|
- TAR archives (with compression)
|
34
33
|
- Single binary files
|
35
34
|
- Platform-specific installation patterns
|
36
35
|
"""
|
37
|
-
|
36
|
+
|
38
37
|
def install(self, artifact: Path, metadata: ToolMetadata) -> Path:
|
39
38
|
"""
|
40
39
|
Install tool from artifact.
|
41
|
-
|
40
|
+
|
42
41
|
Args:
|
43
42
|
artifact: Path to downloaded artifact.
|
44
43
|
metadata: Tool metadata with installation info.
|
45
|
-
|
44
|
+
|
46
45
|
Returns:
|
47
46
|
Path to installed tool directory.
|
48
|
-
|
47
|
+
|
49
48
|
Raises:
|
50
49
|
InstallError: If installation fails.
|
51
50
|
"""
|
52
51
|
if not artifact.exists():
|
53
52
|
raise InstallError(f"Artifact not found: {artifact}")
|
54
|
-
|
53
|
+
|
55
54
|
# Determine install directory
|
56
55
|
install_dir = self.get_install_dir(metadata)
|
57
|
-
|
56
|
+
|
58
57
|
log.info(f"Installing {metadata.name} {metadata.version} to {install_dir}")
|
59
|
-
|
58
|
+
|
60
59
|
# Extract based on file type
|
61
60
|
suffix = artifact.suffix.lower()
|
62
61
|
if suffix == ".zip":
|
@@ -67,65 +66,65 @@ class ToolInstaller:
|
|
67
66
|
self.install_binary(artifact, install_dir, metadata)
|
68
67
|
else:
|
69
68
|
raise InstallError(f"Unknown artifact type: {suffix}")
|
70
|
-
|
69
|
+
|
71
70
|
# Set permissions
|
72
71
|
self.set_permissions(install_dir, metadata)
|
73
|
-
|
72
|
+
|
74
73
|
# Create symlinks if needed
|
75
74
|
self.create_symlinks(install_dir, metadata)
|
76
|
-
|
75
|
+
|
77
76
|
log.info(f"Successfully installed {metadata.name} to {install_dir}")
|
78
77
|
return install_dir
|
79
|
-
|
78
|
+
|
80
79
|
def get_install_dir(self, metadata: ToolMetadata) -> Path:
|
81
80
|
"""
|
82
81
|
Get installation directory for tool.
|
83
|
-
|
82
|
+
|
84
83
|
Args:
|
85
84
|
metadata: Tool metadata.
|
86
|
-
|
85
|
+
|
87
86
|
Returns:
|
88
87
|
Installation directory path.
|
89
88
|
"""
|
90
89
|
if metadata.install_path:
|
91
90
|
return metadata.install_path
|
92
|
-
|
91
|
+
|
93
92
|
# Default to ~/.wrknv/tools/<name>/<version>
|
94
93
|
base = Path.home() / ".wrknv" / "tools"
|
95
94
|
return base / metadata.name / metadata.version
|
96
|
-
|
95
|
+
|
97
96
|
def extract_zip(self, archive: Path, dest: Path) -> None:
|
98
97
|
"""
|
99
98
|
Extract ZIP archive.
|
100
|
-
|
99
|
+
|
101
100
|
Args:
|
102
101
|
archive: Path to ZIP file.
|
103
102
|
dest: Destination directory.
|
104
103
|
"""
|
105
104
|
log.debug(f"Extracting ZIP {archive} to {dest}")
|
106
|
-
|
105
|
+
|
107
106
|
dest.mkdir(parents=True, exist_ok=True)
|
108
|
-
|
107
|
+
|
109
108
|
with zipfile.ZipFile(archive, "r") as zf:
|
110
109
|
# Check for unsafe paths
|
111
110
|
for member in zf.namelist():
|
112
111
|
if member.startswith("/") or ".." in member:
|
113
112
|
raise InstallError(f"Unsafe path in archive: {member}")
|
114
|
-
|
113
|
+
|
115
114
|
zf.extractall(dest)
|
116
|
-
|
115
|
+
|
117
116
|
def extract_tar(self, archive: Path, dest: Path) -> None:
|
118
117
|
"""
|
119
118
|
Extract tar archive (with optional compression).
|
120
|
-
|
119
|
+
|
121
120
|
Args:
|
122
121
|
archive: Path to tar file.
|
123
122
|
dest: Destination directory.
|
124
123
|
"""
|
125
124
|
log.debug(f"Extracting tar {archive} to {dest}")
|
126
|
-
|
125
|
+
|
127
126
|
dest.mkdir(parents=True, exist_ok=True)
|
128
|
-
|
127
|
+
|
129
128
|
# Determine mode based on extension
|
130
129
|
mode = "r"
|
131
130
|
if archive.suffix in [".gz", ".tgz"]:
|
@@ -134,22 +133,22 @@ class ToolInstaller:
|
|
134
133
|
mode = "r:bz2"
|
135
134
|
elif archive.suffix == ".xz":
|
136
135
|
mode = "r:xz"
|
137
|
-
|
136
|
+
|
138
137
|
with tarfile.open(archive, mode) as tf:
|
139
138
|
# Check for unsafe paths
|
140
139
|
for member in tf.getmembers():
|
141
140
|
if member.name.startswith("/") or ".." in member.name:
|
142
141
|
raise InstallError(f"Unsafe path in archive: {member.name}")
|
143
|
-
|
142
|
+
|
144
143
|
tf.extractall(dest)
|
145
|
-
|
144
|
+
|
146
145
|
def is_binary(self, file_path: Path) -> bool:
|
147
146
|
"""
|
148
147
|
Check if file is a binary executable.
|
149
|
-
|
148
|
+
|
150
149
|
Args:
|
151
150
|
file_path: Path to check.
|
152
|
-
|
151
|
+
|
153
152
|
Returns:
|
154
153
|
True if file appears to be binary.
|
155
154
|
"""
|
@@ -170,85 +169,80 @@ class ToolInstaller:
|
|
170
169
|
return True
|
171
170
|
except Exception:
|
172
171
|
pass
|
173
|
-
|
172
|
+
|
174
173
|
return False
|
175
|
-
|
176
|
-
def install_binary(
|
177
|
-
self,
|
178
|
-
binary: Path,
|
179
|
-
dest: Path,
|
180
|
-
metadata: ToolMetadata
|
181
|
-
) -> None:
|
174
|
+
|
175
|
+
def install_binary(self, binary: Path, dest: Path, metadata: ToolMetadata) -> None:
|
182
176
|
"""
|
183
177
|
Install single binary file.
|
184
|
-
|
178
|
+
|
185
179
|
Args:
|
186
180
|
binary: Path to binary file.
|
187
181
|
dest: Destination directory.
|
188
182
|
metadata: Tool metadata.
|
189
183
|
"""
|
190
184
|
log.debug(f"Installing binary {binary} to {dest}")
|
191
|
-
|
185
|
+
|
192
186
|
dest.mkdir(parents=True, exist_ok=True)
|
193
187
|
bin_dir = dest / "bin"
|
194
188
|
bin_dir.mkdir(exist_ok=True)
|
195
|
-
|
189
|
+
|
196
190
|
# Determine target name
|
197
191
|
target_name = metadata.executable_name or binary.name
|
198
192
|
target = bin_dir / target_name
|
199
|
-
|
193
|
+
|
200
194
|
# Copy binary
|
201
195
|
shutil.copy2(binary, target)
|
202
|
-
|
196
|
+
|
203
197
|
# Make executable
|
204
198
|
target.chmod(0o755)
|
205
|
-
|
199
|
+
|
206
200
|
def set_permissions(self, install_dir: Path, metadata: ToolMetadata) -> None:
|
207
201
|
"""
|
208
202
|
Set appropriate permissions on installed files.
|
209
|
-
|
203
|
+
|
210
204
|
Args:
|
211
205
|
install_dir: Installation directory.
|
212
206
|
metadata: Tool metadata.
|
213
207
|
"""
|
214
208
|
import platform
|
215
|
-
|
209
|
+
|
216
210
|
if platform.system() == "Windows":
|
217
211
|
return # Windows handles permissions differently
|
218
|
-
|
212
|
+
|
219
213
|
# Find executables and make them executable
|
220
214
|
bin_dir = install_dir / "bin"
|
221
215
|
if bin_dir.exists():
|
222
216
|
for file in bin_dir.iterdir():
|
223
217
|
if file.is_file():
|
224
218
|
file.chmod(0o755)
|
225
|
-
|
219
|
+
|
226
220
|
# Check for executable name in root
|
227
221
|
if metadata.executable_name:
|
228
222
|
exe_path = install_dir / metadata.executable_name
|
229
223
|
if exe_path.exists():
|
230
224
|
exe_path.chmod(0o755)
|
231
|
-
|
225
|
+
|
232
226
|
def create_symlinks(self, install_dir: Path, metadata: ToolMetadata) -> None:
|
233
227
|
"""
|
234
228
|
Create symlinks for easier access.
|
235
|
-
|
229
|
+
|
236
230
|
Args:
|
237
231
|
install_dir: Installation directory.
|
238
232
|
metadata: Tool metadata.
|
239
233
|
"""
|
240
234
|
import platform
|
241
|
-
|
235
|
+
|
242
236
|
if platform.system() == "Windows":
|
243
237
|
return # Windows doesn't support symlinks easily
|
244
|
-
|
238
|
+
|
245
239
|
# Create version-less symlink
|
246
240
|
if metadata.name and metadata.version:
|
247
241
|
parent = install_dir.parent
|
248
242
|
latest_link = parent / "latest"
|
249
|
-
|
243
|
+
|
250
244
|
if latest_link.exists() or latest_link.is_symlink():
|
251
245
|
latest_link.unlink()
|
252
|
-
|
246
|
+
|
253
247
|
latest_link.symlink_to(install_dir)
|
254
|
-
log.debug(f"Created symlink {latest_link} -> {install_dir}")
|
248
|
+
log.debug(f"Created symlink {latest_link} -> {install_dir}")
|
@@ -19,32 +19,32 @@ log = get_logger(__name__)
|
|
19
19
|
class ToolRegistry:
|
20
20
|
"""
|
21
21
|
Wrapper around the hub registry for tool management.
|
22
|
-
|
22
|
+
|
23
23
|
Uses the main hub registry with dimension="tool_manager"
|
24
24
|
to avoid namespace pollution while leveraging existing
|
25
25
|
registry infrastructure.
|
26
26
|
"""
|
27
|
-
|
27
|
+
|
28
28
|
DIMENSION = "tool_manager"
|
29
|
-
|
29
|
+
|
30
30
|
def __init__(self):
|
31
31
|
"""Initialize the tool registry."""
|
32
32
|
self.hub = get_hub()
|
33
33
|
self._discover_tools()
|
34
|
-
|
34
|
+
|
35
35
|
def _discover_tools(self) -> None:
|
36
36
|
"""
|
37
37
|
Auto-discover tool managers via entry points.
|
38
|
-
|
38
|
+
|
39
39
|
Looks for entry points in the "wrknv.tools" group
|
40
40
|
and automatically registers them.
|
41
41
|
"""
|
42
42
|
try:
|
43
43
|
# Get entry points for tool managers
|
44
|
-
if hasattr(importlib.metadata,
|
44
|
+
if hasattr(importlib.metadata, "entry_points"):
|
45
45
|
# Python 3.10+
|
46
46
|
eps = importlib.metadata.entry_points()
|
47
|
-
if hasattr(eps,
|
47
|
+
if hasattr(eps, "select"):
|
48
48
|
# Python 3.10+ with select method
|
49
49
|
group_eps = eps.select(group="wrknv.tools")
|
50
50
|
else:
|
@@ -54,7 +54,7 @@ class ToolRegistry:
|
|
54
54
|
# Python 3.8-3.9
|
55
55
|
eps = importlib.metadata.entry_points()
|
56
56
|
group_eps = eps.get("wrknv.tools", [])
|
57
|
-
|
57
|
+
|
58
58
|
for ep in group_eps:
|
59
59
|
try:
|
60
60
|
manager_class = ep.load()
|
@@ -64,16 +64,16 @@ class ToolRegistry:
|
|
64
64
|
log.warning(f"Failed to load tool manager {ep.name}: {e}")
|
65
65
|
except Exception as e:
|
66
66
|
log.debug(f"Entry point discovery not available: {e}")
|
67
|
-
|
67
|
+
|
68
68
|
def register_tool_manager(
|
69
69
|
self,
|
70
70
|
name: str,
|
71
71
|
manager_class: type[BaseToolManager],
|
72
|
-
aliases: list[str] | None = None
|
72
|
+
aliases: list[str] | None = None,
|
73
73
|
) -> None:
|
74
74
|
"""
|
75
75
|
Register a tool manager with the hub.
|
76
|
-
|
76
|
+
|
77
77
|
Args:
|
78
78
|
name: Tool name (e.g., "terraform").
|
79
79
|
manager_class: Tool manager class.
|
@@ -85,7 +85,7 @@ class ToolRegistry:
|
|
85
85
|
"executable": manager_class.executable_name,
|
86
86
|
"platforms": manager_class.supported_platforms,
|
87
87
|
}
|
88
|
-
|
88
|
+
|
89
89
|
# Register with hub
|
90
90
|
self.hub.registry.register(
|
91
91
|
name=name,
|
@@ -93,35 +93,33 @@ class ToolRegistry:
|
|
93
93
|
dimension=self.DIMENSION,
|
94
94
|
metadata=metadata,
|
95
95
|
aliases=aliases,
|
96
|
-
replace=True # Allow re-registration for updates
|
96
|
+
replace=True, # Allow re-registration for updates
|
97
97
|
)
|
98
|
-
|
98
|
+
|
99
99
|
log.info(f"Registered tool manager: {name}")
|
100
|
-
|
100
|
+
|
101
101
|
def get_tool_manager_class(self, name: str) -> type[BaseToolManager] | None:
|
102
102
|
"""
|
103
103
|
Get a tool manager class by name.
|
104
|
-
|
104
|
+
|
105
105
|
Args:
|
106
106
|
name: Tool name or alias.
|
107
|
-
|
107
|
+
|
108
108
|
Returns:
|
109
109
|
Tool manager class, or None if not found.
|
110
110
|
"""
|
111
111
|
return self.hub.registry.get(name, dimension=self.DIMENSION)
|
112
|
-
|
112
|
+
|
113
113
|
def create_tool_manager(
|
114
|
-
self,
|
115
|
-
name: str,
|
116
|
-
config: BaseConfig
|
114
|
+
self, name: str, config: BaseConfig
|
117
115
|
) -> BaseToolManager | None:
|
118
116
|
"""
|
119
117
|
Create a tool manager instance.
|
120
|
-
|
118
|
+
|
121
119
|
Args:
|
122
120
|
name: Tool name or alias.
|
123
121
|
config: Configuration object.
|
124
|
-
|
122
|
+
|
125
123
|
Returns:
|
126
124
|
Tool manager instance, or None if not found.
|
127
125
|
"""
|
@@ -129,42 +127,42 @@ class ToolRegistry:
|
|
129
127
|
if manager_class:
|
130
128
|
return manager_class(config)
|
131
129
|
return None
|
132
|
-
|
130
|
+
|
133
131
|
def list_tools(self) -> list[tuple[str, dict[str, Any]]]:
|
134
132
|
"""
|
135
133
|
List all registered tools.
|
136
|
-
|
134
|
+
|
137
135
|
Returns:
|
138
136
|
List of (name, metadata) tuples.
|
139
137
|
"""
|
140
138
|
tools = []
|
141
139
|
for name, entry in self.hub.registry.list_dimension(self.DIMENSION):
|
142
|
-
metadata = entry.metadata if hasattr(entry,
|
140
|
+
metadata = entry.metadata if hasattr(entry, "metadata") else {}
|
143
141
|
tools.append((name, metadata))
|
144
142
|
return tools
|
145
|
-
|
143
|
+
|
146
144
|
def get_tool_info(self, name: str) -> dict[str, Any] | None:
|
147
145
|
"""
|
148
146
|
Get information about a specific tool.
|
149
|
-
|
147
|
+
|
150
148
|
Args:
|
151
149
|
name: Tool name or alias.
|
152
|
-
|
150
|
+
|
153
151
|
Returns:
|
154
152
|
Tool metadata dictionary, or None if not found.
|
155
153
|
"""
|
156
154
|
entry = self.hub.registry.get_entry(name, dimension=self.DIMENSION)
|
157
|
-
if entry and hasattr(entry,
|
155
|
+
if entry and hasattr(entry, "metadata"):
|
158
156
|
return entry.metadata
|
159
157
|
return None
|
160
|
-
|
158
|
+
|
161
159
|
def is_tool_registered(self, name: str) -> bool:
|
162
160
|
"""
|
163
161
|
Check if a tool is registered.
|
164
|
-
|
162
|
+
|
165
163
|
Args:
|
166
164
|
name: Tool name or alias.
|
167
|
-
|
165
|
+
|
168
166
|
Returns:
|
169
167
|
True if registered, False otherwise.
|
170
168
|
"""
|
@@ -178,7 +176,7 @@ _tool_registry: ToolRegistry | None = None
|
|
178
176
|
def get_tool_registry() -> ToolRegistry:
|
179
177
|
"""
|
180
178
|
Get the global tool registry instance.
|
181
|
-
|
179
|
+
|
182
180
|
Returns:
|
183
181
|
Tool registry instance.
|
184
182
|
"""
|
@@ -189,13 +187,11 @@ def get_tool_registry() -> ToolRegistry:
|
|
189
187
|
|
190
188
|
|
191
189
|
def register_tool_manager(
|
192
|
-
name: str,
|
193
|
-
manager_class: type[BaseToolManager],
|
194
|
-
aliases: list[str] | None = None
|
190
|
+
name: str, manager_class: type[BaseToolManager], aliases: list[str] | None = None
|
195
191
|
) -> None:
|
196
192
|
"""
|
197
193
|
Register a tool manager with the global registry.
|
198
|
-
|
194
|
+
|
199
195
|
Args:
|
200
196
|
name: Tool name.
|
201
197
|
manager_class: Tool manager class.
|
@@ -205,19 +201,16 @@ def register_tool_manager(
|
|
205
201
|
registry.register_tool_manager(name, manager_class, aliases)
|
206
202
|
|
207
203
|
|
208
|
-
def get_tool_manager(
|
209
|
-
name: str,
|
210
|
-
config: BaseConfig
|
211
|
-
) -> BaseToolManager | None:
|
204
|
+
def get_tool_manager(name: str, config: BaseConfig) -> BaseToolManager | None:
|
212
205
|
"""
|
213
206
|
Get a tool manager instance from the global registry.
|
214
|
-
|
207
|
+
|
215
208
|
Args:
|
216
209
|
name: Tool name or alias.
|
217
210
|
config: Configuration object.
|
218
|
-
|
211
|
+
|
219
212
|
Returns:
|
220
213
|
Tool manager instance, or None if not found.
|
221
214
|
"""
|
222
215
|
registry = get_tool_registry()
|
223
|
-
return registry.create_tool_manager(name, config)
|
216
|
+
return registry.create_tool_manager(name, config)
|