agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0__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 (184) hide show
  1. agentscope_runtime/adapters/__init__.py +0 -0
  2. agentscope_runtime/adapters/agentscope/__init__.py +0 -0
  3. agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
  4. agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
  5. agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
  6. agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
  7. agentscope_runtime/adapters/agentscope/message.py +535 -0
  8. agentscope_runtime/adapters/agentscope/stream.py +506 -0
  9. agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
  10. agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
  11. agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
  12. agentscope_runtime/adapters/autogen/__init__.py +0 -0
  13. agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
  14. agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
  15. agentscope_runtime/adapters/text/__init__.py +0 -0
  16. agentscope_runtime/adapters/text/stream.py +29 -0
  17. agentscope_runtime/common/collections/redis_mapping.py +4 -1
  18. agentscope_runtime/common/container_clients/fc_client.py +855 -0
  19. agentscope_runtime/common/utils/__init__.py +0 -0
  20. agentscope_runtime/common/utils/lazy_loader.py +57 -0
  21. agentscope_runtime/engine/__init__.py +25 -18
  22. agentscope_runtime/engine/app/agent_app.py +161 -91
  23. agentscope_runtime/engine/app/base_app.py +4 -118
  24. agentscope_runtime/engine/constant.py +8 -0
  25. agentscope_runtime/engine/deployers/__init__.py +8 -0
  26. agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
  27. agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
  28. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
  29. agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
  30. agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
  31. agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
  32. agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
  33. agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
  34. agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
  35. agentscope_runtime/engine/deployers/local_deployer.py +47 -74
  36. agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
  37. agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
  38. agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
  39. agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
  40. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
  41. agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
  42. agentscope_runtime/engine/deployers/utils/package.py +693 -0
  43. agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
  44. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
  45. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
  46. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
  47. agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
  48. agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
  49. agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
  50. agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
  51. agentscope_runtime/engine/helpers/runner.py +40 -0
  52. agentscope_runtime/engine/runner.py +171 -130
  53. agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
  54. agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
  55. agentscope_runtime/engine/schemas/oai_llm.py +23 -23
  56. agentscope_runtime/engine/schemas/response_api.py +65 -0
  57. agentscope_runtime/engine/schemas/session.py +24 -0
  58. agentscope_runtime/engine/services/__init__.py +0 -9
  59. agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
  60. agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
  61. agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
  62. agentscope_runtime/engine/services/memory/__init__.py +24 -0
  63. agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
  64. agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
  65. agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
  66. agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
  67. agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
  68. agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +12 -18
  69. agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
  70. agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
  71. agentscope_runtime/engine/services/session_history/__init__.py +23 -0
  72. agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
  73. agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
  74. agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
  75. agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
  76. agentscope_runtime/engine/tracing/base.py +10 -9
  77. agentscope_runtime/engine/tracing/message_util.py +1 -1
  78. agentscope_runtime/engine/tracing/tracing_util.py +7 -2
  79. agentscope_runtime/engine/tracing/wrapper.py +49 -31
  80. agentscope_runtime/sandbox/__init__.py +10 -2
  81. agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
  82. agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
  83. agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
  84. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
  85. agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
  86. agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
  87. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
  88. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
  89. agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
  90. agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
  91. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
  92. agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
  93. agentscope_runtime/sandbox/client/http_client.py +1 -0
  94. agentscope_runtime/sandbox/enums.py +2 -0
  95. agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
  96. agentscope_runtime/sandbox/manager/server/app.py +12 -0
  97. agentscope_runtime/sandbox/manager/server/config.py +19 -0
  98. agentscope_runtime/sandbox/model/manager_config.py +79 -2
  99. agentscope_runtime/sandbox/utils.py +0 -18
  100. agentscope_runtime/tools/RAGs/__init__.py +0 -0
  101. agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
  102. agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
  103. agentscope_runtime/tools/__init__.py +119 -0
  104. agentscope_runtime/tools/_constants.py +18 -0
  105. agentscope_runtime/tools/alipay/__init__.py +4 -0
  106. agentscope_runtime/tools/alipay/base.py +334 -0
  107. agentscope_runtime/tools/alipay/payment.py +835 -0
  108. agentscope_runtime/tools/alipay/subscribe.py +551 -0
  109. agentscope_runtime/tools/base.py +264 -0
  110. agentscope_runtime/tools/cli/__init__.py +0 -0
  111. agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
  112. agentscope_runtime/tools/generations/__init__.py +75 -0
  113. agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
  114. agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
  115. agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
  116. agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
  117. agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
  118. agentscope_runtime/tools/generations/image_edit.py +208 -0
  119. agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
  120. agentscope_runtime/tools/generations/image_generation.py +202 -0
  121. agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
  122. agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
  123. agentscope_runtime/tools/generations/image_to_video.py +233 -0
  124. agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
  125. agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
  126. agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
  127. agentscope_runtime/tools/generations/speech_to_text.py +260 -0
  128. agentscope_runtime/tools/generations/speech_to_video.py +314 -0
  129. agentscope_runtime/tools/generations/text_to_video.py +221 -0
  130. agentscope_runtime/tools/mcp_wrapper.py +215 -0
  131. agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
  132. agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
  133. agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
  134. agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
  135. agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
  136. agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
  137. agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
  138. agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
  139. agentscope_runtime/tools/searches/__init__.py +3 -0
  140. agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
  141. agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
  142. agentscope_runtime/tools/utils/__init__.py +0 -0
  143. agentscope_runtime/tools/utils/api_key_util.py +45 -0
  144. agentscope_runtime/tools/utils/crypto_utils.py +99 -0
  145. agentscope_runtime/tools/utils/mcp_util.py +35 -0
  146. agentscope_runtime/version.py +1 -1
  147. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +240 -168
  148. agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
  149. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
  150. agentscope_runtime/engine/agents/__init__.py +0 -2
  151. agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
  152. agentscope_runtime/engine/agents/agno_agent.py +0 -220
  153. agentscope_runtime/engine/agents/autogen_agent.py +0 -250
  154. agentscope_runtime/engine/agents/base_agent.py +0 -29
  155. agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
  156. agentscope_runtime/engine/agents/utils.py +0 -53
  157. agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
  158. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
  159. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
  160. agentscope_runtime/engine/helpers/helper.py +0 -179
  161. agentscope_runtime/engine/schemas/context.py +0 -54
  162. agentscope_runtime/engine/services/context_manager.py +0 -164
  163. agentscope_runtime/engine/services/environment_manager.py +0 -50
  164. agentscope_runtime/engine/services/manager.py +0 -174
  165. agentscope_runtime/engine/services/rag_service.py +0 -195
  166. agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
  167. agentscope_runtime/sandbox/tools/__init__.py +0 -12
  168. agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
  169. agentscope_runtime/sandbox/tools/base/tool.py +0 -52
  170. agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
  171. agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
  172. agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
  173. agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
  174. agentscope_runtime/sandbox/tools/function_tool.py +0 -321
  175. agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
  176. agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
  177. agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
  178. agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
  179. agentscope_runtime/sandbox/tools/tool.py +0 -238
  180. agentscope_runtime/sandbox/tools/utils.py +0 -68
  181. agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
  182. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
  183. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
  184. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/top_level.txt +0 -0
@@ -13,7 +13,8 @@ class FastAPITemplateManager:
13
13
  def __init__(self):
14
14
  """Initialize template manager."""
15
15
  self.template_dir = os.path.join(
16
- os.path.dirname(__file__),
16
+ os.path.dirname(os.path.dirname(__file__)),
17
+ "templates",
17
18
  )
18
19
  self.env = Environment(
19
20
  loader=FileSystemLoader(self.template_dir),
@@ -59,7 +60,6 @@ class FastAPITemplateManager:
59
60
  response_type: str = "sse",
60
61
  runner_code: str = "",
61
62
  func_code: str = "",
62
- services_config: str = "",
63
63
  protocol_adapters: Optional[str] = None,
64
64
  **kwargs,
65
65
  ) -> str:
@@ -73,7 +73,6 @@ class FastAPITemplateManager:
73
73
  response_type: Response type
74
74
  runner_code: Code to setup runner
75
75
  func_code: Code to setup custom function
76
- services_config: Services configuration code
77
76
  protocol_adapters: Protocol adapters code string
78
77
  **kwargs: Additional template variables
79
78
 
@@ -89,7 +88,6 @@ class FastAPITemplateManager:
89
88
  response_type=response_type,
90
89
  runner_code=runner_code,
91
90
  func_code=func_code,
92
- services_config=services_config,
93
91
  protocol_adapters=protocol_adapters,
94
92
  **kwargs,
95
93
  )
@@ -251,13 +251,17 @@ class ProcessManager:
251
251
  """
252
252
  import socket
253
253
 
254
+ # Normalize host for connection check
255
+ # When service binds to 0.0.0.0, we need to connect to 127.0.0.1
256
+ check_host = self._normalize_host_for_check(host)
257
+
254
258
  end_time = asyncio.get_event_loop().time() + timeout
255
259
 
256
260
  while asyncio.get_event_loop().time() < end_time:
257
261
  try:
258
262
  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
259
263
  sock.settimeout(1)
260
- result = sock.connect_ex((host, port))
264
+ result = sock.connect_ex((check_host, port))
261
265
  if result == 0:
262
266
  return True
263
267
  except Exception:
@@ -266,3 +270,21 @@ class ProcessManager:
266
270
  await asyncio.sleep(0.5)
267
271
 
268
272
  return False
273
+
274
+ @staticmethod
275
+ def _normalize_host_for_check(host: str) -> str:
276
+ """Normalize host for connection check.
277
+
278
+ When a service binds to 0.0.0.0 (all interfaces), it cannot be
279
+ directly connected to. We need to connect to 127.0.0.1 instead
280
+ to check if the service is running locally.
281
+
282
+ Args:
283
+ host: The host the service binds to
284
+
285
+ Returns:
286
+ The host to use for connection check
287
+ """
288
+ if host in ("0.0.0.0", "::"):
289
+ return "127.0.0.1"
290
+ return host
@@ -0,0 +1,84 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Auto-generated main.py for AgentApp deployment.
4
+
5
+ This file imports and runs the AgentApp from the original entrypoint file,
6
+ avoiding circular deployment issues.
7
+ """
8
+
9
+ import argparse
10
+ import asyncio
11
+ from agentscope_runtime.engine.deployers.utils.deployment_modes import DeploymentMode
12
+
13
+
14
+ from {{ module_name }} import {{ object_name }}
15
+
16
+ # Type whitelist for argument parser to prevent code injection
17
+ ALLOWED_TYPES = {
18
+ "int": int,
19
+ "str": str,
20
+ "float": float,
21
+ "bool": bool,
22
+ }
23
+
24
+
25
+ def main():
26
+ """Run the AgentApp service."""
27
+ parser = argparse.ArgumentParser(
28
+ description="{{ object_name }} Service"
29
+ )
30
+ parser.add_argument(
31
+ "--host",
32
+ default="{{ host }}",
33
+ help="Host to bind to (default: {{ host }})"
34
+ )
35
+ parser.add_argument(
36
+ "--port",
37
+ type=int,
38
+ default={{ port }},
39
+ help="Port to bind to (default: {{ port }})"
40
+ )
41
+ parser.add_argument(
42
+ "--embed-task-processor",
43
+ action="store_true",
44
+ default=False,
45
+ help="Whether to embed task processor"
46
+ )
47
+ {% if extra_parameters %}
48
+
49
+ # Additional runtime parameters
50
+ {% for param in extra_parameters %}
51
+ {% set cli_arg = param.cli_name or '--' + param.name.replace('_', '-') %}
52
+ parser.add_argument(
53
+ {{ cli_arg | tojson }},
54
+ {% if param.type == "bool" %}
55
+ action="store_true",
56
+ default={{ param.default | default(False) | lower }},
57
+ {% else %}
58
+ type=ALLOWED_TYPES[{{ param.type | tojson }}],
59
+ default={{ param.default | tojson if param.default is not none else 'None' }},
60
+ {% endif %}
61
+ help={{ (param.help or param.name) | tojson }}
62
+ )
63
+ {% endfor %}
64
+ {% endif %}
65
+
66
+ args = parser.parse_args()
67
+
68
+ # Run the AgentApp with specified parameters
69
+ {{ object_name }}.run(
70
+ mode=DeploymentMode.DETACHED_PROCESS,
71
+ host=args.host,
72
+ port=args.port,
73
+ embed_task_processor=args.embed_task_processor,
74
+ {% if extra_parameters %}
75
+ # Additional parameters
76
+ {% for param in extra_parameters %}
77
+ {{ param.name }}=args.{{ param.name }},
78
+ {% endfor %}
79
+ {% endif %}
80
+ )
81
+
82
+
83
+ if __name__ == "__main__":
84
+ main()
@@ -0,0 +1,95 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Auto-generated main.py for Runner deployment.
4
+
5
+ This file imports the Runner from the original entrypoint file,
6
+ wraps it in an AgentApp, and runs it as a service.
7
+ """
8
+
9
+ import argparse
10
+ import asyncio
11
+ from {{ module_name }} import {{ object_name }}
12
+ from agentscope_runtime.engine.app import AgentApp
13
+
14
+ # Type whitelist for argument parser to prevent code injection
15
+ ALLOWED_TYPES = {
16
+ "int": int,
17
+ "str": str,
18
+ "float": float,
19
+ "bool": bool,
20
+ }
21
+
22
+
23
+ # Wrap the runner in an AgentApp
24
+ app = AgentApp(
25
+ app_name="{{ app_name }}",
26
+ app_description="{{ app_description }}",
27
+ )
28
+
29
+
30
+ @app.query(framework="agentscope")
31
+ async def query_func(self, msgs, **kwargs):
32
+ """Query handler that uses the runner."""
33
+ result = await {{ object_name }}(msgs)
34
+ return result
35
+
36
+
37
+ async def main():
38
+ """Run the Runner as an AgentApp service."""
39
+ parser = argparse.ArgumentParser(
40
+ description="{{ object_name }} Service (wrapped in AgentApp)"
41
+ )
42
+ parser.add_argument(
43
+ "--host",
44
+ default="{{ host }}",
45
+ help="Host to bind to (default: {{ host }})"
46
+ )
47
+ parser.add_argument(
48
+ "--port",
49
+ type=int,
50
+ default={{ port }},
51
+ help="Port to bind to (default: {{ port }})"
52
+ )
53
+ parser.add_argument(
54
+ "--embed-task-processor",
55
+ action="store_true",
56
+ default=False,
57
+ help="Whether to embed task processor"
58
+ )
59
+ {% if extra_parameters %}
60
+
61
+ # Additional runtime parameters
62
+ {% for param in extra_parameters %}
63
+ {% set cli_arg = param.cli_name or '--' + param.name.replace('_', '-') %}
64
+ parser.add_argument(
65
+ {{ cli_arg | tojson }},
66
+ {% if param.type == "bool" %}
67
+ action="store_true",
68
+ default={{ param.default | default(False) | lower }},
69
+ {% else %}
70
+ type=ALLOWED_TYPES[{{ param.type | tojson }}],
71
+ default={{ param.default | tojson if param.default is not none else 'None' }},
72
+ {% endif %}
73
+ help={{ (param.help or param.name) | tojson }}
74
+ )
75
+ {% endfor %}
76
+ {% endif %}
77
+
78
+ args = parser.parse_args()
79
+
80
+ # Run the wrapped AgentApp with specified parameters
81
+ await app.run(
82
+ host=args.host,
83
+ port=args.port,
84
+ embed_task_processor=args.embed_task_processor,
85
+ {% if extra_parameters %}
86
+ # Additional parameters
87
+ {% for param in extra_parameters %}
88
+ {{ param.name }}=args.{{ param.name }},
89
+ {% endfor %}
90
+ {% endif %}
91
+ )
92
+
93
+
94
+ if __name__ == "__main__":
95
+ asyncio.run(main())
@@ -19,8 +19,6 @@ import uvicorn
19
19
  from agentscope_runtime.engine.deployers.utils.deployment_modes import DeploymentMode
20
20
  from agentscope_runtime.engine.deployers.utils.service_utils import (
21
21
  FastAPIAppFactory,
22
- ServicesConfig,
23
- ServiceConfig,
24
22
  )
25
23
  from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
26
24
  from typing import Callable, Optional, Dict, List, Any, Union
@@ -41,45 +39,6 @@ from agent_file import {{endpoint.function_name}}
41
39
 
42
40
 
43
41
 
44
- def load_services_config() -> ServicesConfig:
45
- """Load services configuration from environment variables or config file."""
46
- config_file = os.getenv('AGENTSCOPE_SERVICES_CONFIG')
47
-
48
- if config_file and os.path.exists(config_file):
49
- # Load from JSON config file
50
- import json
51
- with open(config_file, 'r', encoding='utf-8') as f:
52
- config_data = json.load(f)
53
- return ServicesConfig.model_validate(config_data)
54
- else:
55
- # Load from environment variables
56
- memory_provider = os.getenv('MEMORY_PROVIDER', 'in_memory')
57
- session_provider = os.getenv('SESSION_HISTORY_PROVIDER', 'in_memory')
58
-
59
- memory_config = {}
60
- session_config = {}
61
-
62
- # Add Redis configuration if using Redis
63
- if memory_provider == 'redis':
64
- memory_config = {
65
- 'host': os.getenv('REDIS_HOST', 'localhost'),
66
- 'port': int(os.getenv('REDIS_PORT', 6379)),
67
- 'db': int(os.getenv('REDIS_MEMORY_DB', 0))
68
- }
69
-
70
- if session_provider == 'redis':
71
- session_config = {
72
- 'host': os.getenv('REDIS_HOST', 'localhost'),
73
- 'port': int(os.getenv('REDIS_PORT', 6379)),
74
- 'db': int(os.getenv('REDIS_SESSION_DB', 1))
75
- }
76
-
77
- return ServicesConfig(
78
- memory=ServiceConfig(provider=memory_provider, config=memory_config),
79
- session_history=ServiceConfig(provider=session_provider, config=session_config)
80
- )
81
-
82
-
83
42
  def load_celery_config():
84
43
  """Load Celery configuration from environment variables or infer from existing config."""
85
44
  celery_config = {
@@ -162,9 +121,6 @@ async def after_finish(app, **kwargs):
162
121
  pass
163
122
 
164
123
 
165
- # Load services configuration
166
- services_config = load_services_config()
167
-
168
124
  # Load Celery configuration
169
125
  celery_config = load_celery_config()
170
126
 
@@ -181,7 +137,6 @@ else:
181
137
  app = FastAPIAppFactory.create_app(
182
138
  endpoint_path="{{endpoint_path}}",
183
139
  mode=deployment_mode,
184
- services_config=services_config,
185
140
  before_start=before_start,
186
141
  after_finish=after_finish,
187
142
  stream=True,
@@ -30,7 +30,7 @@ except ImportError: # pragma: no cover - fallback on older Pythons
30
30
  tomllib = None # type: ignore
31
31
 
32
32
 
33
- async def _read_text_file_lines(file_path: Path) -> List[str]:
33
+ def _read_text_file_lines(file_path: Path) -> List[str]:
34
34
  if not file_path.is_file():
35
35
  return []
36
36
  return [
@@ -39,16 +39,32 @@ async def _read_text_file_lines(file_path: Path) -> List[str]:
39
39
  ]
40
40
 
41
41
 
42
- async def _parse_requirements_txt(req_path: Path) -> List[str]:
43
- requirements: List[str] = []
44
- for line in await _read_text_file_lines(req_path):
42
+ def _parse_requirements_txt(req_path: Path) -> Tuple[List[str], List[str]]:
43
+ """
44
+ Parse requirements.txt, separating standard requirements from local wheel paths.
45
+
46
+ Returns:
47
+ Tuple of (standard_requirements, local_wheel_paths)
48
+ """
49
+ standard_requirements: List[str] = []
50
+ local_wheel_paths: List[str] = []
51
+
52
+ for line in _read_text_file_lines(req_path):
45
53
  if not line or line.startswith("#"):
46
54
  continue
47
- requirements.append(line)
48
- return requirements
49
55
 
56
+ # Check if this is a local wheel file path
57
+ if line.endswith(".whl") and (
58
+ "/" in line or "\\" in line or line.startswith(".")
59
+ ):
60
+ local_wheel_paths.append(line)
61
+ else:
62
+ standard_requirements.append(line)
63
+
64
+ return standard_requirements, local_wheel_paths
50
65
 
51
- async def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
66
+
67
+ def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
52
68
  deps: List[str] = []
53
69
  if not pyproject_path.is_file():
54
70
  return deps
@@ -114,15 +130,30 @@ async def _parse_pyproject_toml(pyproject_path: Path) -> List[str]:
114
130
  return deps
115
131
 
116
132
 
117
- async def _gather_user_dependencies(project_dir: Path) -> List[str]:
133
+ def _gather_user_dependencies(
134
+ project_dir: Path,
135
+ ) -> Tuple[List[str], List[Path]]:
136
+ """
137
+ Gather user dependencies from pyproject.toml and requirements.txt.
138
+
139
+ Returns:
140
+ Tuple of (standard_dependencies, local_wheel_files)
141
+ where local_wheel_files are absolute paths to wheel files
142
+ """
118
143
  pyproject = project_dir / "pyproject.toml"
119
144
  req_txt = project_dir / "requirements.txt"
120
145
  deps: List[str] = []
146
+ local_wheels: List[Path] = []
147
+
121
148
  if pyproject.is_file():
122
- dep = await _parse_pyproject_toml(pyproject)
149
+ dep = _parse_pyproject_toml(pyproject)
123
150
  deps.extend(dep)
151
+
124
152
  if req_txt.is_file():
125
- # Merge requirements.txt too, avoiding duplicates
153
+ # Parse requirements.txt to separate standard deps from local wheels
154
+ standard_reqs, local_wheel_paths = _parse_requirements_txt(req_txt)
155
+
156
+ # Merge standard requirements, avoiding duplicates
126
157
  existing = set(
127
158
  d.split("[", 1)[0]
128
159
  .split("=", 1)[0]
@@ -132,7 +163,7 @@ async def _gather_user_dependencies(project_dir: Path) -> List[str]:
132
163
  .lower()
133
164
  for d in deps
134
165
  )
135
- for r in await _parse_requirements_txt(req_txt):
166
+ for r in standard_reqs:
136
167
  name_key = (
137
168
  r.split("[", 1)[0]
138
169
  .split("=", 1)[0]
@@ -143,7 +174,18 @@ async def _gather_user_dependencies(project_dir: Path) -> List[str]:
143
174
  )
144
175
  if name_key not in existing:
145
176
  deps.append(r)
146
- return deps
177
+
178
+ # Process local wheel paths - convert to absolute paths
179
+ for wheel_path_str in local_wheel_paths:
180
+ # Handle relative paths like ./wheels/xxx.whl or wheels/xxx.whl
181
+ wheel_path = Path(wheel_path_str)
182
+ if not wheel_path.is_absolute():
183
+ wheel_path = (project_dir / wheel_path).resolve()
184
+
185
+ if wheel_path.exists() and wheel_path.is_file():
186
+ local_wheels.append(wheel_path)
187
+
188
+ return deps, local_wheels
147
189
 
148
190
 
149
191
  def _venv_python(venv_dir: Path) -> Path:
@@ -163,7 +205,7 @@ def _write_file(path: Path, content: str) -> None:
163
205
  path.write_text(content, encoding="utf-8")
164
206
 
165
207
 
166
- async def generate_wrapper_project(
208
+ def generate_wrapper_project(
167
209
  build_root: Path,
168
210
  user_project_dir: Path,
169
211
  start_cmd: str,
@@ -203,28 +245,47 @@ async def generate_wrapper_project(
203
245
  )
204
246
 
205
247
  # 2) Dependencies
206
- user_deps = await _gather_user_dependencies(user_project_dir)
248
+ _, local_wheels = _gather_user_dependencies(user_project_dir)
249
+
250
+ # Copy local wheel files to wrapper project
251
+ if local_wheels:
252
+ wheels_dir = wrapper_dir / "deploy_starter" / "wheels"
253
+ wheels_dir.mkdir(parents=True, exist_ok=True)
254
+ for wheel_file in local_wheels:
255
+ dest = wheels_dir / wheel_file.name
256
+ shutil.copy2(wheel_file, dest)
257
+
207
258
  wrapper_deps = [
208
259
  "pyyaml",
209
260
  "alibabacloud-oss-v2",
210
- "alibabacloud-bailian20231229",
261
+ "alibabacloud-bailian20231229>=2.6.0",
262
+ "alibabacloud-agentrun20250910>=2.0.1",
211
263
  "alibabacloud-credentials",
212
264
  "alibabacloud-tea-openapi",
213
265
  "alibabacloud-tea-util",
214
266
  "python-dotenv",
267
+ "jinja2",
268
+ "psutil",
215
269
  ]
216
270
  # De-duplicate while preserving order
217
271
  seen = set()
272
+ standard_reqs, local_wheel_paths = _parse_requirements_txt(
273
+ user_project_dir / "requirements.txt",
274
+ )
275
+
218
276
  install_requires: List[str] = []
219
- for pkg in wrapper_deps + user_deps:
277
+ for pkg in wrapper_deps + standard_reqs:
220
278
  key = pkg.strip().lower()
221
279
  if key and key not in seen:
222
280
  seen.add(key)
223
281
  install_requires.append(pkg)
224
282
 
283
+ req_content = "\n".join(install_requires) + "\n"
284
+ req_content += "\n".join(local_wheel_paths) + "\n"
285
+
225
286
  # 3) Packaging metadata
226
287
  unique_suffix = uuid.uuid4().hex[:8]
227
- package_name = f"agentdev_starter_{unique_suffix}"
288
+ package_name = f"agentscope_runtime_{unique_suffix}"
228
289
  version = f"0.1.{int(time.time())}"
229
290
 
230
291
  # 4) Template package: deploy_starter
@@ -248,7 +309,29 @@ def read_config():
248
309
  return yaml.safe_load(f) or {{}}
249
310
 
250
311
 
312
+ def install_local_wheels():
313
+ \"\"\"Install local wheel files if they exist.\"\"\"
314
+ wheels_dir = Path(__file__).resolve().parent / 'wheels'
315
+ if wheels_dir.exists() and wheels_dir.is_dir():
316
+ wheel_files = list(wheels_dir.glob('*.whl'))
317
+ if wheel_files:
318
+ print(f'[deploy_starter] Installing {{len(wheel_files)}} local wheel(s)...')
319
+ for wheel in wheel_files:
320
+ try:
321
+ subprocess.run(
322
+ ['pip', 'install', '--no-deps', str(wheel)],
323
+ check=True,
324
+ capture_output=True,
325
+ )
326
+ print(f'[deploy_starter] Installed: {{wheel.name}}')
327
+ except subprocess.CalledProcessError as e:
328
+ print(f'[deploy_starter] Warning: Failed to install {{wheel.name}}: {{e}}', file=sys.stderr)
329
+
330
+
251
331
  def main():
332
+ # Install local wheels first
333
+ install_local_wheels()
334
+
252
335
  cfg = read_config()
253
336
  subdir = cfg.get('APP_SUBDIR_NAME')
254
337
  if not subdir:
@@ -336,6 +419,23 @@ APP_SUBDIR_NAME: "{project_basename}"
336
419
 
337
420
  setup_py = f"""
338
421
  from setuptools import setup, find_packages
422
+ import os
423
+ import subprocess
424
+ import sys
425
+ from pathlib import Path
426
+ from setuptools import setup, find_packages
427
+ from setuptools.command.install import install
428
+
429
+ def run():
430
+ # Step 1: Install all .whl files in the ./wheel/ directory (relative to setup.py)
431
+ wheel_dir = Path(__file__).parent / "wheel"
432
+ if wheel_dir.is_dir():
433
+ whl_files = sorted(wheel_dir.glob("*.whl"))
434
+ if whl_files:
435
+ for whl in whl_files:
436
+ # Use the same Python interpreter to avoid env issues
437
+ subprocess.check_call([sys.executable, "-m", "pip", "install", str(whl)])
438
+
339
439
 
340
440
  setup(
341
441
  name='{package_name}',
@@ -350,13 +450,14 @@ setup(
350
450
  manifest_in = """
351
451
  recursive-include deploy_starter *.yml
352
452
  recursive-include deploy_starter/user_bundle *
453
+ recursive-include deploy_starter/wheels *.whl
353
454
  """
354
455
  _write_file(wrapper_dir / "MANIFEST.in", manifest_in)
355
456
 
356
457
  return wrapper_dir, wrapper_dir / "dist"
357
458
 
358
459
 
359
- async def build_wheel(project_dir: Path) -> Path:
460
+ def build_wheel(project_dir: Path) -> Path:
360
461
  """
361
462
  Build a wheel inside an isolated virtual environment to avoid PEP 668
362
463
  issues. Returns the path to the built wheel.
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint: disable=unused-argument
3
+ import logging
4
+
5
+ from agentscope_runtime.engine import Runner
6
+ from agentscope_runtime.engine.schemas.agent_schemas import (
7
+ AgentRequest,
8
+ )
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class SimpleRunner(Runner):
14
+ def __init__(self) -> None:
15
+ super().__init__()
16
+ self.framework_type = "text"
17
+
18
+ async def query_handler(
19
+ self,
20
+ request: AgentRequest = None,
21
+ **kwargs,
22
+ ):
23
+ print(request)
24
+ yield "Hi"
25
+ yield "! My name is Friday"
26
+ yield "."
27
+
28
+
29
+ class ErrorRunner(Runner):
30
+ def __init__(self) -> None:
31
+ super().__init__()
32
+ self.framework_type = "text"
33
+
34
+ async def query_handler(
35
+ self,
36
+ request: AgentRequest = None,
37
+ **kwargs,
38
+ ):
39
+ yield "Hi"
40
+ raise RuntimeError("Error")