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
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from typing import Any, Dict, Literal, Optional
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from requests import post
|
|
6
|
+
|
|
7
|
+
from agno.agent import Agent
|
|
8
|
+
from agno.media import Image
|
|
9
|
+
from agno.tools import Toolkit
|
|
10
|
+
from agno.tools.function import ToolResult
|
|
11
|
+
from agno.utils.log import log_debug, logger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AzureOpenAITools(Toolkit):
|
|
15
|
+
"""Toolkit for Azure OpenAI services.
|
|
16
|
+
|
|
17
|
+
Currently supports:
|
|
18
|
+
- DALL-E image generation
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# Define valid parameter options as class constants
|
|
22
|
+
VALID_MODELS = ["dall-e-3", "dall-e-2"]
|
|
23
|
+
VALID_SIZES = ["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]
|
|
24
|
+
VALID_QUALITIES = ["standard", "hd"]
|
|
25
|
+
VALID_STYLES = ["vivid", "natural"]
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
api_key: Optional[str] = None,
|
|
30
|
+
azure_endpoint: Optional[str] = None,
|
|
31
|
+
api_version: Optional[str] = None,
|
|
32
|
+
image_deployment: Optional[str] = None,
|
|
33
|
+
image_model: str = "dall-e-3",
|
|
34
|
+
image_quality: Literal["standard", "hd"] = "standard", # Note: "hd" quality is only available for dall-e-3.
|
|
35
|
+
enable_generate_image: bool = True,
|
|
36
|
+
all: bool = False,
|
|
37
|
+
):
|
|
38
|
+
# Set credentials from parameters or environment variables
|
|
39
|
+
self.api_key = api_key or getenv("AZURE_OPENAI_API_KEY")
|
|
40
|
+
self.azure_endpoint = azure_endpoint or getenv("AZURE_OPENAI_ENDPOINT")
|
|
41
|
+
self.api_version = api_version or getenv("AZURE_OPENAI_API_VERSION") or "2023-12-01-preview"
|
|
42
|
+
|
|
43
|
+
# Log warnings for missing credentials
|
|
44
|
+
if not self.api_key:
|
|
45
|
+
logger.error("AZURE_OPENAI_API_KEY not set")
|
|
46
|
+
if not self.azure_endpoint:
|
|
47
|
+
logger.error("AZURE_OPENAI_ENDPOINT not set")
|
|
48
|
+
|
|
49
|
+
# Initialize image generation parameters
|
|
50
|
+
self.image_deployment = image_deployment or getenv("AZURE_OPENAI_IMAGE_DEPLOYMENT")
|
|
51
|
+
self.image_model = image_model
|
|
52
|
+
|
|
53
|
+
# Build tools list based on available services
|
|
54
|
+
tools = []
|
|
55
|
+
|
|
56
|
+
# Validate image generation parameters
|
|
57
|
+
if self.image_deployment and self.image_model in self.VALID_MODELS:
|
|
58
|
+
# Create and store the base URL
|
|
59
|
+
self.image_base_url = f"{self.azure_endpoint}/openai/deployments/{self.image_deployment}/images/generations?api-version={self.api_version}"
|
|
60
|
+
if all or enable_generate_image:
|
|
61
|
+
tools.append(self.generate_image)
|
|
62
|
+
else:
|
|
63
|
+
logger.error("Missing required image generation parameters or invalid model")
|
|
64
|
+
|
|
65
|
+
super().__init__(name="azure_openai_tools", tools=tools)
|
|
66
|
+
|
|
67
|
+
self.image_quality = image_quality
|
|
68
|
+
|
|
69
|
+
# Validate quality
|
|
70
|
+
if self.image_quality not in self.VALID_QUALITIES:
|
|
71
|
+
self.image_quality = "standard"
|
|
72
|
+
log_debug(f"Enforcing valid quality: '{self.image_quality}' -> 'standard'")
|
|
73
|
+
|
|
74
|
+
def _enforce_valid_image_parameters(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
75
|
+
"""Enforce valid parameters by replacing invalid ones with defaults."""
|
|
76
|
+
enforced = params.copy()
|
|
77
|
+
|
|
78
|
+
# Validate size
|
|
79
|
+
if params.get("size") not in self.VALID_SIZES:
|
|
80
|
+
enforced["size"] = "1024x1024"
|
|
81
|
+
log_debug(f"Enforcing valid size: '{params.get('size')}' -> '1024x1024'")
|
|
82
|
+
|
|
83
|
+
# Validate style
|
|
84
|
+
if params.get("style") not in self.VALID_STYLES:
|
|
85
|
+
enforced["style"] = "vivid"
|
|
86
|
+
log_debug(f"Enforcing valid style: '{params.get('style')}' -> 'vivid'")
|
|
87
|
+
|
|
88
|
+
# Validate number of images
|
|
89
|
+
if not isinstance(params.get("n"), int) or params.get("n", 0) <= 0:
|
|
90
|
+
enforced["n"] = 1
|
|
91
|
+
log_debug(f"Enforcing valid n: '{params.get('n')}' -> 1")
|
|
92
|
+
|
|
93
|
+
# Special case: dall-e-3 only supports n=1
|
|
94
|
+
if enforced.get("model") == "dall-e-3" and enforced.get("n", 1) > 1:
|
|
95
|
+
enforced["n"] = 1
|
|
96
|
+
log_debug("Enforcing n=1 for dall-e-3 model")
|
|
97
|
+
|
|
98
|
+
return enforced
|
|
99
|
+
|
|
100
|
+
def generate_image(
|
|
101
|
+
self,
|
|
102
|
+
agent: Agent,
|
|
103
|
+
prompt: str,
|
|
104
|
+
n: int = 1,
|
|
105
|
+
size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] = "1024x1024",
|
|
106
|
+
style: Literal["vivid", "natural"] = "vivid",
|
|
107
|
+
) -> ToolResult:
|
|
108
|
+
"""Generate an image using Azure OpenAI image generation.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
agent: The agent instance for adding images
|
|
112
|
+
prompt: Text description of the desired image
|
|
113
|
+
n: Number of images to generate (default: 1).
|
|
114
|
+
Note: dall-e-3 only supports n=1, while dall-e-2 supports multiple images.
|
|
115
|
+
size: Image size.
|
|
116
|
+
Valid options: "256x256", "512x512", "1024x1024", "1792x1024", "1024x1792" (default: "1024x1024")
|
|
117
|
+
Note: Not all sizes are available for all models.
|
|
118
|
+
style: Image style.
|
|
119
|
+
Valid options: "vivid" or "natural" (default: "vivid")
|
|
120
|
+
Note: "vivid" produces more dramatic images, while "natural" produces more realistic ones.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
ToolResult: A ToolResult containing the generated images or error message.
|
|
124
|
+
|
|
125
|
+
Note:
|
|
126
|
+
Invalid parameters will be automatically corrected to valid values. For example:
|
|
127
|
+
- Invalid sizes will be changed to "1024x1024"
|
|
128
|
+
- Invalid quality values will be changed to "standard"
|
|
129
|
+
- Invalid style values will be changed to "vivid"
|
|
130
|
+
- For dall-e-3, n will always be set to 1
|
|
131
|
+
"""
|
|
132
|
+
# Check if image generation is properly initialized
|
|
133
|
+
if not hasattr(self, "image_base_url"):
|
|
134
|
+
return ToolResult(
|
|
135
|
+
content="Image generation tool not properly initialized. Please check your configuration."
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Enforce valid parameters
|
|
139
|
+
params = self._enforce_valid_image_parameters(
|
|
140
|
+
{
|
|
141
|
+
"n": n,
|
|
142
|
+
"size": size,
|
|
143
|
+
"quality": self.image_quality,
|
|
144
|
+
"style": style,
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Add prompt and model to params - this wasn't included in enforcement because it doesn't need validation
|
|
149
|
+
params["prompt"] = prompt
|
|
150
|
+
params["model"] = self.image_model
|
|
151
|
+
|
|
152
|
+
try:
|
|
153
|
+
# Make API request using stored base URL
|
|
154
|
+
headers = {"api-key": self.api_key, "Content-Type": "application/json"}
|
|
155
|
+
response = post(self.image_base_url, headers=headers, json=params)
|
|
156
|
+
|
|
157
|
+
if response.status_code != 200:
|
|
158
|
+
return ToolResult(content=f"Error {response.status_code}: {response.text}")
|
|
159
|
+
|
|
160
|
+
# Process results
|
|
161
|
+
data = response.json()
|
|
162
|
+
log_debug("Image generated successfully")
|
|
163
|
+
|
|
164
|
+
# Create ImageArtifact objects for generated images
|
|
165
|
+
generated_images = []
|
|
166
|
+
response_str = ""
|
|
167
|
+
|
|
168
|
+
for img in data.get("data", []):
|
|
169
|
+
image_url = img.get("url")
|
|
170
|
+
revised_prompt = img.get("revised_prompt")
|
|
171
|
+
|
|
172
|
+
# Create ImageArtifact with URL
|
|
173
|
+
image_artifact = Image(
|
|
174
|
+
id=str(uuid4()), url=image_url, original_prompt=prompt, revised_prompt=revised_prompt
|
|
175
|
+
)
|
|
176
|
+
generated_images.append(image_artifact)
|
|
177
|
+
|
|
178
|
+
response_str += f"Image has been generated at the URL {image_url}\n"
|
|
179
|
+
|
|
180
|
+
if generated_images:
|
|
181
|
+
return ToolResult(
|
|
182
|
+
content=response_str.strip(),
|
|
183
|
+
images=generated_images,
|
|
184
|
+
)
|
|
185
|
+
else:
|
|
186
|
+
return ToolResult(content="No images were generated.")
|
|
187
|
+
|
|
188
|
+
except Exception as e:
|
|
189
|
+
logger.error(f"Failed to generate image: {e}")
|
|
190
|
+
return ToolResult(content=f"Error: {e}")
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import time
|
|
3
|
+
from os import getenv
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
from uuid import uuid4
|
|
6
|
+
|
|
7
|
+
from agno.agent import Agent
|
|
8
|
+
from agno.media import Image, Video
|
|
9
|
+
from agno.tools import Toolkit
|
|
10
|
+
from agno.tools.function import ToolResult
|
|
11
|
+
from agno.utils.log import log_debug, log_error, log_info
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from google.genai import Client
|
|
15
|
+
from google.genai.types import GenerateImagesResponse, GenerateVideosOperation
|
|
16
|
+
except (ModuleNotFoundError, ImportError):
|
|
17
|
+
raise ImportError("`google-genai` not installed. Please install using `pip install google-genai`")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GeminiTools(Toolkit):
|
|
21
|
+
"""Tools for interacting with Google Gemini API"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
api_key: Optional[str] = None,
|
|
26
|
+
vertexai: bool = False,
|
|
27
|
+
project_id: Optional[str] = None,
|
|
28
|
+
location: Optional[str] = None,
|
|
29
|
+
image_generation_model: str = "imagen-3.0-generate-002",
|
|
30
|
+
video_generation_model: str = "veo-2.0-generate-001",
|
|
31
|
+
enable_generate_image: bool = True,
|
|
32
|
+
enable_generate_video: bool = True,
|
|
33
|
+
all: bool = False,
|
|
34
|
+
**kwargs,
|
|
35
|
+
):
|
|
36
|
+
tools = []
|
|
37
|
+
if all or enable_generate_image:
|
|
38
|
+
tools.append(self.generate_image)
|
|
39
|
+
if all or enable_generate_video:
|
|
40
|
+
tools.append(self.generate_video)
|
|
41
|
+
|
|
42
|
+
super().__init__(name="gemini_tools", tools=tools, **kwargs)
|
|
43
|
+
|
|
44
|
+
# Set mode and credentials: use only provided vertexai parameter
|
|
45
|
+
self.vertexai = vertexai or getenv("GOOGLE_GENAI_USE_VERTEXAI") == "true"
|
|
46
|
+
self.project_id = project_id
|
|
47
|
+
self.location = location
|
|
48
|
+
|
|
49
|
+
# Load API key from argument or environment
|
|
50
|
+
self.api_key = api_key or getenv("GOOGLE_API_KEY")
|
|
51
|
+
if not self.vertexai and not self.api_key:
|
|
52
|
+
log_error("GOOGLE_API_KEY not set. Please set the GOOGLE_API_KEY environment variable.")
|
|
53
|
+
raise ValueError("GOOGLE_API_KEY not set. Please provide api_key or set the environment variable.")
|
|
54
|
+
|
|
55
|
+
# Prepare client parameters
|
|
56
|
+
client_params: dict[str, Any] = {}
|
|
57
|
+
if self.vertexai:
|
|
58
|
+
log_info("Using Vertex AI API")
|
|
59
|
+
client_params["vertexai"] = True
|
|
60
|
+
client_params["project"] = self.project_id or getenv("GOOGLE_CLOUD_PROJECT")
|
|
61
|
+
client_params["location"] = self.location or getenv("GOOGLE_CLOUD_LOCATION")
|
|
62
|
+
else:
|
|
63
|
+
log_info("Using Gemini API")
|
|
64
|
+
client_params["api_key"] = self.api_key
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
self.client = Client(**client_params)
|
|
68
|
+
log_debug("Google GenAI Client created successfully.")
|
|
69
|
+
except Exception as e:
|
|
70
|
+
log_error(f"Failed to create Google GenAI Client: {e}", exc_info=True)
|
|
71
|
+
raise ValueError(f"Failed to create Google GenAI Client. Error: {e}")
|
|
72
|
+
|
|
73
|
+
self.image_model = image_generation_model
|
|
74
|
+
self.video_model = video_generation_model
|
|
75
|
+
|
|
76
|
+
def generate_image(
|
|
77
|
+
self,
|
|
78
|
+
agent: Agent,
|
|
79
|
+
prompt: str,
|
|
80
|
+
) -> ToolResult:
|
|
81
|
+
"""Generate images based on a text prompt using Google Imagen.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
prompt (str): The text prompt to generate the image from.
|
|
85
|
+
Returns:
|
|
86
|
+
ToolResult: A ToolResult containing the generated images or error message.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
response: GenerateImagesResponse = self.client.models.generate_images(
|
|
91
|
+
model=self.image_model,
|
|
92
|
+
prompt=prompt,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
log_debug("DEBUG: Raw Gemini API response")
|
|
96
|
+
|
|
97
|
+
# Extract image bytes
|
|
98
|
+
if response.generated_images is None or not response.generated_images:
|
|
99
|
+
log_info("No images were generated.")
|
|
100
|
+
return ToolResult(content="Failed to generate image: No images were generated.")
|
|
101
|
+
|
|
102
|
+
generated_images = []
|
|
103
|
+
for generated_image in response.generated_images:
|
|
104
|
+
if generated_image.image is None or not generated_image.image.image_bytes:
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
image_bytes = generated_image.image.image_bytes
|
|
108
|
+
actual_mime_type = "image/png"
|
|
109
|
+
media_id = str(uuid4())
|
|
110
|
+
|
|
111
|
+
# Create ImageArtifact with raw bytes (not base64 encoded)
|
|
112
|
+
image_artifact = Image(
|
|
113
|
+
id=media_id,
|
|
114
|
+
content=image_bytes,
|
|
115
|
+
original_prompt=prompt,
|
|
116
|
+
mime_type=actual_mime_type,
|
|
117
|
+
)
|
|
118
|
+
generated_images.append(image_artifact)
|
|
119
|
+
log_debug(f"Successfully generated image {media_id} with model {self.image_model}")
|
|
120
|
+
|
|
121
|
+
if generated_images:
|
|
122
|
+
return ToolResult(
|
|
123
|
+
content="Image generated successfully",
|
|
124
|
+
images=generated_images,
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
return ToolResult(content="Failed to generate image: No valid images were generated.")
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
log_error(f"Failed to generate image: Client or method not available ({e})")
|
|
131
|
+
return ToolResult(content=f"Failed to generate image: Client or method not available ({e})")
|
|
132
|
+
|
|
133
|
+
def generate_video(
|
|
134
|
+
self,
|
|
135
|
+
agent: Agent,
|
|
136
|
+
prompt: str,
|
|
137
|
+
) -> ToolResult:
|
|
138
|
+
"""Generate a video based on a text prompt.
|
|
139
|
+
Args:
|
|
140
|
+
prompt (str): The text prompt to generate the video from.
|
|
141
|
+
Returns:
|
|
142
|
+
ToolResult: A ToolResult containing the generated video or error message.
|
|
143
|
+
"""
|
|
144
|
+
# Video generation requires Vertex AI mode.
|
|
145
|
+
if not self.vertexai:
|
|
146
|
+
log_error("Video generation requires Vertex AI mode. Please enable Vertex AI mode.")
|
|
147
|
+
return ToolResult(
|
|
148
|
+
content="Video generation requires Vertex AI mode. "
|
|
149
|
+
"Please set `vertexai=True` or environment variable `GOOGLE_GENAI_USE_VERTEXAI=true`."
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
from google.genai.types import GenerateVideosConfig
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
operation: GenerateVideosOperation = self.client.models.generate_videos(
|
|
156
|
+
model=self.video_model,
|
|
157
|
+
prompt=prompt,
|
|
158
|
+
config=GenerateVideosConfig(
|
|
159
|
+
enhance_prompt=True,
|
|
160
|
+
),
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
while not operation.done:
|
|
164
|
+
time.sleep(5)
|
|
165
|
+
operation = self.client.operations.get(operation=operation)
|
|
166
|
+
|
|
167
|
+
result = operation.result
|
|
168
|
+
if result is None or result.generated_videos is None or not result.generated_videos:
|
|
169
|
+
log_error("No videos were generated.")
|
|
170
|
+
return ToolResult(content="Failed to generate video: No videos were generated.")
|
|
171
|
+
|
|
172
|
+
generated_videos = []
|
|
173
|
+
for video in result.generated_videos:
|
|
174
|
+
if video.video is None or not video.video.video_bytes:
|
|
175
|
+
continue
|
|
176
|
+
|
|
177
|
+
generated_video = video.video
|
|
178
|
+
if generated_video.video_bytes is None:
|
|
179
|
+
continue
|
|
180
|
+
|
|
181
|
+
media_id = str(uuid4())
|
|
182
|
+
|
|
183
|
+
# Create VideoArtifact with base64 encoded content
|
|
184
|
+
video_artifact = Video(
|
|
185
|
+
id=media_id,
|
|
186
|
+
content=base64.b64encode(generated_video.video_bytes).decode("utf-8"),
|
|
187
|
+
original_prompt=prompt,
|
|
188
|
+
mime_type=generated_video.mime_type or "video/mp4",
|
|
189
|
+
)
|
|
190
|
+
generated_videos.append(video_artifact)
|
|
191
|
+
log_debug(f"Successfully generated video {media_id} with model {self.video_model}")
|
|
192
|
+
|
|
193
|
+
if generated_videos:
|
|
194
|
+
return ToolResult(
|
|
195
|
+
content="Video generated successfully",
|
|
196
|
+
videos=generated_videos,
|
|
197
|
+
)
|
|
198
|
+
else:
|
|
199
|
+
return ToolResult(content="Failed to generate video: No valid videos were generated.")
|
|
200
|
+
|
|
201
|
+
except Exception as e:
|
|
202
|
+
log_error(f"Failed to generate video: {e}")
|
|
203
|
+
return ToolResult(content=f"Failed to generate video: {e}")
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, List, Optional
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from agno.agent import Agent
|
|
7
|
+
from agno.media import Audio
|
|
8
|
+
from agno.tools import Toolkit
|
|
9
|
+
from agno.tools.function import ToolResult
|
|
10
|
+
from agno.utils.log import log_debug, log_error
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from groq import Groq as GroqClient
|
|
14
|
+
except (ModuleNotFoundError, ImportError):
|
|
15
|
+
raise ImportError("`groq` not installed. Please install using `pip install groq`")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GroqTools(Toolkit):
|
|
19
|
+
"""Tools for interacting with Groq API"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
api_key: Optional[str] = None,
|
|
24
|
+
transcription_model: str = "whisper-large-v3",
|
|
25
|
+
translation_model: str = "whisper-large-v3",
|
|
26
|
+
tts_model: str = "playai-tts",
|
|
27
|
+
tts_voice: str = "Chip-PlayAI",
|
|
28
|
+
enable_transcribe_audio: bool = True,
|
|
29
|
+
enable_translate_audio: bool = True,
|
|
30
|
+
enable_generate_speech: bool = True,
|
|
31
|
+
all: bool = False,
|
|
32
|
+
**kwargs,
|
|
33
|
+
):
|
|
34
|
+
tools: List[Any] = []
|
|
35
|
+
if all or enable_transcribe_audio:
|
|
36
|
+
tools.append(self.transcribe_audio)
|
|
37
|
+
if all or enable_translate_audio:
|
|
38
|
+
tools.append(self.translate_audio)
|
|
39
|
+
if all or enable_generate_speech:
|
|
40
|
+
tools.append(self.generate_speech)
|
|
41
|
+
|
|
42
|
+
super().__init__(name="groq_tools", tools=tools, **kwargs)
|
|
43
|
+
|
|
44
|
+
self.api_key = api_key or getenv("GROQ_API_KEY")
|
|
45
|
+
if not self.api_key:
|
|
46
|
+
raise ValueError("GROQ_API_KEY not set. Please set the GROQ_API_KEY environment variable.")
|
|
47
|
+
|
|
48
|
+
self.client = GroqClient(api_key=self.api_key)
|
|
49
|
+
self.transcription_model = transcription_model
|
|
50
|
+
self.translation_model = translation_model
|
|
51
|
+
self.tts_model = tts_model
|
|
52
|
+
self.tts_voice = tts_voice
|
|
53
|
+
self.tts_format = "wav"
|
|
54
|
+
|
|
55
|
+
def transcribe_audio(self, audio_source: str) -> str:
|
|
56
|
+
"""Transcribe audio file or URL using Groq's Whisper API.
|
|
57
|
+
Args:
|
|
58
|
+
audio_source: Path to the local audio file or a publicly accessible URL to the audio.
|
|
59
|
+
Returns:
|
|
60
|
+
str: Transcribed text
|
|
61
|
+
"""
|
|
62
|
+
log_debug(f"Transcribing audio from {audio_source} using Groq model {self.transcription_model}")
|
|
63
|
+
try:
|
|
64
|
+
# Check if the audio source as a local file or a URL
|
|
65
|
+
if not Path(audio_source).exists():
|
|
66
|
+
log_debug(f"Audio source '{audio_source}' not found locally, attempting as URL.")
|
|
67
|
+
transcription_text = self.client.audio.transcriptions.create(
|
|
68
|
+
url=audio_source,
|
|
69
|
+
model=self.transcription_model,
|
|
70
|
+
response_format="text",
|
|
71
|
+
)
|
|
72
|
+
else:
|
|
73
|
+
log_debug(f"Transcribing local file: {audio_source}")
|
|
74
|
+
with open(audio_source, "rb") as audio_file:
|
|
75
|
+
transcription_text = self.client.audio.transcriptions.create(
|
|
76
|
+
file=(Path(audio_source).name, audio_file.read()),
|
|
77
|
+
model=self.transcription_model,
|
|
78
|
+
response_format="text",
|
|
79
|
+
)
|
|
80
|
+
log_debug(f"Transcript Generated: {transcription_text}")
|
|
81
|
+
return str(transcription_text)
|
|
82
|
+
|
|
83
|
+
except Exception as e:
|
|
84
|
+
log_error(f"Failed to transcribe audio source '{audio_source}' with Groq: {str(e)}")
|
|
85
|
+
return f"Failed to transcribe audio source '{audio_source}' with Groq: {str(e)}"
|
|
86
|
+
|
|
87
|
+
def translate_audio(self, audio_source: str) -> str:
|
|
88
|
+
"""Translate audio file or URL to English using Groq's Whisper API.
|
|
89
|
+
Args:
|
|
90
|
+
audio_source: Path to the local audio file or a publicly accessible URL to the audio.
|
|
91
|
+
Returns:
|
|
92
|
+
str: Translated English text
|
|
93
|
+
"""
|
|
94
|
+
log_debug(f"Translating audio from {audio_source} to English using Groq model {self.translation_model}")
|
|
95
|
+
try:
|
|
96
|
+
if not Path(audio_source).exists():
|
|
97
|
+
log_debug(f"Audio source '{audio_source}' not found locally.")
|
|
98
|
+
translation = self.client.audio.translations.create(
|
|
99
|
+
url=audio_source,
|
|
100
|
+
model=self.translation_model,
|
|
101
|
+
response_format="text",
|
|
102
|
+
)
|
|
103
|
+
else:
|
|
104
|
+
log_debug(f"Translating local file: {audio_source}")
|
|
105
|
+
with open(audio_source, "rb") as audio_file:
|
|
106
|
+
translation = self.client.audio.translations.create(
|
|
107
|
+
file=(Path(audio_source).name, audio_file.read()),
|
|
108
|
+
model=self.translation_model,
|
|
109
|
+
response_format="text",
|
|
110
|
+
)
|
|
111
|
+
log_debug(f"Groq Translation: {translation}")
|
|
112
|
+
return str(translation)
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
log_error(f"Failed to translate audio source '{audio_source}' with Groq: {str(e)}")
|
|
116
|
+
return f"Failed to translate audio source '{audio_source}' with Groq: {str(e)}"
|
|
117
|
+
|
|
118
|
+
def generate_speech(
|
|
119
|
+
self,
|
|
120
|
+
agent: Agent,
|
|
121
|
+
text_input: str,
|
|
122
|
+
) -> ToolResult:
|
|
123
|
+
"""Generate speech from text using Groq's Text-to-Speech API.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
text_input: The text to synthesize into speech.
|
|
127
|
+
Returns:
|
|
128
|
+
ToolResult: Contains the generated audio artifact or error message.
|
|
129
|
+
"""
|
|
130
|
+
log_debug(
|
|
131
|
+
f"Generating speech for text: '{text_input[:50]}...' using Groq model {self.tts_model}, voice {self.tts_voice}"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
response = self.client.audio.speech.create(
|
|
136
|
+
model=self.tts_model,
|
|
137
|
+
voice=self.tts_voice,
|
|
138
|
+
input=text_input,
|
|
139
|
+
response_format="wav",
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
log_debug(f"Groq TTS Response: {response}")
|
|
143
|
+
|
|
144
|
+
audio_data: bytes = response.read()
|
|
145
|
+
|
|
146
|
+
media_id = str(uuid4())
|
|
147
|
+
audio_artifact = Audio(
|
|
148
|
+
id=media_id,
|
|
149
|
+
content=audio_data,
|
|
150
|
+
mime_type="audio/wav",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
log_debug(f"Successfully generated speech artifact with ID: {media_id}")
|
|
154
|
+
return ToolResult(content=f"Speech generated successfully with ID: {media_id}", audios=[audio_artifact])
|
|
155
|
+
|
|
156
|
+
except Exception as e:
|
|
157
|
+
log_error(f"Failed to generate speech with Groq: {str(e)}")
|
|
158
|
+
return ToolResult(content=f"Failed to generate speech with Groq: {str(e)}")
|