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
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
from typing import List, Optional
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
from sqlalchemy import BigInteger, Column, Engine, Index, MetaData, String, Table, create_engine, inspect
|
|
6
|
-
from sqlalchemy.dialects import postgresql
|
|
7
|
-
from sqlalchemy.orm import scoped_session, sessionmaker
|
|
8
|
-
from sqlalchemy.sql.expression import select, text
|
|
9
|
-
except ImportError:
|
|
10
|
-
raise ImportError("`sqlalchemy` not installed. Please install it with `pip install sqlalchemy`")
|
|
11
|
-
|
|
12
|
-
from agno.storage.workflow.base import WorkflowStorage
|
|
13
|
-
from agno.storage.workflow.session import WorkflowSession
|
|
14
|
-
from agno.utils.log import logger
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class PostgresWorkflowStorage(WorkflowStorage):
|
|
18
|
-
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
table_name: str,
|
|
21
|
-
schema: Optional[str] = "ai",
|
|
22
|
-
db_url: Optional[str] = None,
|
|
23
|
-
db_engine: Optional[Engine] = None,
|
|
24
|
-
schema_version: int = 1,
|
|
25
|
-
auto_upgrade_schema: bool = False,
|
|
26
|
-
):
|
|
27
|
-
"""
|
|
28
|
-
This class provides workflow storage using a PostgreSQL database.
|
|
29
|
-
|
|
30
|
-
The following order is used to determine the database connection:
|
|
31
|
-
1. Use the db_engine if provided
|
|
32
|
-
2. Use the db_url
|
|
33
|
-
3. Raise an error if neither is provided
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
table_name (str): The name of the table to store Workflow sessions.
|
|
37
|
-
schema (Optional[str]): The schema to use for the table. Defaults to "ai".
|
|
38
|
-
db_url (Optional[str]): The database URL to connect to.
|
|
39
|
-
db_engine (Optional[Engine]): The SQLAlchemy database engine to use.
|
|
40
|
-
schema_version (int): Version of the schema. Defaults to 1.
|
|
41
|
-
auto_upgrade_schema (bool): Whether to automatically upgrade the schema.
|
|
42
|
-
|
|
43
|
-
Raises:
|
|
44
|
-
ValueError: If neither db_url nor db_engine is provided.
|
|
45
|
-
"""
|
|
46
|
-
_engine: Optional[Engine] = db_engine
|
|
47
|
-
if _engine is None and db_url is not None:
|
|
48
|
-
_engine = create_engine(db_url)
|
|
49
|
-
|
|
50
|
-
if _engine is None:
|
|
51
|
-
raise ValueError("Must provide either db_url or db_engine")
|
|
52
|
-
|
|
53
|
-
# Database attributes
|
|
54
|
-
self.table_name: str = table_name
|
|
55
|
-
self.schema: Optional[str] = schema
|
|
56
|
-
self.db_url: Optional[str] = db_url
|
|
57
|
-
self.db_engine: Engine = _engine
|
|
58
|
-
self.metadata: MetaData = MetaData(schema=self.schema)
|
|
59
|
-
self.inspector = inspect(self.db_engine)
|
|
60
|
-
|
|
61
|
-
# Table schema version
|
|
62
|
-
self.schema_version: int = schema_version
|
|
63
|
-
# Automatically upgrade schema if True
|
|
64
|
-
self.auto_upgrade_schema: bool = auto_upgrade_schema
|
|
65
|
-
|
|
66
|
-
# Database session
|
|
67
|
-
self.Session: scoped_session = scoped_session(sessionmaker(bind=self.db_engine))
|
|
68
|
-
# Database table for storage
|
|
69
|
-
self.table: Table = self.get_table()
|
|
70
|
-
logger.debug(f"Created PostgresWorkflowStorage: '{self.schema}.{self.table_name}'")
|
|
71
|
-
|
|
72
|
-
def get_table_v1(self) -> Table:
|
|
73
|
-
"""
|
|
74
|
-
Define the table schema for version 1.
|
|
75
|
-
|
|
76
|
-
Returns:
|
|
77
|
-
Table: SQLAlchemy Table object representing the schema.
|
|
78
|
-
"""
|
|
79
|
-
table = Table(
|
|
80
|
-
self.table_name,
|
|
81
|
-
self.metadata,
|
|
82
|
-
# Session UUID: Primary Key
|
|
83
|
-
Column("session_id", String, primary_key=True),
|
|
84
|
-
# ID of the workflow that this session is associated with
|
|
85
|
-
Column("workflow_id", String),
|
|
86
|
-
# ID of the user interacting with this workflow
|
|
87
|
-
Column("user_id", String),
|
|
88
|
-
# Workflow Memory
|
|
89
|
-
Column("memory", postgresql.JSONB),
|
|
90
|
-
# Workflow Data
|
|
91
|
-
Column("workflow_data", postgresql.JSONB),
|
|
92
|
-
# Session Data
|
|
93
|
-
Column("session_data", postgresql.JSONB),
|
|
94
|
-
# Extra Data
|
|
95
|
-
Column("extra_data", postgresql.JSONB),
|
|
96
|
-
# The Unix timestamp of when this session was created.
|
|
97
|
-
Column("created_at", BigInteger, default=lambda: int(time.time())),
|
|
98
|
-
# The Unix timestamp of when this session was last updated.
|
|
99
|
-
Column("updated_at", BigInteger, onupdate=lambda: int(time.time())),
|
|
100
|
-
extend_existing=True,
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
# Add indexes
|
|
104
|
-
Index(f"idx_{self.table_name}_session_id", table.c.session_id)
|
|
105
|
-
Index(f"idx_{self.table_name}_workflow_id", table.c.workflow_id)
|
|
106
|
-
Index(f"idx_{self.table_name}_user_id", table.c.user_id)
|
|
107
|
-
|
|
108
|
-
return table
|
|
109
|
-
|
|
110
|
-
def get_table(self) -> Table:
|
|
111
|
-
"""
|
|
112
|
-
Get the table schema based on the schema version.
|
|
113
|
-
|
|
114
|
-
Returns:
|
|
115
|
-
Table: SQLAlchemy Table object for the current schema version.
|
|
116
|
-
|
|
117
|
-
Raises:
|
|
118
|
-
ValueError: If an unsupported schema version is specified.
|
|
119
|
-
"""
|
|
120
|
-
if self.schema_version == 1:
|
|
121
|
-
return self.get_table_v1()
|
|
122
|
-
else:
|
|
123
|
-
raise ValueError(f"Unsupported schema version: {self.schema_version}")
|
|
124
|
-
|
|
125
|
-
def table_exists(self) -> bool:
|
|
126
|
-
"""
|
|
127
|
-
Check if the table exists in the database.
|
|
128
|
-
|
|
129
|
-
Returns:
|
|
130
|
-
bool: True if the table exists, False otherwise.
|
|
131
|
-
"""
|
|
132
|
-
logger.debug(f"Checking if table exists: {self.table.name}")
|
|
133
|
-
try:
|
|
134
|
-
return self.inspector.has_table(self.table.name, schema=self.schema)
|
|
135
|
-
except Exception as e:
|
|
136
|
-
logger.error(f"Error checking if table exists: {e}")
|
|
137
|
-
return False
|
|
138
|
-
|
|
139
|
-
def create(self) -> None:
|
|
140
|
-
"""
|
|
141
|
-
Create the table if it doesn't exist.
|
|
142
|
-
"""
|
|
143
|
-
if not self.table_exists():
|
|
144
|
-
try:
|
|
145
|
-
with self.Session() as sess, sess.begin():
|
|
146
|
-
if self.schema is not None:
|
|
147
|
-
logger.debug(f"Creating schema: {self.schema}")
|
|
148
|
-
sess.execute(text(f"CREATE SCHEMA IF NOT EXISTS {self.schema};"))
|
|
149
|
-
logger.debug(f"Creating table: {self.table_name}")
|
|
150
|
-
self.table.create(self.db_engine, checkfirst=True)
|
|
151
|
-
except Exception as e:
|
|
152
|
-
logger.error(f"Could not create table: '{self.table.fullname}': {e}")
|
|
153
|
-
|
|
154
|
-
def read(self, session_id: str, user_id: Optional[str] = None) -> Optional[WorkflowSession]:
|
|
155
|
-
"""
|
|
156
|
-
Read a WorkflowSession from the database.
|
|
157
|
-
|
|
158
|
-
Args:
|
|
159
|
-
session_id (str): The ID of the session to read.
|
|
160
|
-
user_id (Optional[str]): The ID of the user associated with the session.
|
|
161
|
-
|
|
162
|
-
Returns:
|
|
163
|
-
Optional[WorkflowSession]: The WorkflowSession object if found, None otherwise.
|
|
164
|
-
"""
|
|
165
|
-
try:
|
|
166
|
-
with self.Session() as sess:
|
|
167
|
-
stmt = select(self.table).where(self.table.c.session_id == session_id)
|
|
168
|
-
if user_id:
|
|
169
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
170
|
-
result = sess.execute(stmt).fetchone()
|
|
171
|
-
return WorkflowSession.from_dict(result._mapping) if result is not None else None # type: ignore
|
|
172
|
-
except Exception as e:
|
|
173
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
174
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
175
|
-
logger.debug("Creating table for future transactions")
|
|
176
|
-
self.create()
|
|
177
|
-
return None
|
|
178
|
-
|
|
179
|
-
def get_all_session_ids(self, user_id: Optional[str] = None, workflow_id: Optional[str] = None) -> List[str]:
|
|
180
|
-
"""
|
|
181
|
-
Get all session IDs, optionally filtered by user_id and/or workflow_id.
|
|
182
|
-
|
|
183
|
-
Args:
|
|
184
|
-
user_id (Optional[str]): The ID of the user to filter by.
|
|
185
|
-
workflow_id (Optional[str]): The ID of the workflow to filter by.
|
|
186
|
-
|
|
187
|
-
Returns:
|
|
188
|
-
List[str]: List of session IDs matching the criteria.
|
|
189
|
-
"""
|
|
190
|
-
try:
|
|
191
|
-
with self.Session() as sess, sess.begin():
|
|
192
|
-
# get all session_ids
|
|
193
|
-
stmt = select(self.table.c.session_id)
|
|
194
|
-
if user_id is not None or user_id != "":
|
|
195
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
196
|
-
if workflow_id is not None:
|
|
197
|
-
stmt = stmt.where(self.table.c.workflow_id == workflow_id)
|
|
198
|
-
# order by created_at desc
|
|
199
|
-
stmt = stmt.order_by(self.table.c.created_at.desc())
|
|
200
|
-
# execute query
|
|
201
|
-
rows = sess.execute(stmt).fetchall()
|
|
202
|
-
return [row[0] for row in rows] if rows is not None else []
|
|
203
|
-
except Exception as e:
|
|
204
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
205
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
206
|
-
logger.debug("Creating table for future transactions")
|
|
207
|
-
self.create()
|
|
208
|
-
return []
|
|
209
|
-
|
|
210
|
-
def get_all_sessions(
|
|
211
|
-
self, user_id: Optional[str] = None, workflow_id: Optional[str] = None
|
|
212
|
-
) -> List[WorkflowSession]:
|
|
213
|
-
"""
|
|
214
|
-
Get all sessions, optionally filtered by user_id and/or workflow_id.
|
|
215
|
-
|
|
216
|
-
Args:
|
|
217
|
-
user_id (Optional[str]): The ID of the user to filter by.
|
|
218
|
-
workflow_id (Optional[str]): The ID of the workflow to filter by.
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
List[WorkflowSession]: List of AgentSession objects matching the criteria.
|
|
222
|
-
"""
|
|
223
|
-
try:
|
|
224
|
-
with self.Session() as sess, sess.begin():
|
|
225
|
-
# get all sessions
|
|
226
|
-
stmt = select(self.table)
|
|
227
|
-
if user_id is not None and user_id != "":
|
|
228
|
-
stmt = stmt.where(self.table.c.user_id == user_id)
|
|
229
|
-
if workflow_id is not None:
|
|
230
|
-
stmt = stmt.where(self.table.c.workflow_id == workflow_id)
|
|
231
|
-
# order by created_at desc
|
|
232
|
-
stmt = stmt.order_by(self.table.c.created_at.desc())
|
|
233
|
-
# execute query
|
|
234
|
-
rows = sess.execute(stmt).fetchall()
|
|
235
|
-
return [WorkflowSession.from_dict(row._mapping) for row in rows] if rows is not None else [] # type: ignore
|
|
236
|
-
except Exception as e:
|
|
237
|
-
logger.debug(f"Exception reading from table: {e}")
|
|
238
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
239
|
-
logger.debug("Creating table for future transactions")
|
|
240
|
-
self.create()
|
|
241
|
-
return []
|
|
242
|
-
|
|
243
|
-
def upsert(self, session: WorkflowSession, create_and_retry: bool = True) -> Optional[WorkflowSession]:
|
|
244
|
-
"""
|
|
245
|
-
Insert or update a WorkflowSession in the database.
|
|
246
|
-
|
|
247
|
-
Args:
|
|
248
|
-
session (WorkflowSession): The WorkflowSession object to upsert.
|
|
249
|
-
create_and_retry (bool): Retry upsert if table does not exist.
|
|
250
|
-
|
|
251
|
-
Returns:
|
|
252
|
-
Optional[WorkflowSession]: The upserted WorkflowSession object.
|
|
253
|
-
"""
|
|
254
|
-
try:
|
|
255
|
-
with self.Session() as sess, sess.begin():
|
|
256
|
-
# Create an insert statement
|
|
257
|
-
stmt = postgresql.insert(self.table).values(
|
|
258
|
-
session_id=session.session_id,
|
|
259
|
-
workflow_id=session.workflow_id,
|
|
260
|
-
user_id=session.user_id,
|
|
261
|
-
memory=session.memory,
|
|
262
|
-
workflow_data=session.workflow_data,
|
|
263
|
-
session_data=session.session_data,
|
|
264
|
-
extra_data=session.extra_data,
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
# Define the upsert if the session_id already exists
|
|
268
|
-
# See: https://docs.sqlalchemy.org/en/20/dialects/postgresql.html#postgresql-insert-on-conflict
|
|
269
|
-
stmt = stmt.on_conflict_do_update(
|
|
270
|
-
index_elements=["session_id"],
|
|
271
|
-
set_=dict(
|
|
272
|
-
workflow_id=session.workflow_id,
|
|
273
|
-
user_id=session.user_id,
|
|
274
|
-
memory=session.memory,
|
|
275
|
-
workflow_data=session.workflow_data,
|
|
276
|
-
session_data=session.session_data,
|
|
277
|
-
extra_data=session.extra_data,
|
|
278
|
-
updated_at=int(time.time()),
|
|
279
|
-
), # The updated value for each column
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
sess.execute(stmt)
|
|
283
|
-
except Exception as e:
|
|
284
|
-
logger.debug(f"Exception upserting into table: {e}")
|
|
285
|
-
if create_and_retry and not self.table_exists():
|
|
286
|
-
logger.debug(f"Table does not exist: {self.table.name}")
|
|
287
|
-
logger.debug("Creating table and retrying upsert")
|
|
288
|
-
self.create()
|
|
289
|
-
return self.upsert(session, create_and_retry=False)
|
|
290
|
-
return None
|
|
291
|
-
return self.read(session_id=session.session_id)
|
|
292
|
-
|
|
293
|
-
def delete_session(self, session_id: Optional[str] = None):
|
|
294
|
-
"""
|
|
295
|
-
Delete a workflow session from the database.
|
|
296
|
-
|
|
297
|
-
Args:
|
|
298
|
-
session_id (Optional[str]): The ID of the session to delete.
|
|
299
|
-
|
|
300
|
-
Raises:
|
|
301
|
-
ValueError: If session_id is not provided.
|
|
302
|
-
"""
|
|
303
|
-
if session_id is None:
|
|
304
|
-
logger.warning("No session_id provided for deletion.")
|
|
305
|
-
return
|
|
306
|
-
|
|
307
|
-
try:
|
|
308
|
-
with self.Session() as sess, sess.begin():
|
|
309
|
-
# Delete the session with the given session_id
|
|
310
|
-
delete_stmt = self.table.delete().where(self.table.c.session_id == session_id)
|
|
311
|
-
result = sess.execute(delete_stmt)
|
|
312
|
-
if result.rowcount == 0:
|
|
313
|
-
logger.debug(f"No session found with session_id: {session_id}")
|
|
314
|
-
else:
|
|
315
|
-
logger.debug(f"Successfully deleted session with session_id: {session_id}")
|
|
316
|
-
except Exception as e:
|
|
317
|
-
logger.error(f"Error deleting session: {e}")
|
|
318
|
-
|
|
319
|
-
def drop(self) -> None:
|
|
320
|
-
"""
|
|
321
|
-
Drop the table from the database if it exists.
|
|
322
|
-
"""
|
|
323
|
-
if self.table_exists():
|
|
324
|
-
logger.debug(f"Deleting table: {self.table_name}")
|
|
325
|
-
self.table.drop(self.db_engine)
|
|
326
|
-
|
|
327
|
-
def upgrade_schema(self) -> None:
|
|
328
|
-
"""
|
|
329
|
-
Upgrade the schema of the workflow storage table.
|
|
330
|
-
This method is currently a placeholder and does not perform any actions.
|
|
331
|
-
"""
|
|
332
|
-
pass
|
|
333
|
-
|
|
334
|
-
def __deepcopy__(self, memo):
|
|
335
|
-
"""
|
|
336
|
-
Create a deep copy of the PostgresWorkflowStorage instance, handling unpickleable attributes.
|
|
337
|
-
|
|
338
|
-
Args:
|
|
339
|
-
memo (dict): A dictionary of objects already copied during the current copying pass.
|
|
340
|
-
|
|
341
|
-
Returns:
|
|
342
|
-
PostgresWorkflowStorage: A deep-copied instance of PostgresWorkflowStorage.
|
|
343
|
-
"""
|
|
344
|
-
from copy import deepcopy
|
|
345
|
-
|
|
346
|
-
# Create a new instance without calling __init__
|
|
347
|
-
cls = self.__class__
|
|
348
|
-
copied_obj = cls.__new__(cls)
|
|
349
|
-
memo[id(self)] = copied_obj
|
|
350
|
-
|
|
351
|
-
# Deep copy attributes
|
|
352
|
-
for k, v in self.__dict__.items():
|
|
353
|
-
if k in {"metadata", "table", "inspector"}:
|
|
354
|
-
continue
|
|
355
|
-
# Reuse db_engine and Session without copying
|
|
356
|
-
elif k in {"db_engine", "Session"}:
|
|
357
|
-
setattr(copied_obj, k, v)
|
|
358
|
-
else:
|
|
359
|
-
setattr(copied_obj, k, deepcopy(v, memo))
|
|
360
|
-
|
|
361
|
-
# Recreate metadata and table for the copied instance
|
|
362
|
-
copied_obj.metadata = MetaData(schema=copied_obj.schema)
|
|
363
|
-
copied_obj.inspector = inspect(copied_obj.db_engine)
|
|
364
|
-
copied_obj.table = copied_obj.get_table()
|
|
365
|
-
|
|
366
|
-
return copied_obj
|
agno/storage/workflow/session.py
DELETED
|
@@ -1,60 +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 WorkflowSession:
|
|
11
|
-
"""Workflow Session that is stored in the database"""
|
|
12
|
-
|
|
13
|
-
# Session UUID
|
|
14
|
-
session_id: str
|
|
15
|
-
# ID of the workflow that this session is associated with
|
|
16
|
-
workflow_id: Optional[str] = None
|
|
17
|
-
# ID of the user interacting with this workflow
|
|
18
|
-
user_id: Optional[str] = None
|
|
19
|
-
# Workflow Memory
|
|
20
|
-
memory: Optional[Dict[str, Any]] = None
|
|
21
|
-
# Workflow Data
|
|
22
|
-
workflow_data: Optional[Dict[str, Any]] = None
|
|
23
|
-
# Session Data
|
|
24
|
-
session_data: Optional[Dict[str, Any]] = None
|
|
25
|
-
# Extra Data stored with this workflow
|
|
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
|
-
return asdict(self)
|
|
37
|
-
|
|
38
|
-
def telemetry_data(self) -> Dict[str, Any]:
|
|
39
|
-
return {
|
|
40
|
-
"created_at": self.created_at,
|
|
41
|
-
"updated_at": self.updated_at,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@classmethod
|
|
45
|
-
def from_dict(cls, data: Mapping[str, Any]) -> Optional[WorkflowSession]:
|
|
46
|
-
if data is None or data.get("session_id") is None:
|
|
47
|
-
logger.warning("WorkflowSession is missing session_id")
|
|
48
|
-
return None
|
|
49
|
-
|
|
50
|
-
return cls(
|
|
51
|
-
session_id=data.get("session_id"), # type: ignore
|
|
52
|
-
workflow_id=data.get("workflow_id"),
|
|
53
|
-
user_id=data.get("user_id"),
|
|
54
|
-
memory=data.get("memory"),
|
|
55
|
-
workflow_data=data.get("workflow_data"),
|
|
56
|
-
session_data=data.get("session_data"),
|
|
57
|
-
extra_data=data.get("extra_data"),
|
|
58
|
-
created_at=data.get("created_at"),
|
|
59
|
-
updated_at=data.get("updated_at"),
|
|
60
|
-
)
|