agno 0.1.2__py3-none-any.whl → 2.3.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/__init__.py +24 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -0
- agno/db/gcs_json/utils.py +228 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -0
- agno/db/redis/utils.py +346 -0
- agno/db/schemas/__init__.py +4 -0
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/knowledge/embedder/google.py +258 -0
- agno/knowledge/embedder/huggingface.py +94 -0
- agno/knowledge/embedder/jina.py +182 -0
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +206 -0
- agno/knowledge/embedder/nebius.py +13 -0
- agno/knowledge/embedder/ollama.py +154 -0
- agno/knowledge/embedder/openai.py +195 -0
- agno/knowledge/embedder/sentence_transformer.py +63 -0
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/knowledge/reader/arxiv_reader.py +81 -0
- agno/knowledge/reader/base.py +95 -0
- agno/knowledge/reader/csv_reader.py +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -0
- agno/knowledge/reader/markdown_reader.py +137 -0
- agno/knowledge/reader/pdf_reader.py +431 -0
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +313 -0
- agno/knowledge/reader/s3_reader.py +89 -0
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/knowledge/reranker/infinity.py +195 -0
- agno/knowledge/reranker/sentence_transformer.py +54 -0
- agno/knowledge/types.py +39 -0
- agno/knowledge/utils.py +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -0
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/lmstudio/__init__.py +5 -0
- agno/models/lmstudio/lmstudio.py +25 -0
- agno/models/message.py +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +249 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +47 -0
- agno/os/interfaces/agui/router.py +147 -0
- agno/os/interfaces/agui/utils.py +574 -0
- agno/os/interfaces/base.py +25 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/os/interfaces/slack/router.py +148 -0
- agno/os/interfaces/slack/security.py +30 -0
- agno/os/interfaces/slack/slack.py +47 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/os/interfaces/whatsapp/router.py +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -0
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +190 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +997 -0
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -0
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +67 -0
- agno/reasoning/deepseek.py +63 -0
- agno/reasoning/default.py +97 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +71 -0
- agno/reasoning/helpers.py +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- agno/tools/bitbucket.py +292 -0
- agno/tools/brandfetch.py +213 -0
- agno/tools/bravesearch.py +106 -0
- agno/tools/brightdata.py +367 -0
- agno/tools/browserbase.py +209 -0
- agno/tools/calcom.py +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +193 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- agno/tools/models/azure_openai.py +190 -0
- agno/tools/models/gemini.py +203 -0
- agno/tools/models/groq.py +158 -0
- agno/tools/models/morph.py +186 -0
- agno/tools/models/nebius.py +124 -0
- agno/tools/models_labs.py +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- agno/tools/user_control_flow.py +78 -0
- agno/tools/valyu.py +228 -0
- agno/tools/visualization.py +467 -0
- agno/tools/webbrowser.py +28 -0
- agno/tools/webex.py +76 -0
- agno/tools/website.py +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -0
- agno/utils/models/openai_responses.py +140 -0
- agno/utils/models/schema_utils.py +153 -0
- agno/utils/models/watsonx.py +41 -0
- agno/utils/openai.py +257 -0
- agno/utils/pickle.py +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -0
- agno/utils/print_response/workflow.py +1668 -0
- agno/utils/prompts.py +111 -0
- agno/utils/reasoning.py +108 -0
- agno/utils/response.py +163 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +163 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +388 -0
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +166 -0
- agno/vectordb/milvus/__init__.py +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -0
- agno/vectordb/upstashdb/__init__.py +5 -0
- agno/vectordb/upstashdb/upstashdb.py +718 -0
- agno/vectordb/weaviate/__init__.py +8 -0
- agno/vectordb/weaviate/index.py +15 -0
- agno/vectordb/weaviate/weaviate.py +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/tools/zoom.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from
|
|
2
|
+
from base64 import b64encode
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
from os import getenv
|
|
5
|
+
from typing import Any, List, Optional
|
|
3
6
|
|
|
4
7
|
import requests
|
|
5
8
|
|
|
6
|
-
from agno.tools
|
|
7
|
-
from agno.utils.log import logger
|
|
9
|
+
from agno.tools import Toolkit
|
|
10
|
+
from agno.utils.log import log_debug, log_info, logger
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
class ZoomTools(Toolkit):
|
|
@@ -13,37 +16,83 @@ class ZoomTools(Toolkit):
|
|
|
13
16
|
account_id: Optional[str] = None,
|
|
14
17
|
client_id: Optional[str] = None,
|
|
15
18
|
client_secret: Optional[str] = None,
|
|
16
|
-
|
|
19
|
+
**kwargs,
|
|
17
20
|
):
|
|
18
21
|
"""
|
|
19
22
|
Initialize the ZoomTool.
|
|
20
23
|
|
|
21
24
|
Args:
|
|
22
|
-
account_id (str): The Zoom account ID for authentication.
|
|
23
|
-
client_id (str): The client ID for authentication.
|
|
24
|
-
client_secret (str): The client secret for authentication.
|
|
25
|
+
account_id (str): The Zoom account ID for authentication. If not provided, will use ZOOM_ACCOUNT_ID env var.
|
|
26
|
+
client_id (str): The client ID for authentication. If not provided, will use ZOOM_CLIENT_ID env var.
|
|
27
|
+
client_secret (str): The client secret for authentication. If not provided, will use ZOOM_CLIENT_SECRET env var.
|
|
25
28
|
name (str): The name of the tool. Defaults to "zoom_tool".
|
|
26
29
|
"""
|
|
27
|
-
|
|
28
|
-
self.account_id = account_id
|
|
29
|
-
self.client_id = client_id
|
|
30
|
-
self.client_secret = client_secret
|
|
30
|
+
# Get credentials from env vars if not provided
|
|
31
|
+
self.account_id = account_id or getenv("ZOOM_ACCOUNT_ID")
|
|
32
|
+
self.client_id = client_id or getenv("ZOOM_CLIENT_ID")
|
|
33
|
+
self.client_secret = client_secret or getenv("ZOOM_CLIENT_SECRET")
|
|
31
34
|
self.__access_token = None # Made private
|
|
35
|
+
self.__token_expiry = None # Track token expiration
|
|
32
36
|
|
|
33
37
|
if not self.account_id or not self.client_id or not self.client_secret:
|
|
34
|
-
logger.error(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
logger.error(
|
|
39
|
+
"ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, and ZOOM_CLIENT_SECRET must be set either through parameters or environment variables."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
tools: List[Any] = [
|
|
43
|
+
self.get_access_token,
|
|
44
|
+
self.schedule_meeting,
|
|
45
|
+
self.get_upcoming_meetings,
|
|
46
|
+
self.list_meetings,
|
|
47
|
+
self.get_meeting_recordings,
|
|
48
|
+
self.delete_meeting,
|
|
49
|
+
self.get_meeting,
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
super().__init__(name="zoom_tool", tools=tools, **kwargs)
|
|
43
53
|
|
|
44
54
|
def get_access_token(self) -> str:
|
|
45
|
-
"""
|
|
46
|
-
|
|
55
|
+
"""
|
|
56
|
+
Get a valid access token, refreshing if necessary using Zoom's Server-to-Server OAuth.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
str: The current access token or empty string if token generation fails.
|
|
60
|
+
"""
|
|
61
|
+
# Check if we have a valid token
|
|
62
|
+
if self.__access_token and self.__token_expiry and datetime.now() < self.__token_expiry:
|
|
63
|
+
return self.__access_token
|
|
64
|
+
|
|
65
|
+
# Generate new token
|
|
66
|
+
try:
|
|
67
|
+
headers = {
|
|
68
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# Create base64 encoded auth string
|
|
72
|
+
auth_string = b64encode(f"{self.client_id}:{self.client_secret}".encode()).decode()
|
|
73
|
+
headers["Authorization"] = f"Basic {auth_string}"
|
|
74
|
+
|
|
75
|
+
data = {
|
|
76
|
+
"grant_type": "account_credentials",
|
|
77
|
+
"account_id": self.account_id,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
response = requests.post("https://zoom.us/oauth/token", headers=headers, data=data)
|
|
81
|
+
response.raise_for_status()
|
|
82
|
+
|
|
83
|
+
token_data = response.json()
|
|
84
|
+
self.__access_token = token_data["access_token"]
|
|
85
|
+
# Set expiry time slightly before actual expiry to ensure token validity
|
|
86
|
+
self.__token_expiry = datetime.now() + timedelta(seconds=token_data["expires_in"] - 60) # type: ignore
|
|
87
|
+
|
|
88
|
+
log_debug("Successfully generated new Zoom access token")
|
|
89
|
+
return self.__access_token # type: ignore
|
|
90
|
+
|
|
91
|
+
except requests.RequestException as e:
|
|
92
|
+
logger.error(f"Failed to generate Zoom access token: {e}")
|
|
93
|
+
self.__access_token = None
|
|
94
|
+
self.__token_expiry = None
|
|
95
|
+
return ""
|
|
47
96
|
|
|
48
97
|
def schedule_meeting(self, topic: str, start_time: str, duration: int, timezone: str = "UTC") -> str:
|
|
49
98
|
"""
|
|
@@ -59,7 +108,7 @@ class ZoomTools(Toolkit):
|
|
|
59
108
|
A JSON-formatted string containing the response from Zoom API with the scheduled meeting details,
|
|
60
109
|
or an error message if the scheduling fails.
|
|
61
110
|
"""
|
|
62
|
-
|
|
111
|
+
log_debug(f"Attempting to schedule meeting: {topic} in timezone: {timezone}")
|
|
63
112
|
token = self.get_access_token()
|
|
64
113
|
if not token:
|
|
65
114
|
logger.error("Unable to obtain access token.")
|
|
@@ -97,7 +146,7 @@ class ZoomTools(Toolkit):
|
|
|
97
146
|
"duration": meeting_info["duration"],
|
|
98
147
|
"join_url": meeting_info["join_url"],
|
|
99
148
|
}
|
|
100
|
-
|
|
149
|
+
log_info(f"Meeting scheduled successfully. ID: {meeting_info['id']}")
|
|
101
150
|
return json.dumps(result, indent=2)
|
|
102
151
|
except requests.RequestException as e:
|
|
103
152
|
logger.error(f"Error scheduling meeting: {e}")
|
|
@@ -114,7 +163,7 @@ class ZoomTools(Toolkit):
|
|
|
114
163
|
A JSON-formatted string containing the upcoming meetings information,
|
|
115
164
|
or an error message if the request fails.
|
|
116
165
|
"""
|
|
117
|
-
|
|
166
|
+
log_debug(f"Fetching upcoming meetings for user: {user_id}")
|
|
118
167
|
token = self.get_access_token()
|
|
119
168
|
if not token:
|
|
120
169
|
logger.error("Unable to obtain access token.")
|
|
@@ -125,12 +174,12 @@ class ZoomTools(Toolkit):
|
|
|
125
174
|
params = {"type": "upcoming", "page_size": str(30)}
|
|
126
175
|
|
|
127
176
|
try:
|
|
128
|
-
response = requests.get(url, headers=headers, params=params)
|
|
177
|
+
response = requests.get(url, headers=headers, params=params) # type: ignore
|
|
129
178
|
response.raise_for_status()
|
|
130
179
|
meetings = response.json()
|
|
131
180
|
|
|
132
181
|
result = {"message": "Upcoming meetings retrieved successfully", "meetings": meetings.get("meetings", [])}
|
|
133
|
-
|
|
182
|
+
log_info(f"Retrieved {len(result['meetings'])} upcoming meetings")
|
|
134
183
|
return json.dumps(result, indent=2)
|
|
135
184
|
except requests.RequestException as e:
|
|
136
185
|
logger.error(f"Error fetching upcoming meetings: {e}")
|
|
@@ -153,7 +202,7 @@ class ZoomTools(Toolkit):
|
|
|
153
202
|
A JSON-formatted string containing the meetings information,
|
|
154
203
|
or an error message if the request fails.
|
|
155
204
|
"""
|
|
156
|
-
|
|
205
|
+
log_debug(f"Fetching meetings for user: {user_id}")
|
|
157
206
|
token = self.get_access_token()
|
|
158
207
|
if not token:
|
|
159
208
|
logger.error("Unable to obtain access token.")
|
|
@@ -176,7 +225,7 @@ class ZoomTools(Toolkit):
|
|
|
176
225
|
"total_records": meetings.get("total_records", 0),
|
|
177
226
|
"meetings": meetings.get("meetings", []),
|
|
178
227
|
}
|
|
179
|
-
|
|
228
|
+
log_info(f"Retrieved {len(result['meetings'])} meetings")
|
|
180
229
|
return json.dumps(result, indent=2)
|
|
181
230
|
except requests.RequestException as e:
|
|
182
231
|
logger.error(f"Error fetching meetings: {e}")
|
|
@@ -197,7 +246,7 @@ class ZoomTools(Toolkit):
|
|
|
197
246
|
A JSON-formatted string containing the meeting recordings information,
|
|
198
247
|
or an error message if the request fails.
|
|
199
248
|
"""
|
|
200
|
-
|
|
249
|
+
log_debug(f"Fetching recordings for meeting: {meeting_id}")
|
|
201
250
|
token = self.get_access_token()
|
|
202
251
|
if not token:
|
|
203
252
|
logger.error("Unable to obtain access token.")
|
|
@@ -223,7 +272,7 @@ class ZoomTools(Toolkit):
|
|
|
223
272
|
|
|
224
273
|
result = {
|
|
225
274
|
"message": "Meeting recordings retrieved successfully",
|
|
226
|
-
"meeting_id": recordings.get("id", ""),
|
|
275
|
+
"meeting_id": str(recordings.get("id", "")),
|
|
227
276
|
"uuid": recordings.get("uuid", ""),
|
|
228
277
|
"host_id": recordings.get("host_id", ""),
|
|
229
278
|
"topic": recordings.get("topic", ""),
|
|
@@ -234,7 +283,7 @@ class ZoomTools(Toolkit):
|
|
|
234
283
|
"recording_files": recordings.get("recording_files", []),
|
|
235
284
|
}
|
|
236
285
|
|
|
237
|
-
|
|
286
|
+
log_info(f"Retrieved {result['recording_count']} recording files")
|
|
238
287
|
return json.dumps(result, indent=2)
|
|
239
288
|
except requests.RequestException as e:
|
|
240
289
|
logger.error(f"Error fetching meeting recordings: {e}")
|
|
@@ -253,7 +302,7 @@ class ZoomTools(Toolkit):
|
|
|
253
302
|
A JSON-formatted string containing the response status,
|
|
254
303
|
or an error message if the deletion fails.
|
|
255
304
|
"""
|
|
256
|
-
|
|
305
|
+
log_debug(f"Attempting to delete meeting: {meeting_id}")
|
|
257
306
|
token = self.get_access_token()
|
|
258
307
|
if not token:
|
|
259
308
|
logger.error("Unable to obtain access token.")
|
|
@@ -270,7 +319,7 @@ class ZoomTools(Toolkit):
|
|
|
270
319
|
# Zoom returns 204 No Content for successful deletion
|
|
271
320
|
if response.status_code == 204:
|
|
272
321
|
result = {"message": "Meeting deleted successfully!", "meeting_id": meeting_id}
|
|
273
|
-
|
|
322
|
+
log_info(f"Meeting {meeting_id} deleted successfully")
|
|
274
323
|
else:
|
|
275
324
|
result = response.json()
|
|
276
325
|
|
|
@@ -290,7 +339,7 @@ class ZoomTools(Toolkit):
|
|
|
290
339
|
A JSON-formatted string containing the meeting details,
|
|
291
340
|
or an error message if the request fails.
|
|
292
341
|
"""
|
|
293
|
-
|
|
342
|
+
log_debug(f"Fetching details for meeting: {meeting_id}")
|
|
294
343
|
token = self.get_access_token()
|
|
295
344
|
if not token:
|
|
296
345
|
logger.error("Unable to obtain access token.")
|
|
@@ -306,7 +355,7 @@ class ZoomTools(Toolkit):
|
|
|
306
355
|
|
|
307
356
|
result = {
|
|
308
357
|
"message": "Meeting details retrieved successfully",
|
|
309
|
-
"meeting_id": meeting_info.get("id", ""),
|
|
358
|
+
"meeting_id": str(meeting_info.get("id", "")),
|
|
310
359
|
"topic": meeting_info.get("topic", ""),
|
|
311
360
|
"type": meeting_info.get("type", ""),
|
|
312
361
|
"start_time": meeting_info.get("start_time", ""),
|
|
@@ -317,7 +366,7 @@ class ZoomTools(Toolkit):
|
|
|
317
366
|
"settings": meeting_info.get("settings", {}),
|
|
318
367
|
}
|
|
319
368
|
|
|
320
|
-
|
|
369
|
+
log_info(f"Retrieved details for meeting ID: {meeting_id}")
|
|
321
370
|
return json.dumps(result, indent=2)
|
|
322
371
|
except requests.RequestException as e:
|
|
323
372
|
logger.error(f"Error fetching meeting details: {e}")
|
agno/tracing/__init__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agno Tracing Module
|
|
3
|
+
|
|
4
|
+
This module provides OpenTelemetry-based tracing capabilities for Agno agents.
|
|
5
|
+
It uses the openinference-instrumentation-agno package for automatic instrumentation
|
|
6
|
+
and provides a custom DatabaseSpanExporter to store traces in the Agno database.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from agno.tracing.exporter import DatabaseSpanExporter
|
|
10
|
+
from agno.tracing.setup import setup_tracing
|
|
11
|
+
|
|
12
|
+
__all__ = ["DatabaseSpanExporter", "setup_tracing"]
|
agno/tracing/exporter.py
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom OpenTelemetry SpanExporter that writes traces to Agno database.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from typing import Dict, List, Sequence, Union
|
|
8
|
+
|
|
9
|
+
from opentelemetry.sdk.trace import ReadableSpan # type: ignore
|
|
10
|
+
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult # type: ignore
|
|
11
|
+
|
|
12
|
+
from agno.db.base import AsyncBaseDb, BaseDb
|
|
13
|
+
from agno.tracing.schemas import Span, create_trace_from_spans
|
|
14
|
+
from agno.utils.log import logger
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DatabaseSpanExporter(SpanExporter):
|
|
18
|
+
"""Custom OpenTelemetry SpanExporter that writes to Agno database"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, db: Union[BaseDb, AsyncBaseDb]):
|
|
21
|
+
"""
|
|
22
|
+
Initialize the DatabaseSpanExporter.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
db: Database instance (sync or async) to store traces
|
|
26
|
+
"""
|
|
27
|
+
self.db = db
|
|
28
|
+
self._shutdown = False
|
|
29
|
+
|
|
30
|
+
def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
|
|
31
|
+
"""
|
|
32
|
+
Export spans to the database.
|
|
33
|
+
|
|
34
|
+
This method:
|
|
35
|
+
1. Converts OpenTelemetry spans to Span objects
|
|
36
|
+
2. Groups spans by trace_id
|
|
37
|
+
3. Creates Trace records (one per trace_id)
|
|
38
|
+
4. Creates Span records (multiple per trace_id)
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
spans: Sequence of OpenTelemetry ReadableSpan objects
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
SpanExportResult indicating success or failure
|
|
45
|
+
"""
|
|
46
|
+
if self._shutdown:
|
|
47
|
+
logger.warning("DatabaseSpanExporter is shutdown, cannot export spans")
|
|
48
|
+
return SpanExportResult.FAILURE
|
|
49
|
+
|
|
50
|
+
if not spans:
|
|
51
|
+
return SpanExportResult.SUCCESS
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
# Convert OpenTelemetry spans to Span objects
|
|
55
|
+
converted_spans: List[Span] = []
|
|
56
|
+
for span in spans:
|
|
57
|
+
try:
|
|
58
|
+
converted_span = Span.from_otel_span(span)
|
|
59
|
+
converted_spans.append(converted_span)
|
|
60
|
+
except Exception as e:
|
|
61
|
+
logger.error(f"Failed to convert span {span.name}: {e}")
|
|
62
|
+
# Continue processing other spans
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
if not converted_spans:
|
|
66
|
+
return SpanExportResult.SUCCESS
|
|
67
|
+
|
|
68
|
+
# Group spans by trace_id
|
|
69
|
+
spans_by_trace: Dict[str, List[Span]] = defaultdict(list)
|
|
70
|
+
for converted_span in converted_spans:
|
|
71
|
+
spans_by_trace[converted_span.trace_id].append(converted_span)
|
|
72
|
+
|
|
73
|
+
# Handle async DB
|
|
74
|
+
if isinstance(self.db, AsyncBaseDb):
|
|
75
|
+
self._export_async(spans_by_trace)
|
|
76
|
+
else:
|
|
77
|
+
# Synchronous database
|
|
78
|
+
self._export_sync(spans_by_trace)
|
|
79
|
+
|
|
80
|
+
return SpanExportResult.SUCCESS
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.error(f"Failed to export spans to database: {e}", exc_info=True)
|
|
83
|
+
return SpanExportResult.FAILURE
|
|
84
|
+
|
|
85
|
+
def _export_sync(self, spans_by_trace: Dict[str, List[Span]]) -> None:
|
|
86
|
+
"""Export traces and spans to synchronous database"""
|
|
87
|
+
try:
|
|
88
|
+
# Create trace and span records for each trace
|
|
89
|
+
for trace_id, spans in spans_by_trace.items():
|
|
90
|
+
# Create trace record (aggregate of all spans)
|
|
91
|
+
trace = create_trace_from_spans(spans)
|
|
92
|
+
if trace:
|
|
93
|
+
self.db.upsert_trace(trace)
|
|
94
|
+
|
|
95
|
+
# Create span records
|
|
96
|
+
self.db.create_spans(spans)
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
logger.error(f"Failed to export sync traces: {e}", exc_info=True)
|
|
100
|
+
raise
|
|
101
|
+
|
|
102
|
+
def _export_async(self, spans_by_trace: Dict[str, List[Span]]) -> None:
|
|
103
|
+
"""Handle async database export"""
|
|
104
|
+
try:
|
|
105
|
+
loop = asyncio.get_event_loop()
|
|
106
|
+
if loop.is_running():
|
|
107
|
+
# We're in an async context, schedule the coroutine
|
|
108
|
+
asyncio.create_task(self._do_async_export(spans_by_trace))
|
|
109
|
+
else:
|
|
110
|
+
# No running loop, run in new loop
|
|
111
|
+
loop.run_until_complete(self._do_async_export(spans_by_trace))
|
|
112
|
+
except RuntimeError:
|
|
113
|
+
# No event loop, create new one
|
|
114
|
+
try:
|
|
115
|
+
asyncio.run(self._do_async_export(spans_by_trace))
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Failed to export async traces: {e}", exc_info=True)
|
|
118
|
+
|
|
119
|
+
async def _do_async_export(self, spans_by_trace: Dict[str, List[Span]]) -> None:
|
|
120
|
+
"""Actually perform the async export"""
|
|
121
|
+
try:
|
|
122
|
+
# Create trace and span records for each trace
|
|
123
|
+
for trace_id, spans in spans_by_trace.items():
|
|
124
|
+
# Create trace record (aggregate of all spans)
|
|
125
|
+
trace = create_trace_from_spans(spans)
|
|
126
|
+
if trace:
|
|
127
|
+
create_trace_result = self.db.upsert_trace(trace)
|
|
128
|
+
if create_trace_result is not None:
|
|
129
|
+
await create_trace_result
|
|
130
|
+
|
|
131
|
+
# Create span records
|
|
132
|
+
create_spans_result = self.db.create_spans(spans)
|
|
133
|
+
if create_spans_result is not None:
|
|
134
|
+
await create_spans_result
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error(f"Failed to do async export: {e}", exc_info=True)
|
|
138
|
+
raise
|
|
139
|
+
|
|
140
|
+
def shutdown(self) -> None:
|
|
141
|
+
"""Shutdown the exporter"""
|
|
142
|
+
self._shutdown = True
|
|
143
|
+
logger.debug("DatabaseSpanExporter shutdown")
|
|
144
|
+
|
|
145
|
+
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
146
|
+
"""
|
|
147
|
+
Force flush any pending spans.
|
|
148
|
+
|
|
149
|
+
Since we write immediately to the database, this is a no-op.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
timeout_millis: Timeout in milliseconds
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
True if flush was successful
|
|
156
|
+
"""
|
|
157
|
+
return True
|