agentscope-runtime 0.2.0b1__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 (185) 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/container_clients/kubernetes_client.py +6 -13
  20. agentscope_runtime/common/utils/__init__.py +0 -0
  21. agentscope_runtime/common/utils/lazy_loader.py +57 -0
  22. agentscope_runtime/engine/__init__.py +25 -18
  23. agentscope_runtime/engine/app/agent_app.py +161 -91
  24. agentscope_runtime/engine/app/base_app.py +4 -118
  25. agentscope_runtime/engine/constant.py +8 -0
  26. agentscope_runtime/engine/deployers/__init__.py +8 -0
  27. agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
  28. agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
  29. agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
  30. agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
  31. agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
  32. agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
  33. agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
  34. agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
  35. agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
  36. agentscope_runtime/engine/deployers/local_deployer.py +47 -74
  37. agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
  38. agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
  39. agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
  40. agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
  41. agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
  42. agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
  43. agentscope_runtime/engine/deployers/utils/package.py +693 -0
  44. agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
  45. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
  46. agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
  47. agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
  48. agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
  49. agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
  50. agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
  51. agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
  52. agentscope_runtime/engine/helpers/runner.py +40 -0
  53. agentscope_runtime/engine/runner.py +171 -130
  54. agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
  55. agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
  56. agentscope_runtime/engine/schemas/oai_llm.py +23 -23
  57. agentscope_runtime/engine/schemas/response_api.py +65 -0
  58. agentscope_runtime/engine/schemas/session.py +24 -0
  59. agentscope_runtime/engine/services/__init__.py +0 -9
  60. agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
  61. agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
  62. agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
  63. agentscope_runtime/engine/services/memory/__init__.py +24 -0
  64. agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
  65. agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
  66. agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
  67. agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
  68. agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
  69. agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +16 -19
  70. agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
  71. agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
  72. agentscope_runtime/engine/services/session_history/__init__.py +23 -0
  73. agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
  74. agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
  75. agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
  76. agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
  77. agentscope_runtime/engine/tracing/base.py +10 -9
  78. agentscope_runtime/engine/tracing/message_util.py +1 -1
  79. agentscope_runtime/engine/tracing/tracing_util.py +7 -2
  80. agentscope_runtime/engine/tracing/wrapper.py +49 -31
  81. agentscope_runtime/sandbox/__init__.py +10 -2
  82. agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
  83. agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
  84. agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
  85. agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
  86. agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
  87. agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
  88. agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
  89. agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
  90. agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
  91. agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
  92. agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
  93. agentscope_runtime/sandbox/box/training_box/training_box.py +2 -44
  94. agentscope_runtime/sandbox/client/http_client.py +1 -0
  95. agentscope_runtime/sandbox/enums.py +2 -1
  96. agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
  97. agentscope_runtime/sandbox/manager/server/app.py +12 -0
  98. agentscope_runtime/sandbox/manager/server/config.py +19 -0
  99. agentscope_runtime/sandbox/model/manager_config.py +79 -2
  100. agentscope_runtime/sandbox/utils.py +0 -18
  101. agentscope_runtime/tools/RAGs/__init__.py +0 -0
  102. agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
  103. agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
  104. agentscope_runtime/tools/__init__.py +119 -0
  105. agentscope_runtime/tools/_constants.py +18 -0
  106. agentscope_runtime/tools/alipay/__init__.py +4 -0
  107. agentscope_runtime/tools/alipay/base.py +334 -0
  108. agentscope_runtime/tools/alipay/payment.py +835 -0
  109. agentscope_runtime/tools/alipay/subscribe.py +551 -0
  110. agentscope_runtime/tools/base.py +264 -0
  111. agentscope_runtime/tools/cli/__init__.py +0 -0
  112. agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
  113. agentscope_runtime/tools/generations/__init__.py +75 -0
  114. agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
  115. agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
  116. agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
  117. agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
  118. agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
  119. agentscope_runtime/tools/generations/image_edit.py +208 -0
  120. agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
  121. agentscope_runtime/tools/generations/image_generation.py +202 -0
  122. agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
  123. agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
  124. agentscope_runtime/tools/generations/image_to_video.py +233 -0
  125. agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
  126. agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
  127. agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
  128. agentscope_runtime/tools/generations/speech_to_text.py +260 -0
  129. agentscope_runtime/tools/generations/speech_to_video.py +314 -0
  130. agentscope_runtime/tools/generations/text_to_video.py +221 -0
  131. agentscope_runtime/tools/mcp_wrapper.py +215 -0
  132. agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
  133. agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
  134. agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
  135. agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
  136. agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
  137. agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
  138. agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
  139. agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
  140. agentscope_runtime/tools/searches/__init__.py +3 -0
  141. agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
  142. agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
  143. agentscope_runtime/tools/utils/__init__.py +0 -0
  144. agentscope_runtime/tools/utils/api_key_util.py +45 -0
  145. agentscope_runtime/tools/utils/crypto_utils.py +99 -0
  146. agentscope_runtime/tools/utils/mcp_util.py +35 -0
  147. agentscope_runtime/version.py +1 -1
  148. {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +244 -168
  149. agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
  150. {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
  151. agentscope_runtime/engine/agents/__init__.py +0 -2
  152. agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
  153. agentscope_runtime/engine/agents/agno_agent.py +0 -222
  154. agentscope_runtime/engine/agents/autogen_agent.py +0 -250
  155. agentscope_runtime/engine/agents/base_agent.py +0 -29
  156. agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
  157. agentscope_runtime/engine/agents/utils.py +0 -53
  158. agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
  159. agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
  160. agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
  161. agentscope_runtime/engine/helpers/helper.py +0 -179
  162. agentscope_runtime/engine/schemas/context.py +0 -54
  163. agentscope_runtime/engine/services/context_manager.py +0 -164
  164. agentscope_runtime/engine/services/environment_manager.py +0 -50
  165. agentscope_runtime/engine/services/manager.py +0 -174
  166. agentscope_runtime/engine/services/rag_service.py +0 -195
  167. agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
  168. agentscope_runtime/sandbox/tools/__init__.py +0 -12
  169. agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
  170. agentscope_runtime/sandbox/tools/base/tool.py +0 -52
  171. agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
  172. agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
  173. agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
  174. agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
  175. agentscope_runtime/sandbox/tools/function_tool.py +0 -321
  176. agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
  177. agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
  178. agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
  179. agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
  180. agentscope_runtime/sandbox/tools/tool.py +0 -238
  181. agentscope_runtime/sandbox/tools/utils.py +0 -68
  182. agentscope_runtime-0.2.0b1.dist-info/RECORD +0 -183
  183. {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
  184. {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
  185. {agentscope_runtime-0.2.0b1.dist-info → agentscope_runtime-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,320 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint:disable=abstract-method, deprecated-module, wrong-import-order
3
+
4
+ import os
5
+ import uuid
6
+ from http import HTTPStatus
7
+ from typing import Any, Optional
8
+
9
+ from dashscope.aigc.video_synthesis import AioVideoSynthesis
10
+ from mcp.server.fastmcp import Context
11
+ from pydantic import BaseModel, Field
12
+
13
+ from ..base import Tool
14
+ from ..utils.api_key_util import get_api_key, ApiNames
15
+ from ...engine.tracing import trace, TracingUtil
16
+
17
+
18
+ class TextToVideoSubmitInput(BaseModel):
19
+ """
20
+ Text to video generation input model
21
+ """
22
+
23
+ prompt: str = Field(
24
+ ...,
25
+ description="正向提示词,用来描述生成视频中期望包含的元素和视觉特点, 超过800个字符自动截断",
26
+ )
27
+ negative_prompt: Optional[str] = Field(
28
+ default=None,
29
+ description="反向提示词,用来描述不希望在视频画面中看到的内容,可以对视频画面进行限制,超过500个字符自动截断",
30
+ )
31
+ size: Optional[str] = Field(
32
+ default=None,
33
+ description="视频分辨率,默认不设置",
34
+ )
35
+ duration: Optional[int] = Field(
36
+ default=None,
37
+ description="视频生成时长,单位为秒",
38
+ )
39
+ prompt_extend: Optional[bool] = Field(
40
+ default=None,
41
+ description="是否开启prompt智能改写,开启后使用大模型对输入prompt进行智能改写",
42
+ )
43
+ watermark: Optional[bool] = Field(
44
+ default=None,
45
+ description="是否添加水印,默认不设置",
46
+ )
47
+ ctx: Optional[Context] = Field(
48
+ default=None,
49
+ description="HTTP request context containing headers for mcp only, "
50
+ "don't generate it",
51
+ )
52
+
53
+
54
+ class TextToVideoSubmitOutput(BaseModel):
55
+ """
56
+ Text to video generation output model
57
+ """
58
+
59
+ task_id: str = Field(
60
+ title="Task ID",
61
+ description="视频生成的任务ID",
62
+ )
63
+
64
+ task_status: str = Field(
65
+ title="Task Status",
66
+ description="视频生成的任务状态,PENDING:任务排队中,RUNNING:任务处理中,SUCCEEDED:任务执行成功,"
67
+ "FAILED:任务执行失败,CANCELED:任务取消成功,UNKNOWN:任务不存在或状态未知",
68
+ )
69
+
70
+ request_id: Optional[str] = Field(
71
+ default=None,
72
+ title="Request ID",
73
+ description="请求ID",
74
+ )
75
+
76
+
77
+ class TextToVideoSubmit(
78
+ Tool[TextToVideoSubmitInput, TextToVideoSubmitOutput],
79
+ ):
80
+ """
81
+ Text to video generation service that converts text into videos
82
+ using DashScope's VideoSynthesis API.
83
+ """
84
+
85
+ name: str = "modelstudio_text_to_video_submit_task"
86
+ description: str = (
87
+ "通义万相-文生视频模型的异步任务提交工具。可根据文本生成5秒无声视频,支持 480P、720P、1080P 多种分辨率档位,"
88
+ "并在各档位下提供多个具体尺寸选项,以适配不同业务场景。"
89
+ )
90
+
91
+ @trace(trace_type="AIGC", trace_name="text_to_video_submit")
92
+ async def arun(
93
+ self,
94
+ args: TextToVideoSubmitInput,
95
+ **kwargs: Any,
96
+ ) -> TextToVideoSubmitOutput:
97
+ """
98
+ Generate video from text prompt using DashScope VideoSynthesis
99
+
100
+ This method wraps DashScope's VideoSynthesis service to generate videos
101
+ based on text descriptions. It uses async call pattern for better
102
+ performance and supports polling for task completion.
103
+
104
+ Args:
105
+ args: TextToVideoInput containing optional parameters
106
+ **kwargs: Additional keyword arguments including:
107
+ - request_id: Optional request ID for tracking
108
+ - model_name: Model name to use (defaults to wan2.2-t2v-plus)
109
+ - api_key: DashScope API key for authentication
110
+
111
+ Returns:
112
+ TextToVideoOutput containing the generated video URL and request ID
113
+
114
+ Raises:
115
+ ValueError: If DASHSCOPE_API_KEY is not set or invalid
116
+ TimeoutError: If video generation takes too long
117
+ RuntimeError: If video generation fails
118
+ """
119
+ trace_event = kwargs.pop("trace_event", None)
120
+ request_id = TracingUtil.get_request_id()
121
+
122
+ try:
123
+ api_key = get_api_key(ApiNames.dashscope_api_key, **kwargs)
124
+ except AssertionError as e:
125
+ raise ValueError("Please set valid DASHSCOPE_API_KEY!") from e
126
+
127
+ model_name = kwargs.get(
128
+ "model_name",
129
+ os.getenv("TEXT_TO_VIDEO_MODEL_NAME", "wan2.2-t2v-plus"),
130
+ )
131
+
132
+ parameters = {}
133
+ if args.prompt_extend is not None:
134
+ parameters["prompt_extend"] = args.prompt_extend
135
+ if args.size:
136
+ parameters["size"] = args.size
137
+ if args.duration is not None:
138
+ parameters["duration"] = args.duration
139
+ if args.watermark is not None:
140
+ parameters["watermark"] = args.watermark
141
+
142
+ # Create AioVideoSynthesis instance
143
+ aio_video_synthesis = AioVideoSynthesis()
144
+
145
+ # Submit async task
146
+ response = await aio_video_synthesis.async_call(
147
+ model=model_name,
148
+ api_key=api_key,
149
+ prompt=args.prompt,
150
+ negative_prompt=args.negative_prompt,
151
+ **parameters,
152
+ )
153
+ # Log trace event if provided
154
+ if trace_event:
155
+ trace_event.on_log(
156
+ "",
157
+ **{
158
+ "step_suffix": "results",
159
+ "payload": {
160
+ "request_id": request_id,
161
+ "submit_task": response,
162
+ },
163
+ },
164
+ )
165
+
166
+ if (
167
+ response.status_code != HTTPStatus.OK
168
+ or not response.output
169
+ or response.output.task_status in ["FAILED", "CANCELED"]
170
+ ):
171
+ raise RuntimeError(f"Failed to submit task: {response}")
172
+
173
+ if not request_id:
174
+ request_id = (
175
+ response.request_id
176
+ if response.request_id
177
+ else str(uuid.uuid4())
178
+ )
179
+
180
+ result = TextToVideoSubmitOutput(
181
+ request_id=request_id,
182
+ task_id=response.output.task_id,
183
+ task_status=response.output.task_status,
184
+ )
185
+ return result
186
+
187
+
188
+ class TextToVideoFetchInput(BaseModel):
189
+ """
190
+ Text to video fetch task input model
191
+ """
192
+
193
+ task_id: str = Field(
194
+ title="Task ID",
195
+ description="视频生成的任务ID",
196
+ )
197
+ ctx: Optional[Context] = Field(
198
+ default=None,
199
+ description="HTTP request context containing headers for mcp only, "
200
+ "don't generate it",
201
+ )
202
+
203
+
204
+ class TextToVideoFetchOutput(BaseModel):
205
+ """
206
+ Text to video fetch task output model
207
+ """
208
+
209
+ video_url: str = Field(
210
+ title="Video URL",
211
+ description="输出的视频url",
212
+ )
213
+
214
+ task_id: str = Field(
215
+ title="Task ID",
216
+ description="视频生成的任务ID",
217
+ )
218
+
219
+ task_status: str = Field(
220
+ title="Task Status",
221
+ description="视频生成的任务状态,PENDING:任务排队中,RUNNING:任务处理中,SUCCEEDED:任务执行成功,"
222
+ "FAILED:任务执行失败,CANCELED:任务取消成功,UNKNOWN:任务不存在或状态未知",
223
+ )
224
+
225
+ request_id: Optional[str] = Field(
226
+ default=None,
227
+ title="Request ID",
228
+ description="请求ID",
229
+ )
230
+
231
+
232
+ class TextToVideoFetch(
233
+ Tool[TextToVideoFetchInput, TextToVideoFetchOutput],
234
+ ):
235
+ """
236
+ Text to video fetch service that retrieves video generation results
237
+ using DashScope's VideoSynthesis API.
238
+ """
239
+
240
+ name: str = "modelstudio_text_to_video_fetch_result"
241
+ description: str = "通义万相-文生视频模型的异步任务结果查询工具,根据Task ID查询任务结果。"
242
+
243
+ @trace(trace_type="AIGC", trace_name="text_to_video_fetch")
244
+ async def arun(
245
+ self,
246
+ args: TextToVideoFetchInput,
247
+ **kwargs: Any,
248
+ ) -> TextToVideoFetchOutput:
249
+ """
250
+ Fetch video generation result using DashScope VideoSynthesis
251
+
252
+ This method wraps DashScope's VideoSynthesis fetch service to retrieve
253
+ video generation results based on task ID. It uses async call pattern
254
+ for better performance.
255
+
256
+ Args:
257
+ args: TextToVideoFetchInput containing task_id parameter
258
+ **kwargs: Additional keyword arguments including:
259
+ - api_key: DashScope API key for authentication
260
+
261
+ Returns:
262
+ TextToVideoFetchOutput containing the video URL, task status and
263
+ request ID
264
+
265
+ Raises:
266
+ ValueError: If DASHSCOPE_API_KEY is not set or invalid
267
+ RuntimeError: If video fetch fails or response status is not OK
268
+ """
269
+ trace_event = kwargs.pop("trace_event", None)
270
+ request_id = TracingUtil.get_request_id()
271
+
272
+ try:
273
+ api_key = get_api_key(ApiNames.dashscope_api_key, **kwargs)
274
+ except AssertionError as e:
275
+ raise ValueError("Please set valid DASHSCOPE_API_KEY!") from e
276
+
277
+ # Create AioVideoSynthesis instance
278
+ aio_video_synthesis = AioVideoSynthesis()
279
+
280
+ response = await aio_video_synthesis.fetch(
281
+ api_key=api_key,
282
+ task=args.task_id,
283
+ )
284
+
285
+ # Log trace event if provided
286
+ if trace_event:
287
+ trace_event.on_log(
288
+ "",
289
+ **{
290
+ "step_suffix": "results",
291
+ "payload": {
292
+ "request_id": response.request_id,
293
+ "fetch_result": response,
294
+ },
295
+ },
296
+ )
297
+
298
+ if (
299
+ response.status_code != HTTPStatus.OK
300
+ or not response.output
301
+ or response.output.task_status in ["FAILED", "CANCELED"]
302
+ ):
303
+ raise RuntimeError(f"Failed to fetch result: {response}")
304
+
305
+ # Handle request ID
306
+ if not request_id:
307
+ request_id = (
308
+ response.request_id
309
+ if response.request_id
310
+ else str(uuid.uuid4())
311
+ )
312
+
313
+ result = TextToVideoFetchOutput(
314
+ video_url=response.output.video_url,
315
+ task_id=response.output.task_id,
316
+ task_status=response.output.task_status,
317
+ request_id=request_id,
318
+ )
319
+
320
+ return result
@@ -0,0 +1,334 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint:disable=abstract-method, deprecated-module, wrong-import-order
3
+
4
+ import os
5
+ import uuid
6
+ from http import HTTPStatus
7
+ from typing import Any, Optional
8
+
9
+ from dashscope.aigc.video_synthesis import AioVideoSynthesis
10
+ from mcp.server.fastmcp import Context
11
+ from pydantic import BaseModel, Field
12
+
13
+ from ..base import Tool
14
+ from ..utils.api_key_util import get_api_key, ApiNames
15
+ from ...engine.tracing import trace, TracingUtil
16
+
17
+
18
+ class TextToVideoWan25SubmitInput(BaseModel):
19
+ """
20
+ Text to video generation input model
21
+ """
22
+
23
+ prompt: str = Field(
24
+ ...,
25
+ description="正向提示词,用来描述生成视频中期望包含的元素和视觉特点, 超过800个字符自动截断",
26
+ )
27
+ negative_prompt: Optional[str] = Field(
28
+ default=None,
29
+ description="反向提示词,用来描述不希望在视频画面中看到的内容,可以对视频画面进行限制,超过500个字符自动截断",
30
+ )
31
+ audio_url: Optional[str] = Field(
32
+ default=None,
33
+ description="自定义音频文件URL,模型将使用该音频生成视频。"
34
+ "参数优先级:audio_url > audio,仅在 audio_url 为空时audio生效。",
35
+ )
36
+ audio: Optional[bool] = Field(
37
+ default=None,
38
+ description="是否自动生成音频。"
39
+ "参数优先级:audio_url > audio,仅在 audio_url 为空时audio生效。",
40
+ )
41
+ size: Optional[str] = Field(
42
+ default=None,
43
+ description="视频分辨率,默认不设置",
44
+ )
45
+ duration: Optional[int] = Field(
46
+ default=None,
47
+ description="视频生成时长,单位为秒",
48
+ )
49
+ prompt_extend: Optional[bool] = Field(
50
+ default=None,
51
+ description="是否开启prompt智能改写,开启后使用大模型对输入prompt进行智能改写",
52
+ )
53
+ watermark: Optional[bool] = Field(
54
+ default=None,
55
+ description="是否添加水印,默认不设置",
56
+ )
57
+ ctx: Optional[Context] = Field(
58
+ default=None,
59
+ description="HTTP request context containing headers for mcp only, "
60
+ "don't generate it",
61
+ )
62
+
63
+
64
+ class TextToVideoWan25SubmitOutput(BaseModel):
65
+ """
66
+ Text to video generation output model
67
+ """
68
+
69
+ task_id: str = Field(
70
+ title="Task ID",
71
+ description="视频生成的任务ID",
72
+ )
73
+
74
+ task_status: str = Field(
75
+ title="Task Status",
76
+ description="视频生成的任务状态,PENDING:任务排队中,RUNNING:任务处理中,SUCCEEDED:任务执行成功,"
77
+ "FAILED:任务执行失败,CANCELED:任务取消成功,UNKNOWN:任务不存在或状态未知",
78
+ )
79
+
80
+ request_id: Optional[str] = Field(
81
+ default=None,
82
+ title="Request ID",
83
+ description="请求ID",
84
+ )
85
+
86
+
87
+ class TextToVideoWan25Submit(
88
+ Tool[TextToVideoWan25SubmitInput, TextToVideoWan25SubmitOutput],
89
+ ):
90
+ """
91
+ Text to video generation service that converts text into videos
92
+ using DashScope's VideoSynthesis API.
93
+ """
94
+
95
+ name: str = "modelstudio_text_to_video_wan25_submit_task"
96
+ description: str = (
97
+ "通义万相-文生视频模型的异步任务提交工具。可根据文本生成5秒或10秒有声视频,支持 480P、720P、1080P 多种分辨率档位,"
98
+ "支持自动配音,或传入自定义音频文件,实现音画同步。"
99
+ )
100
+
101
+ @trace(trace_type="AIGC", trace_name="text_to_video_wan25_submit")
102
+ async def arun(
103
+ self,
104
+ args: TextToVideoWan25SubmitInput,
105
+ **kwargs: Any,
106
+ ) -> TextToVideoWan25SubmitOutput:
107
+ """
108
+ Generate video from text prompt using DashScope VideoSynthesis
109
+
110
+ This method wraps DashScope's VideoSynthesis service to generate videos
111
+ based on text descriptions. It uses async call pattern for better
112
+ performance and supports polling for task completion.
113
+
114
+ Args:
115
+ args: TextToVideoWan25SubmitInput containing optional parameters
116
+ **kwargs: Additional keyword arguments including:
117
+ - request_id: Optional request ID for tracking
118
+ - model_name: Model name to use (defaults to wan2.2-t2v-plus)
119
+ - api_key: DashScope API key for authentication
120
+
121
+ Returns:
122
+ TextToVideoWan25SubmitOutput containing the generated video URL
123
+ and request ID
124
+
125
+ Raises:
126
+ ValueError: If DASHSCOPE_API_KEY is not set or invalid
127
+ TimeoutError: If video generation takes too long
128
+ RuntimeError: If video generation fails
129
+ """
130
+ trace_event = kwargs.pop("trace_event", None)
131
+ request_id = TracingUtil.get_request_id()
132
+
133
+ try:
134
+ api_key = get_api_key(ApiNames.dashscope_api_key, **kwargs)
135
+ except AssertionError as e:
136
+ raise ValueError("Please set valid DASHSCOPE_API_KEY!") from e
137
+
138
+ model_name = kwargs.get(
139
+ "model_name",
140
+ os.getenv("TEXT_TO_VIDEO_MODEL_NAME", "wan2.5-t2v-preview"),
141
+ )
142
+
143
+ parameters = {}
144
+ if args.prompt_extend is not None:
145
+ parameters["prompt_extend"] = args.prompt_extend
146
+ if args.audio is not None:
147
+ parameters["audio"] = args.audio
148
+ if args.size:
149
+ parameters["size"] = args.size
150
+ if args.duration is not None:
151
+ parameters["duration"] = args.duration
152
+ if args.watermark is not None:
153
+ parameters["watermark"] = args.watermark
154
+
155
+ # Create AioVideoSynthesis instance
156
+ aio_video_synthesis = AioVideoSynthesis()
157
+
158
+ # Submit async task
159
+ response = await aio_video_synthesis.async_call(
160
+ model=model_name,
161
+ api_key=api_key,
162
+ prompt=args.prompt,
163
+ negative_prompt=args.negative_prompt,
164
+ audio_url=args.audio_url,
165
+ **parameters,
166
+ )
167
+ # Log trace event if provided
168
+ if trace_event:
169
+ trace_event.on_log(
170
+ "",
171
+ **{
172
+ "step_suffix": "results",
173
+ "payload": {
174
+ "request_id": request_id,
175
+ "submit_task": response,
176
+ },
177
+ },
178
+ )
179
+
180
+ if (
181
+ response.status_code != HTTPStatus.OK
182
+ or not response.output
183
+ or response.output.task_status in ["FAILED", "CANCELED"]
184
+ ):
185
+ raise RuntimeError(f"Failed to submit task: {response}")
186
+
187
+ if not request_id:
188
+ request_id = (
189
+ response.request_id
190
+ if response.request_id
191
+ else str(uuid.uuid4())
192
+ )
193
+
194
+ result = TextToVideoWan25SubmitOutput(
195
+ request_id=request_id,
196
+ task_id=response.output.task_id,
197
+ task_status=response.output.task_status,
198
+ )
199
+ return result
200
+
201
+
202
+ class TextToVideoWan25FetchInput(BaseModel):
203
+ """
204
+ Text to video fetch task input model
205
+ """
206
+
207
+ task_id: str = Field(
208
+ title="Task ID",
209
+ description="视频生成的任务ID",
210
+ )
211
+ ctx: Optional[Context] = Field(
212
+ default=None,
213
+ description="HTTP request context containing headers for mcp only, "
214
+ "don't generate it",
215
+ )
216
+
217
+
218
+ class TextToVideoWan25FetchOutput(BaseModel):
219
+ """
220
+ Text to video fetch task output model
221
+ """
222
+
223
+ video_url: str = Field(
224
+ title="Video URL",
225
+ description="输出的视频url",
226
+ )
227
+
228
+ task_id: str = Field(
229
+ title="Task ID",
230
+ description="视频生成的任务ID",
231
+ )
232
+
233
+ task_status: str = Field(
234
+ title="Task Status",
235
+ description="视频生成的任务状态,PENDING:任务排队中,RUNNING:任务处理中,SUCCEEDED:任务执行成功,"
236
+ "FAILED:任务执行失败,CANCELED:任务取消成功,UNKNOWN:任务不存在或状态未知",
237
+ )
238
+
239
+ request_id: Optional[str] = Field(
240
+ default=None,
241
+ title="Request ID",
242
+ description="请求ID",
243
+ )
244
+
245
+
246
+ class TextToVideoWan25Fetch(
247
+ Tool[TextToVideoWan25FetchInput, TextToVideoWan25FetchOutput],
248
+ ):
249
+ """
250
+ Text to video fetch service that retrieves video generation results
251
+ using DashScope's VideoSynthesis API.
252
+ """
253
+
254
+ name: str = "modelstudio_text_to_video_wan25_fetch_result"
255
+ description: str = "通义万相-文生视频模型的异步任务结果查询工具,根据Task ID查询任务结果。"
256
+
257
+ @trace(trace_type="AIGC", trace_name="text_to_video_wan25_fetch")
258
+ async def arun(
259
+ self,
260
+ args: TextToVideoWan25FetchInput,
261
+ **kwargs: Any,
262
+ ) -> TextToVideoWan25FetchOutput:
263
+ """
264
+ Fetch video generation result using DashScope VideoSynthesis
265
+
266
+ This method wraps DashScope's VideoSynthesis fetch service to retrieve
267
+ video generation results based on task ID. It uses async call pattern
268
+ for better performance.
269
+
270
+ Args:
271
+ args: TextToVideoWan25FetchInput containing task_id parameter
272
+ **kwargs: Additional keyword arguments including:
273
+ - api_key: DashScope API key for authentication
274
+
275
+ Returns:
276
+ TextToVideoWan25FetchOutput containing the video URL, task status
277
+ and request ID
278
+
279
+ Raises:
280
+ ValueError: If DASHSCOPE_API_KEY is not set or invalid
281
+ RuntimeError: If video fetch fails or response status is not OK
282
+ """
283
+ trace_event = kwargs.pop("trace_event", None)
284
+ request_id = TracingUtil.get_request_id()
285
+
286
+ try:
287
+ api_key = get_api_key(ApiNames.dashscope_api_key, **kwargs)
288
+ except AssertionError as e:
289
+ raise ValueError("Please set valid DASHSCOPE_API_KEY!") from e
290
+
291
+ # Create AioVideoSynthesis instance
292
+ aio_video_synthesis = AioVideoSynthesis()
293
+
294
+ response = await aio_video_synthesis.fetch(
295
+ api_key=api_key,
296
+ task=args.task_id,
297
+ )
298
+
299
+ # Log trace event if provided
300
+ if trace_event:
301
+ trace_event.on_log(
302
+ "",
303
+ **{
304
+ "step_suffix": "results",
305
+ "payload": {
306
+ "request_id": response.request_id,
307
+ "fetch_result": response,
308
+ },
309
+ },
310
+ )
311
+
312
+ if (
313
+ response.status_code != HTTPStatus.OK
314
+ or not response.output
315
+ or response.output.task_status in ["FAILED", "CANCELED"]
316
+ ):
317
+ raise RuntimeError(f"Failed to fetch result: {response}")
318
+
319
+ # Handle request ID
320
+ if not request_id:
321
+ request_id = (
322
+ response.request_id
323
+ if response.request_id
324
+ else str(uuid.uuid4())
325
+ )
326
+
327
+ result = TextToVideoWan25FetchOutput(
328
+ video_url=response.output.video_url,
329
+ task_id=response.output.task_id,
330
+ task_status=response.output.task_status,
331
+ request_id=request_id,
332
+ )
333
+
334
+ return result