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,377 @@
1
+ # -*- coding: utf-8 -*-
2
+ import asyncio
3
+ import logging
4
+ import traceback
5
+ from typing import Any, Dict, List, Tuple, Union, Optional
6
+
7
+ import aiohttp
8
+ from pydantic import BaseModel, Field
9
+
10
+ from ..base import Tool
11
+ from .._constants import (
12
+ DASHSCOPE_HTTP_BASE_URL,
13
+ DASHSCOPE_API_KEY,
14
+ )
15
+ from ...engine.schemas.modelstudio_llm import (
16
+ OpenAIMessage,
17
+ RagOptions,
18
+ )
19
+ from ...engine.schemas.oai_llm import UserMessage
20
+ from ...engine.tracing import trace
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+ PIPELINE_SIMPLE_ENDPOINT = "/indices/pipeline_simple"
25
+ PIPELINE_RETRIEVE_PROMPT_ENDPOINT = "/indices/pipeline/retrieve_prompt"
26
+
27
+
28
+ class RagInput(BaseModel):
29
+ """
30
+ Search Input.
31
+ """
32
+
33
+ messages: Union[str, List[Union[OpenAIMessage, Dict]]] = Field(
34
+ ...,
35
+ description="user query in the format of str or message, "
36
+ "**do not generate message format**",
37
+ )
38
+ rag_options: Optional[Union[RagOptions, Dict]] = Field(
39
+ default=None,
40
+ description="Rag options",
41
+ )
42
+ rest_token: Optional[int] = Field(default=1500, description="rest token")
43
+ image_urls: Optional[List[str]] = Field(
44
+ default=[],
45
+ description="image urls for multimodal RAG",
46
+ )
47
+ workspace_id: Optional[str] = Field(
48
+ "",
49
+ description="user workspace id could be found at modelstudio",
50
+ )
51
+
52
+
53
+ class RagOutput(BaseModel):
54
+ """
55
+ Search Input.
56
+ """
57
+
58
+ raw_result: List[dict] = Field(
59
+ ...,
60
+ description="raw result from rag service",
61
+ )
62
+ rag_result: str = Field(
63
+ ...,
64
+ description="rag retrieval result with ranking in the format of "
65
+ "string",
66
+ )
67
+ messages: Optional[List[OpenAIMessage]] = Field(
68
+ ...,
69
+ description="user query in the format of Message "
70
+ "with updated system prompt",
71
+ )
72
+
73
+
74
+ class ModelstudioRag(Tool[RagInput, RagOutput]):
75
+ """
76
+ Dashscope Rag Tool that recalling user info on modelstudio
77
+ """
78
+
79
+ description: str = (
80
+ "Modelstudio_Rag可召回用户在百炼上的数据库中存储的信息,当用户要求搜索图片"
81
+ "或者指定库里信息的时候,请优先调用该工具在用户自己库里的查找一下是否有相关信息。"
82
+ )
83
+ name: str = "modelstudio_RAG"
84
+
85
+ @trace(trace_type="RAG", trace_name="modelstudio_rag")
86
+ async def _arun(self, args: RagInput, **kwargs: Any) -> RagOutput:
87
+ """RAG Tool to retrieve and augment user data on Modelstudio.
88
+
89
+ This method performs RAG by querying the user's knowledge base on
90
+ Modelstudio platform and updating the system prompt with the retrieved
91
+ information.
92
+
93
+ Args:
94
+ args: RagInput containing user messages, RAG options, workspace ID,
95
+ and other configuration parameters.
96
+ **kwargs: Additional keyword arguments including:
97
+ - api_key: DashScope API key for authentication
98
+
99
+ Returns:
100
+ RagOutput containing the retrieved text and updated messages with
101
+ augmented system prompt.
102
+
103
+ Raises:
104
+ ValueError: If DASHSCOPE_API_KEY is not set or provided.
105
+ """
106
+ # make sure the rag could generate simple result for function call
107
+ is_function_call: bool = False
108
+ if isinstance(args.messages, str):
109
+ is_function_call = True
110
+
111
+ try:
112
+ if args.rag_options and not isinstance(
113
+ args.rag_options,
114
+ RagOptions,
115
+ ):
116
+ args.rag_options = RagOptions(**args.rag_options, **kwargs)
117
+ # tracer = kwargs.get('tracer', get_tracer())
118
+
119
+ payload, headers = await ModelstudioRag.generate_rag_request(
120
+ args,
121
+ **kwargs,
122
+ )
123
+
124
+ kwargs["context"] = {
125
+ "payload": payload,
126
+ }
127
+
128
+ base_url = kwargs.get("base_url", DASHSCOPE_HTTP_BASE_URL)
129
+
130
+ rag_url = base_url + PIPELINE_RETRIEVE_PROMPT_ENDPOINT
131
+
132
+ async with aiohttp.ClientSession() as session:
133
+ async with session.post(
134
+ rag_url,
135
+ headers=headers,
136
+ json=payload,
137
+ ) as response:
138
+ if response.status != 200:
139
+ text = await response.text()
140
+ raise RuntimeError(text)
141
+
142
+ response_json = await response.json()
143
+ if response_json.get("data"):
144
+ result = response_json["data"][0]["text"]
145
+ output_messages = ModelstudioRag.update_system_prompt(
146
+ args,
147
+ result,
148
+ )
149
+ if is_function_call:
150
+ return RagOutput(
151
+ rag_result=result,
152
+ raw_result=[],
153
+ messages=None,
154
+ )
155
+ else:
156
+ return RagOutput(
157
+ rag_result=result,
158
+ raw_result=response_json["data"][0]["nodes"],
159
+ messages=output_messages,
160
+ )
161
+ else:
162
+ return RagOutput(
163
+ rag_result="",
164
+ raw_result=[],
165
+ messages=args.messages,
166
+ )
167
+ except Exception as e:
168
+ logger.error(f"{e}: {traceback.format_exc()}")
169
+ return RagOutput(
170
+ rag_result="",
171
+ raw_result=[],
172
+ messages=args.messages,
173
+ )
174
+
175
+ @staticmethod
176
+ async def generate_rag_request(
177
+ rag_input: RagInput,
178
+ **kwargs: Any,
179
+ ) -> Tuple[Dict, Dict]:
180
+ """Generate the request payload and headers for RAG API call.
181
+
182
+ This method constructs the complete request including payload and
183
+ headers needed for the Modelstudio RAG service API call.
184
+
185
+ Args:
186
+ rag_input: RagInput containing all the necessary information
187
+ for the RAG request.
188
+ **kwargs: Additional keyword arguments including:
189
+ - api_key: DashScope API key for authentication
190
+
191
+ Returns:
192
+ Tuple containing:
193
+ - Dict: The request payload with query, options,
194
+ and configuration
195
+ - Dict: The HTTP headers including authorization and
196
+ workspace info
197
+
198
+ Raises:
199
+ ValueError: If DASHSCOPE_API_KEY is not set or provided.
200
+ """
201
+ api_key = kwargs.get(
202
+ "api_key",
203
+ DASHSCOPE_API_KEY,
204
+ )
205
+
206
+ base_url = kwargs.get("base_url", DASHSCOPE_HTTP_BASE_URL)
207
+
208
+ if not api_key:
209
+ raise ValueError("DASHSCOPE_API_KEY is not set")
210
+
211
+ async def _build_body(_rag_input: RagInput, base_url: str) -> dict:
212
+ """Build the request body for RAG API call.
213
+
214
+ Args:
215
+ _rag_input: RagInput containing the request parameters.
216
+
217
+ Returns:
218
+ Dict containing the formatted request body.
219
+ """
220
+ _rag_options = _rag_input.rag_options
221
+
222
+ # get pipeline_id_list from either index_names or pipeline_ids
223
+ pipeline_id_list = [
224
+ pid for pid in _rag_options.pipeline_ids if pid
225
+ ]
226
+ if _rag_options.index_names:
227
+ tasks = [
228
+ ModelstudioRag.get_pipeline_id(
229
+ api_key,
230
+ base_url,
231
+ index_name,
232
+ )
233
+ for index_name in _rag_options.index_names
234
+ if index_name
235
+ ]
236
+ task_results = await asyncio.gather(*tasks)
237
+ pipeline_id_list.extend(
238
+ [task for task in task_results if task],
239
+ )
240
+
241
+ if not pipeline_id_list:
242
+ raise ValueError(
243
+ "Please specify pipeline_ids or index_names",
244
+ )
245
+
246
+ data = await ModelstudioRag.get_body(_rag_input, pipeline_id_list)
247
+
248
+ return data
249
+
250
+ header = {
251
+ "Content-Type": "application/json",
252
+ "Accept-Encoding": "utf-8",
253
+ "Authorization": "Bearer " + api_key,
254
+ }
255
+
256
+ if kwargs.get("user_id"):
257
+ header["X-DashScope-Uid"] = kwargs.get("user_id")
258
+ if kwargs.get("subuser_id"):
259
+ header["X-DashScope-SubUid"] = kwargs.get("subuser_id")
260
+
261
+ payload = await _build_body(rag_input, base_url)
262
+ return payload, header
263
+
264
+ @staticmethod
265
+ def update_system_prompt(
266
+ rag_input: RagInput,
267
+ rag_text: str,
268
+ ) -> List[OpenAIMessage]:
269
+ """Update system prompt with retrieved RAG text.
270
+
271
+ This method processes the original messages and replaces the
272
+ placeholder in the system prompt with the retrieved RAG text.
273
+
274
+ Args:
275
+ rag_input: RagInput containing the original messages and
276
+ replacement configuration.
277
+ rag_text: The retrieved text to insert into the system prompt.
278
+
279
+ Returns:
280
+ List of PromptMessage objects with updated system prompt
281
+ containing the RAG text.
282
+ """
283
+ replaced_word = rag_input.rag_options.replaced_word
284
+ messages = []
285
+ if isinstance(rag_input.messages, str):
286
+ rag_messages = [UserMessage(content=rag_input.messages)]
287
+ rag_input.messages = rag_messages
288
+ for message in rag_input.messages:
289
+ content = message.content
290
+ if message.role == "system":
291
+ if isinstance(content, str) and replaced_word in content:
292
+ content = content.replace(replaced_word, rag_text)
293
+ messages.append(OpenAIMessage(role=message.role, content=content))
294
+ return messages
295
+
296
+ @staticmethod
297
+ async def get_body(
298
+ _rag_input: RagInput,
299
+ pipeline_id_list: Optional[List[str]] = None,
300
+ ) -> dict:
301
+ if isinstance(_rag_input.messages, str):
302
+ query_content = _rag_input.messages
303
+ history = []
304
+ system_prompt = None
305
+ else:
306
+ for i, item in enumerate(_rag_input.messages):
307
+ if isinstance(item, dict):
308
+ _rag_input.messages[i] = OpenAIMessage(**item)
309
+ query_content = _rag_input.messages[-1].content
310
+ history = [
311
+ message.model_dump() for message in _rag_input.messages[:-1]
312
+ ]
313
+ system_prompt = next(
314
+ (
315
+ message.content
316
+ for message in _rag_input.messages
317
+ if message.role == "system"
318
+ ),
319
+ None,
320
+ )
321
+ _rag_options = _rag_input.rag_options
322
+
323
+ data = _rag_options.model_dump(by_alias=True, exclude_none=True)
324
+
325
+ data["query"] = query_content
326
+ if system_prompt:
327
+ data["system_prompt"] = system_prompt
328
+ if history:
329
+ data["query_history"] = history
330
+
331
+ if pipeline_id_list:
332
+ data["pipeline_id_list"] = pipeline_id_list
333
+
334
+ if _rag_input.image_urls:
335
+ data["image_list"] = _rag_input.image_urls
336
+
337
+ if _rag_input.rest_token is not None:
338
+ data["prompt_max_token_length"] = [_rag_input.rest_token]
339
+
340
+ return data
341
+
342
+ @staticmethod
343
+ async def get_pipeline_id(
344
+ api_key: str,
345
+ base_url: str,
346
+ index_name: str,
347
+ ) -> str:
348
+ url = base_url + PIPELINE_SIMPLE_ENDPOINT
349
+
350
+ headers = {
351
+ "Content-Type": "application/json",
352
+ "Accept-Encoding": "utf-8",
353
+ "Authorization": api_key,
354
+ "X-DashScope-OpenAPISource": "CloudSDK",
355
+ }
356
+
357
+ params = {"pipeline_name": index_name}
358
+
359
+ try:
360
+ async with aiohttp.ClientSession() as session:
361
+ async with session.get(
362
+ url,
363
+ headers=headers,
364
+ params=params,
365
+ ) as response:
366
+ if response.status != 200:
367
+ text = await response.text()
368
+ raise RuntimeError(text)
369
+
370
+ response_dict = await response.json()
371
+ if response_dict.get("code") != "Success":
372
+ raise RuntimeError(response_dict)
373
+ return response_dict.get("id", "")
374
+ except Exception as e:
375
+ raise RuntimeError(
376
+ f"get pipeline id exceptionally: {str(e)}",
377
+ ) from e
@@ -0,0 +1,219 @@
1
+ # -*- coding: utf-8 -*-
2
+ import asyncio
3
+ from typing import Any, Dict, List, Tuple, Optional
4
+
5
+ import aiohttp
6
+
7
+ from .modelstudio_rag import (
8
+ RagInput,
9
+ RagOutput,
10
+ ModelstudioRag,
11
+ )
12
+ from ..base import Tool
13
+ from .._constants import (
14
+ DASHSCOPE_HTTP_BASE_URL,
15
+ DASHSCOPE_API_KEY,
16
+ )
17
+ from ...engine.schemas.modelstudio_llm import (
18
+ OpenAIMessage,
19
+ RagOptions,
20
+ )
21
+ from ...engine.tracing import trace
22
+
23
+ PIPELINE_RETRIEVE_ENDPOINT = "/indices/pipeline/{pipeline_id}/retrieve"
24
+
25
+
26
+ class ModelstudioRagLite(Tool[RagInput, RagOutput]):
27
+ """
28
+ Dashscope Rag Tool that recalling user info on modelstudio
29
+ """
30
+
31
+ description: str = "Modelstudio Rag可召回用户在百炼上的数据库中存储的信息,用于后续大模型生成使用。"
32
+ name: str = "modelstudio_RAG_lite"
33
+
34
+ @trace(trace_type="RAG", trace_name="modelstudio_rag_lite")
35
+ async def _arun(self, args: RagInput, **kwargs: Any) -> RagOutput:
36
+ """RAG Tool to retrieve and augment user data on Modelstudio.
37
+
38
+ This method performs RAG by querying the user's knowledge base on
39
+ Modelstudio platform and updating the system prompt with the retrieved
40
+ information.
41
+
42
+ Args:
43
+ args: RagInput containing user messages, RAG options, workspace ID,
44
+ and other configuration parameters.
45
+ **kwargs: Additional keyword arguments including:
46
+ - api_key: DashScope API key for authentication
47
+
48
+ Returns:
49
+ RagOutput containing the retrieved text and updated messages with
50
+ augmented system prompt.
51
+
52
+ Raises:
53
+ ValueError: If DASHSCOPE_API_KEY is not set or provided.
54
+ """
55
+ #
56
+ if isinstance(args.rag_options, dict):
57
+ args.rag_options = RagOptions(**args.rag_options)
58
+ # tracer = kwargs.get('tracer', get_tracer())
59
+
60
+ tasks = [
61
+ self.retrieve_one_index(args, index_name, None, **kwargs)
62
+ for index_name in args.rag_options.index_names
63
+ if index_name
64
+ ] + [
65
+ self.retrieve_one_index(args, None, pipeline_id, **kwargs)
66
+ for pipeline_id in args.rag_options.pipeline_ids
67
+ if pipeline_id
68
+ ]
69
+
70
+ task_results = await asyncio.gather(*tasks)
71
+ raw_result = []
72
+ for task_result in task_results:
73
+ if task_result.get("nodes"):
74
+ raw_result.extend(task_result.get("nodes", []))
75
+
76
+ return RagOutput(
77
+ rag_result="",
78
+ raw_result=raw_result,
79
+ messages=args.messages,
80
+ )
81
+
82
+ @staticmethod
83
+ async def retrieve_one_index(
84
+ args: RagInput,
85
+ index_name: Optional[str] = None,
86
+ pipeline_id: Optional[str] = None,
87
+ **kwargs: Any,
88
+ ) -> Dict[str, Any]:
89
+ base_url = kwargs.get("base_url", DASHSCOPE_HTTP_BASE_URL)
90
+
91
+ api_key = kwargs.get(
92
+ "api_key",
93
+ DASHSCOPE_API_KEY,
94
+ )
95
+
96
+ if not pipeline_id and index_name:
97
+ pipeline_id = await ModelstudioRag.get_pipeline_id(
98
+ api_key,
99
+ base_url,
100
+ index_name,
101
+ )
102
+
103
+ if not pipeline_id:
104
+ raise ValueError(
105
+ "Please specify pipeline_id or index_name",
106
+ )
107
+
108
+ payload, headers = await ModelstudioRagLite.generate_rag_request(
109
+ args,
110
+ **kwargs,
111
+ )
112
+
113
+ rag_url = base_url + PIPELINE_RETRIEVE_ENDPOINT.format(
114
+ pipeline_id=pipeline_id,
115
+ )
116
+
117
+ try:
118
+ async with aiohttp.ClientSession() as session:
119
+ async with session.post(
120
+ rag_url,
121
+ headers=headers,
122
+ json=payload,
123
+ ) as response:
124
+ if response.status != 200:
125
+ text = await response.text()
126
+ raise RuntimeError(text)
127
+
128
+ response_dict = await response.json()
129
+ return response_dict
130
+ except Exception as e:
131
+ raise RuntimeError(
132
+ f"retrieve pipeline exceptionally: {str(e)}",
133
+ ) from e
134
+
135
+ @staticmethod
136
+ async def generate_rag_request(
137
+ rag_input: RagInput,
138
+ **kwargs: Any,
139
+ ) -> Tuple[Dict, Dict]:
140
+ """Generate the request payload and headers for RAG API call.
141
+
142
+ This method constructs the complete request including payload and
143
+ headers needed for the Modelstudio RAG service API call.
144
+
145
+ Args:
146
+ rag_input: RagInput containing all the necessary information
147
+ for the RAG request.
148
+ **kwargs: Additional keyword arguments including:
149
+ - api_key: DashScope API key for authentication
150
+
151
+ Returns:
152
+ Tuple containing:
153
+ - Dict: The request payload with query, options,
154
+ and configuration
155
+ - Dict: The HTTP headers including authorization and
156
+ workspace info
157
+
158
+ Raises:
159
+ ValueError: If DASHSCOPE_API_KEY is not set or provided.
160
+ """
161
+ api_key = kwargs.get(
162
+ "api_key",
163
+ DASHSCOPE_API_KEY,
164
+ )
165
+
166
+ async def _build_body(_rag_input: RagInput) -> dict:
167
+ """Build the request body for RAG API call.
168
+
169
+ Args:
170
+ _rag_input: RagInput containing the request parameters.
171
+
172
+ Returns:
173
+ Dict containing the formatted request body.
174
+ """
175
+ data = await ModelstudioRag.get_body(_rag_input)
176
+ return data
177
+
178
+ header = {
179
+ "Content-Type": "application/json",
180
+ "Accept-Encoding": "utf-8",
181
+ "Authorization": "Bearer " + api_key,
182
+ }
183
+
184
+ if kwargs.get("user_id"):
185
+ header["X-DashScope-Uid"] = kwargs.get("user_id")
186
+ if kwargs.get("subuser_id"):
187
+ header["X-DashScope-SubUid"] = kwargs.get("subuser_id")
188
+
189
+ payload = await _build_body(rag_input)
190
+ return payload, header
191
+
192
+ @staticmethod
193
+ def update_system_prompt(
194
+ rag_input: RagInput,
195
+ rag_text: str,
196
+ ) -> List[OpenAIMessage]:
197
+ """Update system prompt with retrieved RAG text.
198
+
199
+ This method processes the original messages and replaces the
200
+ placeholder in the system prompt with the retrieved RAG text.
201
+
202
+ Args:
203
+ rag_input: RagInput containing the original messages and
204
+ replacement configuration.
205
+ rag_text: The retrieved text to insert into the system prompt.
206
+
207
+ Returns:
208
+ List of PromptMessage objects with updated system prompt
209
+ containing the RAG text.
210
+ """
211
+ replaced_word = rag_input.rag_options.replaced_word
212
+ messages = []
213
+ for message in rag_input.messages:
214
+ content = message.content
215
+ if message.role == "system":
216
+ if isinstance(content, str) and replaced_word in content:
217
+ content = content.replace(replaced_word, rag_text)
218
+ messages.append(OpenAIMessage(role=message.role, content=content))
219
+ return messages