agno 2.2.13__py3-none-any.whl → 2.3.1__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.
Files changed (92) hide show
  1. agno/agent/agent.py +197 -110
  2. agno/api/api.py +2 -0
  3. agno/db/base.py +26 -0
  4. agno/db/dynamo/dynamo.py +8 -0
  5. agno/db/dynamo/schemas.py +1 -0
  6. agno/db/firestore/firestore.py +8 -0
  7. agno/db/firestore/schemas.py +1 -0
  8. agno/db/gcs_json/gcs_json_db.py +8 -0
  9. agno/db/in_memory/in_memory_db.py +8 -1
  10. agno/db/json/json_db.py +8 -0
  11. agno/db/migrations/manager.py +199 -0
  12. agno/db/migrations/versions/__init__.py +0 -0
  13. agno/db/migrations/versions/v2_3_0.py +938 -0
  14. agno/db/mongo/async_mongo.py +16 -6
  15. agno/db/mongo/mongo.py +11 -0
  16. agno/db/mongo/schemas.py +3 -0
  17. agno/db/mongo/utils.py +17 -0
  18. agno/db/mysql/mysql.py +76 -3
  19. agno/db/mysql/schemas.py +20 -10
  20. agno/db/postgres/async_postgres.py +99 -25
  21. agno/db/postgres/postgres.py +75 -6
  22. agno/db/postgres/schemas.py +30 -20
  23. agno/db/redis/redis.py +15 -2
  24. agno/db/redis/schemas.py +4 -0
  25. agno/db/schemas/memory.py +13 -0
  26. agno/db/singlestore/schemas.py +11 -0
  27. agno/db/singlestore/singlestore.py +79 -5
  28. agno/db/sqlite/async_sqlite.py +97 -19
  29. agno/db/sqlite/schemas.py +10 -0
  30. agno/db/sqlite/sqlite.py +79 -2
  31. agno/db/surrealdb/surrealdb.py +8 -0
  32. agno/knowledge/chunking/semantic.py +7 -2
  33. agno/knowledge/embedder/nebius.py +1 -1
  34. agno/knowledge/knowledge.py +57 -86
  35. agno/knowledge/reader/csv_reader.py +7 -9
  36. agno/knowledge/reader/docx_reader.py +5 -5
  37. agno/knowledge/reader/field_labeled_csv_reader.py +16 -18
  38. agno/knowledge/reader/json_reader.py +5 -4
  39. agno/knowledge/reader/markdown_reader.py +8 -8
  40. agno/knowledge/reader/pdf_reader.py +11 -11
  41. agno/knowledge/reader/pptx_reader.py +5 -5
  42. agno/knowledge/reader/s3_reader.py +3 -3
  43. agno/knowledge/reader/text_reader.py +8 -8
  44. agno/knowledge/reader/web_search_reader.py +1 -48
  45. agno/knowledge/reader/website_reader.py +10 -10
  46. agno/models/anthropic/claude.py +319 -28
  47. agno/models/aws/claude.py +32 -0
  48. agno/models/azure/openai_chat.py +19 -10
  49. agno/models/base.py +612 -545
  50. agno/models/cerebras/cerebras.py +8 -11
  51. agno/models/cohere/chat.py +27 -1
  52. agno/models/google/gemini.py +39 -7
  53. agno/models/groq/groq.py +25 -11
  54. agno/models/meta/llama.py +20 -9
  55. agno/models/meta/llama_openai.py +3 -19
  56. agno/models/nebius/nebius.py +4 -4
  57. agno/models/openai/chat.py +30 -14
  58. agno/models/openai/responses.py +10 -13
  59. agno/models/response.py +1 -0
  60. agno/models/vertexai/claude.py +26 -0
  61. agno/os/app.py +8 -19
  62. agno/os/router.py +54 -0
  63. agno/os/routers/knowledge/knowledge.py +2 -2
  64. agno/os/schema.py +2 -2
  65. agno/session/agent.py +57 -92
  66. agno/session/summary.py +1 -1
  67. agno/session/team.py +62 -112
  68. agno/session/workflow.py +353 -57
  69. agno/team/team.py +227 -125
  70. agno/tools/models/nebius.py +5 -5
  71. agno/tools/models_labs.py +20 -10
  72. agno/tools/nano_banana.py +151 -0
  73. agno/tools/yfinance.py +12 -11
  74. agno/utils/http.py +111 -0
  75. agno/utils/media.py +11 -0
  76. agno/utils/models/claude.py +8 -0
  77. agno/utils/print_response/agent.py +33 -12
  78. agno/utils/print_response/team.py +22 -12
  79. agno/vectordb/couchbase/couchbase.py +6 -2
  80. agno/workflow/condition.py +13 -0
  81. agno/workflow/loop.py +13 -0
  82. agno/workflow/parallel.py +13 -0
  83. agno/workflow/router.py +13 -0
  84. agno/workflow/step.py +120 -20
  85. agno/workflow/steps.py +13 -0
  86. agno/workflow/workflow.py +76 -63
  87. {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/METADATA +6 -2
  88. {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/RECORD +91 -88
  89. agno/tools/googlesearch.py +0 -98
  90. {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/WHEEL +0 -0
  91. {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/licenses/LICENSE +0 -0
  92. {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/top_level.txt +0 -0
agno/workflow/workflow.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import warnings
2
3
  from dataclasses import dataclass
3
4
  from datetime import datetime
4
5
  from os import getenv
@@ -50,7 +51,7 @@ from agno.run.workflow import (
50
51
  WorkflowRunOutputEvent,
51
52
  WorkflowStartedEvent,
52
53
  )
53
- from agno.session.workflow import WorkflowSession
54
+ from agno.session.workflow import WorkflowChatInteraction, WorkflowSession
54
55
  from agno.team.team import Team
55
56
  from agno.utils.common import is_typed_dict, validate_typed_dict
56
57
  from agno.utils.log import (
@@ -153,8 +154,6 @@ class Workflow:
153
154
  stream: Optional[bool] = None
154
155
  # Stream the intermediate steps from the Workflow
155
156
  stream_events: bool = False
156
- # [Deprecated] Stream the intermediate steps from the Workflow
157
- stream_intermediate_steps: bool = False
158
157
  # Stream events from executors (agents/teams/functions) within steps
159
158
  stream_executor_events: bool = True
160
159
 
@@ -184,6 +183,9 @@ class Workflow:
184
183
  # Number of historical runs to include in the messages
185
184
  num_history_runs: int = 3
186
185
 
186
+ # Deprecated. Use stream_events instead.
187
+ stream_intermediate_steps: bool = False
188
+
187
189
  def __init__(
188
190
  self,
189
191
  id: Optional[str] = None,
@@ -224,8 +226,6 @@ class Workflow:
224
226
  self.store_events = store_events
225
227
  self.events_to_skip = events_to_skip or []
226
228
  self.stream = stream
227
- self.stream_events = stream_events
228
- self.stream_intermediate_steps = stream_intermediate_steps
229
229
  self.stream_executor_events = stream_executor_events
230
230
  self.store_executor_outputs = store_executor_outputs
231
231
  self.input_schema = input_schema
@@ -237,6 +237,14 @@ class Workflow:
237
237
  self.num_history_runs = num_history_runs
238
238
  self._workflow_session: Optional[WorkflowSession] = None
239
239
 
240
+ if stream_intermediate_steps:
241
+ warnings.warn(
242
+ "The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
243
+ DeprecationWarning,
244
+ stacklevel=2,
245
+ )
246
+ self.stream_events = stream_events or stream_intermediate_steps
247
+
240
248
  # Warn if workflow history is enabled without a database
241
249
  if self.add_workflow_history_to_steps and self.db is None:
242
250
  log_warning(
@@ -755,13 +763,12 @@ class Workflow:
755
763
  Returns:
756
764
  WorkflowSession: The WorkflowSession loaded from the database or created if it does not exist.
757
765
  """
758
- if not session_id and not self.session_id:
759
- raise Exception("No session_id provided")
760
-
761
766
  session_id_to_load = session_id or self.session_id
767
+ if session_id_to_load is None:
768
+ raise Exception("No session_id provided")
762
769
 
763
770
  # Try to load from database
764
- if self.db is not None and session_id_to_load is not None:
771
+ if self.db is not None:
765
772
  workflow_session = cast(WorkflowSession, await self._aread_session(session_id=session_id_to_load))
766
773
  return workflow_session
767
774
 
@@ -831,6 +838,54 @@ class Workflow:
831
838
  self._upsert_session(session=session)
832
839
  log_debug(f"Created or updated WorkflowSession record: {session.session_id}")
833
840
 
841
+ def get_chat_history(
842
+ self, session_id: Optional[str] = None, last_n_runs: Optional[int] = None
843
+ ) -> List[WorkflowChatInteraction]:
844
+ """Return a list of dictionaries containing the input and output for each run in the session.
845
+
846
+ Args:
847
+ session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
848
+ last_n_runs: Number of recent runs to include. If None, all runs will be considered.
849
+
850
+ Returns:
851
+ A list of WorkflowChatInteraction objects.
852
+ """
853
+ session_id = session_id or self.session_id
854
+ if session_id is None:
855
+ log_warning("Session ID is not set, cannot get messages for session")
856
+ return []
857
+
858
+ session = self.get_session(
859
+ session_id=session_id,
860
+ )
861
+ if session is None:
862
+ raise Exception("Session not found")
863
+
864
+ return session.get_chat_history(last_n_runs=last_n_runs)
865
+
866
+ async def aget_chat_history(
867
+ self, session_id: Optional[str] = None, last_n_runs: Optional[int] = None
868
+ ) -> List[WorkflowChatInteraction]:
869
+ """Return a list of dictionaries containing the input and output for each run in the session.
870
+
871
+ Args:
872
+ session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
873
+ last_n_runs: Number of recent runs to include. If None, all runs will be considered.
874
+
875
+ Returns:
876
+ A list of dictionaries containing the input and output for each run.
877
+ """
878
+ session_id = session_id or self.session_id
879
+ if session_id is None:
880
+ log_warning("Session ID is not set, cannot get messages for session")
881
+ return []
882
+
883
+ session = await self.aget_session(session_id=session_id)
884
+ if session is None:
885
+ raise Exception("Session not found")
886
+
887
+ return session.get_chat_history(last_n_runs=last_n_runs)
888
+
834
889
  # -*- Session Database Functions
835
890
  async def _aread_session(self, session_id: str) -> Optional[WorkflowSession]:
836
891
  """Get a Session from the database."""
@@ -3617,6 +3672,12 @@ class Workflow:
3617
3672
  if background:
3618
3673
  if stream and websocket:
3619
3674
  # Consider both stream_events and stream_intermediate_steps (deprecated)
3675
+ if stream_intermediate_steps is not None:
3676
+ warnings.warn(
3677
+ "The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
3678
+ DeprecationWarning,
3679
+ stacklevel=2,
3680
+ )
3620
3681
  stream_events = stream_events or stream_intermediate_steps or False
3621
3682
 
3622
3683
  # Background + Streaming + WebSocket = Real-time events
@@ -3792,8 +3853,6 @@ class Workflow:
3792
3853
  videos: Optional[List[Video]] = None,
3793
3854
  files: Optional[List[File]] = None,
3794
3855
  stream: Optional[bool] = None,
3795
- stream_events: Optional[bool] = None,
3796
- stream_intermediate_steps: Optional[bool] = None,
3797
3856
  markdown: bool = True,
3798
3857
  show_time: bool = True,
3799
3858
  show_step_details: bool = True,
@@ -3812,12 +3871,10 @@ class Workflow:
3812
3871
  videos: Video input
3813
3872
  files: File input
3814
3873
  stream: Whether to stream the response content
3815
- stream_events: Whether to stream intermediate steps
3816
3874
  markdown: Whether to render content as markdown
3817
3875
  show_time: Whether to show execution time
3818
3876
  show_step_details: Whether to show individual step outputs
3819
3877
  console: Rich console instance (optional)
3820
- (deprecated) stream_intermediate_steps: Whether to stream intermediate step outputs. If None, uses workflow default.
3821
3878
  """
3822
3879
  if self._has_async_db():
3823
3880
  raise Exception("`print_response()` is not supported with an async DB. Please use `aprint_response()`.")
@@ -3825,19 +3882,8 @@ class Workflow:
3825
3882
  if stream is None:
3826
3883
  stream = self.stream or False
3827
3884
 
3828
- # Considering both stream_events and stream_intermediate_steps (deprecated)
3829
- stream_events = stream_events or stream_intermediate_steps
3830
-
3831
- # Can't stream events if streaming is disabled
3832
- if stream is False:
3833
- stream_events = False
3834
-
3835
- if stream_events is None:
3836
- stream_events = (
3837
- False
3838
- if (self.stream_events is None and self.stream_intermediate_steps is None)
3839
- else (self.stream_intermediate_steps or self.stream_events)
3840
- )
3885
+ if "stream_events" in kwargs:
3886
+ kwargs.pop("stream_events")
3841
3887
 
3842
3888
  if stream:
3843
3889
  print_response_stream(
@@ -3850,7 +3896,7 @@ class Workflow:
3850
3896
  images=images,
3851
3897
  videos=videos,
3852
3898
  files=files,
3853
- stream_events=stream_events,
3899
+ stream_events=True,
3854
3900
  markdown=markdown,
3855
3901
  show_time=show_time,
3856
3902
  show_step_details=show_step_details,
@@ -3886,8 +3932,6 @@ class Workflow:
3886
3932
  videos: Optional[List[Video]] = None,
3887
3933
  files: Optional[List[File]] = None,
3888
3934
  stream: Optional[bool] = None,
3889
- stream_events: Optional[bool] = None,
3890
- stream_intermediate_steps: Optional[bool] = None,
3891
3935
  markdown: bool = True,
3892
3936
  show_time: bool = True,
3893
3937
  show_step_details: bool = True,
@@ -3906,29 +3950,16 @@ class Workflow:
3906
3950
  videos: Video input
3907
3951
  files: Files input
3908
3952
  stream: Whether to stream the response content
3909
- stream_events: Whether to stream intermediate steps
3910
3953
  markdown: Whether to render content as markdown
3911
3954
  show_time: Whether to show execution time
3912
3955
  show_step_details: Whether to show individual step outputs
3913
3956
  console: Rich console instance (optional)
3914
- (deprecated) stream_intermediate_steps: Whether to stream intermediate step outputs. If None, uses workflow default.
3915
3957
  """
3916
3958
  if stream is None:
3917
3959
  stream = self.stream or False
3918
3960
 
3919
- # Considering both stream_events and stream_intermediate_steps (deprecated)
3920
- stream_events = stream_events or stream_intermediate_steps
3921
-
3922
- # Can't stream events if streaming is disabled
3923
- if stream is False:
3924
- stream_events = False
3925
-
3926
- if stream_events is None:
3927
- stream_events = (
3928
- False
3929
- if (self.stream_events is None and self.stream_intermediate_steps is None)
3930
- else (self.stream_intermediate_steps or self.stream_events)
3931
- )
3961
+ if "stream_events" in kwargs:
3962
+ kwargs.pop("stream_events")
3932
3963
 
3933
3964
  if stream:
3934
3965
  await aprint_response_stream(
@@ -3941,7 +3972,7 @@ class Workflow:
3941
3972
  images=images,
3942
3973
  videos=videos,
3943
3974
  files=files,
3944
- stream_events=stream_events,
3975
+ stream_events=True,
3945
3976
  markdown=markdown,
3946
3977
  show_time=show_time,
3947
3978
  show_step_details=show_step_details,
@@ -4174,8 +4205,6 @@ class Workflow:
4174
4205
  user: str = "User",
4175
4206
  emoji: str = ":technologist:",
4176
4207
  stream: Optional[bool] = None,
4177
- stream_events: Optional[bool] = None,
4178
- stream_intermediate_steps: Optional[bool] = None,
4179
4208
  markdown: bool = True,
4180
4209
  show_time: bool = True,
4181
4210
  show_step_details: bool = True,
@@ -4195,12 +4224,10 @@ class Workflow:
4195
4224
  user: Display name for the user in the CLI prompt. Defaults to "User".
4196
4225
  emoji: Emoji to display next to the user name in prompts. Defaults to ":technologist:".
4197
4226
  stream: Whether to stream the workflow response. If None, uses workflow default.
4198
- stream_events: Whether to stream intermediate step outputs. If None, uses workflow default.
4199
4227
  markdown: Whether to render output as markdown. Defaults to True.
4200
4228
  show_time: Whether to display timestamps in the output. Defaults to True.
4201
4229
  show_step_details: Whether to show detailed step information. Defaults to True.
4202
4230
  exit_on: List of commands that will exit the CLI. Defaults to ["exit", "quit", "bye", "stop"].
4203
- (deprecated) stream_intermediate_steps: Whether to stream intermediate step outputs. If None, uses workflow default.
4204
4231
  **kwargs: Additional keyword arguments passed to the workflow's print_response method.
4205
4232
 
4206
4233
  Returns:
@@ -4209,14 +4236,10 @@ class Workflow:
4209
4236
 
4210
4237
  from rich.prompt import Prompt
4211
4238
 
4212
- # Considering both stream_events and stream_intermediate_steps (deprecated)
4213
- stream_events = stream_events or stream_intermediate_steps or False
4214
-
4215
4239
  if input:
4216
4240
  self.print_response(
4217
4241
  input=input,
4218
4242
  stream=stream,
4219
- stream_events=stream_events,
4220
4243
  markdown=markdown,
4221
4244
  show_time=show_time,
4222
4245
  show_step_details=show_step_details,
@@ -4234,7 +4257,6 @@ class Workflow:
4234
4257
  self.print_response(
4235
4258
  input=message,
4236
4259
  stream=stream,
4237
- stream_events=stream_events,
4238
4260
  markdown=markdown,
4239
4261
  show_time=show_time,
4240
4262
  show_step_details=show_step_details,
@@ -4251,8 +4273,6 @@ class Workflow:
4251
4273
  user: str = "User",
4252
4274
  emoji: str = ":technologist:",
4253
4275
  stream: Optional[bool] = None,
4254
- stream_events: Optional[bool] = None,
4255
- stream_intermediate_steps: Optional[bool] = None,
4256
4276
  markdown: bool = True,
4257
4277
  show_time: bool = True,
4258
4278
  show_step_details: bool = True,
@@ -4272,12 +4292,10 @@ class Workflow:
4272
4292
  user: Display name for the user in the CLI prompt. Defaults to "User".
4273
4293
  emoji: Emoji to display next to the user name in prompts. Defaults to ":technologist:".
4274
4294
  stream: Whether to stream the workflow response. If None, uses workflow default.
4275
- stream_events: Whether to stream events from the workflow. If None, uses workflow default.
4276
4295
  markdown: Whether to render output as markdown. Defaults to True.
4277
4296
  show_time: Whether to display timestamps in the output. Defaults to True.
4278
4297
  show_step_details: Whether to show detailed step information. Defaults to True.
4279
4298
  exit_on: List of commands that will exit the CLI. Defaults to ["exit", "quit", "bye", "stop"].
4280
- (deprecated) stream_intermediate_steps: Whether to stream intermediate step outputs. If None, uses workflow default.
4281
4299
  **kwargs: Additional keyword arguments passed to the workflow's print_response method.
4282
4300
 
4283
4301
  Returns:
@@ -4286,14 +4304,10 @@ class Workflow:
4286
4304
 
4287
4305
  from rich.prompt import Prompt
4288
4306
 
4289
- # Considering both stream_events and stream_intermediate_steps (deprecated)
4290
- stream_events = stream_events or stream_intermediate_steps or False
4291
-
4292
4307
  if input:
4293
4308
  await self.aprint_response(
4294
4309
  input=input,
4295
4310
  stream=stream,
4296
- stream_events=stream_events,
4297
4311
  markdown=markdown,
4298
4312
  show_time=show_time,
4299
4313
  show_step_details=show_step_details,
@@ -4311,7 +4325,6 @@ class Workflow:
4311
4325
  await self.aprint_response(
4312
4326
  input=message,
4313
4327
  stream=stream,
4314
- stream_events=stream_events,
4315
4328
  markdown=markdown,
4316
4329
  show_time=show_time,
4317
4330
  show_step_details=show_step_details,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.2.13
3
+ Version: 2.3.1
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
@@ -24,7 +24,7 @@ License-File: LICENSE
24
24
  Requires-Dist: docstring-parser
25
25
  Requires-Dist: gitpython
26
26
  Requires-Dist: h11>=0.16.0
27
- Requires-Dist: httpx
27
+ Requires-Dist: httpx[http2]
28
28
  Requires-Dist: packaging
29
29
  Requires-Dist: pydantic-settings
30
30
  Requires-Dist: pydantic
@@ -200,6 +200,9 @@ Provides-Extra: postgres
200
200
  Requires-Dist: psycopg-binary; extra == "postgres"
201
201
  Provides-Extra: async-postgres
202
202
  Requires-Dist: asyncpg; extra == "async-postgres"
203
+ Provides-Extra: async-mongo
204
+ Requires-Dist: pymongo; extra == "async-mongo"
205
+ Requires-Dist: motor; extra == "async-mongo"
203
206
  Provides-Extra: sqlite
204
207
  Requires-Dist: sqlalchemy; extra == "sqlite"
205
208
  Provides-Extra: gcs
@@ -336,6 +339,7 @@ Provides-Extra: storage
336
339
  Requires-Dist: agno[sql]; extra == "storage"
337
340
  Requires-Dist: agno[postgres]; extra == "storage"
338
341
  Requires-Dist: agno[async_postgres]; extra == "storage"
342
+ Requires-Dist: agno[async_mongo]; extra == "storage"
339
343
  Requires-Dist: agno[sqlite]; extra == "storage"
340
344
  Requires-Dist: agno[gcs]; extra == "storage"
341
345
  Requires-Dist: agno[firestore]; extra == "storage"