agentscope-runtime 1.0.2__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.
Files changed (25) hide show
  1. agentscope_runtime/cli/commands/deploy.py +12 -0
  2. agentscope_runtime/common/collections/redis_mapping.py +4 -1
  3. agentscope_runtime/engine/app/agent_app.py +48 -5
  4. agentscope_runtime/engine/deployers/adapter/a2a/__init__.py +56 -1
  5. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +449 -41
  6. agentscope_runtime/engine/deployers/adapter/a2a/a2a_registry.py +273 -0
  7. agentscope_runtime/engine/deployers/adapter/a2a/nacos_a2a_registry.py +640 -0
  8. agentscope_runtime/engine/deployers/kubernetes_deployer.py +3 -0
  9. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +8 -2
  10. agentscope_runtime/engine/deployers/utils/docker_image_utils/image_factory.py +5 -0
  11. agentscope_runtime/engine/deployers/utils/net_utils.py +65 -0
  12. agentscope_runtime/engine/runner.py +5 -3
  13. agentscope_runtime/engine/schemas/exception.py +24 -0
  14. agentscope_runtime/engine/services/agent_state/redis_state_service.py +61 -8
  15. agentscope_runtime/engine/services/agent_state/state_service_factory.py +2 -5
  16. agentscope_runtime/engine/services/memory/redis_memory_service.py +129 -25
  17. agentscope_runtime/engine/services/session_history/redis_session_history_service.py +160 -34
  18. agentscope_runtime/sandbox/build.py +50 -57
  19. agentscope_runtime/version.py +1 -1
  20. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/METADATA +9 -3
  21. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/RECORD +25 -22
  22. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/WHEEL +0 -0
  23. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/entry_points.txt +0 -0
  24. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/licenses/LICENSE +0 -0
  25. {agentscope_runtime-1.0.2.dist-info → agentscope_runtime-1.0.3.dist-info}/top_level.txt +0 -0
@@ -828,6 +828,13 @@ def agentrun(
828
828
  help="Target platform (e.g., 'linux/amd64', 'linux/arm64')",
829
829
  default="linux/amd64",
830
830
  )
831
+ @click.option(
832
+ "--pypi-mirror",
833
+ help="PyPI mirror URL for pip package installation (e.g., "
834
+ "https://pypi.tuna.tsinghua.edu.cn/simple). If not specified, "
835
+ "uses pip default.",
836
+ default=None,
837
+ )
831
838
  def k8s(
832
839
  source: str,
833
840
  name: str,
@@ -854,6 +861,7 @@ def k8s(
854
861
  deploy_timeout: int,
855
862
  health_check: bool,
856
863
  platform: str,
864
+ pypi_mirror: str,
857
865
  ):
858
866
  """
859
867
  Deploy to Kubernetes/ACK.
@@ -898,6 +906,7 @@ def k8s(
898
906
  "deploy_timeout": deploy_timeout,
899
907
  "health_check": health_check,
900
908
  "platform": platform,
909
+ "pypi_mirror": pypi_mirror,
901
910
  }
902
911
  merged_config = _merge_config(config_dict, cli_params)
903
912
 
@@ -918,6 +927,7 @@ def k8s(
918
927
  deploy_timeout = merged_config.get("deploy_timeout", 300)
919
928
  health_check = merged_config.get("health_check", True)
920
929
  platform = merged_config.get("platform")
930
+ pypi_mirror = merged_config.get("pypi_mirror")
921
931
 
922
932
  # Handle requirements (can be comma-separated string, list, or file
923
933
  # path)
@@ -1033,6 +1043,8 @@ def k8s(
1033
1043
  deploy_params["health_check"] = health_check
1034
1044
  if platform:
1035
1045
  deploy_params["platform"] = platform
1046
+ if pypi_mirror:
1047
+ deploy_params["pypi_mirror"] = pypi_mirror
1036
1048
 
1037
1049
  # Add agent_source for state saving
1038
1050
  deploy_params["agent_source"] = abs_source
@@ -38,7 +38,10 @@ class RedisMapping(Mapping):
38
38
  match=search_pattern,
39
39
  )
40
40
  for key in keys:
41
- decoded_key = key.decode("utf-8")
41
+ if isinstance(key, bytes):
42
+ decoded_key = key.decode("utf-8")
43
+ else:
44
+ decoded_key = str(key)
42
45
  yield self._strip_prefix(decoded_key)
43
46
 
44
47
  if cursor == 0:
@@ -12,7 +12,11 @@ from pydantic import BaseModel
12
12
 
13
13
  from .base_app import BaseApp
14
14
  from ..deployers import DeployManager
15
- from ..deployers.adapter.a2a import A2AFastAPIDefaultAdapter
15
+ from ..deployers.adapter.a2a import (
16
+ A2AFastAPIDefaultAdapter,
17
+ AgentCardWithRuntimeConfig,
18
+ extract_a2a_config,
19
+ )
16
20
  from ..deployers.adapter.responses.response_api_protocol_adapter import (
17
21
  ResponseAPIDefaultAdapter,
18
22
  )
@@ -47,14 +51,49 @@ class AgentApp(BaseApp):
47
51
  backend_url: Optional[str] = None,
48
52
  runner: Optional[Runner] = None,
49
53
  enable_embedded_worker: bool = False,
54
+ a2a_config: Optional["AgentCardWithRuntimeConfig"] = None,
50
55
  **kwargs,
51
56
  ):
52
57
  """
53
58
  Initialize the AgentApp.
54
59
 
55
60
  Args:
56
- *args: Variable length argument list.
57
- **kwargs: Arbitrary keyword arguments.
61
+ app_name: Name of the agent application
62
+ app_description: Description of the agent application
63
+ endpoint_path: API endpoint path for processing requests
64
+ response_type: Type of response (default: "sse")
65
+ stream: Whether to enable streaming responses
66
+ request_model: Request model class
67
+ before_start: Callback function to execute before starting
68
+ after_finish: Callback function to execute after finishing
69
+ broker_url: URL for message broker
70
+ backend_url: URL for backend service
71
+ runner: Optional runner instance
72
+ enable_embedded_worker: Whether to enable embedded worker
73
+ a2a_config: Optional A2A runtime configuration.
74
+ Must be an ``AgentCardWithRuntimeConfig`` instance, which
75
+ contains ``agent_card`` (AgentCard object or dict) and runtime
76
+ 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
+ AgentCardWithRuntimeConfig,
81
+ )
82
+ config = AgentCardWithRuntimeConfig(
83
+ agent_card={
84
+ "name": "MyAgent",
85
+ "version": "1.0.0",
86
+ "description": "My agent",
87
+ "url": "http://localhost:8080",
88
+ "capabilities": AgentCapabilities(),
89
+ "default_input_modes": ["text"],
90
+ "default_output_modes": ["text"],
91
+ "skills": [],
92
+ },
93
+ registry=[nacos_registry],
94
+ task_timeout=120,
95
+ )
96
+ **kwargs: Additional keyword arguments passed to FastAPI app
58
97
  """
59
98
 
60
99
  self.endpoint_path = endpoint_path
@@ -76,9 +115,13 @@ class AgentApp(BaseApp):
76
115
  self._shutdown_handler: Optional[Callable] = None
77
116
  self._framework_type: Optional[str] = None
78
117
 
118
+ # Prepare A2A protocol adapter configuration
119
+ a2a_config = extract_a2a_config(a2a_config=a2a_config)
120
+
79
121
  a2a_protocol = A2AFastAPIDefaultAdapter(
80
122
  agent_name=app_name,
81
123
  agent_description=app_description,
124
+ a2a_config=a2a_config,
82
125
  )
83
126
 
84
127
  response_protocol = ResponseAPIDefaultAdapter()
@@ -96,8 +139,8 @@ class AgentApp(BaseApp):
96
139
  backend_url=backend_url,
97
140
  )
98
141
 
99
- # Store custom endpoints and tasks for deployment
100
- # but don't add them to FastAPI here - let FastAPIAppFactory handle it
142
+ # Store custom endpoints for deployment
143
+ # FastAPIAppFactory will handle adding them to FastAPI
101
144
 
102
145
  def init(self, func):
103
146
  """Register init hook (support async and sync functions)."""
@@ -1,2 +1,57 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .a2a_protocol_adapter import A2AFastAPIDefaultAdapter
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
+ )
13
+
14
+ # NOTE: NacosRegistry is NOT imported at module import time to avoid forcing
15
+ # an optional dependency on environments that don't have nacos SDK installed.
16
+ # Instead, NacosRegistry is imported lazily via __getattr__ (see below) when
17
+ # actually needed (e.g., when user does: from ... import NacosRegistry).
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}")