agentscope-runtime 1.0.1__py3-none-any.whl → 1.0.3__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.
- agentscope_runtime/adapters/agentscope/message.py +32 -7
- agentscope_runtime/adapters/agentscope/stream.py +121 -91
- agentscope_runtime/adapters/agno/__init__.py +0 -0
- agentscope_runtime/adapters/agno/message.py +30 -0
- agentscope_runtime/adapters/agno/stream.py +122 -0
- agentscope_runtime/adapters/langgraph/__init__.py +12 -0
- agentscope_runtime/adapters/langgraph/message.py +257 -0
- agentscope_runtime/adapters/langgraph/stream.py +205 -0
- agentscope_runtime/cli/__init__.py +7 -0
- agentscope_runtime/cli/cli.py +63 -0
- agentscope_runtime/cli/commands/__init__.py +2 -0
- agentscope_runtime/cli/commands/chat.py +815 -0
- agentscope_runtime/cli/commands/deploy.py +1074 -0
- agentscope_runtime/cli/commands/invoke.py +58 -0
- agentscope_runtime/cli/commands/list_cmd.py +103 -0
- agentscope_runtime/cli/commands/run.py +176 -0
- agentscope_runtime/cli/commands/sandbox.py +128 -0
- agentscope_runtime/cli/commands/status.py +60 -0
- agentscope_runtime/cli/commands/stop.py +185 -0
- agentscope_runtime/cli/commands/web.py +166 -0
- agentscope_runtime/cli/loaders/__init__.py +6 -0
- agentscope_runtime/cli/loaders/agent_loader.py +295 -0
- agentscope_runtime/cli/state/__init__.py +10 -0
- agentscope_runtime/cli/utils/__init__.py +18 -0
- agentscope_runtime/cli/utils/console.py +378 -0
- agentscope_runtime/cli/utils/validators.py +118 -0
- agentscope_runtime/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/engine/app/agent_app.py +55 -9
- agentscope_runtime/engine/deployers/__init__.py +1 -0
- agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +56 -1
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +449 -41
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +273 -0
- agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +640 -0
- agentscope_runtime/engine/deployers/agentrun_deployer.py +152 -22
- agentscope_runtime/engine/deployers/base.py +27 -2
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +161 -31
- agentscope_runtime/engine/deployers/local_deployer.py +188 -25
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +109 -18
- agentscope_runtime/engine/deployers/state/__init__.py +9 -0
- agentscope_runtime/engine/deployers/state/manager.py +388 -0
- agentscope_runtime/engine/deployers/state/schema.py +96 -0
- agentscope_runtime/engine/deployers/utils/build_cache.py +736 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +105 -30
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +31 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +23 -10
- agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +35 -2
- agentscope_runtime/engine/deployers/utils/k8s_utils.py +241 -0
- agentscope_runtime/engine/deployers/utils/net_utils.py +65 -0
- agentscope_runtime/engine/deployers/utils/package.py +56 -6
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +16 -2
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +155 -5
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +107 -123
- agentscope_runtime/engine/runner.py +30 -9
- agentscope_runtime/engine/schemas/exception.py +604 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +61 -8
- agentscope_runtime/engine/services/agent_state/state_service_factory.py +2 -5
- agentscope_runtime/engine/services/memory/redis_memory_service.py +129 -25
- agentscope_runtime/engine/services/session_history/redis_session_history_service.py +160 -34
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +113 -39
- agentscope_runtime/sandbox/box/shared/routers/mcp_utils.py +20 -4
- agentscope_runtime/sandbox/build.py +50 -57
- agentscope_runtime/sandbox/utils.py +2 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/METADATA +31 -8
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/RECORD +69 -36
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/entry_points.txt +1 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/WHEEL +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-1.0.1.dist-info → agentscope_runtime-1.0.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
A2A Registry Extension Point
|
|
4
|
+
|
|
5
|
+
Defines the abstract interface and helper utilities for A2A registry
|
|
6
|
+
implementations. Registry implementations are responsible for registering
|
|
7
|
+
agent services to service discovery systems (for example: Nacos).
|
|
8
|
+
|
|
9
|
+
This module focuses on clarity and small helper functions used by the
|
|
10
|
+
runtime to instantiate registry implementations from environment
|
|
11
|
+
configuration or .env files.
|
|
12
|
+
"""
|
|
13
|
+
import logging
|
|
14
|
+
import os
|
|
15
|
+
from abc import ABC, abstractmethod
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
18
|
+
|
|
19
|
+
from dotenv import find_dotenv, load_dotenv
|
|
20
|
+
from pydantic import ConfigDict
|
|
21
|
+
from pydantic_settings import BaseSettings
|
|
22
|
+
|
|
23
|
+
from a2a.types import AgentCard
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from v2.nacos import ClientConfig
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"A2ARegistry",
|
|
30
|
+
"A2ATransportsProperties",
|
|
31
|
+
"A2ARegistrySettings",
|
|
32
|
+
"get_registry_settings",
|
|
33
|
+
"create_registry_from_env",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class A2ATransportsProperties:
|
|
41
|
+
"""A2A transport properties for multi-transport support.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
host: Transport host
|
|
45
|
+
port: Transport port
|
|
46
|
+
path: Transport path
|
|
47
|
+
support_tls: Whether TLS is supported
|
|
48
|
+
extra: Additional transport properties
|
|
49
|
+
transport_type: Type of transport (e.g., "JSONRPC", "HTTP")
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
host: Optional[str] = None
|
|
53
|
+
port: Optional[int] = None
|
|
54
|
+
path: Optional[str] = None
|
|
55
|
+
support_tls: Optional[bool] = False
|
|
56
|
+
extra: Dict[str, Any] = field(default_factory=dict)
|
|
57
|
+
transport_type: str = "JSONRPC"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class A2ARegistry(ABC):
|
|
61
|
+
"""Abstract base class for A2A registry implementations.
|
|
62
|
+
|
|
63
|
+
Implementations should not raise on non-fatal errors during startup; the
|
|
64
|
+
runtime will catch and log exceptions so that registry failures do not
|
|
65
|
+
prevent the runtime from starting.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def registry_name(self) -> str:
|
|
70
|
+
"""Return a short name identifying the registry (e.g. "nacos")."""
|
|
71
|
+
raise NotImplementedError("Subclasses must implement registry_name()")
|
|
72
|
+
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def register(
|
|
75
|
+
self,
|
|
76
|
+
agent_card: AgentCard,
|
|
77
|
+
a2a_transports_properties: Optional[
|
|
78
|
+
List[A2ATransportsProperties]
|
|
79
|
+
] = None,
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Register an agent/service.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
agent_card: Agent card of this agent
|
|
85
|
+
a2a_transports_properties: Multiple transports for A2A Server,
|
|
86
|
+
and each transport might include different configs.
|
|
87
|
+
|
|
88
|
+
Implementations may register the agent card itself and/or endpoint
|
|
89
|
+
depending on their semantics.
|
|
90
|
+
"""
|
|
91
|
+
raise NotImplementedError("Subclasses must implement register()")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class A2ARegistrySettings(BaseSettings):
|
|
95
|
+
"""Settings that control A2A registry behavior.
|
|
96
|
+
|
|
97
|
+
Values are loaded from environment variables or a .env file when
|
|
98
|
+
`get_registry_settings()` is called.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
# Feature toggle
|
|
102
|
+
A2A_REGISTRY_ENABLED: bool = True
|
|
103
|
+
|
|
104
|
+
# Registry type(s). Can be a single value like "nacos" or a comma-separated
|
|
105
|
+
# list of registry types (e.g. "nacos").
|
|
106
|
+
A2A_REGISTRY_TYPE: Optional[str] = None
|
|
107
|
+
|
|
108
|
+
# Nacos specific configuration
|
|
109
|
+
NACOS_SERVER_ADDR: str = "localhost:8848"
|
|
110
|
+
NACOS_USERNAME: Optional[str] = None
|
|
111
|
+
NACOS_PASSWORD: Optional[str] = None
|
|
112
|
+
NACOS_NAMESPACE_ID: Optional[str] = None
|
|
113
|
+
NACOS_ACCESS_KEY: Optional[str] = None
|
|
114
|
+
NACOS_SECRET_KEY: Optional[str] = None
|
|
115
|
+
|
|
116
|
+
model_config = ConfigDict(
|
|
117
|
+
extra="allow",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
_registry_settings: Optional[A2ARegistrySettings] = None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_registry_settings() -> A2ARegistrySettings:
|
|
125
|
+
"""Return a singleton settings instance, loading .env files if needed."""
|
|
126
|
+
global _registry_settings
|
|
127
|
+
|
|
128
|
+
if _registry_settings is None:
|
|
129
|
+
# Inline _load_env_files() logic
|
|
130
|
+
# prefer a .env file if present, otherwise fall back to .env.example
|
|
131
|
+
dotenv_path = find_dotenv(raise_error_if_not_found=False)
|
|
132
|
+
if dotenv_path:
|
|
133
|
+
load_dotenv(dotenv_path, override=False)
|
|
134
|
+
else:
|
|
135
|
+
# If find_dotenv didn't find a file, try the explicit fallback name
|
|
136
|
+
if os.path.exists(".env.example"):
|
|
137
|
+
load_dotenv(".env.example", override=False)
|
|
138
|
+
_registry_settings = A2ARegistrySettings()
|
|
139
|
+
|
|
140
|
+
return _registry_settings
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _create_nacos_registry_from_settings(
|
|
144
|
+
settings: A2ARegistrySettings,
|
|
145
|
+
) -> Optional[A2ARegistry]:
|
|
146
|
+
"""Create a NacosRegistry instance from provided settings, or return
|
|
147
|
+
None if the required nacos SDK is not available or construction fails."""
|
|
148
|
+
try:
|
|
149
|
+
# lazy import so package is optional
|
|
150
|
+
from .nacos_a2a_registry import NacosRegistry
|
|
151
|
+
except ImportError:
|
|
152
|
+
logger.warning(
|
|
153
|
+
"[A2A] Nacos registry requested but nacos SDK not available. "
|
|
154
|
+
"Install with: pip install v2-nacos",
|
|
155
|
+
exc_info=False,
|
|
156
|
+
)
|
|
157
|
+
return None
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.warning(
|
|
160
|
+
"[A2A] Unexpected error during Nacos registry import: %s",
|
|
161
|
+
str(e),
|
|
162
|
+
exc_info=True,
|
|
163
|
+
)
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
nacos_client_config = _build_nacos_client_config(settings)
|
|
168
|
+
registry = NacosRegistry(nacos_client_config=nacos_client_config)
|
|
169
|
+
|
|
170
|
+
# Determine authentication status
|
|
171
|
+
auth_methods = []
|
|
172
|
+
if settings.NACOS_USERNAME and settings.NACOS_PASSWORD:
|
|
173
|
+
auth_methods.append("username/password")
|
|
174
|
+
if settings.NACOS_ACCESS_KEY and settings.NACOS_SECRET_KEY:
|
|
175
|
+
auth_methods.append("access_key")
|
|
176
|
+
auth_status = ", ".join(auth_methods) if auth_methods else "disabled"
|
|
177
|
+
|
|
178
|
+
namespace_info = (
|
|
179
|
+
f", namespace={settings.NACOS_NAMESPACE_ID}"
|
|
180
|
+
if settings.NACOS_NAMESPACE_ID
|
|
181
|
+
else ""
|
|
182
|
+
)
|
|
183
|
+
logger.info(
|
|
184
|
+
f"[A2A] Created Nacos registry from environment: "
|
|
185
|
+
f"server={settings.NACOS_SERVER_ADDR}, "
|
|
186
|
+
f"authentication={auth_status}{namespace_info}",
|
|
187
|
+
)
|
|
188
|
+
return registry
|
|
189
|
+
except Exception:
|
|
190
|
+
logger.warning(
|
|
191
|
+
"[A2A] Failed to construct Nacos registry from settings",
|
|
192
|
+
exc_info=True,
|
|
193
|
+
)
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _build_nacos_client_config(
|
|
198
|
+
settings: A2ARegistrySettings,
|
|
199
|
+
) -> Any:
|
|
200
|
+
"""Build Nacos client configuration from settings.
|
|
201
|
+
|
|
202
|
+
Supports both username/password and access key authentication.
|
|
203
|
+
"""
|
|
204
|
+
from v2.nacos import ClientConfigBuilder
|
|
205
|
+
|
|
206
|
+
builder = ClientConfigBuilder().server_address(settings.NACOS_SERVER_ADDR)
|
|
207
|
+
|
|
208
|
+
if settings.NACOS_NAMESPACE_ID:
|
|
209
|
+
builder.namespace_id(settings.NACOS_NAMESPACE_ID)
|
|
210
|
+
logger.debug(
|
|
211
|
+
"[A2A] Using Nacos namespace: %s",
|
|
212
|
+
settings.NACOS_NAMESPACE_ID,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
if settings.NACOS_USERNAME and settings.NACOS_PASSWORD:
|
|
216
|
+
builder.username(settings.NACOS_USERNAME).password(
|
|
217
|
+
settings.NACOS_PASSWORD,
|
|
218
|
+
)
|
|
219
|
+
logger.debug("[A2A] Using Nacos username/password authentication")
|
|
220
|
+
|
|
221
|
+
if settings.NACOS_ACCESS_KEY and settings.NACOS_SECRET_KEY:
|
|
222
|
+
builder.access_key(settings.NACOS_ACCESS_KEY).secret_key(
|
|
223
|
+
settings.NACOS_SECRET_KEY,
|
|
224
|
+
)
|
|
225
|
+
logger.debug("[A2A] Using Nacos access key authentication")
|
|
226
|
+
|
|
227
|
+
return builder.build()
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def create_registry_from_env() -> (
|
|
231
|
+
Optional[Union[A2ARegistry, List[A2ARegistry]]]
|
|
232
|
+
):
|
|
233
|
+
"""Create registry instance(s) from environment settings.
|
|
234
|
+
|
|
235
|
+
Supports single or multiple registry types (comma-separated).
|
|
236
|
+
Returns None if disabled or no valid registry created.
|
|
237
|
+
"""
|
|
238
|
+
settings = get_registry_settings()
|
|
239
|
+
|
|
240
|
+
if not settings.A2A_REGISTRY_ENABLED:
|
|
241
|
+
logger.debug("[A2A] Registry disabled via A2A_REGISTRY_ENABLED")
|
|
242
|
+
return None
|
|
243
|
+
|
|
244
|
+
# Inline _split_registry_types() logic
|
|
245
|
+
raw = settings.A2A_REGISTRY_TYPE
|
|
246
|
+
types = (
|
|
247
|
+
[r.strip().lower() for r in raw.split(",") if r.strip()] if raw else []
|
|
248
|
+
)
|
|
249
|
+
if not types:
|
|
250
|
+
logger.debug("[A2A] No registry type specified in A2A_REGISTRY_TYPE")
|
|
251
|
+
return None
|
|
252
|
+
|
|
253
|
+
registry_list: List[A2ARegistry] = []
|
|
254
|
+
|
|
255
|
+
for registry_type in types:
|
|
256
|
+
if registry_type == "nacos":
|
|
257
|
+
registry = _create_nacos_registry_from_settings(settings)
|
|
258
|
+
if registry:
|
|
259
|
+
registry_list.append(registry)
|
|
260
|
+
else:
|
|
261
|
+
logger.debug(
|
|
262
|
+
"[A2A] Skipping nacos registry due to earlier errors",
|
|
263
|
+
)
|
|
264
|
+
else:
|
|
265
|
+
logger.warning(
|
|
266
|
+
f"[A2A] Unknown registry type requested: "
|
|
267
|
+
f"{registry_type}. Supported: nacos",
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
if not registry_list:
|
|
271
|
+
return None
|
|
272
|
+
|
|
273
|
+
return registry_list[0] if len(registry_list) == 1 else registry_list
|