agentscope-runtime 0.2.0b2__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentscope_runtime/adapters/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/__init__.py +0 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/long_term_memory/_long_term_memory_adapter.py +258 -0
- agentscope_runtime/adapters/agentscope/memory/__init__.py +6 -0
- agentscope_runtime/adapters/agentscope/memory/_memory_adapter.py +152 -0
- agentscope_runtime/adapters/agentscope/message.py +535 -0
- agentscope_runtime/adapters/agentscope/stream.py +506 -0
- agentscope_runtime/adapters/agentscope/tool/__init__.py +9 -0
- agentscope_runtime/adapters/agentscope/tool/sandbox_tool.py +69 -0
- agentscope_runtime/adapters/agentscope/tool/tool.py +233 -0
- agentscope_runtime/adapters/autogen/__init__.py +0 -0
- agentscope_runtime/adapters/autogen/tool/__init__.py +7 -0
- agentscope_runtime/adapters/autogen/tool/tool.py +211 -0
- agentscope_runtime/adapters/text/__init__.py +0 -0
- agentscope_runtime/adapters/text/stream.py +29 -0
- agentscope_runtime/common/collections/redis_mapping.py +4 -1
- agentscope_runtime/common/container_clients/fc_client.py +855 -0
- agentscope_runtime/common/utils/__init__.py +0 -0
- agentscope_runtime/common/utils/lazy_loader.py +57 -0
- agentscope_runtime/engine/__init__.py +25 -18
- agentscope_runtime/engine/app/agent_app.py +161 -91
- agentscope_runtime/engine/app/base_app.py +4 -118
- agentscope_runtime/engine/constant.py +8 -0
- agentscope_runtime/engine/deployers/__init__.py +8 -0
- agentscope_runtime/engine/deployers/adapter/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_adapter_utils.py +0 -21
- agentscope_runtime/engine/deployers/adapter/a2a/a2a_protocol_adapter.py +28 -9
- agentscope_runtime/engine/deployers/adapter/responses/__init__.py +2 -0
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +5 -2
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +1 -1
- agentscope_runtime/engine/deployers/agentrun_deployer.py +2541 -0
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +1 -1
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +9 -21
- agentscope_runtime/engine/deployers/local_deployer.py +47 -74
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +216 -50
- agentscope_runtime/engine/deployers/utils/app_runner_utils.py +29 -0
- agentscope_runtime/engine/deployers/utils/detached_app.py +510 -0
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +1 -1
- agentscope_runtime/engine/deployers/utils/docker_image_utils/{runner_image_factory.py → image_factory.py} +121 -61
- agentscope_runtime/engine/deployers/utils/package.py +693 -0
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -5
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +301 -282
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +2 -4
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +23 -1
- agentscope_runtime/engine/deployers/utils/templates/app_main.py.j2 +84 -0
- agentscope_runtime/engine/deployers/utils/templates/runner_main.py.j2 +95 -0
- agentscope_runtime/engine/deployers/utils/{service_utils → templates}/standalone_main.py.j2 +0 -45
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +119 -18
- agentscope_runtime/engine/helpers/runner.py +40 -0
- agentscope_runtime/engine/runner.py +171 -130
- agentscope_runtime/engine/schemas/agent_schemas.py +114 -3
- agentscope_runtime/engine/schemas/modelstudio_llm.py +4 -2
- agentscope_runtime/engine/schemas/oai_llm.py +23 -23
- agentscope_runtime/engine/schemas/response_api.py +65 -0
- agentscope_runtime/engine/schemas/session.py +24 -0
- agentscope_runtime/engine/services/__init__.py +0 -9
- agentscope_runtime/engine/services/agent_state/__init__.py +16 -0
- agentscope_runtime/engine/services/agent_state/redis_state_service.py +113 -0
- agentscope_runtime/engine/services/agent_state/state_service.py +179 -0
- agentscope_runtime/engine/services/memory/__init__.py +24 -0
- agentscope_runtime/engine/services/{mem0_memory_service.py → memory/mem0_memory_service.py} +17 -13
- agentscope_runtime/engine/services/{memory_service.py → memory/memory_service.py} +28 -7
- agentscope_runtime/engine/services/{redis_memory_service.py → memory/redis_memory_service.py} +1 -1
- agentscope_runtime/engine/services/{reme_personal_memory_service.py → memory/reme_personal_memory_service.py} +9 -6
- agentscope_runtime/engine/services/{reme_task_memory_service.py → memory/reme_task_memory_service.py} +2 -2
- agentscope_runtime/engine/services/{tablestore_memory_service.py → memory/tablestore_memory_service.py} +12 -18
- agentscope_runtime/engine/services/sandbox/__init__.py +13 -0
- agentscope_runtime/engine/services/{sandbox_service.py → sandbox/sandbox_service.py} +86 -71
- agentscope_runtime/engine/services/session_history/__init__.py +23 -0
- agentscope_runtime/engine/services/{redis_session_history_service.py → session_history/redis_session_history_service.py} +3 -2
- agentscope_runtime/engine/services/{session_history_service.py → session_history/session_history_service.py} +44 -34
- agentscope_runtime/engine/services/{tablestore_session_history_service.py → session_history/tablestore_session_history_service.py} +14 -19
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +2 -2
- agentscope_runtime/engine/tracing/base.py +10 -9
- agentscope_runtime/engine/tracing/message_util.py +1 -1
- agentscope_runtime/engine/tracing/tracing_util.py +7 -2
- agentscope_runtime/engine/tracing/wrapper.py +49 -31
- agentscope_runtime/sandbox/__init__.py +10 -2
- agentscope_runtime/sandbox/box/agentbay/__init__.py +4 -0
- agentscope_runtime/sandbox/box/agentbay/agentbay_sandbox.py +559 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +12 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +115 -11
- agentscope_runtime/sandbox/box/cloud/__init__.py +4 -0
- agentscope_runtime/sandbox/box/cloud/cloud_sandbox.py +254 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +66 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +42 -0
- agentscope_runtime/sandbox/box/mobile/__init__.py +4 -0
- agentscope_runtime/sandbox/box/mobile/box/__init__.py +0 -0
- agentscope_runtime/sandbox/box/mobile/mobile_sandbox.py +216 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +2 -2
- agentscope_runtime/sandbox/client/http_client.py +1 -0
- agentscope_runtime/sandbox/enums.py +2 -0
- agentscope_runtime/sandbox/manager/sandbox_manager.py +15 -2
- agentscope_runtime/sandbox/manager/server/app.py +12 -0
- agentscope_runtime/sandbox/manager/server/config.py +19 -0
- agentscope_runtime/sandbox/model/manager_config.py +79 -2
- agentscope_runtime/sandbox/utils.py +0 -18
- agentscope_runtime/tools/RAGs/__init__.py +0 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag.py +377 -0
- agentscope_runtime/tools/RAGs/modelstudio_rag_lite.py +219 -0
- agentscope_runtime/tools/__init__.py +119 -0
- agentscope_runtime/tools/_constants.py +18 -0
- agentscope_runtime/tools/alipay/__init__.py +4 -0
- agentscope_runtime/tools/alipay/base.py +334 -0
- agentscope_runtime/tools/alipay/payment.py +835 -0
- agentscope_runtime/tools/alipay/subscribe.py +551 -0
- agentscope_runtime/tools/base.py +264 -0
- agentscope_runtime/tools/cli/__init__.py +0 -0
- agentscope_runtime/tools/cli/modelstudio_mcp_server.py +78 -0
- agentscope_runtime/tools/generations/__init__.py +75 -0
- agentscope_runtime/tools/generations/async_image_to_video.py +350 -0
- agentscope_runtime/tools/generations/async_image_to_video_wan25.py +366 -0
- agentscope_runtime/tools/generations/async_speech_to_video.py +422 -0
- agentscope_runtime/tools/generations/async_text_to_video.py +320 -0
- agentscope_runtime/tools/generations/async_text_to_video_wan25.py +334 -0
- agentscope_runtime/tools/generations/image_edit.py +208 -0
- agentscope_runtime/tools/generations/image_edit_wan25.py +193 -0
- agentscope_runtime/tools/generations/image_generation.py +202 -0
- agentscope_runtime/tools/generations/image_generation_wan25.py +201 -0
- agentscope_runtime/tools/generations/image_style_repaint.py +208 -0
- agentscope_runtime/tools/generations/image_to_video.py +233 -0
- agentscope_runtime/tools/generations/qwen_image_edit.py +205 -0
- agentscope_runtime/tools/generations/qwen_image_generation.py +214 -0
- agentscope_runtime/tools/generations/qwen_text_to_speech.py +154 -0
- agentscope_runtime/tools/generations/speech_to_text.py +260 -0
- agentscope_runtime/tools/generations/speech_to_video.py +314 -0
- agentscope_runtime/tools/generations/text_to_video.py +221 -0
- agentscope_runtime/tools/mcp_wrapper.py +215 -0
- agentscope_runtime/tools/realtime_clients/__init__.py +13 -0
- agentscope_runtime/tools/realtime_clients/asr_client.py +27 -0
- agentscope_runtime/tools/realtime_clients/azure_asr_client.py +195 -0
- agentscope_runtime/tools/realtime_clients/azure_tts_client.py +383 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_asr_client.py +151 -0
- agentscope_runtime/tools/realtime_clients/modelstudio_tts_client.py +199 -0
- agentscope_runtime/tools/realtime_clients/realtime_tool.py +55 -0
- agentscope_runtime/tools/realtime_clients/tts_client.py +33 -0
- agentscope_runtime/tools/searches/__init__.py +3 -0
- agentscope_runtime/tools/searches/modelstudio_search.py +877 -0
- agentscope_runtime/tools/searches/modelstudio_search_lite.py +310 -0
- agentscope_runtime/tools/utils/__init__.py +0 -0
- agentscope_runtime/tools/utils/api_key_util.py +45 -0
- agentscope_runtime/tools/utils/crypto_utils.py +99 -0
- agentscope_runtime/tools/utils/mcp_util.py +35 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/METADATA +240 -168
- agentscope_runtime-1.0.0.dist-info/RECORD +240 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/entry_points.txt +1 -0
- agentscope_runtime/engine/agents/__init__.py +0 -2
- agentscope_runtime/engine/agents/agentscope_agent.py +0 -488
- agentscope_runtime/engine/agents/agno_agent.py +0 -220
- agentscope_runtime/engine/agents/autogen_agent.py +0 -250
- agentscope_runtime/engine/agents/base_agent.py +0 -29
- agentscope_runtime/engine/agents/langgraph_agent.py +0 -59
- agentscope_runtime/engine/agents/utils.py +0 -53
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -1163
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/helpers/helper.py +0 -179
- agentscope_runtime/engine/schemas/context.py +0 -54
- agentscope_runtime/engine/services/context_manager.py +0 -164
- agentscope_runtime/engine/services/environment_manager.py +0 -50
- agentscope_runtime/engine/services/manager.py +0 -174
- agentscope_runtime/engine/services/rag_service.py +0 -195
- agentscope_runtime/engine/services/tablestore_rag_service.py +0 -143
- agentscope_runtime/sandbox/tools/__init__.py +0 -12
- agentscope_runtime/sandbox/tools/base/__init__.py +0 -8
- agentscope_runtime/sandbox/tools/base/tool.py +0 -52
- agentscope_runtime/sandbox/tools/browser/__init__.py +0 -57
- agentscope_runtime/sandbox/tools/browser/tool.py +0 -597
- agentscope_runtime/sandbox/tools/filesystem/__init__.py +0 -32
- agentscope_runtime/sandbox/tools/filesystem/tool.py +0 -319
- agentscope_runtime/sandbox/tools/function_tool.py +0 -321
- agentscope_runtime/sandbox/tools/gui/__init__.py +0 -7
- agentscope_runtime/sandbox/tools/gui/tool.py +0 -77
- agentscope_runtime/sandbox/tools/mcp_tool.py +0 -195
- agentscope_runtime/sandbox/tools/sandbox_tool.py +0 -104
- agentscope_runtime/sandbox/tools/tool.py +0 -238
- agentscope_runtime/sandbox/tools/utils.py +0 -68
- agentscope_runtime-0.2.0b2.dist-info/RECORD +0 -183
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.2.0b2.dist-info → agentscope_runtime-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.2.0b2.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
|