From 86523dc306d35d3abcbd852c5b462ea5dbc1f476 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:45:05 +0000 Subject: [PATCH] fix: support 'embedder' key as alias for 'embedding_model' in RagTool config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes GitHub issue #4122 where users following the documentation examples using the 'embedder' key were getting OPENAI_API_KEY errors when trying to use non-OpenAI embedding providers like Amazon Bedrock. Changes: - Add 'embedder' key to RagToolConfig TypedDict as alias for 'embedding_model' - Normalize 'embedder' to 'embedding_model' in _validate_config method - Add validation to reject configs with both keys specified - Add tests for embedder key alias and Bedrock embedder configuration Co-Authored-By: João --- .../src/crewai_tools/tools/rag/rag_tool.py | 19 ++- .../src/crewai_tools/tools/rag/types.py | 2 + .../tests/tools/rag/rag_tool_test.py | 110 ++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/lib/crewai-tools/src/crewai_tools/tools/rag/rag_tool.py b/lib/crewai-tools/src/crewai_tools/tools/rag/rag_tool.py index 52fc903e9..6018d671b 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/rag/rag_tool.py +++ b/lib/crewai-tools/src/crewai_tools/tools/rag/rag_tool.py @@ -131,11 +131,28 @@ class RagTool(BaseTool): @field_validator("config", mode="before") @classmethod def _validate_config(cls, value: Any) -> Any: - """Validate config with improved error messages for embedding providers.""" + """Validate config with improved error messages for embedding providers. + + Also normalizes 'embedder' key to 'embedding_model' for backward compatibility + with documentation examples that use the 'embedder' key. + """ if not isinstance(value, dict): return value + embedder = value.get("embedder") embedding_model = value.get("embedding_model") + + if embedder is not None and embedding_model is not None: + raise ValueError( + "Cannot specify both 'embedder' and 'embedding_model' in config. " + "Please use only one of them (they are aliases for the same setting)." + ) + + if embedder is not None: + value["embedding_model"] = embedder + del value["embedder"] + embedding_model = embedder + if embedding_model: try: value["embedding_model"] = _validate_embedding_config(embedding_model) diff --git a/lib/crewai-tools/src/crewai_tools/tools/rag/types.py b/lib/crewai-tools/src/crewai_tools/tools/rag/types.py index 606f86401..3055f645b 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/rag/types.py +++ b/lib/crewai-tools/src/crewai_tools/tools/rag/types.py @@ -65,8 +65,10 @@ class RagToolConfig(TypedDict, total=False): Attributes: embedding_model: Embedding model configuration accepted by RAG tools. + embedder: Alias for embedding_model (for backward compatibility with docs). vectordb: Vector database configuration accepted by RAG tools. """ embedding_model: ProviderSpec + embedder: ProviderSpec vectordb: VectorDbConfig diff --git a/lib/crewai-tools/tests/tools/rag/rag_tool_test.py b/lib/crewai-tools/tests/tools/rag/rag_tool_test.py index 48411699e..1416011c1 100644 --- a/lib/crewai-tools/tests/tools/rag/rag_tool_test.py +++ b/lib/crewai-tools/tests/tools/rag/rag_tool_test.py @@ -299,3 +299,113 @@ def test_rag_tool_config_with_qdrant_and_azure_embeddings( assert tool.adapter is not None assert isinstance(tool.adapter, CrewAIRagAdapter) + + +@patch("crewai_tools.adapters.crewai_rag_adapter.create_client") +def test_rag_tool_with_embedder_key_alias( + mock_create_client: Mock, +) -> None: + """Test that RagTool accepts 'embedder' key as alias for 'embedding_model'. + + This test verifies the fix for GitHub issue #4122 where users following + the documentation examples using 'embedder' key were getting errors. + """ + mock_embedding_func = MagicMock() + mock_embedding_func.return_value = [[0.1] * 1536] + + mock_client = MagicMock() + mock_client.get_or_create_collection = MagicMock(return_value=None) + mock_create_client.return_value = mock_client + + with patch( + "crewai_tools.tools.rag.rag_tool.build_embedder", + return_value=mock_embedding_func, + ): + + class MyTool(RagTool): + pass + + config = { + "embedder": { + "provider": "openai", + "config": { + "model": "text-embedding-3-small", + "api_key": "sk-test123", + }, + } + } + + tool = MyTool(config=config) + + assert tool.adapter is not None + assert isinstance(tool.adapter, CrewAIRagAdapter) + + +@patch("crewai_tools.adapters.crewai_rag_adapter.create_client") +def test_rag_tool_with_bedrock_embedder_config( + mock_create_client: Mock, +) -> None: + """Test RagTool with Amazon Bedrock embedder configuration. + + This test verifies the fix for GitHub issue #4122 where users trying + to use Bedrock embeddings were getting OPENAI_API_KEY errors. + """ + mock_embedding_func = MagicMock() + mock_embedding_func.return_value = [[0.1] * 1536] + + mock_client = MagicMock() + mock_client.get_or_create_collection = MagicMock(return_value=None) + mock_create_client.return_value = mock_client + + with patch( + "crewai_tools.tools.rag.rag_tool.build_embedder", + return_value=mock_embedding_func, + ): + + class MyTool(RagTool): + pass + + config = { + "embedder": { + "provider": "amazon-bedrock", + "config": { + "model_name": "amazon.titan-embed-text-v2:0", + }, + } + } + + tool = MyTool(config=config) + + assert tool.adapter is not None + assert isinstance(tool.adapter, CrewAIRagAdapter) + + +@patch("crewai_tools.adapters.crewai_rag_adapter.create_client") +def test_rag_tool_rejects_both_embedder_and_embedding_model( + mock_create_client: Mock, +) -> None: + """Test that RagTool raises error when both 'embedder' and 'embedding_model' are provided.""" + import pytest + + mock_client = MagicMock() + mock_client.get_or_create_collection = MagicMock(return_value=None) + mock_create_client.return_value = mock_client + + class MyTool(RagTool): + pass + + config = { + "embedder": { + "provider": "openai", + "config": {"model": "text-embedding-3-small"}, + }, + "embedding_model": { + "provider": "openai", + "config": {"model": "text-embedding-3-large"}, + }, + } + + with pytest.raises(ValueError) as exc_info: + MyTool(config=config) + + assert "Cannot specify both 'embedder' and 'embedding_model'" in str(exc_info.value)