agno 2.3.7__py3-none-any.whl → 2.3.8__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 +371 -367
- agno/db/mongo/async_mongo.py +0 -24
- agno/db/mongo/mongo.py +0 -16
- agno/db/mysql/mysql.py +0 -19
- agno/db/postgres/async_postgres.py +0 -21
- agno/db/postgres/postgres.py +0 -23
- agno/db/redis/redis.py +0 -4
- agno/db/singlestore/singlestore.py +0 -11
- agno/db/sqlite/async_sqlite.py +0 -24
- agno/db/sqlite/sqlite.py +0 -20
- agno/models/base.py +134 -11
- agno/models/openai/responses.py +3 -2
- agno/os/interfaces/a2a/utils.py +1 -1
- agno/os/middleware/jwt.py +8 -6
- agno/team/team.py +88 -86
- agno/tools/workflow.py +8 -1
- agno/workflow/parallel.py +8 -2
- agno/workflow/step.py +3 -3
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/METADATA +2 -2
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/RECORD +23 -24
- agno/tools/memori.py +0 -339
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/WHEEL +0 -0
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/top_level.txt +0 -0
agno/workflow/parallel.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import warnings
|
|
3
3
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
4
|
+
from contextvars import copy_context
|
|
4
5
|
from copy import deepcopy
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
@@ -267,8 +268,9 @@ class Parallel:
|
|
|
267
268
|
|
|
268
269
|
with ThreadPoolExecutor(max_workers=len(self.steps)) as executor:
|
|
269
270
|
# Submit all tasks with their original indices
|
|
271
|
+
# Use copy_context().run to propagate context variables to child threads
|
|
270
272
|
future_to_index = {
|
|
271
|
-
executor.submit(execute_step_with_index, indexed_step): indexed_step[0]
|
|
273
|
+
executor.submit(copy_context().run, execute_step_with_index, indexed_step): indexed_step[0]
|
|
272
274
|
for indexed_step in indexed_steps
|
|
273
275
|
}
|
|
274
276
|
|
|
@@ -449,7 +451,11 @@ class Parallel:
|
|
|
449
451
|
|
|
450
452
|
with ThreadPoolExecutor(max_workers=len(self.steps)) as executor:
|
|
451
453
|
# Submit all tasks
|
|
452
|
-
|
|
454
|
+
# Use copy_context().run to propagate context variables to child threads
|
|
455
|
+
futures = [
|
|
456
|
+
executor.submit(copy_context().run, execute_step_stream_with_index, indexed_step)
|
|
457
|
+
for indexed_step in indexed_steps
|
|
458
|
+
]
|
|
453
459
|
|
|
454
460
|
# Process events from queue as they arrive
|
|
455
461
|
completed_steps = 0
|
agno/workflow/step.py
CHANGED
|
@@ -644,7 +644,7 @@ class Step:
|
|
|
644
644
|
session_state=session_state_copy, # Send a copy to the executor
|
|
645
645
|
stream=True,
|
|
646
646
|
stream_events=stream_events,
|
|
647
|
-
|
|
647
|
+
yield_run_output=True,
|
|
648
648
|
run_context=run_context,
|
|
649
649
|
**kwargs,
|
|
650
650
|
)
|
|
@@ -653,7 +653,7 @@ class Step:
|
|
|
653
653
|
for event in response_stream:
|
|
654
654
|
if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
|
|
655
655
|
active_executor_run_response = event
|
|
656
|
-
|
|
656
|
+
continue
|
|
657
657
|
# Only yield executor events if stream_executor_events is True
|
|
658
658
|
if stream_executor_events:
|
|
659
659
|
enriched_event = self._enrich_event_with_context(
|
|
@@ -1174,7 +1174,7 @@ class Step:
|
|
|
1174
1174
|
stream=True,
|
|
1175
1175
|
stream_events=stream_events,
|
|
1176
1176
|
run_context=run_context,
|
|
1177
|
-
|
|
1177
|
+
yield_run_output=True,
|
|
1178
1178
|
**kwargs,
|
|
1179
1179
|
)
|
|
1180
1180
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agno
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.8
|
|
4
4
|
Summary: Agno: a lightweight library for building Multi-Agent Systems
|
|
5
5
|
Author-email: Ashpreet Bedi <ashpreet@agno.com>
|
|
6
6
|
Project-URL: homepage, https://agno.com
|
|
@@ -153,7 +153,7 @@ Requires-Dist: mcp>=1.9.2; extra == "mcp"
|
|
|
153
153
|
Provides-Extra: mem0
|
|
154
154
|
Requires-Dist: mem0ai; extra == "mem0"
|
|
155
155
|
Provides-Extra: memori
|
|
156
|
-
Requires-Dist: memorisdk==
|
|
156
|
+
Requires-Dist: memorisdk==3.0.5; extra == "memori"
|
|
157
157
|
Provides-Extra: newspaper
|
|
158
158
|
Requires-Dist: newspaper4k; extra == "newspaper"
|
|
159
159
|
Requires-Dist: lxml_html_clean; extra == "newspaper"
|
|
@@ -6,7 +6,7 @@ agno/media.py,sha256=eTfYb_pwhX_PCIVPSrW4VYRqmoxKABEF1aZClrVvQ30,16500
|
|
|
6
6
|
agno/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
agno/table.py,sha256=9hHFnInNsrj0ZKtWjGDP5c6kbmNdtQvDDYT2j2CZJ6o,198
|
|
8
8
|
agno/agent/__init__.py,sha256=s7S3FgsjZxuaabzi8L5n4aSH8IZAiZ7XaNNcySGR-EQ,1051
|
|
9
|
-
agno/agent/agent.py,sha256=
|
|
9
|
+
agno/agent/agent.py,sha256=ljgnuhq2UTjMC6-hSSnb4eM66x8ItubRpNWvR4tpNtE,497820
|
|
10
10
|
agno/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
agno/api/agent.py,sha256=fKlQ62E_C9Rjd7Zus3Gs3R1RG-IhzFV-ICpkb6SLqYc,932
|
|
12
12
|
agno/api/api.py,sha256=gFhVjxJYkQsw8mBl2fhoStMPGlyJ37DJaqgUOwZVvQI,1021
|
|
@@ -60,21 +60,21 @@ agno/db/migrations/v1_to_v2.py,sha256=gj8deaEWUxOr0qJyMfjOpV3LxEh-otOSOxDckeUq0q
|
|
|
60
60
|
agno/db/migrations/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
61
|
agno/db/migrations/versions/v2_3_0.py,sha256=WikuOtgQs_Tq8o3JndCMG6HAMzKvz4GVth9V5V5RuvE,35161
|
|
62
62
|
agno/db/mongo/__init__.py,sha256=NG2WC2jE5PX1kMXTYCVHjhomf5DAJgvzSj45QHdvl2E,466
|
|
63
|
-
agno/db/mongo/async_mongo.py,sha256=
|
|
64
|
-
agno/db/mongo/mongo.py,sha256=
|
|
63
|
+
agno/db/mongo/async_mongo.py,sha256=0jh36UmtYqeQOyMT9MB-2GE7aqCUEN0jGWJzuv8ZfCo,107154
|
|
64
|
+
agno/db/mongo/mongo.py,sha256=GHeDRw2VhhuTDtLcXpsf2UMU_WlJbJCc6n131Omn3Bw,98457
|
|
65
65
|
agno/db/mongo/schemas.py,sha256=Q3JrMZ3zCKZcHilh5CoQePI5d5dRjHAtjs5QuWrxiWc,3098
|
|
66
66
|
agno/db/mongo/utils.py,sha256=1KrbF1PR_707e9SqXZcquaw_N7mRYm9HjJnvYwBjgG8,9921
|
|
67
67
|
agno/db/mysql/__init__.py,sha256=ohBMZ1E6ctioEF0XX5PjC4LtUQrc6lFkjsE4ojyXA8g,63
|
|
68
|
-
agno/db/mysql/mysql.py,sha256=
|
|
68
|
+
agno/db/mysql/mysql.py,sha256=io5bOVEXvcM85DJsJhYUf5w4nCeeF6TtU9ypZAM3eiQ,120209
|
|
69
69
|
agno/db/mysql/schemas.py,sha256=_4p2IWt0zVq-fHuxFhEpWLWxlp3QPKk8xtNMiB1TNOY,9067
|
|
70
70
|
agno/db/mysql/utils.py,sha256=PdqN-SxM-ox8HU9CZyxzvs2D1FE2vdZFVCyFgFcQsyU,12366
|
|
71
71
|
agno/db/postgres/__init__.py,sha256=Ojk00nTCzQFiH2ViD7KIBjgpkTKLRNPCwWnuXMKtNXY,154
|
|
72
|
-
agno/db/postgres/async_postgres.py,sha256=
|
|
73
|
-
agno/db/postgres/postgres.py,sha256=
|
|
72
|
+
agno/db/postgres/async_postgres.py,sha256=pZAVNSk41_nD5B4DtUJ1jDX1l2ZDe-tAdkhGR-ru5pQ,106024
|
|
73
|
+
agno/db/postgres/postgres.py,sha256=rbkI4YJQYHqryMrpZOLtP07i8izbcschg7XQZlVI160,116664
|
|
74
74
|
agno/db/postgres/schemas.py,sha256=G0BRG9GcUcO43-TU52nKSEog8v3tdJNwIhEjts9dCns,8405
|
|
75
75
|
agno/db/postgres/utils.py,sha256=UE3UQZ-h7fADAKBsX4BWcDka54YNROEpBrlfTmDvpqc,15471
|
|
76
76
|
agno/db/redis/__init__.py,sha256=rZWeZ4CpVeKP-enVQ-SRoJ777i0rdGNgoNDRS9gsfAc,63
|
|
77
|
-
agno/db/redis/redis.py,sha256=
|
|
77
|
+
agno/db/redis/redis.py,sha256=WgP-f8OfPTUEISY8O8meYbcJsFA3rpmXEthVQZRKdoM,82222
|
|
78
78
|
agno/db/redis/schemas.py,sha256=90rDTGUyN1kYZ2KgeFjyOu1SwqYoTc1ErePxGqFlbj0,5217
|
|
79
79
|
agno/db/redis/utils.py,sha256=vQpLI-V442B6m0q_l8IVEJctLD4P-kawbCm5A_Fnotg,11326
|
|
80
80
|
agno/db/schemas/__init__.py,sha256=g72Zr5_nm00yXHStv4pf9PG9bGLKXEK7Av6YQtrDbCQ,147
|
|
@@ -85,12 +85,12 @@ agno/db/schemas/memory.py,sha256=dA7It1cN60dId-GpowmKTORy4Q6r9L49ZpGnnZkXmds,212
|
|
|
85
85
|
agno/db/schemas/metrics.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
86
86
|
agno/db/singlestore/__init__.py,sha256=dufbaod8ZZIeZIVi0hYJQ8Eu2DfIfWdIy00cpqAsx9U,87
|
|
87
87
|
agno/db/singlestore/schemas.py,sha256=gnCpoRAztbPiZOCfx9MGBx1sySijwogajSjxIeGpsaA,8923
|
|
88
|
-
agno/db/singlestore/singlestore.py,sha256=
|
|
88
|
+
agno/db/singlestore/singlestore.py,sha256=mShU-mGdOamf82VihF96e1tVjzSNol8Zs94f0S--HLs,118169
|
|
89
89
|
agno/db/singlestore/utils.py,sha256=w2FVFIBpFJK6nKJVt1sgv9N-esmfpGY_8ViFRI69I2I,13677
|
|
90
90
|
agno/db/sqlite/__init__.py,sha256=09V3i4y0-tBjt60--57ivZ__SaaS67GCsDT4Apzv-5Y,138
|
|
91
|
-
agno/db/sqlite/async_sqlite.py,sha256=
|
|
91
|
+
agno/db/sqlite/async_sqlite.py,sha256=62P-HurucmK3pk5aM8vjqHbHuuor5pDSuJW-vCLyE74,121942
|
|
92
92
|
agno/db/sqlite/schemas.py,sha256=1lrIFWEhXYZJIlQYEnOl3XLp3UfsE5ILj2HUPmOf3cg,8265
|
|
93
|
-
agno/db/sqlite/sqlite.py,sha256=
|
|
93
|
+
agno/db/sqlite/sqlite.py,sha256=XjRJAmClEzYS6itHuPRD6RB9-iTtHgDkBmNLKy2vJOM,119118
|
|
94
94
|
agno/db/sqlite/utils.py,sha256=sgp-KR7A5naTqTORHYHyP_21hG9LffOzCgqbx5S8RfE,15171
|
|
95
95
|
agno/db/surrealdb/__init__.py,sha256=C8qp5-Nx9YnSmgKEtGua-sqG_ntCXONBw1qqnNyKPqI,75
|
|
96
96
|
agno/db/surrealdb/metrics.py,sha256=oKDRyjRQ6KR3HaO8zDHQLVMG7-0NDkOFOKX5I7mD5FA,10336
|
|
@@ -181,7 +181,7 @@ agno/memory/strategies/base.py,sha256=13xCiBPtFUrpDaWbiz8zmNGjopT4VSIkcHVxfnvJ4W
|
|
|
181
181
|
agno/memory/strategies/summarize.py,sha256=4M9zWTsooC3EtHpZoC7Z-yFaQgQoebRMNfZPitdsvB0,7307
|
|
182
182
|
agno/memory/strategies/types.py,sha256=b3N5jOG_dM4AxT7vGagFIc9sqUUjxFtRHSoH4_AhEx8,1225
|
|
183
183
|
agno/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
184
|
-
agno/models/base.py,sha256=
|
|
184
|
+
agno/models/base.py,sha256=_ldhrYebV77fEzHtnILNILPW2aG4KwMjsT-THnYDwHA,114403
|
|
185
185
|
agno/models/defaults.py,sha256=1_fe4-ZbNriE8BgqxVRVi4KGzEYxYKYsz4hn6CZNEEM,40
|
|
186
186
|
agno/models/message.py,sha256=5-Nvqd6rXNca37yiVVQgBJY4w_gudVawg-ZQHcUX4SE,19763
|
|
187
187
|
agno/models/metrics.py,sha256=81IILXZwGmOTiWK003bi5mg4bM1f4LCWbwyamjFzp18,4500
|
|
@@ -247,7 +247,7 @@ agno/models/ollama/chat.py,sha256=Szc8rEWRvQ2CW50V5xAuccX4Ozc1BAV9wUPbFJhY_J8,16
|
|
|
247
247
|
agno/models/openai/__init__.py,sha256=OssVgQRpsriU6aJZ3lIp_jFuqvX6y78L4Fd3uTlmI3E,225
|
|
248
248
|
agno/models/openai/chat.py,sha256=KZupbtQxrNiHH9m-y6hrldLq0dGe0XYjvShJQsz-Kjw,40096
|
|
249
249
|
agno/models/openai/like.py,sha256=wmw9PfAVqluBs4MMY73dgjelKn1yl5JDKyCRvaNFjFw,745
|
|
250
|
-
agno/models/openai/responses.py,sha256=
|
|
250
|
+
agno/models/openai/responses.py,sha256=SahBoPgh8KFhRIE1QymhNhQoydFHFEmpBWxmFuixT88,46702
|
|
251
251
|
agno/models/openrouter/__init__.py,sha256=ZpZhNyy_EGSXp58uC9e2iyjnxBctql7GaY8rUG-599I,90
|
|
252
252
|
agno/models/openrouter/openrouter.py,sha256=fdFZy-1ZwvDKlO0b9TiXdtNe5ScSU4RJSYw08DojK_4,3284
|
|
253
253
|
agno/models/perplexity/__init__.py,sha256=JNmOElDLwcZ9_Lk5owkEdgwmAhaH3YJ-VJqOI8rgp5c,90
|
|
@@ -284,7 +284,7 @@ agno/os/interfaces/base.py,sha256=vXkr1tRjWHTcmBlQFzvQjqURLhObmFtUAx82uij_j48,54
|
|
|
284
284
|
agno/os/interfaces/a2a/__init__.py,sha256=Fs7--dx9drvtVS9QjsCCm0P7c-hJ7TzU8gNwKTQsZDA,62
|
|
285
285
|
agno/os/interfaces/a2a/a2a.py,sha256=UiTX-GOuXxp1CQzRgtmgSSYNn2iFC_vKYnC37OidygM,1337
|
|
286
286
|
agno/os/interfaces/a2a/router.py,sha256=OpNCHhYoCUyfcuRtiOdvUrUZnxfFB1jhMWraLA85XMg,10985
|
|
287
|
-
agno/os/interfaces/a2a/utils.py,sha256=
|
|
287
|
+
agno/os/interfaces/a2a/utils.py,sha256=J_m_l3noqfjjRRQ-kQQMAab1CnvDPh-M1regJ9_o5Yg,39286
|
|
288
288
|
agno/os/interfaces/agui/__init__.py,sha256=1zrGICk4roXUINwSFZfqH6sBsbHmD5KjGYVJMGg4fKQ,66
|
|
289
289
|
agno/os/interfaces/agui/agui.py,sha256=PKGoDDbtQFmEC0zRwZmsjS_5t9bJWJ-ZGwxEQsu9P-U,1415
|
|
290
290
|
agno/os/interfaces/agui/router.py,sha256=U2w26v2oOCCOl5t5XduQChO3_eJBNH4Mk9BH77KKJag,5257
|
|
@@ -298,7 +298,7 @@ agno/os/interfaces/whatsapp/router.py,sha256=K7Ex4Xq-4hPcRKoVxBkb8KoGxH6WXC1bubd
|
|
|
298
298
|
agno/os/interfaces/whatsapp/security.py,sha256=0GYdG28yeSpV47nMWASaFSTiGESSstcFAeL6amobvFE,1772
|
|
299
299
|
agno/os/interfaces/whatsapp/whatsapp.py,sha256=tNJncEu_hm0lFOHbjaSoz5-VIKORR_pyW26cseBLfbs,989
|
|
300
300
|
agno/os/middleware/__init__.py,sha256=EYsNzeixFgL3n8kepKWXT42fTTmrNyD8b8rOdXecMRI,94
|
|
301
|
-
agno/os/middleware/jwt.py,sha256=
|
|
301
|
+
agno/os/middleware/jwt.py,sha256=O3O_h7WeO7xN6uj4NiBMgz9tTvJpfX2c-f4w4-ykBNA,9575
|
|
302
302
|
agno/os/routers/__init__.py,sha256=du4LO9aZwiY1t59VcV9M6wiAfftFFlUZc-YXsTGy9LI,97
|
|
303
303
|
agno/os/routers/health.py,sha256=AO3ec6Xi1wXOwUUFJhEcM45488qu6aZRJTwF2GLz6Ak,992
|
|
304
304
|
agno/os/routers/home.py,sha256=xe8DYJkRgad55qiza0lHt8pUIV5PLSyu2MkybjuPDDE,1708
|
|
@@ -346,7 +346,7 @@ agno/session/summary.py,sha256=9JnDyQyggckd3zx6L8Q5f-lglZvrFQxvPjGU8gLCgR4,10292
|
|
|
346
346
|
agno/session/team.py,sha256=-MkB6qQCrnXLKko8L5s9fJOWPsjeK5Gx0SXEPoOwSFQ,13437
|
|
347
347
|
agno/session/workflow.py,sha256=nPHnh1N0SJby5JRjysCUI-kTDCelQMFfqosEnnLzPIg,19690
|
|
348
348
|
agno/team/__init__.py,sha256=toHidBOo5M3n_TIVtIKHgcDbLL9HR-_U-YQYuIt_XtE,847
|
|
349
|
-
agno/team/team.py,sha256=
|
|
349
|
+
agno/team/team.py,sha256=TOc7jPk0sTVqV-3nm6By9QlX_632fsJtn-FjIvAC2Co,434423
|
|
350
350
|
agno/tools/__init__.py,sha256=jNll2sELhPPbqm5nPeT4_uyzRO2_KRTW-8Or60kioS0,210
|
|
351
351
|
agno/tools/agentql.py,sha256=S82Z9aTNr-E5wnA4fbFs76COljJtiQIjf2grjz3CkHU,4104
|
|
352
352
|
agno/tools/airflow.py,sha256=uf2rOzZpSU64l_qRJ5Raku-R3Gky-uewmYkh6W0-oxg,2610
|
|
@@ -405,7 +405,6 @@ agno/tools/local_file_system.py,sha256=wWyhM5-lqDgDO_YNzRA8ekG-m2n89k8fWr8M1BWiQ
|
|
|
405
405
|
agno/tools/lumalab.py,sha256=6WnZXbThKY2jL9zLswq1PVsbFm2jz81qshWqBZi59oo,6808
|
|
406
406
|
agno/tools/mcp_toolbox.py,sha256=z6qZqUOmYueBoiQtTqRWV9GohhCAd3s5D4GyqtezHeY,12760
|
|
407
407
|
agno/tools/mem0.py,sha256=5W5pZwJmBTt-_l4nvBdNQHavXFSKV9mVdJg5aso4JBI,7680
|
|
408
|
-
agno/tools/memori.py,sha256=tubBYj0rQFbBXadhWxwTjjmb3Rnims536AVPkGdCMcw,13181
|
|
409
408
|
agno/tools/memory.py,sha256=vpMoKtCqs3m6vkuqmZ4fW9IRf1OhXHQGGaq3exJK0Xo,18449
|
|
410
409
|
agno/tools/mlx_transcribe.py,sha256=kuiYZAM5ZAdkiOfFdbGJsCb0gacnJRtSTFzuX8eWGLw,6379
|
|
411
410
|
agno/tools/models_labs.py,sha256=E91DZDJOU2ldgI3U_ueFiZcXLLWfbh0MsZ2pYP9c0eQ,7933
|
|
@@ -457,7 +456,7 @@ agno/tools/website.py,sha256=jzcXLEsCfGIEqV88OLePiCEjfDoAbXQDCPAr9JbP8cU,1798
|
|
|
457
456
|
agno/tools/webtools.py,sha256=5Dyp8U2ov32DkJMpj-7plzQZcfnCL7wlXbQIfRh8jmw,1305
|
|
458
457
|
agno/tools/whatsapp.py,sha256=DaDyNogtbgrinJohfU7CmVQJSZsZO-00XUbRJegN_eE,11055
|
|
459
458
|
agno/tools/wikipedia.py,sha256=u6xhc5wkEGcjng4leVCmo28o6Ti7OzDgRqiOqTMnmoc,2277
|
|
460
|
-
agno/tools/workflow.py,sha256=
|
|
459
|
+
agno/tools/workflow.py,sha256=8__QqwLQ0uWXiwk99SoLl2rC3Sr_5nJur6CeGeU0xx4,12744
|
|
461
460
|
agno/tools/x.py,sha256=gaFCel9FyDPnKLL03nkjsc9NGsfQOsS92XByp3hdwMo,14495
|
|
462
461
|
agno/tools/yfinance.py,sha256=1bPUMZ7BWxEyblJLxyhzV6y4O-EBmljUM_aKfr0cf0o,11540
|
|
463
462
|
agno/tools/youtube.py,sha256=H6SbBfWrmkazR8QrgXvLpqBOGAy4eHbRxkgTRJEt91Q,6667
|
|
@@ -585,14 +584,14 @@ agno/workflow/__init__.py,sha256=Ze2j811jwnsS8Sjv6u0Ap4l7Pyw_ivRof1uBYNJhb1w,609
|
|
|
585
584
|
agno/workflow/agent.py,sha256=fKLB4kop7YYFeM1e-d3IzvVPsVF5cLNX6Z0gPn81ZR4,12170
|
|
586
585
|
agno/workflow/condition.py,sha256=2zKLgrvwa3Up4aDKWSACOa7vZD0lSLX_lUW-LYJa0Yc,33939
|
|
587
586
|
agno/workflow/loop.py,sha256=nDBXCRMhXHaRb-jnIbtEgY78h69zCdUrHwiJ6VXl5zo,33986
|
|
588
|
-
agno/workflow/parallel.py,sha256=
|
|
587
|
+
agno/workflow/parallel.py,sha256=yTtc6dkNmIGU6zOI_7EZ3mATrJZFEArUUcUG47L-DwE,38007
|
|
589
588
|
agno/workflow/router.py,sha256=HQDOnErjtiQdY_EskJBV_mZq_k6d1gH6JJPIM2Yfelw,32016
|
|
590
|
-
agno/workflow/step.py,sha256=
|
|
589
|
+
agno/workflow/step.py,sha256=BbzpETSMtlDkUsm47-TwhfGAgRM6TcWnp-orIJgOTQY,74267
|
|
591
590
|
agno/workflow/steps.py,sha256=rbfue2M4qYEkgHueojCY1-cB4i1MFjO-jX6uTxyoKwk,27118
|
|
592
591
|
agno/workflow/types.py,sha256=LObJ0VkUtepZ-uewv3j283S4hrCXy0eCplQzIzRG1ic,19175
|
|
593
592
|
agno/workflow/workflow.py,sha256=6khBK6tbO9i2aSovduwNoQUfbcyEdoKyF4F86Uyj4gM,193181
|
|
594
|
-
agno-2.3.
|
|
595
|
-
agno-2.3.
|
|
596
|
-
agno-2.3.
|
|
597
|
-
agno-2.3.
|
|
598
|
-
agno-2.3.
|
|
593
|
+
agno-2.3.8.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
594
|
+
agno-2.3.8.dist-info/METADATA,sha256=ANDODVqjcZLqQzSxWL-lXsxjWQUUjUl8XThT9VSy4Og,31018
|
|
595
|
+
agno-2.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
596
|
+
agno-2.3.8.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
|
|
597
|
+
agno-2.3.8.dist-info/RECORD,,
|
agno/tools/memori.py
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from typing import Any, Dict, List, Optional
|
|
3
|
-
|
|
4
|
-
from agno.tools.toolkit import Toolkit
|
|
5
|
-
from agno.utils.log import log_debug, log_error, log_info, log_warning
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
from memori import Memori, create_memory_tool
|
|
9
|
-
except ImportError:
|
|
10
|
-
raise ImportError("`memorisdk` package not found. Please install it with `pip install memorisdk`")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class MemoriTools(Toolkit):
|
|
14
|
-
"""
|
|
15
|
-
Memori ToolKit for Agno Agents and Teams, providing persistent memory capabilities.
|
|
16
|
-
|
|
17
|
-
This toolkit integrates Memori's memory system with Agno, allowing Agents and Teams to:
|
|
18
|
-
- Store and retrieve conversation history
|
|
19
|
-
- Search through past interactions
|
|
20
|
-
- Maintain user preferences and context
|
|
21
|
-
- Build long-term memory across sessions
|
|
22
|
-
|
|
23
|
-
Requirements:
|
|
24
|
-
- pip install memorisdk
|
|
25
|
-
- Database connection string (SQLite, PostgreSQL, etc.)
|
|
26
|
-
|
|
27
|
-
Example:
|
|
28
|
-
```python
|
|
29
|
-
from agno.tools.memori import MemoriTools
|
|
30
|
-
|
|
31
|
-
# Initialize with SQLite (default)
|
|
32
|
-
memori_tools = MemoriTools(
|
|
33
|
-
database_connect="sqlite:///agent_memory.db",
|
|
34
|
-
namespace="my_agent",
|
|
35
|
-
auto_ingest=True # Automatically ingest conversations
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
# Add to agent
|
|
39
|
-
agent = Agent(
|
|
40
|
-
model=OpenAIChat(),
|
|
41
|
-
tools=[memori_tools],
|
|
42
|
-
description="An AI assistant with persistent memory"
|
|
43
|
-
)
|
|
44
|
-
```
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
def __init__(
|
|
48
|
-
self,
|
|
49
|
-
database_connect: Optional[str] = None,
|
|
50
|
-
namespace: Optional[str] = None,
|
|
51
|
-
conscious_ingest: bool = True,
|
|
52
|
-
auto_ingest: bool = True,
|
|
53
|
-
verbose: bool = False,
|
|
54
|
-
config: Optional[Dict[str, Any]] = None,
|
|
55
|
-
auto_enable: bool = True,
|
|
56
|
-
enable_search_memory: bool = True,
|
|
57
|
-
enable_record_conversation: bool = True,
|
|
58
|
-
enable_get_memory_stats: bool = True,
|
|
59
|
-
all: bool = False,
|
|
60
|
-
**kwargs,
|
|
61
|
-
):
|
|
62
|
-
"""
|
|
63
|
-
Initialize Memori toolkit.
|
|
64
|
-
|
|
65
|
-
Args:
|
|
66
|
-
database_connect: Database connection string (e.g., "sqlite:///memory.db")
|
|
67
|
-
namespace: Namespace for organizing memories (e.g., "agent_v1", "user_session")
|
|
68
|
-
conscious_ingest: Whether to use conscious memory ingestion
|
|
69
|
-
auto_ingest: Whether to automatically ingest conversations into memory
|
|
70
|
-
verbose: Enable verbose logging from Memori
|
|
71
|
-
config: Additional Memori configuration
|
|
72
|
-
auto_enable: Automatically enable the memory system on initialization
|
|
73
|
-
**kwargs: Additional arguments passed to Toolkit base class
|
|
74
|
-
"""
|
|
75
|
-
tools: List[Any] = []
|
|
76
|
-
if all or enable_search_memory:
|
|
77
|
-
tools.append(self.search_memory)
|
|
78
|
-
if all or enable_record_conversation:
|
|
79
|
-
tools.append(self.record_conversation)
|
|
80
|
-
if all or enable_get_memory_stats:
|
|
81
|
-
tools.append(self.get_memory_stats)
|
|
82
|
-
|
|
83
|
-
super().__init__(name="memori_tools", tools=tools, **kwargs)
|
|
84
|
-
|
|
85
|
-
# Set default database connection if not provided
|
|
86
|
-
if not database_connect:
|
|
87
|
-
sqlite_db = "sqlite:///agno_memori_memory.db"
|
|
88
|
-
log_info(f"No database connection provided, using default SQLite database at {sqlite_db}")
|
|
89
|
-
database_connect = sqlite_db
|
|
90
|
-
|
|
91
|
-
self.database_connect = database_connect
|
|
92
|
-
self.namespace = namespace or "agno_default"
|
|
93
|
-
self.conscious_ingest = conscious_ingest
|
|
94
|
-
self.auto_ingest = auto_ingest
|
|
95
|
-
self.verbose = verbose
|
|
96
|
-
self.config = config or {}
|
|
97
|
-
|
|
98
|
-
try:
|
|
99
|
-
# Initialize Memori memory system
|
|
100
|
-
log_debug(f"Initializing Memori with database: {self.database_connect}")
|
|
101
|
-
self.memory_system = Memori(
|
|
102
|
-
database_connect=self.database_connect,
|
|
103
|
-
conscious_ingest=self.conscious_ingest,
|
|
104
|
-
auto_ingest=self.auto_ingest,
|
|
105
|
-
verbose=self.verbose,
|
|
106
|
-
namespace=self.namespace,
|
|
107
|
-
**self.config,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
# Enable the memory system if auto_enable is True
|
|
111
|
-
if auto_enable:
|
|
112
|
-
self.memory_system.enable()
|
|
113
|
-
log_debug("Memori memory system enabled")
|
|
114
|
-
|
|
115
|
-
# Create the memory tool for internal use
|
|
116
|
-
self._memory_tool = create_memory_tool(self.memory_system)
|
|
117
|
-
|
|
118
|
-
except Exception as e:
|
|
119
|
-
log_error(f"Failed to initialize Memori: {e}")
|
|
120
|
-
raise ConnectionError("Failed to initialize Memori memory system") from e
|
|
121
|
-
|
|
122
|
-
def search_memory(
|
|
123
|
-
self,
|
|
124
|
-
query: str,
|
|
125
|
-
limit: Optional[int] = None,
|
|
126
|
-
) -> str:
|
|
127
|
-
"""
|
|
128
|
-
Search the Agent's memory for past conversations and information.
|
|
129
|
-
|
|
130
|
-
This performs semantic search across all stored memories to find
|
|
131
|
-
relevant information based on the provided query.
|
|
132
|
-
|
|
133
|
-
Args:
|
|
134
|
-
query: What to search for in memory (e.g., "past conversations about AI", "user preferences")
|
|
135
|
-
limit: Maximum number of results to return (optional)
|
|
136
|
-
|
|
137
|
-
Returns:
|
|
138
|
-
str: JSON-encoded search results or error message
|
|
139
|
-
|
|
140
|
-
Example:
|
|
141
|
-
search_memory("user's favorite programming languages")
|
|
142
|
-
search_memory("previous discussions about machine learning")
|
|
143
|
-
"""
|
|
144
|
-
try:
|
|
145
|
-
if not query.strip():
|
|
146
|
-
return json.dumps({"error": "Please provide a search query"})
|
|
147
|
-
|
|
148
|
-
log_debug(f"Searching memory for: {query}")
|
|
149
|
-
|
|
150
|
-
# Execute search using Memori's memory tool
|
|
151
|
-
result = self._memory_tool.execute(query=query.strip())
|
|
152
|
-
|
|
153
|
-
if result:
|
|
154
|
-
# If limit is specified, truncate results
|
|
155
|
-
if limit and isinstance(result, list):
|
|
156
|
-
result = result[:limit]
|
|
157
|
-
|
|
158
|
-
return json.dumps(
|
|
159
|
-
{
|
|
160
|
-
"success": True,
|
|
161
|
-
"query": query,
|
|
162
|
-
"results": result,
|
|
163
|
-
"count": len(result) if isinstance(result, list) else 1,
|
|
164
|
-
}
|
|
165
|
-
)
|
|
166
|
-
else:
|
|
167
|
-
return json.dumps(
|
|
168
|
-
{
|
|
169
|
-
"success": True,
|
|
170
|
-
"query": query,
|
|
171
|
-
"results": [],
|
|
172
|
-
"count": 0,
|
|
173
|
-
"message": "No relevant memories found",
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
except Exception as e:
|
|
178
|
-
log_error(f"Error searching memory: {e}")
|
|
179
|
-
return json.dumps({"success": False, "error": f"Memory search error: {str(e)}"})
|
|
180
|
-
|
|
181
|
-
def record_conversation(self, content: str) -> str:
|
|
182
|
-
"""
|
|
183
|
-
Add important information or facts to memory.
|
|
184
|
-
|
|
185
|
-
Use this tool to store important information, user preferences, facts, or context that should be remembered
|
|
186
|
-
for future conversations.
|
|
187
|
-
|
|
188
|
-
Args:
|
|
189
|
-
content: The information/facts to store in memory
|
|
190
|
-
|
|
191
|
-
Returns:
|
|
192
|
-
str: Success message or error details
|
|
193
|
-
|
|
194
|
-
Example:
|
|
195
|
-
record_conversation("User prefers Python over JavaScript")
|
|
196
|
-
record_conversation("User is working on an e-commerce project using Django")
|
|
197
|
-
record_conversation("User's name is John and they live in NYC")
|
|
198
|
-
"""
|
|
199
|
-
try:
|
|
200
|
-
if not content.strip():
|
|
201
|
-
return json.dumps({"success": False, "error": "Content cannot be empty"})
|
|
202
|
-
|
|
203
|
-
log_debug(f"Adding conversation: {content}")
|
|
204
|
-
|
|
205
|
-
# Extract the actual AI response from the agent's conversation history
|
|
206
|
-
ai_output = "I've noted this information and will remember it."
|
|
207
|
-
|
|
208
|
-
self.memory_system.record_conversation(user_input=content, ai_output=str(ai_output))
|
|
209
|
-
return json.dumps(
|
|
210
|
-
{
|
|
211
|
-
"success": True,
|
|
212
|
-
"message": "Memory added successfully via conversation recording",
|
|
213
|
-
"content_length": len(content),
|
|
214
|
-
}
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
except Exception as e:
|
|
218
|
-
log_error(f"Error adding memory: {e}")
|
|
219
|
-
return json.dumps({"success": False, "error": f"Failed to add memory: {str(e)}"})
|
|
220
|
-
|
|
221
|
-
def get_memory_stats(
|
|
222
|
-
self,
|
|
223
|
-
) -> str:
|
|
224
|
-
"""
|
|
225
|
-
Get statistics about the memory system.
|
|
226
|
-
|
|
227
|
-
Returns information about the current state of the memory system,
|
|
228
|
-
including total memories, memory distribution by retention type
|
|
229
|
-
(short-term vs long-term), and system configuration.
|
|
230
|
-
|
|
231
|
-
Returns:
|
|
232
|
-
str: JSON-encoded memory statistics
|
|
233
|
-
|
|
234
|
-
Example:
|
|
235
|
-
Returns statistics like:
|
|
236
|
-
{
|
|
237
|
-
"success": true,
|
|
238
|
-
"total_memories": 42,
|
|
239
|
-
"memories_by_retention": {
|
|
240
|
-
"short_term": 5,
|
|
241
|
-
"long_term": 37
|
|
242
|
-
},
|
|
243
|
-
"namespace": "my_agent",
|
|
244
|
-
"conscious_ingest": true,
|
|
245
|
-
"auto_ingest": true,
|
|
246
|
-
"memory_system_enabled": true
|
|
247
|
-
}
|
|
248
|
-
"""
|
|
249
|
-
try:
|
|
250
|
-
log_debug("Retrieving memory statistics")
|
|
251
|
-
|
|
252
|
-
# Base stats about the system configuration
|
|
253
|
-
stats = {
|
|
254
|
-
"success": True,
|
|
255
|
-
"namespace": self.namespace,
|
|
256
|
-
"database_connect": self.database_connect,
|
|
257
|
-
"conscious_ingest": self.conscious_ingest,
|
|
258
|
-
"auto_ingest": self.auto_ingest,
|
|
259
|
-
"verbose": self.verbose,
|
|
260
|
-
"memory_system_enabled": hasattr(self.memory_system, "_enabled") and self.memory_system._enabled,
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
# Get Memori's built-in memory statistics
|
|
264
|
-
try:
|
|
265
|
-
if hasattr(self.memory_system, "get_memory_stats"):
|
|
266
|
-
# Use the get_memory_stats method as shown in the example
|
|
267
|
-
memori_stats = self.memory_system.get_memory_stats()
|
|
268
|
-
|
|
269
|
-
# Add the Memori-specific stats to our response
|
|
270
|
-
if isinstance(memori_stats, dict):
|
|
271
|
-
# Include total memories
|
|
272
|
-
if "total_memories" in memori_stats:
|
|
273
|
-
stats["total_memories"] = memori_stats["total_memories"]
|
|
274
|
-
|
|
275
|
-
# Include memory distribution by retention type
|
|
276
|
-
if "memories_by_retention" in memori_stats:
|
|
277
|
-
stats["memories_by_retention"] = memori_stats["memories_by_retention"]
|
|
278
|
-
|
|
279
|
-
# Also add individual counts for convenience
|
|
280
|
-
retention_info = memori_stats["memories_by_retention"]
|
|
281
|
-
stats["short_term_memories"] = retention_info.get("short_term", 0)
|
|
282
|
-
stats["long_term_memories"] = retention_info.get("long_term", 0)
|
|
283
|
-
|
|
284
|
-
# Include any other available stats
|
|
285
|
-
for key, value in memori_stats.items():
|
|
286
|
-
if key not in stats:
|
|
287
|
-
stats[key] = value
|
|
288
|
-
|
|
289
|
-
log_debug(
|
|
290
|
-
f"Retrieved memory stats: total={stats.get('total_memories', 0)}, "
|
|
291
|
-
f"short_term={stats.get('short_term_memories', 0)}, "
|
|
292
|
-
f"long_term={stats.get('long_term_memories', 0)}"
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
else:
|
|
296
|
-
log_debug("get_memory_stats method not available, providing basic stats only")
|
|
297
|
-
stats["total_memories"] = 0
|
|
298
|
-
stats["memories_by_retention"] = {"short_term": 0, "long_term": 0}
|
|
299
|
-
stats["short_term_memories"] = 0
|
|
300
|
-
stats["long_term_memories"] = 0
|
|
301
|
-
|
|
302
|
-
except Exception as e:
|
|
303
|
-
log_debug(f"Could not retrieve detailed memory stats: {e}")
|
|
304
|
-
# Provide basic stats if detailed stats fail
|
|
305
|
-
stats["total_memories"] = 0
|
|
306
|
-
stats["memories_by_retention"] = {"short_term": 0, "long_term": 0}
|
|
307
|
-
stats["short_term_memories"] = 0
|
|
308
|
-
stats["long_term_memories"] = 0
|
|
309
|
-
stats["stats_warning"] = "Detailed memory statistics not available"
|
|
310
|
-
|
|
311
|
-
return json.dumps(stats)
|
|
312
|
-
|
|
313
|
-
except Exception as e:
|
|
314
|
-
log_error(f"Error getting memory stats: {e}")
|
|
315
|
-
return json.dumps({"success": False, "error": f"Failed to get memory statistics: {str(e)}"})
|
|
316
|
-
|
|
317
|
-
def enable_memory_system(self) -> bool:
|
|
318
|
-
"""Enable the Memori memory system."""
|
|
319
|
-
try:
|
|
320
|
-
self.memory_system.enable()
|
|
321
|
-
log_debug("Memori memory system enabled")
|
|
322
|
-
return True
|
|
323
|
-
except Exception as e:
|
|
324
|
-
log_error(f"Failed to enable memory system: {e}")
|
|
325
|
-
return False
|
|
326
|
-
|
|
327
|
-
def disable_memory_system(self) -> bool:
|
|
328
|
-
"""Disable the Memori memory system."""
|
|
329
|
-
try:
|
|
330
|
-
if hasattr(self.memory_system, "disable"):
|
|
331
|
-
self.memory_system.disable()
|
|
332
|
-
log_debug("Memori memory system disabled")
|
|
333
|
-
return True
|
|
334
|
-
else:
|
|
335
|
-
log_warning("Memory system disable method not available")
|
|
336
|
-
return False
|
|
337
|
-
except Exception as e:
|
|
338
|
-
log_error(f"Failed to disable memory system: {e}")
|
|
339
|
-
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|