agentscope-runtime 0.1.3__py3-none-any.whl → 0.1.5b1__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 (44) hide show
  1. agentscope_runtime/engine/agents/agentscope_agent/agent.py +3 -0
  2. agentscope_runtime/engine/deployers/__init__.py +13 -0
  3. agentscope_runtime/engine/deployers/adapter/responses/__init__.py +0 -0
  4. agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +2886 -0
  5. agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +51 -0
  6. agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +314 -0
  7. agentscope_runtime/engine/deployers/cli_fc_deploy.py +143 -0
  8. agentscope_runtime/engine/deployers/kubernetes_deployer.py +265 -0
  9. agentscope_runtime/engine/deployers/local_deployer.py +356 -501
  10. agentscope_runtime/engine/deployers/modelstudio_deployer.py +626 -0
  11. agentscope_runtime/engine/deployers/utils/__init__.py +0 -0
  12. agentscope_runtime/engine/deployers/utils/deployment_modes.py +14 -0
  13. agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +8 -0
  14. agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +429 -0
  15. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +240 -0
  16. agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +297 -0
  17. agentscope_runtime/engine/deployers/utils/package_project_utils.py +932 -0
  18. agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +9 -0
  19. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +504 -0
  20. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +157 -0
  21. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +268 -0
  22. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +75 -0
  23. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +220 -0
  24. agentscope_runtime/engine/deployers/utils/wheel_packager.py +389 -0
  25. agentscope_runtime/engine/helpers/agent_api_builder.py +651 -0
  26. agentscope_runtime/engine/runner.py +36 -10
  27. agentscope_runtime/engine/schemas/agent_schemas.py +70 -2
  28. agentscope_runtime/engine/schemas/embedding.py +37 -0
  29. agentscope_runtime/engine/schemas/modelstudio_llm.py +310 -0
  30. agentscope_runtime/engine/schemas/oai_llm.py +538 -0
  31. agentscope_runtime/engine/schemas/realtime.py +254 -0
  32. agentscope_runtime/engine/services/context_manager.py +2 -0
  33. agentscope_runtime/engine/services/mem0_memory_service.py +124 -0
  34. agentscope_runtime/engine/services/memory_service.py +2 -1
  35. agentscope_runtime/engine/services/redis_session_history_service.py +4 -3
  36. agentscope_runtime/engine/services/session_history_service.py +4 -3
  37. agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +555 -10
  38. agentscope_runtime/version.py +1 -1
  39. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/METADATA +25 -5
  40. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/RECORD +44 -17
  41. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/entry_points.txt +1 -0
  42. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/WHEEL +0 -0
  43. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/licenses/LICENSE +0 -0
  44. {agentscope_runtime-0.1.3.dist-info → agentscope_runtime-0.1.5b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,265 @@
1
+ # -*- coding: utf-8 -*-
2
+ import logging
3
+ import os
4
+ import time
5
+ from typing import Optional, Dict, List, Union, Any
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+ from agentscope_runtime.engine.runner import Runner
10
+ from agentscope_runtime.sandbox.manager.container_clients import (
11
+ KubernetesClient,
12
+ )
13
+ from .adapter.protocol_adapter import ProtocolAdapter
14
+ from .base import DeployManager
15
+ from .utils.docker_image_utils import (
16
+ RunnerImageFactory,
17
+ RegistryConfig,
18
+ )
19
+ from .utils.service_utils import (
20
+ ServicesConfig,
21
+ )
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class K8sConfig(BaseModel):
27
+ # Kubernetes settings
28
+ k8s_namespace: Optional[str] = Field(
29
+ "agentscope-runtime",
30
+ description="Kubernetes namespace to deploy pods. Required if "
31
+ "container_deployment is 'k8s'.",
32
+ )
33
+ kubeconfig_path: Optional[str] = Field(
34
+ None,
35
+ description="Path to kubeconfig file. If not set, will try "
36
+ "in-cluster config or default kubeconfig.",
37
+ )
38
+
39
+
40
+ class BuildConfig(BaseModel):
41
+ """Build configuration"""
42
+
43
+ build_context_dir: str = "/tmp/k8s_build"
44
+ dockerfile_template: str = None
45
+ build_timeout: int = 600 # 10 minutes
46
+ push_timeout: int = 300 # 5 minutes
47
+ cleanup_after_build: bool = True
48
+
49
+
50
+ class KubernetesDeployManager(DeployManager):
51
+ """Kubernetes deployer for agent services"""
52
+
53
+ def __init__(
54
+ self,
55
+ kube_config: K8sConfig = None,
56
+ registry_config: RegistryConfig = RegistryConfig(),
57
+ use_deployment: bool = True,
58
+ build_context_dir: str = "/tmp/k8s_build",
59
+ ):
60
+ super().__init__()
61
+ self.kubeconfig = kube_config
62
+ self.registry_config = registry_config
63
+ self.image_factory = RunnerImageFactory()
64
+ self.use_deployment = use_deployment
65
+ self.build_context_dir = build_context_dir
66
+ self._deployed_resources = {}
67
+ self._built_images = {}
68
+
69
+ self.k8s_client = KubernetesClient(
70
+ config=self.kubeconfig,
71
+ image_registry=self.registry_config.get_full_url(),
72
+ )
73
+
74
+ async def deploy(
75
+ self,
76
+ runner: Runner,
77
+ endpoint_path: str = "/process",
78
+ stream: bool = True,
79
+ services_config: Optional[Union[ServicesConfig, dict]] = None,
80
+ protocol_adapters: Optional[list[ProtocolAdapter]] = None,
81
+ requirements: Optional[Union[str, List[str]]] = None,
82
+ extra_packages: Optional[List[str]] = None,
83
+ base_image: str = "python:3.9-slim",
84
+ environment: Dict = None,
85
+ runtime_config: Dict = None,
86
+ port: int = 8090,
87
+ replicas: int = 1,
88
+ mount_dir: str = None,
89
+ image_name: str = "agent_llm",
90
+ image_tag: str = "latest",
91
+ push_to_registry: bool = False,
92
+ **kwargs,
93
+ ) -> Dict[str, Any]:
94
+ """
95
+ Deploy runner to Kubernetes.
96
+
97
+ Args:
98
+ runner: Complete Runner object with agent, environment_manager,
99
+ context_manager
100
+ endpoint_path: API endpoint path
101
+ stream: Enable streaming responses
102
+ services_config: Services configuration for context manager
103
+ protocol_adapters: protocol adapters
104
+ requirements: PyPI dependencies (following _agent_engines.py
105
+ pattern)
106
+ extra_packages: User code directory/file path
107
+ base_image: Docker base image
108
+ port: Container port
109
+ replicas: Number of replicas
110
+ environment: Environment variables dict
111
+ mount_dir: Mount directory
112
+ runtime_config: K8s runtime configuration
113
+ # Backward compatibility
114
+ image_name: Image name
115
+ image_tag: Image tag
116
+ push_to_registry: Push to registry
117
+ **kwargs: Additional arguments
118
+
119
+ Returns:
120
+ Dict containing deploy_id, url, resource_name, replicas
121
+
122
+ Raises:
123
+ RuntimeError: If deployment fails
124
+ """
125
+ created_resources = []
126
+ deploy_id = self.deploy_id
127
+
128
+ try:
129
+ logger.info(f"Starting deployment {deploy_id}")
130
+
131
+ # Handle backward compatibility
132
+ if runner is None:
133
+ raise ValueError(
134
+ "Runner must be provided",
135
+ )
136
+
137
+ # convert services_config to Model body
138
+ if services_config and isinstance(services_config, dict):
139
+ services_config = ServicesConfig(**services_config)
140
+
141
+ # Step 1: Build image with proper error handling
142
+ logger.info("Building runner image...")
143
+ try:
144
+ built_image_name = self.image_factory.build_runner_image(
145
+ runner=runner,
146
+ requirements=requirements,
147
+ extra_packages=extra_packages or [],
148
+ base_image=base_image,
149
+ stream=stream,
150
+ endpoint_path=endpoint_path,
151
+ build_context_dir=self.build_context_dir,
152
+ registry_config=self.registry_config,
153
+ image_name=image_name,
154
+ image_tag=image_tag,
155
+ push_to_registry=push_to_registry,
156
+ port=port,
157
+ services_config=services_config, # type: ignore[arg-type]
158
+ protocol_adapters=protocol_adapters,
159
+ **kwargs,
160
+ )
161
+ if not built_image_name:
162
+ raise RuntimeError(
163
+ "Image build failed - no image name returned",
164
+ )
165
+
166
+ created_resources.append(f"image:{built_image_name}")
167
+ self._built_images[deploy_id] = built_image_name
168
+ logger.info(f"Image built successfully: {built_image_name}")
169
+ except Exception as e:
170
+ logger.error(f"Image build failed: {e}")
171
+ raise RuntimeError(f"Failed to build image: {e}") from e
172
+
173
+ if mount_dir:
174
+ if not os.path.isabs(mount_dir):
175
+ mount_dir = os.path.abspath(mount_dir)
176
+
177
+ if mount_dir:
178
+ volume_bindings = {
179
+ mount_dir: {
180
+ "bind": mount_dir,
181
+ "mode": "rw",
182
+ },
183
+ }
184
+ else:
185
+ volume_bindings = {}
186
+
187
+ resource_name = f"agent-{deploy_id[:8]}"
188
+
189
+ # Create Deployment
190
+ _id, ports, ip = self.k8s_client.create_deployment(
191
+ image=built_image_name,
192
+ name=resource_name,
193
+ ports=[port],
194
+ volumes=volume_bindings,
195
+ environment=environment,
196
+ runtime_config=runtime_config or {},
197
+ replicas=replicas,
198
+ create_service=True,
199
+ )
200
+ if not _id:
201
+ import traceback
202
+
203
+ raise RuntimeError(
204
+ f"Failed to create resource: "
205
+ f"{resource_name}, {traceback.format_exc()}",
206
+ )
207
+
208
+ url = f"http://{ip}:{ports[0]}"
209
+ logger.info(f"Deployment {deploy_id} successful: {url}")
210
+
211
+ self._deployed_resources[deploy_id] = {
212
+ "resource_name": resource_name,
213
+ "service_name": _id,
214
+ "image": built_image_name,
215
+ "created_at": time.time(),
216
+ "replicas": replicas if self.use_deployment else 1,
217
+ "config": {
218
+ "runner": runner.__class__.__name__,
219
+ "extra_packages": extra_packages,
220
+ "requirements": requirements, # New format
221
+ "base_image": base_image,
222
+ "port": port,
223
+ "replicas": replicas,
224
+ "environment": environment,
225
+ "runtime_config": runtime_config,
226
+ "endpoint_path": endpoint_path,
227
+ "stream": stream,
228
+ "protocol_adapters": protocol_adapters,
229
+ **kwargs,
230
+ },
231
+ }
232
+ return {
233
+ "deploy_id": deploy_id,
234
+ "url": url,
235
+ "resource_name": resource_name,
236
+ "replicas": replicas,
237
+ }
238
+
239
+ except Exception as e:
240
+ import traceback
241
+
242
+ logger.error(f"Deployment {deploy_id} failed: {e}")
243
+ # Enhanced rollback with better error handling
244
+ raise RuntimeError(
245
+ f"Deployment failed: {e}, {traceback.format_exc()}",
246
+ ) from e
247
+
248
+ async def stop(self) -> bool:
249
+ """Stop service"""
250
+ if self.deploy_id not in self._deployed_resources:
251
+ return False
252
+
253
+ resources = self._deployed_resources[self.deploy_id]
254
+ service_name = resources["service_name"]
255
+ return self.k8s_client.remove_deployment(service_name)
256
+
257
+ def get_status(self) -> str:
258
+ """Get deployment status"""
259
+ if self.deploy_id not in self._deployed_resources:
260
+ return "not_found"
261
+
262
+ resources = self._deployed_resources[self.deploy_id]
263
+ service_name = resources["service_name"]
264
+
265
+ return self.k8s_client.get_deployment_status(service_name)