agno 2.0.0rc2__py3-none-any.whl → 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/agent.py +6009 -2874
- agno/api/api.py +2 -0
- agno/api/os.py +1 -1
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +385 -6
- agno/db/dynamo/dynamo.py +388 -81
- agno/db/dynamo/schemas.py +47 -10
- agno/db/dynamo/utils.py +63 -4
- agno/db/firestore/firestore.py +435 -64
- agno/db/firestore/schemas.py +11 -0
- agno/db/firestore/utils.py +102 -4
- agno/db/gcs_json/gcs_json_db.py +384 -42
- agno/db/gcs_json/utils.py +60 -26
- agno/db/in_memory/in_memory_db.py +351 -66
- agno/db/in_memory/utils.py +60 -2
- agno/db/json/json_db.py +339 -48
- agno/db/json/utils.py +60 -26
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +510 -37
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +15 -1
- agno/db/mongo/async_mongo.py +2036 -0
- agno/db/mongo/mongo.py +653 -76
- agno/db/mongo/schemas.py +13 -0
- agno/db/mongo/utils.py +80 -8
- agno/db/mysql/mysql.py +687 -25
- agno/db/mysql/schemas.py +61 -37
- agno/db/mysql/utils.py +60 -2
- agno/db/postgres/__init__.py +2 -1
- agno/db/postgres/async_postgres.py +2001 -0
- agno/db/postgres/postgres.py +676 -57
- agno/db/postgres/schemas.py +43 -18
- agno/db/postgres/utils.py +164 -2
- agno/db/redis/redis.py +344 -38
- agno/db/redis/schemas.py +18 -0
- agno/db/redis/utils.py +60 -2
- agno/db/schemas/__init__.py +2 -1
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/memory.py +13 -0
- agno/db/singlestore/schemas.py +26 -1
- agno/db/singlestore/singlestore.py +687 -53
- agno/db/singlestore/utils.py +60 -2
- agno/db/sqlite/__init__.py +2 -1
- agno/db/sqlite/async_sqlite.py +2371 -0
- agno/db/sqlite/schemas.py +24 -0
- agno/db/sqlite/sqlite.py +774 -85
- agno/db/sqlite/utils.py +168 -5
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +309 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1361 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +50 -22
- agno/eval/accuracy.py +50 -43
- agno/eval/performance.py +6 -3
- agno/eval/reliability.py +6 -3
- agno/eval/utils.py +33 -16
- agno/exceptions.py +68 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/integrations/discord/client.py +1 -0
- agno/knowledge/chunking/agentic.py +13 -10
- agno/knowledge/chunking/fixed.py +1 -1
- agno/knowledge/chunking/semantic.py +40 -8
- agno/knowledge/chunking/strategy.py +59 -15
- agno/knowledge/embedder/aws_bedrock.py +9 -4
- agno/knowledge/embedder/azure_openai.py +54 -0
- agno/knowledge/embedder/base.py +2 -0
- agno/knowledge/embedder/cohere.py +184 -5
- agno/knowledge/embedder/fastembed.py +1 -1
- agno/knowledge/embedder/google.py +79 -1
- agno/knowledge/embedder/huggingface.py +9 -4
- agno/knowledge/embedder/jina.py +63 -0
- agno/knowledge/embedder/mistral.py +78 -11
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/ollama.py +13 -0
- agno/knowledge/embedder/openai.py +37 -65
- agno/knowledge/embedder/sentence_transformer.py +8 -4
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +69 -16
- agno/knowledge/knowledge.py +595 -187
- agno/knowledge/reader/base.py +9 -2
- agno/knowledge/reader/csv_reader.py +8 -10
- agno/knowledge/reader/docx_reader.py +5 -6
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/json_reader.py +6 -5
- agno/knowledge/reader/markdown_reader.py +13 -13
- agno/knowledge/reader/pdf_reader.py +43 -68
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +51 -6
- agno/knowledge/reader/s3_reader.py +3 -15
- agno/knowledge/reader/tavily_reader.py +194 -0
- agno/knowledge/reader/text_reader.py +13 -13
- agno/knowledge/reader/web_search_reader.py +2 -43
- agno/knowledge/reader/website_reader.py +43 -25
- agno/knowledge/reranker/__init__.py +3 -0
- agno/knowledge/types.py +9 -0
- agno/knowledge/utils.py +20 -0
- agno/media.py +339 -266
- agno/memory/manager.py +336 -82
- agno/models/aimlapi/aimlapi.py +2 -2
- agno/models/anthropic/claude.py +183 -37
- agno/models/aws/bedrock.py +52 -112
- agno/models/aws/claude.py +33 -1
- agno/models/azure/ai_foundry.py +33 -15
- agno/models/azure/openai_chat.py +25 -8
- agno/models/base.py +1011 -566
- agno/models/cerebras/cerebras.py +19 -13
- agno/models/cerebras/cerebras_openai.py +8 -5
- agno/models/cohere/chat.py +27 -1
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/dashscope/dashscope.py +1 -0
- agno/models/deepinfra/deepinfra.py +2 -2
- agno/models/deepseek/deepseek.py +2 -2
- agno/models/fireworks/fireworks.py +2 -2
- agno/models/google/gemini.py +110 -37
- agno/models/groq/groq.py +28 -11
- agno/models/huggingface/huggingface.py +2 -1
- agno/models/internlm/internlm.py +2 -2
- agno/models/langdb/langdb.py +4 -4
- agno/models/litellm/chat.py +18 -1
- agno/models/litellm/litellm_openai.py +2 -2
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/message.py +143 -4
- agno/models/meta/llama.py +27 -10
- agno/models/meta/llama_openai.py +5 -17
- agno/models/nebius/nebius.py +6 -6
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/nvidia.py +2 -2
- agno/models/ollama/chat.py +60 -6
- agno/models/openai/chat.py +102 -43
- agno/models/openai/responses.py +103 -106
- agno/models/openrouter/openrouter.py +41 -3
- agno/models/perplexity/perplexity.py +4 -5
- agno/models/portkey/portkey.py +3 -3
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +52 -0
- agno/models/response.py +81 -5
- agno/models/sambanova/sambanova.py +2 -2
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +25 -0
- agno/models/together/together.py +2 -2
- agno/models/utils.py +254 -8
- agno/models/vercel/v0.py +2 -2
- agno/models/vertexai/__init__.py +0 -0
- agno/models/vertexai/claude.py +96 -0
- agno/models/vllm/vllm.py +1 -0
- agno/models/xai/xai.py +3 -2
- agno/os/app.py +543 -175
- agno/os/auth.py +24 -14
- agno/os/config.py +1 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +250 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/agui.py +23 -7
- agno/os/interfaces/agui/router.py +27 -3
- agno/os/interfaces/agui/utils.py +242 -142
- agno/os/interfaces/base.py +6 -2
- agno/os/interfaces/slack/router.py +81 -23
- agno/os/interfaces/slack/slack.py +29 -14
- agno/os/interfaces/whatsapp/router.py +11 -4
- agno/os/interfaces/whatsapp/whatsapp.py +14 -7
- agno/os/mcp.py +111 -54
- agno/os/middleware/__init__.py +7 -0
- agno/os/middleware/jwt.py +233 -0
- agno/os/router.py +556 -139
- agno/os/routers/evals/evals.py +71 -34
- agno/os/routers/evals/schemas.py +31 -31
- agno/os/routers/evals/utils.py +6 -5
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/knowledge.py +185 -38
- agno/os/routers/knowledge/schemas.py +82 -22
- agno/os/routers/memory/memory.py +158 -53
- agno/os/routers/memory/schemas.py +20 -16
- agno/os/routers/metrics/metrics.py +20 -8
- agno/os/routers/metrics/schemas.py +16 -16
- agno/os/routers/session/session.py +499 -38
- agno/os/schema.py +308 -198
- agno/os/utils.py +401 -41
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +3 -1
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +2 -2
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +7 -2
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +266 -112
- agno/run/base.py +53 -24
- agno/run/team.py +252 -111
- agno/run/workflow.py +156 -45
- agno/session/agent.py +105 -89
- agno/session/summary.py +65 -25
- agno/session/team.py +176 -96
- agno/session/workflow.py +406 -40
- agno/team/team.py +3854 -1692
- agno/tools/brightdata.py +3 -3
- agno/tools/cartesia.py +3 -5
- agno/tools/dalle.py +9 -8
- agno/tools/decorator.py +4 -2
- agno/tools/desi_vocal.py +2 -2
- agno/tools/duckduckgo.py +15 -11
- agno/tools/e2b.py +20 -13
- agno/tools/eleven_labs.py +26 -28
- agno/tools/exa.py +21 -16
- agno/tools/fal.py +4 -4
- agno/tools/file.py +153 -23
- agno/tools/file_generation.py +350 -0
- agno/tools/firecrawl.py +4 -4
- agno/tools/function.py +257 -37
- agno/tools/giphy.py +2 -2
- agno/tools/gmail.py +238 -14
- agno/tools/google_drive.py +270 -0
- agno/tools/googlecalendar.py +36 -8
- agno/tools/googlesheets.py +20 -5
- agno/tools/jira.py +20 -0
- agno/tools/knowledge.py +3 -3
- agno/tools/lumalab.py +3 -3
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +11 -17
- agno/tools/memori.py +1 -53
- agno/tools/memory.py +419 -0
- agno/tools/models/azure_openai.py +2 -2
- agno/tools/models/gemini.py +3 -3
- agno/tools/models/groq.py +3 -5
- agno/tools/models/nebius.py +7 -7
- agno/tools/models_labs.py +25 -15
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +4 -9
- agno/tools/opencv.py +3 -3
- agno/tools/parallel.py +314 -0
- agno/tools/replicate.py +7 -7
- agno/tools/scrapegraph.py +58 -31
- agno/tools/searxng.py +2 -2
- agno/tools/serper.py +2 -2
- agno/tools/slack.py +18 -3
- agno/tools/spider.py +2 -2
- agno/tools/tavily.py +146 -0
- agno/tools/whatsapp.py +1 -1
- agno/tools/workflow.py +278 -0
- agno/tools/yfinance.py +12 -11
- agno/utils/agent.py +820 -0
- agno/utils/audio.py +27 -0
- agno/utils/common.py +90 -1
- agno/utils/events.py +222 -7
- agno/utils/gemini.py +181 -23
- agno/utils/hooks.py +57 -0
- agno/utils/http.py +111 -0
- agno/utils/knowledge.py +12 -5
- agno/utils/log.py +1 -0
- agno/utils/mcp.py +95 -5
- agno/utils/media.py +188 -10
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +60 -0
- agno/utils/models/claude.py +40 -11
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/print_response/agent.py +105 -21
- agno/utils/print_response/team.py +103 -38
- agno/utils/print_response/workflow.py +251 -34
- agno/utils/reasoning.py +22 -1
- agno/utils/serialize.py +32 -0
- agno/utils/streamlit.py +16 -10
- agno/utils/string.py +41 -0
- agno/utils/team.py +98 -9
- agno/utils/tools.py +1 -1
- agno/vectordb/base.py +23 -4
- agno/vectordb/cassandra/cassandra.py +65 -9
- agno/vectordb/chroma/chromadb.py +182 -38
- agno/vectordb/clickhouse/clickhousedb.py +64 -11
- agno/vectordb/couchbase/couchbase.py +105 -10
- agno/vectordb/lancedb/lance_db.py +183 -135
- agno/vectordb/langchaindb/langchaindb.py +25 -7
- agno/vectordb/lightrag/lightrag.py +17 -3
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +46 -7
- agno/vectordb/milvus/milvus.py +126 -9
- agno/vectordb/mongodb/__init__.py +7 -1
- agno/vectordb/mongodb/mongodb.py +112 -7
- agno/vectordb/pgvector/pgvector.py +142 -21
- agno/vectordb/pineconedb/pineconedb.py +80 -8
- agno/vectordb/qdrant/qdrant.py +125 -39
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +694 -0
- agno/vectordb/singlestore/singlestore.py +111 -25
- agno/vectordb/surrealdb/surrealdb.py +31 -5
- agno/vectordb/upstashdb/upstashdb.py +76 -8
- agno/vectordb/weaviate/weaviate.py +86 -15
- agno/workflow/__init__.py +2 -0
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +112 -18
- agno/workflow/loop.py +69 -10
- agno/workflow/parallel.py +266 -118
- agno/workflow/router.py +110 -17
- agno/workflow/step.py +645 -136
- agno/workflow/steps.py +65 -6
- agno/workflow/types.py +71 -33
- agno/workflow/workflow.py +2113 -300
- agno-2.3.0.dist-info/METADATA +618 -0
- agno-2.3.0.dist-info/RECORD +577 -0
- agno-2.3.0.dist-info/licenses/LICENSE +201 -0
- agno/knowledge/reader/url_reader.py +0 -128
- agno/tools/googlesearch.py +0 -98
- agno/tools/mcp.py +0 -610
- agno/utils/models/aws_claude.py +0 -170
- agno-2.0.0rc2.dist-info/METADATA +0 -355
- agno-2.0.0rc2.dist-info/RECORD +0 -515
- agno-2.0.0rc2.dist-info/licenses/LICENSE +0 -375
- {agno-2.0.0rc2.dist-info → agno-2.3.0.dist-info}/WHEEL +0 -0
- {agno-2.0.0rc2.dist-info → agno-2.3.0.dist-info}/top_level.txt +0 -0
agno/memory/manager.py
CHANGED
|
@@ -7,12 +7,19 @@ from typing import Any, Callable, Dict, List, Literal, Optional, Type, Union
|
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field
|
|
9
9
|
|
|
10
|
-
from agno.db.base import BaseDb
|
|
10
|
+
from agno.db.base import AsyncBaseDb, BaseDb
|
|
11
11
|
from agno.db.schemas import UserMemory
|
|
12
12
|
from agno.models.base import Model
|
|
13
13
|
from agno.models.message import Message
|
|
14
|
+
from agno.models.utils import get_model
|
|
14
15
|
from agno.tools.function import Function
|
|
15
|
-
from agno.utils.log import
|
|
16
|
+
from agno.utils.log import (
|
|
17
|
+
log_debug,
|
|
18
|
+
log_error,
|
|
19
|
+
log_warning,
|
|
20
|
+
set_log_level_to_debug,
|
|
21
|
+
set_log_level_to_info,
|
|
22
|
+
)
|
|
16
23
|
from agno.utils.prompts import get_json_output_prompt
|
|
17
24
|
from agno.utils.string import parse_response_model_str
|
|
18
25
|
|
|
@@ -21,7 +28,8 @@ class MemorySearchResponse(BaseModel):
|
|
|
21
28
|
"""Model for Memory Search Response."""
|
|
22
29
|
|
|
23
30
|
memory_ids: List[str] = Field(
|
|
24
|
-
...,
|
|
31
|
+
...,
|
|
32
|
+
description="The IDs of the memories that are most semantically similar to the query.",
|
|
25
33
|
)
|
|
26
34
|
|
|
27
35
|
|
|
@@ -32,11 +40,11 @@ class MemoryManager:
|
|
|
32
40
|
# Model used for memory management
|
|
33
41
|
model: Optional[Model] = None
|
|
34
42
|
|
|
35
|
-
# Provide the system message for the manager as a string. If not provided,
|
|
43
|
+
# Provide the system message for the manager as a string. If not provided, the default system message will be used.
|
|
36
44
|
system_message: Optional[str] = None
|
|
37
|
-
# Provide the memory capture instructions for the manager as a string. If not provided,
|
|
45
|
+
# Provide the memory capture instructions for the manager as a string. If not provided, the default memory capture instructions will be used.
|
|
38
46
|
memory_capture_instructions: Optional[str] = None
|
|
39
|
-
# Additional instructions for the manager
|
|
47
|
+
# Additional instructions for the manager. These instructions are appended to the default system message.
|
|
40
48
|
additional_instructions: Optional[str] = None
|
|
41
49
|
|
|
42
50
|
# Whether memories were created in the last run
|
|
@@ -53,26 +61,24 @@ class MemoryManager:
|
|
|
53
61
|
add_memories: bool = True
|
|
54
62
|
|
|
55
63
|
# The database to store memories
|
|
56
|
-
db: Optional[BaseDb] = None
|
|
64
|
+
db: Optional[Union[BaseDb, AsyncBaseDb]] = None
|
|
57
65
|
|
|
58
66
|
debug_mode: bool = False
|
|
59
67
|
|
|
60
68
|
def __init__(
|
|
61
69
|
self,
|
|
62
|
-
model: Optional[Model] = None,
|
|
70
|
+
model: Optional[Union[Model, str]] = None,
|
|
63
71
|
system_message: Optional[str] = None,
|
|
64
72
|
memory_capture_instructions: Optional[str] = None,
|
|
65
73
|
additional_instructions: Optional[str] = None,
|
|
66
|
-
db: Optional[BaseDb] = None,
|
|
67
|
-
delete_memories: bool =
|
|
74
|
+
db: Optional[Union[BaseDb, AsyncBaseDb]] = None,
|
|
75
|
+
delete_memories: bool = False,
|
|
68
76
|
update_memories: bool = True,
|
|
69
77
|
add_memories: bool = True,
|
|
70
|
-
clear_memories: bool =
|
|
78
|
+
clear_memories: bool = False,
|
|
71
79
|
debug_mode: bool = False,
|
|
72
80
|
):
|
|
73
|
-
self.model = model
|
|
74
|
-
if self.model is not None and isinstance(self.model, str):
|
|
75
|
-
raise ValueError("Model must be a Model object, not a string")
|
|
81
|
+
self.model = model # type: ignore[assignment]
|
|
76
82
|
self.system_message = system_message
|
|
77
83
|
self.memory_capture_instructions = memory_capture_instructions
|
|
78
84
|
self.additional_instructions = additional_instructions
|
|
@@ -82,8 +88,12 @@ class MemoryManager:
|
|
|
82
88
|
self.add_memories = add_memories
|
|
83
89
|
self.clear_memories = clear_memories
|
|
84
90
|
self.debug_mode = debug_mode
|
|
85
|
-
|
|
86
|
-
self.
|
|
91
|
+
|
|
92
|
+
self._get_models()
|
|
93
|
+
|
|
94
|
+
def _get_models(self) -> None:
|
|
95
|
+
if self.model is not None:
|
|
96
|
+
self.model = get_model(self.model)
|
|
87
97
|
|
|
88
98
|
def get_model(self) -> Model:
|
|
89
99
|
if self.model is None:
|
|
@@ -114,6 +124,28 @@ class MemoryManager:
|
|
|
114
124
|
return memories
|
|
115
125
|
return None
|
|
116
126
|
|
|
127
|
+
async def aread_from_db(self, user_id: Optional[str] = None):
|
|
128
|
+
if self.db:
|
|
129
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
130
|
+
# If no user_id is provided, read all memories
|
|
131
|
+
if user_id is None:
|
|
132
|
+
all_memories: List[UserMemory] = await self.db.get_user_memories() # type: ignore
|
|
133
|
+
else:
|
|
134
|
+
all_memories = await self.db.get_user_memories(user_id=user_id) # type: ignore
|
|
135
|
+
else:
|
|
136
|
+
if user_id is None:
|
|
137
|
+
all_memories = self.db.get_user_memories() # type: ignore
|
|
138
|
+
else:
|
|
139
|
+
all_memories = self.db.get_user_memories(user_id=user_id) # type: ignore
|
|
140
|
+
|
|
141
|
+
memories: Dict[str, List[UserMemory]] = {}
|
|
142
|
+
for memory in all_memories:
|
|
143
|
+
if memory.user_id is not None and memory.memory_id is not None:
|
|
144
|
+
memories.setdefault(memory.user_id, []).append(memory)
|
|
145
|
+
|
|
146
|
+
return memories
|
|
147
|
+
return None
|
|
148
|
+
|
|
117
149
|
def set_log_level(self):
|
|
118
150
|
if self.debug_mode or getenv("AGNO_DEBUG", "false").lower() == "true":
|
|
119
151
|
self.debug_mode = True
|
|
@@ -139,6 +171,20 @@ class MemoryManager:
|
|
|
139
171
|
log_warning("Memory Db not provided.")
|
|
140
172
|
return []
|
|
141
173
|
|
|
174
|
+
async def aget_user_memories(self, user_id: Optional[str] = None) -> Optional[List[UserMemory]]:
|
|
175
|
+
"""Get the user memories for a given user id"""
|
|
176
|
+
if self.db:
|
|
177
|
+
if user_id is None:
|
|
178
|
+
user_id = "default"
|
|
179
|
+
# Refresh from the Db
|
|
180
|
+
memories = await self.aread_from_db(user_id=user_id)
|
|
181
|
+
if memories is None:
|
|
182
|
+
return []
|
|
183
|
+
return memories.get(user_id, [])
|
|
184
|
+
else:
|
|
185
|
+
log_warning("Memory Db not provided.")
|
|
186
|
+
return []
|
|
187
|
+
|
|
142
188
|
def get_user_memory(self, memory_id: str, user_id: Optional[str] = None) -> Optional[UserMemory]:
|
|
143
189
|
"""Get the user memory for a given user id"""
|
|
144
190
|
if self.db:
|
|
@@ -236,8 +282,11 @@ class MemoryManager:
|
|
|
236
282
|
memory_id (str): The id of the memory to delete
|
|
237
283
|
user_id (Optional[str]): The user id to delete the memory from. If not provided, the memory is deleted from the "default" user.
|
|
238
284
|
"""
|
|
285
|
+
if user_id is None:
|
|
286
|
+
user_id = "default"
|
|
287
|
+
|
|
239
288
|
if self.db:
|
|
240
|
-
self._delete_db_memory(memory_id=memory_id)
|
|
289
|
+
self._delete_db_memory(memory_id=memory_id, user_id=user_id)
|
|
241
290
|
else:
|
|
242
291
|
log_warning("Memory DB not provided.")
|
|
243
292
|
return None
|
|
@@ -258,6 +307,11 @@ class MemoryManager:
|
|
|
258
307
|
log_warning("MemoryDb not provided.")
|
|
259
308
|
return "Please provide a db to store memories"
|
|
260
309
|
|
|
310
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
311
|
+
raise ValueError(
|
|
312
|
+
"create_user_memories() is not supported with an async DB. Please use acreate_user_memories() instead."
|
|
313
|
+
)
|
|
314
|
+
|
|
261
315
|
if not messages and not message:
|
|
262
316
|
raise ValueError("You must provide either a message or a list of messages")
|
|
263
317
|
|
|
@@ -318,7 +372,10 @@ class MemoryManager:
|
|
|
318
372
|
if user_id is None:
|
|
319
373
|
user_id = "default"
|
|
320
374
|
|
|
321
|
-
|
|
375
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
376
|
+
memories = await self.aread_from_db(user_id=user_id)
|
|
377
|
+
else:
|
|
378
|
+
memories = self.read_from_db(user_id=user_id)
|
|
322
379
|
if memories is None:
|
|
323
380
|
memories = {}
|
|
324
381
|
|
|
@@ -337,7 +394,10 @@ class MemoryManager:
|
|
|
337
394
|
)
|
|
338
395
|
|
|
339
396
|
# We refresh from the DB
|
|
340
|
-
self.
|
|
397
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
398
|
+
memories = await self.aread_from_db(user_id=user_id)
|
|
399
|
+
else:
|
|
400
|
+
memories = self.read_from_db(user_id=user_id)
|
|
341
401
|
|
|
342
402
|
return response
|
|
343
403
|
|
|
@@ -348,6 +408,11 @@ class MemoryManager:
|
|
|
348
408
|
log_warning("MemoryDb not provided.")
|
|
349
409
|
return "Please provide a db to store memories"
|
|
350
410
|
|
|
411
|
+
if not isinstance(self.db, BaseDb):
|
|
412
|
+
raise ValueError(
|
|
413
|
+
"update_memory_task() is not supported with an async DB. Please use aupdate_memory_task() instead."
|
|
414
|
+
)
|
|
415
|
+
|
|
351
416
|
if user_id is None:
|
|
352
417
|
user_id = "default"
|
|
353
418
|
|
|
@@ -385,7 +450,11 @@ class MemoryManager:
|
|
|
385
450
|
if user_id is None:
|
|
386
451
|
user_id = "default"
|
|
387
452
|
|
|
388
|
-
|
|
453
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
454
|
+
memories = await self.aread_from_db(user_id=user_id)
|
|
455
|
+
else:
|
|
456
|
+
memories = self.read_from_db(user_id=user_id)
|
|
457
|
+
|
|
389
458
|
if memories is None:
|
|
390
459
|
memories = {}
|
|
391
460
|
|
|
@@ -404,7 +473,10 @@ class MemoryManager:
|
|
|
404
473
|
)
|
|
405
474
|
|
|
406
475
|
# We refresh from the DB
|
|
407
|
-
self.
|
|
476
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
477
|
+
await self.aread_from_db(user_id=user_id)
|
|
478
|
+
else:
|
|
479
|
+
self.read_from_db(user_id=user_id)
|
|
408
480
|
|
|
409
481
|
return response
|
|
410
482
|
|
|
@@ -420,12 +492,16 @@ class MemoryManager:
|
|
|
420
492
|
log_warning(f"Error storing memory in db: {e}")
|
|
421
493
|
return f"Error adding memory: {e}"
|
|
422
494
|
|
|
423
|
-
def _delete_db_memory(self, memory_id: str) -> str:
|
|
495
|
+
def _delete_db_memory(self, memory_id: str, user_id: Optional[str] = None) -> str:
|
|
424
496
|
"""Use this function to delete a memory from the database."""
|
|
425
497
|
try:
|
|
426
498
|
if not self.db:
|
|
427
499
|
raise ValueError("Memory db not initialized")
|
|
428
|
-
|
|
500
|
+
|
|
501
|
+
if user_id is None:
|
|
502
|
+
user_id = "default"
|
|
503
|
+
|
|
504
|
+
self.db.delete_user_memory(memory_id=memory_id, user_id=user_id)
|
|
429
505
|
return "Memory deleted successfully"
|
|
430
506
|
except Exception as e:
|
|
431
507
|
log_warning(f"Error deleting memory in db: {e}")
|
|
@@ -637,23 +713,26 @@ class MemoryManager:
|
|
|
637
713
|
return sorted_memories_list
|
|
638
714
|
|
|
639
715
|
# --Memory Manager Functions--
|
|
640
|
-
def determine_tools_for_model(self, tools: List[Callable]) ->
|
|
716
|
+
def determine_tools_for_model(self, tools: List[Callable]) -> List[Union[Function, dict]]:
|
|
641
717
|
# Have to reset each time, because of different user IDs
|
|
642
|
-
|
|
643
|
-
|
|
718
|
+
_function_names = []
|
|
719
|
+
_functions: List[Union[Function, dict]] = []
|
|
644
720
|
|
|
645
721
|
for tool in tools:
|
|
646
722
|
try:
|
|
647
723
|
function_name = tool.__name__
|
|
648
|
-
if function_name
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
724
|
+
if function_name in _function_names:
|
|
725
|
+
continue
|
|
726
|
+
_function_names.append(function_name)
|
|
727
|
+
func = Function.from_callable(tool, strict=True) # type: ignore
|
|
728
|
+
func.strict = True
|
|
729
|
+
_functions.append(func)
|
|
730
|
+
log_debug(f"Added function {func.name}")
|
|
654
731
|
except Exception as e:
|
|
655
732
|
log_warning(f"Could not add function {tool}: {e}")
|
|
656
733
|
|
|
734
|
+
return _functions
|
|
735
|
+
|
|
657
736
|
def get_system_message(
|
|
658
737
|
self,
|
|
659
738
|
existing_memories: Optional[List[Dict[str, Any]]] = None,
|
|
@@ -665,18 +744,20 @@ class MemoryManager:
|
|
|
665
744
|
if self.system_message is not None:
|
|
666
745
|
return Message(role="system", content=self.system_message)
|
|
667
746
|
|
|
668
|
-
memory_capture_instructions = self.memory_capture_instructions or dedent(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
747
|
+
memory_capture_instructions = self.memory_capture_instructions or dedent(
|
|
748
|
+
"""\
|
|
749
|
+
Memories should capture personal information about the user that is relevant to the current conversation, such as:
|
|
750
|
+
- Personal facts: name, age, occupation, location, interests, and preferences
|
|
751
|
+
- Opinions and preferences: what the user likes, dislikes, enjoys, or finds frustrating
|
|
752
|
+
- Significant life events or experiences shared by the user
|
|
753
|
+
- Important context about the user's current situation, challenges, or goals
|
|
754
|
+
- Any other details that offer meaningful insight into the user's personality, perspective, or needs
|
|
755
|
+
"""
|
|
756
|
+
)
|
|
676
757
|
|
|
677
758
|
# -*- Return a system message for the memory manager
|
|
678
759
|
system_prompt_lines = [
|
|
679
|
-
"You are a
|
|
760
|
+
"You are a Memory Manager that is responsible for managing information and preferences about the user. "
|
|
680
761
|
"You will be provided with a criteria for memories to capture in the <memories_to_capture> section and a list of existing memories in the <existing_memories> section.",
|
|
681
762
|
"",
|
|
682
763
|
"## When to add or update memories",
|
|
@@ -705,16 +786,16 @@ class MemoryManager:
|
|
|
705
786
|
"",
|
|
706
787
|
"## Updating memories",
|
|
707
788
|
"You will also be provided with a list of existing memories in the <existing_memories> section. You can:",
|
|
708
|
-
"
|
|
789
|
+
" - Decide to make no changes.",
|
|
709
790
|
]
|
|
710
791
|
if enable_add_memory:
|
|
711
|
-
system_prompt_lines.append("
|
|
792
|
+
system_prompt_lines.append(" - Decide to add a new memory, using the `add_memory` tool.")
|
|
712
793
|
if enable_update_memory:
|
|
713
|
-
system_prompt_lines.append("
|
|
794
|
+
system_prompt_lines.append(" - Decide to update an existing memory, using the `update_memory` tool.")
|
|
714
795
|
if enable_delete_memory:
|
|
715
|
-
system_prompt_lines.append("
|
|
796
|
+
system_prompt_lines.append(" - Decide to delete an existing memory, using the `delete_memory` tool.")
|
|
716
797
|
if enable_clear_memory:
|
|
717
|
-
system_prompt_lines.append("
|
|
798
|
+
system_prompt_lines.append(" - Decide to clear all memories, using the `clear_memory` tool.")
|
|
718
799
|
|
|
719
800
|
system_prompt_lines += [
|
|
720
801
|
"You can call multiple tools in a single response if needed. ",
|
|
@@ -758,7 +839,7 @@ class MemoryManager:
|
|
|
758
839
|
|
|
759
840
|
model_copy = deepcopy(self.model)
|
|
760
841
|
# Update the Model (set defaults, add logit etc.)
|
|
761
|
-
self.determine_tools_for_model(
|
|
842
|
+
_tools = self.determine_tools_for_model(
|
|
762
843
|
self._get_db_tools(
|
|
763
844
|
user_id,
|
|
764
845
|
db,
|
|
@@ -767,7 +848,7 @@ class MemoryManager:
|
|
|
767
848
|
team_id=team_id,
|
|
768
849
|
enable_add_memory=add_memories,
|
|
769
850
|
enable_update_memory=update_memories,
|
|
770
|
-
enable_delete_memory=
|
|
851
|
+
enable_delete_memory=True,
|
|
771
852
|
enable_clear_memory=False,
|
|
772
853
|
),
|
|
773
854
|
)
|
|
@@ -778,7 +859,7 @@ class MemoryManager:
|
|
|
778
859
|
existing_memories=existing_memories,
|
|
779
860
|
enable_update_memory=update_memories,
|
|
780
861
|
enable_add_memory=add_memories,
|
|
781
|
-
enable_delete_memory=
|
|
862
|
+
enable_delete_memory=True,
|
|
782
863
|
enable_clear_memory=False,
|
|
783
864
|
),
|
|
784
865
|
*messages,
|
|
@@ -786,7 +867,8 @@ class MemoryManager:
|
|
|
786
867
|
|
|
787
868
|
# Generate a response from the Model (includes running function calls)
|
|
788
869
|
response = model_copy.response(
|
|
789
|
-
messages=messages_for_model,
|
|
870
|
+
messages=messages_for_model,
|
|
871
|
+
tools=_tools,
|
|
790
872
|
)
|
|
791
873
|
|
|
792
874
|
if response.tool_calls is not None and len(response.tool_calls) > 0:
|
|
@@ -800,7 +882,7 @@ class MemoryManager:
|
|
|
800
882
|
messages: List[Message],
|
|
801
883
|
existing_memories: List[Dict[str, Any]],
|
|
802
884
|
user_id: str,
|
|
803
|
-
db: BaseDb,
|
|
885
|
+
db: Union[BaseDb, AsyncBaseDb],
|
|
804
886
|
agent_id: Optional[str] = None,
|
|
805
887
|
team_id: Optional[str] = None,
|
|
806
888
|
update_memories: bool = True,
|
|
@@ -819,19 +901,34 @@ class MemoryManager:
|
|
|
819
901
|
|
|
820
902
|
model_copy = deepcopy(self.model)
|
|
821
903
|
# Update the Model (set defaults, add logit etc.)
|
|
822
|
-
|
|
823
|
-
self.
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
904
|
+
if isinstance(db, AsyncBaseDb):
|
|
905
|
+
_tools = self.determine_tools_for_model(
|
|
906
|
+
await self._aget_db_tools(
|
|
907
|
+
user_id,
|
|
908
|
+
db,
|
|
909
|
+
input_string,
|
|
910
|
+
agent_id=agent_id,
|
|
911
|
+
team_id=team_id,
|
|
912
|
+
enable_add_memory=add_memories,
|
|
913
|
+
enable_update_memory=update_memories,
|
|
914
|
+
enable_delete_memory=True,
|
|
915
|
+
enable_clear_memory=False,
|
|
916
|
+
),
|
|
917
|
+
)
|
|
918
|
+
else:
|
|
919
|
+
_tools = self.determine_tools_for_model(
|
|
920
|
+
self._get_db_tools(
|
|
921
|
+
user_id,
|
|
922
|
+
db,
|
|
923
|
+
input_string,
|
|
924
|
+
agent_id=agent_id,
|
|
925
|
+
team_id=team_id,
|
|
926
|
+
enable_add_memory=add_memories,
|
|
927
|
+
enable_update_memory=update_memories,
|
|
928
|
+
enable_delete_memory=True,
|
|
929
|
+
enable_clear_memory=False,
|
|
930
|
+
),
|
|
931
|
+
)
|
|
835
932
|
|
|
836
933
|
# Prepare the List of messages to send to the Model
|
|
837
934
|
messages_for_model: List[Message] = [
|
|
@@ -839,7 +936,7 @@ class MemoryManager:
|
|
|
839
936
|
existing_memories=existing_memories,
|
|
840
937
|
enable_update_memory=update_memories,
|
|
841
938
|
enable_add_memory=add_memories,
|
|
842
|
-
enable_delete_memory=
|
|
939
|
+
enable_delete_memory=True,
|
|
843
940
|
enable_clear_memory=False,
|
|
844
941
|
),
|
|
845
942
|
*messages,
|
|
@@ -847,7 +944,8 @@ class MemoryManager:
|
|
|
847
944
|
|
|
848
945
|
# Generate a response from the Model (includes running function calls)
|
|
849
946
|
response = await model_copy.aresponse(
|
|
850
|
-
messages=messages_for_model,
|
|
947
|
+
messages=messages_for_model,
|
|
948
|
+
tools=_tools,
|
|
851
949
|
)
|
|
852
950
|
|
|
853
951
|
if response.tool_calls is not None and len(response.tool_calls) > 0:
|
|
@@ -875,7 +973,7 @@ class MemoryManager:
|
|
|
875
973
|
|
|
876
974
|
model_copy = deepcopy(self.model)
|
|
877
975
|
# Update the Model (set defaults, add logit etc.)
|
|
878
|
-
self.determine_tools_for_model(
|
|
976
|
+
_tools = self.determine_tools_for_model(
|
|
879
977
|
self._get_db_tools(
|
|
880
978
|
user_id,
|
|
881
979
|
db,
|
|
@@ -902,7 +1000,8 @@ class MemoryManager:
|
|
|
902
1000
|
|
|
903
1001
|
# Generate a response from the Model (includes running function calls)
|
|
904
1002
|
response = model_copy.response(
|
|
905
|
-
messages=messages_for_model,
|
|
1003
|
+
messages=messages_for_model,
|
|
1004
|
+
tools=_tools,
|
|
906
1005
|
)
|
|
907
1006
|
|
|
908
1007
|
if response.tool_calls is not None and len(response.tool_calls) > 0:
|
|
@@ -916,7 +1015,7 @@ class MemoryManager:
|
|
|
916
1015
|
task: str,
|
|
917
1016
|
existing_memories: List[Dict[str, Any]],
|
|
918
1017
|
user_id: str,
|
|
919
|
-
db: BaseDb,
|
|
1018
|
+
db: Union[BaseDb, AsyncBaseDb],
|
|
920
1019
|
delete_memories: bool = True,
|
|
921
1020
|
clear_memories: bool = True,
|
|
922
1021
|
update_memories: bool = True,
|
|
@@ -930,17 +1029,30 @@ class MemoryManager:
|
|
|
930
1029
|
|
|
931
1030
|
model_copy = deepcopy(self.model)
|
|
932
1031
|
# Update the Model (set defaults, add logit etc.)
|
|
933
|
-
|
|
934
|
-
self.
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1032
|
+
if isinstance(db, AsyncBaseDb):
|
|
1033
|
+
_tools = self.determine_tools_for_model(
|
|
1034
|
+
await self._aget_db_tools(
|
|
1035
|
+
user_id,
|
|
1036
|
+
db,
|
|
1037
|
+
task,
|
|
1038
|
+
enable_delete_memory=delete_memories,
|
|
1039
|
+
enable_clear_memory=clear_memories,
|
|
1040
|
+
enable_update_memory=update_memories,
|
|
1041
|
+
enable_add_memory=add_memories,
|
|
1042
|
+
),
|
|
1043
|
+
)
|
|
1044
|
+
else:
|
|
1045
|
+
_tools = self.determine_tools_for_model(
|
|
1046
|
+
self._get_db_tools(
|
|
1047
|
+
user_id,
|
|
1048
|
+
db,
|
|
1049
|
+
task,
|
|
1050
|
+
enable_delete_memory=delete_memories,
|
|
1051
|
+
enable_clear_memory=clear_memories,
|
|
1052
|
+
enable_update_memory=update_memories,
|
|
1053
|
+
enable_add_memory=add_memories,
|
|
1054
|
+
),
|
|
1055
|
+
)
|
|
944
1056
|
|
|
945
1057
|
# Prepare the List of messages to send to the Model
|
|
946
1058
|
messages_for_model: List[Message] = [
|
|
@@ -957,7 +1069,8 @@ class MemoryManager:
|
|
|
957
1069
|
|
|
958
1070
|
# Generate a response from the Model (includes running function calls)
|
|
959
1071
|
response = await model_copy.aresponse(
|
|
960
|
-
messages=messages_for_model,
|
|
1072
|
+
messages=messages_for_model,
|
|
1073
|
+
tools=_tools,
|
|
961
1074
|
)
|
|
962
1075
|
|
|
963
1076
|
if response.tool_calls is not None and len(response.tool_calls) > 0:
|
|
@@ -1021,12 +1134,16 @@ class MemoryManager:
|
|
|
1021
1134
|
"""
|
|
1022
1135
|
from agno.db.base import UserMemory
|
|
1023
1136
|
|
|
1137
|
+
if memory == "":
|
|
1138
|
+
return "Can't update memory with empty string. Use the delete memory function if available."
|
|
1139
|
+
|
|
1024
1140
|
try:
|
|
1025
1141
|
db.upsert_user_memory(
|
|
1026
1142
|
UserMemory(
|
|
1027
1143
|
memory_id=memory_id,
|
|
1028
1144
|
memory=memory,
|
|
1029
1145
|
topics=topics,
|
|
1146
|
+
user_id=user_id,
|
|
1030
1147
|
input=input_string,
|
|
1031
1148
|
)
|
|
1032
1149
|
)
|
|
@@ -1044,7 +1161,7 @@ class MemoryManager:
|
|
|
1044
1161
|
str: A message indicating if the memory was deleted successfully or not.
|
|
1045
1162
|
"""
|
|
1046
1163
|
try:
|
|
1047
|
-
db.delete_user_memory(memory_id=memory_id)
|
|
1164
|
+
db.delete_user_memory(memory_id=memory_id, user_id=user_id)
|
|
1048
1165
|
log_debug("Memory deleted")
|
|
1049
1166
|
return "Memory deleted successfully"
|
|
1050
1167
|
except Exception as e:
|
|
@@ -1071,3 +1188,140 @@ class MemoryManager:
|
|
|
1071
1188
|
if enable_clear_memory:
|
|
1072
1189
|
functions.append(clear_memory)
|
|
1073
1190
|
return functions
|
|
1191
|
+
|
|
1192
|
+
async def _aget_db_tools(
|
|
1193
|
+
self,
|
|
1194
|
+
user_id: str,
|
|
1195
|
+
db: Union[BaseDb, AsyncBaseDb],
|
|
1196
|
+
input_string: str,
|
|
1197
|
+
enable_add_memory: bool = True,
|
|
1198
|
+
enable_update_memory: bool = True,
|
|
1199
|
+
enable_delete_memory: bool = True,
|
|
1200
|
+
enable_clear_memory: bool = True,
|
|
1201
|
+
agent_id: Optional[str] = None,
|
|
1202
|
+
team_id: Optional[str] = None,
|
|
1203
|
+
) -> List[Callable]:
|
|
1204
|
+
async def add_memory(memory: str, topics: Optional[List[str]] = None) -> str:
|
|
1205
|
+
"""Use this function to add a memory to the database.
|
|
1206
|
+
Args:
|
|
1207
|
+
memory (str): The memory to be added.
|
|
1208
|
+
topics (Optional[List[str]]): The topics of the memory (e.g. ["name", "hobbies", "location"]).
|
|
1209
|
+
Returns:
|
|
1210
|
+
str: A message indicating if the memory was added successfully or not.
|
|
1211
|
+
"""
|
|
1212
|
+
from uuid import uuid4
|
|
1213
|
+
|
|
1214
|
+
from agno.db.base import UserMemory
|
|
1215
|
+
|
|
1216
|
+
try:
|
|
1217
|
+
memory_id = str(uuid4())
|
|
1218
|
+
if isinstance(db, AsyncBaseDb):
|
|
1219
|
+
await db.upsert_user_memory(
|
|
1220
|
+
UserMemory(
|
|
1221
|
+
memory_id=memory_id,
|
|
1222
|
+
user_id=user_id,
|
|
1223
|
+
agent_id=agent_id,
|
|
1224
|
+
team_id=team_id,
|
|
1225
|
+
memory=memory,
|
|
1226
|
+
topics=topics,
|
|
1227
|
+
input=input_string,
|
|
1228
|
+
)
|
|
1229
|
+
)
|
|
1230
|
+
else:
|
|
1231
|
+
db.upsert_user_memory(
|
|
1232
|
+
UserMemory(
|
|
1233
|
+
memory_id=memory_id,
|
|
1234
|
+
user_id=user_id,
|
|
1235
|
+
agent_id=agent_id,
|
|
1236
|
+
team_id=team_id,
|
|
1237
|
+
memory=memory,
|
|
1238
|
+
topics=topics,
|
|
1239
|
+
input=input_string,
|
|
1240
|
+
)
|
|
1241
|
+
)
|
|
1242
|
+
log_debug(f"Memory added: {memory_id}")
|
|
1243
|
+
return "Memory added successfully"
|
|
1244
|
+
except Exception as e:
|
|
1245
|
+
log_warning(f"Error storing memory in db: {e}")
|
|
1246
|
+
return f"Error adding memory: {e}"
|
|
1247
|
+
|
|
1248
|
+
async def update_memory(memory_id: str, memory: str, topics: Optional[List[str]] = None) -> str:
|
|
1249
|
+
"""Use this function to update an existing memory in the database.
|
|
1250
|
+
Args:
|
|
1251
|
+
memory_id (str): The id of the memory to be updated.
|
|
1252
|
+
memory (str): The updated memory.
|
|
1253
|
+
topics (Optional[List[str]]): The topics of the memory (e.g. ["name", "hobbies", "location"]).
|
|
1254
|
+
Returns:
|
|
1255
|
+
str: A message indicating if the memory was updated successfully or not.
|
|
1256
|
+
"""
|
|
1257
|
+
from agno.db.base import UserMemory
|
|
1258
|
+
|
|
1259
|
+
if memory == "":
|
|
1260
|
+
return "Can't update memory with empty string. Use the delete memory function if available."
|
|
1261
|
+
|
|
1262
|
+
try:
|
|
1263
|
+
if isinstance(db, AsyncBaseDb):
|
|
1264
|
+
await db.upsert_user_memory(
|
|
1265
|
+
UserMemory(
|
|
1266
|
+
memory_id=memory_id,
|
|
1267
|
+
memory=memory,
|
|
1268
|
+
topics=topics,
|
|
1269
|
+
input=input_string,
|
|
1270
|
+
)
|
|
1271
|
+
)
|
|
1272
|
+
else:
|
|
1273
|
+
db.upsert_user_memory(
|
|
1274
|
+
UserMemory(
|
|
1275
|
+
memory_id=memory_id,
|
|
1276
|
+
memory=memory,
|
|
1277
|
+
topics=topics,
|
|
1278
|
+
input=input_string,
|
|
1279
|
+
)
|
|
1280
|
+
)
|
|
1281
|
+
log_debug("Memory updated")
|
|
1282
|
+
return "Memory updated successfully"
|
|
1283
|
+
except Exception as e:
|
|
1284
|
+
log_warning(f"Error storing memory in db: {e}")
|
|
1285
|
+
return f"Error adding memory: {e}"
|
|
1286
|
+
|
|
1287
|
+
async def delete_memory(memory_id: str) -> str:
|
|
1288
|
+
"""Use this function to delete a single memory from the database.
|
|
1289
|
+
Args:
|
|
1290
|
+
memory_id (str): The id of the memory to be deleted.
|
|
1291
|
+
Returns:
|
|
1292
|
+
str: A message indicating if the memory was deleted successfully or not.
|
|
1293
|
+
"""
|
|
1294
|
+
try:
|
|
1295
|
+
if isinstance(db, AsyncBaseDb):
|
|
1296
|
+
await db.delete_user_memory(memory_id=memory_id)
|
|
1297
|
+
else:
|
|
1298
|
+
db.delete_user_memory(memory_id=memory_id)
|
|
1299
|
+
log_debug("Memory deleted")
|
|
1300
|
+
return "Memory deleted successfully"
|
|
1301
|
+
except Exception as e:
|
|
1302
|
+
log_warning(f"Error deleting memory in db: {e}")
|
|
1303
|
+
return f"Error deleting memory: {e}"
|
|
1304
|
+
|
|
1305
|
+
async def clear_memory() -> str:
|
|
1306
|
+
"""Use this function to remove all (or clear all) memories from the database.
|
|
1307
|
+
|
|
1308
|
+
Returns:
|
|
1309
|
+
str: A message indicating if the memory was cleared successfully or not.
|
|
1310
|
+
"""
|
|
1311
|
+
if isinstance(db, AsyncBaseDb):
|
|
1312
|
+
await db.clear_memories()
|
|
1313
|
+
else:
|
|
1314
|
+
db.clear_memories()
|
|
1315
|
+
log_debug("Memory cleared")
|
|
1316
|
+
return "Memory cleared successfully"
|
|
1317
|
+
|
|
1318
|
+
functions: List[Callable] = []
|
|
1319
|
+
if enable_add_memory:
|
|
1320
|
+
functions.append(add_memory)
|
|
1321
|
+
if enable_update_memory:
|
|
1322
|
+
functions.append(update_memory)
|
|
1323
|
+
if enable_delete_memory:
|
|
1324
|
+
functions.append(delete_memory)
|
|
1325
|
+
if enable_clear_memory:
|
|
1326
|
+
functions.append(clear_memory)
|
|
1327
|
+
return functions
|