agentscope-runtime 1.0.4a1__py3-none-any.whl → 1.0.5__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.
Files changed (79) hide show
  1. agentscope_runtime/adapters/agentscope/stream.py +2 -8
  2. agentscope_runtime/adapters/langgraph/stream.py +120 -70
  3. agentscope_runtime/adapters/ms_agent_framework/__init__.py +0 -0
  4. agentscope_runtime/adapters/ms_agent_framework/message.py +205 -0
  5. agentscope_runtime/adapters/ms_agent_framework/stream.py +418 -0
  6. agentscope_runtime/adapters/utils.py +6 -0
  7. agentscope_runtime/cli/commands/deploy.py +836 -1
  8. agentscope_runtime/cli/commands/stop.py +16 -0
  9. agentscope_runtime/common/container_clients/__init__.py +52 -0
  10. agentscope_runtime/common/container_clients/agentrun_client.py +6 -4
  11. agentscope_runtime/common/container_clients/boxlite_client.py +442 -0
  12. agentscope_runtime/common/container_clients/docker_client.py +0 -20
  13. agentscope_runtime/common/container_clients/fc_client.py +6 -4
  14. agentscope_runtime/common/container_clients/gvisor_client.py +38 -0
  15. agentscope_runtime/common/container_clients/knative_client.py +467 -0
  16. agentscope_runtime/common/utils/deprecation.py +164 -0
  17. agentscope_runtime/engine/__init__.py +4 -0
  18. agentscope_runtime/engine/app/agent_app.py +16 -4
  19. agentscope_runtime/engine/constant.py +1 -0
  20. agentscope_runtime/engine/deployers/__init__.py +34 -11
  21. agentscope_runtime/engine/deployers/adapter/__init__.py +8 -0
  22. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +26 -51
  23. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +23 -13
  24. agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +4 -201
  25. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +152 -25
  26. agentscope_runtime/engine/deployers/adapter/agui/__init__.py +8 -0
  27. agentscope_runtime/engine/deployers/adapter/agui/agui_adapter_utils.py +652 -0
  28. agentscope_runtime/engine/deployers/adapter/agui/agui_protocol_adapter.py +225 -0
  29. agentscope_runtime/engine/deployers/agentrun_deployer.py +2 -2
  30. agentscope_runtime/engine/deployers/fc_deployer.py +1506 -0
  31. agentscope_runtime/engine/deployers/knative_deployer.py +290 -0
  32. agentscope_runtime/engine/deployers/pai_deployer.py +2335 -0
  33. agentscope_runtime/engine/deployers/utils/net_utils.py +37 -0
  34. agentscope_runtime/engine/deployers/utils/oss_utils.py +38 -0
  35. agentscope_runtime/engine/deployers/utils/package.py +46 -42
  36. agentscope_runtime/engine/helpers/agent_api_client.py +372 -0
  37. agentscope_runtime/engine/runner.py +13 -0
  38. agentscope_runtime/engine/schemas/agent_schemas.py +9 -3
  39. agentscope_runtime/engine/services/agent_state/__init__.py +7 -0
  40. agentscope_runtime/engine/services/memory/__init__.py +7 -0
  41. agentscope_runtime/engine/services/memory/redis_memory_service.py +15 -16
  42. agentscope_runtime/engine/services/session_history/__init__.py +7 -0
  43. agentscope_runtime/engine/tracing/local_logging_handler.py +2 -3
  44. agentscope_runtime/engine/tracing/wrapper.py +18 -4
  45. agentscope_runtime/sandbox/__init__.py +14 -6
  46. agentscope_runtime/sandbox/box/base/__init__.py +2 -2
  47. agentscope_runtime/sandbox/box/base/base_sandbox.py +51 -1
  48. agentscope_runtime/sandbox/box/browser/__init__.py +2 -2
  49. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +198 -2
  50. agentscope_runtime/sandbox/box/filesystem/__init__.py +2 -2
  51. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +99 -2
  52. agentscope_runtime/sandbox/box/gui/__init__.py +2 -2
  53. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +117 -1
  54. agentscope_runtime/sandbox/box/mobile/__init__.py +2 -2
  55. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +247 -100
  56. agentscope_runtime/sandbox/box/sandbox.py +102 -65
  57. agentscope_runtime/sandbox/box/shared/routers/generic.py +36 -29
  58. agentscope_runtime/sandbox/client/__init__.py +6 -1
  59. agentscope_runtime/sandbox/client/async_http_client.py +339 -0
  60. agentscope_runtime/sandbox/client/base.py +74 -0
  61. agentscope_runtime/sandbox/client/http_client.py +108 -329
  62. agentscope_runtime/sandbox/enums.py +7 -0
  63. agentscope_runtime/sandbox/manager/sandbox_manager.py +275 -29
  64. agentscope_runtime/sandbox/manager/server/app.py +7 -1
  65. agentscope_runtime/sandbox/manager/server/config.py +3 -1
  66. agentscope_runtime/sandbox/model/manager_config.py +11 -9
  67. agentscope_runtime/tools/modelstudio_memory/__init__.py +106 -0
  68. agentscope_runtime/tools/modelstudio_memory/base.py +220 -0
  69. agentscope_runtime/tools/modelstudio_memory/config.py +86 -0
  70. agentscope_runtime/tools/modelstudio_memory/core.py +594 -0
  71. agentscope_runtime/tools/modelstudio_memory/exceptions.py +60 -0
  72. agentscope_runtime/tools/modelstudio_memory/schemas.py +253 -0
  73. agentscope_runtime/version.py +1 -1
  74. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/METADATA +186 -73
  75. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/RECORD +79 -55
  76. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/WHEEL +0 -0
  77. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/entry_points.txt +0 -0
  78. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/licenses/LICENSE +0 -0
  79. {agentscope_runtime-1.0.4a1.dist-info → agentscope_runtime-1.0.5.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
+ # flake8: noqa: E501
2
3
  import logging
3
4
  import os
4
5
  import types
@@ -20,6 +21,7 @@ from ..deployers.adapter.a2a import (
20
21
  from ..deployers.adapter.responses.response_api_protocol_adapter import (
21
22
  ResponseAPIDefaultAdapter,
22
23
  )
24
+ from ..deployers.adapter.agui import AGUIDefaultAdapter, AGUIAdaptorConfig
23
25
  from ..deployers.utils.deployment_modes import DeploymentMode
24
26
  from ..deployers.utils.service_utils.fastapi_factory import FastAPIAppFactory
25
27
  from ..runner import Runner
@@ -52,6 +54,7 @@ class AgentApp(BaseApp):
52
54
  runner: Optional[Runner] = None,
53
55
  enable_embedded_worker: bool = False,
54
56
  a2a_config: Optional["AgentCardWithRuntimeConfig"] = None,
57
+ agui_config: Optional[AGUIAdaptorConfig] = None,
55
58
  **kwargs,
56
59
  ):
57
60
  """
@@ -74,11 +77,14 @@ class AgentApp(BaseApp):
74
77
  Must be an ``AgentCardWithRuntimeConfig`` instance, which
75
78
  contains ``agent_card`` (AgentCard object or dict) and runtime
76
79
  settings (host, port, registry, task_timeout, etc.).
77
- Example:
78
- from a2a.types import AgentCard, AgentCapabilities
79
- from agentscope_runtime.engine.deployers.adapter.a2a import ( # noqa: E501
80
+
81
+ Example::
82
+
83
+ from a2a.types import AgentCapabilities
84
+ from agentscope_runtime.engine.deployers.adapter.a2a import (
80
85
  AgentCardWithRuntimeConfig,
81
86
  )
87
+
82
88
  config = AgentCardWithRuntimeConfig(
83
89
  agent_card={
84
90
  "name": "MyAgent",
@@ -93,6 +99,7 @@ class AgentApp(BaseApp):
93
99
  registry=[nacos_registry],
94
100
  task_timeout=120,
95
101
  )
102
+ agui_config: Config for AGUI adaptor.
96
103
  **kwargs: Additional keyword arguments passed to FastAPI app
97
104
  """
98
105
 
@@ -125,7 +132,12 @@ class AgentApp(BaseApp):
125
132
  )
126
133
 
127
134
  response_protocol = ResponseAPIDefaultAdapter()
128
- self.protocol_adapters = [a2a_protocol, response_protocol]
135
+ agui_protocol = AGUIDefaultAdapter(config=agui_config)
136
+ self.protocol_adapters = [
137
+ a2a_protocol,
138
+ response_protocol,
139
+ agui_protocol,
140
+ ]
129
141
 
130
142
  self._app_kwargs = {
131
143
  "title": "Agent Service",
@@ -5,4 +5,5 @@ ALLOWED_FRAMEWORK_TYPES = [
5
5
  "autogen",
6
6
  "langgraph",
7
7
  "agno",
8
+ "ms_agent_framework",
8
9
  ]
@@ -1,25 +1,48 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .base import DeployManager
3
- from .local_deployer import LocalDeployManager
4
- from .kubernetes_deployer import (
5
- KubernetesDeployManager,
6
- K8sConfig,
7
- )
8
- from .modelstudio_deployer import (
9
- ModelstudioDeployManager,
2
+ from typing import TYPE_CHECKING
3
+ from ...common.utils.lazy_loader import install_lazy_loader
4
+
5
+ if TYPE_CHECKING:
6
+ from .base import DeployManager
7
+ from .local_deployer import LocalDeployManager
8
+ from .kubernetes_deployer import (
9
+ KubernetesDeployManager,
10
+ K8sConfig,
11
+ )
12
+ from .modelstudio_deployer import ModelstudioDeployManager
13
+ from .knative_deployer import KnativeDeployManager
14
+ from .agentrun_deployer import AgentRunDeployManager
15
+ from .fc_deployer import FCDeployManager
16
+
17
+ install_lazy_loader(
18
+ globals(),
19
+ {
20
+ "DeployManager": ".base",
21
+ "LocalDeployManager": ".local_deployer",
22
+ "KubernetesDeployManager": ".kubernetes_deployer",
23
+ "K8sConfig": ".kubernetes_deployer",
24
+ "ModelstudioDeployManager": ".modelstudio_deployer",
25
+ "KnativeDeployManager": ".knative_deployer",
26
+ "AgentRunDeployManager": ".agentrun_deployer",
27
+ "FCDeployManager": ".fc_deployer",
28
+ },
10
29
  )
11
30
 
12
31
  try:
13
- from .agentrun_deployer import (
14
- AgentRunDeployManager,
32
+ from .pai_deployer import (
33
+ PAIDeployManager,
15
34
  )
16
35
  except ImportError:
17
- AgentRunDeployManager = None # type: ignore
36
+ PAIDeployManager = None # type: ignore
18
37
 
19
38
  __all__ = [
39
+ "K8sConfig",
20
40
  "DeployManager",
21
41
  "LocalDeployManager",
22
42
  "KubernetesDeployManager",
23
43
  "ModelstudioDeployManager",
24
44
  "AgentRunDeployManager",
45
+ "KnativeDeployManager",
46
+ "FCDeployManager",
47
+ "PAIDeployManager",
25
48
  ]
@@ -1,2 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from .a2a import A2AFastAPIDefaultAdapter
3
+ from .agui import AGUIDefaultAdapter
4
+ from .responses import ResponseAPIDefaultAdapter
5
+
6
+ __all__ = [
7
+ "A2AFastAPIDefaultAdapter",
8
+ "AGUIDefaultAdapter",
9
+ "ResponseAPIDefaultAdapter",
10
+ ]
@@ -1,57 +1,32 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .a2a_protocol_adapter import (
3
- A2AFastAPIDefaultAdapter,
4
- AgentCardWithRuntimeConfig,
5
- extract_a2a_config,
6
- )
7
- from .a2a_registry import (
8
- A2ARegistry,
9
- A2ARegistrySettings,
10
- get_registry_settings,
11
- create_registry_from_env,
12
- )
2
+ from typing import TYPE_CHECKING
3
+ from .....common.utils.lazy_loader import install_lazy_loader
4
+
5
+ if TYPE_CHECKING:
6
+ from .a2a_protocol_adapter import (
7
+ A2AFastAPIDefaultAdapter,
8
+ AgentCardWithRuntimeConfig,
9
+ extract_a2a_config,
10
+ )
11
+ from .a2a_registry import A2ARegistry
12
+ from .nacos_a2a_registry import NacosRegistry
13
13
 
14
14
  # NOTE: NacosRegistry is NOT imported at module import time to avoid forcing
15
15
  # an optional dependency on environments that don't have nacos SDK installed.
16
- # Instead, NacosRegistry is imported lazily via __getattr__ (see below) when
16
+ # Instead, NacosRegistry is imported lazily via install_lazy_loader when
17
17
  # actually needed (e.g., when user does: from ... import NacosRegistry).
18
18
 
19
- __all__ = [
20
- "A2AFastAPIDefaultAdapter",
21
- "AgentCardWithRuntimeConfig",
22
- "extract_a2a_config",
23
- "A2ARegistry",
24
- "A2ARegistrySettings",
25
- "get_registry_settings",
26
- "create_registry_from_env",
27
- "NacosRegistry", # pylint: disable=undefined-all-variable
28
- ]
29
-
30
-
31
- def __getattr__(name: str):
32
- """
33
- Lazy import for NacosRegistry to avoid forcing optional nacos dependency.
34
-
35
- This function is called by Python when an attribute is accessed
36
- that doesn't exist at module level. This allows NacosRegistry
37
- to be imported only when actually needed, rather than at module
38
- import time.
39
-
40
- If the nacos SDK is not installed, provides a helpful error message
41
- instead of a confusing ImportError.
42
- """
43
- if name == "NacosRegistry":
44
- try:
45
- from .nacos_a2a_registry import NacosRegistry
46
-
47
- return NacosRegistry
48
- except ImportError as e:
49
- # Check if it's the v2.nacos dependency that's missing
50
- if "v2.nacos" in str(e) or "nacos" in str(e).lower():
51
- raise ImportError(
52
- "NacosRegistry requires the 'v2-nacos' package. "
53
- "Install it with: pip install v2-nacos",
54
- ) from e
55
- # Re-raise other import errors as-is
56
- raise
57
- raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
19
+ install_lazy_loader(
20
+ globals(),
21
+ {
22
+ "A2AFastAPIDefaultAdapter": ".a2a_protocol_adapter",
23
+ "AgentCardWithRuntimeConfig": ".a2a_protocol_adapter",
24
+ "extract_a2a_config": ".a2a_protocol_adapter",
25
+ "A2ARegistry": ".a2a_registry",
26
+ "NacosRegistry": {
27
+ "module": ".nacos_a2a_registry",
28
+ "hint": "NacosRegistry requires the 'nacos-sdk-python' package. "
29
+ "Install it with: pip install nacos-sdk-python",
30
+ },
31
+ },
32
+ )
@@ -19,19 +19,18 @@ from a2a.types import (
19
19
  AgentCard,
20
20
  AgentSkill,
21
21
  )
22
+ from a2a.utils import AGENT_CARD_WELL_KNOWN_PATH
22
23
  from fastapi import FastAPI
23
24
  from pydantic import ConfigDict, BaseModel, field_validator
24
25
 
25
26
  from agentscope_runtime.engine.deployers.utils.net_utils import (
26
27
  get_first_non_loopback_ip,
27
28
  )
28
- from agentscope_runtime.version import __version__ as runtime_version
29
29
 
30
30
  from .a2a_agent_adapter import A2AExecutor
31
31
  from .a2a_registry import (
32
32
  A2ARegistry,
33
33
  A2ATransportsProperties,
34
- create_registry_from_env,
35
34
  )
36
35
 
37
36
  # NOTE: Do NOT import NacosRegistry at module import time to avoid
@@ -44,7 +43,7 @@ from ..protocol_adapter import ProtocolAdapter
44
43
  logger = logging.getLogger(__name__)
45
44
 
46
45
  A2A_JSON_RPC_URL = "/a2a"
47
- DEFAULT_WELLKNOWN_PATH = "/.wellknown/agent-card.json"
46
+ DEFAULT_WELLKNOWN_PATH = AGENT_CARD_WELL_KNOWN_PATH
48
47
  DEFAULT_TASK_TIMEOUT = 60
49
48
  DEFAULT_TASK_EVENT_TIMEOUT = 10
50
49
  DEFAULT_TRANSPORT = "JSONRPC"
@@ -56,26 +55,37 @@ AGENT_VERSION = "1.0.0"
56
55
  def extract_a2a_config(
57
56
  a2a_config: Optional["AgentCardWithRuntimeConfig"] = None,
58
57
  ) -> "AgentCardWithRuntimeConfig":
59
- """Normalize a2a_config to AgentCardWithRuntimeConfig object.
58
+ """Normalize ``a2a_config`` to an ``AgentCardWithRuntimeConfig`` object.
60
59
 
61
- Ensures a non-null ``AgentCardWithRuntimeConfig`` instance and sets up
62
- environment-based registry fallback if registry is not provided.
60
+ Registry resolution priority:
61
+
62
+ 1. Use ``registry`` from ``a2a_config`` if provided.
63
+ 2. Fallback to environment variables if ``a2a_config.registry`` is
64
+ ``None``.
65
+ 3. If neither is available, registry remains ``None``
66
+ (user doesn't want it).
63
67
 
64
68
  Args:
65
- a2a_config: Optional AgentCardWithRuntimeConfig instance.
69
+ a2a_config: Optional ``AgentCardWithRuntimeConfig`` instance.
66
70
 
67
71
  Returns:
68
- Normalized AgentCardWithRuntimeConfig object.
72
+ Normalized ``AgentCardWithRuntimeConfig`` object.
69
73
  """
70
74
  if a2a_config is None:
71
75
  a2a_config = AgentCardWithRuntimeConfig()
72
76
 
73
- # Fallback to environment registry if not provided
77
+ # Try environment variables only if registry is not explicitly provided
74
78
  if a2a_config.registry is None:
75
- env_registry = create_registry_from_env()
76
- if env_registry is not None:
77
- a2a_config.registry = env_registry
78
- logger.debug("[A2A] Using registry from environment variables")
79
+ try:
80
+ from .nacos_a2a_registry import create_nacos_registry_from_env
81
+
82
+ env_registry = create_nacos_registry_from_env()
83
+ if env_registry is not None:
84
+ a2a_config.registry = env_registry
85
+ logger.debug("[A2A] Using registry from environment variables")
86
+ except ImportError:
87
+ # Nacos SDK not available, registry remains None
88
+ logger.debug("[A2A] Nacos registry not available")
79
89
 
80
90
  return a2a_config
81
91
 
@@ -2,35 +2,20 @@
2
2
  """
3
3
  A2A Registry Extension Point
4
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.
5
+ Defines the abstract interface for A2A registry implementations.
6
+ Registry implementations are responsible for registering agent services
7
+ to service discovery systems (for example: Nacos).
12
8
  """
13
9
  import logging
14
- import os
15
10
  from abc import ABC, abstractmethod
16
11
  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
12
+ from typing import Any, Dict, List, Optional
22
13
 
23
14
  from a2a.types import AgentCard
24
15
 
25
- if TYPE_CHECKING:
26
- from v2.nacos import ClientConfig
27
-
28
16
  __all__ = [
29
17
  "A2ARegistry",
30
18
  "A2ATransportsProperties",
31
- "A2ARegistrySettings",
32
- "get_registry_settings",
33
- "create_registry_from_env",
34
19
  ]
35
20
 
36
21
  logger = logging.getLogger(__name__)
@@ -89,185 +74,3 @@ class A2ARegistry(ABC):
89
74
  depending on their semantics.
90
75
  """
91
76
  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