agno 2.0.1__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 +6015 -2823
- 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 +594 -186
- 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 +2 -8
- agno/knowledge/types.py +9 -0
- agno/knowledge/utils.py +20 -0
- agno/media.py +72 -0
- 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 +999 -519
- 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 +103 -31
- 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 +139 -0
- 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 +59 -5
- agno/models/openai/chat.py +69 -29
- 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 +77 -1
- 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 -178
- 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 +248 -94
- agno/run/base.py +44 -5
- agno/run/team.py +238 -97
- agno/run/workflow.py +144 -33
- 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 -1610
- agno/tools/dalle.py +2 -4
- agno/tools/decorator.py +4 -2
- agno/tools/duckduckgo.py +15 -11
- agno/tools/e2b.py +14 -7
- agno/tools/eleven_labs.py +23 -25
- agno/tools/exa.py +21 -16
- agno/tools/file.py +153 -23
- agno/tools/file_generation.py +350 -0
- agno/tools/firecrawl.py +4 -4
- agno/tools/function.py +250 -30
- 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/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/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/notion.py +204 -0
- agno/tools/parallel.py +314 -0
- 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 +217 -2
- agno/utils/gemini.py +180 -22
- 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 +92 -2
- 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/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 +124 -133
- 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 +638 -129
- agno/workflow/steps.py +65 -6
- agno/workflow/types.py +61 -23
- agno/workflow/workflow.py +2085 -272
- {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/METADATA +182 -58
- agno-2.3.0.dist-info/RECORD +577 -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.1.dist-info/RECORD +0 -515
- {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/WHEEL +0 -0
- {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.1.dist-info → agno-2.3.0.dist-info}/top_level.txt +0 -0
agno/tools/mem0.py
CHANGED
|
@@ -2,7 +2,6 @@ import json
|
|
|
2
2
|
from os import getenv
|
|
3
3
|
from typing import Any, Dict, List, Optional, Union
|
|
4
4
|
|
|
5
|
-
from agno.agent import Agent
|
|
6
5
|
from agno.tools import Toolkit
|
|
7
6
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
8
7
|
|
|
@@ -69,15 +68,13 @@ class Mem0Tools(Toolkit):
|
|
|
69
68
|
def _get_user_id(
|
|
70
69
|
self,
|
|
71
70
|
method_name: str,
|
|
72
|
-
|
|
71
|
+
session_state: Dict[str, Any],
|
|
73
72
|
) -> str:
|
|
74
73
|
"""Resolve the user ID"""
|
|
75
74
|
resolved_user_id = self.user_id
|
|
76
|
-
if not resolved_user_id
|
|
75
|
+
if not resolved_user_id:
|
|
77
76
|
try:
|
|
78
|
-
|
|
79
|
-
if isinstance(session_state, dict):
|
|
80
|
-
resolved_user_id = session_state.get("current_user_id")
|
|
77
|
+
resolved_user_id = session_state.get("current_user_id")
|
|
81
78
|
except Exception:
|
|
82
79
|
pass
|
|
83
80
|
if not resolved_user_id:
|
|
@@ -88,7 +85,7 @@ class Mem0Tools(Toolkit):
|
|
|
88
85
|
|
|
89
86
|
def add_memory(
|
|
90
87
|
self,
|
|
91
|
-
|
|
88
|
+
session_state,
|
|
92
89
|
content: Union[str, Dict[str, str]],
|
|
93
90
|
) -> str:
|
|
94
91
|
"""Add facts to the user's memory.
|
|
@@ -101,7 +98,7 @@ class Mem0Tools(Toolkit):
|
|
|
101
98
|
str: JSON-encoded Mem0 response or an error message.
|
|
102
99
|
"""
|
|
103
100
|
|
|
104
|
-
resolved_user_id = self._get_user_id("add_memory",
|
|
101
|
+
resolved_user_id = self._get_user_id("add_memory", session_state=session_state)
|
|
105
102
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in add_memory:"):
|
|
106
103
|
return resolved_user_id
|
|
107
104
|
try:
|
|
@@ -116,7 +113,6 @@ class Mem0Tools(Toolkit):
|
|
|
116
113
|
messages_list,
|
|
117
114
|
user_id=resolved_user_id,
|
|
118
115
|
infer=self.infer,
|
|
119
|
-
output_format="v1.1",
|
|
120
116
|
)
|
|
121
117
|
return json.dumps(result)
|
|
122
118
|
except Exception as e:
|
|
@@ -125,19 +121,18 @@ class Mem0Tools(Toolkit):
|
|
|
125
121
|
|
|
126
122
|
def search_memory(
|
|
127
123
|
self,
|
|
128
|
-
|
|
124
|
+
session_state: Dict[str, Any],
|
|
129
125
|
query: str,
|
|
130
126
|
) -> str:
|
|
131
127
|
"""Semantic search for *query* across the user's stored memories."""
|
|
132
128
|
|
|
133
|
-
resolved_user_id = self._get_user_id("search_memory",
|
|
129
|
+
resolved_user_id = self._get_user_id("search_memory", session_state=session_state)
|
|
134
130
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in search_memory:"):
|
|
135
131
|
return resolved_user_id
|
|
136
132
|
try:
|
|
137
133
|
results = self.client.search(
|
|
138
134
|
query=query,
|
|
139
135
|
user_id=resolved_user_id,
|
|
140
|
-
output_format="v1.1",
|
|
141
136
|
)
|
|
142
137
|
|
|
143
138
|
if isinstance(results, dict) and "results" in results:
|
|
@@ -156,16 +151,15 @@ class Mem0Tools(Toolkit):
|
|
|
156
151
|
log_error(f"Error searching memory: {e}")
|
|
157
152
|
return f"Error searching memory: {e}"
|
|
158
153
|
|
|
159
|
-
def get_all_memories(self,
|
|
154
|
+
def get_all_memories(self, session_state: Dict[str, Any]) -> str:
|
|
160
155
|
"""Return **all** memories for the current user as a JSON string."""
|
|
161
156
|
|
|
162
|
-
resolved_user_id = self._get_user_id("get_all_memories",
|
|
157
|
+
resolved_user_id = self._get_user_id("get_all_memories", session_state=session_state)
|
|
163
158
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in get_all_memories:"):
|
|
164
159
|
return resolved_user_id
|
|
165
160
|
try:
|
|
166
161
|
results = self.client.get_all(
|
|
167
162
|
user_id=resolved_user_id,
|
|
168
|
-
output_format="v1.1",
|
|
169
163
|
)
|
|
170
164
|
|
|
171
165
|
if isinstance(results, dict) and "results" in results:
|
|
@@ -183,10 +177,10 @@ class Mem0Tools(Toolkit):
|
|
|
183
177
|
log_error(f"Error getting all memories: {e}")
|
|
184
178
|
return f"Error getting all memories: {e}"
|
|
185
179
|
|
|
186
|
-
def delete_all_memories(self,
|
|
180
|
+
def delete_all_memories(self, session_state: Dict[str, Any]) -> str:
|
|
187
181
|
"""Delete *all* memories associated with the current user"""
|
|
188
182
|
|
|
189
|
-
resolved_user_id = self._get_user_id("delete_all_memories",
|
|
183
|
+
resolved_user_id = self._get_user_id("delete_all_memories", session_state=session_state)
|
|
190
184
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in delete_all_memories:"):
|
|
191
185
|
error_msg = resolved_user_id
|
|
192
186
|
log_error(error_msg)
|
agno/tools/memori.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from typing import Any, Dict, List, Optional
|
|
3
3
|
|
|
4
|
-
from agno.agent import Agent
|
|
5
4
|
from agno.tools.toolkit import Toolkit
|
|
6
5
|
from agno.utils.log import log_debug, log_error, log_info, log_warning
|
|
7
6
|
|
|
@@ -122,7 +121,6 @@ class MemoriTools(Toolkit):
|
|
|
122
121
|
|
|
123
122
|
def search_memory(
|
|
124
123
|
self,
|
|
125
|
-
agent: Agent,
|
|
126
124
|
query: str,
|
|
127
125
|
limit: Optional[int] = None,
|
|
128
126
|
) -> str:
|
|
@@ -180,7 +178,7 @@ class MemoriTools(Toolkit):
|
|
|
180
178
|
log_error(f"Error searching memory: {e}")
|
|
181
179
|
return json.dumps({"success": False, "error": f"Memory search error: {str(e)}"})
|
|
182
180
|
|
|
183
|
-
def record_conversation(self,
|
|
181
|
+
def record_conversation(self, content: str) -> str:
|
|
184
182
|
"""
|
|
185
183
|
Add important information or facts to memory.
|
|
186
184
|
|
|
@@ -222,7 +220,6 @@ class MemoriTools(Toolkit):
|
|
|
222
220
|
|
|
223
221
|
def get_memory_stats(
|
|
224
222
|
self,
|
|
225
|
-
agent: Agent,
|
|
226
223
|
) -> str:
|
|
227
224
|
"""
|
|
228
225
|
Get statistics about the memory system.
|
|
@@ -340,52 +337,3 @@ class MemoriTools(Toolkit):
|
|
|
340
337
|
except Exception as e:
|
|
341
338
|
log_error(f"Failed to disable memory system: {e}")
|
|
342
339
|
return False
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
def create_memori_search_tool(memori_toolkit: MemoriTools):
|
|
346
|
-
"""
|
|
347
|
-
Create a standalone memory search function for use with Agno agents.
|
|
348
|
-
|
|
349
|
-
This is a convenience function that creates a memory search tool similar
|
|
350
|
-
to the pattern shown in the Memori example code.
|
|
351
|
-
|
|
352
|
-
Args:
|
|
353
|
-
memori_toolkit: An initialized MemoriTools instance
|
|
354
|
-
|
|
355
|
-
Returns:
|
|
356
|
-
Callable: A memory search function that can be used as an agent tool
|
|
357
|
-
|
|
358
|
-
Example:
|
|
359
|
-
```python
|
|
360
|
-
memori_tools = MemoriTools(database_connect="sqlite:///memory.db")
|
|
361
|
-
search_tool = create_memori_search_tool(memori_tools)
|
|
362
|
-
|
|
363
|
-
agent = Agent(
|
|
364
|
-
model=OpenAIChat(),
|
|
365
|
-
tools=[search_tool],
|
|
366
|
-
description="Agent with memory search capability"
|
|
367
|
-
)
|
|
368
|
-
```
|
|
369
|
-
"""
|
|
370
|
-
|
|
371
|
-
def search_memory(query: str) -> str:
|
|
372
|
-
"""
|
|
373
|
-
Search the agent's memory for past conversations and information.
|
|
374
|
-
|
|
375
|
-
Args:
|
|
376
|
-
query: What to search for in memory
|
|
377
|
-
|
|
378
|
-
Returns:
|
|
379
|
-
str: Search results or error message
|
|
380
|
-
"""
|
|
381
|
-
try:
|
|
382
|
-
if not query.strip():
|
|
383
|
-
return "Please provide a search query"
|
|
384
|
-
|
|
385
|
-
result = memori_toolkit._memory_tool.execute(query=query.strip())
|
|
386
|
-
return str(result) if result else "No relevant memories found"
|
|
387
|
-
|
|
388
|
-
except Exception as e:
|
|
389
|
-
return f"Memory search error: {str(e)}"
|
|
390
|
-
|
|
391
|
-
return search_memory
|
agno/tools/memory.py
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from textwrap import dedent
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from agno.db.base import BaseDb
|
|
7
|
+
from agno.db.schemas import UserMemory
|
|
8
|
+
from agno.tools import Toolkit
|
|
9
|
+
from agno.utils.log import log_debug, log_error
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MemoryTools(Toolkit):
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
db: BaseDb,
|
|
16
|
+
enable_get_memories: bool = True,
|
|
17
|
+
enable_add_memory: bool = True,
|
|
18
|
+
enable_update_memory: bool = True,
|
|
19
|
+
enable_delete_memory: bool = True,
|
|
20
|
+
enable_analyze: bool = True,
|
|
21
|
+
enable_think: bool = True,
|
|
22
|
+
instructions: Optional[str] = None,
|
|
23
|
+
add_instructions: bool = True,
|
|
24
|
+
add_few_shot: bool = True,
|
|
25
|
+
few_shot_examples: Optional[str] = None,
|
|
26
|
+
all: bool = False,
|
|
27
|
+
**kwargs,
|
|
28
|
+
):
|
|
29
|
+
# Add instructions for using this toolkit
|
|
30
|
+
if instructions is None:
|
|
31
|
+
self.instructions = self.DEFAULT_INSTRUCTIONS
|
|
32
|
+
if add_few_shot:
|
|
33
|
+
if few_shot_examples is not None:
|
|
34
|
+
self.instructions += "\n" + few_shot_examples
|
|
35
|
+
else:
|
|
36
|
+
self.instructions += "\n" + self.FEW_SHOT_EXAMPLES
|
|
37
|
+
else:
|
|
38
|
+
self.instructions = instructions
|
|
39
|
+
|
|
40
|
+
# The database to use for memory operations
|
|
41
|
+
self.db: BaseDb = db
|
|
42
|
+
|
|
43
|
+
tools: List[Any] = []
|
|
44
|
+
if enable_think or all:
|
|
45
|
+
tools.append(self.think)
|
|
46
|
+
if enable_get_memories or all:
|
|
47
|
+
tools.append(self.get_memories)
|
|
48
|
+
if enable_add_memory or all:
|
|
49
|
+
tools.append(self.add_memory)
|
|
50
|
+
if enable_update_memory or all:
|
|
51
|
+
tools.append(self.update_memory)
|
|
52
|
+
if enable_delete_memory or all:
|
|
53
|
+
tools.append(self.delete_memory)
|
|
54
|
+
if enable_analyze or all:
|
|
55
|
+
tools.append(self.analyze)
|
|
56
|
+
|
|
57
|
+
super().__init__(
|
|
58
|
+
name="memory_tools",
|
|
59
|
+
instructions=self.instructions,
|
|
60
|
+
add_instructions=add_instructions,
|
|
61
|
+
tools=tools,
|
|
62
|
+
**kwargs,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def think(self, session_state: Dict[str, Any], thought: str) -> str:
|
|
66
|
+
"""Use this tool as a scratchpad to reason about memory operations, refine your approach, brainstorm memory content, or revise your plan.
|
|
67
|
+
|
|
68
|
+
Call `Think` whenever you need to figure out what to do next, analyze the user's requirements, plan memory operations, or decide on execution strategy.
|
|
69
|
+
You should use this tool as frequently as needed.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
thought: Your thought process and reasoning about memory operations.
|
|
73
|
+
"""
|
|
74
|
+
try:
|
|
75
|
+
log_debug(f"Memory Thought: {thought}")
|
|
76
|
+
|
|
77
|
+
# Add the thought to the session state
|
|
78
|
+
if session_state is None:
|
|
79
|
+
session_state = {}
|
|
80
|
+
if "memory_thoughts" not in session_state:
|
|
81
|
+
session_state["memory_thoughts"] = []
|
|
82
|
+
session_state["memory_thoughts"].append(thought)
|
|
83
|
+
|
|
84
|
+
# Return the full log of thoughts and the new thought
|
|
85
|
+
thoughts = "\n".join([f"- {t}" for t in session_state["memory_thoughts"]])
|
|
86
|
+
formatted_thoughts = dedent(
|
|
87
|
+
f"""Memory Thoughts:
|
|
88
|
+
{thoughts}
|
|
89
|
+
"""
|
|
90
|
+
).strip()
|
|
91
|
+
return formatted_thoughts
|
|
92
|
+
except Exception as e:
|
|
93
|
+
log_error(f"Error recording memory thought: {e}")
|
|
94
|
+
return f"Error recording memory thought: {e}"
|
|
95
|
+
|
|
96
|
+
def get_memories(self, session_state: Dict[str, Any]) -> str:
|
|
97
|
+
"""
|
|
98
|
+
Use this tool to get a list of memories for the current user from the database.
|
|
99
|
+
"""
|
|
100
|
+
try:
|
|
101
|
+
# Get user info from session state
|
|
102
|
+
user_id = session_state.get("current_user_id") if session_state else None
|
|
103
|
+
|
|
104
|
+
memories = self.db.get_user_memories(user_id=user_id)
|
|
105
|
+
|
|
106
|
+
# Store the result in session state for analysis
|
|
107
|
+
if session_state is None:
|
|
108
|
+
session_state = {}
|
|
109
|
+
if "memory_operations" not in session_state:
|
|
110
|
+
session_state["memory_operations"] = []
|
|
111
|
+
|
|
112
|
+
operation_result = {
|
|
113
|
+
"operation": "get_memories",
|
|
114
|
+
"success": True,
|
|
115
|
+
"memories": [memory.to_dict() for memory in memories], # type: ignore
|
|
116
|
+
"error": None,
|
|
117
|
+
}
|
|
118
|
+
session_state["memory_operations"].append(operation_result)
|
|
119
|
+
|
|
120
|
+
return json.dumps([memory.to_dict() for memory in memories], indent=2) # type: ignore
|
|
121
|
+
except Exception as e:
|
|
122
|
+
log_error(f"Error getting memories: {e}")
|
|
123
|
+
return json.dumps({"error": str(e)}, indent=2)
|
|
124
|
+
|
|
125
|
+
def add_memory(
|
|
126
|
+
self,
|
|
127
|
+
session_state: Dict[str, Any],
|
|
128
|
+
memory: str,
|
|
129
|
+
topics: Optional[List[str]] = None,
|
|
130
|
+
) -> str:
|
|
131
|
+
"""Use this tool to add a new memory to the database.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
memory: The memory content to store
|
|
135
|
+
topics: Optional list of topics associated with this memory
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
str: JSON string containing the created memory information
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
log_debug(f"Adding memory: {memory}")
|
|
142
|
+
|
|
143
|
+
# Get user and agent info from session state
|
|
144
|
+
user_id = session_state.get("current_user_id") if session_state else None
|
|
145
|
+
|
|
146
|
+
# Create UserMemory object
|
|
147
|
+
user_memory = UserMemory(
|
|
148
|
+
memory_id=str(uuid4()),
|
|
149
|
+
memory=memory,
|
|
150
|
+
topics=topics,
|
|
151
|
+
user_id=user_id,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
# Add to database
|
|
155
|
+
created_memory = self.db.upsert_user_memory(user_memory)
|
|
156
|
+
|
|
157
|
+
# Store the result in session state for analysis
|
|
158
|
+
if session_state is None:
|
|
159
|
+
session_state = {}
|
|
160
|
+
if "memory_operations" not in session_state:
|
|
161
|
+
session_state["memory_operations"] = []
|
|
162
|
+
|
|
163
|
+
memory_dict = created_memory.to_dict() if created_memory else None # type: ignore
|
|
164
|
+
|
|
165
|
+
operation_result = {
|
|
166
|
+
"operation": "add_memory",
|
|
167
|
+
"success": created_memory is not None,
|
|
168
|
+
"memory": memory_dict,
|
|
169
|
+
"error": None,
|
|
170
|
+
}
|
|
171
|
+
session_state["memory_operations"].append(operation_result)
|
|
172
|
+
|
|
173
|
+
if created_memory:
|
|
174
|
+
return json.dumps({"success": True, "operation": "add_memory", "memory": memory_dict}, indent=2)
|
|
175
|
+
else:
|
|
176
|
+
return json.dumps(
|
|
177
|
+
{"success": False, "operation": "add_memory", "error": "Failed to create memory"}, indent=2
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
except Exception as e:
|
|
181
|
+
log_error(f"Error adding memory: {e}")
|
|
182
|
+
return json.dumps({"success": False, "operation": "add_memory", "error": str(e)}, indent=2)
|
|
183
|
+
|
|
184
|
+
def update_memory(
|
|
185
|
+
self,
|
|
186
|
+
session_state: Dict[str, Any],
|
|
187
|
+
memory_id: str,
|
|
188
|
+
memory: Optional[str] = None,
|
|
189
|
+
topics: Optional[List[str]] = None,
|
|
190
|
+
) -> str:
|
|
191
|
+
"""Use this tool to update an existing memory in the database.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
memory_id: The ID of the memory to update
|
|
195
|
+
memory: Updated memory content (if provided)
|
|
196
|
+
topics: Updated list of topics (if provided)
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
str: JSON string containing the updated memory information
|
|
200
|
+
"""
|
|
201
|
+
try:
|
|
202
|
+
log_debug(f"Updating memory: {memory_id}")
|
|
203
|
+
|
|
204
|
+
# First get the existing memory
|
|
205
|
+
existing_memory = self.db.get_user_memory(memory_id)
|
|
206
|
+
if not existing_memory:
|
|
207
|
+
return json.dumps(
|
|
208
|
+
{"success": False, "operation": "update_memory", "error": f"Memory with ID {memory_id} not found"},
|
|
209
|
+
indent=2,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Update fields if provided
|
|
213
|
+
updated_memory = UserMemory(
|
|
214
|
+
memory=memory if memory is not None else existing_memory.memory, # type: ignore
|
|
215
|
+
memory_id=memory_id,
|
|
216
|
+
topics=topics if topics is not None else existing_memory.topics, # type: ignore
|
|
217
|
+
user_id=existing_memory.user_id, # type: ignore
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# Update in database
|
|
221
|
+
updated_result = self.db.upsert_user_memory(updated_memory)
|
|
222
|
+
|
|
223
|
+
# Store the result in session state for analysis
|
|
224
|
+
if session_state is None:
|
|
225
|
+
session_state = {}
|
|
226
|
+
if "memory_operations" not in session_state:
|
|
227
|
+
session_state["memory_operations"] = []
|
|
228
|
+
|
|
229
|
+
memory_dict = updated_result.to_dict() if updated_result else None # type: ignore
|
|
230
|
+
|
|
231
|
+
operation_result = {
|
|
232
|
+
"operation": "update_memory",
|
|
233
|
+
"success": updated_result is not None,
|
|
234
|
+
"memory": memory_dict,
|
|
235
|
+
"error": None,
|
|
236
|
+
}
|
|
237
|
+
session_state["memory_operations"].append(operation_result)
|
|
238
|
+
|
|
239
|
+
if updated_result:
|
|
240
|
+
return json.dumps({"success": True, "operation": "update_memory", "memory": memory_dict}, indent=2)
|
|
241
|
+
else:
|
|
242
|
+
return json.dumps(
|
|
243
|
+
{"success": False, "operation": "update_memory", "error": "Failed to update memory"}, indent=2
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
except Exception as e:
|
|
247
|
+
log_error(f"Error updating memory: {e}")
|
|
248
|
+
return json.dumps({"success": False, "operation": "update_memory", "error": str(e)}, indent=2)
|
|
249
|
+
|
|
250
|
+
def delete_memory(
|
|
251
|
+
self,
|
|
252
|
+
session_state: Dict[str, Any],
|
|
253
|
+
memory_id: str,
|
|
254
|
+
) -> str:
|
|
255
|
+
"""Use this tool to delete a memory from the database.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
memory_id: The ID of the memory to delete
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
str: JSON string containing the deletion result
|
|
262
|
+
"""
|
|
263
|
+
try:
|
|
264
|
+
log_debug(f"Deleting memory: {memory_id}")
|
|
265
|
+
|
|
266
|
+
# Check if memory exists before deletion
|
|
267
|
+
existing_memory = self.db.get_user_memory(memory_id)
|
|
268
|
+
if not existing_memory:
|
|
269
|
+
return json.dumps(
|
|
270
|
+
{"success": False, "operation": "delete_memory", "error": f"Memory with ID {memory_id} not found"},
|
|
271
|
+
indent=2,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
# Delete from database
|
|
275
|
+
self.db.delete_user_memory(memory_id)
|
|
276
|
+
|
|
277
|
+
# Store the result in session state for analysis
|
|
278
|
+
if session_state is None:
|
|
279
|
+
session_state = {}
|
|
280
|
+
if "memory_operations" not in session_state:
|
|
281
|
+
session_state["memory_operations"] = []
|
|
282
|
+
|
|
283
|
+
memory_dict = existing_memory.to_dict() if existing_memory else None # type: ignore
|
|
284
|
+
|
|
285
|
+
operation_result = {
|
|
286
|
+
"operation": "delete_memory",
|
|
287
|
+
"success": True,
|
|
288
|
+
"memory_id": memory_id,
|
|
289
|
+
"deleted_memory": memory_dict,
|
|
290
|
+
"error": None,
|
|
291
|
+
}
|
|
292
|
+
session_state["memory_operations"].append(operation_result)
|
|
293
|
+
|
|
294
|
+
return json.dumps(
|
|
295
|
+
{
|
|
296
|
+
"success": True,
|
|
297
|
+
"operation": "delete_memory",
|
|
298
|
+
"memory_id": memory_id,
|
|
299
|
+
"deleted_memory": memory_dict,
|
|
300
|
+
},
|
|
301
|
+
indent=2,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
except Exception as e:
|
|
305
|
+
log_error(f"Error deleting memory: {e}")
|
|
306
|
+
return json.dumps({"success": False, "operation": "delete_memory", "error": str(e)}, indent=2)
|
|
307
|
+
|
|
308
|
+
def analyze(self, session_state: Dict[str, Any], analysis: str) -> str:
|
|
309
|
+
"""Use this tool to evaluate whether the memory operations results are correct and sufficient.
|
|
310
|
+
If not, go back to "Think" or use memory operations with refined parameters.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
analysis: Your analysis of the memory operations results.
|
|
314
|
+
"""
|
|
315
|
+
try:
|
|
316
|
+
log_debug(f"Memory Analysis: {analysis}")
|
|
317
|
+
|
|
318
|
+
# Add the analysis to the session state
|
|
319
|
+
if session_state is None:
|
|
320
|
+
session_state = {}
|
|
321
|
+
if "memory_analysis" not in session_state:
|
|
322
|
+
session_state["memory_analysis"] = []
|
|
323
|
+
session_state["memory_analysis"].append(analysis)
|
|
324
|
+
|
|
325
|
+
# Return the full log of analysis and the new analysis
|
|
326
|
+
analysis_log = "\n".join([f"- {a}" for a in session_state["memory_analysis"]])
|
|
327
|
+
formatted_analysis = dedent(
|
|
328
|
+
f"""Memory Analysis:
|
|
329
|
+
{analysis_log}
|
|
330
|
+
"""
|
|
331
|
+
).strip()
|
|
332
|
+
return formatted_analysis
|
|
333
|
+
except Exception as e:
|
|
334
|
+
log_error(f"Error recording memory analysis: {e}")
|
|
335
|
+
return f"Error recording memory analysis: {e}"
|
|
336
|
+
|
|
337
|
+
DEFAULT_INSTRUCTIONS = dedent("""\
|
|
338
|
+
You have access to the Think, Add Memory, Update Memory, Delete Memory, and Analyze tools that will help you manage user memories and analyze their operations. Use these tools as frequently as needed to successfully complete memory management tasks.
|
|
339
|
+
|
|
340
|
+
## How to use the Think, Memory Operations, and Analyze tools:
|
|
341
|
+
|
|
342
|
+
1. **Think**
|
|
343
|
+
- Purpose: A scratchpad for planning memory operations, brainstorming memory content, and refining your approach. You never reveal your "Think" content to the user.
|
|
344
|
+
- Usage: Call `think` whenever you need to figure out what memory operations to perform, analyze requirements, or decide on strategy.
|
|
345
|
+
|
|
346
|
+
2. **Get Memories**
|
|
347
|
+
- Purpose: Retrieves a list of memories from the database for the current user.
|
|
348
|
+
- Usage: Call `get_memories` when you need to retrieve memories for the current user.
|
|
349
|
+
|
|
350
|
+
3. **Add Memory**
|
|
351
|
+
- Purpose: Creates new memories in the database with specified content and metadata.
|
|
352
|
+
- Usage: Call `add_memory` with memory content and optional topics when you need to store new information.
|
|
353
|
+
|
|
354
|
+
4. **Update Memory**
|
|
355
|
+
- Purpose: Modifies existing memories in the database by memory ID.
|
|
356
|
+
- Usage: Call `update_memory` with a memory ID and the fields you want to change. Only specify the fields that need updating.
|
|
357
|
+
|
|
358
|
+
5. **Delete Memory**
|
|
359
|
+
- Purpose: Removes memories from the database by memory ID.
|
|
360
|
+
- Usage: Call `delete_memory` with a memory ID when a memory is no longer needed or requested to be removed.
|
|
361
|
+
|
|
362
|
+
6. **Analyze**
|
|
363
|
+
- Purpose: Evaluate whether the memory operations results are correct and sufficient. If not, go back to "Think" or use memory operations with refined parameters.
|
|
364
|
+
- Usage: Call `analyze` after performing memory operations to verify:
|
|
365
|
+
- Success: Did the operation complete successfully?
|
|
366
|
+
- Accuracy: Is the memory content correct and well-formed?
|
|
367
|
+
- Completeness: Are all required fields populated appropriately?
|
|
368
|
+
- Errors: Were there any failures or unexpected behaviors?
|
|
369
|
+
|
|
370
|
+
**Important Guidelines**:
|
|
371
|
+
- Do not include your internal chain-of-thought in direct user responses.
|
|
372
|
+
- Use "Think" to reason internally. These notes are never exposed to the user.
|
|
373
|
+
- When you provide a final answer to the user, be clear, concise, and based on the memory operation results.
|
|
374
|
+
- If memory operations fail or produce unexpected results, acknowledge limitations and explain what went wrong.
|
|
375
|
+
- Always verify memory IDs exist before attempting updates or deletions.
|
|
376
|
+
- Use descriptive topics and clear memory content to make memories easily searchable and understandable.\
|
|
377
|
+
""")
|
|
378
|
+
|
|
379
|
+
FEW_SHOT_EXAMPLES = dedent("""\
|
|
380
|
+
You can refer to the examples below as guidance for how to use each tool.
|
|
381
|
+
|
|
382
|
+
### Examples
|
|
383
|
+
|
|
384
|
+
#### Example 1: Adding User Preferences
|
|
385
|
+
|
|
386
|
+
User: I prefer vegetarian recipes and I'm allergic to nuts.
|
|
387
|
+
Think: I should store the user's dietary preferences. I should create a memory with this information and use relevant topics for easy retrieval.
|
|
388
|
+
Add Memory: memory="User prefers vegetarian recipes and is allergic to nuts", topics=["dietary_preferences", "allergies", "food"]
|
|
389
|
+
Analyze: Successfully created memory with dietary preferences. The topics are well-chosen for future retrieval. This should help with future food-related requests.
|
|
390
|
+
|
|
391
|
+
Final Answer: Noted. I've stored your dietary preferences. I'll remember that you prefer vegetarian recipes and have a nut allergy for future reference.
|
|
392
|
+
|
|
393
|
+
#### Example 2: Updating Existing Information
|
|
394
|
+
|
|
395
|
+
User: Actually, update my dietary info - I'm now eating fish too, so I'm pescatarian.
|
|
396
|
+
Think: The user wants to update their previous dietary preference from vegetarian to pescatarian. I need to find their existing dietary memory and update it.
|
|
397
|
+
Update Memory: memory_id="previous_memory_id", memory="User follows pescatarian diet (vegetarian + fish) and is allergic to nuts", topics=["dietary_preferences", "allergies", "food", "pescatarian"]
|
|
398
|
+
Analyze: Successfully updated the dietary preference memory. The content now accurately reflects pescatarian diet and maintains the nut allergy information.
|
|
399
|
+
|
|
400
|
+
Final Answer: I've updated your dietary preferences to reflect that you follow a pescatarian diet (vegetarian plus fish) while maintaining your nut allergy information.
|
|
401
|
+
|
|
402
|
+
#### Example 3: Removing Outdated Information
|
|
403
|
+
|
|
404
|
+
User: Please forget about my old work schedule - it's completely changed.
|
|
405
|
+
Think: The user wants me to delete their old work schedule memory since it's no longer relevant. I should find and remove that memory.
|
|
406
|
+
Delete Memory: memory_id="work_schedule_memory_id"
|
|
407
|
+
Analyze: Successfully deleted the outdated work schedule memory. The old information won't interfere with future scheduling requests.
|
|
408
|
+
|
|
409
|
+
Final Answer: I've removed your old work schedule information. Feel free to share your new schedule when you're ready, and I'll store the updated information.
|
|
410
|
+
|
|
411
|
+
#### Example 4: Retrieving Memories
|
|
412
|
+
|
|
413
|
+
User: What have you remembered about me?
|
|
414
|
+
Think: The user wants to retrieve memories about themselves. I should use the get_memories tool to retrieve the memories.
|
|
415
|
+
Get Memories:
|
|
416
|
+
Analyze: Successfully retrieved the memories about the user. The memories are relevant to the user's preferences and activities.
|
|
417
|
+
|
|
418
|
+
Final Answer: I've retrieved the memories about you. You like to hike in the mountains on weekends and travel to new places and experience different cultures. You are planning to travel to Africa in December.\
|
|
419
|
+
""")
|
agno/tools/models/nebius.py
CHANGED
|
@@ -12,12 +12,12 @@ from agno.utils.log import log_error, log_warning
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class NebiusTools(Toolkit):
|
|
15
|
-
"""Tools for interacting with Nebius
|
|
15
|
+
"""Tools for interacting with Nebius Token Factory's text-to-image API"""
|
|
16
16
|
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
19
19
|
api_key: Optional[str] = None,
|
|
20
|
-
base_url: str = "https://api.
|
|
20
|
+
base_url: str = "https://api.tokenfactory.nebius.com/v1",
|
|
21
21
|
image_model: str = "black-forest-labs/flux-schnell",
|
|
22
22
|
image_quality: Optional[str] = "standard",
|
|
23
23
|
image_size: Optional[str] = "1024x1024",
|
|
@@ -26,11 +26,11 @@ class NebiusTools(Toolkit):
|
|
|
26
26
|
all: bool = False,
|
|
27
27
|
**kwargs,
|
|
28
28
|
):
|
|
29
|
-
"""Initialize Nebius
|
|
29
|
+
"""Initialize Nebius Token Factory text-to-image tools.
|
|
30
30
|
|
|
31
31
|
Args:
|
|
32
32
|
api_key: Nebius API key. If not provided, will look for NEBIUS_API_KEY environment variable.
|
|
33
|
-
base_url: The base URL for the Nebius
|
|
33
|
+
base_url: The base URL for the Nebius Token Factory API. This should be configured according to Nebius's documentation.
|
|
34
34
|
image_model: The model to use for generation. Options include:
|
|
35
35
|
- "black-forest-labs/flux-schnell" (fastest)
|
|
36
36
|
- "black-forest-labs/flux-dev" (balanced)
|
|
@@ -69,7 +69,7 @@ class NebiusTools(Toolkit):
|
|
|
69
69
|
agent: Agent,
|
|
70
70
|
prompt: str,
|
|
71
71
|
) -> ToolResult:
|
|
72
|
-
"""Generate images based on a text prompt using Nebius
|
|
72
|
+
"""Generate images based on a text prompt using Nebius Token Factory.
|
|
73
73
|
|
|
74
74
|
Args:
|
|
75
75
|
agent: The agent instance for adding images
|