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,310 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint:disable=unused-argument, (unused-argument
3
+
4
+ import json
5
+ import os
6
+ from typing import Any, Dict, List, Optional, Tuple
7
+
8
+ import aiohttp
9
+ from mcp.server.fastmcp import Context
10
+ from pydantic import BaseModel, Field
11
+
12
+ from .modelstudio_search import (
13
+ SEARCH_PAGE,
14
+ SEARCH_STRATEGY_SETTING,
15
+ SEARCH_TIMEOUT,
16
+ FieldValidator,
17
+ )
18
+ from ..utils.mcp_util import get_mcp_dash_request_id
19
+ from ...engine.tracing import trace
20
+ from ..base import Tool
21
+
22
+ SEARCH_URL = os.getenv(
23
+ "SEARCH_URL",
24
+ "https://dashscope.aliyuncs.com/api/v1/indices/plugin/mcp_search",
25
+ )
26
+ SEARCH_STRATEGY = os.getenv("SEARCH_STRATEGY", "turbo")
27
+ DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY", None)
28
+ SEARCH_RULES = {
29
+ "url": {
30
+ "DROPOUT_ENTIRE_IF_MISSING": "DROPOUT_ENTIRE_IF_MISSING",
31
+ "FILTER_ITEMS_FROM_LIST": [
32
+ "uclink://www.uc.cn",
33
+ "qklink://www.quark.cn",
34
+ "https://page.sm.cn",
35
+ ],
36
+ },
37
+ "title": "DROPOUT_ENTIRE_IF_MISSING",
38
+ }
39
+
40
+
41
+ class SearchLiteInput(BaseModel):
42
+ """
43
+ Search Input.
44
+ """
45
+
46
+ query: str = Field(..., description="user query in the format of string")
47
+ count: int = Field(default=5, description="number of search results")
48
+ ctx: Optional[Context] = Field(
49
+ default=None,
50
+ description="HTTP request context containing headers",
51
+ )
52
+
53
+
54
+ class SearchLiteOutput(BaseModel):
55
+ """
56
+ Search Output.
57
+ """
58
+
59
+ status: int = Field(
60
+ ...,
61
+ description="status code for success or failed, 0 is success",
62
+ )
63
+ pages: List[Dict[str, Any]] = Field(
64
+ ...,
65
+ description="Search results with url, title, etc,.",
66
+ )
67
+ tools: List[Dict[str, Any]] = Field(
68
+ ...,
69
+ description="The tool calling result during search",
70
+ )
71
+ request_id: Optional[str] = Field(
72
+ default=None,
73
+ title="Request ID",
74
+ description="请求ID",
75
+ )
76
+
77
+
78
+ class ModelstudioSearchLite(Tool[SearchLiteInput, SearchLiteOutput]):
79
+ """
80
+ Search tool that calling dashscope for llm search result.
81
+ """
82
+
83
+ description = "搜索可用于查询百科知识、时事新闻、天气等信息"
84
+ name = "modelstudio_web_search"
85
+
86
+ @trace(trace_type="SEARCH", trace_name="modelstudio_search_lite")
87
+ async def _arun(
88
+ self,
89
+ args: SearchLiteInput,
90
+ **kwargs: Any,
91
+ ) -> SearchLiteOutput:
92
+ """
93
+ Run the search component with SearchLiteInput and return
94
+ SearchLiteOutput.
95
+ Args:
96
+ args: in SearchLiteInput format that generated by from llm
97
+ ctx: Optional MCP context containing request information
98
+ **kwargs: should include other arguments if needed,
99
+ 'trace_event' in kwargs can be used for tracing_utils
100
+
101
+ Returns:SearchLiteOutput
102
+
103
+ """
104
+
105
+ if DASHSCOPE_API_KEY is None:
106
+ raise ValueError(
107
+ "DASHSCOPE_API_KEY is required for search component, "
108
+ "please get your dashscope api-key on Modelstudio platform",
109
+ )
110
+ trace_event = kwargs.pop("trace_event", None)
111
+ request_id = get_mcp_dash_request_id(args.ctx)
112
+
113
+ # call search engine to get search result
114
+ payload = ModelstudioSearchLite.generate_search_payload(
115
+ search_input=args,
116
+ request_id=request_id,
117
+ rid=request_id,
118
+ )
119
+ header = {
120
+ "Content-Type": "application/json",
121
+ "Accept-Encoding": "utf-8",
122
+ "Authorization": "Bearer " + DASHSCOPE_API_KEY,
123
+ "x-acs-req-uuid": request_id,
124
+ }
125
+ kwargs["context"] = {
126
+ "payload": payload,
127
+ "search_strategy": SEARCH_STRATEGY,
128
+ "timeout": SEARCH_TIMEOUT,
129
+ }
130
+
131
+ trace_event.on_log(
132
+ "",
133
+ **{
134
+ "step_suffix": "test_header_inject",
135
+ "payload": {
136
+ "request_id": request_id,
137
+ "dash_request_id": request_id,
138
+ "search_header": header,
139
+ "search_payload": payload,
140
+ "search_url": SEARCH_URL,
141
+ },
142
+ },
143
+ )
144
+ try:
145
+ (
146
+ search_result,
147
+ extra_tool_info,
148
+ status,
149
+ result_message,
150
+ ) = await ModelstudioSearchLite.dashscope_search_kernel(
151
+ url=SEARCH_URL,
152
+ payload=payload,
153
+ headers=header,
154
+ timeout=SEARCH_TIMEOUT,
155
+ )
156
+ if trace_event:
157
+ trace_event.on_log(
158
+ "",
159
+ **{
160
+ "step_suffix": "results",
161
+ "payload": {
162
+ "request_id": request_id,
163
+ "search_status": status,
164
+ "search_query_result": result_message,
165
+ "search_result": search_result,
166
+ "extra_tool_info": extra_tool_info,
167
+ },
168
+ },
169
+ )
170
+
171
+ except Exception as e:
172
+ print(f"Error: {e}")
173
+ return SearchLiteOutput(
174
+ status=1,
175
+ pages=[],
176
+ tools=[],
177
+ request_id=request_id,
178
+ )
179
+
180
+ # post process search results
181
+ (
182
+ search_items,
183
+ tool_items,
184
+ ) = ModelstudioSearchLite.post_process_search_detail(
185
+ search_results=search_result,
186
+ extra_tool_info=extra_tool_info,
187
+ )
188
+
189
+ return SearchLiteOutput(
190
+ status=0,
191
+ pages=search_items,
192
+ tools=tool_items,
193
+ request_id=request_id,
194
+ )
195
+
196
+ @staticmethod
197
+ def generate_search_payload(
198
+ search_input: SearchLiteInput,
199
+ request_id: str,
200
+ **kwargs: Any,
201
+ ) -> str:
202
+ search_strategy = SEARCH_STRATEGY
203
+
204
+ payload = {
205
+ "scene": SEARCH_STRATEGY_SETTING[search_strategy]["scene"],
206
+ "uq": search_input.query,
207
+ "rid": request_id,
208
+ "fields": [],
209
+ "page": int(SEARCH_PAGE),
210
+ "rows": search_input.count,
211
+ "headers": {
212
+ "__d_head_qto": SEARCH_STRATEGY_SETTING[search_strategy][
213
+ "timeout"
214
+ ],
215
+ },
216
+ }
217
+ result = json.dumps(payload)
218
+ return result
219
+
220
+ @staticmethod
221
+ async def dashscope_search_kernel(
222
+ url: str,
223
+ payload: str,
224
+ headers: Dict,
225
+ timeout: int,
226
+ **kwargs: Any,
227
+ ) -> Tuple[List, List, int, str]:
228
+ extra_tool_info = []
229
+ results_list = []
230
+ results = {}
231
+ try:
232
+ # 使用异步HTTP客户端替代同步requests
233
+ timeout_config = aiohttp.ClientTimeout(total=timeout)
234
+ async with aiohttp.ClientSession(
235
+ timeout=timeout_config,
236
+ ) as session:
237
+ async with session.post(
238
+ url,
239
+ headers=headers,
240
+ data=payload,
241
+ ) as response:
242
+ results = await response.json()
243
+
244
+ result_message = results["message"]
245
+ if results["status"] == 0:
246
+ extra_tool_info = results["data"]["extras"].get(
247
+ "toolResult",
248
+ [],
249
+ )
250
+ results_list = results["data"]["docs"]
251
+ except Exception as e:
252
+ print(f"Error: {e}")
253
+ raise RuntimeError(
254
+ f"Unable to reach search source with error: {e} and result: "
255
+ f"{results}",
256
+ ) from e
257
+
258
+ return results_list, extra_tool_info, results["status"], result_message
259
+
260
+ @staticmethod
261
+ def post_process_search_detail(
262
+ search_results: List,
263
+ extra_tool_info: List,
264
+ **kwargs: Any,
265
+ ) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
266
+ field_validator = FieldValidator(SEARCH_RULES)
267
+ search_items = []
268
+ tool_items = []
269
+
270
+ try:
271
+ for doc in search_results:
272
+ tmp_search_result = {
273
+ "url": doc.get("url", "") or "",
274
+ "title": doc.get("title", "") or "",
275
+ "icon": doc.get("hostlogo", "") or "",
276
+ "site_name": doc.get("hostname", "") or "",
277
+ "image": doc.get("image", "") or "",
278
+ }
279
+ filtered_search_result = field_validator.validate(
280
+ tmp_search_result,
281
+ )
282
+ if filtered_search_result:
283
+ url = doc.get("url")
284
+ url = url.replace(" ", "%20").strip() or "expired_url"
285
+ url = url.replace(
286
+ "chatm6.sm.cn",
287
+ "quark.sm.cn",
288
+ ) # noqa E501
289
+ search_items.append(
290
+ {
291
+ "snippet": doc.get("snippet", ""),
292
+ "title": doc.get("title", ""),
293
+ "url": url,
294
+ "hostname": doc.get("hostname", ""),
295
+ "hostlogo": doc.get("hostlogo", ""),
296
+ },
297
+ )
298
+ for item in extra_tool_info:
299
+ if item.get("tool"):
300
+ tool_items.append(
301
+ {
302
+ "tool": item.get("tool"),
303
+ "result": item.get("result", ""),
304
+ },
305
+ )
306
+ except Exception as e:
307
+ print(f"Error: {e}")
308
+ return [], []
309
+
310
+ return search_items, tool_items
File without changes
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+ from enum import Enum
4
+ from typing import Any, Optional
5
+
6
+
7
+ class ApiNames(Enum):
8
+ """Enumeration of API key names."""
9
+
10
+ dashscope_api_key = "DASHSCOPE_API_KEY"
11
+
12
+
13
+ def get_api_key(
14
+ api_enum: ApiNames,
15
+ key: Optional[str] = None,
16
+ **kwargs: Any,
17
+ ) -> str:
18
+ """Get API key from both input, kwargs, and env sources with priority
19
+ order.
20
+
21
+ Args:
22
+ api_enum (ApiNames): Enum of API name to retrieve.
23
+ key (Optional[str]): Default key value. Defaults to None.
24
+ **kwargs (Any): Additional keyword arguments that might contain the
25
+ API key.
26
+
27
+ Returns:
28
+ str: The API key value.
29
+
30
+ Raises:
31
+ AssertionError: If no API key is found from any source.
32
+ """
33
+ api_key = ""
34
+ if key is not None:
35
+ if kwargs.get(api_enum.name, "") != "":
36
+ if key != kwargs.get(api_enum.name):
37
+ # use runtime key instead of init key
38
+ api_key = kwargs.get(api_enum.name)
39
+ else:
40
+ api_key = key
41
+ else:
42
+ api_key = kwargs.get(api_enum.name, os.environ.get(api_enum.value, ""))
43
+
44
+ assert api_key != "", f"{api_enum.name} must be acquired"
45
+ return api_key
@@ -0,0 +1,99 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Crypto utilities for key format conversion.
4
+ """
5
+
6
+ try:
7
+ from cryptography.hazmat.primitives import serialization
8
+ from cryptography.hazmat.backends import default_backend
9
+
10
+ CRYPTOGRAPHY_AVAILABLE = True
11
+ except ImportError:
12
+ CRYPTOGRAPHY_AVAILABLE = False
13
+ serialization = None
14
+ default_backend = None
15
+
16
+
17
+ def ensure_pkcs1_format(private_key_string: str) -> str:
18
+ """
19
+ Receive a private key string of unknown format and ensure the output is
20
+ in PKCS#1 format.
21
+
22
+ Supported input formats:
23
+ - PKCS#1 PEM format
24
+ - PKCS#8 PEM format
25
+
26
+ Args:
27
+ private_key_string: A string containing the private key (PEM format
28
+ or pure Base64)
29
+
30
+ Returns:
31
+ A string containing the private key in PKCS#1 PEM format.
32
+
33
+ Raises:
34
+ ImportError: Raised when the cryptography library is not installed.
35
+ ValueError: Raised when the private key string is invalid or empty.
36
+ """
37
+ # Check if cryptography library is available
38
+ if not CRYPTOGRAPHY_AVAILABLE:
39
+ raise ImportError(
40
+ "Please install the cryptography library: pip "
41
+ "install cryptography",
42
+ )
43
+
44
+ if not private_key_string or not private_key_string.strip():
45
+ raise ValueError("The private key string cannot be empty.")
46
+
47
+ key_string = private_key_string.strip()
48
+
49
+ try:
50
+ # Try to load directly as PEM format
51
+ if "-----BEGIN" in key_string:
52
+ private_key = serialization.load_pem_private_key(
53
+ data=key_string.encode("utf-8"),
54
+ password=None,
55
+ backend=default_backend(),
56
+ )
57
+ else:
58
+ # If it's pure Base64, first try PKCS#8 format
59
+ clean_base64 = "".join(key_string.split())
60
+
61
+ try:
62
+ # Attempt PKCS#8 format PEM wrapping
63
+ pkcs8_pem = (
64
+ f"-----BEGIN {'PRIVATE'} {'KEY'}-----\n"
65
+ f"{clean_base64}\n-----END {'PRIVATE'} {'KEY'}-----"
66
+ )
67
+ private_key = serialization.load_pem_private_key(
68
+ data=pkcs8_pem.encode("utf-8"),
69
+ password=None,
70
+ backend=default_backend(),
71
+ )
72
+ except Exception:
73
+ # If PKCS#8 fails, try PKCS#1 format PEM wrapping
74
+ pkcs1_pem = (
75
+ f"-----BEGIN RSA {'PRIVATE'} {'KEY'}-----\n"
76
+ f"{clean_base64}\n-----END RSA {'PRIVATE'} {'KEY'}-----"
77
+ )
78
+ private_key = serialization.load_pem_private_key(
79
+ data=pkcs1_pem.encode("utf-8"),
80
+ password=None,
81
+ backend=default_backend(),
82
+ )
83
+
84
+ # Force output in PKCS#1 format (Traditional OpenSSL format)
85
+ pkcs1_pem = private_key.private_bytes(
86
+ encoding=serialization.Encoding.PEM,
87
+ format=serialization.PrivateFormat.TraditionalOpenSSL,
88
+ encryption_algorithm=serialization.NoEncryption(),
89
+ )
90
+
91
+ return pkcs1_pem.decode("utf-8")
92
+
93
+ except Exception as e:
94
+ # If loading or conversion fails (e.g., the key is corrupted),
95
+ # raise an exception
96
+ raise ValueError(
97
+ f"Failed to parse or convert the provided private key. Please "
98
+ f"check if it is valid: {e}",
99
+ ) from e
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint:disable=unused-argument
3
+
4
+ import uuid
5
+ from typing import Any
6
+
7
+ from mcp.server.fastmcp import Context
8
+
9
+
10
+ def get_mcp_dash_request_id(
11
+ ctx: Context,
12
+ **kwargs: Any,
13
+ ) -> str:
14
+ """
15
+ Return the MCP dash request ID.
16
+ Args:
17
+ ctx: MCP CONTEXT
18
+ **kwargs (Any): Additional keyword arguments.
19
+
20
+ Returns:
21
+ dash request ID.
22
+ """
23
+ dashscope_request_id = None
24
+ if ctx and ctx.request_context:
25
+ http_request = ctx.request_context.request
26
+ if http_request:
27
+ headers = dict(http_request.headers.items())
28
+ if headers:
29
+ dashscope_request_id = headers.get("dashscope_request_id")
30
+
31
+ if dashscope_request_id and dashscope_request_id.strip():
32
+ dashscope_request_id = dashscope_request_id.strip()
33
+ else:
34
+ dashscope_request_id = str(uuid.uuid4())
35
+ return dashscope_request_id
@@ -1,2 +1,2 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "v0.2.0b1"
2
+ __version__ = "v1.0.0"