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,12 @@
|
|
|
1
|
+
from agno.models.cerebras.cerebras import Cerebras
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from agno.models.cerebras.cerebras_openai import CerebrasOpenAI
|
|
5
|
+
except ImportError:
|
|
6
|
+
|
|
7
|
+
class CerebrasOpenAI: # type: ignore
|
|
8
|
+
def __init__(self, *args, **kwargs):
|
|
9
|
+
raise ImportError("`openai` not installed. Please install it via `pip install openai`")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__all__ = ["Cerebras", "CerebrasOpenAI"]
|
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from collections.abc import AsyncIterator
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from os import getenv
|
|
5
|
+
from typing import Any, Dict, Iterator, List, Optional, Type, Union
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
|
|
10
|
+
from agno.models.base import Model
|
|
11
|
+
from agno.models.message import Message
|
|
12
|
+
from agno.models.metrics import Metrics
|
|
13
|
+
from agno.models.response import ModelResponse
|
|
14
|
+
from agno.run.agent import RunOutput
|
|
15
|
+
from agno.utils.http import get_default_async_client, get_default_sync_client
|
|
16
|
+
from agno.utils.log import log_debug, log_error, log_warning
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from cerebras.cloud.sdk import AsyncCerebras as AsyncCerebrasClient
|
|
20
|
+
from cerebras.cloud.sdk import Cerebras as CerebrasClient
|
|
21
|
+
from cerebras.cloud.sdk.types.chat.chat_completion import (
|
|
22
|
+
ChatChunkResponse,
|
|
23
|
+
ChatChunkResponseChoice,
|
|
24
|
+
ChatChunkResponseChoiceDelta,
|
|
25
|
+
ChatChunkResponseUsage,
|
|
26
|
+
ChatCompletionResponse,
|
|
27
|
+
ChatCompletionResponseChoice,
|
|
28
|
+
ChatCompletionResponseChoiceMessage,
|
|
29
|
+
ChatCompletionResponseUsage,
|
|
30
|
+
)
|
|
31
|
+
except (ImportError, ModuleNotFoundError):
|
|
32
|
+
raise ImportError("`cerebras-cloud-sdk` not installed. Please install using `pip install cerebras-cloud-sdk`")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class Cerebras(Model):
|
|
37
|
+
"""
|
|
38
|
+
A class for interacting with models using the Cerebras API.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
id: str = "llama-4-scout-17b-16e-instruct"
|
|
42
|
+
name: str = "Cerebras"
|
|
43
|
+
provider: str = "Cerebras"
|
|
44
|
+
|
|
45
|
+
supports_native_structured_outputs: bool = False
|
|
46
|
+
supports_json_schema_outputs: bool = True
|
|
47
|
+
|
|
48
|
+
# Request parameters
|
|
49
|
+
parallel_tool_calls: Optional[bool] = None
|
|
50
|
+
max_completion_tokens: Optional[int] = None
|
|
51
|
+
repetition_penalty: Optional[float] = None
|
|
52
|
+
temperature: Optional[float] = None
|
|
53
|
+
top_p: Optional[float] = None
|
|
54
|
+
top_k: Optional[int] = None
|
|
55
|
+
strict_output: bool = True # When True, guarantees schema adherence for structured outputs. When False, attempts to follow schema as a guide but may occasionally deviate
|
|
56
|
+
extra_headers: Optional[Any] = None
|
|
57
|
+
extra_query: Optional[Any] = None
|
|
58
|
+
extra_body: Optional[Any] = None
|
|
59
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
60
|
+
|
|
61
|
+
# Client parameters
|
|
62
|
+
api_key: Optional[str] = None
|
|
63
|
+
base_url: Optional[Union[str, httpx.URL]] = None
|
|
64
|
+
timeout: Optional[float] = None
|
|
65
|
+
max_retries: Optional[int] = None
|
|
66
|
+
default_headers: Optional[Any] = None
|
|
67
|
+
default_query: Optional[Any] = None
|
|
68
|
+
http_client: Optional[Union[httpx.Client, httpx.AsyncClient]] = None
|
|
69
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
70
|
+
|
|
71
|
+
# Cerebras clients
|
|
72
|
+
client: Optional[CerebrasClient] = None
|
|
73
|
+
async_client: Optional[AsyncCerebrasClient] = None
|
|
74
|
+
|
|
75
|
+
def _get_client_params(self) -> Dict[str, Any]:
|
|
76
|
+
# Fetch API key from env if not already set
|
|
77
|
+
if not self.api_key:
|
|
78
|
+
self.api_key = getenv("CEREBRAS_API_KEY")
|
|
79
|
+
if not self.api_key:
|
|
80
|
+
log_error("CEREBRAS_API_KEY not set. Please set the CEREBRAS_API_KEY environment variable.")
|
|
81
|
+
|
|
82
|
+
# Define base client params
|
|
83
|
+
base_params = {
|
|
84
|
+
"api_key": self.api_key,
|
|
85
|
+
"base_url": self.base_url,
|
|
86
|
+
"timeout": self.timeout,
|
|
87
|
+
"max_retries": self.max_retries,
|
|
88
|
+
"default_headers": self.default_headers,
|
|
89
|
+
"default_query": self.default_query,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Create client_params dict with non-None values
|
|
93
|
+
client_params = {k: v for k, v in base_params.items() if v is not None}
|
|
94
|
+
|
|
95
|
+
# Add additional client params if provided
|
|
96
|
+
if self.client_params:
|
|
97
|
+
client_params.update(self.client_params)
|
|
98
|
+
return client_params
|
|
99
|
+
|
|
100
|
+
def get_client(self) -> CerebrasClient:
|
|
101
|
+
"""
|
|
102
|
+
Returns a Cerebras client.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
CerebrasClient: An instance of the Cerebras client.
|
|
106
|
+
"""
|
|
107
|
+
if self.client and not self.client.is_closed():
|
|
108
|
+
return self.client
|
|
109
|
+
|
|
110
|
+
client_params: Dict[str, Any] = self._get_client_params()
|
|
111
|
+
if self.http_client is not None:
|
|
112
|
+
client_params["http_client"] = self.http_client
|
|
113
|
+
else:
|
|
114
|
+
# Use global sync client when no custom http_client is provided
|
|
115
|
+
client_params["http_client"] = get_default_sync_client()
|
|
116
|
+
self.client = CerebrasClient(**client_params)
|
|
117
|
+
return self.client
|
|
118
|
+
|
|
119
|
+
def get_async_client(self) -> AsyncCerebrasClient:
|
|
120
|
+
"""
|
|
121
|
+
Returns an asynchronous Cerebras client.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
AsyncCerebras: An instance of the asynchronous Cerebras client.
|
|
125
|
+
"""
|
|
126
|
+
if self.async_client and not self.async_client.is_closed():
|
|
127
|
+
return self.async_client
|
|
128
|
+
|
|
129
|
+
client_params: Dict[str, Any] = self._get_client_params()
|
|
130
|
+
if self.http_client and isinstance(self.http_client, httpx.AsyncClient):
|
|
131
|
+
client_params["http_client"] = self.http_client
|
|
132
|
+
else:
|
|
133
|
+
# Use global async client when no custom http_client is provided
|
|
134
|
+
client_params["http_client"] = get_default_async_client()
|
|
135
|
+
self.async_client = AsyncCerebrasClient(**client_params)
|
|
136
|
+
return self.async_client
|
|
137
|
+
|
|
138
|
+
def get_request_params(
|
|
139
|
+
self,
|
|
140
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
141
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
142
|
+
**kwargs: Any,
|
|
143
|
+
) -> Dict[str, Any]:
|
|
144
|
+
"""
|
|
145
|
+
Returns keyword arguments for API requests.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Dict[str, Any]: A dictionary of keyword arguments for API requests.
|
|
149
|
+
"""
|
|
150
|
+
# Define base request parameters
|
|
151
|
+
base_params = {
|
|
152
|
+
"max_completion_tokens": self.max_completion_tokens,
|
|
153
|
+
"repetition_penalty": self.repetition_penalty,
|
|
154
|
+
"temperature": self.temperature,
|
|
155
|
+
"top_p": self.top_p,
|
|
156
|
+
"top_k": self.top_k,
|
|
157
|
+
"extra_headers": self.extra_headers,
|
|
158
|
+
"extra_query": self.extra_query,
|
|
159
|
+
"extra_body": self.extra_body,
|
|
160
|
+
"request_params": self.request_params,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Filter out None values
|
|
164
|
+
request_params: Dict[str, Any] = {k: v for k, v in base_params.items() if v is not None}
|
|
165
|
+
|
|
166
|
+
# Add tools
|
|
167
|
+
if tools is not None and len(tools) > 0:
|
|
168
|
+
request_params["tools"] = [
|
|
169
|
+
{
|
|
170
|
+
"type": "function",
|
|
171
|
+
"function": {
|
|
172
|
+
"name": tool["function"]["name"],
|
|
173
|
+
"description": tool["function"]["description"],
|
|
174
|
+
"parameters": tool["function"]["parameters"],
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
for tool in tools
|
|
178
|
+
]
|
|
179
|
+
# Cerebras requires parallel_tool_calls=False for llama-4-scout-17b-16e-instruct
|
|
180
|
+
if self.id == "llama-4-scout-17b-16e-instruct":
|
|
181
|
+
request_params["parallel_tool_calls"] = False
|
|
182
|
+
elif self.parallel_tool_calls is not None:
|
|
183
|
+
request_params["parallel_tool_calls"] = self.parallel_tool_calls
|
|
184
|
+
|
|
185
|
+
# Handle response format for structured outputs
|
|
186
|
+
if response_format is not None:
|
|
187
|
+
if (
|
|
188
|
+
isinstance(response_format, dict)
|
|
189
|
+
and response_format.get("type") == "json_schema"
|
|
190
|
+
and isinstance(response_format.get("json_schema"), dict)
|
|
191
|
+
):
|
|
192
|
+
# Ensure json_schema has strict parameter set
|
|
193
|
+
schema = response_format["json_schema"]
|
|
194
|
+
if isinstance(schema.get("schema"), dict) and "strict" not in schema:
|
|
195
|
+
schema["strict"] = self.strict_output
|
|
196
|
+
|
|
197
|
+
request_params["response_format"] = response_format
|
|
198
|
+
|
|
199
|
+
# Add additional request params if provided
|
|
200
|
+
if self.request_params:
|
|
201
|
+
request_params.update(self.request_params)
|
|
202
|
+
|
|
203
|
+
if request_params:
|
|
204
|
+
log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
|
|
205
|
+
return request_params
|
|
206
|
+
|
|
207
|
+
def invoke(
|
|
208
|
+
self,
|
|
209
|
+
messages: List[Message],
|
|
210
|
+
assistant_message: Message,
|
|
211
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
212
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
213
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
214
|
+
run_response: Optional[RunOutput] = None,
|
|
215
|
+
compress_tool_results: bool = False,
|
|
216
|
+
) -> ModelResponse:
|
|
217
|
+
"""
|
|
218
|
+
Send a chat completion request to the Cerebras API.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
messages (List[Message]): A list of messages to send to the model.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
CompletionResponse: The chat completion response from the API.
|
|
225
|
+
"""
|
|
226
|
+
if run_response and run_response.metrics:
|
|
227
|
+
run_response.metrics.set_time_to_first_token()
|
|
228
|
+
|
|
229
|
+
assistant_message.metrics.start_timer()
|
|
230
|
+
provider_response = self.get_client().chat.completions.create(
|
|
231
|
+
model=self.id,
|
|
232
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
233
|
+
**self.get_request_params(response_format=response_format, tools=tools),
|
|
234
|
+
)
|
|
235
|
+
assistant_message.metrics.stop_timer()
|
|
236
|
+
|
|
237
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format) # type: ignore
|
|
238
|
+
|
|
239
|
+
return model_response
|
|
240
|
+
|
|
241
|
+
async def ainvoke(
|
|
242
|
+
self,
|
|
243
|
+
messages: List[Message],
|
|
244
|
+
assistant_message: Message,
|
|
245
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
246
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
247
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
248
|
+
run_response: Optional[RunOutput] = None,
|
|
249
|
+
compress_tool_results: bool = False,
|
|
250
|
+
) -> ModelResponse:
|
|
251
|
+
"""
|
|
252
|
+
Sends an asynchronous chat completion request to the Cerebras API.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
messages (List[Message]): A list of messages to send to the model.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
ChatCompletion: The chat completion response from the API.
|
|
259
|
+
"""
|
|
260
|
+
if run_response and run_response.metrics:
|
|
261
|
+
run_response.metrics.set_time_to_first_token()
|
|
262
|
+
|
|
263
|
+
assistant_message.metrics.start_timer()
|
|
264
|
+
provider_response = await self.get_async_client().chat.completions.create(
|
|
265
|
+
model=self.id,
|
|
266
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
267
|
+
**self.get_request_params(response_format=response_format, tools=tools),
|
|
268
|
+
)
|
|
269
|
+
assistant_message.metrics.stop_timer()
|
|
270
|
+
|
|
271
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format) # type: ignore
|
|
272
|
+
|
|
273
|
+
return model_response
|
|
274
|
+
|
|
275
|
+
def invoke_stream(
|
|
276
|
+
self,
|
|
277
|
+
messages: List[Message],
|
|
278
|
+
assistant_message: Message,
|
|
279
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
280
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
281
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
282
|
+
run_response: Optional[RunOutput] = None,
|
|
283
|
+
compress_tool_results: bool = False,
|
|
284
|
+
) -> Iterator[ModelResponse]:
|
|
285
|
+
"""
|
|
286
|
+
Send a streaming chat completion request to the Cerebras API.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
messages (List[Message]): A list of messages to send to the model.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Iterator[ChatChunkResponse]: An iterator of chat completion chunks.
|
|
293
|
+
"""
|
|
294
|
+
if run_response and run_response.metrics:
|
|
295
|
+
run_response.metrics.set_time_to_first_token()
|
|
296
|
+
|
|
297
|
+
assistant_message.metrics.start_timer()
|
|
298
|
+
|
|
299
|
+
for chunk in self.get_client().chat.completions.create(
|
|
300
|
+
model=self.id,
|
|
301
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
302
|
+
stream=True,
|
|
303
|
+
**self.get_request_params(response_format=response_format, tools=tools),
|
|
304
|
+
):
|
|
305
|
+
yield self._parse_provider_response_delta(chunk) # type: ignore
|
|
306
|
+
|
|
307
|
+
assistant_message.metrics.stop_timer()
|
|
308
|
+
|
|
309
|
+
async def ainvoke_stream(
|
|
310
|
+
self,
|
|
311
|
+
messages: List[Message],
|
|
312
|
+
assistant_message: Message,
|
|
313
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
314
|
+
tools: Optional[List[Dict[str, Any]]] = None,
|
|
315
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
316
|
+
run_response: Optional[RunOutput] = None,
|
|
317
|
+
compress_tool_results: bool = False,
|
|
318
|
+
) -> AsyncIterator[ModelResponse]:
|
|
319
|
+
"""
|
|
320
|
+
Sends an asynchronous streaming chat completion request to the Cerebras API.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
messages (List[Message]): A list of messages to send to the model.
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
AsyncIterator[ChatChunkResponse]: An asynchronous iterator of chat completion chunks.
|
|
327
|
+
"""
|
|
328
|
+
if run_response and run_response.metrics:
|
|
329
|
+
run_response.metrics.set_time_to_first_token()
|
|
330
|
+
|
|
331
|
+
assistant_message.metrics.start_timer()
|
|
332
|
+
|
|
333
|
+
async_stream = await self.get_async_client().chat.completions.create(
|
|
334
|
+
model=self.id,
|
|
335
|
+
messages=[self._format_message(m, compress_tool_results) for m in messages], # type: ignore
|
|
336
|
+
stream=True,
|
|
337
|
+
**self.get_request_params(response_format=response_format, tools=tools),
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
async for chunk in async_stream: # type: ignore
|
|
341
|
+
yield self._parse_provider_response_delta(chunk) # type: ignore
|
|
342
|
+
|
|
343
|
+
assistant_message.metrics.stop_timer()
|
|
344
|
+
|
|
345
|
+
def _format_message(self, message: Message, compress_tool_results: bool = False) -> Dict[str, Any]:
|
|
346
|
+
"""
|
|
347
|
+
Format a message into the format expected by the Cerebras API.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
message (Message): The message to format.
|
|
351
|
+
compress_tool_results: Whether to compress tool results.
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
Dict[str, Any]: The formatted message.
|
|
355
|
+
"""
|
|
356
|
+
# Use compressed content for tool messages if compression is active
|
|
357
|
+
if message.role == "tool":
|
|
358
|
+
content = message.get_content(use_compressed_content=compress_tool_results)
|
|
359
|
+
else:
|
|
360
|
+
content = message.content if message.content is not None else ""
|
|
361
|
+
|
|
362
|
+
# Basic message content
|
|
363
|
+
message_dict: Dict[str, Any] = {
|
|
364
|
+
"role": message.role,
|
|
365
|
+
"content": content,
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Add name if present
|
|
369
|
+
if message.name:
|
|
370
|
+
message_dict["name"] = message.name
|
|
371
|
+
|
|
372
|
+
# Handle tool calls
|
|
373
|
+
if message.tool_calls:
|
|
374
|
+
# Ensure tool_calls is properly formatted
|
|
375
|
+
message_dict["tool_calls"] = [
|
|
376
|
+
{
|
|
377
|
+
"id": tool_call["id"],
|
|
378
|
+
"type": tool_call["type"],
|
|
379
|
+
"function": {
|
|
380
|
+
"name": tool_call["function"]["name"],
|
|
381
|
+
"arguments": json.dumps(tool_call["function"]["arguments"])
|
|
382
|
+
if isinstance(tool_call["function"]["arguments"], (dict, list))
|
|
383
|
+
else tool_call["function"]["arguments"],
|
|
384
|
+
},
|
|
385
|
+
}
|
|
386
|
+
for tool_call in message.tool_calls
|
|
387
|
+
]
|
|
388
|
+
|
|
389
|
+
# Handle tool responses
|
|
390
|
+
if message.role == "tool" and message.tool_call_id:
|
|
391
|
+
message_dict = {
|
|
392
|
+
"role": "tool",
|
|
393
|
+
"tool_call_id": message.tool_call_id,
|
|
394
|
+
"content": content,
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
# Ensure no None values in the message
|
|
398
|
+
message_dict = {k: v for k, v in message_dict.items() if v is not None}
|
|
399
|
+
|
|
400
|
+
return message_dict
|
|
401
|
+
|
|
402
|
+
def _parse_provider_response(self, response: ChatCompletionResponse, **kwargs) -> ModelResponse:
|
|
403
|
+
"""
|
|
404
|
+
Parse the Cerebras response into a ModelResponse.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
response (CompletionResponse): The response from the Cerebras API.
|
|
408
|
+
|
|
409
|
+
Returns:
|
|
410
|
+
ModelResponse: The parsed response.
|
|
411
|
+
"""
|
|
412
|
+
model_response = ModelResponse()
|
|
413
|
+
|
|
414
|
+
# Get the first choice (assuming single response)
|
|
415
|
+
choice: ChatCompletionResponseChoice = response.choices[0]
|
|
416
|
+
message: ChatCompletionResponseChoiceMessage = choice.message
|
|
417
|
+
|
|
418
|
+
# Add role
|
|
419
|
+
if message.role is not None:
|
|
420
|
+
model_response.role = message.role
|
|
421
|
+
|
|
422
|
+
# Add content
|
|
423
|
+
if message.content is not None:
|
|
424
|
+
model_response.content = message.content
|
|
425
|
+
|
|
426
|
+
# Add tool calls
|
|
427
|
+
if message.tool_calls is not None:
|
|
428
|
+
try:
|
|
429
|
+
model_response.tool_calls = [
|
|
430
|
+
{
|
|
431
|
+
"id": tool_call.id,
|
|
432
|
+
"type": tool_call.type,
|
|
433
|
+
"function": {
|
|
434
|
+
"name": tool_call.function.name,
|
|
435
|
+
"arguments": tool_call.function.arguments,
|
|
436
|
+
},
|
|
437
|
+
}
|
|
438
|
+
for tool_call in message.tool_calls
|
|
439
|
+
]
|
|
440
|
+
except Exception as e:
|
|
441
|
+
log_warning(f"Error processing tool calls: {e}")
|
|
442
|
+
|
|
443
|
+
# Add usage metrics
|
|
444
|
+
if response.usage:
|
|
445
|
+
model_response.response_usage = self._get_metrics(response.usage)
|
|
446
|
+
|
|
447
|
+
return model_response
|
|
448
|
+
|
|
449
|
+
def _parse_provider_response_delta(
|
|
450
|
+
self, response: Union[ChatChunkResponse, ChatCompletionResponse]
|
|
451
|
+
) -> ModelResponse:
|
|
452
|
+
"""
|
|
453
|
+
Parse the streaming response from the Cerebras API into a ModelResponse.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
response (ChatChunkResponse): The streaming response chunk.
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
ModelResponse: The parsed response.
|
|
460
|
+
"""
|
|
461
|
+
model_response = ModelResponse()
|
|
462
|
+
|
|
463
|
+
# Get the first choice (assuming single response)
|
|
464
|
+
if response.choices is not None:
|
|
465
|
+
choice: Union[ChatChunkResponseChoice, ChatCompletionResponseChoice] = response.choices[0]
|
|
466
|
+
choice_delta: ChatChunkResponseChoiceDelta = choice.delta # type: ignore
|
|
467
|
+
|
|
468
|
+
if choice_delta:
|
|
469
|
+
# Add content
|
|
470
|
+
if choice_delta.content:
|
|
471
|
+
model_response.content = choice_delta.content
|
|
472
|
+
|
|
473
|
+
# Add tool calls - preserve index for proper aggregation in parse_tool_calls
|
|
474
|
+
if choice_delta.tool_calls:
|
|
475
|
+
model_response.tool_calls = [
|
|
476
|
+
{
|
|
477
|
+
"index": tool_call.index if hasattr(tool_call, "index") else idx,
|
|
478
|
+
"id": tool_call.id,
|
|
479
|
+
"type": tool_call.type,
|
|
480
|
+
"function": {
|
|
481
|
+
"name": tool_call.function.name if tool_call.function else None,
|
|
482
|
+
"arguments": tool_call.function.arguments if tool_call.function else None,
|
|
483
|
+
},
|
|
484
|
+
}
|
|
485
|
+
for idx, tool_call in enumerate(choice_delta.tool_calls)
|
|
486
|
+
]
|
|
487
|
+
|
|
488
|
+
# Add usage metrics
|
|
489
|
+
if response.usage:
|
|
490
|
+
model_response.response_usage = self._get_metrics(response.usage)
|
|
491
|
+
|
|
492
|
+
return model_response
|
|
493
|
+
|
|
494
|
+
def parse_tool_calls(self, tool_calls_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
495
|
+
"""
|
|
496
|
+
Build complete tool calls from streamed tool call delta data.
|
|
497
|
+
|
|
498
|
+
Cerebras streams tool calls incrementally with partial data in each chunk.
|
|
499
|
+
This method aggregates those chunks by index to produce complete tool calls.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
tool_calls_data: List of tool call deltas from streaming chunks.
|
|
503
|
+
|
|
504
|
+
Returns:
|
|
505
|
+
List[Dict[str, Any]]: List of fully-formed tool call dicts.
|
|
506
|
+
"""
|
|
507
|
+
tool_calls: List[Dict[str, Any]] = []
|
|
508
|
+
|
|
509
|
+
for tool_call_delta in tool_calls_data:
|
|
510
|
+
# Get the index for this tool call (default to 0 if not present)
|
|
511
|
+
index = tool_call_delta.get("index", 0)
|
|
512
|
+
|
|
513
|
+
# Extend the list if needed
|
|
514
|
+
while len(tool_calls) <= index:
|
|
515
|
+
tool_calls.append(
|
|
516
|
+
{
|
|
517
|
+
"id": None,
|
|
518
|
+
"type": None,
|
|
519
|
+
"function": {
|
|
520
|
+
"name": "",
|
|
521
|
+
"arguments": "",
|
|
522
|
+
},
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
tool_call_entry = tool_calls[index]
|
|
527
|
+
|
|
528
|
+
# Update id if present
|
|
529
|
+
if tool_call_delta.get("id"):
|
|
530
|
+
tool_call_entry["id"] = tool_call_delta["id"]
|
|
531
|
+
|
|
532
|
+
# Update type if present
|
|
533
|
+
if tool_call_delta.get("type"):
|
|
534
|
+
tool_call_entry["type"] = tool_call_delta["type"]
|
|
535
|
+
|
|
536
|
+
# Update function name and arguments (concatenate for streaming)
|
|
537
|
+
if tool_call_delta.get("function"):
|
|
538
|
+
func_delta = tool_call_delta["function"]
|
|
539
|
+
if func_delta.get("name"):
|
|
540
|
+
tool_call_entry["function"]["name"] += func_delta["name"]
|
|
541
|
+
if func_delta.get("arguments"):
|
|
542
|
+
tool_call_entry["function"]["arguments"] += func_delta["arguments"]
|
|
543
|
+
|
|
544
|
+
# Filter out any incomplete tool calls (missing id or function name)
|
|
545
|
+
complete_tool_calls = [tc for tc in tool_calls if tc.get("id") and tc.get("function", {}).get("name")]
|
|
546
|
+
|
|
547
|
+
return complete_tool_calls
|
|
548
|
+
|
|
549
|
+
def _get_metrics(self, response_usage: Union[ChatCompletionResponseUsage, ChatChunkResponseUsage]) -> Metrics:
|
|
550
|
+
"""
|
|
551
|
+
Parse the given Cerebras usage into an Agno Metrics object.
|
|
552
|
+
|
|
553
|
+
Args:
|
|
554
|
+
response_usage: Usage data from Cerebras
|
|
555
|
+
|
|
556
|
+
Returns:
|
|
557
|
+
Metrics: Parsed metrics data
|
|
558
|
+
"""
|
|
559
|
+
metrics = Metrics()
|
|
560
|
+
|
|
561
|
+
metrics.input_tokens = response_usage.prompt_tokens or 0
|
|
562
|
+
metrics.output_tokens = response_usage.completion_tokens or 0
|
|
563
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
|
|
564
|
+
|
|
565
|
+
return metrics
|