veadk-python 0.2.15__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 +118 -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 +83 -42
- 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/config.py +12 -1
- 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 +30 -6
- 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 +117 -4
- veadk/tracing/telemetry/telemetry.py +118 -2
- veadk/utils/misc.py +7 -0
- veadk/version.py +1 -1
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/METADATA +1 -1
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/RECORD +66 -64
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/WHEEL +0 -0
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/entry_points.txt +0 -0
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/licenses/LICENSE +0 -0
- {veadk_python-0.2.15.dist-info → veadk_python-0.2.17.dist-info}/top_level.txt +0 -0
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
|
|
@@ -50,20 +50,87 @@ def wrap_get_session_with_callbacks(obj, callback_fn: Callable):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class ShortTermMemory(BaseModel):
|
|
53
|
+
"""Short term memory for agent execution.
|
|
54
|
+
|
|
55
|
+
The short term memory represents the context of the agent model. All content in the short term memory will be sent to agent model directly, including the system prompt, historical user prompt, and historical model responses.
|
|
56
|
+
|
|
57
|
+
Attributes:
|
|
58
|
+
backend (Literal["local", "mysql", "sqlite", "postgresql", "database"]):
|
|
59
|
+
The backend of short term memory:
|
|
60
|
+
- `local` for in-memory storage
|
|
61
|
+
- `mysql` for mysql / PostgreSQL storage
|
|
62
|
+
- `sqlite` for locally sqlite storage
|
|
63
|
+
backend_configs (dict): Configuration dict for init short term memory backend.
|
|
64
|
+
db_url (str):
|
|
65
|
+
Database connection url for init short term memory backend.
|
|
66
|
+
For example, `sqlite:///./test.db`. Once set, it will override the `backend` parameter.
|
|
67
|
+
local_database_path (str):
|
|
68
|
+
Local database path, only used when `backend` is `sqlite`.
|
|
69
|
+
Default to `/tmp/veadk_local_database.db`.
|
|
70
|
+
after_load_memory_callback (Callable | None):
|
|
71
|
+
A callback to be called after loading memory from the backend. The callback function should accept `Session` as an input.
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
### In-memory simple memory
|
|
75
|
+
|
|
76
|
+
You can initialize a short term memory with in-memory storage:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from veadk import Agent, Runner
|
|
80
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
81
|
+
import asyncio
|
|
82
|
+
|
|
83
|
+
session_id = "veadk_playground_session"
|
|
84
|
+
|
|
85
|
+
agent = Agent()
|
|
86
|
+
short_term_memory = ShortTermMemory(backend="local")
|
|
87
|
+
|
|
88
|
+
runner = Runner(
|
|
89
|
+
agent=agent, short_term_memory=short_term_memory)
|
|
90
|
+
|
|
91
|
+
# This invocation will be stored in short-term memory
|
|
92
|
+
response = asyncio.run(runner.run(
|
|
93
|
+
messages="My name is VeADK", session_id=session_id
|
|
94
|
+
))
|
|
95
|
+
print(response)
|
|
96
|
+
|
|
97
|
+
# The history invocation can be fetched by model
|
|
98
|
+
response = asyncio.run(runner.run(
|
|
99
|
+
messages="Do you remember my name?", session_id=session_id # keep the same `session_id`
|
|
100
|
+
))
|
|
101
|
+
print(response)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Memory with a Database URL
|
|
105
|
+
|
|
106
|
+
Also you can use a databasae connection URL to initialize a short-term memory:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
110
|
+
|
|
111
|
+
short_term_memory = ShortTermMemory(db_url="...")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Memory with SQLite
|
|
115
|
+
|
|
116
|
+
Once you want to start the short term memory with a local SQLite, you can specify the backend to `sqlite`. It will create a local database in `local_database_path`:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
120
|
+
|
|
121
|
+
short_term_memory = ShortTermMemory(backend="sqlite", local_database_path="")
|
|
122
|
+
```
|
|
123
|
+
"""
|
|
124
|
+
|
|
53
125
|
backend: Literal["local", "mysql", "sqlite", "postgresql", "database"] = "local"
|
|
54
|
-
"""Short term memory backend. `Local` for in-memory storage, `mysql` for mysql / PostgreSQL storage. `sqlite` for sqlite storage."""
|
|
55
126
|
|
|
56
127
|
backend_configs: dict = Field(default_factory=dict)
|
|
57
|
-
"""Backend specific configurations."""
|
|
58
128
|
|
|
59
129
|
db_url: str = ""
|
|
60
|
-
"""Database connection URL, e.g. `sqlite:///./test.db`. Once set, it will override the `backend` parameter."""
|
|
61
130
|
|
|
62
131
|
local_database_path: str = "/tmp/veadk_local_database.db"
|
|
63
|
-
"""Local database path, only used when `backend` is `sqlite`. Default to `/tmp/veadk_local_database.db`."""
|
|
64
132
|
|
|
65
133
|
after_load_memory_callback: Callable | None = None
|
|
66
|
-
"""A callback to be called after loading memory from the backend. The callback function should accept `Session` as an input."""
|
|
67
134
|
|
|
68
135
|
_session_service: BaseSessionService = PrivateAttr()
|
|
69
136
|
|
|
@@ -108,6 +175,53 @@ class ShortTermMemory(BaseModel):
|
|
|
108
175
|
user_id: str,
|
|
109
176
|
session_id: str,
|
|
110
177
|
) -> Session | None:
|
|
178
|
+
"""Create or retrieve a user session.
|
|
179
|
+
|
|
180
|
+
Short term memory can attempt to create a new session for a given application and user. If a session with the same `session_id` already exists, it will be returned instead of creating a new one.
|
|
181
|
+
|
|
182
|
+
If the underlying session service is backed by a database (`DatabaseSessionService`), the method first lists all existing sessions for the given `app_name` and `user_id` and logs the number of sessions found. It then checks whether a session with the specified `session_id` already exists:
|
|
183
|
+
- If it exists → returns the existing session.
|
|
184
|
+
- If it does not exist → creates and returns a new session.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
app_name (str): The name of the application associated with the session.
|
|
188
|
+
user_id (str): The unique identifier of the user.
|
|
189
|
+
session_id (str): The unique identifier of the session to be created or retrieved.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Session | None: The retrieved or newly created `Session` object, or `None` if the session creation failed.
|
|
193
|
+
|
|
194
|
+
Examples:
|
|
195
|
+
Create a new session manually:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
import asyncio
|
|
199
|
+
|
|
200
|
+
from veadk.memory import ShortTermMemory
|
|
201
|
+
|
|
202
|
+
app_name = "app_name"
|
|
203
|
+
user_id = "user_id"
|
|
204
|
+
session_id = "session_id"
|
|
205
|
+
|
|
206
|
+
short_term_memory = ShortTermMemory()
|
|
207
|
+
|
|
208
|
+
session = asyncio.run(
|
|
209
|
+
short_term_memory.create_session(
|
|
210
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
print(session)
|
|
215
|
+
|
|
216
|
+
session = asyncio.run(
|
|
217
|
+
short_term_memory.session_service.get_session(
|
|
218
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
print(session)
|
|
223
|
+
```
|
|
224
|
+
"""
|
|
111
225
|
if isinstance(self._session_service, DatabaseSessionService):
|
|
112
226
|
list_sessions_response = await self._session_service.list_sessions(
|
|
113
227
|
app_name=app_name, user_id=user_id
|