agnt5 0.1.1__cp39-abi3-manylinux_2_34_aarch64.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.
- agnt5/__init__.py +27 -0
- agnt5/_compat.py +15 -0
- agnt5/_core.abi3.so +0 -0
- agnt5/decorators.py +198 -0
- agnt5/version.py +23 -0
- agnt5/worker.py +44 -0
- agnt5/worker_manager.py +163 -0
- agnt5-0.1.1.dist-info/METADATA +18 -0
- agnt5-0.1.1.dist-info/RECORD +10 -0
- agnt5-0.1.1.dist-info/WHEEL +4 -0
agnt5/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AGNT5 Python SDK - Build durable, resilient agent-first applications.
|
|
3
|
+
|
|
4
|
+
This SDK provides high-level components for building agents, tools, and workflows
|
|
5
|
+
with built-in durability guarantees and state management, backed by a high-performance
|
|
6
|
+
Rust core.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .version import _get_version
|
|
10
|
+
# Import compatibility checks
|
|
11
|
+
from ._compat import _rust_available, _import_error
|
|
12
|
+
|
|
13
|
+
# Import decorators
|
|
14
|
+
from .decorators import function
|
|
15
|
+
|
|
16
|
+
# Import high-level Worker
|
|
17
|
+
from .worker_manager import Worker
|
|
18
|
+
|
|
19
|
+
__version__ = _get_version()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Import the Rust core if available
|
|
23
|
+
if _rust_available:
|
|
24
|
+
from ._core import (
|
|
25
|
+
PyWorker
|
|
26
|
+
)
|
|
27
|
+
|
agnt5/_compat.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Compatibility utilities for the AGNT5 Python SDK.
|
|
3
|
+
|
|
4
|
+
This module handles runtime compatibility checks and provides utilities
|
|
5
|
+
for cross-referencing throughout the project.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Check if Rust core is available
|
|
9
|
+
try:
|
|
10
|
+
from . import _core
|
|
11
|
+
_rust_available = True
|
|
12
|
+
_import_error = None
|
|
13
|
+
except ImportError as e:
|
|
14
|
+
_rust_available = False
|
|
15
|
+
_import_error = e
|
agnt5/_core.abi3.so
ADDED
|
Binary file
|
agnt5/decorators.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Function decorators for AGNT5 workers.
|
|
3
|
+
|
|
4
|
+
This module provides decorators for registering functions as handlers
|
|
5
|
+
that can be invoked through the AGNT5 platform.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import functools
|
|
9
|
+
import inspect
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
# Global registry of decorated functions
|
|
16
|
+
_function_registry: Dict[str, Callable] = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def function(name: str = None):
|
|
20
|
+
"""
|
|
21
|
+
Decorator to register a function as an AGNT5 handler.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
name: The name to register the function under. If None, uses the function's name.
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
@function("add_numbers")
|
|
28
|
+
def add_numbers(ctx, a: int, b: int) -> int:
|
|
29
|
+
return a + b
|
|
30
|
+
|
|
31
|
+
@function()
|
|
32
|
+
def greet_user(ctx, name: str) -> str:
|
|
33
|
+
return f"Hello, {name}!"
|
|
34
|
+
"""
|
|
35
|
+
def decorator(func: Callable) -> Callable:
|
|
36
|
+
handler_name = name if name is not None else func.__name__
|
|
37
|
+
|
|
38
|
+
# Store function metadata
|
|
39
|
+
func._agnt5_handler_name = handler_name
|
|
40
|
+
func._agnt5_is_function = True
|
|
41
|
+
|
|
42
|
+
# Register in global registry
|
|
43
|
+
_function_registry[handler_name] = func
|
|
44
|
+
|
|
45
|
+
logger.debug(f"Registered function handler: {handler_name}")
|
|
46
|
+
|
|
47
|
+
@functools.wraps(func)
|
|
48
|
+
def wrapper(*args, **kwargs):
|
|
49
|
+
return func(*args, **kwargs)
|
|
50
|
+
|
|
51
|
+
# Copy metadata to wrapper
|
|
52
|
+
wrapper._agnt5_handler_name = handler_name
|
|
53
|
+
wrapper._agnt5_is_function = True
|
|
54
|
+
|
|
55
|
+
return wrapper
|
|
56
|
+
|
|
57
|
+
return decorator
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_registered_functions() -> Dict[str, Callable]:
|
|
61
|
+
"""
|
|
62
|
+
Get all registered function handlers.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Dictionary mapping handler names to functions
|
|
66
|
+
"""
|
|
67
|
+
return _function_registry.copy()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def get_function_metadata(func: Callable) -> Optional[Dict[str, Any]]:
|
|
71
|
+
"""
|
|
72
|
+
Extract metadata from a decorated function.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
func: The function to extract metadata from
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Dictionary with function metadata or None if not decorated
|
|
79
|
+
"""
|
|
80
|
+
if not hasattr(func, '_agnt5_is_function'):
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
signature = inspect.signature(func)
|
|
84
|
+
parameters = []
|
|
85
|
+
|
|
86
|
+
for param_name, param in signature.parameters.items():
|
|
87
|
+
if param_name == 'ctx': # Skip context parameter
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
param_info = {
|
|
91
|
+
'name': param_name,
|
|
92
|
+
'type': 'any' # Default type, could be enhanced with type hints
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Extract type information if available
|
|
96
|
+
if param.annotation != inspect.Parameter.empty:
|
|
97
|
+
param_info['type'] = str(param.annotation.__name__ if hasattr(param.annotation, '__name__') else param.annotation)
|
|
98
|
+
|
|
99
|
+
if param.default != inspect.Parameter.empty:
|
|
100
|
+
param_info['default'] = param.default
|
|
101
|
+
|
|
102
|
+
parameters.append(param_info)
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
'name': func._agnt5_handler_name,
|
|
106
|
+
'type': 'function',
|
|
107
|
+
'parameters': parameters,
|
|
108
|
+
'return_type': str(signature.return_annotation.__name__ if signature.return_annotation != inspect.Parameter.empty else 'any')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def clear_registry():
|
|
113
|
+
"""Clear the function registry. Mainly for testing."""
|
|
114
|
+
global _function_registry
|
|
115
|
+
_function_registry.clear()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def invoke_function(handler_name: str, input_data: bytes, context: Any = None) -> bytes:
|
|
119
|
+
"""
|
|
120
|
+
Invoke a registered function handler.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
handler_name: Name of the handler to invoke
|
|
124
|
+
input_data: Input data as bytes (will be decoded from JSON)
|
|
125
|
+
context: Execution context
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Function result as bytes (JSON encoded)
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
ValueError: If handler is not found
|
|
132
|
+
RuntimeError: If function execution fails
|
|
133
|
+
"""
|
|
134
|
+
import json
|
|
135
|
+
|
|
136
|
+
if handler_name not in _function_registry:
|
|
137
|
+
raise ValueError(f"Handler '{handler_name}' not found")
|
|
138
|
+
|
|
139
|
+
func = _function_registry[handler_name]
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
# Decode input data
|
|
143
|
+
if input_data:
|
|
144
|
+
print(f"📨 Received function invocation: {handler_name}")
|
|
145
|
+
|
|
146
|
+
# Check if this is protobuf data by looking for the pattern
|
|
147
|
+
try:
|
|
148
|
+
raw_data = input_data.decode('utf-8')
|
|
149
|
+
input_params = json.loads(raw_data)
|
|
150
|
+
except (UnicodeDecodeError, json.JSONDecodeError):
|
|
151
|
+
# This is protobuf data - extract the JSON payload
|
|
152
|
+
# The JSON is embedded after the \x1a<length> pattern
|
|
153
|
+
start_idx = input_data.find(b'\x1a')
|
|
154
|
+
if start_idx != -1 and start_idx + 1 < len(input_data):
|
|
155
|
+
# The byte after \x1a indicates the length of the JSON data
|
|
156
|
+
json_length = input_data[start_idx + 1]
|
|
157
|
+
json_start = start_idx + 2
|
|
158
|
+
|
|
159
|
+
if json_start + json_length <= len(input_data):
|
|
160
|
+
json_bytes = input_data[json_start:json_start + json_length]
|
|
161
|
+
raw_data = json_bytes.decode('utf-8')
|
|
162
|
+
print(f"📋 Extracted JSON from protobuf: {raw_data}")
|
|
163
|
+
input_params = json.loads(raw_data)
|
|
164
|
+
else:
|
|
165
|
+
raise ValueError("Invalid protobuf structure - JSON length exceeds available data")
|
|
166
|
+
else:
|
|
167
|
+
raise ValueError("Could not find JSON data in protobuf message")
|
|
168
|
+
else:
|
|
169
|
+
input_params = {}
|
|
170
|
+
|
|
171
|
+
logger.debug(f"Invoking function {handler_name} with params: {input_params}")
|
|
172
|
+
|
|
173
|
+
# Call function with context as first parameter
|
|
174
|
+
if isinstance(input_params, dict):
|
|
175
|
+
result = func(context, **input_params)
|
|
176
|
+
else:
|
|
177
|
+
# Handle case where input is not a dict (e.g., single value)
|
|
178
|
+
result = func(context, input_params)
|
|
179
|
+
|
|
180
|
+
# Encode result
|
|
181
|
+
if result is None:
|
|
182
|
+
result_data = b""
|
|
183
|
+
else:
|
|
184
|
+
result_json = json.dumps(result)
|
|
185
|
+
result_data = result_json.encode('utf-8')
|
|
186
|
+
|
|
187
|
+
logger.debug(f"Function {handler_name} completed successfully")
|
|
188
|
+
return result_data
|
|
189
|
+
|
|
190
|
+
except json.JSONDecodeError as e:
|
|
191
|
+
print(f"❌ JSON parsing failed: {e}")
|
|
192
|
+
print(f"📋 Failed to parse: {repr(raw_data if 'raw_data' in locals() else 'No raw_data available')}")
|
|
193
|
+
logger.error(f"JSON decode error for {handler_name}: {e}")
|
|
194
|
+
raise RuntimeError(f"Invalid JSON input: {e}")
|
|
195
|
+
except Exception as e:
|
|
196
|
+
print(f"❌ Function '{handler_name}' failed: {type(e).__name__}: {e}")
|
|
197
|
+
logger.error(f"Function {handler_name} failed: {e}")
|
|
198
|
+
raise RuntimeError(f"Function execution failed: {e}")
|
agnt5/version.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
# Read version from pyproject.toml to maintain single source of truth
|
|
4
|
+
def _get_version():
|
|
5
|
+
try:
|
|
6
|
+
import tomllib
|
|
7
|
+
except ImportError:
|
|
8
|
+
# Python < 3.11 fallback
|
|
9
|
+
try:
|
|
10
|
+
import tomli as tomllib
|
|
11
|
+
except ImportError:
|
|
12
|
+
# Final fallback if no toml library available
|
|
13
|
+
return "UNKNOWN"
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import pathlib
|
|
17
|
+
pyproject_path = pathlib.Path(__file__).parent.parent.parent / "pyproject.toml"
|
|
18
|
+
with open(pyproject_path, "rb") as f:
|
|
19
|
+
pyproject_data = tomllib.load(f)
|
|
20
|
+
return pyproject_data["project"]["version"]
|
|
21
|
+
except Exception:
|
|
22
|
+
# Fallback version if reading fails
|
|
23
|
+
return "UNKNOWN"
|
agnt5/worker.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from ._compat import _rust_available, _import_error
|
|
2
|
+
|
|
3
|
+
def get_worker(
|
|
4
|
+
service_name: str,
|
|
5
|
+
service_version: str = "1.0.0",
|
|
6
|
+
coordinator_endpoint: str = None,
|
|
7
|
+
auto_register: bool = True,
|
|
8
|
+
) -> "DurableWorker":
|
|
9
|
+
"""
|
|
10
|
+
Create a new durable worker using the Rust core.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
service_name: Name of the service
|
|
14
|
+
service_version: Version of the service
|
|
15
|
+
coordinator_endpoint: Endpoint of the coordinator service
|
|
16
|
+
auto_register: Whether to automatically register decorated components
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
A configured DurableWorker instance
|
|
20
|
+
|
|
21
|
+
Raises:
|
|
22
|
+
RuntimeError: If the Rust core is not available
|
|
23
|
+
"""
|
|
24
|
+
if not _rust_available:
|
|
25
|
+
raise RuntimeError(f"Rust core is required but not available: {_import_error}. Please build and install the Rust extension first.")
|
|
26
|
+
|
|
27
|
+
# Use the high-performance Rust core
|
|
28
|
+
import uuid
|
|
29
|
+
|
|
30
|
+
worker_id = str(uuid.uuid4())
|
|
31
|
+
|
|
32
|
+
rust_worker = create_worker(
|
|
33
|
+
worker_id=worker_id,
|
|
34
|
+
service_name=service_name,
|
|
35
|
+
version=service_version,
|
|
36
|
+
coordinator_endpoint=coordinator_endpoint,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
worker = DurableWorker(rust_worker)
|
|
40
|
+
|
|
41
|
+
# Store auto-registration preference for later use
|
|
42
|
+
worker._auto_register = auto_register
|
|
43
|
+
|
|
44
|
+
return worker
|
agnt5/worker_manager.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"""
|
|
2
|
+
High-level Worker manager that integrates function decorators with the Rust core.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import time
|
|
7
|
+
from typing import Any, Dict, List, Optional
|
|
8
|
+
|
|
9
|
+
from ._compat import _rust_available, _import_error
|
|
10
|
+
from .decorators import get_registered_functions, get_function_metadata, invoke_function
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Worker:
|
|
16
|
+
"""
|
|
17
|
+
High-level AGNT5 Worker that automatically registers decorated functions.
|
|
18
|
+
|
|
19
|
+
This class wraps the low-level Rust PyWorker and provides automatic
|
|
20
|
+
registration of @function decorated handlers.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self,
|
|
24
|
+
service_name: str,
|
|
25
|
+
service_version: str = "1.0.0",
|
|
26
|
+
coordinator_endpoint: str = "http://localhost:9091"):
|
|
27
|
+
"""
|
|
28
|
+
Initialize the worker.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
service_name: Name of the service
|
|
32
|
+
service_version: Version of the service
|
|
33
|
+
coordinator_endpoint: Endpoint of the coordinator service
|
|
34
|
+
"""
|
|
35
|
+
if not _rust_available:
|
|
36
|
+
raise RuntimeError(f"Rust core is required but not available: {_import_error}")
|
|
37
|
+
|
|
38
|
+
self.service_name = service_name
|
|
39
|
+
self.service_version = service_version
|
|
40
|
+
self.coordinator_endpoint = coordinator_endpoint
|
|
41
|
+
|
|
42
|
+
# Import and create Rust worker
|
|
43
|
+
from ._core import PyWorker
|
|
44
|
+
self._rust_worker = PyWorker(
|
|
45
|
+
coordinator_endpoint,
|
|
46
|
+
service_name,
|
|
47
|
+
service_version,
|
|
48
|
+
"python"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
self._running = False
|
|
52
|
+
|
|
53
|
+
logger.info(f"Worker created: {service_name} v{service_version}")
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def worker_id(self) -> str:
|
|
57
|
+
"""Get the worker ID."""
|
|
58
|
+
return self._rust_worker.worker_id()
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def tenant_id(self) -> Optional[str]:
|
|
62
|
+
"""Get the tenant ID."""
|
|
63
|
+
return self._rust_worker.tenant_id()
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def deployment_id(self) -> Optional[str]:
|
|
67
|
+
"""Get the deployment ID."""
|
|
68
|
+
return self._rust_worker.deployment_id()
|
|
69
|
+
|
|
70
|
+
def start(self):
|
|
71
|
+
"""
|
|
72
|
+
Start the worker and register all decorated functions.
|
|
73
|
+
|
|
74
|
+
This will:
|
|
75
|
+
1. Start the underlying Rust worker
|
|
76
|
+
2. Wait for successful registration with coordinator
|
|
77
|
+
3. Collect all @function decorated handlers
|
|
78
|
+
"""
|
|
79
|
+
logger.info(f"Starting worker {self.service_name}...")
|
|
80
|
+
|
|
81
|
+
# Start the Rust worker first
|
|
82
|
+
self._rust_worker.start()
|
|
83
|
+
|
|
84
|
+
# Give it a moment to connect and register
|
|
85
|
+
# TODO: Replace with proper callback mechanism from Rust core
|
|
86
|
+
time.sleep(1.0) # Increased timeout for registration
|
|
87
|
+
|
|
88
|
+
# Check if worker is still running (registration successful)
|
|
89
|
+
if not self._rust_worker.is_running():
|
|
90
|
+
raise RuntimeError(f"Worker {self.service_name} failed to start or register")
|
|
91
|
+
|
|
92
|
+
# Register all decorated functions
|
|
93
|
+
self._register_functions()
|
|
94
|
+
|
|
95
|
+
self._running = True
|
|
96
|
+
logger.info(f"Worker {self.service_name} connected and registered successfully")
|
|
97
|
+
|
|
98
|
+
def stop(self):
|
|
99
|
+
"""Stop the worker."""
|
|
100
|
+
logger.info(f"Stopping worker {self.service_name}...")
|
|
101
|
+
|
|
102
|
+
self._running = False
|
|
103
|
+
self._rust_worker.stop()
|
|
104
|
+
|
|
105
|
+
logger.info(f"Worker {self.service_name} stopped")
|
|
106
|
+
|
|
107
|
+
def is_running(self) -> bool:
|
|
108
|
+
"""Check if the worker is running."""
|
|
109
|
+
return self._running and self._rust_worker.is_running()
|
|
110
|
+
|
|
111
|
+
def _register_functions(self):
|
|
112
|
+
"""Register all decorated functions with the Worker Coordinator."""
|
|
113
|
+
functions = get_registered_functions()
|
|
114
|
+
|
|
115
|
+
if not functions:
|
|
116
|
+
logger.warning("No @function decorated handlers found")
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
logger.info(f"Registering {len(functions)} function handlers: {list(functions.keys())}")
|
|
120
|
+
|
|
121
|
+
# Build component list for registration
|
|
122
|
+
components = []
|
|
123
|
+
for handler_name, func in functions.items():
|
|
124
|
+
metadata = get_function_metadata(func)
|
|
125
|
+
if metadata:
|
|
126
|
+
components.append({
|
|
127
|
+
'name': handler_name,
|
|
128
|
+
'type': 'function',
|
|
129
|
+
'metadata': metadata
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
# TODO: Use the Rust worker to send registration message
|
|
133
|
+
# For now, just log the components that would be registered
|
|
134
|
+
logger.info(f"Would register components: {components}")
|
|
135
|
+
|
|
136
|
+
def handle_invocation(self, handler_name: str, input_data: bytes) -> bytes:
|
|
137
|
+
"""
|
|
138
|
+
Handle a function invocation request.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
handler_name: Name of the handler to invoke
|
|
142
|
+
input_data: Input data as bytes
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Function result as bytes
|
|
146
|
+
"""
|
|
147
|
+
logger.info(f"Handling invocation: {handler_name}")
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
# Create a basic context object
|
|
151
|
+
context = {
|
|
152
|
+
'worker_id': self.worker_id,
|
|
153
|
+
'service_name': self.service_name,
|
|
154
|
+
'handler_name': handler_name
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
result = invoke_function(handler_name, input_data, context)
|
|
158
|
+
logger.info(f"Invocation {handler_name} completed successfully")
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
except Exception as e:
|
|
162
|
+
logger.error(f"Invocation {handler_name} failed: {e}")
|
|
163
|
+
raise
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agnt5
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: maturin>=1.9.3
|
|
13
|
+
Summary: AGNT5 Python SDK - Build durable, resilient agent-first applications
|
|
14
|
+
Author-email: AGNT5 Team <team@agnt5.com>
|
|
15
|
+
License: Apache-2.0
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Project-URL: Homepage, https://agnt5.dev
|
|
18
|
+
Project-URL: Documentation, https://docs.agnt5.dev
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
agnt5-0.1.1.dist-info/METADATA,sha256=aAtTmCD-mFWTHk6haLGMlGgJ1-UAW6Wu6zPg39RkLpY,723
|
|
2
|
+
agnt5-0.1.1.dist-info/WHEEL,sha256=wXFsR52eKbC_1u1hvryOgwsP7iu1Vt96HUw7DlYPh-E,107
|
|
3
|
+
agnt5/__init__.py,sha256=RQMVsOLj01XYYPjOWkQgohOZcmDLc3iMWZ8il7t5f38,630
|
|
4
|
+
agnt5/_compat.py,sha256=jNfxdubYi3XbhPN6_bAXP4TCEdocZltiB4r2AugiWl4,367
|
|
5
|
+
agnt5/_core.abi3.so,sha256=jWjq2YB7yUk630EJp_XvyjsZw4xzAX0LP8HvmJ8nYY4,3641992
|
|
6
|
+
agnt5/decorators.py,sha256=iSnKN2vL48KQYC6tBG3sNzlCPDzCndJbyjhwn3VPUy8,6824
|
|
7
|
+
agnt5/version.py,sha256=ZJQ4ut-NS1vc8qIEUnUqdfsBK0nCG60qdz34_b5H0co,703
|
|
8
|
+
agnt5/worker.py,sha256=oyBzguGRpT7lOVQOlJxu4bT-7Dg1LaVzesb2c4m_gOk,1276
|
|
9
|
+
agnt5/worker_manager.py,sha256=IiRy0zMUgf8VVs14XUDoYsNaiwYl-JaWB1EqgaXw4XA,5537
|
|
10
|
+
agnt5-0.1.1.dist-info/RECORD,,
|