veadk-python 0.2.27__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 (218) hide show
  1. veadk/__init__.py +37 -0
  2. veadk/a2a/__init__.py +13 -0
  3. veadk/a2a/agent_card.py +45 -0
  4. veadk/a2a/remote_ve_agent.py +390 -0
  5. veadk/a2a/utils/__init__.py +13 -0
  6. veadk/a2a/utils/agent_to_a2a.py +170 -0
  7. veadk/a2a/ve_a2a_server.py +93 -0
  8. veadk/a2a/ve_agent_executor.py +78 -0
  9. veadk/a2a/ve_middlewares.py +313 -0
  10. veadk/a2a/ve_task_store.py +37 -0
  11. veadk/agent.py +402 -0
  12. veadk/agent_builder.py +93 -0
  13. veadk/agents/loop_agent.py +68 -0
  14. veadk/agents/parallel_agent.py +72 -0
  15. veadk/agents/sequential_agent.py +64 -0
  16. veadk/auth/__init__.py +13 -0
  17. veadk/auth/base_auth.py +22 -0
  18. veadk/auth/ve_credential_service.py +203 -0
  19. veadk/auth/veauth/__init__.py +13 -0
  20. veadk/auth/veauth/apmplus_veauth.py +58 -0
  21. veadk/auth/veauth/ark_veauth.py +75 -0
  22. veadk/auth/veauth/base_veauth.py +50 -0
  23. veadk/auth/veauth/cozeloop_veauth.py +13 -0
  24. veadk/auth/veauth/opensearch_veauth.py +75 -0
  25. veadk/auth/veauth/postgresql_veauth.py +75 -0
  26. veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
  27. veadk/auth/veauth/speech_veauth.py +54 -0
  28. veadk/auth/veauth/utils.py +69 -0
  29. veadk/auth/veauth/vesearch_veauth.py +62 -0
  30. veadk/auth/veauth/viking_mem0_veauth.py +91 -0
  31. veadk/cli/__init__.py +13 -0
  32. veadk/cli/cli.py +58 -0
  33. veadk/cli/cli_clean.py +87 -0
  34. veadk/cli/cli_create.py +163 -0
  35. veadk/cli/cli_deploy.py +233 -0
  36. veadk/cli/cli_eval.py +215 -0
  37. veadk/cli/cli_init.py +214 -0
  38. veadk/cli/cli_kb.py +110 -0
  39. veadk/cli/cli_pipeline.py +285 -0
  40. veadk/cli/cli_prompt.py +86 -0
  41. veadk/cli/cli_update.py +106 -0
  42. veadk/cli/cli_uploadevalset.py +139 -0
  43. veadk/cli/cli_web.py +143 -0
  44. veadk/cloud/__init__.py +13 -0
  45. veadk/cloud/cloud_agent_engine.py +485 -0
  46. veadk/cloud/cloud_app.py +475 -0
  47. veadk/config.py +115 -0
  48. veadk/configs/__init__.py +13 -0
  49. veadk/configs/auth_configs.py +133 -0
  50. veadk/configs/database_configs.py +132 -0
  51. veadk/configs/model_configs.py +78 -0
  52. veadk/configs/tool_configs.py +54 -0
  53. veadk/configs/tracing_configs.py +110 -0
  54. veadk/consts.py +74 -0
  55. veadk/evaluation/__init__.py +17 -0
  56. veadk/evaluation/adk_evaluator/__init__.py +17 -0
  57. veadk/evaluation/adk_evaluator/adk_evaluator.py +302 -0
  58. veadk/evaluation/base_evaluator.py +642 -0
  59. veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
  60. veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +339 -0
  61. veadk/evaluation/eval_set_file_loader.py +48 -0
  62. veadk/evaluation/eval_set_recorder.py +146 -0
  63. veadk/evaluation/types.py +65 -0
  64. veadk/evaluation/utils/prometheus.py +196 -0
  65. veadk/integrations/__init__.py +13 -0
  66. veadk/integrations/ve_apig/__init__.py +13 -0
  67. veadk/integrations/ve_apig/ve_apig.py +349 -0
  68. veadk/integrations/ve_apig/ve_apig_utils.py +332 -0
  69. veadk/integrations/ve_code_pipeline/__init__.py +13 -0
  70. veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
  71. veadk/integrations/ve_cozeloop/__init__.py +13 -0
  72. veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
  73. veadk/integrations/ve_cr/__init__.py +13 -0
  74. veadk/integrations/ve_cr/ve_cr.py +220 -0
  75. veadk/integrations/ve_faas/__init__.py +13 -0
  76. veadk/integrations/ve_faas/template/cookiecutter.json +15 -0
  77. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  78. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  79. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/config.yaml.example +6 -0
  80. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +106 -0
  81. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/__init__.py +13 -0
  82. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +25 -0
  83. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +202 -0
  84. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +3 -0
  85. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +49 -0
  86. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/__init__.py +14 -0
  87. veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{ cookiecutter.app_name }}/agent.py +27 -0
  88. veadk/integrations/ve_faas/ve_faas.py +754 -0
  89. veadk/integrations/ve_faas/ve_faas_utils.py +408 -0
  90. veadk/integrations/ve_faas/web_template/cookiecutter.json +20 -0
  91. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/__init__.py +13 -0
  92. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/clean.py +23 -0
  93. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/config.yaml.example +2 -0
  94. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/deploy.py +44 -0
  95. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/Dockerfile +23 -0
  96. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/app.py +123 -0
  97. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/init_db.py +46 -0
  98. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/models.py +36 -0
  99. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/requirements.txt +4 -0
  100. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/run.sh +21 -0
  101. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/css/style.css +368 -0
  102. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/static/js/admin.js +0 -0
  103. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/dashboard.html +21 -0
  104. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/edit_post.html +24 -0
  105. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/login.html +21 -0
  106. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/admin/posts.html +53 -0
  107. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/base.html +45 -0
  108. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/index.html +29 -0
  109. veadk/integrations/ve_faas/web_template/{{cookiecutter.local_dir_name}}/src/templates/post.html +14 -0
  110. veadk/integrations/ve_identity/__init__.py +110 -0
  111. veadk/integrations/ve_identity/auth_config.py +261 -0
  112. veadk/integrations/ve_identity/auth_mixins.py +650 -0
  113. veadk/integrations/ve_identity/auth_processor.py +385 -0
  114. veadk/integrations/ve_identity/function_tool.py +158 -0
  115. veadk/integrations/ve_identity/identity_client.py +864 -0
  116. veadk/integrations/ve_identity/mcp_tool.py +181 -0
  117. veadk/integrations/ve_identity/mcp_toolset.py +431 -0
  118. veadk/integrations/ve_identity/models.py +228 -0
  119. veadk/integrations/ve_identity/token_manager.py +188 -0
  120. veadk/integrations/ve_identity/utils.py +151 -0
  121. veadk/integrations/ve_prompt_pilot/__init__.py +13 -0
  122. veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +85 -0
  123. veadk/integrations/ve_tls/__init__.py +13 -0
  124. veadk/integrations/ve_tls/utils.py +116 -0
  125. veadk/integrations/ve_tls/ve_tls.py +212 -0
  126. veadk/integrations/ve_tos/ve_tos.py +710 -0
  127. veadk/integrations/ve_viking_db_memory/__init__.py +13 -0
  128. veadk/integrations/ve_viking_db_memory/ve_viking_db_memory.py +308 -0
  129. veadk/knowledgebase/__init__.py +17 -0
  130. veadk/knowledgebase/backends/__init__.py +13 -0
  131. veadk/knowledgebase/backends/base_backend.py +72 -0
  132. veadk/knowledgebase/backends/in_memory_backend.py +91 -0
  133. veadk/knowledgebase/backends/opensearch_backend.py +162 -0
  134. veadk/knowledgebase/backends/redis_backend.py +172 -0
  135. veadk/knowledgebase/backends/utils.py +92 -0
  136. veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +608 -0
  137. veadk/knowledgebase/entry.py +25 -0
  138. veadk/knowledgebase/knowledgebase.py +307 -0
  139. veadk/memory/__init__.py +35 -0
  140. veadk/memory/long_term_memory.py +365 -0
  141. veadk/memory/long_term_memory_backends/__init__.py +13 -0
  142. veadk/memory/long_term_memory_backends/base_backend.py +35 -0
  143. veadk/memory/long_term_memory_backends/in_memory_backend.py +67 -0
  144. veadk/memory/long_term_memory_backends/mem0_backend.py +155 -0
  145. veadk/memory/long_term_memory_backends/opensearch_backend.py +124 -0
  146. veadk/memory/long_term_memory_backends/redis_backend.py +140 -0
  147. veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +189 -0
  148. veadk/memory/short_term_memory.py +252 -0
  149. veadk/memory/short_term_memory_backends/__init__.py +13 -0
  150. veadk/memory/short_term_memory_backends/base_backend.py +31 -0
  151. veadk/memory/short_term_memory_backends/mysql_backend.py +49 -0
  152. veadk/memory/short_term_memory_backends/postgresql_backend.py +49 -0
  153. veadk/memory/short_term_memory_backends/sqlite_backend.py +55 -0
  154. veadk/memory/short_term_memory_processor.py +100 -0
  155. veadk/processors/__init__.py +26 -0
  156. veadk/processors/base_run_processor.py +120 -0
  157. veadk/prompts/__init__.py +13 -0
  158. veadk/prompts/agent_default_prompt.py +30 -0
  159. veadk/prompts/prompt_evaluator.py +20 -0
  160. veadk/prompts/prompt_memory_processor.py +55 -0
  161. veadk/prompts/prompt_optimization.py +150 -0
  162. veadk/runner.py +732 -0
  163. veadk/tools/__init__.py +13 -0
  164. veadk/tools/builtin_tools/__init__.py +13 -0
  165. veadk/tools/builtin_tools/agent_authorization.py +94 -0
  166. veadk/tools/builtin_tools/generate_image.py +23 -0
  167. veadk/tools/builtin_tools/image_edit.py +300 -0
  168. veadk/tools/builtin_tools/image_generate.py +446 -0
  169. veadk/tools/builtin_tools/lark.py +67 -0
  170. veadk/tools/builtin_tools/las.py +24 -0
  171. veadk/tools/builtin_tools/link_reader.py +66 -0
  172. veadk/tools/builtin_tools/llm_shield.py +381 -0
  173. veadk/tools/builtin_tools/load_knowledgebase.py +97 -0
  174. veadk/tools/builtin_tools/mcp_router.py +29 -0
  175. veadk/tools/builtin_tools/run_code.py +113 -0
  176. veadk/tools/builtin_tools/tts.py +253 -0
  177. veadk/tools/builtin_tools/vesearch.py +49 -0
  178. veadk/tools/builtin_tools/video_generate.py +363 -0
  179. veadk/tools/builtin_tools/web_scraper.py +76 -0
  180. veadk/tools/builtin_tools/web_search.py +83 -0
  181. veadk/tools/demo_tools.py +58 -0
  182. veadk/tools/load_knowledgebase_tool.py +149 -0
  183. veadk/tools/sandbox/__init__.py +13 -0
  184. veadk/tools/sandbox/browser_sandbox.py +37 -0
  185. veadk/tools/sandbox/code_sandbox.py +40 -0
  186. veadk/tools/sandbox/computer_sandbox.py +34 -0
  187. veadk/tracing/__init__.py +13 -0
  188. veadk/tracing/base_tracer.py +58 -0
  189. veadk/tracing/telemetry/__init__.py +13 -0
  190. veadk/tracing/telemetry/attributes/attributes.py +29 -0
  191. veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +180 -0
  192. veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +858 -0
  193. veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +152 -0
  194. veadk/tracing/telemetry/attributes/extractors/types.py +164 -0
  195. veadk/tracing/telemetry/exporters/__init__.py +13 -0
  196. veadk/tracing/telemetry/exporters/apmplus_exporter.py +558 -0
  197. veadk/tracing/telemetry/exporters/base_exporter.py +39 -0
  198. veadk/tracing/telemetry/exporters/cozeloop_exporter.py +129 -0
  199. veadk/tracing/telemetry/exporters/inmemory_exporter.py +248 -0
  200. veadk/tracing/telemetry/exporters/tls_exporter.py +139 -0
  201. veadk/tracing/telemetry/opentelemetry_tracer.py +320 -0
  202. veadk/tracing/telemetry/telemetry.py +411 -0
  203. veadk/types.py +47 -0
  204. veadk/utils/__init__.py +13 -0
  205. veadk/utils/audio_manager.py +95 -0
  206. veadk/utils/auth.py +294 -0
  207. veadk/utils/logger.py +59 -0
  208. veadk/utils/mcp_utils.py +44 -0
  209. veadk/utils/misc.py +184 -0
  210. veadk/utils/patches.py +101 -0
  211. veadk/utils/volcengine_sign.py +205 -0
  212. veadk/version.py +15 -0
  213. veadk_python-0.2.27.dist-info/METADATA +373 -0
  214. veadk_python-0.2.27.dist-info/RECORD +218 -0
  215. veadk_python-0.2.27.dist-info/WHEEL +5 -0
  216. veadk_python-0.2.27.dist-info/entry_points.txt +2 -0
  217. veadk_python-0.2.27.dist-info/licenses/LICENSE +201 -0
  218. veadk_python-0.2.27.dist-info/top_level.txt +1 -0
@@ -0,0 +1,13 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABC, abstractmethod
16
+
17
+ from pydantic import BaseModel
18
+
19
+
20
+ class BaseLongTermMemoryBackend(ABC, BaseModel):
21
+ index: str
22
+
23
+ @abstractmethod
24
+ def precheck_index_naming(self):
25
+ """Check the index name is valid or not"""
26
+
27
+ @abstractmethod
28
+ def save_memory(self, user_id: str, event_strings: list[str], **kwargs) -> bool:
29
+ """Save memory to long term memory backend"""
30
+
31
+ @abstractmethod
32
+ def search_memory(
33
+ self, user_id: str, query: str, top_k: int, **kwargs
34
+ ) -> list[str]:
35
+ """Retrieve memory from long term memory backend"""
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from llama_index.core import Document, VectorStoreIndex
16
+ from llama_index.core.schema import BaseNode
17
+ from llama_index.embeddings.openai_like import OpenAILikeEmbedding
18
+ from pydantic import Field
19
+ from typing_extensions import Any, override
20
+
21
+ from veadk.configs.model_configs import EmbeddingModelConfig
22
+ from veadk.knowledgebase.backends.utils import get_llama_index_splitter
23
+ from veadk.memory.long_term_memory_backends.base_backend import (
24
+ BaseLongTermMemoryBackend,
25
+ )
26
+
27
+
28
+ class InMemoryLTMBackend(BaseLongTermMemoryBackend):
29
+ embedding_config: EmbeddingModelConfig = Field(default_factory=EmbeddingModelConfig)
30
+ """Embedding model configs"""
31
+
32
+ def model_post_init(self, __context: Any) -> None:
33
+ self._embed_model = OpenAILikeEmbedding(
34
+ model_name=self.embedding_config.name,
35
+ api_key=self.embedding_config.api_key,
36
+ api_base=self.embedding_config.api_base,
37
+ )
38
+ self._vector_index = VectorStoreIndex([], embed_model=self._embed_model)
39
+
40
+ def precheck_index_naming(self):
41
+ # no checking
42
+ pass
43
+
44
+ @override
45
+ def save_memory(self, user_id: str, event_strings: list[str], **kwargs) -> bool:
46
+ for event_string in event_strings:
47
+ document = Document(text=event_string)
48
+ nodes = self._split_documents([document])
49
+ self._vector_index.insert_nodes(nodes)
50
+ return True
51
+
52
+ @override
53
+ def search_memory(
54
+ self, user_id: str, query: str, top_k: int, **kwargs
55
+ ) -> list[str]:
56
+ _retriever = self._vector_index.as_retriever(similarity_top_k=top_k)
57
+ retrieved_nodes = _retriever.retrieve(query)
58
+ return [node.text for node in retrieved_nodes]
59
+
60
+ def _split_documents(self, documents: list[Document]) -> list[BaseNode]:
61
+ """Split document into chunks"""
62
+ nodes = []
63
+ for document in documents:
64
+ splitter = get_llama_index_splitter(document.metadata.get("file_path", ""))
65
+ _nodes = splitter.get_nodes_from_documents([document])
66
+ nodes.extend(_nodes)
67
+ return nodes
@@ -0,0 +1,155 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import Any
16
+
17
+ from pydantic import Field
18
+ from typing_extensions import override
19
+
20
+ from veadk.auth.veauth.viking_mem0_veauth import get_viking_mem0_token
21
+ from veadk.configs.database_configs import Mem0Config
22
+ from veadk.memory.long_term_memory_backends.base_backend import (
23
+ BaseLongTermMemoryBackend,
24
+ )
25
+ from veadk.utils.logger import get_logger
26
+
27
+ logger = get_logger(__name__)
28
+
29
+ try:
30
+ from mem0 import MemoryClient
31
+
32
+ except ImportError:
33
+ logger.error(
34
+ "Failed to import mem0 or dotenv. Please install them with 'pip install mem0 '"
35
+ )
36
+ raise ImportError("Required packages not installed: mem0")
37
+
38
+
39
+ class Mem0LTMBackend(BaseLongTermMemoryBackend):
40
+ """Mem0 long term memory backend implementation"""
41
+
42
+ mem0_config: Mem0Config = Field(default_factory=Mem0Config)
43
+
44
+ def model_post_init(self, __context: Any) -> None:
45
+ """Initialize Mem0 client"""
46
+
47
+ if not self.mem0_config.api_key:
48
+ if not self.mem0_config.api_key_id and not self.mem0_config.project_id:
49
+ raise ValueError(
50
+ "API Key not set, auto fetching api key needs `api_key_id` or `project_id`"
51
+ )
52
+ self.mem0_config.api_key = get_viking_mem0_token(
53
+ api_key_id=self.mem0_config.api_key_id,
54
+ memory_project_id=self.mem0_config.project_id,
55
+ )
56
+
57
+ try:
58
+ self._mem0_client = MemoryClient(
59
+ host=self.mem0_config.base_url, # mem0 endpoint
60
+ api_key=self.mem0_config.api_key, # mem0 API key
61
+ )
62
+ logger.info(
63
+ f"Initialized Mem0 client for host: {self.mem0_config.base_url}"
64
+ )
65
+ logger.info(f"Initialized Mem0 client for index: {self.index}")
66
+ except Exception as e:
67
+ logger.error(
68
+ f"Failed to initialize Mem0 client for host {self.mem0_config.base_url} : {str(e)}"
69
+ )
70
+ raise
71
+
72
+ def precheck_index_naming(self):
73
+ """Check if the index name is valid
74
+ For Mem0, there are no specific naming constraints
75
+ """
76
+ pass
77
+
78
+ @override
79
+ def save_memory(
80
+ self, event_strings: list[str], user_id: str = "default_user", **kwargs
81
+ ) -> bool:
82
+ """Save memory to Mem0
83
+
84
+ Args:
85
+ event_strings: List of event strings to save
86
+ **kwargs: Additional parameters, including 'user_id' for Mem0
87
+
88
+ Returns:
89
+ bool: True if saved successfully, False otherwise
90
+ """
91
+ try:
92
+ logger.info(
93
+ f"Saving {len(event_strings)} events to Mem0 for user: {user_id}"
94
+ )
95
+
96
+ for event_string in event_strings:
97
+ # Save event string to Mem0
98
+ result = self._mem0_client.add(
99
+ [{"role": "user", "content": event_string}],
100
+ user_id=user_id,
101
+ output_format="v1.1",
102
+ async_mode=True,
103
+ )
104
+ logger.debug(f"Saved memory result: {result}")
105
+
106
+ logger.info(f"Successfully saved {len(event_strings)} events to Mem0")
107
+ return True
108
+ except Exception as e:
109
+ logger.error(f"Failed to save memory to Mem0: {str(e)}")
110
+ return False
111
+
112
+ @override
113
+ def search_memory(
114
+ self, query: str, top_k: int, user_id: str = "default_user", **kwargs
115
+ ) -> list[str]:
116
+ """Search memory from Mem0
117
+
118
+ Args:
119
+ query: Search query
120
+ top_k: Number of results to return
121
+ **kwargs: Additional parameters, including 'user_id' for Mem0
122
+
123
+ Returns:
124
+ list[str]: List of memory strings
125
+ """
126
+
127
+ try:
128
+ logger.info(
129
+ f"Searching Mem0 for query: {query}, user: {user_id}, top_k: {top_k}"
130
+ )
131
+
132
+ memories = self._mem0_client.search(
133
+ query, user_id=user_id, output_format="v1.1", top_k=top_k
134
+ )
135
+
136
+ logger.debug(f"return relevant memories: {memories}")
137
+
138
+ memory_list = []
139
+ # 如果 memories 是列表,直接返回
140
+ if isinstance(memories, list):
141
+ for mem in memories:
142
+ if "memory" in mem:
143
+ memory_list.append(mem["memory"])
144
+ return memory_list
145
+
146
+ if memories.get("results", []):
147
+ for mem in memories["results"]:
148
+ if "memory" in mem:
149
+ memory_list.append(mem["memory"])
150
+
151
+ logger.info(f"Found {len(memory_list)} memories matching query: {query}")
152
+ return memory_list
153
+ except Exception as e:
154
+ logger.error(f"Failed to search memory from Mem0: {str(e)}")
155
+ return []
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import re
16
+
17
+ from llama_index.core import Document, VectorStoreIndex
18
+ from llama_index.core.schema import BaseNode
19
+ from llama_index.embeddings.openai_like import OpenAILikeEmbedding
20
+ from pydantic import Field
21
+ from typing_extensions import Any, override
22
+
23
+ import veadk.config # noqa E401
24
+ from veadk.configs.database_configs import OpensearchConfig
25
+ from veadk.configs.model_configs import EmbeddingModelConfig, NormalEmbeddingModelConfig
26
+ from veadk.knowledgebase.backends.utils import get_llama_index_splitter
27
+ from veadk.memory.long_term_memory_backends.base_backend import (
28
+ BaseLongTermMemoryBackend,
29
+ )
30
+ from veadk.utils.logger import get_logger
31
+
32
+ try:
33
+ from llama_index.vector_stores.opensearch import (
34
+ OpensearchVectorClient,
35
+ OpensearchVectorStore,
36
+ )
37
+ except ImportError:
38
+ raise ImportError(
39
+ "Please install VeADK extensions\npip install veadk-python[extensions]"
40
+ )
41
+
42
+ logger = get_logger(__name__)
43
+
44
+
45
+ class OpensearchLTMBackend(BaseLongTermMemoryBackend):
46
+ opensearch_config: OpensearchConfig = Field(default_factory=OpensearchConfig)
47
+ """Opensearch client configs"""
48
+
49
+ embedding_config: EmbeddingModelConfig | NormalEmbeddingModelConfig = Field(
50
+ default_factory=EmbeddingModelConfig
51
+ )
52
+ """Embedding model configs"""
53
+
54
+ def model_post_init(self, __context: Any) -> None:
55
+ self._embed_model = OpenAILikeEmbedding(
56
+ model_name=self.embedding_config.name,
57
+ api_key=self.embedding_config.api_key,
58
+ api_base=self.embedding_config.api_base,
59
+ )
60
+
61
+ def precheck_index_naming(self, index: str):
62
+ if not (
63
+ isinstance(index, str)
64
+ and not index.startswith(("_", "-"))
65
+ and index.islower()
66
+ and re.match(r"^[a-z0-9_\-.]+$", index)
67
+ ):
68
+ raise ValueError(
69
+ f"The index name {index} does not conform to the naming rules of OpenSearch"
70
+ )
71
+
72
+ def _create_vector_index(self, index: str) -> VectorStoreIndex:
73
+ logger.info(f"Create OpenSearch vector index with index={index}")
74
+
75
+ self.precheck_index_naming(index)
76
+
77
+ opensearch_client = OpensearchVectorClient(
78
+ endpoint=self.opensearch_config.host,
79
+ port=self.opensearch_config.port,
80
+ http_auth=(
81
+ self.opensearch_config.username,
82
+ self.opensearch_config.password,
83
+ ),
84
+ use_ssl=True,
85
+ verify_certs=False,
86
+ dim=self.embedding_config.dim,
87
+ index=index,
88
+ )
89
+ vector_store = OpensearchVectorStore(client=opensearch_client)
90
+ return VectorStoreIndex.from_vector_store(
91
+ vector_store=vector_store, embed_model=self._embed_model
92
+ )
93
+
94
+ @override
95
+ def save_memory(self, user_id: str, event_strings: list[str], **kwargs) -> bool:
96
+ index = f"{self.index}_{user_id}"
97
+ vector_index = self._create_vector_index(index)
98
+
99
+ for event_string in event_strings:
100
+ document = Document(text=event_string)
101
+ nodes = self._split_documents([document])
102
+ vector_index.insert_nodes(nodes)
103
+ return True
104
+
105
+ @override
106
+ def search_memory(
107
+ self, user_id: str, query: str, top_k: int, **kwargs
108
+ ) -> list[str]:
109
+ index = f"{self.index}_{user_id}"
110
+
111
+ vector_index = self._create_vector_index(index)
112
+
113
+ _retriever = vector_index.as_retriever(similarity_top_k=top_k)
114
+ retrieved_nodes = _retriever.retrieve(query)
115
+ return [node.text for node in retrieved_nodes]
116
+
117
+ def _split_documents(self, documents: list[Document]) -> list[BaseNode]:
118
+ """Split document into chunks"""
119
+ nodes = []
120
+ for document in documents:
121
+ splitter = get_llama_index_splitter(document.metadata.get("file_path", ""))
122
+ _nodes = splitter.get_nodes_from_documents([document])
123
+ nodes.extend(_nodes)
124
+ return nodes
@@ -0,0 +1,140 @@
1
+ # Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from llama_index.core import Document, VectorStoreIndex
16
+ from llama_index.core.schema import BaseNode
17
+ from llama_index.embeddings.openai_like import OpenAILikeEmbedding
18
+ from pydantic import Field
19
+ from typing_extensions import Any, override
20
+
21
+ import veadk.config # noqa E401
22
+ from veadk.configs.database_configs import RedisConfig
23
+ from veadk.configs.model_configs import EmbeddingModelConfig, NormalEmbeddingModelConfig
24
+ from veadk.knowledgebase.backends.utils import get_llama_index_splitter
25
+ from veadk.memory.long_term_memory_backends.base_backend import (
26
+ BaseLongTermMemoryBackend,
27
+ )
28
+ from veadk.utils.logger import get_logger
29
+
30
+ try:
31
+ from llama_index.vector_stores.redis import RedisVectorStore
32
+ from redis import Redis
33
+ from redisvl.schema import IndexSchema
34
+
35
+ except ImportError:
36
+ raise ImportError(
37
+ "Please install VeADK extensions\npip install veadk-python[extensions]"
38
+ )
39
+
40
+
41
+ logger = get_logger(__name__)
42
+
43
+
44
+ class RedisLTMBackend(BaseLongTermMemoryBackend):
45
+ redis_config: RedisConfig = Field(default_factory=RedisConfig)
46
+ """Redis client configs"""
47
+
48
+ embedding_config: EmbeddingModelConfig | NormalEmbeddingModelConfig = Field(
49
+ default_factory=EmbeddingModelConfig
50
+ )
51
+ """Embedding model configs"""
52
+
53
+ def model_post_init(self, __context: Any) -> None:
54
+ self._embed_model = OpenAILikeEmbedding(
55
+ model_name=self.embedding_config.name,
56
+ api_key=self.embedding_config.api_key,
57
+ api_base=self.embedding_config.api_base,
58
+ )
59
+
60
+ def precheck_index_naming(self, index: str):
61
+ # no checking
62
+ pass
63
+
64
+ def _create_vector_index(self, index: str) -> VectorStoreIndex:
65
+ logger.info(f"Create Redis vector index with index={index}")
66
+
67
+ self.precheck_index_naming(index)
68
+
69
+ # We will use `from_url` to init Redis client once the
70
+ # AK/SK -> STS token is ready.
71
+ # self._redis_client = Redis.from_url(url=...)
72
+ redis_client = Redis(
73
+ host=self.redis_config.host,
74
+ port=self.redis_config.port,
75
+ db=self.redis_config.db,
76
+ password=self.redis_config.password,
77
+ )
78
+
79
+ # Create an index for each user
80
+ # Should be Optimized in the future
81
+ schema = IndexSchema.from_dict(
82
+ {
83
+ "index": {"name": index, "prefix": index, "key_separator": "_"},
84
+ "fields": [
85
+ {"name": "id", "type": "tag", "attrs": {"sortable": False}},
86
+ {"name": "doc_id", "type": "tag", "attrs": {"sortable": False}},
87
+ {"name": "text", "type": "text", "attrs": {"weight": 1.0}},
88
+ {
89
+ "name": "vector",
90
+ "type": "vector",
91
+ "attrs": {
92
+ "dims": self.embedding_config.dim,
93
+ "algorithm": "flat",
94
+ "distance_metric": "cosine",
95
+ },
96
+ },
97
+ ],
98
+ }
99
+ )
100
+ vector_store = RedisVectorStore(schema=schema, redis_client=redis_client)
101
+
102
+ logger.info(
103
+ f"Create vector store done, index_name={vector_store.index_name} prefix={vector_store.schema.index.prefix}"
104
+ )
105
+
106
+ return VectorStoreIndex.from_vector_store(
107
+ vector_store=vector_store, embed_model=self._embed_model
108
+ )
109
+
110
+ @override
111
+ def save_memory(self, user_id: str, event_strings: list[str], **kwargs) -> bool:
112
+ index = f"veadk-ltm/{self.index}/{user_id}"
113
+ vector_index = self._create_vector_index(index)
114
+
115
+ for event_string in event_strings:
116
+ document = Document(text=event_string)
117
+ nodes = self._split_documents([document])
118
+ vector_index.insert_nodes(nodes)
119
+
120
+ return True
121
+
122
+ @override
123
+ def search_memory(
124
+ self, user_id: str, query: str, top_k: int, **kwargs
125
+ ) -> list[str]:
126
+ index = f"veadk-ltm/{self.index}/{user_id}"
127
+ vector_index = self._create_vector_index(index)
128
+
129
+ _retriever = vector_index.as_retriever(similarity_top_k=top_k)
130
+ retrieved_nodes = _retriever.retrieve(query)
131
+ return [node.text for node in retrieved_nodes]
132
+
133
+ def _split_documents(self, documents: list[Document]) -> list[BaseNode]:
134
+ """Split document into chunks"""
135
+ nodes = []
136
+ for document in documents:
137
+ splitter = get_llama_index_splitter(document.metadata.get("file_path", ""))
138
+ _nodes = splitter.get_nodes_from_documents([document])
139
+ nodes.extend(_nodes)
140
+ return nodes