agno 2.1.2__py3-none-any.whl → 2.3.13__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 (314) hide show
  1. agno/agent/agent.py +5540 -2273
  2. agno/api/api.py +2 -0
  3. agno/api/os.py +1 -1
  4. agno/compression/__init__.py +3 -0
  5. agno/compression/manager.py +247 -0
  6. agno/culture/__init__.py +3 -0
  7. agno/culture/manager.py +956 -0
  8. agno/db/async_postgres/__init__.py +3 -0
  9. agno/db/base.py +689 -6
  10. agno/db/dynamo/dynamo.py +933 -37
  11. agno/db/dynamo/schemas.py +174 -10
  12. agno/db/dynamo/utils.py +63 -4
  13. agno/db/firestore/firestore.py +831 -9
  14. agno/db/firestore/schemas.py +51 -0
  15. agno/db/firestore/utils.py +102 -4
  16. agno/db/gcs_json/gcs_json_db.py +660 -12
  17. agno/db/gcs_json/utils.py +60 -26
  18. agno/db/in_memory/in_memory_db.py +287 -14
  19. agno/db/in_memory/utils.py +60 -2
  20. agno/db/json/json_db.py +590 -14
  21. agno/db/json/utils.py +60 -26
  22. agno/db/migrations/manager.py +199 -0
  23. agno/db/migrations/v1_to_v2.py +43 -13
  24. agno/db/migrations/versions/__init__.py +0 -0
  25. agno/db/migrations/versions/v2_3_0.py +938 -0
  26. agno/db/mongo/__init__.py +15 -1
  27. agno/db/mongo/async_mongo.py +2760 -0
  28. agno/db/mongo/mongo.py +879 -11
  29. agno/db/mongo/schemas.py +42 -0
  30. agno/db/mongo/utils.py +80 -8
  31. agno/db/mysql/__init__.py +2 -1
  32. agno/db/mysql/async_mysql.py +2912 -0
  33. agno/db/mysql/mysql.py +946 -68
  34. agno/db/mysql/schemas.py +72 -10
  35. agno/db/mysql/utils.py +198 -7
  36. agno/db/postgres/__init__.py +2 -1
  37. agno/db/postgres/async_postgres.py +2579 -0
  38. agno/db/postgres/postgres.py +942 -57
  39. agno/db/postgres/schemas.py +81 -18
  40. agno/db/postgres/utils.py +164 -2
  41. agno/db/redis/redis.py +671 -7
  42. agno/db/redis/schemas.py +50 -0
  43. agno/db/redis/utils.py +65 -7
  44. agno/db/schemas/__init__.py +2 -1
  45. agno/db/schemas/culture.py +120 -0
  46. agno/db/schemas/evals.py +1 -0
  47. agno/db/schemas/memory.py +17 -2
  48. agno/db/singlestore/schemas.py +63 -0
  49. agno/db/singlestore/singlestore.py +949 -83
  50. agno/db/singlestore/utils.py +60 -2
  51. agno/db/sqlite/__init__.py +2 -1
  52. agno/db/sqlite/async_sqlite.py +2911 -0
  53. agno/db/sqlite/schemas.py +62 -0
  54. agno/db/sqlite/sqlite.py +965 -46
  55. agno/db/sqlite/utils.py +169 -8
  56. agno/db/surrealdb/__init__.py +3 -0
  57. agno/db/surrealdb/metrics.py +292 -0
  58. agno/db/surrealdb/models.py +334 -0
  59. agno/db/surrealdb/queries.py +71 -0
  60. agno/db/surrealdb/surrealdb.py +1908 -0
  61. agno/db/surrealdb/utils.py +147 -0
  62. agno/db/utils.py +2 -0
  63. agno/eval/__init__.py +10 -0
  64. agno/eval/accuracy.py +75 -55
  65. agno/eval/agent_as_judge.py +861 -0
  66. agno/eval/base.py +29 -0
  67. agno/eval/performance.py +16 -7
  68. agno/eval/reliability.py +28 -16
  69. agno/eval/utils.py +35 -17
  70. agno/exceptions.py +27 -2
  71. agno/filters.py +354 -0
  72. agno/guardrails/prompt_injection.py +1 -0
  73. agno/hooks/__init__.py +3 -0
  74. agno/hooks/decorator.py +164 -0
  75. agno/integrations/discord/client.py +1 -1
  76. agno/knowledge/chunking/agentic.py +13 -10
  77. agno/knowledge/chunking/fixed.py +4 -1
  78. agno/knowledge/chunking/semantic.py +9 -4
  79. agno/knowledge/chunking/strategy.py +59 -15
  80. agno/knowledge/embedder/fastembed.py +1 -1
  81. agno/knowledge/embedder/nebius.py +1 -1
  82. agno/knowledge/embedder/ollama.py +8 -0
  83. agno/knowledge/embedder/openai.py +8 -8
  84. agno/knowledge/embedder/sentence_transformer.py +6 -2
  85. agno/knowledge/embedder/vllm.py +262 -0
  86. agno/knowledge/knowledge.py +1618 -318
  87. agno/knowledge/reader/base.py +6 -2
  88. agno/knowledge/reader/csv_reader.py +8 -10
  89. agno/knowledge/reader/docx_reader.py +5 -6
  90. agno/knowledge/reader/field_labeled_csv_reader.py +16 -20
  91. agno/knowledge/reader/json_reader.py +5 -4
  92. agno/knowledge/reader/markdown_reader.py +8 -8
  93. agno/knowledge/reader/pdf_reader.py +17 -19
  94. agno/knowledge/reader/pptx_reader.py +101 -0
  95. agno/knowledge/reader/reader_factory.py +32 -3
  96. agno/knowledge/reader/s3_reader.py +3 -3
  97. agno/knowledge/reader/tavily_reader.py +193 -0
  98. agno/knowledge/reader/text_reader.py +22 -10
  99. agno/knowledge/reader/web_search_reader.py +1 -48
  100. agno/knowledge/reader/website_reader.py +10 -10
  101. agno/knowledge/reader/wikipedia_reader.py +33 -1
  102. agno/knowledge/types.py +1 -0
  103. agno/knowledge/utils.py +72 -7
  104. agno/media.py +22 -6
  105. agno/memory/__init__.py +14 -1
  106. agno/memory/manager.py +544 -83
  107. agno/memory/strategies/__init__.py +15 -0
  108. agno/memory/strategies/base.py +66 -0
  109. agno/memory/strategies/summarize.py +196 -0
  110. agno/memory/strategies/types.py +37 -0
  111. agno/models/aimlapi/aimlapi.py +17 -0
  112. agno/models/anthropic/claude.py +515 -40
  113. agno/models/aws/bedrock.py +102 -21
  114. agno/models/aws/claude.py +131 -274
  115. agno/models/azure/ai_foundry.py +41 -19
  116. agno/models/azure/openai_chat.py +39 -8
  117. agno/models/base.py +1249 -525
  118. agno/models/cerebras/cerebras.py +91 -21
  119. agno/models/cerebras/cerebras_openai.py +21 -2
  120. agno/models/cohere/chat.py +40 -6
  121. agno/models/cometapi/cometapi.py +18 -1
  122. agno/models/dashscope/dashscope.py +2 -3
  123. agno/models/deepinfra/deepinfra.py +18 -1
  124. agno/models/deepseek/deepseek.py +69 -3
  125. agno/models/fireworks/fireworks.py +18 -1
  126. agno/models/google/gemini.py +877 -80
  127. agno/models/google/utils.py +22 -0
  128. agno/models/groq/groq.py +51 -18
  129. agno/models/huggingface/huggingface.py +17 -6
  130. agno/models/ibm/watsonx.py +16 -6
  131. agno/models/internlm/internlm.py +18 -1
  132. agno/models/langdb/langdb.py +13 -1
  133. agno/models/litellm/chat.py +44 -9
  134. agno/models/litellm/litellm_openai.py +18 -1
  135. agno/models/message.py +28 -5
  136. agno/models/meta/llama.py +47 -14
  137. agno/models/meta/llama_openai.py +22 -17
  138. agno/models/mistral/mistral.py +8 -4
  139. agno/models/nebius/nebius.py +6 -7
  140. agno/models/nvidia/nvidia.py +20 -3
  141. agno/models/ollama/chat.py +24 -8
  142. agno/models/openai/chat.py +104 -29
  143. agno/models/openai/responses.py +101 -81
  144. agno/models/openrouter/openrouter.py +60 -3
  145. agno/models/perplexity/perplexity.py +17 -1
  146. agno/models/portkey/portkey.py +7 -6
  147. agno/models/requesty/requesty.py +24 -4
  148. agno/models/response.py +73 -2
  149. agno/models/sambanova/sambanova.py +20 -3
  150. agno/models/siliconflow/siliconflow.py +19 -2
  151. agno/models/together/together.py +20 -3
  152. agno/models/utils.py +254 -8
  153. agno/models/vercel/v0.py +20 -3
  154. agno/models/vertexai/__init__.py +0 -0
  155. agno/models/vertexai/claude.py +190 -0
  156. agno/models/vllm/vllm.py +19 -14
  157. agno/models/xai/xai.py +19 -2
  158. agno/os/app.py +549 -152
  159. agno/os/auth.py +190 -3
  160. agno/os/config.py +23 -0
  161. agno/os/interfaces/a2a/router.py +8 -11
  162. agno/os/interfaces/a2a/utils.py +1 -1
  163. agno/os/interfaces/agui/router.py +18 -3
  164. agno/os/interfaces/agui/utils.py +152 -39
  165. agno/os/interfaces/slack/router.py +55 -37
  166. agno/os/interfaces/slack/slack.py +9 -1
  167. agno/os/interfaces/whatsapp/router.py +0 -1
  168. agno/os/interfaces/whatsapp/security.py +3 -1
  169. agno/os/mcp.py +110 -52
  170. agno/os/middleware/__init__.py +2 -0
  171. agno/os/middleware/jwt.py +676 -112
  172. agno/os/router.py +40 -1478
  173. agno/os/routers/agents/__init__.py +3 -0
  174. agno/os/routers/agents/router.py +599 -0
  175. agno/os/routers/agents/schema.py +261 -0
  176. agno/os/routers/evals/evals.py +96 -39
  177. agno/os/routers/evals/schemas.py +65 -33
  178. agno/os/routers/evals/utils.py +80 -10
  179. agno/os/routers/health.py +10 -4
  180. agno/os/routers/knowledge/knowledge.py +196 -38
  181. agno/os/routers/knowledge/schemas.py +82 -22
  182. agno/os/routers/memory/memory.py +279 -52
  183. agno/os/routers/memory/schemas.py +46 -17
  184. agno/os/routers/metrics/metrics.py +20 -8
  185. agno/os/routers/metrics/schemas.py +16 -16
  186. agno/os/routers/session/session.py +462 -34
  187. agno/os/routers/teams/__init__.py +3 -0
  188. agno/os/routers/teams/router.py +512 -0
  189. agno/os/routers/teams/schema.py +257 -0
  190. agno/os/routers/traces/__init__.py +3 -0
  191. agno/os/routers/traces/schemas.py +414 -0
  192. agno/os/routers/traces/traces.py +499 -0
  193. agno/os/routers/workflows/__init__.py +3 -0
  194. agno/os/routers/workflows/router.py +624 -0
  195. agno/os/routers/workflows/schema.py +75 -0
  196. agno/os/schema.py +256 -693
  197. agno/os/scopes.py +469 -0
  198. agno/os/utils.py +514 -36
  199. agno/reasoning/anthropic.py +80 -0
  200. agno/reasoning/gemini.py +73 -0
  201. agno/reasoning/openai.py +5 -0
  202. agno/reasoning/vertexai.py +76 -0
  203. agno/run/__init__.py +6 -0
  204. agno/run/agent.py +155 -32
  205. agno/run/base.py +55 -3
  206. agno/run/requirement.py +181 -0
  207. agno/run/team.py +125 -38
  208. agno/run/workflow.py +72 -18
  209. agno/session/agent.py +102 -89
  210. agno/session/summary.py +56 -15
  211. agno/session/team.py +164 -90
  212. agno/session/workflow.py +405 -40
  213. agno/table.py +10 -0
  214. agno/team/team.py +3974 -1903
  215. agno/tools/dalle.py +2 -4
  216. agno/tools/eleven_labs.py +23 -25
  217. agno/tools/exa.py +21 -16
  218. agno/tools/file.py +153 -23
  219. agno/tools/file_generation.py +16 -10
  220. agno/tools/firecrawl.py +15 -7
  221. agno/tools/function.py +193 -38
  222. agno/tools/gmail.py +238 -14
  223. agno/tools/google_drive.py +271 -0
  224. agno/tools/googlecalendar.py +36 -8
  225. agno/tools/googlesheets.py +20 -5
  226. agno/tools/jira.py +20 -0
  227. agno/tools/mcp/__init__.py +10 -0
  228. agno/tools/mcp/mcp.py +331 -0
  229. agno/tools/mcp/multi_mcp.py +347 -0
  230. agno/tools/mcp/params.py +24 -0
  231. agno/tools/mcp_toolbox.py +3 -3
  232. agno/tools/models/nebius.py +5 -5
  233. agno/tools/models_labs.py +20 -10
  234. agno/tools/nano_banana.py +151 -0
  235. agno/tools/notion.py +204 -0
  236. agno/tools/parallel.py +314 -0
  237. agno/tools/postgres.py +76 -36
  238. agno/tools/redshift.py +406 -0
  239. agno/tools/scrapegraph.py +1 -1
  240. agno/tools/shopify.py +1519 -0
  241. agno/tools/slack.py +18 -3
  242. agno/tools/spotify.py +919 -0
  243. agno/tools/tavily.py +146 -0
  244. agno/tools/toolkit.py +25 -0
  245. agno/tools/workflow.py +8 -1
  246. agno/tools/yfinance.py +12 -11
  247. agno/tracing/__init__.py +12 -0
  248. agno/tracing/exporter.py +157 -0
  249. agno/tracing/schemas.py +276 -0
  250. agno/tracing/setup.py +111 -0
  251. agno/utils/agent.py +938 -0
  252. agno/utils/cryptography.py +22 -0
  253. agno/utils/dttm.py +33 -0
  254. agno/utils/events.py +151 -3
  255. agno/utils/gemini.py +15 -5
  256. agno/utils/hooks.py +118 -4
  257. agno/utils/http.py +113 -2
  258. agno/utils/knowledge.py +12 -5
  259. agno/utils/log.py +1 -0
  260. agno/utils/mcp.py +92 -2
  261. agno/utils/media.py +187 -1
  262. agno/utils/merge_dict.py +3 -3
  263. agno/utils/message.py +60 -0
  264. agno/utils/models/ai_foundry.py +9 -2
  265. agno/utils/models/claude.py +49 -14
  266. agno/utils/models/cohere.py +9 -2
  267. agno/utils/models/llama.py +9 -2
  268. agno/utils/models/mistral.py +4 -2
  269. agno/utils/print_response/agent.py +109 -16
  270. agno/utils/print_response/team.py +223 -30
  271. agno/utils/print_response/workflow.py +251 -34
  272. agno/utils/streamlit.py +1 -1
  273. agno/utils/team.py +98 -9
  274. agno/utils/tokens.py +657 -0
  275. agno/vectordb/base.py +39 -7
  276. agno/vectordb/cassandra/cassandra.py +21 -5
  277. agno/vectordb/chroma/chromadb.py +43 -12
  278. agno/vectordb/clickhouse/clickhousedb.py +21 -5
  279. agno/vectordb/couchbase/couchbase.py +29 -5
  280. agno/vectordb/lancedb/lance_db.py +92 -181
  281. agno/vectordb/langchaindb/langchaindb.py +24 -4
  282. agno/vectordb/lightrag/lightrag.py +17 -3
  283. agno/vectordb/llamaindex/llamaindexdb.py +25 -5
  284. agno/vectordb/milvus/milvus.py +50 -37
  285. agno/vectordb/mongodb/__init__.py +7 -1
  286. agno/vectordb/mongodb/mongodb.py +36 -30
  287. agno/vectordb/pgvector/pgvector.py +201 -77
  288. agno/vectordb/pineconedb/pineconedb.py +41 -23
  289. agno/vectordb/qdrant/qdrant.py +67 -54
  290. agno/vectordb/redis/__init__.py +9 -0
  291. agno/vectordb/redis/redisdb.py +682 -0
  292. agno/vectordb/singlestore/singlestore.py +50 -29
  293. agno/vectordb/surrealdb/surrealdb.py +31 -41
  294. agno/vectordb/upstashdb/upstashdb.py +34 -6
  295. agno/vectordb/weaviate/weaviate.py +53 -14
  296. agno/workflow/__init__.py +2 -0
  297. agno/workflow/agent.py +299 -0
  298. agno/workflow/condition.py +120 -18
  299. agno/workflow/loop.py +77 -10
  300. agno/workflow/parallel.py +231 -143
  301. agno/workflow/router.py +118 -17
  302. agno/workflow/step.py +609 -170
  303. agno/workflow/steps.py +73 -6
  304. agno/workflow/types.py +96 -21
  305. agno/workflow/workflow.py +2039 -262
  306. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/METADATA +201 -66
  307. agno-2.3.13.dist-info/RECORD +613 -0
  308. agno/tools/googlesearch.py +0 -98
  309. agno/tools/mcp.py +0 -679
  310. agno/tools/memori.py +0 -339
  311. agno-2.1.2.dist-info/RECORD +0 -543
  312. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +0 -0
  313. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/licenses/LICENSE +0 -0
  314. {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Set, Unio
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
5
+ from agno.filters import FilterExpr
5
6
  from agno.media import Audio, File, Image, Video
6
7
  from agno.models.message import Message
7
8
  from agno.models.response import ToolExecution
@@ -24,16 +25,18 @@ def print_response(
24
25
  show_message: bool = True,
25
26
  show_reasoning: bool = True,
26
27
  show_full_reasoning: bool = False,
28
+ show_member_responses: Optional[bool] = None,
27
29
  tags_to_include_in_markdown: Optional[Set[str]] = None,
28
30
  session_id: Optional[str] = None,
29
31
  session_state: Optional[Dict[str, Any]] = None,
30
32
  user_id: Optional[str] = None,
33
+ run_id: Optional[str] = None,
31
34
  audio: Optional[Sequence[Audio]] = None,
32
35
  images: Optional[Sequence[Image]] = None,
33
36
  videos: Optional[Sequence[Video]] = None,
34
37
  files: Optional[Sequence[File]] = None,
35
38
  markdown: bool = False,
36
- knowledge_filters: Optional[Dict[str, Any]] = None,
39
+ knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
37
40
  add_history_to_context: Optional[bool] = None,
38
41
  dependencies: Optional[Dict[str, Any]] = None,
39
42
  add_dependencies_to_context: Optional[bool] = None,
@@ -79,11 +82,13 @@ def print_response(
79
82
  # Run the agent
80
83
  run_response: TeamRunOutput = team.run( # type: ignore
81
84
  input=input,
85
+ run_id=run_id,
82
86
  images=images,
83
87
  audio=audio,
84
88
  videos=videos,
85
89
  files=files,
86
90
  stream=False,
91
+ stream_events=True,
87
92
  session_id=session_id,
88
93
  session_state=session_state,
89
94
  user_id=user_id,
@@ -151,7 +156,7 @@ def print_response(
151
156
 
152
157
  if isinstance(run_response, TeamRunOutput):
153
158
  # Handle member responses
154
- if team.show_members_responses:
159
+ if show_member_responses:
155
160
  for member_response in run_response.member_responses:
156
161
  # Handle member reasoning
157
162
  reasoning_steps = []
@@ -224,11 +229,23 @@ def print_response(
224
229
  panels.append(member_response_panel)
225
230
 
226
231
  if member_response.citations is not None and member_response.citations.urls is not None:
227
- md_content = "\n".join(
232
+ md_lines = []
233
+
234
+ # Add search queries if present
235
+ if member_response.citations.search_queries:
236
+ md_lines.append("**Search Queries:**")
237
+ for query in member_response.citations.search_queries:
238
+ md_lines.append(f"- {query}")
239
+ md_lines.append("") # Empty line before URLs
240
+
241
+ # Add URL citations
242
+ md_lines.extend(
228
243
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
229
244
  for i, citation in enumerate(member_response.citations.urls)
230
245
  if citation.url # Only include citations with valid URLs
231
246
  )
247
+
248
+ md_content = "\n".join(md_lines)
232
249
  if md_content: # Only create panel if there are citations
233
250
  citations_panel = create_panel(
234
251
  content=Markdown(md_content),
@@ -257,6 +274,15 @@ def print_response(
257
274
  # Join with blank lines between items
258
275
  tool_calls_text = "\n\n".join(lines)
259
276
 
277
+ # Add compression stats at end of tool calls
278
+ if team.compression_manager is not None and team.compression_manager.stats:
279
+ stats = team.compression_manager.stats
280
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
281
+ orig = stats.get("original_size", 1)
282
+ if stats.get("tool_results_compressed", 0) > 0:
283
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
284
+ team.compression_manager.stats.clear()
285
+
260
286
  team_tool_calls_panel = create_panel(
261
287
  content=tool_calls_text,
262
288
  title="Team Tool Calls",
@@ -279,11 +305,23 @@ def print_response(
279
305
 
280
306
  # Add citations
281
307
  if run_response.citations is not None and run_response.citations.urls is not None:
282
- md_content = "\n".join(
308
+ md_lines = []
309
+
310
+ # Add search queries if present
311
+ if run_response.citations.search_queries:
312
+ md_lines.append("**Search Queries:**")
313
+ for query in run_response.citations.search_queries:
314
+ md_lines.append(f"- {query}")
315
+ md_lines.append("") # Empty line before URLs
316
+
317
+ # Add URL citations
318
+ md_lines.extend(
283
319
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
284
320
  for i, citation in enumerate(run_response.citations.urls)
285
321
  if citation.url # Only include citations with valid URLs
286
322
  )
323
+
324
+ md_content = "\n".join(md_lines)
287
325
  if md_content: # Only create panel if there are citations
288
326
  citations_panel = create_panel(
289
327
  content=Markdown(md_content),
@@ -322,17 +360,20 @@ def print_response_stream(
322
360
  show_message: bool = True,
323
361
  show_reasoning: bool = True,
324
362
  show_full_reasoning: bool = False,
363
+ show_member_responses: Optional[bool] = None,
325
364
  tags_to_include_in_markdown: Optional[Set[str]] = None,
326
365
  session_id: Optional[str] = None,
327
366
  session_state: Optional[Dict[str, Any]] = None,
328
367
  user_id: Optional[str] = None,
368
+ run_id: Optional[str] = None,
329
369
  audio: Optional[Sequence[Audio]] = None,
330
370
  images: Optional[Sequence[Image]] = None,
331
371
  videos: Optional[Sequence[Video]] = None,
332
372
  files: Optional[Sequence[File]] = None,
333
373
  markdown: bool = False,
374
+ stream_events: bool = False,
334
375
  stream_intermediate_steps: bool = False, # type: ignore
335
- knowledge_filters: Optional[Dict[str, Any]] = None,
376
+ knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
336
377
  add_history_to_context: Optional[bool] = None,
337
378
  dependencies: Optional[Dict[str, Any]] = None,
338
379
  add_dependencies_to_context: Optional[bool] = None,
@@ -355,7 +396,7 @@ def print_response_stream(
355
396
  if not tags_to_include_in_markdown:
356
397
  tags_to_include_in_markdown = {"think", "thinking"}
357
398
 
358
- stream_intermediate_steps = True # With streaming print response, we need to stream intermediate steps
399
+ stream_events = True # With streaming print response, we need to stream intermediate steps
359
400
 
360
401
  _response_content: str = ""
361
402
  _response_reasoning_content: str = ""
@@ -399,10 +440,11 @@ def print_response_stream(
399
440
  videos=videos,
400
441
  files=files,
401
442
  stream=True,
402
- stream_intermediate_steps=stream_intermediate_steps,
443
+ stream_events=stream_events,
403
444
  session_id=session_id,
404
445
  session_state=session_state,
405
446
  user_id=user_id,
447
+ run_id=run_id,
406
448
  knowledge_filters=knowledge_filters,
407
449
  add_history_to_context=add_history_to_context,
408
450
  dependencies=dependencies,
@@ -410,7 +452,7 @@ def print_response_stream(
410
452
  add_session_state_to_context=add_session_state_to_context,
411
453
  metadata=metadata,
412
454
  debug_mode=debug_mode,
413
- yield_run_response=True,
455
+ yield_run_output=True,
414
456
  **kwargs,
415
457
  )
416
458
 
@@ -468,7 +510,7 @@ def print_response_stream(
468
510
  team_tool_calls.append(tool)
469
511
 
470
512
  # Collect member tool calls, avoiding duplicates
471
- if hasattr(resp, "member_responses") and resp.member_responses:
513
+ if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
472
514
  for member_response in resp.member_responses:
473
515
  member_id = None
474
516
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -530,7 +572,9 @@ def print_response_stream(
530
572
  panels.append(status)
531
573
 
532
574
  # Process member responses and their tool calls
533
- for member_response in resp.member_responses if hasattr(resp, "member_responses") else []:
575
+ for member_response in (
576
+ resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
577
+ ):
534
578
  member_id = None
535
579
  member_name = "Team Member"
536
580
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -563,7 +607,7 @@ def print_response_stream(
563
607
  panels.append(member_tool_calls_panel)
564
608
 
565
609
  # Process member response content
566
- if team.show_members_responses and member_id is not None:
610
+ if show_member_responses and member_id is not None:
567
611
  show_markdown = False
568
612
  if markdown:
569
613
  show_markdown = True
@@ -606,6 +650,14 @@ def print_response_stream(
606
650
  # Join with blank lines between items
607
651
  tool_calls_text = "\n\n".join(lines)
608
652
 
653
+ # Add compression stats if available (don't clear - will be cleared in final_panels)
654
+ if team.compression_manager is not None and team.compression_manager.stats:
655
+ stats = team.compression_manager.stats
656
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
657
+ orig = stats.get("original_size", 1)
658
+ if stats.get("tool_results_compressed", 0) > 0:
659
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
660
+
609
661
  team_tool_calls_panel = create_panel(
610
662
  content=tool_calls_text,
611
663
  title="Team Tool Calls",
@@ -632,11 +684,23 @@ def print_response_stream(
632
684
 
633
685
  # Add citations
634
686
  if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
635
- md_content = "\n".join(
687
+ md_lines = []
688
+
689
+ # Add search queries if present
690
+ if resp.citations.search_queries:
691
+ md_lines.append("**Search Queries:**")
692
+ for query in resp.citations.search_queries:
693
+ md_lines.append(f"- {query}")
694
+ md_lines.append("") # Empty line before URLs
695
+
696
+ # Add URL citations
697
+ md_lines.extend(
636
698
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
637
699
  for i, citation in enumerate(resp.citations.urls)
638
700
  if citation.url # Only include citations with valid URLs
639
701
  )
702
+
703
+ md_content = "\n".join(md_lines)
640
704
  if md_content: # Only create panel if there are citations
641
705
  citations_panel = create_panel(
642
706
  content=Markdown(md_content),
@@ -706,7 +770,7 @@ def print_response_stream(
706
770
  final_panels.append(thinking_panel)
707
771
 
708
772
  # Add member tool calls and responses in correct order
709
- if run_response is not None and hasattr(run_response, "member_responses"):
773
+ if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
710
774
  for i, member_response in enumerate(run_response.member_responses): # type: ignore
711
775
  member_id = None
712
776
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -776,11 +840,23 @@ def print_response_stream(
776
840
 
777
841
  # Add citations if any
778
842
  if member_response.citations is not None and member_response.citations.urls is not None:
779
- md_content = "\n".join(
843
+ md_lines = []
844
+
845
+ # Add search queries if present
846
+ if member_response.citations.search_queries:
847
+ md_lines.append("**Search Queries:**")
848
+ for query in member_response.citations.search_queries:
849
+ md_lines.append(f"- {query}")
850
+ md_lines.append("") # Empty line before URLs
851
+
852
+ # Add URL citations
853
+ md_lines.extend(
780
854
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
781
855
  for i, citation in enumerate(member_response.citations.urls)
782
856
  if citation.url # Only include citations with valid URLs
783
857
  )
858
+
859
+ md_content = "\n".join(md_lines)
784
860
  if md_content: # Only create panel if there are citations
785
861
  citations_panel = create_panel(
786
862
  content=Markdown(md_content),
@@ -808,6 +884,15 @@ def print_response_stream(
808
884
 
809
885
  tool_calls_text = "\n\n".join(lines)
810
886
 
887
+ # Add compression stats at end of tool calls
888
+ if team.compression_manager is not None and team.compression_manager.stats:
889
+ stats = team.compression_manager.stats
890
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
891
+ orig = stats.get("original_size", 1)
892
+ if stats.get("tool_results_compressed", 0) > 0:
893
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
894
+ team.compression_manager.stats.clear()
895
+
811
896
  team_tool_calls_panel = create_panel(
812
897
  content=tool_calls_text,
813
898
  title="Team Tool Calls",
@@ -831,11 +916,23 @@ def print_response_stream(
831
916
 
832
917
  # Add team citations
833
918
  if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
834
- md_content = "\n".join(
919
+ md_lines = []
920
+
921
+ # Add search queries if present
922
+ if resp.citations.search_queries:
923
+ md_lines.append("**Search Queries:**")
924
+ for query in resp.citations.search_queries:
925
+ md_lines.append(f"- {query}")
926
+ md_lines.append("") # Empty line before URLs
927
+
928
+ # Add URL citations
929
+ md_lines.extend(
835
930
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
836
931
  for i, citation in enumerate(resp.citations.urls)
837
932
  if citation.url # Only include citations with valid URLs
838
933
  )
934
+
935
+ md_content = "\n".join(md_lines)
839
936
  if md_content: # Only create panel if there are citations
840
937
  citations_panel = create_panel(
841
938
  content=Markdown(md_content),
@@ -855,16 +952,18 @@ async def aprint_response(
855
952
  show_message: bool = True,
856
953
  show_reasoning: bool = True,
857
954
  show_full_reasoning: bool = False,
955
+ show_member_responses: Optional[bool] = None,
858
956
  tags_to_include_in_markdown: Optional[Set[str]] = None,
859
957
  session_id: Optional[str] = None,
860
958
  session_state: Optional[Dict[str, Any]] = None,
861
959
  user_id: Optional[str] = None,
960
+ run_id: Optional[str] = None,
862
961
  audio: Optional[Sequence[Audio]] = None,
863
962
  images: Optional[Sequence[Image]] = None,
864
963
  videos: Optional[Sequence[Video]] = None,
865
964
  files: Optional[Sequence[File]] = None,
866
965
  markdown: bool = False,
867
- knowledge_filters: Optional[Dict[str, Any]] = None,
966
+ knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
868
967
  add_history_to_context: Optional[bool] = None,
869
968
  dependencies: Optional[Dict[str, Any]] = None,
870
969
  add_dependencies_to_context: Optional[bool] = None,
@@ -910,11 +1009,13 @@ async def aprint_response(
910
1009
  # Run the agent
911
1010
  run_response: TeamRunOutput = await team.arun( # type: ignore
912
1011
  input=input,
1012
+ run_id=run_id,
913
1013
  images=images,
914
1014
  audio=audio,
915
1015
  videos=videos,
916
1016
  files=files,
917
1017
  stream=False,
1018
+ stream_events=True,
918
1019
  session_id=session_id,
919
1020
  session_state=session_state,
920
1021
  user_id=user_id,
@@ -982,7 +1083,7 @@ async def aprint_response(
982
1083
 
983
1084
  if isinstance(run_response, TeamRunOutput):
984
1085
  # Handle member responses
985
- if team.show_members_responses:
1086
+ if show_member_responses:
986
1087
  for member_response in run_response.member_responses:
987
1088
  # Handle member reasoning
988
1089
  reasoning_steps = []
@@ -1055,11 +1156,23 @@ async def aprint_response(
1055
1156
  panels.append(member_response_panel)
1056
1157
 
1057
1158
  if member_response.citations is not None and member_response.citations.urls is not None:
1058
- md_content = "\n".join(
1159
+ md_lines = []
1160
+
1161
+ # Add search queries if present
1162
+ if member_response.citations.search_queries:
1163
+ md_lines.append("**Search Queries:**")
1164
+ for query in member_response.citations.search_queries:
1165
+ md_lines.append(f"- {query}")
1166
+ md_lines.append("") # Empty line before URLs
1167
+
1168
+ # Add URL citations
1169
+ md_lines.extend(
1059
1170
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
1060
1171
  for i, citation in enumerate(member_response.citations.urls)
1061
1172
  if citation.url # Only include citations with valid URLs
1062
1173
  )
1174
+
1175
+ md_content = "\n".join(md_lines)
1063
1176
  if md_content:
1064
1177
  citations_panel = create_panel(
1065
1178
  content=Markdown(md_content),
@@ -1086,6 +1199,15 @@ async def aprint_response(
1086
1199
 
1087
1200
  tool_calls_text = "\n\n".join(lines)
1088
1201
 
1202
+ # Add compression stats at end of tool calls
1203
+ if team.compression_manager is not None and team.compression_manager.stats:
1204
+ stats = team.compression_manager.stats
1205
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
1206
+ orig = stats.get("original_size", 1)
1207
+ if stats.get("tool_results_compressed", 0) > 0:
1208
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
1209
+ team.compression_manager.stats.clear()
1210
+
1089
1211
  team_tool_calls_panel = create_panel(
1090
1212
  content=tool_calls_text,
1091
1213
  title="Team Tool Calls",
@@ -1108,11 +1230,23 @@ async def aprint_response(
1108
1230
 
1109
1231
  # Add citations
1110
1232
  if run_response.citations is not None and run_response.citations.urls is not None:
1111
- md_content = "\n".join(
1233
+ md_lines = []
1234
+
1235
+ # Add search queries if present
1236
+ if run_response.citations.search_queries:
1237
+ md_lines.append("**Search Queries:**")
1238
+ for query in run_response.citations.search_queries:
1239
+ md_lines.append(f"- {query}")
1240
+ md_lines.append("") # Empty line before URLs
1241
+
1242
+ # Add URL citations
1243
+ md_lines.extend(
1112
1244
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
1113
1245
  for i, citation in enumerate(run_response.citations.urls)
1114
1246
  if citation.url # Only include citations with valid URLs
1115
1247
  )
1248
+
1249
+ md_content = "\n".join(md_lines)
1116
1250
  if md_content: # Only create panel if there are citations
1117
1251
  citations_panel = create_panel(
1118
1252
  content=Markdown(md_content),
@@ -1151,17 +1285,20 @@ async def aprint_response_stream(
1151
1285
  show_message: bool = True,
1152
1286
  show_reasoning: bool = True,
1153
1287
  show_full_reasoning: bool = False,
1288
+ show_member_responses: Optional[bool] = None,
1154
1289
  tags_to_include_in_markdown: Optional[Set[str]] = None,
1155
1290
  session_id: Optional[str] = None,
1156
1291
  session_state: Optional[Dict[str, Any]] = None,
1157
1292
  user_id: Optional[str] = None,
1293
+ run_id: Optional[str] = None,
1158
1294
  audio: Optional[Sequence[Audio]] = None,
1159
1295
  images: Optional[Sequence[Image]] = None,
1160
1296
  videos: Optional[Sequence[Video]] = None,
1161
1297
  files: Optional[Sequence[File]] = None,
1162
1298
  markdown: bool = False,
1299
+ stream_events: bool = False,
1163
1300
  stream_intermediate_steps: bool = False, # type: ignore
1164
- knowledge_filters: Optional[Dict[str, Any]] = None,
1301
+ knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
1165
1302
  add_history_to_context: Optional[bool] = None,
1166
1303
  dependencies: Optional[Dict[str, Any]] = None,
1167
1304
  add_dependencies_to_context: Optional[bool] = None,
@@ -1182,7 +1319,7 @@ async def aprint_response_stream(
1182
1319
  if not tags_to_include_in_markdown:
1183
1320
  tags_to_include_in_markdown = {"think", "thinking"}
1184
1321
 
1185
- stream_intermediate_steps = True # With streaming print response, we need to stream intermediate steps
1322
+ stream_events = True # With streaming print response, we need to stream intermediate steps
1186
1323
 
1187
1324
  _response_content: str = ""
1188
1325
  _response_reasoning_content: str = ""
@@ -1238,10 +1375,11 @@ async def aprint_response_stream(
1238
1375
  videos=videos,
1239
1376
  files=files,
1240
1377
  stream=True,
1241
- stream_intermediate_steps=stream_intermediate_steps,
1378
+ stream_events=stream_events,
1242
1379
  session_id=session_id,
1243
1380
  session_state=session_state,
1244
1381
  user_id=user_id,
1382
+ run_id=run_id,
1245
1383
  knowledge_filters=knowledge_filters,
1246
1384
  add_history_to_context=add_history_to_context,
1247
1385
  add_dependencies_to_context=add_dependencies_to_context,
@@ -1249,7 +1387,7 @@ async def aprint_response_stream(
1249
1387
  dependencies=dependencies,
1250
1388
  metadata=metadata,
1251
1389
  debug_mode=debug_mode,
1252
- yield_run_response=True,
1390
+ yield_run_output=True,
1253
1391
  **kwargs,
1254
1392
  ):
1255
1393
  if team_markdown is None:
@@ -1296,7 +1434,7 @@ async def aprint_response_stream(
1296
1434
  team_tool_calls.append(tool)
1297
1435
 
1298
1436
  # Collect member tool calls, avoiding duplicates
1299
- if hasattr(resp, "member_responses") and resp.member_responses:
1437
+ if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
1300
1438
  for member_response in resp.member_responses:
1301
1439
  member_id = None
1302
1440
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -1357,7 +1495,9 @@ async def aprint_response_stream(
1357
1495
  panels.append(status)
1358
1496
 
1359
1497
  # Process member responses and their tool calls
1360
- for member_response in resp.member_responses if hasattr(resp, "member_responses") else []:
1498
+ for member_response in (
1499
+ resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
1500
+ ):
1361
1501
  member_id = None
1362
1502
  member_name = "Team Member"
1363
1503
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -1390,7 +1530,7 @@ async def aprint_response_stream(
1390
1530
  panels.append(member_tool_calls_panel)
1391
1531
 
1392
1532
  # Process member response content
1393
- if team.show_members_responses and member_id is not None:
1533
+ if show_member_responses and member_id is not None:
1394
1534
  show_markdown = False
1395
1535
  if markdown:
1396
1536
  show_markdown = True
@@ -1433,6 +1573,14 @@ async def aprint_response_stream(
1433
1573
  # Join with blank lines between items
1434
1574
  tool_calls_text = "\n\n".join(lines)
1435
1575
 
1576
+ # Add compression stats if available (don't clear - will be cleared in final_panels)
1577
+ if team.compression_manager is not None and team.compression_manager.stats:
1578
+ stats = team.compression_manager.stats
1579
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
1580
+ orig = stats.get("original_size", 1)
1581
+ if stats.get("tool_results_compressed", 0) > 0:
1582
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
1583
+
1436
1584
  team_tool_calls_panel = create_panel(
1437
1585
  content=tool_calls_text,
1438
1586
  title="Team Tool Calls",
@@ -1460,11 +1608,23 @@ async def aprint_response_stream(
1460
1608
 
1461
1609
  # Add citations
1462
1610
  if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
1463
- md_content = "\n".join(
1611
+ md_lines = []
1612
+
1613
+ # Add search queries if present
1614
+ if resp.citations.search_queries:
1615
+ md_lines.append("**Search Queries:**")
1616
+ for query in resp.citations.search_queries:
1617
+ md_lines.append(f"- {query}")
1618
+ md_lines.append("") # Empty line before URLs
1619
+
1620
+ # Add URL citations
1621
+ md_lines.extend(
1464
1622
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
1465
1623
  for i, citation in enumerate(resp.citations.urls)
1466
1624
  if citation.url # Only include citations with valid URLs
1467
1625
  )
1626
+
1627
+ md_content = "\n".join(md_lines)
1468
1628
  if md_content: # Only create panel if there are citations
1469
1629
  citations_panel = create_panel(
1470
1630
  content=Markdown(md_content),
@@ -1534,7 +1694,7 @@ async def aprint_response_stream(
1534
1694
  final_panels.append(thinking_panel)
1535
1695
 
1536
1696
  # Add member tool calls and responses in correct order
1537
- if run_response is not None and hasattr(run_response, "member_responses"):
1697
+ if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
1538
1698
  for i, member_response in enumerate(run_response.member_responses):
1539
1699
  member_id = None
1540
1700
  if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
@@ -1621,11 +1781,23 @@ async def aprint_response_stream(
1621
1781
 
1622
1782
  # Add citations if any
1623
1783
  if member_response.citations is not None and member_response.citations.urls is not None:
1624
- md_content = "\n".join(
1784
+ md_lines = []
1785
+
1786
+ # Add search queries if present
1787
+ if member_response.citations.search_queries:
1788
+ md_lines.append("**Search Queries:**")
1789
+ for query in member_response.citations.search_queries:
1790
+ md_lines.append(f"- {query}")
1791
+ md_lines.append("") # Empty line before URLs
1792
+
1793
+ # Add URL citations
1794
+ md_lines.extend(
1625
1795
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
1626
1796
  for i, citation in enumerate(member_response.citations.urls)
1627
1797
  if citation.url # Only include citations with valid URLs
1628
1798
  )
1799
+
1800
+ md_content = "\n".join(md_lines)
1629
1801
  if md_content: # Only create panel if there are citations
1630
1802
  citations_panel = create_panel(
1631
1803
  content=Markdown(md_content),
@@ -1653,6 +1825,15 @@ async def aprint_response_stream(
1653
1825
 
1654
1826
  tool_calls_text = "\n\n".join(lines)
1655
1827
 
1828
+ # Add compression stats at end of tool calls
1829
+ if team.compression_manager is not None and team.compression_manager.stats:
1830
+ stats = team.compression_manager.stats
1831
+ saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
1832
+ orig = stats.get("original_size", 1)
1833
+ if stats.get("tool_results_compressed", 0) > 0:
1834
+ tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
1835
+ team.compression_manager.stats.clear()
1836
+
1656
1837
  team_tool_calls_panel = create_panel(
1657
1838
  content=tool_calls_text,
1658
1839
  title="Team Tool Calls",
@@ -1676,11 +1857,23 @@ async def aprint_response_stream(
1676
1857
 
1677
1858
  # Add team citations
1678
1859
  if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
1679
- md_content = "\n".join(
1860
+ md_lines = []
1861
+
1862
+ # Add search queries if present
1863
+ if resp.citations.search_queries:
1864
+ md_lines.append("**Search Queries:**")
1865
+ for query in resp.citations.search_queries:
1866
+ md_lines.append(f"- {query}")
1867
+ md_lines.append("") # Empty line before URLs
1868
+
1869
+ # Add URL citations
1870
+ md_lines.extend(
1680
1871
  f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
1681
1872
  for i, citation in enumerate(resp.citations.urls)
1682
1873
  if citation.url # Only include citations with valid URLs
1683
1874
  )
1875
+
1876
+ md_content = "\n".join(md_lines)
1684
1877
  if md_content: # Only create panel if there are citations
1685
1878
  citations_panel = create_panel(
1686
1879
  content=Markdown(md_content),