agno 0.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.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/__init__.py +24 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -0
- agno/db/gcs_json/utils.py +228 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -0
- agno/db/redis/utils.py +346 -0
- agno/db/schemas/__init__.py +4 -0
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/knowledge/embedder/google.py +258 -0
- agno/knowledge/embedder/huggingface.py +94 -0
- agno/knowledge/embedder/jina.py +182 -0
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +206 -0
- agno/knowledge/embedder/nebius.py +13 -0
- agno/knowledge/embedder/ollama.py +154 -0
- agno/knowledge/embedder/openai.py +195 -0
- agno/knowledge/embedder/sentence_transformer.py +63 -0
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/knowledge/reader/arxiv_reader.py +81 -0
- agno/knowledge/reader/base.py +95 -0
- agno/knowledge/reader/csv_reader.py +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -0
- agno/knowledge/reader/markdown_reader.py +137 -0
- agno/knowledge/reader/pdf_reader.py +431 -0
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +313 -0
- agno/knowledge/reader/s3_reader.py +89 -0
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/knowledge/reranker/infinity.py +195 -0
- agno/knowledge/reranker/sentence_transformer.py +54 -0
- agno/knowledge/types.py +39 -0
- agno/knowledge/utils.py +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -0
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/lmstudio/__init__.py +5 -0
- agno/models/lmstudio/lmstudio.py +25 -0
- agno/models/message.py +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +249 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +47 -0
- agno/os/interfaces/agui/router.py +147 -0
- agno/os/interfaces/agui/utils.py +574 -0
- agno/os/interfaces/base.py +25 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/os/interfaces/slack/router.py +148 -0
- agno/os/interfaces/slack/security.py +30 -0
- agno/os/interfaces/slack/slack.py +47 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/os/interfaces/whatsapp/router.py +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -0
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +190 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +997 -0
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -0
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +67 -0
- agno/reasoning/deepseek.py +63 -0
- agno/reasoning/default.py +97 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +71 -0
- agno/reasoning/helpers.py +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- agno/tools/bitbucket.py +292 -0
- agno/tools/brandfetch.py +213 -0
- agno/tools/bravesearch.py +106 -0
- agno/tools/brightdata.py +367 -0
- agno/tools/browserbase.py +209 -0
- agno/tools/calcom.py +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +193 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- agno/tools/models/azure_openai.py +190 -0
- agno/tools/models/gemini.py +203 -0
- agno/tools/models/groq.py +158 -0
- agno/tools/models/morph.py +186 -0
- agno/tools/models/nebius.py +124 -0
- agno/tools/models_labs.py +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- agno/tools/user_control_flow.py +78 -0
- agno/tools/valyu.py +228 -0
- agno/tools/visualization.py +467 -0
- agno/tools/webbrowser.py +28 -0
- agno/tools/webex.py +76 -0
- agno/tools/website.py +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -0
- agno/utils/models/openai_responses.py +140 -0
- agno/utils/models/schema_utils.py +153 -0
- agno/utils/models/watsonx.py +41 -0
- agno/utils/openai.py +257 -0
- agno/utils/pickle.py +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -0
- agno/utils/print_response/workflow.py +1668 -0
- agno/utils/prompts.py +111 -0
- agno/utils/reasoning.py +108 -0
- agno/utils/response.py +163 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +163 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +388 -0
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +166 -0
- agno/vectordb/milvus/__init__.py +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -0
- agno/vectordb/upstashdb/__init__.py +5 -0
- agno/vectordb/upstashdb/upstashdb.py +718 -0
- agno/vectordb/weaviate/__init__.py +8 -0
- agno/vectordb/weaviate/index.py +15 -0
- agno/vectordb/weaviate/weaviate.py +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/storage/agent/postgres.py
DELETED
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
from sqlalchemy.dialects import postgresql
|
|
6
|
-
from sqlalchemy.engine import Engine, create_engine
|
|
7
|
-
from sqlalchemy.inspection import inspect
|
|
8
|
-
from sqlalchemy.orm import scoped_session, sessionmaker
|
|
9
|
-
from sqlalchemy.schema import Column, Index, MetaData, Table
|
|
10
|
-
from sqlalchemy.sql.expression import select, text
|
|
11
|
-
from sqlalchemy.types import BigInteger, String
|
|
12
|
-
except ImportError:
|
|
13
|
-
raise ImportError("`sqlalchemy` not installed. Please install it using `pip install sqlalchemy`")
|
|
14
|
-
|
|
15
|
-
from agno.storage.agent.base import AgentStorage
|
|
16
|
-
from agno.storage.agent.session import AgentSession
|
|
17
|
-
from agno.utils.log import logger
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class PostgresAgentStorage(AgentStorage):
|
|
21
|
-
def __init__(
|
|
22
|
-
self,
|
|
23
|
-
table_name: str,
|
|
24
|
-
schema: Optional[str] = "ai",
|
|
25
|
-
db_url: Optional[str] = None,
|
|
26
|
-
db_engine: Optional[Engine] = None,
|
|
27
|
-
schema_version: int = 1,
|
|
28
|
-
auto_upgrade_schema: bool = False,
|
|
29
|
-
):
|
|
30
|
-
"""
|
|
31
|
-
This class provides agent storage using a PostgreSQL table.
|
|
32
|
-
|
|
33
|
-
The following order is used to determine the database connection:
|
|
34
|
-
1. Use the db_engine if provided
|
|
35
|
-
2. Use the db_url
|
|
36
|
-
3. Raise an error if neither is provided
|
|
37
|
-
|
|
38
|
-
Args:
|
|
39
|
-
table_name (str): Name of the table to store Agent sessions.
|
|
40
|
-
schema (Optional[str]): The schema to use for the table. Defaults to "ai".
|
|
41
|
-
db_url (Optional[str]): The database URL to connect to.
|
|
42
|
-
db_engine (Optional[Engine]): The SQLAlchemy database engine to use.
|
|
43
|
-
schema_version (int): Version of the schema. Defaults to 1.
|
|
44
|
-
auto_upgrade_schema (bool): Whether to automatically upgrade the schema.
|
|
45
|
-
|
|
46
|
-
Raises:
|
|
47
|
-
ValueError: If neither db_url nor db_engine is provided.
|
|
48
|
-
"""
|
|
49
|
-
_engine: Optional[Engine] = db_engine
|
|
50
|
-
if _engine is None and db_url is not None:
|
|
51
|
-
_engine = create_engine(db_url)
|
|
52
|
-
|
|
53
|
-
if _engine is None:
|
|
54
|
-
raise ValueError("Must provide either db_url or db_engine")
|
|
55
|
-
|
|
56
|
-
# Database attributes
|
|
57
|
-
self.table_name: str = table_name
|
|
58
|
-
self.schema: Optional[str] = schema
|
|
59
|
-
self.db_url: Optional[str] = db_url
|
|
60
|
-
self.db_engine: Engine = _engine
|
|
61
|
-
self.metadata: MetaData = MetaData(schema=self.schema)
|
|
62
|
-
self.inspector = inspect(self.db_engine)
|
|
63
|
-
|
|
64
|
-
# Table schema version
|
|
65
|
-
self.schema_version: int = schema_version
|
|
66
|
-
# Automatically upgrade schema if True
|
|
67
|
-
self.auto_upgrade_schema: bool = auto_upgrade_schema
|
|
68
|
-
|
|
69
|
-
# Database session
|
|
70
|
-
self.Session: scoped_session = scoped_session(sessionmaker(bind=self.db_engine))
|
|
71
|
-
# Database table for storage
|
|
72
|
-
self.table: Table = self.get_table()
|
|
73
|
-
logger.debug(f"Created PostgresAgentStorage: '{self.schema}.{self.table_name}'")
|
|
74
|
-
|
|
75
|
-
def get_table_v1(self) -> Table:
|
|
76
|
-
"""
|
|
77
|
-
Define the table schema for version 1.
|
|
78
|
-
|
|
79
|
-
Returns:
|
|
80
|
-
Table: SQLAlchemy Table object representing the schema.
|
|
81
|
-
"""
|
|
82
|
-
table = Table(
|
|
83
|
-
self.table_name,
|
|
84
|
-
self.metadata,
|
|
85
|
-
# Session UUID: Primary Key
|
|
86
|
-
Column("session_id", String, primary_key=True),
|
|
87
|
-
# ID of the agent that this session is associated with
|
|
88
|
-
Column("agent_id", String),
|
|
89
|
-
# ID of the user interacting with this agent
|
|
90
|
-
Column("user_id", String),
|
|
91
|
-
# Agent Memory
|
|
92
|
-
Column("memory", postgresql.JSONB),
|
|
93
|
-
# Agent Data
|
|
94
|
-
Column("agent_data", postgresql.JSONB),
|
|
95
|
-
# Session Data
|
|
96
|
-
Column("session_data", postgresql.JSONB),
|
|
97
|
-
# Extra Data stored with this agent
|
|
98
|
-
Column("extra_data", postgresql.JSONB),
|
|
99
|
-
# The Unix timestamp of when this session was created.
|
|
100
|
-
Column("created_at", BigInteger, server_default=text("(extract(epoch from now()))::bigint")),
|
|
101
|
-
# The Unix timestamp of when this session was last updated.
|
|
102
|
-
Column("updated_at", BigInteger, server_onupdate=text("(extract(epoch from now()))::bigint")),
|
|
103
|
-
extend_existing=True,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Add indexes
|
|
107
|
-
Index(f"idx_{self.table_name}_session_id", table.c.session_id)
|
|
108
|
-
Index(f"idx_{self.table_name}_agent_id", table.c.agent_id)
|
|
109
|
-
Index(f"idx_{self.table_name}_user_id", table.c.user_id)
|
|
110
|
-
|
|
111
|
-
return table
|
|
112
|
-
|
|
113
|
-
def get_table(self) -> Table:
|
|
114
|
-
"""
|
|
115
|
-
Get the table schema based on the schema version.
|
|
116
|
-
|
|
117
|
-
Returns:
|
|
118
|
-
Table: SQLAlchemy Table object for the current schema version.
|
|
119
|
-
|
|
120
|
-
Raises:
|
|
121
|
-
ValueError: If an unsupported schema version is specified.
|
|
122
|
-
"""
|
|
123
|
-
if self.schema_version == 1:
|
|
124
|
-
return self.get_table_v1()
|
|
125
|
-
else:
|
|
126
|
-
raise ValueError(f"Unsupported schema version: {self.schema_version}")
|
|
127
|
-
|
|
128
|
-
def table_exists(self) -> bool:
|
|
129
|
-
"""
|
|
130
|
-
Check if the table exists in the database.
|
|
131
|
-
|
|
132
|
-
Returns:
|
|
133
|
-
bool: True if the table exists, False otherwise.
|
|
134
|
-
"""
|
|
135
|
-
logger.debug(f"Checking if table exists: {self.table.name}")
|
|
136
|
-
try:
|
|
137
|
-
return self.inspector.has_table(self.table.name, schema=self.schema)
|
|
138
|
-
except Exception as e:
|
|
139
|
-
logger.error(f"Error checking if table exists: {e}")
|
|
140
|
-
return False
|
|
141
|
-
|
|
142
|
-
def create(self) -> None:
|
|
143
|
-
"""
|
|
144
|
-
Create the table if it does not exist.
|
|
145
|
-
"""
|
|
146
|
-
if not self.table_exists():
|
|
147
|
-
try:
|
|
148
|
-
with self.Session() as sess, sess.begin():
|
|
149
|
-
if self.schema is not None:
|
|
150
|
-
logger.debug(f"Creating schema: {self.schema}")
|
|
151
|
-
sess.execute(text(f"CREATE SCHEMA IF NOT EXISTS {self.schema};"))
|
|
152
|
-
logger.debug(f"Creating table: {self.table_name}")
|
|
153
|
-
self.table.create(self.db_engine, checkfirst=True)
|
|
154
|
-
except Exception as e:
|
|
155
|
-
logger.error(f"Could not create table: '{self.table.fullname}': {e}")
|
|
156
|
-
|
|
157
|
-
def read(self, session_id: str, user_id: Optional[str] = None) -> Optional[AgentSession]:
|
|
158
|
-
"""
|
|
159
|
-
Read an AgentSession from the database.
|
|
160
|
-
|
|
161
|
-
Args:
|
|
162
|
-
session_id (str): ID of the session to read.
|
|
163
|
-
user_id (Optional[str]): User ID to filter by. Defaults to None.
|
|
164
|
-
|
|
165
|
-
Returns:
|
|
166
|
-
Optional[AgentSession]: AgentSession object if found, None otherwise.
|
|
167
|
-
"""
|
|
168
|
-
try:
|
|
169
|
-
with self.Session() as sess:
|
|
170
|
-
stmt = select(self.table).where(self.table.c.session_id == session_id)
|
|
171
|
-
if user_id:
|
|
172
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
173
|
-
result = sess.execute(stmt).fetchone()
|
|
174
|
-
return AgentSession.from_dict(result._mapping) if result is not None else None
|
|
175
|
-
except Exception as e:
|
|
176
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
177
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
178
|
-
logger.debug("Creating table for future transactions")
|
|
179
|
-
self.create()
|
|
180
|
-
return None
|
|
181
|
-
|
|
182
|
-
def get_all_session_ids(self, user_id: Optional[str] = None, agent_id: Optional[str] = None) -> List[str]:
|
|
183
|
-
"""
|
|
184
|
-
Get all session IDs, optionally filtered by user_id and/or agent_id.
|
|
185
|
-
|
|
186
|
-
Args:
|
|
187
|
-
user_id (Optional[str]): The ID of the user to filter by.
|
|
188
|
-
agent_id (Optional[str]): The ID of the agent to filter by.
|
|
189
|
-
|
|
190
|
-
Returns:
|
|
191
|
-
List[str]: List of session IDs matching the criteria.
|
|
192
|
-
"""
|
|
193
|
-
try:
|
|
194
|
-
with self.Session() as sess, sess.begin():
|
|
195
|
-
# get all session_ids
|
|
196
|
-
stmt = select(self.table.c.session_id)
|
|
197
|
-
if user_id is not None:
|
|
198
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
199
|
-
if agent_id is not None:
|
|
200
|
-
stmt = stmt.where(self.table.c.agent_id == agent_id)
|
|
201
|
-
# order by created_at desc
|
|
202
|
-
stmt = stmt.order_by(self.table.c.created_at.desc())
|
|
203
|
-
# execute query
|
|
204
|
-
rows = sess.execute(stmt).fetchall()
|
|
205
|
-
return [row[0] for row in rows] if rows is not None else []
|
|
206
|
-
except Exception as e:
|
|
207
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
208
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
209
|
-
logger.debug("Creating table for future transactions")
|
|
210
|
-
self.create()
|
|
211
|
-
return []
|
|
212
|
-
|
|
213
|
-
def get_all_sessions(self, user_id: Optional[str] = None, agent_id: Optional[str] = None) -> List[AgentSession]:
|
|
214
|
-
"""
|
|
215
|
-
Get all sessions, optionally filtered by user_id and/or agent_id.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
user_id (Optional[str]): The ID of the user to filter by.
|
|
219
|
-
agent_id (Optional[str]): The ID of the agent to filter by.
|
|
220
|
-
|
|
221
|
-
Returns:
|
|
222
|
-
List[AgentSession]: List of AgentSession objects matching the criteria.
|
|
223
|
-
"""
|
|
224
|
-
try:
|
|
225
|
-
with self.Session() as sess, sess.begin():
|
|
226
|
-
# get all sessions
|
|
227
|
-
stmt = select(self.table)
|
|
228
|
-
if user_id is not None:
|
|
229
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
230
|
-
if agent_id is not None:
|
|
231
|
-
stmt = stmt.where(self.table.c.agent_id == agent_id)
|
|
232
|
-
# order by created_at desc
|
|
233
|
-
stmt = stmt.order_by(self.table.c.created_at.desc())
|
|
234
|
-
# execute query
|
|
235
|
-
rows = sess.execute(stmt).fetchall()
|
|
236
|
-
return [AgentSession.from_dict(row._mapping) for row in rows] if rows is not None else [] # type: ignore
|
|
237
|
-
except Exception as e:
|
|
238
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
239
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
240
|
-
logger.debug("Creating table for future transactions")
|
|
241
|
-
self.create()
|
|
242
|
-
return []
|
|
243
|
-
|
|
244
|
-
def upsert(self, session: AgentSession, create_and_retry: bool = True) -> Optional[AgentSession]:
|
|
245
|
-
"""
|
|
246
|
-
Insert or update an AgentSession in the database.
|
|
247
|
-
|
|
248
|
-
Args:
|
|
249
|
-
session (AgentSession): The session data to upsert.
|
|
250
|
-
create_and_retry (bool): Retry upsert if table does not exist.
|
|
251
|
-
|
|
252
|
-
Returns:
|
|
253
|
-
Optional[AgentSession]: The upserted AgentSession, or None if operation failed.
|
|
254
|
-
"""
|
|
255
|
-
try:
|
|
256
|
-
with self.Session() as sess, sess.begin():
|
|
257
|
-
# Create an insert statement
|
|
258
|
-
stmt = postgresql.insert(self.table).values(
|
|
259
|
-
session_id=session.session_id,
|
|
260
|
-
agent_id=session.agent_id,
|
|
261
|
-
user_id=session.user_id,
|
|
262
|
-
memory=session.memory,
|
|
263
|
-
agent_data=session.agent_data,
|
|
264
|
-
session_data=session.session_data,
|
|
265
|
-
extra_data=session.extra_data,
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
# Define the upsert if the session_id already exists
|
|
269
|
-
# See: https://docs.sqlalchemy.org/en/20/dialects/postgresql.html#postgresql-insert-on-conflict
|
|
270
|
-
stmt = stmt.on_conflict_do_update(
|
|
271
|
-
index_elements=["session_id"],
|
|
272
|
-
set_=dict(
|
|
273
|
-
agent_id=session.agent_id,
|
|
274
|
-
user_id=session.user_id,
|
|
275
|
-
memory=session.memory,
|
|
276
|
-
agent_data=session.agent_data,
|
|
277
|
-
session_data=session.session_data,
|
|
278
|
-
extra_data=session.extra_data,
|
|
279
|
-
updated_at=int(time.time()),
|
|
280
|
-
), # The updated value for each column
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
sess.execute(stmt)
|
|
284
|
-
except Exception as e:
|
|
285
|
-
logger.debug(f"Exception upserting into table: {e}")
|
|
286
|
-
if create_and_retry and not self.table_exists():
|
|
287
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
288
|
-
logger.debug("Creating table and retrying upsert")
|
|
289
|
-
self.create()
|
|
290
|
-
return self.upsert(session, create_and_retry=False)
|
|
291
|
-
return None
|
|
292
|
-
return self.read(session_id=session.session_id)
|
|
293
|
-
|
|
294
|
-
def delete_session(self, session_id: Optional[str] = None):
|
|
295
|
-
"""
|
|
296
|
-
Delete a session from the database.
|
|
297
|
-
|
|
298
|
-
Args:
|
|
299
|
-
session_id (Optional[str], optional): ID of the session to delete. Defaults to None.
|
|
300
|
-
|
|
301
|
-
Raises:
|
|
302
|
-
Exception: If an error occurs during deletion.
|
|
303
|
-
"""
|
|
304
|
-
if session_id is None:
|
|
305
|
-
logger.warning("No session_id provided for deletion.")
|
|
306
|
-
return
|
|
307
|
-
|
|
308
|
-
try:
|
|
309
|
-
with self.Session() as sess, sess.begin():
|
|
310
|
-
# Delete the session with the given session_id
|
|
311
|
-
delete_stmt = self.table.delete().where(self.table.c.session_id == session_id)
|
|
312
|
-
result = sess.execute(delete_stmt)
|
|
313
|
-
if result.rowcount == 0:
|
|
314
|
-
logger.debug(f"No session found with session_id: {session_id}")
|
|
315
|
-
else:
|
|
316
|
-
logger.debug(f"Successfully deleted session with session_id: {session_id}")
|
|
317
|
-
except Exception as e:
|
|
318
|
-
logger.error(f"Error deleting session: {e}")
|
|
319
|
-
|
|
320
|
-
def drop(self) -> None:
|
|
321
|
-
"""
|
|
322
|
-
Drop the table from the database if it exists.
|
|
323
|
-
"""
|
|
324
|
-
if self.table_exists():
|
|
325
|
-
logger.debug(f"Deleting table: {self.table_name}")
|
|
326
|
-
self.table.drop(self.db_engine)
|
|
327
|
-
|
|
328
|
-
def upgrade_schema(self) -> None:
|
|
329
|
-
"""
|
|
330
|
-
Upgrade the schema to the latest version.
|
|
331
|
-
This method is currently a placeholder and does not perform any actions.
|
|
332
|
-
"""
|
|
333
|
-
pass
|
|
334
|
-
|
|
335
|
-
def __deepcopy__(self, memo):
|
|
336
|
-
"""
|
|
337
|
-
Create a deep copy of the PostgresAgentStorage instance, handling unpickleable attributes.
|
|
338
|
-
|
|
339
|
-
Args:
|
|
340
|
-
memo (dict): A dictionary of objects already copied during the current copying pass.
|
|
341
|
-
|
|
342
|
-
Returns:
|
|
343
|
-
PostgresAgentStorage: A deep-copied instance of PostgresAgentStorage.
|
|
344
|
-
"""
|
|
345
|
-
from copy import deepcopy
|
|
346
|
-
|
|
347
|
-
# Create a new instance without calling __init__
|
|
348
|
-
cls = self.__class__
|
|
349
|
-
copied_obj = cls.__new__(cls)
|
|
350
|
-
memo[id(self)] = copied_obj
|
|
351
|
-
|
|
352
|
-
# Deep copy attributes
|
|
353
|
-
for k, v in self.__dict__.items():
|
|
354
|
-
if k in {"metadata", "table", "inspector"}:
|
|
355
|
-
continue
|
|
356
|
-
# Reuse db_engine and Session without copying
|
|
357
|
-
elif k in {"db_engine", "Session"}:
|
|
358
|
-
setattr(copied_obj, k, v)
|
|
359
|
-
else:
|
|
360
|
-
setattr(copied_obj, k, deepcopy(v, memo))
|
|
361
|
-
|
|
362
|
-
# Recreate metadata and table for the copied instance
|
|
363
|
-
copied_obj.metadata = MetaData(schema=copied_obj.schema)
|
|
364
|
-
copied_obj.inspector = inspect(copied_obj.db_engine)
|
|
365
|
-
copied_obj.table = copied_obj.get_table()
|
|
366
|
-
|
|
367
|
-
return copied_obj
|
agno/storage/agent/session.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import asdict, dataclass
|
|
4
|
-
from typing import Any, Dict, Mapping, Optional
|
|
5
|
-
|
|
6
|
-
from agno.utils.log import logger
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass
|
|
10
|
-
class AgentSession:
|
|
11
|
-
"""Agent Session that is stored in the database"""
|
|
12
|
-
|
|
13
|
-
# Session UUID
|
|
14
|
-
session_id: str
|
|
15
|
-
# ID of the agent that this session is associated with
|
|
16
|
-
agent_id: Optional[str] = None
|
|
17
|
-
# ID of the user interacting with this agent
|
|
18
|
-
user_id: Optional[str] = None
|
|
19
|
-
# Agent Memory
|
|
20
|
-
memory: Optional[Dict[str, Any]] = None
|
|
21
|
-
# Agent Data: agent_id, name and model
|
|
22
|
-
agent_data: Optional[Dict[str, Any]] = None
|
|
23
|
-
# Session Data: session_name, session_state, images, videos, audio
|
|
24
|
-
session_data: Optional[Dict[str, Any]] = None
|
|
25
|
-
# Extra Data stored with this agent
|
|
26
|
-
extra_data: Optional[Dict[str, Any]] = None
|
|
27
|
-
# The unix timestamp when this session was created
|
|
28
|
-
created_at: Optional[int] = None
|
|
29
|
-
# The unix timestamp when this session was last updated
|
|
30
|
-
updated_at: Optional[int] = None
|
|
31
|
-
|
|
32
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
33
|
-
return asdict(self)
|
|
34
|
-
|
|
35
|
-
def monitoring_data(self) -> Dict[str, Any]:
|
|
36
|
-
# Google Gemini adds a "parts" field to the messages, which is not serializable
|
|
37
|
-
# If the provider is Google, remove the "parts" from the messages
|
|
38
|
-
if self.agent_data is not None:
|
|
39
|
-
if self.agent_data.get("model", {}).get("provider") == "Google" and self.memory is not None:
|
|
40
|
-
# Remove parts from runs' response messages
|
|
41
|
-
if "runs" in self.memory:
|
|
42
|
-
for _run in self.memory["runs"]:
|
|
43
|
-
if "response" in _run and "messages" in _run["response"]:
|
|
44
|
-
for m in _run["response"]["messages"]:
|
|
45
|
-
if isinstance(m, dict):
|
|
46
|
-
m.pop("parts", None)
|
|
47
|
-
|
|
48
|
-
# Remove parts from top-level memory messages
|
|
49
|
-
if "messages" in self.memory:
|
|
50
|
-
for m in self.memory["messages"]:
|
|
51
|
-
if isinstance(m, dict):
|
|
52
|
-
m.pop("parts", None)
|
|
53
|
-
|
|
54
|
-
monitoring_data = asdict(self)
|
|
55
|
-
return monitoring_data
|
|
56
|
-
|
|
57
|
-
def telemetry_data(self) -> Dict[str, Any]:
|
|
58
|
-
return {
|
|
59
|
-
"model": self.agent_data.get("model") if self.agent_data else None,
|
|
60
|
-
"created_at": self.created_at,
|
|
61
|
-
"updated_at": self.updated_at,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@classmethod
|
|
65
|
-
def from_dict(cls, data: Mapping[str, Any]) -> Optional[AgentSession]:
|
|
66
|
-
if data is None or data.get("session_id") is None:
|
|
67
|
-
logger.warning("AgentSession is missing session_id")
|
|
68
|
-
return None
|
|
69
|
-
return cls(
|
|
70
|
-
session_id=data.get("session_id"), # type: ignore
|
|
71
|
-
agent_id=data.get("agent_id"),
|
|
72
|
-
user_id=data.get("user_id"),
|
|
73
|
-
memory=data.get("memory"),
|
|
74
|
-
agent_data=data.get("agent_data"),
|
|
75
|
-
session_data=data.get("session_data"),
|
|
76
|
-
extra_data=data.get("extra_data"),
|
|
77
|
-
created_at=data.get("created_at"),
|
|
78
|
-
updated_at=data.get("updated_at"),
|
|
79
|
-
)
|