agentscope-runtime 0.1.5b1__py3-none-any.whl → 0.1.6__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/engine/agents/agentscope_agent.py +447 -0
- agentscope_runtime/engine/agents/agno_agent.py +19 -18
- agentscope_runtime/engine/agents/autogen_agent.py +13 -8
- agentscope_runtime/engine/agents/utils.py +53 -0
- agentscope_runtime/engine/deployers/__init__.py +0 -13
- agentscope_runtime/engine/deployers/local_deployer.py +501 -356
- agentscope_runtime/engine/helpers/helper.py +60 -41
- agentscope_runtime/engine/runner.py +11 -36
- agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
- agentscope_runtime/engine/services/sandbox_service.py +62 -70
- agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
- agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
- agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
- agentscope_runtime/sandbox/__init__.py +2 -0
- agentscope_runtime/sandbox/box/base/__init__.py +4 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
- agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
- agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
- agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
- agentscope_runtime/sandbox/box/sandbox.py +5 -2
- agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
- agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
- agentscope_runtime/sandbox/build.py +143 -58
- agentscope_runtime/sandbox/client/http_client.py +43 -49
- agentscope_runtime/sandbox/client/training_client.py +0 -1
- agentscope_runtime/sandbox/constant.py +24 -1
- agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
- agentscope_runtime/sandbox/custom/example.py +2 -2
- agentscope_runtime/sandbox/enums.py +1 -0
- agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
- agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
- agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
- agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
- agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
- agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
- agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
- agentscope_runtime/sandbox/manager/server/app.py +82 -14
- agentscope_runtime/sandbox/manager/server/config.py +50 -3
- agentscope_runtime/sandbox/model/container.py +6 -23
- agentscope_runtime/sandbox/model/manager_config.py +93 -5
- agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
- agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
- agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
- agentscope_runtime/sandbox/utils.py +124 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
- agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
- agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
- agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
- agentscope_runtime/engine/agents/llm_agent.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
- agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -143
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -626
- agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
- agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
- 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/deployers/utils/wheel_packager.py +0 -389
- agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
- agentscope_runtime/engine/llms/__init__.py +0 -3
- agentscope_runtime/engine/llms/base_llm.py +0 -60
- agentscope_runtime/engine/llms/qwen_llm.py +0 -47
- agentscope_runtime/engine/schemas/embedding.py +0 -37
- agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
- agentscope_runtime/engine/schemas/oai_llm.py +0 -538
- agentscope_runtime/engine/schemas/realtime.py +0 -254
- /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
- /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.1.5b1.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=redefined-outer-name
|
|
3
|
+
import asyncio
|
|
4
|
+
import copy
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import Any, Dict, List, Optional
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import tablestore
|
|
10
|
+
from langchain_community.embeddings import DashScopeEmbeddings
|
|
11
|
+
from langchain_core.embeddings import Embeddings
|
|
12
|
+
from tablestore import AsyncOTSClient as AsyncTablestoreClient
|
|
13
|
+
from tablestore import VectorMetricType
|
|
14
|
+
from tablestore_for_agent_memory.base.filter import Filters
|
|
15
|
+
from tablestore_for_agent_memory.knowledge.async_knowledge_store import (
|
|
16
|
+
AsyncKnowledgeStore,
|
|
17
|
+
)
|
|
18
|
+
except ImportError as e:
|
|
19
|
+
raise ImportError(
|
|
20
|
+
"aliyun_tablestore is not available. "
|
|
21
|
+
"Please run pip install agentscope-runtime[aliyun_tablestore_ext]",
|
|
22
|
+
) from e
|
|
23
|
+
|
|
24
|
+
from ..schemas.agent_schemas import Message, MessageType
|
|
25
|
+
from .memory_service import MemoryService
|
|
26
|
+
from .utils.tablestore_service_utils import (
|
|
27
|
+
convert_messages_to_tablestore_documents,
|
|
28
|
+
convert_tablestore_document_to_message,
|
|
29
|
+
get_message_metadata_names,
|
|
30
|
+
tablestore_log,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SearchStrategy(Enum):
|
|
35
|
+
FULL_TEXT = "full_text"
|
|
36
|
+
VECTOR = "vector"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TablestoreMemoryService(MemoryService):
|
|
40
|
+
"""
|
|
41
|
+
A Tablestore-based implementation of the memory service.
|
|
42
|
+
based on tablestore_for_agent_memory
|
|
43
|
+
(https://github.com/aliyun/
|
|
44
|
+
alibabacloud-tablestore-for-agent-memory/blob/main/python/docs/knowledge_store_tutorial.ipynb).
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
_SEARCH_INDEX_NAME = "agentscope_runtime_knowledge_search_index_name"
|
|
48
|
+
_DEFAULT_SESSION_ID = "default"
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
tablestore_client: AsyncTablestoreClient,
|
|
53
|
+
search_strategy: SearchStrategy = SearchStrategy.FULL_TEXT,
|
|
54
|
+
embedding_model: Optional[Embeddings] = DashScopeEmbeddings(),
|
|
55
|
+
vector_dimension: int = 1536,
|
|
56
|
+
table_name: Optional[str] = "agentscope_runtime_memory",
|
|
57
|
+
search_index_schema: Optional[List[tablestore.FieldSchema]] = (
|
|
58
|
+
tablestore.FieldSchema("user_id", tablestore.FieldType.KEYWORD),
|
|
59
|
+
tablestore.FieldSchema("session_id", tablestore.FieldType.KEYWORD),
|
|
60
|
+
),
|
|
61
|
+
text_field: Optional[str] = "text",
|
|
62
|
+
embedding_field: Optional[str] = "embedding",
|
|
63
|
+
vector_metric_type: VectorMetricType = VectorMetricType.VM_COSINE,
|
|
64
|
+
**kwargs: Any,
|
|
65
|
+
):
|
|
66
|
+
self._search_strategy = search_strategy
|
|
67
|
+
self._embedding_model = (
|
|
68
|
+
embedding_model # the parameter is None, don't store vector.
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
self._search_strategy == SearchStrategy.VECTOR
|
|
73
|
+
and self._embedding_model is None
|
|
74
|
+
):
|
|
75
|
+
raise ValueError(
|
|
76
|
+
"Embedding model is required when search strategy is VECTOR.",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
self._tablestore_client = tablestore_client
|
|
80
|
+
self._vector_dimension = vector_dimension
|
|
81
|
+
self._table_name = table_name
|
|
82
|
+
self._search_index_schema = (
|
|
83
|
+
list(search_index_schema)
|
|
84
|
+
if search_index_schema is not None
|
|
85
|
+
else None
|
|
86
|
+
)
|
|
87
|
+
self._text_field = text_field
|
|
88
|
+
self._embedding_field = embedding_field
|
|
89
|
+
self._vector_metric_type = vector_metric_type
|
|
90
|
+
self._knowledge_store: Optional[AsyncKnowledgeStore] = None
|
|
91
|
+
self._knowledge_store_init_parameter_kwargs = kwargs
|
|
92
|
+
|
|
93
|
+
async def _init_knowledge_store(self) -> None:
|
|
94
|
+
self._knowledge_store = AsyncKnowledgeStore(
|
|
95
|
+
tablestore_client=self._tablestore_client,
|
|
96
|
+
vector_dimension=self._vector_dimension,
|
|
97
|
+
enable_multi_tenant=False,
|
|
98
|
+
# enable multi tenant will make user be confused,
|
|
99
|
+
# we unify the usage of session id and user id,
|
|
100
|
+
# and allow users to configure the index themselves.
|
|
101
|
+
table_name=self._table_name,
|
|
102
|
+
search_index_name=TablestoreMemoryService._SEARCH_INDEX_NAME,
|
|
103
|
+
search_index_schema=copy.deepcopy(self._search_index_schema),
|
|
104
|
+
text_field=self._text_field,
|
|
105
|
+
embedding_field=self._embedding_field,
|
|
106
|
+
vector_metric_type=self._vector_metric_type,
|
|
107
|
+
**self._knowledge_store_init_parameter_kwargs,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
await self._knowledge_store.init_table()
|
|
111
|
+
|
|
112
|
+
async def start(self) -> None:
|
|
113
|
+
"""Start the tablestore service"""
|
|
114
|
+
if self._knowledge_store:
|
|
115
|
+
return
|
|
116
|
+
await self._init_knowledge_store()
|
|
117
|
+
|
|
118
|
+
async def stop(self) -> None:
|
|
119
|
+
"""Close the tablestore service"""
|
|
120
|
+
if self._knowledge_store is None:
|
|
121
|
+
return
|
|
122
|
+
knowledge_store = self._knowledge_store
|
|
123
|
+
self._knowledge_store = None
|
|
124
|
+
await knowledge_store.close()
|
|
125
|
+
|
|
126
|
+
async def health(self) -> bool:
|
|
127
|
+
"""Checks the health of the service."""
|
|
128
|
+
if self._knowledge_store is None:
|
|
129
|
+
tablestore_log("Tablestore memory service is not started.")
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
async for _ in await self._knowledge_store.get_all_documents():
|
|
134
|
+
return True
|
|
135
|
+
return True
|
|
136
|
+
except Exception as e:
|
|
137
|
+
tablestore_log(
|
|
138
|
+
f"Tablestore memory service "
|
|
139
|
+
f"cannot access Tablestore, error: {str(e)}.",
|
|
140
|
+
)
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
async def add_memory(
|
|
144
|
+
self,
|
|
145
|
+
user_id: str,
|
|
146
|
+
messages: list,
|
|
147
|
+
session_id: Optional[str] = None,
|
|
148
|
+
) -> None:
|
|
149
|
+
if not session_id:
|
|
150
|
+
session_id = TablestoreMemoryService._DEFAULT_SESSION_ID
|
|
151
|
+
|
|
152
|
+
if not messages:
|
|
153
|
+
return
|
|
154
|
+
|
|
155
|
+
tablestore_documents = convert_messages_to_tablestore_documents(
|
|
156
|
+
messages,
|
|
157
|
+
user_id,
|
|
158
|
+
session_id,
|
|
159
|
+
self._embedding_model,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
put_tasks = [
|
|
163
|
+
self._knowledge_store.put_document(tablestore_document)
|
|
164
|
+
for tablestore_document in tablestore_documents
|
|
165
|
+
]
|
|
166
|
+
await asyncio.gather(*put_tasks)
|
|
167
|
+
|
|
168
|
+
@staticmethod
|
|
169
|
+
async def get_query_text(message: Message) -> str:
|
|
170
|
+
if not message or message.type != MessageType.MESSAGE:
|
|
171
|
+
return ""
|
|
172
|
+
|
|
173
|
+
for content in message.content:
|
|
174
|
+
if content.type == "text":
|
|
175
|
+
return content.text
|
|
176
|
+
|
|
177
|
+
return ""
|
|
178
|
+
|
|
179
|
+
async def search_memory(
|
|
180
|
+
self,
|
|
181
|
+
user_id: str,
|
|
182
|
+
messages: list,
|
|
183
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
184
|
+
) -> list:
|
|
185
|
+
if (
|
|
186
|
+
not messages
|
|
187
|
+
or not isinstance(messages, list)
|
|
188
|
+
or len(messages) == 0
|
|
189
|
+
):
|
|
190
|
+
return []
|
|
191
|
+
|
|
192
|
+
query = await TablestoreMemoryService.get_query_text(messages[-1])
|
|
193
|
+
if not query:
|
|
194
|
+
return []
|
|
195
|
+
|
|
196
|
+
top_k = 100
|
|
197
|
+
if (
|
|
198
|
+
filters
|
|
199
|
+
and "top_k" in filters
|
|
200
|
+
and isinstance(filters["top_k"], int)
|
|
201
|
+
):
|
|
202
|
+
top_k = filters["top_k"]
|
|
203
|
+
|
|
204
|
+
if self._search_strategy == SearchStrategy.FULL_TEXT:
|
|
205
|
+
matched_messages = [
|
|
206
|
+
convert_tablestore_document_to_message(hit.document)
|
|
207
|
+
for hit in (
|
|
208
|
+
await self._knowledge_store.full_text_search(
|
|
209
|
+
query=query,
|
|
210
|
+
metadata_filter=Filters.eq("user_id", user_id),
|
|
211
|
+
limit=top_k,
|
|
212
|
+
meta_data_to_get=get_message_metadata_names(),
|
|
213
|
+
)
|
|
214
|
+
).hits
|
|
215
|
+
]
|
|
216
|
+
elif self._search_strategy == SearchStrategy.VECTOR:
|
|
217
|
+
matched_messages = [
|
|
218
|
+
convert_tablestore_document_to_message(hit.document)
|
|
219
|
+
for hit in (
|
|
220
|
+
await self._knowledge_store.vector_search(
|
|
221
|
+
query_vector=self._embedding_model.embed_query(query),
|
|
222
|
+
metadata_filter=Filters.eq("user_id", user_id),
|
|
223
|
+
top_k=top_k,
|
|
224
|
+
meta_data_to_get=get_message_metadata_names(),
|
|
225
|
+
)
|
|
226
|
+
).hits
|
|
227
|
+
]
|
|
228
|
+
else:
|
|
229
|
+
raise ValueError(
|
|
230
|
+
f"Unsupported search strategy: {self._search_strategy}",
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
return matched_messages
|
|
234
|
+
|
|
235
|
+
async def list_memory(
|
|
236
|
+
self,
|
|
237
|
+
user_id: str,
|
|
238
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
239
|
+
) -> list:
|
|
240
|
+
page_num = filters.get("page_num", 1) if filters else 1
|
|
241
|
+
page_size = filters.get("page_size", 10) if filters else 10
|
|
242
|
+
|
|
243
|
+
if page_num < 1 or page_size < 1:
|
|
244
|
+
raise ValueError("page_num and page_size must be greater than 0.")
|
|
245
|
+
|
|
246
|
+
next_token = None
|
|
247
|
+
for _ in range(page_num - 1):
|
|
248
|
+
next_token = (
|
|
249
|
+
await self._knowledge_store.search_documents(
|
|
250
|
+
metadata_filter=Filters.eq("user_id", user_id),
|
|
251
|
+
limit=page_size,
|
|
252
|
+
next_token=next_token,
|
|
253
|
+
)
|
|
254
|
+
).next_token
|
|
255
|
+
if not next_token:
|
|
256
|
+
tablestore_log(
|
|
257
|
+
"Page number exceeds the total number of pages, "
|
|
258
|
+
"return empty list.",
|
|
259
|
+
)
|
|
260
|
+
return []
|
|
261
|
+
|
|
262
|
+
messages = [
|
|
263
|
+
convert_tablestore_document_to_message(hit.document)
|
|
264
|
+
for hit in (
|
|
265
|
+
await self._knowledge_store.search_documents(
|
|
266
|
+
metadata_filter=Filters.eq("user_id", user_id),
|
|
267
|
+
limit=page_size,
|
|
268
|
+
next_token=next_token,
|
|
269
|
+
meta_data_to_get=get_message_metadata_names(),
|
|
270
|
+
)
|
|
271
|
+
).hits
|
|
272
|
+
]
|
|
273
|
+
|
|
274
|
+
return messages
|
|
275
|
+
|
|
276
|
+
async def delete_memory(
|
|
277
|
+
self,
|
|
278
|
+
user_id: str,
|
|
279
|
+
session_id: Optional[str] = None,
|
|
280
|
+
) -> None:
|
|
281
|
+
delete_tablestore_documents = [
|
|
282
|
+
hit.document
|
|
283
|
+
for hit in (
|
|
284
|
+
await self._knowledge_store.search_documents(
|
|
285
|
+
metadata_filter=(
|
|
286
|
+
Filters.eq("user_id", user_id)
|
|
287
|
+
if not session_id
|
|
288
|
+
else Filters.logical_and(
|
|
289
|
+
[
|
|
290
|
+
Filters.eq("user_id", user_id),
|
|
291
|
+
Filters.eq("session_id", session_id),
|
|
292
|
+
],
|
|
293
|
+
)
|
|
294
|
+
),
|
|
295
|
+
)
|
|
296
|
+
).hits
|
|
297
|
+
]
|
|
298
|
+
delete_tasks = [
|
|
299
|
+
self._knowledge_store.delete_document(
|
|
300
|
+
tablestore_document.document_id,
|
|
301
|
+
)
|
|
302
|
+
for tablestore_document in delete_tablestore_documents
|
|
303
|
+
]
|
|
304
|
+
await asyncio.gather(*delete_tasks)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=redefined-outer-name
|
|
3
|
+
import asyncio
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Any, List, Optional, Union
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from langchain_community.embeddings import DashScopeEmbeddings
|
|
9
|
+
from langchain_core.documents import Document
|
|
10
|
+
from langchain_core.embeddings import Embeddings
|
|
11
|
+
from tablestore import AsyncOTSClient as AsyncTablestoreClient
|
|
12
|
+
from tablestore import VectorMetricType
|
|
13
|
+
from tablestore_for_agent_memory.base.base_knowledge_store import (
|
|
14
|
+
Document as TablestoreDocument,
|
|
15
|
+
)
|
|
16
|
+
from tablestore_for_agent_memory.knowledge.async_knowledge_store import (
|
|
17
|
+
AsyncKnowledgeStore,
|
|
18
|
+
)
|
|
19
|
+
except ImportError as e:
|
|
20
|
+
raise ImportError(
|
|
21
|
+
"aliyun_tablestore is not available. "
|
|
22
|
+
"Please run pip install agentscope-runtime[aliyun_tablestore_ext]",
|
|
23
|
+
) from e
|
|
24
|
+
|
|
25
|
+
from .rag_service import RAGService
|
|
26
|
+
from .utils.tablestore_service_utils import tablestore_log
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TablestoreRAGService(RAGService):
|
|
30
|
+
"""
|
|
31
|
+
RAG Service using Tablestore(aliyun tablestore)
|
|
32
|
+
based on tablestore_for_agent_memory
|
|
33
|
+
(https://github.com/aliyun/
|
|
34
|
+
alibabacloud-tablestore-for-agent-memory/blob/main/python/docs/knowledge_store_tutorial.ipynb).
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
_SEARCH_INDEX_NAME = "agentscope_runtime_knowledge_search_index_name"
|
|
38
|
+
_DEFAULT_SESSION_ID = "default"
|
|
39
|
+
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
tablestore_client: AsyncTablestoreClient,
|
|
43
|
+
embedding_model: Optional[Embeddings] = None,
|
|
44
|
+
vector_dimension: int = 1536,
|
|
45
|
+
table_name: Optional[str] = "agentscope_runtime_rag",
|
|
46
|
+
text_field: Optional[str] = "text",
|
|
47
|
+
embedding_field: Optional[str] = "embedding",
|
|
48
|
+
vector_metric_type: VectorMetricType = VectorMetricType.VM_COSINE,
|
|
49
|
+
**kwargs: Any,
|
|
50
|
+
):
|
|
51
|
+
self._embedding_model = (
|
|
52
|
+
embedding_model if embedding_model else DashScopeEmbeddings()
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
self._tablestore_client = tablestore_client
|
|
56
|
+
self._vector_dimension = vector_dimension
|
|
57
|
+
self._table_name = table_name
|
|
58
|
+
self._text_field = text_field
|
|
59
|
+
self._embedding_field = embedding_field
|
|
60
|
+
self._vector_metric_type = vector_metric_type
|
|
61
|
+
self._knowledge_store: Optional[AsyncKnowledgeStore] = None
|
|
62
|
+
self._knowledge_store_init_parameter_kwargs = kwargs
|
|
63
|
+
|
|
64
|
+
async def _init_knowledge_store(self) -> None:
|
|
65
|
+
self._knowledge_store = AsyncKnowledgeStore(
|
|
66
|
+
tablestore_client=self._tablestore_client,
|
|
67
|
+
vector_dimension=self._vector_dimension,
|
|
68
|
+
enable_multi_tenant=False,
|
|
69
|
+
table_name=self._table_name,
|
|
70
|
+
search_index_name=TablestoreRAGService._SEARCH_INDEX_NAME,
|
|
71
|
+
text_field=self._text_field,
|
|
72
|
+
embedding_field=self._embedding_field,
|
|
73
|
+
vector_metric_type=self._vector_metric_type,
|
|
74
|
+
**self._knowledge_store_init_parameter_kwargs,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
await self._knowledge_store.init_table()
|
|
78
|
+
|
|
79
|
+
async def start(self) -> None:
|
|
80
|
+
"""Start the tablestore service"""
|
|
81
|
+
if self._knowledge_store:
|
|
82
|
+
return
|
|
83
|
+
await self._init_knowledge_store()
|
|
84
|
+
|
|
85
|
+
async def stop(self) -> None:
|
|
86
|
+
"""Close the tablestore service"""
|
|
87
|
+
if self._knowledge_store is None:
|
|
88
|
+
return
|
|
89
|
+
knowledge_store = self._knowledge_store
|
|
90
|
+
self._knowledge_store = None
|
|
91
|
+
await knowledge_store.close()
|
|
92
|
+
|
|
93
|
+
async def health(self) -> bool:
|
|
94
|
+
"""Checks the health of the service."""
|
|
95
|
+
if self._knowledge_store is None:
|
|
96
|
+
tablestore_log("Tablestore rag service is not started.")
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
async for _ in await self._knowledge_store.get_all_documents():
|
|
101
|
+
return True
|
|
102
|
+
return True
|
|
103
|
+
except Exception as e:
|
|
104
|
+
tablestore_log(
|
|
105
|
+
f"Tablestore rag service "
|
|
106
|
+
f"cannot access Tablestore, error: {str(e)}.",
|
|
107
|
+
)
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
async def add_docs(self, docs: Union[Document, List[Document]]):
|
|
111
|
+
if not isinstance(docs, List):
|
|
112
|
+
docs = [docs]
|
|
113
|
+
|
|
114
|
+
contents = [doc.page_content for doc in docs]
|
|
115
|
+
# Encode in batches to reduce time consumption.
|
|
116
|
+
embeddings = self._embedding_model.embed_documents(contents)
|
|
117
|
+
|
|
118
|
+
put_tasks = [
|
|
119
|
+
# The conversion logic here is simple,
|
|
120
|
+
# so no separate conversion function is defined.
|
|
121
|
+
self._knowledge_store.put_document(
|
|
122
|
+
document=TablestoreDocument(
|
|
123
|
+
document_id=f"document_{uuid.uuid4()}",
|
|
124
|
+
text=doc.page_content,
|
|
125
|
+
embedding=embedding,
|
|
126
|
+
metadata=doc.metadata,
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
for doc, embedding in zip(docs, embeddings)
|
|
130
|
+
]
|
|
131
|
+
await asyncio.gather(*put_tasks)
|
|
132
|
+
|
|
133
|
+
async def retrieve(self, query: str, k: int = 1) -> list[str]:
|
|
134
|
+
matched_text = [
|
|
135
|
+
hit.document.text
|
|
136
|
+
for hit in (
|
|
137
|
+
await self._knowledge_store.vector_search(
|
|
138
|
+
query_vector=self._embedding_model.embed_query(query),
|
|
139
|
+
top_k=k,
|
|
140
|
+
)
|
|
141
|
+
).hits
|
|
142
|
+
]
|
|
143
|
+
return matched_text
|