agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0b1__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 (183) 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 +474 -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 +256 -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 +170 -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/sandbox/__init__.py +10 -2
  80. agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
  81. agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
  82. agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
  83. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
  84. agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
  85. agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
  86. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
  87. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
  88. agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
  89. agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
  90. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
  91. agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
  92. agentscope_runtime/sandbox/client/http_client.py +1 -0
  93. agentscope_runtime/sandbox/enums.py +2 -0
  94. agentscope_runtime/sandbox/manager/sandbox_manager.py +18 -2
  95. agentscope_runtime/sandbox/manager/server/app.py +12 -0
  96. agentscope_runtime/sandbox/manager/server/config.py +19 -0
  97. agentscope_runtime/sandbox/model/manager_config.py +79 -2
  98. agentscope_runtime/sandbox/utils.py +0 -18
  99. agentscope_runtime/tools/RAGs/__init__.py +0 -0
  100. agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
  101. agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
  102. agentscope_runtime/tools/__init__.py +119 -0
  103. agentscope_runtime/tools/_constants.py +18 -0
  104. agentscope_runtime/tools/alipay/__init__.py +4 -0
  105. agentscope_runtime/tools/alipay/base.py +334 -0
  106. agentscope_runtime/tools/alipay/payment.py +835 -0
  107. agentscope_runtime/tools/alipay/subscribe.py +551 -0
  108. agentscope_runtime/tools/base.py +264 -0
  109. agentscope_runtime/tools/cli/__init__.py +0 -0
  110. agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
  111. agentscope_runtime/tools/generations/__init__.py +75 -0
  112. agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
  113. agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
  114. agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
  115. agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
  116. agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
  117. agentscope_runtime/tools/generations/image_edit.py +208 -0
  118. agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
  119. agentscope_runtime/tools/generations/image_generation.py +202 -0
  120. agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
  121. agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
  122. agentscope_runtime/tools/generations/image_to_video.py +233 -0
  123. agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
  124. agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
  125. agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
  126. agentscope_runtime/tools/generations/speech_to_text.py +260 -0
  127. agentscope_runtime/tools/generations/speech_to_video.py +314 -0
  128. agentscope_runtime/tools/generations/text_to_video.py +221 -0
  129. agentscope_runtime/tools/mcp_wrapper.py +215 -0
  130. agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
  131. agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
  132. agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
  133. agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
  134. agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
  135. agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
  136. agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
  137. agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
  138. agentscope_runtime/tools/searches/__init__.py +3 -0
  139. agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
  140. agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
  141. agentscope_runtime/tools/utils/__init__.py +0 -0
  142. agentscope_runtime/tools/utils/api_key_util.py +45 -0
  143. agentscope_runtime/tools/utils/crypto_utils.py +99 -0
  144. agentscope_runtime/tools/utils/mcp_util.py +35 -0
  145. agentscope_runtime/version.py +1 -1
  146. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/METADATA +234 -165
  147. agentscope_runtime-1.0.0b1.dist-info/RECORD +240 -0
  148. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/entry_points.txt +1 -0
  149. agentscope_runtime/engine/agents/__init__.py +0 -2
  150. agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
  151. agentscope_runtime/engine/agents/agno_agent.py +0 -220
  152. agentscope_runtime/engine/agents/autogen_agent.py +0 -250
  153. agentscope_runtime/engine/agents/base_agent.py +0 -29
  154. agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
  155. agentscope_runtime/engine/agents/utils.py +0 -53
  156. agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
  157. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
  158. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
  159. agentscope_runtime/engine/helpers/helper.py +0 -179
  160. agentscope_runtime/engine/schemas/context.py +0 -54
  161. agentscope_runtime/engine/services/context_manager.py +0 -164
  162. agentscope_runtime/engine/services/environment_manager.py +0 -50
  163. agentscope_runtime/engine/services/manager.py +0 -174
  164. agentscope_runtime/engine/services/rag_service.py +0 -195
  165. agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
  166. agentscope_runtime/sandbox/tools/__init__.py +0 -12
  167. agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
  168. agentscope_runtime/sandbox/tools/base/tool.py +0 -52
  169. agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
  170. agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
  171. agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
  172. agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
  173. agentscope_runtime/sandbox/tools/function_tool.py +0 -321
  174. agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
  175. agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
  176. agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
  177. agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
  178. agentscope_runtime/sandbox/tools/tool.py +0 -238
  179. agentscope_runtime/sandbox/tools/utils.py +0 -68
  180. agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
  181. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/WHEEL +0 -0
  182. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/licenses/LICENSE +0 -0
  183. {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0b1.dist-info}/top_level.txt +0 -0
File without changes
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ import importlib
3
+
4
+
5
+ def install_lazy_loader(globals_dict, lazy_map):
6
+ """
7
+ Install __getattr__ and __all__ for lazy loading of module members.
8
+
9
+ Args:
10
+ globals_dict: The globals() of the current module.
11
+ Pass the globals() from the module where this is called.
12
+ lazy_map: dict[name, module_path]
13
+ OR dict[name, dict(module=..., hint=...)]
14
+ The hint is an optional message for missing dependencies.
15
+ """
16
+ __all__ = list(lazy_map.keys())
17
+
18
+ def __getattr__(name):
19
+ if name in lazy_map:
20
+ entry = lazy_map[name]
21
+ module_path, hint = None, None
22
+
23
+ # Support two configuration formats
24
+ if isinstance(entry, str):
25
+ module_path = entry
26
+ elif isinstance(entry, dict):
27
+ module_path = entry["module"]
28
+ hint = entry.get("hint")
29
+
30
+ try:
31
+ module = importlib.import_module(
32
+ module_path,
33
+ globals_dict["__name__"],
34
+ )
35
+ except ImportError as e:
36
+ msg = f"Failed to import {name}. Possible missing dependency."
37
+ if hint:
38
+ msg += f" Please install dependency: {hint}"
39
+ else:
40
+ msg += (
41
+ " Please install dependency: pip install "
42
+ "agentscope-runtime[ext]"
43
+ )
44
+ raise ImportError(msg) from e
45
+
46
+ obj = getattr(module, name)
47
+ # Cache in globals to avoid reloading
48
+ globals_dict[name] = obj
49
+ return obj
50
+
51
+ raise AttributeError(
52
+ f"module {globals_dict['__name__']} has no attribute {name}",
53
+ )
54
+
55
+ # Modify the globals of the calling module
56
+ globals_dict["__all__"] = __all__
57
+ globals_dict["__getattr__"] = __getattr__
@@ -1,21 +1,28 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .services import (
3
- Service,
4
- SandboxService,
5
- MemoryService,
6
- SessionHistoryService,
7
- )
8
- from .deployers import DeployManager, LocalDeployManager
9
- from .runner import Runner
2
+
3
+ from typing import TYPE_CHECKING
4
+
10
5
  from .app import AgentApp
6
+ from .runner import Runner
7
+ from ..common.utils.lazy_loader import install_lazy_loader
8
+
9
+ if TYPE_CHECKING:
10
+ from .deployers import (
11
+ DeployManager,
12
+ LocalDeployManager,
13
+ KubernetesDeployManager,
14
+ ModelstudioDeployManager,
15
+ AgentRunDeployManager,
16
+ )
11
17
 
12
- __all__ = [
13
- "Service",
14
- "SandboxService",
15
- "MemoryService",
16
- "SessionHistoryService",
17
- "DeployManager",
18
- "LocalDeployManager",
19
- "Runner",
20
- "AgentApp",
21
- ]
18
+
19
+ install_lazy_loader(
20
+ globals(),
21
+ {
22
+ "DeployManager": ".deployers",
23
+ "LocalDeployManager": ".deployers",
24
+ "KubernetesDeployManager": ".deployers",
25
+ "ModelstudioDeployManager": ".deployers",
26
+ "AgentRunDeployManager": ".deployers",
27
+ },
28
+ )
@@ -1,28 +1,23 @@
1
1
  # -*- coding: utf-8 -*-
2
- import asyncio
3
2
  import logging
4
- from contextlib import asynccontextmanager
5
- from typing import Optional, Any, Callable, List
3
+ import types
4
+ import subprocess
5
+ import shlex
6
+ from typing import Optional, Callable, List
6
7
 
7
8
  import uvicorn
8
- from fastapi import FastAPI
9
9
  from pydantic import BaseModel
10
10
 
11
11
  from .base_app import BaseApp
12
- from ..agents.base_agent import Agent
12
+ from ..deployers import DeployManager
13
13
  from ..deployers.adapter.a2a import A2AFastAPIDefaultAdapter
14
14
  from ..deployers.adapter.responses.response_api_protocol_adapter import (
15
15
  ResponseAPIDefaultAdapter,
16
16
  )
17
17
  from ..deployers.utils.deployment_modes import DeploymentMode
18
18
  from ..deployers.utils.service_utils.fastapi_factory import FastAPIAppFactory
19
- from ..deployers.utils.service_utils.service_config import (
20
- DEFAULT_SERVICES_CONFIG,
21
- )
22
19
  from ..runner import Runner
23
20
  from ..schemas.agent_schemas import AgentRequest
24
- from ..services.context_manager import ContextManager
25
- from ..services.environment_manager import EnvironmentManager
26
21
  from ...version import __version__
27
22
 
28
23
  logger = logging.getLogger(__name__)
@@ -36,9 +31,8 @@ class AgentApp(BaseApp):
36
31
  def __init__(
37
32
  self,
38
33
  *,
39
- agent: Optional[Agent] = None,
40
- environment_manager: Optional[EnvironmentManager] = None,
41
- context_manager: Optional[ContextManager] = None,
34
+ app_name: str = "",
35
+ app_description: str = "",
42
36
  endpoint_path: str = "/process",
43
37
  response_type: str = "sse",
44
38
  stream: bool = True,
@@ -47,6 +41,8 @@ class AgentApp(BaseApp):
47
41
  after_finish: Optional[Callable] = None,
48
42
  broker_url: Optional[str] = None,
49
43
  backend_url: Optional[str] = None,
44
+ runner: Optional[Runner] = None,
45
+ enable_embedded_worker: bool = False,
50
46
  **kwargs,
51
47
  ):
52
48
  """
@@ -65,135 +61,209 @@ class AgentApp(BaseApp):
65
61
  self.after_finish = after_finish
66
62
  self.broker_url = broker_url
67
63
  self.backend_url = backend_url
64
+ self.enable_embedded_worker = enable_embedded_worker
68
65
 
69
- self._agent = agent
70
- self._runner = None
66
+ self._runner = runner
71
67
  self.custom_endpoints = [] # Store custom endpoints
72
68
 
73
- a2a_protocol = A2AFastAPIDefaultAdapter(agent=self._agent)
69
+ # Custom Handlers
70
+ self._query_handler: Optional[Callable] = None
71
+ self._init_handler: Optional[Callable] = None
72
+ self._shutdown_handler: Optional[Callable] = None
73
+ self._framework_type: Optional[str] = None
74
+
75
+ a2a_protocol = A2AFastAPIDefaultAdapter(
76
+ agent_name=app_name,
77
+ agent_description=app_description,
78
+ )
79
+
74
80
  response_protocol = ResponseAPIDefaultAdapter()
75
81
  self.protocol_adapters = [a2a_protocol, response_protocol]
76
82
 
77
- if self._agent:
78
- self._runner = Runner(
79
- agent=self._agent,
80
- environment_manager=environment_manager,
81
- context_manager=context_manager,
82
- )
83
-
84
- @asynccontextmanager
85
- async def lifespan(app: FastAPI) -> Any:
86
- """Manage the application lifespan."""
87
- if hasattr(self, "before_start") and self.before_start:
88
- if asyncio.iscoroutinefunction(self.before_start):
89
- await self.before_start(app, **getattr(self, "kwargs", {}))
90
- else:
91
- self.before_start(app, **getattr(self, "kwargs", {}))
92
- yield
93
- if hasattr(self, "after_finish") and self.after_finish:
94
- if asyncio.iscoroutinefunction(self.after_finish):
95
- await self.after_finish(app, **getattr(self, "kwargs", {}))
96
- else:
97
- self.after_finish(app, **getattr(self, "kwargs", {}))
98
-
99
- kwargs = {
83
+ self._app_kwargs = {
100
84
  "title": "Agent Service",
101
85
  "version": __version__,
102
86
  "description": "Production-ready Agent Service API",
103
- "lifespan": lifespan,
104
87
  **kwargs,
105
88
  }
106
89
 
107
- if self._runner:
108
- if self.stream:
109
- self.func = self._runner.stream_query
110
- else:
111
- self.func = self._runner.query
112
-
113
90
  super().__init__(
114
91
  broker_url=broker_url,
115
92
  backend_url=backend_url,
116
- **kwargs,
117
93
  )
118
94
 
119
95
  # Store custom endpoints and tasks for deployment
120
96
  # but don't add them to FastAPI here - let FastAPIAppFactory handle it
121
97
 
98
+ def init(self, func):
99
+ """Register init hook (support async and sync functions)."""
100
+ self._init_handler = func
101
+ return func
102
+
103
+ def query(self, framework: Optional[str] = "agentscope"):
104
+ """
105
+ Register run hook and optionally specify agent framework.
106
+ Allowed framework values: 'agentscope', 'autogen', 'agno', 'langgraph'.
107
+ """
108
+
109
+ allowed_frameworks = {"agentscope", "autogen", "agno", "langgraph"}
110
+ if framework not in allowed_frameworks:
111
+ raise ValueError(f"framework must be one of {allowed_frameworks}")
112
+
113
+ def decorator(func):
114
+ self._query_handler = func
115
+ self._framework_type = framework
116
+ return func
117
+
118
+ return decorator
119
+
120
+ def shutdown(self, func):
121
+ """Register shutdown hook (support async and sync functions)."""
122
+ self._shutdown_handler = func
123
+ return func
124
+
125
+ def _build_runner(self):
126
+ if self._runner is None:
127
+ self._runner = Runner()
128
+
129
+ if self._framework_type is not None:
130
+ self._runner.framework_type = self._framework_type
131
+
132
+ if self._query_handler is not None:
133
+ self._runner.query_handler = types.MethodType(
134
+ self._query_handler,
135
+ self._runner,
136
+ )
137
+
138
+ if self._init_handler is not None:
139
+ self._runner.init_handler = types.MethodType(
140
+ self._init_handler,
141
+ self._runner,
142
+ )
143
+
144
+ if self._shutdown_handler is not None:
145
+ self._runner.shutdown_handler = types.MethodType(
146
+ self._shutdown_handler,
147
+ self._runner,
148
+ )
149
+
122
150
  def run(
123
151
  self,
124
152
  host="0.0.0.0",
125
153
  port=8090,
126
- embed_task_processor=False,
127
- services_config=None,
154
+ web_ui=False,
128
155
  **kwargs,
129
156
  ):
130
157
  """
131
- Run the AgentApp using FastAPIAppFactory directly.
158
+ Launch the AgentApp HTTP API server.
159
+
160
+ This method starts a FastAPI server for the agent service.
161
+ Optionally, it can also launch a browser-based Web UI for
162
+ interacting with the agent.
163
+
164
+ Note:
165
+ If `web_ui=True` and this is the **first time** launching the Web UI,
166
+ additional time may be required to initialize. This happens because the
167
+ underlying Node.js command (`npx @agentscope-ai/chat
168
+ agentscope-runtime-webui`) might install dependencies and set up
169
+ the runtime environment.
132
170
 
133
171
  Args:
134
- host: Host to bind to
135
- port: Port to bind to
136
- embed_task_processor: Whether to embed task processor
137
- services_config: Optional services configuration
138
- **kwargs: Additional keyword arguments
172
+ host (str): Host address to bind to. Default "0.0.0.0".
173
+ port (int): Port number to serve the application on. Default 8090.
174
+ web_ui (bool): If True, launches the Agentscope Web UI in a
175
+ separate process, pointing it to the API endpoint. This
176
+ allows interactive use via browser. Default False.
177
+ **kwargs: Additional keyword arguments passed to FastAPIAppFactory
178
+ when creating the FastAPI application.
179
+
180
+ Example:
181
+ >>> app = AgentApp(app_name="MyAgent")
182
+ >>> app.run(host="127.0.0.1", port=8000, web_ui=True)
139
183
  """
184
+ # Build runner
185
+ self._build_runner()
140
186
 
141
187
  try:
142
188
  logger.info(
143
189
  "[AgentApp] Starting AgentApp with FastAPIAppFactory...",
144
190
  )
145
-
146
- # Use default services config if not provided
147
- if services_config is None:
148
- services_config = DEFAULT_SERVICES_CONFIG
149
-
150
- # Create FastAPI application using the factory
151
- fastapi_app = FastAPIAppFactory.create_app(
152
- runner=self._runner,
153
- endpoint_path=self.endpoint_path,
154
- request_model=self.request_model,
155
- response_type=self.response_type,
156
- stream=self.stream,
157
- before_start=self.before_start,
158
- after_finish=self.after_finish,
159
- mode=DeploymentMode.DAEMON_THREAD,
160
- services_config=services_config,
161
- protocol_adapters=self.protocol_adapters,
162
- custom_endpoints=self.custom_endpoints,
163
- broker_url=self.broker_url,
164
- backend_url=self.backend_url,
165
- enable_embedded_worker=embed_task_processor,
166
- **kwargs,
167
- )
191
+ fastapi_app = self.get_fastapi_app(**kwargs)
168
192
 
169
193
  logger.info(f"[AgentApp] Starting server on {host}:{port}")
170
194
 
171
- # Start the FastAPI application with uvicorn
172
- uvicorn.run(
173
- fastapi_app,
174
- host=host,
175
- port=port,
176
- log_level="info",
177
- access_log=True,
195
+ if web_ui:
196
+ webui_url = f"http://{host}:{port}{self.endpoint_path}"
197
+ cmd = (
198
+ f"npx @agentscope-ai/chat agentscope-runtime-webui "
199
+ f"--url {webui_url}"
200
+ )
201
+ logger.info(f"[AgentApp] WebUI started at {webui_url}")
202
+ logger.info(
203
+ "[AgentApp] Note: First WebUI launch may take extra time "
204
+ "as dependencies are installed.",
205
+ )
206
+ with subprocess.Popen(shlex.split(cmd)):
207
+ uvicorn.run(
208
+ fastapi_app,
209
+ host=host,
210
+ port=port,
211
+ log_level="info",
212
+ access_log=True,
213
+ )
214
+ else:
215
+ uvicorn.run(
216
+ fastapi_app,
217
+ host=host,
218
+ port=port,
219
+ log_level="info",
220
+ access_log=True,
221
+ )
222
+
223
+ except KeyboardInterrupt:
224
+ logger.info(
225
+ "[AgentApp] KeyboardInterrupt received, shutting down...",
178
226
  )
179
227
 
180
- except Exception as e:
181
- logger.error(f"[AgentApp] Error while running: {e}")
182
- raise
228
+ def get_fastapi_app(self, **kwargs):
229
+ """Get the FastAPI application"""
230
+
231
+ self._build_runner()
232
+ mode = kwargs.pop("mode", DeploymentMode.DAEMON_THREAD)
233
+
234
+ return FastAPIAppFactory.create_app(
235
+ runner=self._runner,
236
+ endpoint_path=self.endpoint_path,
237
+ request_model=self.request_model,
238
+ response_type=self.response_type,
239
+ stream=self.stream,
240
+ before_start=self.before_start,
241
+ after_finish=self.after_finish,
242
+ mode=mode,
243
+ protocol_adapters=self.protocol_adapters,
244
+ custom_endpoints=self.custom_endpoints,
245
+ broker_url=self.broker_url,
246
+ backend_url=self.backend_url,
247
+ enable_embedded_worker=self.enable_embedded_worker,
248
+ app_kwargs=self._app_kwargs,
249
+ **kwargs,
250
+ )
183
251
 
184
- async def deploy(self, deployer, **kwargs):
252
+ async def deploy(self, deployer: DeployManager, **kwargs):
185
253
  """Deploy the agent app with custom endpoints support"""
186
254
  # Pass custom endpoints and tasks to the deployer
255
+ # Build runner
256
+ self._build_runner()
187
257
 
188
258
  deploy_kwargs = {
189
- **kwargs,
259
+ "app": self,
190
260
  "custom_endpoints": self.custom_endpoints,
191
- "agent": self._agent,
192
261
  "runner": self._runner,
193
262
  "endpoint_path": self.endpoint_path,
194
263
  "stream": self.stream,
195
264
  "protocol_adapters": self.protocol_adapters,
196
265
  }
266
+ deploy_kwargs.update(kwargs)
197
267
  return await deployer.deploy(**deploy_kwargs)
198
268
 
199
269
  def endpoint(self, path: str, methods: Optional[List[str]] = None):
@@ -1,38 +1,29 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import inspect
3
3
  import logging
4
- import threading
5
4
  from typing import Callable, Optional
6
5
 
7
- import uvicorn
8
- from fastapi import FastAPI, Request
9
- from fastapi.responses import StreamingResponse
6
+ from fastapi import Request
10
7
 
11
8
  from .celery_mixin import CeleryMixin
12
9
 
13
10
  logger = logging.getLogger(__name__)
14
11
 
15
12
 
16
- class BaseApp(FastAPI, CeleryMixin):
13
+ class BaseApp(CeleryMixin):
17
14
  """
18
- BaseApp extends FastAPI and integrates with Celery
19
- for asynchronous background task execution.
15
+ BaseApp integrates Celery for asynchronous background task execution,
16
+ and provides FastAPI-like routing for task endpoints.
20
17
  """
21
18
 
22
19
  def __init__(
23
20
  self,
24
21
  broker_url: Optional[str] = None,
25
22
  backend_url: Optional[str] = None,
26
- **kwargs,
27
23
  ):
28
24
  # Initialize CeleryMixin
29
25
  CeleryMixin.__init__(self, broker_url, backend_url)
30
26
 
31
- self.server = None
32
-
33
- # Initialize FastAPI
34
- FastAPI.__init__(self, **kwargs)
35
-
36
27
  def task(self, path: str, queue: str = "celery"):
37
28
  """
38
29
  Register an asynchronous task endpoint.
@@ -74,108 +65,3 @@ class BaseApp(FastAPI, CeleryMixin):
74
65
  return func
75
66
 
76
67
  return decorator
77
-
78
- def endpoint(self, path: str):
79
- """
80
- Unified POST endpoint decorator.
81
- Pure FastAPI functionality, independent of Celery.
82
- Supports:
83
- - Sync functions
84
- - Async functions (coroutines)
85
- - Sync/async generator functions (streaming responses)
86
- """
87
-
88
- def decorator(func: Callable):
89
- is_async_gen = inspect.isasyncgenfunction(func)
90
- is_sync_gen = inspect.isgeneratorfunction(func)
91
-
92
- if is_async_gen or is_sync_gen:
93
- # Handle streaming responses
94
- async def _stream_generator(request: Request):
95
- if is_async_gen:
96
- async for chunk in func(request):
97
- yield chunk
98
- else:
99
- for chunk in func(request):
100
- yield chunk
101
-
102
- @self.post(path)
103
- async def _wrapped(request: Request):
104
- return StreamingResponse(
105
- _stream_generator(request),
106
- media_type="text/plain",
107
- )
108
-
109
- else:
110
- # Handle regular responses
111
- @self.post(path)
112
- async def _wrapped(request: Request):
113
- if inspect.iscoroutinefunction(func):
114
- return await func(request)
115
- else:
116
- return func(request)
117
-
118
- return func
119
-
120
- return decorator
121
-
122
- def run(
123
- self,
124
- host="0.0.0.0",
125
- port=8090,
126
- embed_task_processor=False,
127
- **kwargs,
128
- ):
129
- """
130
- Run FastAPI with uvicorn.
131
- """
132
- if embed_task_processor:
133
- if self.celery_app is None:
134
- logger.warning(
135
- "[AgentApp] Celery is not configured. "
136
- "Cannot run embedded worker.",
137
- )
138
- else:
139
- logger.warning(
140
- "[AgentApp] embed_task_processor=True: Running "
141
- "task_processor in embedded thread mode. This is "
142
- "intended for development/debug purposes only. In "
143
- "production, run Celery worker in a separate process!",
144
- )
145
-
146
- queues = self._registered_queues or {"celery"}
147
- queue_list = ",".join(sorted(queues))
148
-
149
- def start_celery_worker():
150
- logger.info(
151
- f"[AgentApp] Embedded worker listening "
152
- f"queues: {queue_list}",
153
- )
154
- self.celery_app.worker_main(
155
- [
156
- "worker",
157
- "--loglevel=INFO",
158
- "-Q",
159
- queue_list,
160
- ],
161
- )
162
-
163
- threading.Thread(
164
- target=start_celery_worker,
165
- daemon=True,
166
- ).start()
167
- logger.info(
168
- "[AgentApp] Embedded task processor started in background "
169
- "thread (DEV mode).",
170
- )
171
-
172
- # TODO: Add CLI to main entrypoint to control run/deploy
173
-
174
- config = uvicorn.Config(
175
- app=self,
176
- host=host,
177
- port=port,
178
- **kwargs,
179
- )
180
- self.server = uvicorn.Server(config)
181
- self.server.run()
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ ALLOWED_FRAMEWORK_TYPES = [
3
+ "text",
4
+ "agentscope",
5
+ "autogen",
6
+ "langgraph",
7
+ "agno",
8
+ ]
@@ -8,9 +8,17 @@ from .modelstudio_deployer import (
8
8
  ModelstudioDeployManager,
9
9
  )
10
10
 
11
+ try:
12
+ from .agentrun_deployer import (
13
+ AgentRunDeployManager,
14
+ )
15
+ except ImportError:
16
+ AgentRunDeployManager = None # type: ignore
17
+
11
18
  __all__ = [
12
19
  "DeployManager",
13
20
  "LocalDeployManager",
14
21
  "KubernetesDeployManager",
15
22
  "ModelstudioDeployManager",
23
+ "AgentRunDeployManager",
16
24
  ]
@@ -0,0 +1,2 @@
1
+ # -*- coding: utf-8 -*-
2
+ from .a2a import A2AFastAPIDefaultAdapter
@@ -13,11 +13,8 @@ from a2a.types import (
13
13
  TaskStatusUpdateEvent,
14
14
  TaskArtifactUpdateEvent,
15
15
  TaskQueryParams,
16
- AgentCard,
17
- AgentCapabilities,
18
16
  )
19
17
 
20
- from ....agents import Agent
21
18
  from ....schemas.agent_schemas import (
22
19
  Message as AgentMessage,
23
20
  Content,
@@ -405,21 +402,3 @@ def agent_message_to_a2a_message(msg: "AgentMessage") -> "A2AMessage":
405
402
  parts=parts,
406
403
  # Others can be added as needed, such as metadata
407
404
  )
408
-
409
-
410
- def agent_card(
411
- agent: Agent,
412
- url: str,
413
- version: str = "1.0.0",
414
- **kwargs,
415
- ) -> AgentCard:
416
- return AgentCard(
417
- name=agent.name,
418
- description=agent.description,
419
- url=url,
420
- version=version,
421
- capabilities=AgentCapabilities(streaming=False),
422
- default_input_modes=["application/json"],
423
- default_output_modes=["application/json"],
424
- **kwargs,
425
- )