diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 169c39c..967ba94 100755 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,6 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: python-version: ["3.8", "3.12"] os: [ubuntu-latest, macos-latest, windows-latest] @@ -27,6 +28,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | + python -m pip install -U pip python -m pip install .[lxml,dev] - name: Ruff run: | diff --git a/README.md b/README.md index 1e0e99e..d279805 100755 --- a/README.md +++ b/README.md @@ -240,7 +240,8 @@ def chat(self, keywords: str, model: str = "gpt-3.5") -> str: Args: keywords (str): The initial message or question to send to the AI. - model (str): The model to use: "gpt-3.5", "claude-3-haiku". Defaults to "gpt-3.5". + model (str): The model to use: "gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b". + Defaults to "gpt-3.5". Returns: str: The response from the AI. diff --git a/duckduckgo_search/cli.py b/duckduckgo_search/cli.py index deccd8c..3c68242 100644 --- a/duckduckgo_search/cli.py +++ b/duckduckgo_search/cli.py @@ -137,7 +137,7 @@ def version(): def chat(save, proxy): """CLI function to perform an interactive AI chat using DuckDuckGo API.""" cache_file = "ddgs_chat_conversation.json" - models = ["gpt-3.5", "claude-3-haiku"] + models = ["gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b"] client = DDGS(proxy=proxy) print("DuckDuckGo AI chat. Available models:") diff --git a/duckduckgo_search/duckduckgo_search.py b/duckduckgo_search/duckduckgo_search.py index 8d75312..2aa7887 100644 --- a/duckduckgo_search/duckduckgo_search.py +++ b/duckduckgo_search/duckduckgo_search.py @@ -125,12 +125,18 @@ def chat(self, keywords: str, model: str = "gpt-3.5") -> str: Args: keywords (str): The initial message or question to send to the AI. - model (str): The model to use: "gpt-3.5", "claude-3-haiku". Defaults to "gpt-3.5". + model (str): The model to use: "gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b". + Defaults to "gpt-3.5". Returns: str: The response from the AI. """ - models = {"claude-3-haiku": "claude-3-haiku-20240307", "gpt-3.5": "gpt-3.5-turbo-0125"} + models = { + "claude-3-haiku": "claude-3-haiku-20240307", + "gpt-3.5": "gpt-3.5-turbo-0125", + "llama-3-70b": "meta-llama/Llama-3-70b-chat-hf", + "mixtral-8x7b": "mistralai/Mixtral-8x7B-Instruct-v0.1", + } # vqd if not self._chat_vqd: resp = self.client.get("https://duckduckgo.com/duckchat/v1/status", headers={"x-vqd-accept": "1"}) diff --git a/duckduckgo_search/duckduckgo_search_async.py b/duckduckgo_search/duckduckgo_search_async.py index f558599..b02cf69 100644 --- a/duckduckgo_search/duckduckgo_search_async.py +++ b/duckduckgo_search/duckduckgo_search_async.py @@ -41,7 +41,8 @@ async def achat(self, keywords: str, model: str = "gpt-3.5") -> str: Args: keywords (str): The initial message or question to send to the AI. - model (str): The model to use: "gpt-3.5", "claude-3-haiku". Defaults to "gpt-3.5". + model (str): The model to use: "gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b". + Defaults to "gpt-3.5". Returns: str: The response from the AI. diff --git a/tests/test_duckduckgo_search.py b/tests/test_duckduckgo_search.py index e0454fd..e35b5ec 100644 --- a/tests/test_duckduckgo_search.py +++ b/tests/test_duckduckgo_search.py @@ -14,10 +14,13 @@ def test_context_manager(): results = ddgs.news("cars", max_results=30) assert 20 <= len(results) <= 30 -def test_chat(): - results = DDGS().chat("cat") + +@pytest.mark.parametrize("model", ["gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b"]) +def test_chat(model): + results = DDGS().chat("cat", model=model) assert len(results) >= 1 + def test_text(): results = DDGS().text("cat", safesearch="off", timelimit="m", max_results=30) assert 27 <= len(results) <= 30 diff --git a/tests/test_duckduckgo_search_async.py b/tests/test_duckduckgo_search_async.py index 9dcf3c1..d1a36a7 100644 --- a/tests/test_duckduckgo_search_async.py +++ b/tests/test_duckduckgo_search_async.py @@ -3,60 +3,79 @@ from duckduckgo_search import AsyncDDGS + @pytest.fixture(autouse=True) def pause_between_tests(): time.sleep(0.5) -@pytest.fixture(autouse=True) -async def test_chat(): - results = await AsyncDDGS().chat("cat") +@pytest.mark.asyncio +async def test_context_manager(): + async with AsyncDDGS() as addgs: + results = await addgs.anews("cars", max_results=30) + assert 20 <= len(results) <= 30 + + +@pytest.mark.asyncio +@pytest.mark.parametrize("model", ["gpt-3.5", "claude-3-haiku", "llama-3-70b", "mixtral-8x7b"]) +async def test_chat(model): + results = await AsyncDDGS().achat("cat", model=model) assert len(results) >= 1 + @pytest.mark.asyncio async def test_text(): results = await AsyncDDGS().atext("sky", safesearch="off", timelimit="m", max_results=30) assert 27 <= len(results) <= 30 + @pytest.mark.asyncio async def test_text_html(): results = await AsyncDDGS().atext("eagle", backend="html", max_results=30) assert 27 <= len(results) <= 30 + @pytest.mark.asyncio async def test_text_lite(): results = await AsyncDDGS().atext("dog", backend="lite", max_results=30) assert 27 <= len(results) <= 30 + @pytest.mark.asyncio async def test_async_images(): results = await AsyncDDGS().aimages("flower", max_results=200) assert 95 <= len(results) <= 200 + @pytest.mark.asyncio async def test_async_videos(): results = await AsyncDDGS().avideos("sea", max_results=40) assert 37 <= len(results) <= 40 + @pytest.mark.asyncio async def test_async_news(): results = await AsyncDDGS().anews("tesla", max_results=30) assert 20 <= len(results) <= 30 + @pytest.mark.asyncio async def test_async_maps(): results = await AsyncDDGS().amaps("school", place="London", max_results=30) assert 27 <= len(results) <= 30 + @pytest.mark.asyncio async def test_answers(): results = await AsyncDDGS().aanswers("sun") assert len(results) >= 1 + @pytest.mark.asyncio async def test_suggestions(): results = await AsyncDDGS().asuggestions("moon") assert len(results) >= 1 + @pytest.mark.asyncio async def test_async_translate(): results = await AsyncDDGS().atranslate(["school", "tomatoes"], to="de")