agno 1.8.0__py3-none-any.whl → 2.0.0a1__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 +19 -27
- agno/agent/agent.py +2781 -4126
- agno/api/agent.py +9 -65
- agno/api/api.py +5 -46
- agno/api/evals.py +6 -17
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +9 -64
- 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/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1749 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1438 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +888 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1051 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1417 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +298 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1720 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +281 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1371 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1722 -0
- agno/db/singlestore/utils.py +327 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1680 -0
- agno/db/sqlite/utils.py +269 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +142 -43
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -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/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1515 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +68 -15
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/knowledge/reader/gcs_reader.py +67 -0
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +36 -9
- agno/{document → knowledge}/reader/pdf_reader.py +79 -21
- agno/knowledge/reader/reader_factory.py +275 -0
- agno/knowledge/reader/s3_reader.py +171 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +84 -0
- agno/knowledge/reader/web_search_reader.py +389 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +2 -2
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +129 -82
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +347 -287
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/dashscope/dashscope.py +14 -5
- agno/models/google/gemini.py +123 -53
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +38 -144
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +84 -46
- agno/models/openai/chat.py +135 -27
- agno/models/openai/responses.py +233 -115
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +14 -8
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +393 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +33 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +30 -0
- agno/os/router.py +843 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +204 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +413 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +179 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +58 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +163 -0
- agno/os/schema.py +892 -0
- agno/{app/playground → os}/settings.py +8 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/{response.py → agent.py} +144 -72
- agno/run/base.py +44 -58
- agno/run/cancel.py +83 -0
- agno/run/team.py +133 -77
- agno/run/workflow.py +537 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +2967 -4243
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +42 -22
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +18 -13
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +71 -18
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +18 -11
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +16 -7
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +35 -28
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +29 -29
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +68 -17
- agno/tools/giphy.py +22 -10
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +46 -62
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +31 -19
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +32 -14
- agno/tools/models/gemini.py +58 -31
- agno/tools/models/groq.py +29 -20
- agno/tools/models/nebius.py +27 -11
- agno/tools/models_labs.py +39 -15
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +57 -26
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +62 -46
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +54 -41
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +95 -118
- agno/utils/knowledge.py +29 -0
- agno/utils/location.py +2 -2
- agno/utils/log.py +2 -2
- agno/utils/mcp.py +11 -5
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/claude.py +6 -4
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1565 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +356 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2394 -696
- agno-2.0.0a1.dist-info/METADATA +355 -0
- agno-2.0.0a1.dist-info/RECORD +514 -0
- agno/agent/metrics.py +0 -107
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- 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 -698
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- 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 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- 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/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3312
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.0.dist-info/METADATA +0 -979
- agno-1.8.0.dist-info/RECORD +0 -565
- agno-1.8.0.dist-info/entry_points.txt +0 -3
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
agno/tools/neo4j.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
from neo4j import GraphDatabase
|
|
6
|
+
except ImportError:
|
|
7
|
+
raise ImportError("`neo4j` not installed. Please install using `pip install neo4j`")
|
|
8
|
+
|
|
9
|
+
from agno.tools import Toolkit
|
|
10
|
+
from agno.utils.log import log_debug, logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Neo4jTools(Toolkit):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
uri: Optional[str] = None,
|
|
17
|
+
user: Optional[str] = None,
|
|
18
|
+
password: Optional[str] = None,
|
|
19
|
+
database: Optional[str] = None,
|
|
20
|
+
# Enable flags for <6 functions
|
|
21
|
+
enable_list_labels: bool = True,
|
|
22
|
+
enable_list_relationships: bool = True,
|
|
23
|
+
enable_get_schema: bool = True,
|
|
24
|
+
enable_run_cypher: bool = True,
|
|
25
|
+
all: bool = False,
|
|
26
|
+
**kwargs,
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Initialize the Neo4jTools toolkit.
|
|
30
|
+
Connection parameters (uri/user/password or host/port) can be provided.
|
|
31
|
+
If not provided, falls back to NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD env vars.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
uri (Optional[str]): The Neo4j URI.
|
|
35
|
+
user (Optional[str]): The Neo4j username.
|
|
36
|
+
password (Optional[str]): The Neo4j password.
|
|
37
|
+
host (Optional[str]): The Neo4j host.
|
|
38
|
+
port (Optional[int]): The Neo4j port.
|
|
39
|
+
database (Optional[str]): The Neo4j database.
|
|
40
|
+
list_labels (bool): Whether to list node labels.
|
|
41
|
+
list_relationships (bool): Whether to list relationship types.
|
|
42
|
+
get_schema (bool): Whether to get the schema.
|
|
43
|
+
run_cypher (bool): Whether to run Cypher queries.
|
|
44
|
+
**kwargs: Additional keyword arguments.
|
|
45
|
+
"""
|
|
46
|
+
# Determine the connection URI and credentials
|
|
47
|
+
uri = uri or os.getenv("NEO4J_URI", "bolt://localhost:7687")
|
|
48
|
+
user = user or os.getenv("NEO4J_USERNAME")
|
|
49
|
+
password = password or os.getenv("NEO4J_PASSWORD")
|
|
50
|
+
|
|
51
|
+
if user is None or password is None:
|
|
52
|
+
raise ValueError("Username or password for Neo4j not provided")
|
|
53
|
+
|
|
54
|
+
# Create the Neo4j driver
|
|
55
|
+
try:
|
|
56
|
+
self.driver = GraphDatabase.driver(uri, auth=(user, password)) # type: ignore
|
|
57
|
+
self.driver.verify_connectivity()
|
|
58
|
+
log_debug("Connected to Neo4j database")
|
|
59
|
+
except Exception as e:
|
|
60
|
+
logger.error(f"Failed to connect to Neo4j: {e}")
|
|
61
|
+
raise
|
|
62
|
+
|
|
63
|
+
self.database = database or "neo4j"
|
|
64
|
+
|
|
65
|
+
# Register toolkit methods as tools
|
|
66
|
+
tools: List[Any] = []
|
|
67
|
+
if all or enable_list_labels:
|
|
68
|
+
tools.append(self.list_labels)
|
|
69
|
+
if all or enable_list_relationships:
|
|
70
|
+
tools.append(self.list_relationship_types)
|
|
71
|
+
if all or enable_get_schema:
|
|
72
|
+
tools.append(self.get_schema)
|
|
73
|
+
if all or enable_run_cypher:
|
|
74
|
+
tools.append(self.run_cypher_query)
|
|
75
|
+
super().__init__(name="neo4j_tools", tools=tools, **kwargs)
|
|
76
|
+
|
|
77
|
+
def list_labels(self) -> list:
|
|
78
|
+
"""
|
|
79
|
+
Retrieve all node labels present in the connected Neo4j database.
|
|
80
|
+
"""
|
|
81
|
+
try:
|
|
82
|
+
log_debug("Listing node labels in Neo4j database")
|
|
83
|
+
with self.driver.session(database=self.database) as session:
|
|
84
|
+
result = session.run("CALL db.labels()")
|
|
85
|
+
labels = [record["label"] for record in result]
|
|
86
|
+
return labels
|
|
87
|
+
except Exception as e:
|
|
88
|
+
logger.error(f"Error listing labels: {e}")
|
|
89
|
+
return []
|
|
90
|
+
|
|
91
|
+
def list_relationship_types(self) -> list:
|
|
92
|
+
"""
|
|
93
|
+
Retrieve all relationship types present in the connected Neo4j database.
|
|
94
|
+
"""
|
|
95
|
+
try:
|
|
96
|
+
log_debug("Listing relationship types in Neo4j database")
|
|
97
|
+
with self.driver.session(database=self.database) as session:
|
|
98
|
+
result = session.run("CALL db.relationshipTypes()")
|
|
99
|
+
types = [record["relationshipType"] for record in result]
|
|
100
|
+
return types
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(f"Error listing relationship types: {e}")
|
|
103
|
+
return []
|
|
104
|
+
|
|
105
|
+
def get_schema(self) -> list:
|
|
106
|
+
"""
|
|
107
|
+
Retrieve a visualization of the database schema, including nodes and relationships.
|
|
108
|
+
"""
|
|
109
|
+
try:
|
|
110
|
+
log_debug("Retrieving Neo4j schema visualization")
|
|
111
|
+
with self.driver.session(database=self.database) as session:
|
|
112
|
+
result = session.run("CALL db.schema.visualization()")
|
|
113
|
+
schema_data = result.data()
|
|
114
|
+
return schema_data
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.error(f"Error getting Neo4j schema: {e}")
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
def run_cypher_query(self, query: str) -> list:
|
|
120
|
+
"""
|
|
121
|
+
Execute an arbitrary Cypher query against the connected Neo4j database.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
query (str): The Cypher query string to execute.
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
log_debug(f"Running Cypher query: {query}")
|
|
128
|
+
with self.driver.session(database=self.database) as session:
|
|
129
|
+
result = session.run(query) # type: ignore[arg-type]
|
|
130
|
+
data = result.data()
|
|
131
|
+
return data
|
|
132
|
+
except Exception as e:
|
|
133
|
+
logger.error(f"Error running Cypher query: {e}")
|
|
134
|
+
return []
|
agno/tools/newspaper.py
CHANGED
|
@@ -14,9 +14,14 @@ class NewspaperTools(Toolkit):
|
|
|
14
14
|
get_article_text (bool): Whether to get the text of an article from a URL.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
def __init__(
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
enable_get_article_text: bool = True,
|
|
20
|
+
all: bool = False,
|
|
21
|
+
**kwargs,
|
|
22
|
+
):
|
|
18
23
|
tools = []
|
|
19
|
-
if
|
|
24
|
+
if all or enable_get_article_text:
|
|
20
25
|
tools.append(self.get_article_text)
|
|
21
26
|
|
|
22
27
|
super().__init__(name="newspaper_toolkit", tools=tools, **kwargs)
|
agno/tools/newspaper4k.py
CHANGED
|
@@ -14,19 +14,24 @@ class Newspaper4kTools(Toolkit):
|
|
|
14
14
|
"""
|
|
15
15
|
Newspaper4kTools is a toolkit for getting the text of an article from a URL.
|
|
16
16
|
Args:
|
|
17
|
-
|
|
17
|
+
enable_read_article (bool): Whether to read an article from a URL.
|
|
18
18
|
include_summary (bool): Whether to include the summary of an article.
|
|
19
19
|
article_length (Optional[int]): The length of the article to read.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
22
|
def __init__(
|
|
23
|
-
self,
|
|
23
|
+
self,
|
|
24
|
+
include_summary: bool = False,
|
|
25
|
+
article_length: Optional[int] = None,
|
|
26
|
+
enable_read_article: bool = True,
|
|
27
|
+
all: bool = False,
|
|
28
|
+
**kwargs,
|
|
24
29
|
):
|
|
25
30
|
self.include_summary: bool = include_summary
|
|
26
31
|
self.article_length: Optional[int] = article_length
|
|
27
32
|
|
|
28
33
|
tools = []
|
|
29
|
-
if
|
|
34
|
+
if all or enable_read_article:
|
|
30
35
|
tools.append(self.read_article)
|
|
31
36
|
|
|
32
37
|
super().__init__(name="newspaper4k_tools", tools=tools, **kwargs)
|
agno/tools/openai.py
CHANGED
|
@@ -6,6 +6,7 @@ from agno.agent import Agent
|
|
|
6
6
|
from agno.media import AudioArtifact, ImageArtifact
|
|
7
7
|
from agno.team.team import Team
|
|
8
8
|
from agno.tools import Toolkit
|
|
9
|
+
from agno.tools.function import ToolResult
|
|
9
10
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
10
11
|
|
|
11
12
|
try:
|
|
@@ -20,7 +21,23 @@ OpenAITTSFormat = Literal["mp3", "opus", "aac", "flac", "wav", "pcm"]
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class OpenAITools(Toolkit):
|
|
23
|
-
"""Tools for interacting with
|
|
24
|
+
"""Tools for interacting with OpenAI API.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
api_key (str, optional): OpenAI API key. Retrieved from OPENAI_API_KEY env variable if not provided.
|
|
28
|
+
enable_transcription (bool): Enable audio transcription functionality. Default is True.
|
|
29
|
+
enable_image_generation (bool): Enable image generation functionality. Default is True.
|
|
30
|
+
enable_speech_generation (bool): Enable speech generation functionality. Default is True.
|
|
31
|
+
all (bool): Enable all tools. Overrides individual flags when True. Default is False.
|
|
32
|
+
transcription_model (str): Model to use for transcription. Default is "whisper-1".
|
|
33
|
+
text_to_speech_voice (OpenAIVoice): Voice to use for TTS. Default is "alloy".
|
|
34
|
+
text_to_speech_model (OpenAITTSModel): Model to use for TTS. Default is "tts-1".
|
|
35
|
+
text_to_speech_format (OpenAITTSFormat): Audio format for TTS. Default is "mp3".
|
|
36
|
+
image_model (str, optional): Model to use for image generation. Default is "dall-e-3".
|
|
37
|
+
image_quality (str, optional): Quality setting for image generation.
|
|
38
|
+
image_size (str, optional): Size setting for image generation.
|
|
39
|
+
image_style (str, optional): Style setting for image generation.
|
|
40
|
+
"""
|
|
24
41
|
|
|
25
42
|
def __init__(
|
|
26
43
|
self,
|
|
@@ -28,6 +45,7 @@ class OpenAITools(Toolkit):
|
|
|
28
45
|
enable_transcription: bool = True,
|
|
29
46
|
enable_image_generation: bool = True,
|
|
30
47
|
enable_speech_generation: bool = True,
|
|
48
|
+
all: bool = False,
|
|
31
49
|
transcription_model: str = "whisper-1",
|
|
32
50
|
text_to_speech_voice: OpenAIVoice = "alloy",
|
|
33
51
|
text_to_speech_model: OpenAITTSModel = "tts-1",
|
|
@@ -53,11 +71,11 @@ class OpenAITools(Toolkit):
|
|
|
53
71
|
self.image_size = image_size
|
|
54
72
|
|
|
55
73
|
tools: List[Any] = []
|
|
56
|
-
if enable_transcription:
|
|
74
|
+
if all or enable_transcription:
|
|
57
75
|
tools.append(self.transcribe_audio)
|
|
58
|
-
if enable_image_generation:
|
|
76
|
+
if all or enable_image_generation:
|
|
59
77
|
tools.append(self.generate_image)
|
|
60
|
-
if enable_speech_generation:
|
|
78
|
+
if all or enable_speech_generation:
|
|
61
79
|
tools.append(self.generate_speech)
|
|
62
80
|
|
|
63
81
|
super().__init__(name="openai_tools", tools=tools, **kwargs)
|
|
@@ -85,14 +103,15 @@ class OpenAITools(Toolkit):
|
|
|
85
103
|
|
|
86
104
|
def generate_image(
|
|
87
105
|
self,
|
|
88
|
-
agent: Union[Agent, Team],
|
|
89
106
|
prompt: str,
|
|
90
|
-
) ->
|
|
107
|
+
) -> ToolResult:
|
|
91
108
|
"""Generate images based on a text prompt.
|
|
92
109
|
Args:
|
|
93
110
|
prompt (str): The text prompt to generate the image from.
|
|
94
111
|
"""
|
|
95
112
|
try:
|
|
113
|
+
import base64
|
|
114
|
+
|
|
96
115
|
extra_params = {
|
|
97
116
|
"size": self.image_size,
|
|
98
117
|
"quality": self.image_quality,
|
|
@@ -120,29 +139,38 @@ class OpenAITools(Toolkit):
|
|
|
120
139
|
data = response.data[0]
|
|
121
140
|
if data is None:
|
|
122
141
|
log_warning("OpenAI API did not return any data.")
|
|
123
|
-
return "Failed to generate image: No data received from API."
|
|
142
|
+
return ToolResult(content="Failed to generate image: No data received from API.")
|
|
143
|
+
|
|
124
144
|
if hasattr(data, "b64_json") and data.b64_json:
|
|
125
145
|
image_base64 = data.b64_json
|
|
126
146
|
media_id = str(uuid4())
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
|
|
148
|
+
# Decode base64 to bytes for proper storage
|
|
149
|
+
image_bytes = base64.b64decode(image_base64)
|
|
150
|
+
|
|
151
|
+
# Create ImageArtifact and return in ToolResult
|
|
152
|
+
image_artifact = ImageArtifact(
|
|
153
|
+
id=media_id,
|
|
154
|
+
content=image_bytes, # ← Store as bytes, not encoded string
|
|
155
|
+
mime_type="image/png",
|
|
156
|
+
original_prompt=prompt,
|
|
134
157
|
)
|
|
135
|
-
|
|
136
|
-
|
|
158
|
+
|
|
159
|
+
return ToolResult(
|
|
160
|
+
content="Image generated successfully.",
|
|
161
|
+
images=[image_artifact],
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return ToolResult(content="Failed to generate image: No content received from API.")
|
|
137
165
|
except Exception as e:
|
|
138
166
|
log_error(f"Failed to generate image using {self.image_model}: {e}")
|
|
139
|
-
return f"Failed to generate image: {e}"
|
|
167
|
+
return ToolResult(content=f"Failed to generate image: {e}")
|
|
140
168
|
|
|
141
169
|
def generate_speech(
|
|
142
170
|
self,
|
|
143
171
|
agent: Union[Agent, Team],
|
|
144
172
|
text_input: str,
|
|
145
|
-
) ->
|
|
173
|
+
) -> ToolResult: # Changed return type
|
|
146
174
|
"""Generate speech from text using OpenAI's Text-to-Speech API.
|
|
147
175
|
Args:
|
|
148
176
|
text_input (str): The text to synthesize into speech.
|
|
@@ -163,14 +191,17 @@ class OpenAITools(Toolkit):
|
|
|
163
191
|
# Base64 encode the audio data
|
|
164
192
|
base64_encoded_audio = base64.b64encode(audio_data).decode("utf-8")
|
|
165
193
|
|
|
166
|
-
# Create and
|
|
194
|
+
# Create AudioArtifact and return in ToolResult
|
|
167
195
|
media_id = str(uuid4())
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
196
|
+
audio_artifact = AudioArtifact(
|
|
197
|
+
id=media_id,
|
|
198
|
+
base64_audio=base64_encoded_audio,
|
|
199
|
+
mime_type=f"audio/{self.tts_format}",
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
return ToolResult(
|
|
203
|
+
content=f"Speech generated successfully with ID: {media_id}",
|
|
204
|
+
audios=[audio_artifact],
|
|
173
205
|
)
|
|
174
|
-
return f"Speech generated successfully with ID: {media_id}"
|
|
175
206
|
except Exception as e:
|
|
176
|
-
return f"Failed to generate speech: {str(e)}"
|
|
207
|
+
return ToolResult(content=f"Failed to generate speech: {str(e)}")
|
agno/tools/openbb.py
CHANGED
|
@@ -17,11 +17,12 @@ class OpenBBTools(Toolkit):
|
|
|
17
17
|
obb: Optional[Any] = None,
|
|
18
18
|
openbb_pat: Optional[str] = None,
|
|
19
19
|
provider: Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "tmx", "yfinance"] = "yfinance",
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
enable_get_stock_price: bool = True,
|
|
21
|
+
enable_search_company_symbol: bool = False,
|
|
22
|
+
enable_get_company_news: bool = False,
|
|
23
|
+
enable_get_company_profile: bool = False,
|
|
24
|
+
enable_get_price_targets: bool = False,
|
|
25
|
+
all: bool = False,
|
|
25
26
|
**kwargs,
|
|
26
27
|
):
|
|
27
28
|
self.obb = obb or openbb_app
|
|
@@ -34,18 +35,18 @@ class OpenBBTools(Toolkit):
|
|
|
34
35
|
self.provider: Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "tmx", "yfinance"] = provider
|
|
35
36
|
|
|
36
37
|
tools: List[Any] = []
|
|
37
|
-
if
|
|
38
|
+
if enable_get_stock_price or all:
|
|
38
39
|
tools.append(self.get_stock_price)
|
|
39
|
-
if
|
|
40
|
+
if enable_search_company_symbol or all:
|
|
40
41
|
tools.append(self.search_company_symbol)
|
|
41
|
-
if
|
|
42
|
+
if enable_get_company_news or all:
|
|
42
43
|
tools.append(self.get_company_news)
|
|
43
|
-
if
|
|
44
|
+
if enable_get_company_profile or all:
|
|
44
45
|
tools.append(self.get_company_profile)
|
|
45
|
-
if
|
|
46
|
+
if enable_get_price_targets or all:
|
|
46
47
|
tools.append(self.get_price_targets)
|
|
47
48
|
|
|
48
|
-
super().__init__(name="
|
|
49
|
+
super().__init__(name="openbb_tools", tools=tools, **kwargs)
|
|
49
50
|
|
|
50
51
|
def get_stock_price(self, symbol: str) -> str:
|
|
51
52
|
"""Use this function to get the current stock price for a stock symbol or list of symbols.
|
agno/tools/opencv.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import base64
|
|
2
1
|
import time
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Callable, List
|
|
3
4
|
from uuid import uuid4
|
|
4
5
|
|
|
5
6
|
from agno.agent import Agent
|
|
6
7
|
from agno.media import ImageArtifact, VideoArtifact
|
|
7
|
-
from agno.tools
|
|
8
|
+
from agno.tools import Toolkit
|
|
9
|
+
from agno.tools.function import ToolResult
|
|
8
10
|
from agno.utils.log import log_debug, log_error, log_info
|
|
9
11
|
|
|
10
12
|
try:
|
|
@@ -16,30 +18,40 @@ except ImportError:
|
|
|
16
18
|
class OpenCVTools(Toolkit):
|
|
17
19
|
"""Tools for capturing images and videos from the webcam using OpenCV"""
|
|
18
20
|
|
|
19
|
-
def __init__(
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
show_preview=False,
|
|
24
|
+
enable_capture_image: bool = True,
|
|
25
|
+
enable_capture_video: bool = True,
|
|
26
|
+
all: bool = False,
|
|
27
|
+
**kwargs,
|
|
28
|
+
):
|
|
29
|
+
self.show_preview = show_preview
|
|
30
|
+
|
|
31
|
+
tools: List[Callable] = []
|
|
32
|
+
if all or enable_capture_image:
|
|
33
|
+
tools.append(self.capture_image)
|
|
34
|
+
if all or enable_capture_video:
|
|
35
|
+
tools.append(self.capture_video)
|
|
36
|
+
|
|
20
37
|
super().__init__(
|
|
21
38
|
name="opencv_tools",
|
|
22
|
-
tools=
|
|
23
|
-
self.capture_image,
|
|
24
|
-
self.capture_video,
|
|
25
|
-
],
|
|
39
|
+
tools=tools,
|
|
26
40
|
**kwargs,
|
|
27
41
|
)
|
|
28
42
|
|
|
29
|
-
self.show_preview = show_preview
|
|
30
|
-
|
|
31
43
|
def capture_image(
|
|
32
44
|
self,
|
|
33
45
|
agent: Agent,
|
|
34
46
|
prompt: str = "Webcam capture",
|
|
35
|
-
) ->
|
|
47
|
+
) -> ToolResult:
|
|
36
48
|
"""Capture an image from the webcam.
|
|
37
49
|
|
|
38
50
|
Args:
|
|
39
51
|
prompt (str): Description of the image capture. Defaults to "Webcam capture".
|
|
40
52
|
|
|
41
53
|
Returns:
|
|
42
|
-
|
|
54
|
+
ToolResult: A ToolResult containing the captured image or error message.
|
|
43
55
|
"""
|
|
44
56
|
try:
|
|
45
57
|
log_debug("Initializing webcam for image capture...")
|
|
@@ -55,7 +67,7 @@ class OpenCVTools(Toolkit):
|
|
|
55
67
|
if not cam.isOpened():
|
|
56
68
|
error_msg = "Could not open webcam. Please ensure your terminal has camera permissions and the camera is not being used by another application."
|
|
57
69
|
log_error(error_msg)
|
|
58
|
-
return error_msg
|
|
70
|
+
return ToolResult(content=error_msg)
|
|
59
71
|
|
|
60
72
|
try:
|
|
61
73
|
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
|
|
@@ -73,7 +85,7 @@ class OpenCVTools(Toolkit):
|
|
|
73
85
|
if not ret:
|
|
74
86
|
error_msg = "Failed to read frame from webcam"
|
|
75
87
|
log_error(error_msg)
|
|
76
|
-
return error_msg
|
|
88
|
+
return ToolResult(content=error_msg)
|
|
77
89
|
|
|
78
90
|
cv2.imshow('Camera Preview - Press "c" to capture, "q" to quit', frame)
|
|
79
91
|
|
|
@@ -84,41 +96,42 @@ class OpenCVTools(Toolkit):
|
|
|
84
96
|
break
|
|
85
97
|
elif key == ord("q"):
|
|
86
98
|
log_info("Capture cancelled by user")
|
|
87
|
-
return "Image capture cancelled by user"
|
|
99
|
+
return ToolResult(content="Image capture cancelled by user")
|
|
88
100
|
else:
|
|
89
101
|
ret, captured_frame = cam.read()
|
|
90
102
|
if not ret:
|
|
91
103
|
error_msg = "Failed to capture image from webcam"
|
|
92
104
|
log_error(error_msg)
|
|
93
|
-
return error_msg
|
|
105
|
+
return ToolResult(content=error_msg)
|
|
94
106
|
|
|
95
107
|
if captured_frame is None:
|
|
96
108
|
error_msg = "No frame captured"
|
|
97
109
|
log_error(error_msg)
|
|
98
|
-
return error_msg
|
|
110
|
+
return ToolResult(content=error_msg)
|
|
99
111
|
|
|
100
112
|
success, encoded_image = cv2.imencode(".png", captured_frame)
|
|
101
113
|
|
|
102
114
|
if not success:
|
|
103
115
|
error_msg = "Failed to encode captured image"
|
|
104
116
|
log_error(error_msg)
|
|
105
|
-
return error_msg
|
|
117
|
+
return ToolResult(content=error_msg)
|
|
106
118
|
|
|
107
119
|
image_bytes = encoded_image.tobytes()
|
|
108
|
-
base64_encoded_image = base64.b64encode(image_bytes)
|
|
109
|
-
|
|
110
120
|
media_id = str(uuid4())
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
|
|
122
|
+
# Create ImageArtifact with raw bytes (not base64 encoded)
|
|
123
|
+
image_artifact = ImageArtifact(
|
|
124
|
+
id=media_id,
|
|
125
|
+
content=image_bytes, # Store as raw bytes
|
|
126
|
+
original_prompt=prompt,
|
|
127
|
+
mime_type="image/png",
|
|
118
128
|
)
|
|
119
129
|
|
|
120
130
|
log_debug(f"Successfully captured and attached image {media_id}")
|
|
121
|
-
return
|
|
131
|
+
return ToolResult(
|
|
132
|
+
content="Image captured successfully",
|
|
133
|
+
images=[image_artifact],
|
|
134
|
+
)
|
|
122
135
|
|
|
123
136
|
finally:
|
|
124
137
|
# Release the camera and close windows
|
|
@@ -129,14 +142,14 @@ class OpenCVTools(Toolkit):
|
|
|
129
142
|
except Exception as e:
|
|
130
143
|
error_msg = f"Error capturing image: {str(e)}"
|
|
131
144
|
log_error(error_msg)
|
|
132
|
-
return error_msg
|
|
145
|
+
return ToolResult(content=error_msg)
|
|
133
146
|
|
|
134
147
|
def capture_video(
|
|
135
148
|
self,
|
|
136
149
|
agent: Agent,
|
|
137
150
|
duration: int = 10,
|
|
138
151
|
prompt: str = "Webcam video capture",
|
|
139
|
-
) ->
|
|
152
|
+
) -> ToolResult:
|
|
140
153
|
"""Capture a video from the webcam.
|
|
141
154
|
|
|
142
155
|
Args:
|
|
@@ -144,7 +157,7 @@ class OpenCVTools(Toolkit):
|
|
|
144
157
|
prompt (str): Description of the video capture. Defaults to "Webcam video capture".
|
|
145
158
|
|
|
146
159
|
Returns:
|
|
147
|
-
|
|
160
|
+
ToolResult: A ToolResult containing the captured video or error message.
|
|
148
161
|
"""
|
|
149
162
|
try:
|
|
150
163
|
log_debug("Initializing webcam for video capture...")
|
|
@@ -161,7 +174,7 @@ class OpenCVTools(Toolkit):
|
|
|
161
174
|
if not cap.isOpened():
|
|
162
175
|
error_msg = "Could not open webcam. Please ensure your terminal has camera permissions and the camera is not being used by another application."
|
|
163
176
|
log_error(error_msg)
|
|
164
|
-
return error_msg
|
|
177
|
+
return ToolResult(content=error_msg)
|
|
165
178
|
|
|
166
179
|
try:
|
|
167
180
|
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
@@ -211,7 +224,7 @@ class OpenCVTools(Toolkit):
|
|
|
211
224
|
if not out or not out.isOpened():
|
|
212
225
|
error_msg = "Failed to initialize video writer with any codec"
|
|
213
226
|
log_error(error_msg)
|
|
214
|
-
return error_msg
|
|
227
|
+
return ToolResult(content=error_msg)
|
|
215
228
|
|
|
216
229
|
start_time = time.time()
|
|
217
230
|
frame_count = 0
|
|
@@ -227,7 +240,7 @@ class OpenCVTools(Toolkit):
|
|
|
227
240
|
if not ret:
|
|
228
241
|
error_msg = "Failed to capture video frame"
|
|
229
242
|
log_error(error_msg)
|
|
230
|
-
return error_msg
|
|
243
|
+
return ToolResult(content=error_msg)
|
|
231
244
|
|
|
232
245
|
# Write the frame to the output file
|
|
233
246
|
out.write(frame)
|
|
@@ -263,10 +276,11 @@ class OpenCVTools(Toolkit):
|
|
|
263
276
|
out.release()
|
|
264
277
|
|
|
265
278
|
# Verify the file was created and has content
|
|
266
|
-
|
|
279
|
+
temp_path = Path(temp_filepath)
|
|
280
|
+
if not temp_path.exists() or temp_path.stat().st_size == 0:
|
|
267
281
|
error_msg = "Video file was not created or is empty"
|
|
268
282
|
log_error(error_msg)
|
|
269
|
-
return error_msg
|
|
283
|
+
return ToolResult(content=error_msg)
|
|
270
284
|
|
|
271
285
|
# Read the video file and encode to base64
|
|
272
286
|
with open(temp_filepath, "rb") as video_file:
|
|
@@ -275,23 +289,25 @@ class OpenCVTools(Toolkit):
|
|
|
275
289
|
# Clean up temporary file
|
|
276
290
|
os.unlink(temp_filepath)
|
|
277
291
|
|
|
278
|
-
base64_encoded_video = base64.b64encode(video_bytes)
|
|
279
|
-
|
|
280
292
|
media_id = str(uuid4())
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
|
|
294
|
+
# Create VideoArtifact with base64 encoded content
|
|
295
|
+
video_artifact = VideoArtifact(
|
|
296
|
+
id=media_id,
|
|
297
|
+
content=video_bytes,
|
|
298
|
+
original_prompt=prompt,
|
|
299
|
+
mime_type="video/mp4",
|
|
288
300
|
)
|
|
289
301
|
|
|
290
302
|
actual_duration = time.time() - start_time
|
|
291
303
|
log_debug(
|
|
292
304
|
f"Successfully captured and attached video {media_id} ({actual_duration:.1f}s, {frame_count} frames)"
|
|
293
305
|
)
|
|
294
|
-
|
|
306
|
+
|
|
307
|
+
return ToolResult(
|
|
308
|
+
content=f"Video captured successfully and attached as artifact {media_id} ({actual_duration:.1f}s, {frame_count} frames, {successful_codec} codec)",
|
|
309
|
+
videos=[video_artifact],
|
|
310
|
+
)
|
|
295
311
|
|
|
296
312
|
finally:
|
|
297
313
|
if "cap" in locals():
|
|
@@ -302,4 +318,4 @@ class OpenCVTools(Toolkit):
|
|
|
302
318
|
except Exception as e:
|
|
303
319
|
error_msg = f"Error capturing video: {str(e)}"
|
|
304
320
|
log_error(error_msg)
|
|
305
|
-
return error_msg
|
|
321
|
+
return ToolResult(content=error_msg)
|
agno/tools/openweather.py
CHANGED
|
@@ -18,20 +18,22 @@ class OpenWeatherTools(Toolkit):
|
|
|
18
18
|
Args:
|
|
19
19
|
api_key (Optional[str]): OpenWeatherMap API key. If not provided, will try to get from OPENWEATHER_API_KEY env var.
|
|
20
20
|
units (str): Units of measurement. Options are 'standard', 'metric', and 'imperial'. Default is 'metric'.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
enable_current_weather (bool): Enable current weather function. Default is True.
|
|
22
|
+
enable_forecast (bool): Enable forecast function. Default is True.
|
|
23
|
+
enable_air_pollution (bool): Enable air pollution function. Default is True.
|
|
24
|
+
enable_geocoding (bool): Enable geocoding function. Default is True.
|
|
25
|
+
all (bool): Enable all functions. Default is False.
|
|
25
26
|
"""
|
|
26
27
|
|
|
27
28
|
def __init__(
|
|
28
29
|
self,
|
|
29
30
|
api_key: Optional[str] = None,
|
|
30
31
|
units: str = "metric",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
enable_current_weather: bool = True,
|
|
33
|
+
enable_forecast: bool = True,
|
|
34
|
+
enable_air_pollution: bool = True,
|
|
35
|
+
enable_geocoding: bool = True,
|
|
36
|
+
all: bool = False,
|
|
35
37
|
**kwargs,
|
|
36
38
|
):
|
|
37
39
|
self.api_key = api_key or getenv("OPENWEATHER_API_KEY")
|
|
@@ -45,13 +47,13 @@ class OpenWeatherTools(Toolkit):
|
|
|
45
47
|
self.geo_url = "https://api.openweathermap.org/geo/1.0"
|
|
46
48
|
|
|
47
49
|
tools: List[Any] = []
|
|
48
|
-
if
|
|
50
|
+
if enable_current_weather or all:
|
|
49
51
|
tools.append(self.get_current_weather)
|
|
50
|
-
if
|
|
52
|
+
if enable_forecast or all:
|
|
51
53
|
tools.append(self.get_forecast)
|
|
52
|
-
if
|
|
54
|
+
if enable_air_pollution or all:
|
|
53
55
|
tools.append(self.get_air_pollution)
|
|
54
|
-
if
|
|
56
|
+
if enable_geocoding or all:
|
|
55
57
|
tools.append(self.geocode_location)
|
|
56
58
|
|
|
57
59
|
super().__init__(name="openweather_tools", tools=tools, **kwargs)
|