agno 2.2.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +51 -0
- agno/agent/agent.py +10405 -0
- agno/api/__init__.py +0 -0
- agno/api/agent.py +28 -0
- agno/api/api.py +40 -0
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +13 -0
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +16 -0
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/response.py +6 -0
- agno/api/schemas/team.py +16 -0
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +30 -0
- 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/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 +598 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2042 -0
- agno/db/dynamo/schemas.py +314 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1795 -0
- agno/db/firestore/schemas.py +140 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1335 -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 +1160 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1328 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/__init__.py +0 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2026 -0
- agno/db/mongo/mongo.py +1982 -0
- agno/db/mongo/schemas.py +87 -0
- agno/db/mongo/utils.py +259 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +2308 -0
- agno/db/mysql/schemas.py +138 -0
- agno/db/mysql/utils.py +355 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +1927 -0
- agno/db/postgres/postgres.py +2260 -0
- agno/db/postgres/schemas.py +139 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1660 -0
- agno/db/redis/schemas.py +123 -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 +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/schemas/metrics.py +0 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +130 -0
- agno/db/singlestore/singlestore.py +2272 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2293 -0
- agno/db/sqlite/schemas.py +133 -0
- agno/db/sqlite/sqlite.py +2288 -0
- agno/db/sqlite/utils.py +431 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +309 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1353 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +116 -0
- agno/debug.py +18 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +834 -0
- agno/eval/performance.py +773 -0
- agno/eval/reliability.py +306 -0
- agno/eval/utils.py +119 -0
- agno/exceptions.py +161 -0
- 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/integrations/__init__.py +0 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -0
- agno/knowledge/chunking/__init__.py +0 -0
- agno/knowledge/chunking/agentic.py +79 -0
- agno/knowledge/chunking/document.py +91 -0
- agno/knowledge/chunking/fixed.py +57 -0
- agno/knowledge/chunking/markdown.py +151 -0
- agno/knowledge/chunking/recursive.py +63 -0
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +86 -0
- agno/knowledge/chunking/strategy.py +165 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/knowledge/document/base.py +58 -0
- agno/knowledge/embedder/__init__.py +5 -0
- agno/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/knowledge/embedder/base.py +23 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/knowledge/embedder/fireworks.py +13 -0
- 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/knowledge/embedder/together.py +13 -0
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +1988 -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 +166 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +87 -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 +194 -0
- agno/knowledge/reader/text_reader.py +115 -0
- agno/knowledge/reader/web_search_reader.py +372 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/__init__.py +0 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/knowledge/reranker/base.py +14 -0
- agno/knowledge/reranker/cohere.py +64 -0
- 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 +189 -0
- agno/media.py +462 -0
- agno/memory/__init__.py +3 -0
- agno/memory/manager.py +1327 -0
- agno/models/__init__.py +0 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +45 -0
- agno/models/anthropic/__init__.py +5 -0
- agno/models/anthropic/claude.py +757 -0
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +701 -0
- agno/models/aws/claude.py +378 -0
- agno/models/azure/__init__.py +18 -0
- agno/models/azure/ai_foundry.py +485 -0
- agno/models/azure/openai_chat.py +131 -0
- agno/models/base.py +2175 -0
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +501 -0
- agno/models/cerebras/cerebras_openai.py +112 -0
- agno/models/cohere/__init__.py +5 -0
- agno/models/cohere/chat.py +389 -0
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +91 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +28 -0
- agno/models/deepseek/__init__.py +5 -0
- agno/models/deepseek/deepseek.py +61 -0
- agno/models/defaults.py +1 -0
- agno/models/fireworks/__init__.py +5 -0
- agno/models/fireworks/fireworks.py +26 -0
- agno/models/google/__init__.py +5 -0
- agno/models/google/gemini.py +1085 -0
- agno/models/groq/__init__.py +5 -0
- agno/models/groq/groq.py +556 -0
- agno/models/huggingface/__init__.py +5 -0
- agno/models/huggingface/huggingface.py +491 -0
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +422 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +26 -0
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +48 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +468 -0
- agno/models/litellm/litellm_openai.py +25 -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 +434 -0
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +475 -0
- agno/models/meta/llama_openai.py +78 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +5 -0
- agno/models/mistral/mistral.py +432 -0
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +54 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +5 -0
- agno/models/nvidia/nvidia.py +28 -0
- agno/models/ollama/__init__.py +5 -0
- agno/models/ollama/chat.py +441 -0
- agno/models/openai/__init__.py +9 -0
- agno/models/openai/chat.py +883 -0
- agno/models/openai/like.py +27 -0
- agno/models/openai/responses.py +1050 -0
- agno/models/openrouter/__init__.py +5 -0
- agno/models/openrouter/openrouter.py +66 -0
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +187 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +81 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +52 -0
- agno/models/response.py +199 -0
- agno/models/sambanova/__init__.py +5 -0
- agno/models/sambanova/sambanova.py +28 -0
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +25 -0
- agno/models/together/__init__.py +5 -0
- agno/models/together/together.py +25 -0
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +26 -0
- agno/models/vertexai/__init__.py +0 -0
- agno/models/vertexai/claude.py +70 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +78 -0
- agno/models/xai/__init__.py +3 -0
- agno/models/xai/xai.py +113 -0
- agno/os/__init__.py +3 -0
- agno/os/app.py +876 -0
- agno/os/auth.py +57 -0
- agno/os/config.py +104 -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 +250 -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 +144 -0
- agno/os/interfaces/agui/utils.py +534 -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 +211 -0
- agno/os/interfaces/whatsapp/security.py +53 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +292 -0
- agno/os/middleware/__init__.py +7 -0
- agno/os/middleware/jwt.py +233 -0
- agno/os/router.py +1763 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +430 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +162 -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 +997 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +515 -0
- agno/os/routers/memory/schemas.py +62 -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/schema.py +1055 -0
- agno/os/settings.py +43 -0
- agno/os/utils.py +630 -0
- agno/py.typed +0 -0
- agno/reasoning/__init__.py +0 -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 +63 -0
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +31 -0
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +787 -0
- agno/run/base.py +229 -0
- agno/run/cancel.py +81 -0
- agno/run/messages.py +32 -0
- agno/run/team.py +753 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +295 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +392 -0
- agno/session/workflow.py +205 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +8793 -0
- agno/tools/__init__.py +10 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +69 -0
- agno/tools/api.py +122 -0
- agno/tools/apify.py +314 -0
- agno/tools/arxiv.py +127 -0
- agno/tools/aws_lambda.py +53 -0
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +89 -0
- 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 +255 -0
- agno/tools/calculator.py +151 -0
- agno/tools/cartesia.py +187 -0
- agno/tools/clickup.py +244 -0
- agno/tools/confluence.py +240 -0
- agno/tools/crawl4ai.py +158 -0
- agno/tools/csv_toolkit.py +185 -0
- agno/tools/dalle.py +110 -0
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +262 -0
- agno/tools/desi_vocal.py +108 -0
- agno/tools/discord.py +161 -0
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +379 -0
- agno/tools/duckduckgo.py +91 -0
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +196 -0
- agno/tools/email.py +67 -0
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +396 -0
- agno/tools/fal.py +127 -0
- agno/tools/file.py +240 -0
- agno/tools/file_generation.py +350 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +143 -0
- agno/tools/function.py +1187 -0
- agno/tools/giphy.py +93 -0
- agno/tools/github.py +1760 -0
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +270 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +674 -0
- agno/tools/googlesearch.py +98 -0
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +77 -0
- agno/tools/jina.py +101 -0
- agno/tools/jira.py +170 -0
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +426 -0
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +90 -0
- agno/tools/lumalab.py +183 -0
- 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/memori.py +339 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +139 -0
- agno/tools/models/__init__.py +0 -0
- 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 +195 -0
- agno/tools/moviepy_video.py +349 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +46 -0
- agno/tools/newspaper4k.py +93 -0
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +202 -0
- agno/tools/openbb.py +160 -0
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +102 -0
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +257 -0
- agno/tools/pubmed.py +188 -0
- agno/tools/python.py +205 -0
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +467 -0
- agno/tools/replicate.py +117 -0
- agno/tools/resend.py +62 -0
- agno/tools/scrapegraph.py +222 -0
- agno/tools/searxng.py +152 -0
- agno/tools/serpapi.py +116 -0
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +53 -0
- agno/tools/slack.py +136 -0
- agno/tools/sleep.py +20 -0
- agno/tools/spider.py +116 -0
- agno/tools/sql.py +154 -0
- agno/tools/streamlit/__init__.py +0 -0
- agno/tools/streamlit/components.py +113 -0
- agno/tools/tavily.py +254 -0
- agno/tools/telegram.py +48 -0
- agno/tools/todoist.py +218 -0
- agno/tools/tool_registry.py +1 -0
- agno/tools/toolkit.py +146 -0
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +274 -0
- agno/tools/twilio.py +186 -0
- 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 +54 -0
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +63 -0
- agno/tools/workflow.py +278 -0
- agno/tools/x.py +335 -0
- agno/tools/yfinance.py +257 -0
- agno/tools/youtube.py +184 -0
- agno/tools/zendesk.py +82 -0
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +382 -0
- agno/utils/__init__.py +0 -0
- agno/utils/agent.py +820 -0
- agno/utils/audio.py +49 -0
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +132 -0
- agno/utils/dttm.py +13 -0
- agno/utils/enum.py +22 -0
- agno/utils/env.py +11 -0
- agno/utils/events.py +696 -0
- agno/utils/format_str.py +16 -0
- agno/utils/functions.py +166 -0
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +57 -0
- agno/utils/http.py +74 -0
- agno/utils/json_schema.py +234 -0
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +255 -0
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +352 -0
- agno/utils/merge_dict.py +41 -0
- agno/utils/message.py +118 -0
- agno/utils/models/__init__.py +0 -0
- agno/utils/models/ai_foundry.py +43 -0
- agno/utils/models/claude.py +358 -0
- agno/utils/models/cohere.py +87 -0
- agno/utils/models/llama.py +78 -0
- agno/utils/models/mistral.py +98 -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 +32 -0
- agno/utils/pprint.py +178 -0
- agno/utils/print_response/__init__.py +0 -0
- agno/utils/print_response/agent.py +842 -0
- agno/utils/print_response/team.py +1724 -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/response_iterator.py +17 -0
- agno/utils/safe_formatter.py +24 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +22 -0
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +231 -0
- agno/utils/team.py +139 -0
- agno/utils/timer.py +41 -0
- agno/utils/tools.py +102 -0
- agno/utils/web.py +23 -0
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +25 -0
- agno/vectordb/__init__.py +3 -0
- agno/vectordb/base.py +127 -0
- agno/vectordb/cassandra/__init__.py +5 -0
- agno/vectordb/cassandra/cassandra.py +501 -0
- agno/vectordb/cassandra/extra_param_mixin.py +11 -0
- agno/vectordb/cassandra/index.py +13 -0
- agno/vectordb/chroma/__init__.py +5 -0
- agno/vectordb/chroma/chromadb.py +929 -0
- agno/vectordb/clickhouse/__init__.py +9 -0
- agno/vectordb/clickhouse/clickhousedb.py +835 -0
- agno/vectordb/clickhouse/index.py +9 -0
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1442 -0
- agno/vectordb/distance.py +7 -0
- agno/vectordb/lancedb/__init__.py +6 -0
- agno/vectordb/lancedb/lance_db.py +995 -0
- 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 +4 -0
- agno/vectordb/milvus/milvus.py +1182 -0
- agno/vectordb/mongodb/__init__.py +9 -0
- agno/vectordb/mongodb/mongodb.py +1417 -0
- agno/vectordb/pgvector/__init__.py +12 -0
- agno/vectordb/pgvector/index.py +23 -0
- agno/vectordb/pgvector/pgvector.py +1462 -0
- agno/vectordb/pineconedb/__init__.py +5 -0
- agno/vectordb/pineconedb/pineconedb.py +747 -0
- agno/vectordb/qdrant/__init__.py +5 -0
- agno/vectordb/qdrant/qdrant.py +1134 -0
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +694 -0
- agno/vectordb/search.py +7 -0
- agno/vectordb/singlestore/__init__.py +10 -0
- agno/vectordb/singlestore/index.py +41 -0
- agno/vectordb/singlestore/singlestore.py +763 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +699 -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 +1005 -0
- agno/workflow/__init__.py +23 -0
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +738 -0
- agno/workflow/loop.py +735 -0
- agno/workflow/parallel.py +824 -0
- agno/workflow/router.py +702 -0
- agno/workflow/step.py +1432 -0
- agno/workflow/steps.py +592 -0
- agno/workflow/types.py +520 -0
- agno/workflow/workflow.py +4321 -0
- agno-2.2.13.dist-info/METADATA +614 -0
- agno-2.2.13.dist-info/RECORD +575 -0
- agno-2.2.13.dist-info/WHEEL +5 -0
- agno-2.2.13.dist-info/licenses/LICENSE +201 -0
- agno-2.2.13.dist-info/top_level.txt +1 -0
agno/tools/crawl4ai.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import Any, Dict, List, Optional, Union
|
|
3
|
+
|
|
4
|
+
from agno.tools import Toolkit
|
|
5
|
+
from agno.utils.log import log_debug, log_warning
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig
|
|
9
|
+
except ImportError:
|
|
10
|
+
raise ImportError("`crawl4ai` not installed. Please install using `pip install crawl4ai`")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Crawl4aiTools(Toolkit):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
max_length: Optional[int] = 5000,
|
|
17
|
+
timeout: int = 60,
|
|
18
|
+
use_pruning: bool = False,
|
|
19
|
+
pruning_threshold: float = 0.48,
|
|
20
|
+
bm25_threshold: float = 1.0,
|
|
21
|
+
headless: bool = True,
|
|
22
|
+
wait_until: str = "domcontentloaded",
|
|
23
|
+
enable_crawl: bool = True,
|
|
24
|
+
all: bool = False,
|
|
25
|
+
**kwargs,
|
|
26
|
+
):
|
|
27
|
+
tools = []
|
|
28
|
+
if all or enable_crawl:
|
|
29
|
+
tools.append(self.crawl)
|
|
30
|
+
|
|
31
|
+
super().__init__(name="crawl4ai_tools", tools=tools, **kwargs)
|
|
32
|
+
self.max_length = max_length
|
|
33
|
+
self.timeout = timeout
|
|
34
|
+
self.use_pruning = use_pruning
|
|
35
|
+
self.pruning_threshold = pruning_threshold
|
|
36
|
+
self.bm25_threshold = bm25_threshold
|
|
37
|
+
self.wait_until = wait_until
|
|
38
|
+
self.headless = headless
|
|
39
|
+
|
|
40
|
+
def _build_config(self, search_query: Optional[str] = None) -> Dict[str, Any]:
|
|
41
|
+
"""Build CrawlerRunConfig parameters from toolkit settings."""
|
|
42
|
+
config_params = {
|
|
43
|
+
"page_timeout": self.timeout * 1000, # Convert to milliseconds
|
|
44
|
+
"wait_until": self.wait_until,
|
|
45
|
+
"cache_mode": "bypass", # Don't use cache for fresh results
|
|
46
|
+
"verbose": False,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Handle content filtering
|
|
50
|
+
if self.use_pruning or search_query:
|
|
51
|
+
try:
|
|
52
|
+
from crawl4ai.content_filter_strategy import BM25ContentFilter, PruningContentFilter
|
|
53
|
+
from crawl4ai.markdown_generation_strategy import DefaultMarkdownGenerator
|
|
54
|
+
|
|
55
|
+
if search_query:
|
|
56
|
+
# Use BM25 for query-specific extraction
|
|
57
|
+
content_filter = BM25ContentFilter(user_query=search_query, bm25_threshold=self.bm25_threshold)
|
|
58
|
+
log_debug(f"Using BM25ContentFilter for query: {search_query}")
|
|
59
|
+
else:
|
|
60
|
+
# Use pruning for general cleanup
|
|
61
|
+
content_filter = PruningContentFilter(
|
|
62
|
+
threshold=self.pruning_threshold, threshold_type="fixed", min_word_threshold=2
|
|
63
|
+
)
|
|
64
|
+
log_debug("Using PruningContentFilter for general cleanup")
|
|
65
|
+
|
|
66
|
+
config_params["markdown_generator"] = DefaultMarkdownGenerator(content_filter=content_filter)
|
|
67
|
+
log_debug("Using DefaultMarkdownGenerator with content_filter")
|
|
68
|
+
except ImportError:
|
|
69
|
+
# If advanced features not available, continue without them
|
|
70
|
+
log_warning("crawl4ai.content_filter_strategy or crawl4ai.markdown_generation_strategy not installed")
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
return config_params
|
|
74
|
+
|
|
75
|
+
def crawl(self, url: Union[str, List[str]], search_query: Optional[str] = None) -> Union[str, Dict[str, str]]:
|
|
76
|
+
"""
|
|
77
|
+
Crawl URLs and extract their text content.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
url: Single URL string or list of URLs to crawl
|
|
81
|
+
search_query: Optional query string to filter content using BM25 algorithm
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
The extracted text content from the URL(s)
|
|
85
|
+
"""
|
|
86
|
+
if not url:
|
|
87
|
+
return "Error: No URL provided"
|
|
88
|
+
|
|
89
|
+
# Handle single URL
|
|
90
|
+
if isinstance(url, str):
|
|
91
|
+
return asyncio.run(self._async_crawl(url, search_query))
|
|
92
|
+
|
|
93
|
+
# Handle multiple URLs
|
|
94
|
+
results = {}
|
|
95
|
+
for single_url in url:
|
|
96
|
+
results[single_url] = asyncio.run(self._async_crawl(single_url, search_query))
|
|
97
|
+
return results
|
|
98
|
+
|
|
99
|
+
async def _async_crawl(self, url: str, search_query: Optional[str] = None) -> str:
|
|
100
|
+
"""Crawl a single URL and extract content."""
|
|
101
|
+
try:
|
|
102
|
+
# Use BrowserConfig to suppress crawl4ai logs
|
|
103
|
+
browser_config = BrowserConfig(
|
|
104
|
+
headless=self.headless,
|
|
105
|
+
verbose=False,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
async with AsyncWebCrawler(config=browser_config) as crawler:
|
|
109
|
+
# Build configuration from parameters
|
|
110
|
+
config_params = self._build_config(search_query)
|
|
111
|
+
|
|
112
|
+
config = CrawlerRunConfig(**config_params)
|
|
113
|
+
log_debug(f"Crawling {url} with config: {config}")
|
|
114
|
+
result = await crawler.arun(url=url, config=config)
|
|
115
|
+
|
|
116
|
+
# Process the result
|
|
117
|
+
if not result:
|
|
118
|
+
return "Error: No content found"
|
|
119
|
+
|
|
120
|
+
log_debug(f"Result attributes: {dir(result)}")
|
|
121
|
+
log_debug(f"Result success: {getattr(result, 'success', 'N/A')}")
|
|
122
|
+
|
|
123
|
+
# Try to get markdown content
|
|
124
|
+
content = ""
|
|
125
|
+
if hasattr(result, "fit_markdown") and result.fit_markdown:
|
|
126
|
+
content = result.fit_markdown
|
|
127
|
+
log_debug("Using fit_markdown")
|
|
128
|
+
elif hasattr(result, "markdown") and result.markdown:
|
|
129
|
+
if hasattr(result.markdown, "raw_markdown"):
|
|
130
|
+
content = result.markdown.raw_markdown
|
|
131
|
+
log_debug("Using markdown.raw_markdown")
|
|
132
|
+
else:
|
|
133
|
+
content = str(result.markdown)
|
|
134
|
+
log_debug("Using str(markdown)")
|
|
135
|
+
else:
|
|
136
|
+
# Try to get any text content
|
|
137
|
+
if hasattr(result, "text"):
|
|
138
|
+
content = result.text
|
|
139
|
+
log_debug("Using text attribute")
|
|
140
|
+
elif hasattr(result, "html"):
|
|
141
|
+
log_warning("Only HTML available, no markdown extracted")
|
|
142
|
+
return "Error: Could not extract markdown from page"
|
|
143
|
+
|
|
144
|
+
if not content:
|
|
145
|
+
log_warning(f"No content extracted. Result type: {type(result)}")
|
|
146
|
+
return "Error: No readable content extracted"
|
|
147
|
+
|
|
148
|
+
log_debug(f"Extracted content length: {len(content)}")
|
|
149
|
+
|
|
150
|
+
# Truncate if needed
|
|
151
|
+
if self.max_length and len(content) > self.max_length:
|
|
152
|
+
content = content[: self.max_length] + "..."
|
|
153
|
+
|
|
154
|
+
return content
|
|
155
|
+
|
|
156
|
+
except Exception as e:
|
|
157
|
+
log_warning(f"Exception during crawl: {str(e)}")
|
|
158
|
+
return f"Error crawling {url}: {str(e)}"
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Dict, List, Optional, Union
|
|
5
|
+
|
|
6
|
+
from agno.tools import Toolkit
|
|
7
|
+
from agno.utils.log import log_debug, log_info, logger
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CsvTools(Toolkit):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
csvs: Optional[List[Union[str, Path]]] = None,
|
|
14
|
+
row_limit: Optional[int] = None,
|
|
15
|
+
duckdb_connection: Optional[Any] = None,
|
|
16
|
+
duckdb_kwargs: Optional[Dict[str, Any]] = None,
|
|
17
|
+
enable_read_csv_file: bool = True,
|
|
18
|
+
enable_list_csv_files: bool = True,
|
|
19
|
+
enable_get_columns: bool = True,
|
|
20
|
+
enable_query_csv_file: bool = True,
|
|
21
|
+
all: bool = False,
|
|
22
|
+
**kwargs,
|
|
23
|
+
):
|
|
24
|
+
self.csvs: List[Path] = []
|
|
25
|
+
if csvs:
|
|
26
|
+
for _csv in csvs:
|
|
27
|
+
if isinstance(_csv, str):
|
|
28
|
+
self.csvs.append(Path(_csv))
|
|
29
|
+
elif isinstance(_csv, Path):
|
|
30
|
+
self.csvs.append(_csv)
|
|
31
|
+
else:
|
|
32
|
+
raise ValueError(f"Invalid csv file: {_csv}")
|
|
33
|
+
self.row_limit = row_limit
|
|
34
|
+
self.duckdb_connection: Optional[Any] = duckdb_connection
|
|
35
|
+
self.duckdb_kwargs: Optional[Dict[str, Any]] = duckdb_kwargs
|
|
36
|
+
|
|
37
|
+
tools: List[Any] = []
|
|
38
|
+
if all or enable_read_csv_file:
|
|
39
|
+
tools.append(self.read_csv_file)
|
|
40
|
+
if all or enable_list_csv_files:
|
|
41
|
+
tools.append(self.list_csv_files)
|
|
42
|
+
if all or enable_get_columns:
|
|
43
|
+
tools.append(self.get_columns)
|
|
44
|
+
if all or enable_query_csv_file:
|
|
45
|
+
try:
|
|
46
|
+
import duckdb # noqa: F401
|
|
47
|
+
|
|
48
|
+
tools.append(self.query_csv_file)
|
|
49
|
+
except ImportError:
|
|
50
|
+
logger.warning("`duckdb` not installed. Query functionality disabled.")
|
|
51
|
+
|
|
52
|
+
super().__init__(name="csv_tools", tools=tools, **kwargs)
|
|
53
|
+
|
|
54
|
+
def list_csv_files(self) -> str:
|
|
55
|
+
"""Returns a list of available csv files
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
str: List of available csv files
|
|
59
|
+
"""
|
|
60
|
+
return json.dumps([_csv.stem for _csv in self.csvs])
|
|
61
|
+
|
|
62
|
+
def read_csv_file(self, csv_name: str, row_limit: Optional[int] = None) -> str:
|
|
63
|
+
"""Use this function to read the contents of a csv file `name` without the extension.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
csv_name (str): The name of the csv file to read without the extension.
|
|
67
|
+
row_limit (Optional[int]): The number of rows to return. None returns all rows. Defaults to None.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
str: The contents of the csv file if successful, otherwise returns an error message.
|
|
71
|
+
"""
|
|
72
|
+
try:
|
|
73
|
+
if csv_name not in [_csv.stem for _csv in self.csvs]:
|
|
74
|
+
return f"File: {csv_name} not found, please use one of {self.list_csv_files()}"
|
|
75
|
+
|
|
76
|
+
log_info(f"Reading file: {csv_name}")
|
|
77
|
+
file_path = [_csv for _csv in self.csvs if _csv.stem == csv_name][0]
|
|
78
|
+
|
|
79
|
+
# Read the csv file
|
|
80
|
+
csv_data = []
|
|
81
|
+
_row_limit = row_limit or self.row_limit
|
|
82
|
+
with open(str(file_path), newline="") as csvfile:
|
|
83
|
+
reader = csv.DictReader(csvfile)
|
|
84
|
+
if _row_limit is not None:
|
|
85
|
+
csv_data = [row for row in reader][:_row_limit]
|
|
86
|
+
else:
|
|
87
|
+
csv_data = [row for row in reader]
|
|
88
|
+
return json.dumps(csv_data)
|
|
89
|
+
except Exception as e:
|
|
90
|
+
logger.error(f"Error reading csv: {e}")
|
|
91
|
+
return f"Error reading csv: {e}"
|
|
92
|
+
|
|
93
|
+
def get_columns(self, csv_name: str) -> str:
|
|
94
|
+
"""Use this function to get the columns of the csv file `csv_name` without the extension.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
csv_name (str): The name of the csv file to get the columns from without the extension.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
str: The columns of the csv file if successful, otherwise returns an error message.
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
if csv_name not in [_csv.stem for _csv in self.csvs]:
|
|
104
|
+
return f"File: {csv_name} not found, please use one of {self.list_csv_files()}"
|
|
105
|
+
|
|
106
|
+
log_info(f"Reading columns from file: {csv_name}")
|
|
107
|
+
file_path = [_csv for _csv in self.csvs if _csv.stem == csv_name][0]
|
|
108
|
+
|
|
109
|
+
# Get the columns of the csv file
|
|
110
|
+
with open(str(file_path), newline="") as csvfile:
|
|
111
|
+
reader = csv.DictReader(csvfile)
|
|
112
|
+
columns = reader.fieldnames
|
|
113
|
+
|
|
114
|
+
return json.dumps(columns)
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.error(f"Error getting columns: {e}")
|
|
117
|
+
return f"Error getting columns: {e}"
|
|
118
|
+
|
|
119
|
+
def query_csv_file(self, csv_name: str, sql_query: str) -> str:
|
|
120
|
+
"""Use this function to run a SQL query on csv file `csv_name` without the extension.
|
|
121
|
+
The Table name is the name of the csv file without the extension.
|
|
122
|
+
The SQL Query should be a valid DuckDB SQL query.
|
|
123
|
+
Always wrap column names with double quotes if they contain spaces or special characters
|
|
124
|
+
Remember to escape the quotes in th e JSON string (use \")
|
|
125
|
+
Use single quotes for string values
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
csv_name (str): The name of the csv file to query
|
|
129
|
+
sql_query (str): The SQL Query to run on the csv file.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
str: The query results if successful, otherwise returns an error message.
|
|
133
|
+
"""
|
|
134
|
+
try:
|
|
135
|
+
import duckdb
|
|
136
|
+
|
|
137
|
+
if csv_name not in [_csv.stem for _csv in self.csvs]:
|
|
138
|
+
return f"File: {csv_name} not found, please use one of {self.list_csv_files()}"
|
|
139
|
+
|
|
140
|
+
# Load the csv file into duckdb
|
|
141
|
+
log_info(f"Loading csv file: {csv_name}")
|
|
142
|
+
file_path = [_csv for _csv in self.csvs if _csv.stem == csv_name][0]
|
|
143
|
+
|
|
144
|
+
# Create duckdb connection
|
|
145
|
+
con = self.duckdb_connection
|
|
146
|
+
if not self.duckdb_connection:
|
|
147
|
+
con = duckdb.connect(**(self.duckdb_kwargs or {}))
|
|
148
|
+
if con is None:
|
|
149
|
+
logger.error("Error connecting to DuckDB")
|
|
150
|
+
return "Error connecting to DuckDB, please check the connection."
|
|
151
|
+
|
|
152
|
+
# Create a table from the csv file
|
|
153
|
+
con.execute(
|
|
154
|
+
f"CREATE TABLE {csv_name} AS SELECT * FROM read_csv('{file_path}', ignore_errors=false, auto_detect=true)"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# -*- Format the SQL Query
|
|
158
|
+
# Remove backticks
|
|
159
|
+
formatted_sql = sql_query.replace("`", "")
|
|
160
|
+
# If there are multiple statements, only run the first one
|
|
161
|
+
formatted_sql = formatted_sql.split(";")[0]
|
|
162
|
+
# -*- Run the SQL Query
|
|
163
|
+
log_info(f"Running query: {formatted_sql}")
|
|
164
|
+
query_result = con.sql(formatted_sql)
|
|
165
|
+
result_output = "No output"
|
|
166
|
+
if query_result is not None:
|
|
167
|
+
try:
|
|
168
|
+
results_as_python_objects = query_result.fetchall()
|
|
169
|
+
result_rows = []
|
|
170
|
+
for row in results_as_python_objects:
|
|
171
|
+
if len(row) == 1:
|
|
172
|
+
result_rows.append(str(row[0]))
|
|
173
|
+
else:
|
|
174
|
+
result_rows.append(",".join(str(x) for x in row))
|
|
175
|
+
|
|
176
|
+
result_data = "\n".join(result_rows)
|
|
177
|
+
result_output = ",".join(query_result.columns) + "\n" + result_data
|
|
178
|
+
except AttributeError:
|
|
179
|
+
result_output = str(query_result)
|
|
180
|
+
|
|
181
|
+
log_debug(f"Query result: {result_output}")
|
|
182
|
+
return result_output
|
|
183
|
+
except Exception as e:
|
|
184
|
+
logger.error(f"Error querying csv: {e}")
|
|
185
|
+
return f"Error querying csv: {e}"
|
agno/tools/dalle.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from typing import Any, List, Literal, Optional
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from agno.media import Image
|
|
6
|
+
from agno.tools import Toolkit
|
|
7
|
+
from agno.tools.function import ToolResult
|
|
8
|
+
from agno.utils.log import log_debug, logger
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
from openai import OpenAI
|
|
12
|
+
from openai.types.images_response import ImagesResponse
|
|
13
|
+
except ImportError:
|
|
14
|
+
raise ImportError("`openai` not installed. Please install using `pip install openai`")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DalleTools(Toolkit):
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
model: str = "dall-e-3",
|
|
21
|
+
n: int = 1,
|
|
22
|
+
size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] = "1024x1024",
|
|
23
|
+
quality: Literal["standard", "hd"] = "standard",
|
|
24
|
+
style: Literal["vivid", "natural"] = "vivid",
|
|
25
|
+
api_key: Optional[str] = None,
|
|
26
|
+
enable_create_image: bool = True,
|
|
27
|
+
all: bool = False,
|
|
28
|
+
**kwargs,
|
|
29
|
+
):
|
|
30
|
+
self.model = model
|
|
31
|
+
self.n = n
|
|
32
|
+
self.size = size
|
|
33
|
+
self.quality = quality
|
|
34
|
+
self.style = style
|
|
35
|
+
self.api_key = api_key or getenv("OPENAI_API_KEY")
|
|
36
|
+
|
|
37
|
+
# Validations
|
|
38
|
+
if model not in ["dall-e-3", "dall-e-2"]:
|
|
39
|
+
raise ValueError("Invalid model. Please choose from 'dall-e-3' or 'dall-e-2'.")
|
|
40
|
+
if size not in ["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]:
|
|
41
|
+
raise ValueError(
|
|
42
|
+
"Invalid size. Please choose from '256x256', '512x512', '1024x1024', '1792x1024', '1024x1792'."
|
|
43
|
+
)
|
|
44
|
+
if quality not in ["standard", "hd"]:
|
|
45
|
+
raise ValueError("Invalid quality. Please choose from 'standard' or 'hd'.")
|
|
46
|
+
if not isinstance(n, int) or n <= 0:
|
|
47
|
+
raise ValueError("Invalid number of images. Please provide a positive integer.")
|
|
48
|
+
if model == "dall-e-3" and n > 1:
|
|
49
|
+
raise ValueError("Dall-e-3 only supports a single image generation.")
|
|
50
|
+
|
|
51
|
+
if not self.api_key:
|
|
52
|
+
logger.error("OPENAI_API_KEY not set. Please set the OPENAI_API_KEY environment variable.")
|
|
53
|
+
|
|
54
|
+
tools: List[Any] = []
|
|
55
|
+
if all or enable_create_image:
|
|
56
|
+
tools.append(self.create_image)
|
|
57
|
+
|
|
58
|
+
super().__init__(name="dalle", tools=tools, **kwargs)
|
|
59
|
+
|
|
60
|
+
# TODO:
|
|
61
|
+
# - Add support for response_format
|
|
62
|
+
# - Add support for saving images
|
|
63
|
+
# - Add support for editing images
|
|
64
|
+
|
|
65
|
+
def create_image(self, prompt: str) -> ToolResult:
|
|
66
|
+
"""Use this function to generate an image for a prompt.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
prompt (str): A text description of the desired image.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
ToolResult: Result containing the message and generated images.
|
|
73
|
+
"""
|
|
74
|
+
if not self.api_key:
|
|
75
|
+
return ToolResult(content="Please set the OPENAI_API_KEY")
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
client = OpenAI(api_key=self.api_key)
|
|
79
|
+
log_debug(f"Generating image using prompt: {prompt}")
|
|
80
|
+
response: ImagesResponse = client.images.generate(
|
|
81
|
+
prompt=prompt,
|
|
82
|
+
model=self.model,
|
|
83
|
+
n=self.n,
|
|
84
|
+
quality=self.quality,
|
|
85
|
+
size=self.size,
|
|
86
|
+
style=self.style,
|
|
87
|
+
)
|
|
88
|
+
log_debug("Image generated successfully")
|
|
89
|
+
|
|
90
|
+
generated_images = []
|
|
91
|
+
response_str = ""
|
|
92
|
+
if response.data:
|
|
93
|
+
for img in response.data:
|
|
94
|
+
if img.url:
|
|
95
|
+
image = Image(
|
|
96
|
+
id=str(uuid4()),
|
|
97
|
+
url=img.url,
|
|
98
|
+
original_prompt=prompt,
|
|
99
|
+
revised_prompt=img.revised_prompt,
|
|
100
|
+
)
|
|
101
|
+
generated_images.append(image)
|
|
102
|
+
response_str += f"Image has been generated at the URL {img.url}\n"
|
|
103
|
+
|
|
104
|
+
return ToolResult(
|
|
105
|
+
content=response_str or "No images were generated",
|
|
106
|
+
images=generated_images if generated_images else None,
|
|
107
|
+
)
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error(f"Failed to generate image: {e}")
|
|
110
|
+
return ToolResult(content=f"Error: {e}")
|