Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crawl4ai tool refactoring #1070

Merged
merged 9 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 20 additions & 30 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -143,23 +143,23 @@
"filename": "autogen/oai/openai_utils.py",
"hashed_secret": "aa5bc2e0df7182f74186f26d6e9063b9d57603ec",
"is_verified": false,
"line_number": 353,
"line_number": 378,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "autogen/oai/openai_utils.py",
"hashed_secret": "cbb43d092552e9af4b21efc76bc8c49c071c1d81",
"is_verified": false,
"line_number": 354,
"line_number": 379,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "autogen/oai/openai_utils.py",
"hashed_secret": "79d8b9da0f827f788759bdbe5b9254a02c74d877",
"is_verified": false,
"line_number": 577,
"line_number": 602,
"is_secret": false
}
],
Expand Down Expand Up @@ -1035,127 +1035,127 @@
"filename": "test/oai/test_utils.py",
"hashed_secret": "f72c85879027f6160ce36e1c5074ef8207bfe105",
"is_verified": false,
"line_number": 30,
"line_number": 31,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "4c88039c5079180dacb0e29d715055d95b2b7589",
"is_verified": false,
"line_number": 39,
"line_number": 40,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "7460e665be1988cc62f1caf9d47716b07d55858c",
"is_verified": false,
"line_number": 69,
"line_number": 70,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "b5c2827eb65bf13b87130e7e3c424ba9ff07cd67",
"is_verified": false,
"line_number": 76,
"line_number": 77,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "178c7a21b087dfafc826a21b61aff284c71fd258",
"is_verified": false,
"line_number": 202,
"line_number": 203,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "aa5c90e1b80bb987f562ac30eaa1a71c832892f5",
"is_verified": false,
"line_number": 203,
"line_number": 204,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "4489f55309f29853a4075cbbdf1f18b584809726",
"is_verified": false,
"line_number": 205,
"line_number": 206,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "95cfb33d5e102631e226e7ff9da4b17d6ba5f3e4",
"is_verified": false,
"line_number": 217,
"line_number": 218,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "7943297a6a2188abe697bd1e0189fdd1274818be",
"is_verified": false,
"line_number": 219,
"line_number": 220,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "8cc86c45479a8e0bbb1ddea57d3e195b611241f2",
"is_verified": false,
"line_number": 239,
"line_number": 240,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "eda6571eea7bd0ac4553ac9d745631f1f2bec7a4",
"is_verified": false,
"line_number": 241,
"line_number": 242,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "0ad02c88ffd9754bfbfc24ade0bf8bc48d76b232",
"is_verified": false,
"line_number": 250,
"line_number": 251,
"is_secret": false
},
{
"type": "Secret Keyword",
"filename": "test/oai/test_utils.py",
"hashed_secret": "11841233da3f9f37c5fa14e8b482dde913db6edf",
"is_verified": false,
"line_number": 258,
"line_number": 259,
"is_secret": false
},
{
"type": "Base64 High Entropy String",
"filename": "test/oai/test_utils.py",
"hashed_secret": "11cac88cbfa53881646b024097f531c4f234151b",
"is_verified": false,
"line_number": 436,
"line_number": 475,
"is_secret": false
},
{
"type": "OpenAI Token",
"filename": "test/oai/test_utils.py",
"hashed_secret": "8e8324e8ea2ec13efb774680c6e3850625e575e6",
"is_verified": false,
"line_number": 436,
"line_number": 475,
"is_secret": false
},
{
"type": "Base64 High Entropy String",
"filename": "test/oai/test_utils.py",
"hashed_secret": "8e2fa04ab430ff4817e87e3294f33727fc78ed6c",
"is_verified": false,
"line_number": 439,
"line_number": 478,
"is_secret": false
}
],
Expand Down Expand Up @@ -1187,16 +1187,6 @@
"is_secret": false
}
],
"test/tools/experimental/crawl4ai/test_crawl4ai.py": [
{
"type": "Secret Keyword",
"filename": "test/tools/experimental/crawl4ai/test_crawl4ai.py",
"hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"is_verified": false,
"line_number": 51,
"is_secret": false
}
],
"test/website/test_process_notebooks.py": [
{
"type": "Base64 High Entropy String",
Expand Down Expand Up @@ -1606,5 +1596,5 @@
}
]
},
"generated_at": "2025-02-20T10:09:56Z"
"generated_at": "2025-02-20T13:06:27Z"
}
5 changes: 4 additions & 1 deletion autogen/interop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
from .crewai import CrewAIInteroperability
from .interoperability import Interoperability
from .interoperable import Interoperable
from .langchain import LangChainInteroperability
from .langchain import LangChainChatModelFactory, LangChainInteroperability
from .litellm import LiteLLmConfigFactory
from .pydantic_ai import PydanticAIInteroperability
from .registry import register_interoperable_class

__all__ = [
"CrewAIInteroperability",
"Interoperability",
"Interoperable",
"LangChainChatModelFactory",
"LangChainInteroperability",
"LiteLLmConfigFactory",
"PydanticAIInteroperability",
"register_interoperable_class",
]
5 changes: 3 additions & 2 deletions autogen/interop/langchain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: Apache-2.0

from .langchain import LangChainInteroperability
from .langchain_chat_model_factory import LangChainChatModelFactory
from .langchain_tool import LangChainInteroperability

__all__ = ["LangChainInteroperability"]
__all__ = ["LangChainChatModelFactory", "LangChainInteroperability"]
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
# SPDX-License-Identifier: Apache-2.0

from abc import ABC, abstractmethod
from copy import deepcopy
from typing import Any, Callable
from typing import Any, Callable, TypeVar

from ....import_utils import optional_import_block, require_optional_import
from ...doc_utils import export_module
from ...import_utils import optional_import_block, require_optional_import
from ...oai import get_first_llm_config

with optional_import_block():
from langchain_anthropic import ChatAnthropic
Expand All @@ -16,46 +17,37 @@
from langchain_openai import AzureChatOpenAI, ChatOpenAI


__all__ = ["LangchainFactory"]
__all__ = ["LangChainChatModelFactory"]

T = TypeVar("T", bound="LangChainChatModelFactory")


@require_optional_import(
["langchain_anthropic", "langchain_google_genai", "langchain_ollama", "langchain_openai", "langchain_core"],
"browser-use",
except_for=["__init__", "register_factory"],
)
class LangchainFactory(ABC):
_factories: set["LangchainFactory"] = set()
@export_module("autogen.interop")
class LangChainChatModelFactory(ABC):
_factories: set["LangChainChatModelFactory"] = set()

@classmethod
def create_base_chat_model(cls, llm_config: dict[str, Any]) -> "BaseChatModel": # type: ignore [no-any-unimported]
first_llm_config = cls.get_first_llm_config(llm_config)
for factory in LangchainFactory._factories:
first_llm_config = get_first_llm_config(llm_config)
for factory in LangChainChatModelFactory._factories:
if factory.accepts(first_llm_config):
return factory.create(first_llm_config)

raise ValueError("Could not find a factory for the given config.")

@classmethod
def register_factory(cls) -> Callable[[type["LangchainFactory"]], type["LangchainFactory"]]:
def decorator(factory: type["LangchainFactory"]) -> type["LangchainFactory"]:
def register_factory(cls) -> Callable[[type[T]], type[T]]:
def decorator(factory: type[T]) -> type[T]:
cls._factories.add(factory())
return factory

return decorator

@classmethod
def get_first_llm_config(cls, llm_config: dict[str, Any]) -> dict[str, Any]:
llm_config = deepcopy(llm_config)
if "config_list" not in llm_config:
if "model" in llm_config:
return llm_config
raise ValueError("llm_config must be a valid config dictionary.")

if len(llm_config["config_list"]) == 0:
raise ValueError("Config list must contain at least one config.")
return llm_config["config_list"][0] # type: ignore [no-any-return]

@classmethod
def prepare_config(cls, first_llm_config: dict[str, Any]) -> dict[str, Any]:
for pop_keys in ["api_type", "response_format"]:
Expand All @@ -76,8 +68,8 @@ def accepts(cls, first_llm_config: dict[str, Any]) -> bool:
return first_llm_config.get("api_type", "openai") == cls.get_api_type() # type: ignore [no-any-return]


@LangchainFactory.register_factory()
class ChatOpenAIFactory(LangchainFactory):
@LangChainChatModelFactory.register_factory()
class ChatOpenAIFactory(LangChainChatModelFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "ChatOpenAI": # type: ignore [no-any-unimported]
first_llm_config = cls.prepare_config(first_llm_config)
Expand All @@ -89,7 +81,7 @@ def get_api_type(cls) -> str:
return "openai"


@LangchainFactory.register_factory()
@LangChainChatModelFactory.register_factory()
class DeepSeekFactory(ChatOpenAIFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "ChatOpenAI": # type: ignore [no-any-unimported]
Expand All @@ -102,8 +94,8 @@ def get_api_type(cls) -> str:
return "deepseek"


@LangchainFactory.register_factory()
class ChatAnthropicFactory(LangchainFactory):
@LangChainChatModelFactory.register_factory()
class ChatAnthropicFactory(LangChainChatModelFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "ChatAnthropic": # type: ignore [no-any-unimported]
first_llm_config = cls.prepare_config(first_llm_config)
Expand All @@ -115,8 +107,8 @@ def get_api_type(cls) -> str:
return "anthropic"


@LangchainFactory.register_factory()
class ChatGoogleGenerativeAIFactory(LangchainFactory):
@LangChainChatModelFactory.register_factory()
class ChatGoogleGenerativeAIFactory(LangChainChatModelFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "ChatGoogleGenerativeAI": # type: ignore [no-any-unimported]
first_llm_config = cls.prepare_config(first_llm_config)
Expand All @@ -128,8 +120,8 @@ def get_api_type(cls) -> str:
return "google"


@LangchainFactory.register_factory()
class AzureChatOpenAIFactory(LangchainFactory):
@LangChainChatModelFactory.register_factory()
class AzureChatOpenAIFactory(LangChainChatModelFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "AzureChatOpenAI": # type: ignore [no-any-unimported]
first_llm_config = cls.prepare_config(first_llm_config)
Expand All @@ -145,8 +137,8 @@ def get_api_type(cls) -> str:
return "azure"


@LangchainFactory.register_factory()
class ChatOllamaFactory(LangchainFactory):
@LangChainChatModelFactory.register_factory()
class ChatOllamaFactory(LangChainChatModelFactory):
@classmethod
def create(cls, first_llm_config: dict[str, Any]) -> "ChatOllama": # type: ignore [no-any-unimported]
first_llm_config = cls.prepare_config(first_llm_config)
Expand Down
7 changes: 7 additions & 0 deletions autogen/interop/litellm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
#
# SPDX-License-Identifier: Apache-2.0

from .litellm_config_factory import LiteLLmConfigFactory

__all__ = ["LiteLLmConfigFactory"]
Loading
Loading