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,432 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from os import getenv
|
|
3
|
+
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Type, Union
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from agno.exceptions import ModelProviderError
|
|
8
|
+
from agno.models.base import Model
|
|
9
|
+
from agno.models.message import Message
|
|
10
|
+
from agno.models.metrics import Metrics
|
|
11
|
+
from agno.models.response import ModelResponse
|
|
12
|
+
from agno.run.agent import RunOutput
|
|
13
|
+
from agno.utils.log import log_debug, log_error, log_warning
|
|
14
|
+
from agno.utils.models.watsonx import format_images_for_message
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from ibm_watsonx_ai import Credentials
|
|
18
|
+
from ibm_watsonx_ai.foundation_models import ModelInference
|
|
19
|
+
except ImportError:
|
|
20
|
+
raise ImportError("`ibm-watsonx-ai` is not installed. Please install it using `pip install ibm-watsonx-ai`.")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class WatsonX(Model):
|
|
25
|
+
"""
|
|
26
|
+
A class for interacting with IBM WatsonX models.
|
|
27
|
+
|
|
28
|
+
See supported models at: https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx
|
|
29
|
+
|
|
30
|
+
For more information, see: https://www.ibm.com/watsonx/developer/
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
id: str = "ibm/granite-20b-code-instruct"
|
|
34
|
+
name: str = "WatsonX"
|
|
35
|
+
provider: str = "IBM"
|
|
36
|
+
|
|
37
|
+
# Request parameters
|
|
38
|
+
frequency_penalty: Optional[float] = None
|
|
39
|
+
presence_penalty: Optional[float] = None
|
|
40
|
+
max_tokens: Optional[int] = None
|
|
41
|
+
temperature: Optional[float] = None
|
|
42
|
+
top_p: Optional[float] = None
|
|
43
|
+
logprobs: Optional[int] = None
|
|
44
|
+
top_logprobs: Optional[int] = None
|
|
45
|
+
|
|
46
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
47
|
+
|
|
48
|
+
# Client parameters
|
|
49
|
+
api_key: Optional[str] = None
|
|
50
|
+
project_id: Optional[str] = None
|
|
51
|
+
url: Optional[str] = "https://eu-de.ml.cloud.ibm.com"
|
|
52
|
+
verify: bool = True
|
|
53
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
54
|
+
|
|
55
|
+
# WatsonX client
|
|
56
|
+
model_client: Optional[ModelInference] = None
|
|
57
|
+
|
|
58
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
59
|
+
# Fetch API key and project ID from env if not already set
|
|
60
|
+
self.api_key = self.api_key or getenv("IBM_WATSONX_API_KEY")
|
|
61
|
+
if not self.api_key:
|
|
62
|
+
log_error("IBM_WATSONX_API_KEY not set. Please set the IBM_WATSONX_API_KEY environment variable.")
|
|
63
|
+
|
|
64
|
+
self.project_id = self.project_id or getenv("IBM_WATSONX_PROJECT_ID")
|
|
65
|
+
if not self.project_id:
|
|
66
|
+
log_error("IBM_WATSONX_PROJECT_ID not set. Please set the IBM_WATSONX_PROJECT_ID environment variable.")
|
|
67
|
+
|
|
68
|
+
self.url = getenv("IBM_WATSONX_URL") or self.url
|
|
69
|
+
|
|
70
|
+
# Create credentials object
|
|
71
|
+
credentials = Credentials(url=self.url, api_key=self.api_key, verify=self.verify)
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
"credentials": credentials,
|
|
75
|
+
"project_id": self.project_id,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
def get_client(self) -> ModelInference:
|
|
79
|
+
"""
|
|
80
|
+
Returns a WatsonX ModelInference client.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
ModelInference: An instance of the WatsonX ModelInference client.
|
|
84
|
+
"""
|
|
85
|
+
if self.model_client:
|
|
86
|
+
return self.model_client
|
|
87
|
+
|
|
88
|
+
# Get client parameters
|
|
89
|
+
client_params = self._get_client_params()
|
|
90
|
+
|
|
91
|
+
# Initialize model inference client
|
|
92
|
+
self.model_client = ModelInference(model_id=self.id, **client_params)
|
|
93
|
+
|
|
94
|
+
return self.model_client
|
|
95
|
+
|
|
96
|
+
def get_request_params(
|
|
97
|
+
self,
|
|
98
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
99
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
100
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
101
|
+
) -> Dict[str, Any]:
|
|
102
|
+
params = {
|
|
103
|
+
"frequency_penalty": self.frequency_penalty,
|
|
104
|
+
"presence_penalty": self.presence_penalty,
|
|
105
|
+
"max_tokens": self.max_tokens,
|
|
106
|
+
"temperature": self.temperature,
|
|
107
|
+
"top_p": self.top_p,
|
|
108
|
+
"logprobs": self.logprobs,
|
|
109
|
+
"top_logprobs": self.top_logprobs,
|
|
110
|
+
"response_format": response_format,
|
|
111
|
+
}
|
|
112
|
+
# Filter out None values
|
|
113
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
114
|
+
request_params = {}
|
|
115
|
+
|
|
116
|
+
if params:
|
|
117
|
+
request_params["params"] = params
|
|
118
|
+
|
|
119
|
+
# Add tools
|
|
120
|
+
if tools is not None:
|
|
121
|
+
request_params["tools"] = tools # type: ignore
|
|
122
|
+
if tool_choice is not None:
|
|
123
|
+
request_params["tool_choice"] = tool_choice # type: ignore
|
|
124
|
+
# Add additional request params if provided
|
|
125
|
+
if self.request_params:
|
|
126
|
+
request_params.update(self.request_params)
|
|
127
|
+
|
|
128
|
+
if request_params:
|
|
129
|
+
log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
|
|
130
|
+
return request_params
|
|
131
|
+
|
|
132
|
+
def _format_message(self, message: Message, compress_tool_results: bool = False) -> Dict[str, Any]:
|
|
133
|
+
"""
|
|
134
|
+
Format a message into the format expected by WatsonX.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
message (Message): The message to format.
|
|
138
|
+
compress_tool_results: Whether to compress tool results.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Dict[str, Any]: The formatted message.
|
|
142
|
+
"""
|
|
143
|
+
if message.images is not None and isinstance(message.content, str):
|
|
144
|
+
message = format_images_for_message(message=message, images=message.images)
|
|
145
|
+
|
|
146
|
+
if message.audio is not None and len(message.audio) > 0:
|
|
147
|
+
log_warning("Audio input is currently unsupported.")
|
|
148
|
+
|
|
149
|
+
if message.files is not None and len(message.files) > 0:
|
|
150
|
+
log_warning("File input is currently unsupported.")
|
|
151
|
+
|
|
152
|
+
if message.videos is not None and len(message.videos) > 0:
|
|
153
|
+
log_warning("Video input is currently unsupported.")
|
|
154
|
+
|
|
155
|
+
message_dict = message.to_dict()
|
|
156
|
+
|
|
157
|
+
# Use compressed content for tool messages if compression is active
|
|
158
|
+
if message.role == "tool" and compress_tool_results:
|
|
159
|
+
message_dict["content"] = message.get_content(use_compressed_content=True)
|
|
160
|
+
return message_dict
|
|
161
|
+
|
|
162
|
+
def invoke(
|
|
163
|
+
self,
|
|
164
|
+
messages: List[Message],
|
|
165
|
+
assistant_message: Message,
|
|
166
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
167
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
168
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
169
|
+
run_response: Optional[RunOutput] = None,
|
|
170
|
+
compress_tool_results: bool = False,
|
|
171
|
+
) -> ModelResponse:
|
|
172
|
+
"""
|
|
173
|
+
Send a chat completion request to the WatsonX API.
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
if run_response and run_response.metrics:
|
|
177
|
+
run_response.metrics.set_time_to_first_token()
|
|
178
|
+
|
|
179
|
+
client = self.get_client()
|
|
180
|
+
|
|
181
|
+
formatted_messages = [self._format_message(m, compress_tool_results) for m in messages]
|
|
182
|
+
request_params = self.get_request_params(
|
|
183
|
+
response_format=response_format, tools=tools, tool_choice=tool_choice
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
assistant_message.metrics.start_timer()
|
|
187
|
+
response = client.chat(messages=formatted_messages, **request_params)
|
|
188
|
+
assistant_message.metrics.stop_timer()
|
|
189
|
+
|
|
190
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
191
|
+
|
|
192
|
+
return model_response
|
|
193
|
+
|
|
194
|
+
except Exception as e:
|
|
195
|
+
log_error(f"Error calling WatsonX API: {str(e)}")
|
|
196
|
+
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
197
|
+
|
|
198
|
+
async def ainvoke(
|
|
199
|
+
self,
|
|
200
|
+
messages: List[Message],
|
|
201
|
+
assistant_message: Message,
|
|
202
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
203
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
204
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
205
|
+
run_response: Optional[RunOutput] = None,
|
|
206
|
+
compress_tool_results: bool = False,
|
|
207
|
+
) -> Any:
|
|
208
|
+
"""
|
|
209
|
+
Sends an asynchronous chat completion request to the WatsonX API.
|
|
210
|
+
"""
|
|
211
|
+
try:
|
|
212
|
+
if run_response and run_response.metrics:
|
|
213
|
+
run_response.metrics.set_time_to_first_token()
|
|
214
|
+
|
|
215
|
+
client = self.get_client()
|
|
216
|
+
formatted_messages = [self._format_message(m, compress_tool_results) for m in messages]
|
|
217
|
+
|
|
218
|
+
request_params = self.get_request_params(
|
|
219
|
+
response_format=response_format, tools=tools, tool_choice=tool_choice
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
assistant_message.metrics.start_timer()
|
|
223
|
+
provider_response = await client.achat(messages=formatted_messages, **request_params)
|
|
224
|
+
assistant_message.metrics.stop_timer()
|
|
225
|
+
|
|
226
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format)
|
|
227
|
+
|
|
228
|
+
return model_response
|
|
229
|
+
|
|
230
|
+
except Exception as e:
|
|
231
|
+
log_error(f"Error calling WatsonX API: {str(e)}")
|
|
232
|
+
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
233
|
+
|
|
234
|
+
def invoke_stream(
|
|
235
|
+
self,
|
|
236
|
+
messages: List[Message],
|
|
237
|
+
assistant_message: Message,
|
|
238
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
239
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
240
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
241
|
+
run_response: Optional[RunOutput] = None,
|
|
242
|
+
compress_tool_results: bool = False,
|
|
243
|
+
) -> Iterator[ModelResponse]:
|
|
244
|
+
"""
|
|
245
|
+
Send a streaming chat completion request to the WatsonX API.
|
|
246
|
+
"""
|
|
247
|
+
try:
|
|
248
|
+
client = self.get_client()
|
|
249
|
+
formatted_messages = [self._format_message(m, compress_tool_results) for m in messages]
|
|
250
|
+
|
|
251
|
+
request_params = self.get_request_params(
|
|
252
|
+
response_format=response_format, tools=tools, tool_choice=tool_choice
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
if run_response and run_response.metrics:
|
|
256
|
+
run_response.metrics.set_time_to_first_token()
|
|
257
|
+
|
|
258
|
+
assistant_message.metrics.start_timer()
|
|
259
|
+
|
|
260
|
+
for chunk in client.chat_stream(messages=formatted_messages, **request_params):
|
|
261
|
+
yield self._parse_provider_response_delta(chunk)
|
|
262
|
+
|
|
263
|
+
assistant_message.metrics.stop_timer()
|
|
264
|
+
|
|
265
|
+
except Exception as e:
|
|
266
|
+
log_error(f"Error calling WatsonX API: {str(e)}")
|
|
267
|
+
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
268
|
+
|
|
269
|
+
async def ainvoke_stream(
|
|
270
|
+
self,
|
|
271
|
+
messages: List[Message],
|
|
272
|
+
assistant_message: Message,
|
|
273
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
274
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
275
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
276
|
+
run_response: Optional[RunOutput] = None,
|
|
277
|
+
compress_tool_results: bool = False,
|
|
278
|
+
) -> AsyncIterator[ModelResponse]:
|
|
279
|
+
"""
|
|
280
|
+
Sends an asynchronous streaming chat completion request to the WatsonX API.
|
|
281
|
+
"""
|
|
282
|
+
try:
|
|
283
|
+
if run_response and run_response.metrics:
|
|
284
|
+
run_response.metrics.set_time_to_first_token()
|
|
285
|
+
|
|
286
|
+
client = self.get_client()
|
|
287
|
+
formatted_messages = [self._format_message(m, compress_tool_results) for m in messages]
|
|
288
|
+
|
|
289
|
+
# Get parameters for chat
|
|
290
|
+
request_params = self.get_request_params(
|
|
291
|
+
response_format=response_format, tools=tools, tool_choice=tool_choice
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
assistant_message.metrics.start_timer()
|
|
295
|
+
|
|
296
|
+
async_stream = await client.achat_stream(messages=formatted_messages, **request_params)
|
|
297
|
+
async for chunk in async_stream:
|
|
298
|
+
yield self._parse_provider_response_delta(chunk)
|
|
299
|
+
|
|
300
|
+
assistant_message.metrics.stop_timer()
|
|
301
|
+
|
|
302
|
+
except Exception as e:
|
|
303
|
+
log_error(f"Error in async streaming from WatsonX API: {str(e)}")
|
|
304
|
+
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
305
|
+
|
|
306
|
+
# Override base method
|
|
307
|
+
@staticmethod
|
|
308
|
+
def parse_tool_calls(tool_calls_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
309
|
+
"""
|
|
310
|
+
Build tool calls from streamed tool call data.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
tool_calls_data (List[ChoiceDeltaToolCall]): The tool call data to build from.
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
List[Dict[str, Any]]: The built tool calls.
|
|
317
|
+
"""
|
|
318
|
+
tool_calls: List[Dict[str, Any]] = []
|
|
319
|
+
for _tool_call in tool_calls_data:
|
|
320
|
+
_index = _tool_call.get("index", 0)
|
|
321
|
+
_tool_call_id = _tool_call.get("id")
|
|
322
|
+
_tool_call_type = _tool_call.get("type")
|
|
323
|
+
_function_name = _tool_call.get("function", {}).get("name")
|
|
324
|
+
_function_arguments = _tool_call.get("function", {}).get("arguments")
|
|
325
|
+
|
|
326
|
+
if len(tool_calls) <= _index:
|
|
327
|
+
tool_calls.extend([{}] * (_index - len(tool_calls) + 1))
|
|
328
|
+
tool_call_entry = tool_calls[_index]
|
|
329
|
+
if not tool_call_entry:
|
|
330
|
+
tool_call_entry["id"] = _tool_call_id
|
|
331
|
+
tool_call_entry["type"] = _tool_call_type
|
|
332
|
+
tool_call_entry["function"] = {
|
|
333
|
+
"name": _function_name or "",
|
|
334
|
+
"arguments": _function_arguments or "",
|
|
335
|
+
}
|
|
336
|
+
else:
|
|
337
|
+
if _function_name:
|
|
338
|
+
tool_call_entry["function"]["name"] += _function_name
|
|
339
|
+
if _function_arguments:
|
|
340
|
+
tool_call_entry["function"]["arguments"] += _function_arguments
|
|
341
|
+
if _tool_call_id:
|
|
342
|
+
tool_call_entry["id"] = _tool_call_id
|
|
343
|
+
if _tool_call_type:
|
|
344
|
+
tool_call_entry["type"] = _tool_call_type
|
|
345
|
+
return tool_calls
|
|
346
|
+
|
|
347
|
+
def _parse_provider_response(
|
|
348
|
+
self,
|
|
349
|
+
response: Dict[str, Any],
|
|
350
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
351
|
+
) -> ModelResponse:
|
|
352
|
+
"""
|
|
353
|
+
Parse the WatsonX response into a ModelResponse.
|
|
354
|
+
"""
|
|
355
|
+
model_response = ModelResponse()
|
|
356
|
+
|
|
357
|
+
# Get response message
|
|
358
|
+
response_message = response["choices"][0]["message"]
|
|
359
|
+
# Parse structured outputs if enabled
|
|
360
|
+
try:
|
|
361
|
+
if (
|
|
362
|
+
response_format is not None
|
|
363
|
+
and isinstance(response_format, type)
|
|
364
|
+
and issubclass(response_format, BaseModel)
|
|
365
|
+
):
|
|
366
|
+
parsed_object = response_message.parsed # type: ignore
|
|
367
|
+
if parsed_object is not None:
|
|
368
|
+
model_response.parsed = parsed_object
|
|
369
|
+
except Exception as e:
|
|
370
|
+
log_warning(f"Error retrieving structured outputs: {e}")
|
|
371
|
+
|
|
372
|
+
# Add role
|
|
373
|
+
if response_message.get("role") is not None:
|
|
374
|
+
model_response.role = response_message["role"]
|
|
375
|
+
|
|
376
|
+
# Add content
|
|
377
|
+
if response_message.get("content") is not None:
|
|
378
|
+
model_response.content = response_message["content"]
|
|
379
|
+
|
|
380
|
+
# Add tool calls
|
|
381
|
+
if response_message.get("tool_calls") is not None and len(response_message["tool_calls"]) > 0:
|
|
382
|
+
try:
|
|
383
|
+
model_response.tool_calls = response_message["tool_calls"]
|
|
384
|
+
except Exception as e:
|
|
385
|
+
log_warning(f"Error processing tool calls: {e}")
|
|
386
|
+
|
|
387
|
+
if response.get("usage") is not None:
|
|
388
|
+
model_response.response_usage = self._get_metrics(response["usage"])
|
|
389
|
+
|
|
390
|
+
return model_response
|
|
391
|
+
|
|
392
|
+
def _parse_provider_response_delta(self, response_delta: Dict[str, Any]) -> ModelResponse:
|
|
393
|
+
"""
|
|
394
|
+
Parse the OpenAI streaming response into a ModelResponse.
|
|
395
|
+
"""
|
|
396
|
+
model_response = ModelResponse()
|
|
397
|
+
|
|
398
|
+
if response_delta.get("choices") and len(response_delta["choices"]) > 0:
|
|
399
|
+
choice_delta: Dict[str, Any] = response_delta["choices"][0].get("delta")
|
|
400
|
+
|
|
401
|
+
if choice_delta:
|
|
402
|
+
# Add content
|
|
403
|
+
if choice_delta.get("content") is not None:
|
|
404
|
+
model_response.content = choice_delta["content"]
|
|
405
|
+
|
|
406
|
+
# Add tool calls
|
|
407
|
+
if choice_delta.get("tool_calls") is not None:
|
|
408
|
+
model_response.tool_calls = choice_delta["tool_calls"]
|
|
409
|
+
|
|
410
|
+
# Add usage metrics if present
|
|
411
|
+
if response_delta.get("usage") is not None:
|
|
412
|
+
model_response.response_usage = self._get_metrics(response_delta["usage"])
|
|
413
|
+
|
|
414
|
+
return model_response
|
|
415
|
+
|
|
416
|
+
def _get_metrics(self, response_usage: Dict[str, Any]) -> Metrics:
|
|
417
|
+
"""
|
|
418
|
+
Parse the given WatsonX usage into an Agno Metrics object.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
response_usage: Usage data from WatsonX
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
Metrics: Parsed metrics data
|
|
425
|
+
"""
|
|
426
|
+
metrics = Metrics()
|
|
427
|
+
|
|
428
|
+
metrics.input_tokens = response_usage.get("prompt_tokens") or 0
|
|
429
|
+
metrics.output_tokens = response_usage.get("completion_tokens") or 0
|
|
430
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
|
|
431
|
+
|
|
432
|
+
return metrics
|
agno/models/internlm/__init__.py
CHANGED
agno/models/internlm/internlm.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
|
+
from agno.exceptions import ModelAuthenticationError
|
|
5
6
|
from agno.models.openai.like import OpenAILike
|
|
6
7
|
|
|
7
8
|
|
|
@@ -22,5 +23,21 @@ class InternLM(OpenAILike):
|
|
|
22
23
|
name: str = "InternLM"
|
|
23
24
|
provider: str = "InternLM"
|
|
24
25
|
|
|
25
|
-
api_key: Optional[str] = getenv("INTERNLM_API_KEY"
|
|
26
|
+
api_key: Optional[str] = field(default_factory=lambda: getenv("INTERNLM_API_KEY"))
|
|
26
27
|
base_url: Optional[str] = "https://internlm-chat.intern-ai.org.cn/puyu/api/v1/chat/completions"
|
|
28
|
+
|
|
29
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
30
|
+
"""
|
|
31
|
+
Returns client parameters for API requests, checking for INTERNLM_API_KEY.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Dict[str, Any]: A dictionary of client parameters for API requests.
|
|
35
|
+
"""
|
|
36
|
+
if not self.api_key:
|
|
37
|
+
self.api_key = getenv("INTERNLM_API_KEY")
|
|
38
|
+
if not self.api_key:
|
|
39
|
+
raise ModelAuthenticationError(
|
|
40
|
+
message="INTERNLM_API_KEY not set. Please set the INTERNLM_API_KEY environment variable.",
|
|
41
|
+
model_name=self.name,
|
|
42
|
+
)
|
|
43
|
+
return super()._get_client_params()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from agno.models.langdb.langdb import LangDB
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from os import getenv
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from agno.exceptions import ModelAuthenticationError
|
|
6
|
+
from agno.models.openai.like import OpenAILike
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class LangDB(OpenAILike):
|
|
11
|
+
"""
|
|
12
|
+
A class for using models hosted on LangDB.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
id (str): The model id. Defaults to "gpt-4o".
|
|
16
|
+
name (str): The model name. Defaults to "LangDB".
|
|
17
|
+
provider (str): The provider name. Defaults to "LangDB".
|
|
18
|
+
api_key (Optional[str]): The API key. Defaults to getenv("LANGDB_API_KEY").
|
|
19
|
+
project_id (Optional[str]): The project id. Defaults to None.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
id: str = "gpt-4o"
|
|
23
|
+
name: str = "LangDB"
|
|
24
|
+
provider: str = "LangDB"
|
|
25
|
+
|
|
26
|
+
api_key: Optional[str] = field(default_factory=lambda: getenv("LANGDB_API_KEY"))
|
|
27
|
+
project_id: Optional[str] = field(default_factory=lambda: getenv("LANGDB_PROJECT_ID"))
|
|
28
|
+
|
|
29
|
+
base_host_url: str = field(default_factory=lambda: getenv("LANGDB_API_BASE_URL", "https://api.us-east-1.langdb.ai"))
|
|
30
|
+
|
|
31
|
+
base_url: Optional[str] = None
|
|
32
|
+
label: Optional[str] = None
|
|
33
|
+
default_headers: Optional[dict] = None
|
|
34
|
+
|
|
35
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
36
|
+
if not self.api_key:
|
|
37
|
+
self.api_key = getenv("LANGDB_API_KEY")
|
|
38
|
+
if not self.api_key:
|
|
39
|
+
raise ModelAuthenticationError(
|
|
40
|
+
message="LANGDB_API_KEY not set. Please set the LANGDB_API_KEY environment variable.",
|
|
41
|
+
model_name=self.name,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if not self.project_id:
|
|
45
|
+
raise ModelAuthenticationError(
|
|
46
|
+
message="LANGDB_PROJECT_ID not set. Please set the LANGDB_PROJECT_ID environment variable.",
|
|
47
|
+
model_name=self.name,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if not self.base_url:
|
|
51
|
+
self.base_url = f"{self.base_host_url}/{self.project_id}/v1"
|
|
52
|
+
|
|
53
|
+
# Initialize headers with label if present
|
|
54
|
+
if self.label and not self.default_headers:
|
|
55
|
+
self.default_headers = {
|
|
56
|
+
"x-label": self.label,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
client_params = super()._get_client_params()
|
|
60
|
+
return client_params
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from agno.models.litellm.chat import LiteLLM
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from agno.models.litellm.litellm_openai import LiteLLMOpenAI
|
|
5
|
+
except ImportError:
|
|
6
|
+
|
|
7
|
+
class LiteLLMOpenAI: # type: ignore
|
|
8
|
+
def __init__(self, *args, **kwargs):
|
|
9
|
+
raise ImportError("`openai` not installed. Please install using `pip install openai`")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"LiteLLM",
|
|
14
|
+
]
|