agno 2.2.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 (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
@@ -0,0 +1,10 @@
1
+ from typing import Union
2
+
3
+ from agno.session.agent import AgentSession
4
+ from agno.session.summary import SessionSummaryManager
5
+ from agno.session.team import TeamSession
6
+ from agno.session.workflow import WorkflowSession
7
+
8
+ Session = Union[AgentSession, TeamSession, WorkflowSession]
9
+
10
+ __all__ = ["AgentSession", "TeamSession", "WorkflowSession", "Session", "SessionSummaryManager"]
agno/session/agent.py ADDED
@@ -0,0 +1,295 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import asdict, dataclass
4
+ from typing import Any, Dict, List, Mapping, Optional, Union
5
+
6
+ from agno.models.message import Message
7
+ from agno.run.agent import RunOutput
8
+ from agno.run.base import RunStatus
9
+ from agno.run.team import TeamRunOutput
10
+ from agno.session.summary import SessionSummary
11
+ from agno.utils.log import log_debug, log_warning
12
+
13
+
14
+ @dataclass
15
+ class AgentSession:
16
+ """Agent Session that is stored in the database"""
17
+
18
+ # Session UUID
19
+ session_id: str
20
+
21
+ # ID of the agent that this session is associated with
22
+ agent_id: Optional[str] = None
23
+ # ID of the team that this session is associated with
24
+ team_id: Optional[str] = None
25
+ # # ID of the user interacting with this agent
26
+ user_id: Optional[str] = None
27
+ # ID of the workflow that this session is associated with
28
+ workflow_id: Optional[str] = None
29
+
30
+ # Session Data: session_name, session_state, images, videos, audio
31
+ session_data: Optional[Dict[str, Any]] = None
32
+ # Metadata stored with this agent
33
+ metadata: Optional[Dict[str, Any]] = None
34
+ # Agent Data: agent_id, name and model
35
+ agent_data: Optional[Dict[str, Any]] = None
36
+ # List of all runs in the session
37
+ runs: Optional[List[Union[RunOutput, TeamRunOutput]]] = None
38
+ # Summary of the session
39
+ summary: Optional["SessionSummary"] = None
40
+
41
+ # The unix timestamp when this session was created
42
+ created_at: Optional[int] = None
43
+ # The unix timestamp when this session was last updated
44
+ updated_at: Optional[int] = None
45
+
46
+ def to_dict(self) -> Dict[str, Any]:
47
+ session_dict = asdict(self)
48
+
49
+ session_dict["runs"] = [run.to_dict() for run in self.runs] if self.runs else None
50
+ session_dict["summary"] = self.summary.to_dict() if self.summary else None
51
+
52
+ return session_dict
53
+
54
+ @classmethod
55
+ def from_dict(cls, data: Mapping[str, Any]) -> Optional[AgentSession]:
56
+ if data is None or data.get("session_id") is None:
57
+ log_warning("AgentSession is missing session_id")
58
+ return None
59
+
60
+ runs = data.get("runs")
61
+ serialized_runs: List[Union[RunOutput, TeamRunOutput]] = []
62
+ if runs is not None and isinstance(runs[0], dict):
63
+ for run in runs:
64
+ if "agent_id" in run:
65
+ serialized_runs.append(RunOutput.from_dict(run))
66
+ elif "team_id" in run:
67
+ serialized_runs.append(TeamRunOutput.from_dict(run))
68
+
69
+ summary = data.get("summary")
70
+ if summary is not None and isinstance(summary, dict):
71
+ summary = SessionSummary.from_dict(summary)
72
+
73
+ metadata = data.get("metadata")
74
+
75
+ return cls(
76
+ session_id=data.get("session_id"), # type: ignore
77
+ agent_id=data.get("agent_id"),
78
+ user_id=data.get("user_id"),
79
+ workflow_id=data.get("workflow_id"),
80
+ team_id=data.get("team_id"),
81
+ agent_data=data.get("agent_data"),
82
+ session_data=data.get("session_data"),
83
+ metadata=metadata,
84
+ created_at=data.get("created_at"),
85
+ updated_at=data.get("updated_at"),
86
+ runs=serialized_runs,
87
+ summary=summary,
88
+ )
89
+
90
+ def upsert_run(self, run: RunOutput):
91
+ """Adds a RunOutput, together with some calculated data, to the runs list."""
92
+ messages = run.messages
93
+ for m in messages or []:
94
+ if m.metrics is not None:
95
+ m.metrics.duration = None
96
+
97
+ if not self.runs:
98
+ self.runs = []
99
+
100
+ for i, existing_run in enumerate(self.runs or []):
101
+ if existing_run.run_id == run.run_id:
102
+ self.runs[i] = run
103
+ break
104
+ else:
105
+ self.runs.append(run)
106
+
107
+ log_debug("Added RunOutput to Agent Session")
108
+
109
+ def get_run(self, run_id: str) -> Optional[Union[RunOutput, TeamRunOutput]]:
110
+ for run in self.runs or []:
111
+ if run.run_id == run_id:
112
+ return run
113
+ return None
114
+
115
+ def _should_skip_message(
116
+ self, message: Message, skip_role: Optional[str] = None, skip_history_messages: bool = True
117
+ ) -> bool:
118
+ """Processes a message for history"""
119
+ # Skip messages that were tagged as history in previous runs
120
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
121
+ return True
122
+
123
+ # Skip messages with specified role
124
+ if skip_role and message.role == skip_role:
125
+ return True
126
+ return False
127
+
128
+ def get_messages_from_last_n_runs(
129
+ self,
130
+ agent_id: Optional[str] = None,
131
+ team_id: Optional[str] = None,
132
+ last_n: Optional[int] = None,
133
+ last_n_messages: Optional[int] = None,
134
+ skip_role: Optional[str] = None,
135
+ skip_status: Optional[List[RunStatus]] = None,
136
+ skip_history_messages: bool = True,
137
+ ) -> List[Message]:
138
+ """Returns the messages from the last_n runs, excluding previously tagged history messages.
139
+ Args:
140
+ agent_id: The id of the agent to get the messages from.
141
+ team_id: The id of the team to get the messages from.
142
+ last_n: The number of runs to return from the end of the conversation. Defaults to all runs.
143
+ last_n_messages: The number of messages to return from the end of the conversation. Defaults to all messages.
144
+ skip_role: Skip messages with this role.
145
+ skip_status: Skip messages with this status.
146
+ skip_history_messages: Skip messages that were tagged as history in previous runs.
147
+ Returns:
148
+ A list of Messages from the specified runs, excluding history messages.
149
+ """
150
+ if not self.runs:
151
+ return []
152
+
153
+ if skip_status is None:
154
+ skip_status = [RunStatus.paused, RunStatus.cancelled, RunStatus.error]
155
+
156
+ session_runs = self.runs
157
+ # Filter by agent_id and team_id
158
+ if agent_id:
159
+ session_runs = [run for run in session_runs if hasattr(run, "agent_id") and run.agent_id == agent_id] # type: ignore
160
+ if team_id:
161
+ session_runs = [run for run in session_runs if hasattr(run, "team_id") and run.team_id == team_id] # type: ignore
162
+
163
+ # Skip any messages that might be part of members of teams (for session re-use)
164
+ session_runs = [run for run in session_runs if run.parent_run_id is None] # type: ignore
165
+
166
+ # Filter by status
167
+ session_runs = [run for run in session_runs if hasattr(run, "status") and run.status not in skip_status] # type: ignore
168
+
169
+ messages_from_history = []
170
+ system_message = None
171
+
172
+ # Filter by last_n_messages
173
+ if last_n_messages is not None:
174
+ for run_response in session_runs:
175
+ if not run_response or not run_response.messages:
176
+ continue
177
+
178
+ for message in run_response.messages or []:
179
+ if self._should_skip_message(message, skip_role, skip_history_messages):
180
+ continue
181
+
182
+ if message.role == "system":
183
+ # Only add the system message once
184
+ if system_message is None:
185
+ system_message = message
186
+ else:
187
+ messages_from_history.append(message)
188
+
189
+ if system_message:
190
+ messages_from_history = [system_message] + messages_from_history[
191
+ -(last_n_messages - 1) :
192
+ ] # Grab one less message then add the system message
193
+ else:
194
+ messages_from_history = messages_from_history[-last_n_messages:]
195
+
196
+ # Remove tool result messages that don't have an associated assistant message with tool calls
197
+ while len(messages_from_history) > 0 and messages_from_history[0].role == "tool":
198
+ messages_from_history.pop(0)
199
+
200
+ else:
201
+ # Filter by last_n runs
202
+ runs_to_process = session_runs[-last_n:] if last_n is not None else session_runs
203
+ for run_response in runs_to_process:
204
+ if not run_response or not run_response.messages:
205
+ continue
206
+
207
+ for message in run_response.messages or []:
208
+ if self._should_skip_message(message, skip_role, skip_history_messages):
209
+ continue
210
+
211
+ if message.role == "system":
212
+ # Only add the system message once
213
+ if system_message is None:
214
+ system_message = message
215
+ messages_from_history.append(system_message)
216
+ else:
217
+ messages_from_history.append(message)
218
+
219
+ log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
220
+ return messages_from_history
221
+
222
+ def get_tool_calls(self, num_calls: Optional[int] = None) -> List[Dict[str, Any]]:
223
+ """Returns a list of tool calls from the messages"""
224
+
225
+ tool_calls = []
226
+ if self.runs:
227
+ session_runs = self.runs
228
+ for run_response in session_runs[::-1]:
229
+ if run_response and run_response.messages:
230
+ for message in run_response.messages or []:
231
+ if message.tool_calls:
232
+ for tool_call in message.tool_calls:
233
+ tool_calls.append(tool_call)
234
+ if num_calls and len(tool_calls) >= num_calls:
235
+ return tool_calls
236
+ return tool_calls
237
+
238
+ def get_messages_for_session(
239
+ self,
240
+ user_role: str = "user",
241
+ assistant_role: Optional[List[str]] = None,
242
+ skip_history_messages: bool = True,
243
+ ) -> List[Message]:
244
+ """Returns a list of messages for the session that iterate through user message and assistant response."""
245
+
246
+ if assistant_role is None:
247
+ # TODO: Check if we still need CHATBOT as a role
248
+ assistant_role = ["assistant", "model", "CHATBOT"]
249
+
250
+ final_messages: List[Message] = []
251
+ session_runs = self.runs
252
+ if not session_runs:
253
+ return []
254
+
255
+ for run_response in session_runs:
256
+ if run_response and run_response.messages:
257
+ user_message_from_run = None
258
+ assistant_message_from_run = None
259
+
260
+ # Start from the beginning to look for the user message
261
+ for message in run_response.messages or []:
262
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
263
+ continue
264
+ if message.role == user_role:
265
+ user_message_from_run = message
266
+ break
267
+
268
+ # Start from the end to look for the assistant response
269
+ for message in run_response.messages[::-1]:
270
+ if hasattr(message, "from_history") and message.from_history and skip_history_messages:
271
+ continue
272
+ if message.role in assistant_role:
273
+ assistant_message_from_run = message
274
+ break
275
+
276
+ if user_message_from_run and assistant_message_from_run:
277
+ final_messages.append(user_message_from_run)
278
+ final_messages.append(assistant_message_from_run)
279
+ return final_messages
280
+
281
+ def get_session_summary(self) -> Optional[SessionSummary]:
282
+ """Get the session summary for the session"""
283
+
284
+ if self.summary is None:
285
+ return None
286
+ return self.summary
287
+
288
+ # Chat History functions
289
+ def get_chat_history(self) -> List[Message]:
290
+ """Get the chat history for the session"""
291
+
292
+ messages = []
293
+ for run in self.runs or []:
294
+ messages.extend([msg for msg in run.messages or [] if not msg.from_history])
295
+ return messages
@@ -0,0 +1,265 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from textwrap import dedent
4
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from agno.models.base import Model
9
+ from agno.models.utils import get_model
10
+ from agno.run.agent import Message
11
+ from agno.utils.log import log_debug, log_warning
12
+
13
+ # TODO: Look into moving all managers into a separate dir
14
+ if TYPE_CHECKING:
15
+ from agno.session import Session
16
+ from agno.session.agent import AgentSession
17
+ from agno.session.team import TeamSession
18
+
19
+
20
+ @dataclass
21
+ class SessionSummary:
22
+ """Model for Session Summary."""
23
+
24
+ summary: str
25
+ topics: Optional[List[str]] = None
26
+ updated_at: Optional[datetime] = None
27
+
28
+ def to_dict(self) -> Dict[str, Any]:
29
+ _dict = {
30
+ "summary": self.summary,
31
+ "topics": self.topics,
32
+ "updated_at": self.updated_at.isoformat() if self.updated_at else None,
33
+ }
34
+ return {k: v for k, v in _dict.items() if v is not None}
35
+
36
+ @classmethod
37
+ def from_dict(cls, data: Dict[str, Any]) -> "SessionSummary":
38
+ updated_at = data.get("updated_at")
39
+ if updated_at:
40
+ data["updated_at"] = datetime.fromisoformat(updated_at)
41
+ return cls(**data)
42
+
43
+
44
+ class SessionSummaryResponse(BaseModel):
45
+ """Model for Session Summary."""
46
+
47
+ summary: str = Field(
48
+ ...,
49
+ description="Summary of the session. Be concise and focus on only important information. Do not make anything up.",
50
+ )
51
+ topics: Optional[List[str]] = Field(None, description="Topics discussed in the session.")
52
+
53
+ def to_dict(self) -> Dict[str, Any]:
54
+ return self.model_dump(exclude_none=True)
55
+
56
+ def to_json(self) -> str:
57
+ return self.model_dump_json(exclude_none=True, indent=2)
58
+
59
+
60
+ @dataclass
61
+ class SessionSummaryManager:
62
+ """Session Summary Manager"""
63
+
64
+ # Model used for session summary generation
65
+ model: Optional[Model] = None
66
+
67
+ # Prompt used for session summary generation
68
+ session_summary_prompt: Optional[str] = None
69
+
70
+ # User message prompt for requesting the summary
71
+ summary_request_message: str = "Provide the summary of the conversation."
72
+
73
+ # Whether session summaries were created in the last run
74
+ summaries_updated: bool = False
75
+
76
+ def get_response_format(self, model: "Model") -> Union[Dict[str, Any], Type[BaseModel]]: # type: ignore
77
+ if model.supports_native_structured_outputs:
78
+ return SessionSummaryResponse
79
+
80
+ elif model.supports_json_schema_outputs:
81
+ return {
82
+ "type": "json_schema",
83
+ "json_schema": {
84
+ "name": SessionSummaryResponse.__name__,
85
+ "schema": SessionSummaryResponse.model_json_schema(),
86
+ },
87
+ }
88
+ else:
89
+ return {"type": "json_object"}
90
+
91
+ def get_system_message(
92
+ self,
93
+ conversation: List[Message],
94
+ response_format: Union[Dict[str, Any], Type[BaseModel]],
95
+ ) -> Message:
96
+ if self.session_summary_prompt is not None:
97
+ system_prompt = self.session_summary_prompt
98
+ else:
99
+ system_prompt = dedent("""\
100
+ Analyze the following conversation between a user and an assistant, and extract the following details:
101
+ - Summary (str): Provide a concise summary of the session, focusing on important information that would be helpful for future interactions.
102
+ - Topics (Optional[List[str]]): List the topics discussed in the session.
103
+ Keep the summary concise and to the point. Only include relevant information.
104
+ """)
105
+ conversation_messages = []
106
+ system_prompt += "<conversation>"
107
+ for message in conversation:
108
+ if message.role == "user":
109
+ # Handle empty user messages with media - note what media was provided
110
+ if not message.content or (isinstance(message.content, str) and message.content.strip() == ""):
111
+ media_types = []
112
+ if hasattr(message, "images") and message.images:
113
+ media_types.append(f"{len(message.images)} image(s)")
114
+ if hasattr(message, "videos") and message.videos:
115
+ media_types.append(f"{len(message.videos)} video(s)")
116
+ if hasattr(message, "audio") and message.audio:
117
+ media_types.append(f"{len(message.audio)} audio file(s)")
118
+ if hasattr(message, "files") and message.files:
119
+ media_types.append(f"{len(message.files)} file(s)")
120
+
121
+ if media_types:
122
+ conversation_messages.append(f"User: [Provided {', '.join(media_types)}]")
123
+ # Skip empty messages with no media
124
+ else:
125
+ conversation_messages.append(f"User: {message.content}")
126
+ elif message.role in ["assistant", "model"]:
127
+ conversation_messages.append(f"Assistant: {message.content}\n")
128
+ system_prompt += "\n".join(conversation_messages)
129
+ system_prompt += "</conversation>"
130
+
131
+ if response_format == {"type": "json_object"}:
132
+ from agno.utils.prompts import get_json_output_prompt
133
+
134
+ system_prompt += "\n" + get_json_output_prompt(SessionSummaryResponse) # type: ignore
135
+
136
+ return Message(role="system", content=system_prompt)
137
+
138
+ def _prepare_summary_messages(
139
+ self,
140
+ session: Optional["Session"] = None,
141
+ ) -> Optional[List[Message]]:
142
+ """Prepare messages for session summary generation. Returns None if no meaningful messages to summarize."""
143
+ if not session:
144
+ return None
145
+
146
+ self.model = get_model(self.model)
147
+ if self.model is None:
148
+ return None
149
+
150
+ response_format = self.get_response_format(self.model)
151
+
152
+ system_message = self.get_system_message(
153
+ conversation=session.get_messages_for_session(), # type: ignore
154
+ response_format=response_format,
155
+ )
156
+
157
+ if system_message is None:
158
+ return None
159
+
160
+ return [
161
+ system_message,
162
+ Message(role="user", content=self.summary_request_message),
163
+ ]
164
+
165
+ def _process_summary_response(self, summary_response, session_summary_model: "Model") -> Optional[SessionSummary]: # type: ignore
166
+ """Process the model response into a SessionSummary"""
167
+ from datetime import datetime
168
+
169
+ if summary_response is None:
170
+ return None
171
+
172
+ # Handle native structured outputs
173
+ if (
174
+ session_summary_model.supports_native_structured_outputs
175
+ and summary_response.parsed is not None
176
+ and isinstance(summary_response.parsed, SessionSummaryResponse)
177
+ ):
178
+ session_summary = SessionSummary(
179
+ summary=summary_response.parsed.summary,
180
+ topics=summary_response.parsed.topics,
181
+ updated_at=datetime.now(),
182
+ )
183
+ self.summary = session_summary
184
+ log_debug("Session summary created", center=True)
185
+ return session_summary
186
+
187
+ # Handle string responses
188
+ if isinstance(summary_response.content, str):
189
+ try:
190
+ from agno.utils.string import parse_response_model_str
191
+
192
+ parsed_summary: SessionSummaryResponse = parse_response_model_str( # type: ignore
193
+ summary_response.content, SessionSummaryResponse
194
+ )
195
+
196
+ if parsed_summary is not None:
197
+ session_summary = SessionSummary(
198
+ summary=parsed_summary.summary, topics=parsed_summary.topics, updated_at=datetime.now()
199
+ )
200
+ self.summary = session_summary
201
+ log_debug("Session summary created", center=True)
202
+ return session_summary
203
+ else:
204
+ log_warning("Failed to parse session summary response")
205
+
206
+ except Exception as e:
207
+ log_warning(f"Failed to parse session summary response: {e}")
208
+
209
+ return None
210
+
211
+ def create_session_summary(
212
+ self,
213
+ session: Union["AgentSession", "TeamSession"],
214
+ ) -> Optional[SessionSummary]:
215
+ """Creates a summary of the session"""
216
+ log_debug("Creating session summary", center=True)
217
+ self.model = get_model(self.model)
218
+ if self.model is None:
219
+ return None
220
+
221
+ messages = self._prepare_summary_messages(session)
222
+
223
+ # Skip summary generation if there are no meaningful messages
224
+ if messages is None:
225
+ log_debug("No meaningful messages to summarize, skipping session summary")
226
+ return None
227
+
228
+ response_format = self.get_response_format(self.model)
229
+
230
+ summary_response = self.model.response(messages=messages, response_format=response_format)
231
+ session_summary = self._process_summary_response(summary_response, self.model)
232
+
233
+ if session is not None and session_summary is not None:
234
+ session.summary = session_summary
235
+ self.summaries_updated = True
236
+
237
+ return session_summary
238
+
239
+ async def acreate_session_summary(
240
+ self,
241
+ session: Union["AgentSession", "TeamSession"],
242
+ ) -> Optional[SessionSummary]:
243
+ """Creates a summary of the session"""
244
+ log_debug("Creating session summary", center=True)
245
+ self.model = get_model(self.model)
246
+ if self.model is None:
247
+ return None
248
+
249
+ messages = self._prepare_summary_messages(session)
250
+
251
+ # Skip summary generation if there are no meaningful messages
252
+ if messages is None:
253
+ log_debug("No meaningful messages to summarize, skipping session summary")
254
+ return None
255
+
256
+ response_format = self.get_response_format(self.model)
257
+
258
+ summary_response = await self.model.aresponse(messages=messages, response_format=response_format)
259
+ session_summary = self._process_summary_response(summary_response, self.model)
260
+
261
+ if session is not None and session_summary is not None:
262
+ session.summary = session_summary
263
+ self.summaries_updated = True
264
+
265
+ return session_summary