agno 2.3.4__py3-none-any.whl → 2.3.6__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.
Files changed (116) hide show
  1. agno/agent/agent.py +184 -45
  2. agno/culture/manager.py +2 -2
  3. agno/db/base.py +330 -8
  4. agno/db/dynamo/dynamo.py +722 -2
  5. agno/db/dynamo/schemas.py +127 -0
  6. agno/db/firestore/firestore.py +573 -1
  7. agno/db/firestore/schemas.py +40 -0
  8. agno/db/gcs_json/gcs_json_db.py +446 -1
  9. agno/db/in_memory/in_memory_db.py +143 -1
  10. agno/db/json/json_db.py +438 -1
  11. agno/db/mongo/async_mongo.py +522 -0
  12. agno/db/mongo/mongo.py +523 -1
  13. agno/db/mongo/schemas.py +29 -0
  14. agno/db/mysql/mysql.py +536 -3
  15. agno/db/mysql/schemas.py +38 -0
  16. agno/db/postgres/async_postgres.py +553 -15
  17. agno/db/postgres/postgres.py +544 -5
  18. agno/db/postgres/schemas.py +38 -0
  19. agno/db/redis/redis.py +468 -1
  20. agno/db/redis/schemas.py +32 -0
  21. agno/db/singlestore/schemas.py +38 -0
  22. agno/db/singlestore/singlestore.py +523 -1
  23. agno/db/sqlite/async_sqlite.py +549 -10
  24. agno/db/sqlite/schemas.py +38 -0
  25. agno/db/sqlite/sqlite.py +540 -9
  26. agno/db/sqlite/utils.py +6 -8
  27. agno/db/surrealdb/models.py +25 -0
  28. agno/db/surrealdb/surrealdb.py +548 -1
  29. agno/eval/accuracy.py +18 -8
  30. agno/eval/performance.py +10 -4
  31. agno/eval/reliability.py +22 -13
  32. agno/exceptions.py +11 -0
  33. agno/hooks/__init__.py +3 -0
  34. agno/hooks/decorator.py +164 -0
  35. agno/integrations/discord/client.py +1 -1
  36. agno/knowledge/chunking/semantic.py +2 -2
  37. agno/models/aimlapi/aimlapi.py +2 -3
  38. agno/models/anthropic/claude.py +18 -13
  39. agno/models/aws/bedrock.py +3 -4
  40. agno/models/aws/claude.py +5 -1
  41. agno/models/azure/ai_foundry.py +2 -2
  42. agno/models/azure/openai_chat.py +8 -0
  43. agno/models/cerebras/cerebras.py +62 -11
  44. agno/models/cerebras/cerebras_openai.py +2 -3
  45. agno/models/cohere/chat.py +1 -5
  46. agno/models/cometapi/cometapi.py +2 -3
  47. agno/models/dashscope/dashscope.py +2 -3
  48. agno/models/deepinfra/deepinfra.py +2 -3
  49. agno/models/deepseek/deepseek.py +2 -3
  50. agno/models/fireworks/fireworks.py +2 -3
  51. agno/models/google/gemini.py +9 -7
  52. agno/models/groq/groq.py +2 -3
  53. agno/models/huggingface/huggingface.py +1 -5
  54. agno/models/ibm/watsonx.py +1 -5
  55. agno/models/internlm/internlm.py +2 -3
  56. agno/models/langdb/langdb.py +6 -4
  57. agno/models/litellm/chat.py +2 -2
  58. agno/models/litellm/litellm_openai.py +2 -3
  59. agno/models/meta/llama.py +1 -5
  60. agno/models/meta/llama_openai.py +4 -5
  61. agno/models/mistral/mistral.py +1 -5
  62. agno/models/nebius/nebius.py +2 -3
  63. agno/models/nvidia/nvidia.py +4 -5
  64. agno/models/openai/chat.py +14 -3
  65. agno/models/openai/responses.py +14 -3
  66. agno/models/openrouter/openrouter.py +4 -5
  67. agno/models/perplexity/perplexity.py +2 -3
  68. agno/models/portkey/portkey.py +7 -6
  69. agno/models/requesty/requesty.py +4 -5
  70. agno/models/response.py +2 -1
  71. agno/models/sambanova/sambanova.py +4 -5
  72. agno/models/siliconflow/siliconflow.py +3 -4
  73. agno/models/together/together.py +4 -5
  74. agno/models/vercel/v0.py +4 -5
  75. agno/models/vllm/vllm.py +19 -14
  76. agno/models/xai/xai.py +4 -5
  77. agno/os/app.py +104 -0
  78. agno/os/config.py +13 -0
  79. agno/os/interfaces/whatsapp/router.py +0 -1
  80. agno/os/interfaces/whatsapp/security.py +3 -1
  81. agno/os/mcp.py +1 -0
  82. agno/os/router.py +31 -0
  83. agno/os/routers/traces/__init__.py +3 -0
  84. agno/os/routers/traces/schemas.py +414 -0
  85. agno/os/routers/traces/traces.py +499 -0
  86. agno/os/schema.py +12 -2
  87. agno/os/utils.py +57 -0
  88. agno/run/agent.py +1 -0
  89. agno/run/base.py +17 -0
  90. agno/run/team.py +4 -0
  91. agno/table.py +10 -0
  92. agno/team/team.py +221 -69
  93. agno/tools/function.py +10 -8
  94. agno/tools/google_drive.py +4 -3
  95. agno/tools/nano_banana.py +1 -1
  96. agno/tools/spotify.py +922 -0
  97. agno/tracing/__init__.py +12 -0
  98. agno/tracing/exporter.py +157 -0
  99. agno/tracing/schemas.py +276 -0
  100. agno/tracing/setup.py +111 -0
  101. agno/utils/agent.py +6 -6
  102. agno/utils/hooks.py +56 -1
  103. agno/utils/mcp.py +1 -1
  104. agno/vectordb/qdrant/qdrant.py +22 -22
  105. agno/workflow/condition.py +8 -0
  106. agno/workflow/loop.py +8 -0
  107. agno/workflow/parallel.py +8 -0
  108. agno/workflow/router.py +8 -0
  109. agno/workflow/step.py +20 -0
  110. agno/workflow/steps.py +8 -0
  111. agno/workflow/workflow.py +88 -19
  112. {agno-2.3.4.dist-info → agno-2.3.6.dist-info}/METADATA +38 -33
  113. {agno-2.3.4.dist-info → agno-2.3.6.dist-info}/RECORD +116 -105
  114. {agno-2.3.4.dist-info → agno-2.3.6.dist-info}/WHEEL +0 -0
  115. {agno-2.3.4.dist-info → agno-2.3.6.dist-info}/licenses/LICENSE +0 -0
  116. {agno-2.3.4.dist-info → agno-2.3.6.dist-info}/top_level.txt +0 -0
@@ -7,14 +7,13 @@ from typing import Any, Dict, Iterator, List, Optional, Type, Union
7
7
  import httpx
8
8
  from pydantic import BaseModel
9
9
 
10
- from agno.exceptions import ModelProviderError
11
10
  from agno.models.base import Model
12
11
  from agno.models.message import Message
13
12
  from agno.models.metrics import Metrics
14
13
  from agno.models.response import ModelResponse
15
14
  from agno.run.agent import RunOutput
16
15
  from agno.utils.http import get_default_async_client, get_default_sync_client
17
- from agno.utils.log import log_debug, log_warning
16
+ from agno.utils.log import log_debug, log_error, log_warning
18
17
 
19
18
  try:
20
19
  from cerebras.cloud.sdk import AsyncCerebras as AsyncCerebrasClient
@@ -78,11 +77,7 @@ class Cerebras(Model):
78
77
  if not self.api_key:
79
78
  self.api_key = getenv("CEREBRAS_API_KEY")
80
79
  if not self.api_key:
81
- raise ModelProviderError(
82
- message="CEREBRAS_API_KEY not set. Please set the CEREBRAS_API_KEY environment variable.",
83
- model_name=self.name,
84
- model_id=self.id,
85
- )
80
+ log_error("CEREBRAS_API_KEY not set. Please set the CEREBRAS_API_KEY environment variable.")
86
81
 
87
82
  # Define base client params
88
83
  base_params = {
@@ -475,18 +470,19 @@ class Cerebras(Model):
475
470
  if choice_delta.content:
476
471
  model_response.content = choice_delta.content
477
472
 
478
- # Add tool calls
473
+ # Add tool calls - preserve index for proper aggregation in parse_tool_calls
479
474
  if choice_delta.tool_calls:
480
475
  model_response.tool_calls = [
481
476
  {
477
+ "index": tool_call.index if hasattr(tool_call, "index") else idx,
482
478
  "id": tool_call.id,
483
479
  "type": tool_call.type,
484
480
  "function": {
485
- "name": tool_call.function.name,
486
- "arguments": tool_call.function.arguments,
481
+ "name": tool_call.function.name if tool_call.function else None,
482
+ "arguments": tool_call.function.arguments if tool_call.function else None,
487
483
  },
488
484
  }
489
- for tool_call in choice_delta.tool_calls
485
+ for idx, tool_call in enumerate(choice_delta.tool_calls)
490
486
  ]
491
487
 
492
488
  # Add usage metrics
@@ -495,6 +491,61 @@ class Cerebras(Model):
495
491
 
496
492
  return model_response
497
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
+
498
549
  def _get_metrics(self, response_usage: Union[ChatCompletionResponseUsage, ChatChunkResponseUsage]) -> Metrics:
499
550
  """
500
551
  Parse the given Cerebras usage into an Agno Metrics object.
@@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional, Type, Union
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
8
- from agno.exceptions import ModelProviderError
8
+ from agno.exceptions import ModelAuthenticationError
9
9
  from agno.models.message import Message
10
10
  from agno.models.openai.like import OpenAILike
11
11
  from agno.utils.log import log_debug
@@ -31,10 +31,9 @@ class CerebrasOpenAI(OpenAILike):
31
31
  if not self.api_key:
32
32
  self.api_key = getenv("CEREBRAS_API_KEY")
33
33
  if not self.api_key:
34
- raise ModelProviderError(
34
+ raise ModelAuthenticationError(
35
35
  message="CEREBRAS_API_KEY not set. Please set the CEREBRAS_API_KEY environment variable.",
36
36
  model_name=self.name,
37
- model_id=self.id,
38
37
  )
39
38
  return super()._get_client_params()
40
39
 
@@ -65,11 +65,7 @@ class Cohere(Model):
65
65
 
66
66
  self.api_key = self.api_key or getenv("CO_API_KEY")
67
67
  if not self.api_key:
68
- raise ModelProviderError(
69
- message="CO_API_KEY not set. Please set the CO_API_KEY environment variable.",
70
- model_name=self.name,
71
- model_id=self.id,
72
- )
68
+ log_error("CO_API_KEY not set. Please set the CO_API_KEY environment variable.")
73
69
 
74
70
  _client_params["api_key"] = self.api_key
75
71
 
@@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional
4
4
 
5
5
  import httpx
6
6
 
7
- from agno.exceptions import ModelProviderError
7
+ from agno.exceptions import ModelAuthenticationError
8
8
  from agno.models.openai.like import OpenAILike
9
9
  from agno.utils.log import log_debug
10
10
 
@@ -37,10 +37,9 @@ class CometAPI(OpenAILike):
37
37
  if not self.api_key:
38
38
  self.api_key = getenv("COMETAPI_KEY")
39
39
  if not self.api_key:
40
- raise ModelProviderError(
40
+ raise ModelAuthenticationError(
41
41
  message="COMETAPI_KEY not set. Please set the COMETAPI_KEY environment variable.",
42
42
  model_name=self.name,
43
- model_id=self.id,
44
43
  )
45
44
  return super()._get_client_params()
46
45
 
@@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
- from agno.exceptions import ModelProviderError
7
+ from agno.exceptions import ModelAuthenticationError
8
8
  from agno.models.openai.like import OpenAILike
9
9
 
10
10
 
@@ -43,10 +43,9 @@ class DashScope(OpenAILike):
43
43
  if not self.api_key:
44
44
  self.api_key = getenv("DASHSCOPE_API_KEY")
45
45
  if not self.api_key:
46
- raise ModelProviderError(
46
+ raise ModelAuthenticationError(
47
47
  message="DASHSCOPE_API_KEY not set. Please set the DASHSCOPE_API_KEY environment variable.",
48
48
  model_name=self.name,
49
- model_id=self.id,
50
49
  )
51
50
 
52
51
  # Define base client params
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -38,9 +38,8 @@ class DeepInfra(OpenAILike):
38
38
  if not self.api_key:
39
39
  self.api_key = getenv("DEEPINFRA_API_KEY")
40
40
  if not self.api_key:
41
- raise ModelProviderError(
41
+ raise ModelAuthenticationError(
42
42
  message="DEEPINFRA_API_KEY not set. Please set the DEEPINFRA_API_KEY environment variable.",
43
43
  model_name=self.name,
44
- model_id=self.id,
45
44
  )
46
45
  return super()._get_client_params()
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -35,10 +35,9 @@ class DeepSeek(OpenAILike):
35
35
  self.api_key = getenv("DEEPSEEK_API_KEY")
36
36
  if not self.api_key:
37
37
  # Raise error immediately if key is missing
38
- raise ModelProviderError(
38
+ raise ModelAuthenticationError(
39
39
  message="DEEPSEEK_API_KEY not set. Please set the DEEPSEEK_API_KEY environment variable.",
40
40
  model_name=self.name,
41
- model_id=self.id,
42
41
  )
43
42
 
44
43
  # Define base client params
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai import OpenAILike
7
7
 
8
8
 
@@ -36,9 +36,8 @@ class Fireworks(OpenAILike):
36
36
  if not self.api_key:
37
37
  self.api_key = getenv("FIREWORKS_API_KEY")
38
38
  if not self.api_key:
39
- raise ModelProviderError(
39
+ raise ModelAuthenticationError(
40
40
  message="FIREWORKS_API_KEY not set. Please set the FIREWORKS_API_KEY environment variable.",
41
41
  model_name=self.name,
42
- model_id=self.id,
43
42
  )
44
43
  return super()._get_client_params()
@@ -141,17 +141,19 @@ class Gemini(Model):
141
141
  if not vertexai:
142
142
  self.api_key = self.api_key or getenv("GOOGLE_API_KEY")
143
143
  if not self.api_key:
144
- raise ModelProviderError(
145
- message="GOOGLE_API_KEY not set. Please set the GOOGLE_API_KEY environment variable.",
146
- model_name=self.name,
147
- model_id=self.id,
148
- )
144
+ log_error("GOOGLE_API_KEY not set. Please set the GOOGLE_API_KEY environment variable.")
149
145
  client_params["api_key"] = self.api_key
150
146
  else:
151
147
  log_info("Using Vertex AI API")
152
148
  client_params["vertexai"] = True
153
- client_params["project"] = self.project_id or getenv("GOOGLE_CLOUD_PROJECT")
154
- client_params["location"] = self.location or getenv("GOOGLE_CLOUD_LOCATION")
149
+ project_id = self.project_id or getenv("GOOGLE_CLOUD_PROJECT")
150
+ if not project_id:
151
+ log_error("GOOGLE_CLOUD_PROJECT not set. Please set the GOOGLE_CLOUD_PROJECT environment variable.")
152
+ location = self.location or getenv("GOOGLE_CLOUD_LOCATION")
153
+ if not location:
154
+ log_error("GOOGLE_CLOUD_LOCATION not set. Please set the GOOGLE_CLOUD_LOCATION environment variable.")
155
+ client_params["project"] = project_id
156
+ client_params["location"] = location
155
157
 
156
158
  client_params = {k: v for k, v in client_params.items() if v is not None}
157
159
 
agno/models/groq/groq.py CHANGED
@@ -6,7 +6,7 @@ from typing import Any, Dict, Iterator, List, Optional, Type, Union
6
6
  import httpx
7
7
  from pydantic import BaseModel
8
8
 
9
- from agno.exceptions import ModelProviderError
9
+ from agno.exceptions import ModelAuthenticationError, ModelProviderError
10
10
  from agno.models.base import Model
11
11
  from agno.models.message import Message
12
12
  from agno.models.metrics import Metrics
@@ -74,10 +74,9 @@ class Groq(Model):
74
74
  if not self.api_key:
75
75
  self.api_key = getenv("GROQ_API_KEY")
76
76
  if not self.api_key:
77
- raise ModelProviderError(
77
+ raise ModelAuthenticationError(
78
78
  message="GROQ_API_KEY not set. Please set the GROQ_API_KEY environment variable.",
79
79
  model_name=self.name,
80
- model_id=self.id,
81
80
  )
82
81
 
83
82
  # Define base client params
@@ -73,11 +73,7 @@ class HuggingFace(Model):
73
73
  def get_client_params(self) -> Dict[str, Any]:
74
74
  self.api_key = self.api_key or getenv("HF_TOKEN")
75
75
  if not self.api_key:
76
- raise ModelProviderError(
77
- message="HF_TOKEN not set. Please set the HF_TOKEN environment variable.",
78
- model_name=self.name,
79
- model_id=self.id,
80
- )
76
+ log_error("HF_TOKEN not set. Please set the HF_TOKEN environment variable.")
81
77
 
82
78
  _client_params: Dict[str, Any] = {}
83
79
  if self.api_key is not None:
@@ -59,11 +59,7 @@ class WatsonX(Model):
59
59
  # Fetch API key and project ID from env if not already set
60
60
  self.api_key = self.api_key or getenv("IBM_WATSONX_API_KEY")
61
61
  if not self.api_key:
62
- raise ModelProviderError(
63
- message="IBM_WATSONX_API_KEY not set. Please set the IBM_WATSONX_API_KEY environment variable.",
64
- model_name=self.name,
65
- model_id=self.id,
66
- )
62
+ log_error("IBM_WATSONX_API_KEY not set. Please set the IBM_WATSONX_API_KEY environment variable.")
67
63
 
68
64
  self.project_id = self.project_id or getenv("IBM_WATSONX_PROJECT_ID")
69
65
  if not self.project_id:
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -36,9 +36,8 @@ class InternLM(OpenAILike):
36
36
  if not self.api_key:
37
37
  self.api_key = getenv("INTERNLM_API_KEY")
38
38
  if not self.api_key:
39
- raise ModelProviderError(
39
+ raise ModelAuthenticationError(
40
40
  message="INTERNLM_API_KEY not set. Please set the INTERNLM_API_KEY environment variable.",
41
41
  model_name=self.name,
42
- model_id=self.id,
43
42
  )
44
43
  return super()._get_client_params()
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -36,14 +36,16 @@ class LangDB(OpenAILike):
36
36
  if not self.api_key:
37
37
  self.api_key = getenv("LANGDB_API_KEY")
38
38
  if not self.api_key:
39
- raise ModelProviderError(
39
+ raise ModelAuthenticationError(
40
40
  message="LANGDB_API_KEY not set. Please set the LANGDB_API_KEY environment variable.",
41
41
  model_name=self.name,
42
- model_id=self.id,
43
42
  )
44
43
 
45
44
  if not self.project_id:
46
- raise ValueError("LANGDB_PROJECT_ID not set in the environment")
45
+ raise ModelAuthenticationError(
46
+ message="LANGDB_PROJECT_ID not set. Please set the LANGDB_PROJECT_ID environment variable.",
47
+ model_name=self.name,
48
+ )
47
49
 
48
50
  if not self.base_url:
49
51
  self.base_url = f"{self.base_host_url}/{self.project_id}/v1"
@@ -57,8 +57,8 @@ class LiteLLM(Model):
57
57
  # Check for other present valid keys, e.g. OPENAI_API_KEY if self.id is an OpenAI model
58
58
  env_validation = validate_environment(model=self.id, api_base=self.api_base)
59
59
  if not env_validation.get("keys_in_environment"):
60
- log_warning(
61
- "Missing required key. Please set the LITELLM_API_KEY or other valid environment variables."
60
+ log_error(
61
+ "LITELLM_API_KEY not set. Please set the LITELLM_API_KEY or other valid environment variables."
62
62
  )
63
63
 
64
64
  def get_client(self) -> Any:
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -35,9 +35,8 @@ class LiteLLMOpenAI(OpenAILike):
35
35
  if not self.api_key:
36
36
  self.api_key = getenv("LITELLM_API_KEY")
37
37
  if not self.api_key:
38
- raise ModelProviderError(
38
+ raise ModelAuthenticationError(
39
39
  message="LITELLM_API_KEY not set. Please set the LITELLM_API_KEY environment variable.",
40
40
  model_name=self.name,
41
- model_id=self.id,
42
41
  )
43
42
  return super()._get_client_params()
agno/models/meta/llama.py CHANGED
@@ -74,11 +74,7 @@ class Llama(Model):
74
74
  if not self.api_key:
75
75
  self.api_key = getenv("LLAMA_API_KEY")
76
76
  if not self.api_key:
77
- raise ModelProviderError(
78
- message="LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.",
79
- model_name=self.name,
80
- model_id=self.id,
81
- )
77
+ log_error("LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.")
82
78
 
83
79
  # Define base client params
84
80
  base_params = {
@@ -1,4 +1,4 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
@@ -7,7 +7,7 @@ try:
7
7
  except ImportError:
8
8
  raise ImportError("`openai` not installed. Please install using `pip install openai`")
9
9
 
10
- from agno.exceptions import ModelProviderError
10
+ from agno.exceptions import ModelAuthenticationError
11
11
  from agno.models.meta.llama import Message
12
12
  from agno.models.openai.like import OpenAILike
13
13
  from agno.utils.models.llama import format_message
@@ -30,7 +30,7 @@ class LlamaOpenAI(OpenAILike):
30
30
  name: str = "LlamaOpenAI"
31
31
  provider: str = "LlamaOpenAI"
32
32
 
33
- api_key: Optional[str] = field(default_factory=lambda: getenv("LLAMA_API_KEY"))
33
+ api_key: Optional[str] = None
34
34
  base_url: Optional[str] = "https://api.llama.com/compat/v1/"
35
35
 
36
36
  # Request parameters
@@ -60,10 +60,9 @@ class LlamaOpenAI(OpenAILike):
60
60
  if not self.api_key:
61
61
  self.api_key = getenv("LLAMA_API_KEY")
62
62
  if not self.api_key:
63
- raise ModelProviderError(
63
+ raise ModelAuthenticationError(
64
64
  message="LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.",
65
65
  model_name=self.name,
66
- model_id=self.id,
67
66
  )
68
67
  return super()._get_client_params()
69
68
 
@@ -94,11 +94,7 @@ class MistralChat(Model):
94
94
 
95
95
  self.api_key = self.api_key or getenv("MISTRAL_API_KEY")
96
96
  if not self.api_key:
97
- raise ModelProviderError(
98
- message="MISTRAL_API_KEY not set. Please set the MISTRAL_API_KEY environment variable.",
99
- model_name=self.name,
100
- model_id=self.id,
101
- )
97
+ log_error("MISTRAL_API_KEY not set. Please set the MISTRAL_API_KEY environment variable.")
102
98
 
103
99
  client_params.update(
104
100
  {
@@ -2,7 +2,7 @@ from dataclasses import dataclass, field
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -28,10 +28,9 @@ class Nebius(OpenAILike):
28
28
 
29
29
  def _get_client_params(self) -> Dict[str, Any]:
30
30
  if not self.api_key:
31
- raise ModelProviderError(
31
+ raise ModelAuthenticationError(
32
32
  message="NEBIUS_API_KEY not set. Please set the NEBIUS_API_KEY environment variable.",
33
33
  model_name=self.name,
34
- model_id=self.id,
35
34
  )
36
35
 
37
36
  # Define base client params
@@ -1,8 +1,8 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
 
@@ -23,7 +23,7 @@ class Nvidia(OpenAILike):
23
23
  name: str = "Nvidia"
24
24
  provider: str = "Nvidia"
25
25
 
26
- api_key: Optional[str] = field(default_factory=lambda: getenv("NVIDIA_API_KEY"))
26
+ api_key: Optional[str] = None
27
27
  base_url: str = "https://integrate.api.nvidia.com/v1"
28
28
 
29
29
  supports_native_structured_outputs: bool = False
@@ -38,9 +38,8 @@ class Nvidia(OpenAILike):
38
38
  if not self.api_key:
39
39
  self.api_key = getenv("NVIDIA_API_KEY")
40
40
  if not self.api_key:
41
- raise ModelProviderError(
41
+ raise ModelAuthenticationError(
42
42
  message="NVIDIA_API_KEY not set. Please set the NVIDIA_API_KEY environment variable.",
43
43
  model_name=self.name,
44
- model_id=self.id,
45
44
  )
46
45
  return super()._get_client_params()
@@ -7,7 +7,7 @@ from uuid import uuid4
7
7
  import httpx
8
8
  from pydantic import BaseModel
9
9
 
10
- from agno.exceptions import ModelProviderError
10
+ from agno.exceptions import ModelAuthenticationError, ModelProviderError
11
11
  from agno.media import Audio
12
12
  from agno.models.base import Model
13
13
  from agno.models.message import Message
@@ -102,10 +102,9 @@ class OpenAIChat(Model):
102
102
  if not self.api_key:
103
103
  self.api_key = getenv("OPENAI_API_KEY")
104
104
  if not self.api_key:
105
- raise ModelProviderError(
105
+ raise ModelAuthenticationError(
106
106
  message="OPENAI_API_KEY not set. Please set the OPENAI_API_KEY environment variable.",
107
107
  model_name=self.name,
108
- model_id=self.id,
109
108
  )
110
109
 
111
110
  # Define base client params
@@ -451,6 +450,9 @@ class OpenAIChat(Model):
451
450
  model_name=self.name,
452
451
  model_id=self.id,
453
452
  ) from e
453
+ except ModelAuthenticationError as e:
454
+ log_error(f"Model authentication error from OpenAI API: {e}")
455
+ raise e
454
456
  except Exception as e:
455
457
  log_error(f"Error from OpenAI API: {e}")
456
458
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -532,6 +534,9 @@ class OpenAIChat(Model):
532
534
  model_name=self.name,
533
535
  model_id=self.id,
534
536
  ) from e
537
+ except ModelAuthenticationError as e:
538
+ log_error(f"Model authentication error from OpenAI API: {e}")
539
+ raise e
535
540
  except Exception as e:
536
541
  log_error(f"Error from OpenAI API: {e}")
537
542
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -610,6 +615,9 @@ class OpenAIChat(Model):
610
615
  model_name=self.name,
611
616
  model_id=self.id,
612
617
  ) from e
618
+ except ModelAuthenticationError as e:
619
+ log_error(f"Model authentication error from OpenAI API: {e}")
620
+ raise e
613
621
  except Exception as e:
614
622
  log_error(f"Error from OpenAI API: {e}")
615
623
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -690,6 +698,9 @@ class OpenAIChat(Model):
690
698
  model_name=self.name,
691
699
  model_id=self.id,
692
700
  ) from e
701
+ except ModelAuthenticationError as e:
702
+ log_error(f"Model authentication error from OpenAI API: {e}")
703
+ raise e
693
704
  except Exception as e:
694
705
  log_error(f"Error from OpenAI API: {e}")
695
706
  raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
@@ -6,7 +6,7 @@ import httpx
6
6
  from pydantic import BaseModel
7
7
  from typing_extensions import Literal
8
8
 
9
- from agno.exceptions import ModelProviderError
9
+ from agno.exceptions import ModelAuthenticationError, ModelProviderError
10
10
  from agno.media import File
11
11
  from agno.models.base import Model
12
12
  from agno.models.message import Citations, Message, UrlCitation
@@ -117,10 +117,9 @@ class OpenAIResponses(Model):
117
117
  if not self.api_key:
118
118
  self.api_key = getenv("OPENAI_API_KEY")
119
119
  if not self.api_key:
120
- raise ModelProviderError(
120
+ raise ModelAuthenticationError(
121
121
  message="OPENAI_API_KEY not set. Please set the OPENAI_API_KEY environment variable.",
122
122
  model_name=self.name,
123
- model_id=self.id,
124
123
  )
125
124
 
126
125
  # Define base client params
@@ -586,6 +585,9 @@ class OpenAIResponses(Model):
586
585
  model_name=self.name,
587
586
  model_id=self.id,
588
587
  ) from exc
588
+ except ModelAuthenticationError as exc:
589
+ log_error(f"Model authentication error from OpenAI API: {exc}")
590
+ raise exc
589
591
  except Exception as exc:
590
592
  log_error(f"Error from OpenAI API: {exc}")
591
593
  raise ModelProviderError(message=str(exc), model_name=self.name, model_id=self.id) from exc
@@ -656,6 +658,9 @@ class OpenAIResponses(Model):
656
658
  model_name=self.name,
657
659
  model_id=self.id,
658
660
  ) from exc
661
+ except ModelAuthenticationError as exc:
662
+ log_error(f"Model authentication error from OpenAI API: {exc}")
663
+ raise exc
659
664
  except Exception as exc:
660
665
  log_error(f"Error from OpenAI API: {exc}")
661
666
  raise ModelProviderError(message=str(exc), model_name=self.name, model_id=self.id) from exc
@@ -730,6 +735,9 @@ class OpenAIResponses(Model):
730
735
  model_name=self.name,
731
736
  model_id=self.id,
732
737
  ) from exc
738
+ except ModelAuthenticationError as exc:
739
+ log_error(f"Model authentication error from OpenAI API: {exc}")
740
+ raise exc
733
741
  except Exception as exc:
734
742
  log_error(f"Error from OpenAI API: {exc}")
735
743
  raise ModelProviderError(message=str(exc), model_name=self.name, model_id=self.id) from exc
@@ -801,6 +809,9 @@ class OpenAIResponses(Model):
801
809
  model_name=self.name,
802
810
  model_id=self.id,
803
811
  ) from exc
812
+ except ModelAuthenticationError as exc:
813
+ log_error(f"Model authentication error from OpenAI API: {exc}")
814
+ raise exc
804
815
  except Exception as exc:
805
816
  log_error(f"Error from OpenAI API: {exc}")
806
817
  raise ModelProviderError(message=str(exc), model_name=self.name, model_id=self.id) from exc