veadk-python 0.2.16__py3-none-any.whl → 0.2.17__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.
- veadk/a2a/remote_ve_agent.py +56 -1
- veadk/agent.py +79 -26
- veadk/agents/loop_agent.py +22 -9
- veadk/agents/parallel_agent.py +21 -9
- veadk/agents/sequential_agent.py +18 -9
- veadk/auth/veauth/apmplus_veauth.py +32 -39
- veadk/auth/veauth/ark_veauth.py +3 -1
- veadk/auth/veauth/utils.py +12 -0
- veadk/auth/veauth/viking_mem0_veauth.py +91 -0
- veadk/cli/cli.py +5 -1
- veadk/cli/cli_create.py +62 -1
- veadk/cli/cli_deploy.py +36 -1
- veadk/cli/cli_eval.py +55 -0
- veadk/cli/cli_init.py +44 -3
- veadk/cli/cli_kb.py +36 -1
- veadk/cli/cli_pipeline.py +66 -1
- veadk/cli/cli_prompt.py +16 -1
- veadk/cli/cli_uploadevalset.py +15 -1
- veadk/cli/cli_web.py +35 -4
- veadk/cloud/cloud_agent_engine.py +142 -25
- veadk/cloud/cloud_app.py +219 -12
- veadk/configs/database_configs.py +4 -0
- veadk/configs/model_configs.py +5 -1
- veadk/configs/tracing_configs.py +2 -2
- veadk/evaluation/adk_evaluator/adk_evaluator.py +77 -17
- veadk/evaluation/base_evaluator.py +219 -3
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +116 -1
- veadk/evaluation/eval_set_file_loader.py +20 -0
- veadk/evaluation/eval_set_recorder.py +54 -0
- veadk/evaluation/types.py +32 -0
- veadk/evaluation/utils/prometheus.py +61 -0
- veadk/knowledgebase/backends/base_backend.py +14 -1
- veadk/knowledgebase/backends/in_memory_backend.py +10 -1
- veadk/knowledgebase/backends/opensearch_backend.py +26 -0
- veadk/knowledgebase/backends/redis_backend.py +29 -2
- veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +43 -5
- veadk/knowledgebase/knowledgebase.py +173 -12
- veadk/memory/long_term_memory.py +148 -4
- veadk/memory/long_term_memory_backends/mem0_backend.py +11 -0
- veadk/memory/short_term_memory.py +119 -5
- veadk/runner.py +412 -1
- veadk/tools/builtin_tools/llm_shield.py +381 -0
- veadk/tools/builtin_tools/mcp_router.py +9 -2
- veadk/tools/builtin_tools/run_code.py +25 -5
- veadk/tools/builtin_tools/web_search.py +38 -154
- veadk/tracing/base_tracer.py +28 -1
- veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +105 -1
- veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +260 -0
- veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +69 -0
- veadk/tracing/telemetry/attributes/extractors/types.py +78 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +157 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +8 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +60 -1
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +118 -1
- veadk/tracing/telemetry/exporters/tls_exporter.py +66 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +111 -1
- veadk/tracing/telemetry/telemetry.py +118 -2
- veadk/version.py +1 -1
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/METADATA +1 -1
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/RECORD +64 -62
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/WHEEL +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/entry_points.txt +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/licenses/LICENSE +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/top_level.txt +0 -0
|
@@ -18,8 +18,21 @@ from pydantic import BaseModel
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class BaseKnowledgebaseBackend(ABC, BaseModel):
|
|
21
|
+
"""Base backend for knowledgebase.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
index (str): Index or collection name of the vector storage.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
You can implement your own knowledgebase backend.
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
class CustomKnowledgebaseBackend(BaseKnowledgebaseBackend):
|
|
31
|
+
pass
|
|
32
|
+
```
|
|
33
|
+
"""
|
|
34
|
+
|
|
21
35
|
index: str
|
|
22
|
-
"""Index or collection name of the vector storage."""
|
|
23
36
|
|
|
24
37
|
@abstractmethod
|
|
25
38
|
def precheck_index_naming(self) -> None:
|
|
@@ -24,10 +24,19 @@ from veadk.knowledgebase.backends.utils import get_llama_index_splitter
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class InMemoryKnowledgeBackend(BaseKnowledgebaseBackend):
|
|
27
|
+
"""A in-memory implementation backend for knowledgebase.
|
|
28
|
+
|
|
29
|
+
In-memory backend stores embedded text in a vector storage from Llama-index.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
embedding_config (EmbeddingModelConfig):
|
|
33
|
+
Embedding config for text embedding and search.
|
|
34
|
+
Embedding config contains embedding model name and the corresponding dim.
|
|
35
|
+
"""
|
|
36
|
+
|
|
27
37
|
embedding_config: NormalEmbeddingModelConfig | EmbeddingModelConfig = Field(
|
|
28
38
|
default_factory=EmbeddingModelConfig
|
|
29
39
|
)
|
|
30
|
-
"""Embedding model configs"""
|
|
31
40
|
|
|
32
41
|
def model_post_init(self, __context: Any) -> None:
|
|
33
42
|
self._embed_model = OpenAILikeEmbedding(
|
|
@@ -43,6 +43,32 @@ except ImportError:
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class OpensearchKnowledgeBackend(BaseKnowledgebaseBackend):
|
|
46
|
+
"""Opensearch-based backend for knowledgebase.
|
|
47
|
+
|
|
48
|
+
Opensearch backend stores embedded text in a opensearch database by Llama-index.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
opensearch_config (OpensearchConfig):
|
|
52
|
+
Opensearch database configurations.
|
|
53
|
+
Mainly contains opensearch host, port, username, password, etc.
|
|
54
|
+
embedding_config (EmbeddingModelConfig):
|
|
55
|
+
Embedding config for text embedding and search.
|
|
56
|
+
Embedding config contains embedding model name and the corresponding dim.
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
Init a knowledgebase based on opensearch backend.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
knowledgebase = Knowledgebase(backend="opensearch")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
With more configurations:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
...
|
|
69
|
+
```
|
|
70
|
+
"""
|
|
71
|
+
|
|
46
72
|
opensearch_config: OpensearchConfig = Field(default_factory=OpensearchConfig)
|
|
47
73
|
"""Opensearch client configs"""
|
|
48
74
|
|
|
@@ -44,13 +44,40 @@ except ImportError:
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class RedisKnowledgeBackend(BaseKnowledgebaseBackend):
|
|
47
|
+
"""Redis based backend for knowledgebase.
|
|
48
|
+
|
|
49
|
+
Redis backend stores embedded text in a redis database by Llama-index.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
redis_config (RedisConfig):
|
|
53
|
+
Redis database configurations.
|
|
54
|
+
Mainly contains redis database host, port, etc.
|
|
55
|
+
embedding_config (EmbeddingModelConfig):
|
|
56
|
+
Embedding configurations for text embedding and search.
|
|
57
|
+
Embedding config contains embedding model name and the corresponding dim.
|
|
58
|
+
|
|
59
|
+
Notes:
|
|
60
|
+
Please ensure that your redis database supports Redisaearch stack.
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
Init a knowledgebase based on redis backend.
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
knowledgebase = Knowledgebase(backend="redis")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
With more configurations:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
...
|
|
73
|
+
```
|
|
74
|
+
"""
|
|
75
|
+
|
|
47
76
|
redis_config: RedisConfig = Field(default_factory=RedisConfig)
|
|
48
|
-
"""Redis client configs"""
|
|
49
77
|
|
|
50
78
|
embedding_config: EmbeddingModelConfig | NormalEmbeddingModelConfig = Field(
|
|
51
79
|
default_factory=EmbeddingModelConfig
|
|
52
80
|
)
|
|
53
|
-
"""Embedding model configs"""
|
|
54
81
|
|
|
55
82
|
def model_post_init(self, __context: Any) -> None:
|
|
56
83
|
# We will use `from_url` to init Redis client once the
|
|
@@ -59,24 +59,62 @@ def get_files_in_directory(directory: str):
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
class VikingDBKnowledgeBackend(BaseKnowledgebaseBackend):
|
|
62
|
+
"""Volcengine Viking DB knowledgebase backend.
|
|
63
|
+
|
|
64
|
+
Volcegnine Viking DB knowledgebase provides powerful knowledgebase storage and search.
|
|
65
|
+
|
|
66
|
+
Attributes:
|
|
67
|
+
volcengine_access_key (str | None):
|
|
68
|
+
Access key for Volcengine. Loaded automatically from the
|
|
69
|
+
`VOLCENGINE_ACCESS_KEY` environment variable if not provided.
|
|
70
|
+
|
|
71
|
+
volcengine_secret_key (str | None):
|
|
72
|
+
Secret key for Volcengine. Loaded automatically from the
|
|
73
|
+
`VOLCENGINE_SECRET_KEY` environment variable if not provided.
|
|
74
|
+
|
|
75
|
+
session_token (str):
|
|
76
|
+
Optional session token for temporary credentials. Defaults to an empty string.
|
|
77
|
+
|
|
78
|
+
volcengine_project (str):
|
|
79
|
+
VikingDB knowledgebase project name in the Volcengine console platform.
|
|
80
|
+
Defaults to `"default"`.
|
|
81
|
+
|
|
82
|
+
region (str): Region of the VikingDB knowledgebase. Defaults to `"cn-beijing"`.
|
|
83
|
+
|
|
84
|
+
tos_config (TOSConfig | NormalTOSConfig):
|
|
85
|
+
TOS configuration used for uploading files to TOS (Volcengine’s Object Storage).
|
|
86
|
+
Defaults to a new instance of `TOSConfig`.
|
|
87
|
+
|
|
88
|
+
Notes:
|
|
89
|
+
Please make sure that you have created a bucket in your TOS.
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
Init a knowledgebase based on VikingDB knowledgebase backend.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
knowledgebase = Knowledgebase(backend="redis")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
With more configurations:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
...
|
|
102
|
+
```
|
|
103
|
+
"""
|
|
104
|
+
|
|
62
105
|
volcengine_access_key: str | None = Field(
|
|
63
106
|
default_factory=lambda: os.getenv("VOLCENGINE_ACCESS_KEY")
|
|
64
107
|
)
|
|
65
|
-
|
|
66
108
|
volcengine_secret_key: str | None = Field(
|
|
67
109
|
default_factory=lambda: os.getenv("VOLCENGINE_SECRET_KEY")
|
|
68
110
|
)
|
|
69
|
-
|
|
70
111
|
session_token: str = ""
|
|
71
112
|
|
|
72
113
|
volcengine_project: str = "default"
|
|
73
|
-
"""VikingDB knowledgebase project in Volcengine console platform. Default by `default`"""
|
|
74
114
|
|
|
75
115
|
region: str = "cn-beijing"
|
|
76
|
-
"""VikingDB knowledgebase region"""
|
|
77
116
|
|
|
78
117
|
tos_config: TOSConfig | NormalTOSConfig = Field(default_factory=TOSConfig)
|
|
79
|
-
"""TOS config, used to upload files to TOS"""
|
|
80
118
|
|
|
81
119
|
def model_post_init(self, __context: Any) -> None:
|
|
82
120
|
self.precheck_index_naming()
|
|
@@ -56,6 +56,110 @@ def _get_backend_cls(backend: str) -> type[BaseKnowledgebaseBackend]:
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
class KnowledgeBase(BaseModel):
|
|
59
|
+
"""A knowledge base for storing user-related information.
|
|
60
|
+
|
|
61
|
+
This class represents a knowledge base used to store and retrieve user-specific data.
|
|
62
|
+
It supports multiple backend options, including in-memory, OpenSearch, Redis, and Volcengine's
|
|
63
|
+
VikingDB. The knowledge base allows for efficient document retrieval based on similarity,
|
|
64
|
+
with the ability to configure backend-specific settings.
|
|
65
|
+
|
|
66
|
+
Attributes:
|
|
67
|
+
name (str): The name of the knowledge base. Default is "user_knowledgebase".
|
|
68
|
+
description (str): A description of the knowledge base. Default is "This knowledgebase stores some user-related information."
|
|
69
|
+
backend (Union[Literal["local", "opensearch", "viking", "redis"], BaseKnowledgebaseBackend]):
|
|
70
|
+
The type of backend to use for storing and querying the knowledge base. Supported options include:
|
|
71
|
+
- 'local' for in-memory storage (data is lost when the program exits).
|
|
72
|
+
- 'opensearch' for OpenSearch (requires OpenSearch cluster).
|
|
73
|
+
- 'viking' for Volcengine VikingDB (requires VikingDB service).
|
|
74
|
+
- 'redis' for Redis with vector search capability (requires Redis).
|
|
75
|
+
Default is 'local'.
|
|
76
|
+
backend_config (dict): Configuration dictionary for the selected backend.
|
|
77
|
+
top_k (int): The number of top similar documents to retrieve during a search. Default is 10.
|
|
78
|
+
app_name (str): The name of the application associated with the knowledge base. If index is not provided, this value will be set to `index`.
|
|
79
|
+
index (str): The name of the knowledge base index.
|
|
80
|
+
|
|
81
|
+
Notes:
|
|
82
|
+
Please ensure that you have set the embedding-related configurations in environment variables.
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
### Simple backend
|
|
86
|
+
|
|
87
|
+
Create a local knowledgebase:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from veadk import Agent, Runner
|
|
91
|
+
from veadk.knowledgebase.knowledgebase import KnowledgeBase
|
|
92
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
93
|
+
|
|
94
|
+
app_name = "veadk_playground_app"
|
|
95
|
+
user_id = "veadk_playground_user"
|
|
96
|
+
session_id = "veadk_playground_session"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
knowledgebase = KnowledgeBase(backend="opensearch", app_name=app_name)
|
|
100
|
+
knowledgebase.add_from_files(files=[knowledgebase_file])
|
|
101
|
+
|
|
102
|
+
agent = Agent(knowledgebase=knowledgebase)
|
|
103
|
+
|
|
104
|
+
runner = Runner(
|
|
105
|
+
agent=agent,
|
|
106
|
+
short_term_memory=ShortTermMemory(),
|
|
107
|
+
app_name=app_name,
|
|
108
|
+
user_id=user_id,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
response = await runner.run(
|
|
112
|
+
messages="Tell me the secret of green.", session_id=session_id
|
|
113
|
+
)
|
|
114
|
+
print(response)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Initialize knowledgebase with metadata
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from veadk.knowledgebase import KnowledgeBase
|
|
121
|
+
|
|
122
|
+
knowledgebase = KnowledgeBase(
|
|
123
|
+
name="user_data",
|
|
124
|
+
description="A knowledgebase contains user hobbies.",
|
|
125
|
+
index="my_app",
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Initialize knowledgebase with backend instance
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import veadk.config # noqa
|
|
133
|
+
|
|
134
|
+
from veadk.knowledgebase import KnowledgeBase
|
|
135
|
+
from veadk.knowledgebase.backends.in_memory_backend import InMemoryKnowledgeBackend
|
|
136
|
+
|
|
137
|
+
backend = InMemoryKnowledgeBackend(
|
|
138
|
+
index="my_app",
|
|
139
|
+
embedding_config=...,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
knowledgebase = KnowledgeBase(
|
|
143
|
+
name="user_data",
|
|
144
|
+
description="A knowledgebase contains user hobbies.",
|
|
145
|
+
backend=backend,
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Initialize knowledgebase with backend config
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from veadk.knowledgebase import KnowledgeBase
|
|
153
|
+
|
|
154
|
+
knowledgebase = KnowledgeBase(
|
|
155
|
+
name="user_data",
|
|
156
|
+
description="A knowledgebase contains user hobbies.",
|
|
157
|
+
backend="local",
|
|
158
|
+
backend_config={"index": "user_app"},
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
"""
|
|
162
|
+
|
|
59
163
|
name: str = "user_knowledgebase"
|
|
60
164
|
|
|
61
165
|
description: str = "This knowledgebase stores some user-related information."
|
|
@@ -63,23 +167,14 @@ class KnowledgeBase(BaseModel):
|
|
|
63
167
|
backend: Union[
|
|
64
168
|
Literal["local", "opensearch", "viking", "redis"], BaseKnowledgebaseBackend
|
|
65
169
|
] = "local"
|
|
66
|
-
"""Knowledgebase backend type. Supported backends are:
|
|
67
|
-
- local: In-memory knowledgebase, data will be lost when the program exits.
|
|
68
|
-
- opensearch: OpenSearch knowledgebase, requires an OpenSearch cluster.
|
|
69
|
-
- viking: Volcengine VikingDB knowledgebase, requires VikingDB service.
|
|
70
|
-
- redis: Redis knowledgebase, requires Redis with vector search capability.
|
|
71
|
-
Default is `local`."""
|
|
72
170
|
|
|
73
171
|
backend_config: dict = Field(default_factory=dict)
|
|
74
|
-
"""Configuration for the backend"""
|
|
75
172
|
|
|
76
173
|
top_k: int = 10
|
|
77
|
-
"""Number of top similar documents to retrieve during search"""
|
|
78
174
|
|
|
79
175
|
app_name: str = ""
|
|
80
176
|
|
|
81
177
|
index: str = ""
|
|
82
|
-
"""The name of the knowledgebase index. If not provided, it will be generated based on the `app_name`."""
|
|
83
178
|
|
|
84
179
|
def model_post_init(self, __context: Any) -> None:
|
|
85
180
|
if isinstance(self.backend, BaseKnowledgebaseBackend):
|
|
@@ -108,15 +203,81 @@ class KnowledgeBase(BaseModel):
|
|
|
108
203
|
)
|
|
109
204
|
|
|
110
205
|
def add_from_directory(self, directory: str, **kwargs) -> bool:
|
|
111
|
-
"""Add knowledge from file path to knowledgebase
|
|
206
|
+
"""Add knowledge from file path to knowledgebase.
|
|
207
|
+
|
|
208
|
+
Add the files in the directory to knowledgebase backend.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
directory (str): The directory path that needs to store.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
bool: True if successfully store the knowledgebase, False otherwise.
|
|
215
|
+
|
|
216
|
+
Examples:
|
|
217
|
+
Store a directory to knowledgebase:
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
knowledgebase = Knowledgebase(backend="local")
|
|
221
|
+
|
|
222
|
+
if knowledgebase.add_from_directory("./knowledgebase"):
|
|
223
|
+
# add successfully
|
|
224
|
+
...
|
|
225
|
+
else:
|
|
226
|
+
raise RuntimeError("Uploaded directory failed.")
|
|
227
|
+
```
|
|
228
|
+
"""
|
|
112
229
|
return self._backend.add_from_directory(directory=directory, **kwargs)
|
|
113
230
|
|
|
114
231
|
def add_from_files(self, files: list[str], **kwargs) -> bool:
|
|
115
|
-
"""Add knowledge
|
|
232
|
+
"""Add knowledge files to knowledgebase.
|
|
233
|
+
|
|
234
|
+
Add a list of files to knowledgebase backend.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
files (str): The list of files.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
bool: True if successfully store the knowledgebase, False otherwise.
|
|
241
|
+
|
|
242
|
+
Examples:
|
|
243
|
+
Store files to knowledgebase:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
knowledgebase = Knowledgebase(backend="local")
|
|
247
|
+
|
|
248
|
+
if knowledgebase.add_from_files("./knowledgebase"):
|
|
249
|
+
# add successfully
|
|
250
|
+
...
|
|
251
|
+
else:
|
|
252
|
+
raise RuntimeError("Uploaded files failed.")
|
|
253
|
+
```
|
|
254
|
+
"""
|
|
116
255
|
return self._backend.add_from_files(files=files, **kwargs)
|
|
117
256
|
|
|
118
257
|
def add_from_text(self, text: str | list[str], **kwargs) -> bool:
|
|
119
|
-
"""Add
|
|
258
|
+
"""Add a piece of text or a list of text to knowledgebase.
|
|
259
|
+
|
|
260
|
+
The `text` can be a string or a list of string. The text will be embedded and stored by the corresponding backend.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
text (str | list[str]): The text string or a list of text strings.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
bool: True if successfully store the knowledgebase, False otherwise.
|
|
267
|
+
|
|
268
|
+
Examples:
|
|
269
|
+
Store a string or a list of string to knowledgebase:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
knowledgebase = Knowledgebase(backend="local")
|
|
273
|
+
|
|
274
|
+
if knowledgebase.add_from_text("./knowledgebase"):
|
|
275
|
+
# add successfully
|
|
276
|
+
...
|
|
277
|
+
else:
|
|
278
|
+
raise RuntimeError("Uploaded text failed.")
|
|
279
|
+
```
|
|
280
|
+
"""
|
|
120
281
|
return self._backend.add_from_text(text=text, **kwargs)
|
|
121
282
|
|
|
122
283
|
def search(self, query: str, top_k: int = 0, **kwargs) -> list[KnowledgebaseEntry]:
|
veadk/memory/long_term_memory.py
CHANGED
|
@@ -73,24 +73,111 @@ def _get_backend_cls(backend: str) -> type[BaseLongTermMemoryBackend]:
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
class LongTermMemory(BaseMemoryService, BaseModel):
|
|
76
|
+
"""Manages long-term memory storage and retrieval for applications.
|
|
77
|
+
|
|
78
|
+
This class provides an interface to store, retrieve, and manage long-term
|
|
79
|
+
contextual information using different backend types (e.g., OpenSearch, Redis).
|
|
80
|
+
It supports configuration of the backend service and retrieval behavior.
|
|
81
|
+
|
|
82
|
+
Attributes:
|
|
83
|
+
backend (Union[Literal["local", "opensearch", "redis", "viking", "viking_mem", "mem0"], BaseLongTermMemoryBackend]):
|
|
84
|
+
The type or instance of the long-term memory backend. Defaults to "opensearch".
|
|
85
|
+
|
|
86
|
+
backend_config (dict):
|
|
87
|
+
Configuration parameters for the selected backend. Defaults to an empty dictionary.
|
|
88
|
+
|
|
89
|
+
top_k (int):
|
|
90
|
+
The number of top similar documents to retrieve during search. Defaults to 5.
|
|
91
|
+
|
|
92
|
+
index (str):
|
|
93
|
+
The name of the index or collection used for storing memory items. Defaults to an empty string.
|
|
94
|
+
|
|
95
|
+
app_name (str):
|
|
96
|
+
The name of the application that owns this memory instance. Defaults to an empty string.
|
|
97
|
+
|
|
98
|
+
user_id (str):
|
|
99
|
+
Deprecated attribute. Retained for backward compatibility. Defaults to an empty string.
|
|
100
|
+
|
|
101
|
+
Notes:
|
|
102
|
+
Please ensure that you have set the embedding-related configurations in environment variables.
|
|
103
|
+
|
|
104
|
+
Examples:
|
|
105
|
+
### Simple long-term memory
|
|
106
|
+
|
|
107
|
+
Once create a long-term memory withou any arguments, all configurations are come from **environment variables**.
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
import asyncio
|
|
111
|
+
|
|
112
|
+
from veadk import Agent, Runner
|
|
113
|
+
from veadk.memory.long_term_memory import LongTermMemory
|
|
114
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
115
|
+
|
|
116
|
+
app_name = "veadk_playground_app"
|
|
117
|
+
user_id = "veadk_playground_user"
|
|
118
|
+
|
|
119
|
+
long_term_memory = LongTermMemory(backend="local", app_name=app_name)
|
|
120
|
+
|
|
121
|
+
agent = Agent(long_term_memory=long_term_memory)
|
|
122
|
+
|
|
123
|
+
runner = Runner(
|
|
124
|
+
agent=agent,
|
|
125
|
+
app_name=app_name,
|
|
126
|
+
user_id=user_id,
|
|
127
|
+
short_term_memory=ShortTermMemory(),
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# ===== add memory =====
|
|
131
|
+
session_id = "veadk_playground_session"
|
|
132
|
+
teaching_prompt = "I brought an ice-cream last week."
|
|
133
|
+
|
|
134
|
+
asyncio.run(runner.run(messages=teaching_prompt, session_id=session_id))
|
|
135
|
+
asyncio.run(
|
|
136
|
+
runner.save_session_to_long_term_memory(session_id=session_id)
|
|
137
|
+
) # save session to long-term memory
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# ===== check memory =====
|
|
141
|
+
session_id = "veadk_playground_session_2" # use a new session
|
|
142
|
+
student_prompt = "What I brought last week?"
|
|
143
|
+
|
|
144
|
+
response = asyncio.run(runner.run(messages=student_prompt, session_id=session_id))
|
|
145
|
+
|
|
146
|
+
print(response)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Create with a backend instance
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from veadk.memory.long_term_memory import LongTermMemory
|
|
153
|
+
from veadk.memory.long_term_memory.backends import LongTermMemory
|
|
154
|
+
|
|
155
|
+
long_term_memory = LongTermMemory(backend=...)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Create with backend configurations
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from veadk.memory.long_term_memory import LongTermMemory
|
|
162
|
+
|
|
163
|
+
long_term_memory = LongTermMemory(backend="", backend_config={})
|
|
164
|
+
```
|
|
165
|
+
"""
|
|
166
|
+
|
|
76
167
|
backend: Union[
|
|
77
168
|
Literal["local", "opensearch", "redis", "viking", "viking_mem", "mem0"],
|
|
78
169
|
BaseLongTermMemoryBackend,
|
|
79
170
|
] = "opensearch"
|
|
80
|
-
"""Long term memory backend type"""
|
|
81
171
|
|
|
82
172
|
backend_config: dict = Field(default_factory=dict)
|
|
83
|
-
"""Long term memory backend configuration"""
|
|
84
173
|
|
|
85
174
|
top_k: int = 5
|
|
86
|
-
"""Number of top similar documents to retrieve during search."""
|
|
87
175
|
|
|
88
176
|
index: str = ""
|
|
89
177
|
|
|
90
178
|
app_name: str = ""
|
|
91
179
|
|
|
92
180
|
user_id: str = ""
|
|
93
|
-
"""Deprecated attribute"""
|
|
94
181
|
|
|
95
182
|
def model_post_init(self, __context: Any) -> None:
|
|
96
183
|
# Once user define a backend instance, use it directly
|
|
@@ -163,6 +250,33 @@ class LongTermMemory(BaseMemoryService, BaseModel):
|
|
|
163
250
|
self,
|
|
164
251
|
session: Session,
|
|
165
252
|
):
|
|
253
|
+
"""Add a chat session's events to the long-term memory backend.
|
|
254
|
+
|
|
255
|
+
This method extracts and filters the events from a given `Session` object,
|
|
256
|
+
converts them into serialized strings, and stores them into the long-term
|
|
257
|
+
memory system. It is typically called after a chat session ends or when
|
|
258
|
+
important contextual data needs to be persisted for future retrieval.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
session (Session):
|
|
262
|
+
The session object containing user ID and a list of events to persist.
|
|
263
|
+
|
|
264
|
+
Examples:
|
|
265
|
+
```python
|
|
266
|
+
session = Session(
|
|
267
|
+
user_id="user_123",
|
|
268
|
+
events=[
|
|
269
|
+
Event(role="user", content="I like Go and Rust."),
|
|
270
|
+
Event(role="assistant", content="Got it! I'll remember that."),
|
|
271
|
+
]
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
await memory_service.add_session_to_memory(session)
|
|
275
|
+
# Logs:
|
|
276
|
+
# Adding 2 events to long term memory: index=main
|
|
277
|
+
# Added 2 events to long term memory: index=main, user_id=user_123
|
|
278
|
+
```
|
|
279
|
+
"""
|
|
166
280
|
user_id = session.user_id
|
|
167
281
|
event_strings = self._filter_and_convert_events(session.events)
|
|
168
282
|
|
|
@@ -178,6 +292,36 @@ class LongTermMemory(BaseMemoryService, BaseModel):
|
|
|
178
292
|
async def search_memory(
|
|
179
293
|
self, *, app_name: str, user_id: str, query: str
|
|
180
294
|
) -> SearchMemoryResponse:
|
|
295
|
+
"""Search memory entries for a given user and query.
|
|
296
|
+
|
|
297
|
+
This method queries the memory backend to retrieve the most relevant stored
|
|
298
|
+
memory chunks for a given user and text query. It then converts those raw
|
|
299
|
+
memory chunks into structured `MemoryEntry` objects to be returned to the caller.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
app_name (str): Name of the application requesting the memory search.
|
|
303
|
+
user_id (str): Unique identifier for the user whose memory is being queried.
|
|
304
|
+
query (str): The text query to match against stored memory content.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
SearchMemoryResponse:
|
|
308
|
+
An object containing a list of `MemoryEntry` items representing
|
|
309
|
+
the retrieved memory snippets relevant to the query.
|
|
310
|
+
|
|
311
|
+
Examples:
|
|
312
|
+
```python
|
|
313
|
+
response = await memory_service.search_memory(
|
|
314
|
+
app_name="chat_app",
|
|
315
|
+
user_id="user_123",
|
|
316
|
+
query="favorite programming language"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
for memory in response.memories:
|
|
320
|
+
print(memory.content.parts[0].text)
|
|
321
|
+
# Output:
|
|
322
|
+
# User likes Python and TypeScript for backend development.
|
|
323
|
+
```
|
|
324
|
+
"""
|
|
181
325
|
logger.info(f"Search memory with query={query}")
|
|
182
326
|
|
|
183
327
|
memory_chunks = []
|
|
@@ -17,6 +17,7 @@ from typing import Any
|
|
|
17
17
|
from pydantic import Field
|
|
18
18
|
from typing_extensions import override
|
|
19
19
|
|
|
20
|
+
from veadk.auth.veauth.viking_mem0_veauth import get_viking_mem0_token
|
|
20
21
|
from veadk.configs.database_configs import Mem0Config
|
|
21
22
|
from veadk.memory.long_term_memory_backends.base_backend import (
|
|
22
23
|
BaseLongTermMemoryBackend,
|
|
@@ -43,6 +44,16 @@ class Mem0LTMBackend(BaseLongTermMemoryBackend):
|
|
|
43
44
|
def model_post_init(self, __context: Any) -> None:
|
|
44
45
|
"""Initialize Mem0 client"""
|
|
45
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
|
+
|
|
46
57
|
try:
|
|
47
58
|
self._mem0_client = MemoryClient(
|
|
48
59
|
host=self.mem0_config.base_url, # mem0 endpoint
|