forked from langchain-ai/langchain
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
community: Add you.com tool, add async to retriever, add async testin…
…g, add You tool doc (langchain-ai#18032) - **Description:** finishes adding the you.com functionality including: - add async functions to utility and retriever - add the You.com Tool - add async testing for utility, retriever, and tool - add a tool integration notebook page - **Dependencies:** any dependencies required for this change - **Twitter handle:** @scottnath
- Loading branch information
Showing
11 changed files
with
567 additions
and
40 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
"""You.com API toolkit.""" | ||
|
||
|
||
from langchain_community.tools.you.tool import YouSearchTool | ||
|
||
__all__ = [ | ||
"YouSearchTool", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from typing import List, Optional, Type | ||
|
||
from langchain_core.callbacks import ( | ||
AsyncCallbackManagerForToolRun, | ||
CallbackManagerForToolRun, | ||
) | ||
from langchain_core.documents import Document | ||
from langchain_core.pydantic_v1 import BaseModel, Field | ||
from langchain_core.tools import BaseTool | ||
|
||
from langchain_community.utilities.you import YouSearchAPIWrapper | ||
|
||
|
||
class YouInput(BaseModel): | ||
query: str = Field(description="should be a search query") | ||
|
||
|
||
class YouSearchTool(BaseTool): | ||
"""Tool that searches the you.com API""" | ||
|
||
name = "you_search" | ||
description = ( | ||
"The YOU APIs make LLMs and search experiences more factual and" | ||
"up to date with realtime web data." | ||
) | ||
args_schema: Type[BaseModel] = YouInput | ||
api_wrapper: YouSearchAPIWrapper = Field(default_factory=YouSearchAPIWrapper) | ||
|
||
def _run( | ||
self, | ||
query: str, | ||
run_manager: Optional[CallbackManagerForToolRun] = None, | ||
) -> List[Document]: | ||
"""Use the you.com tool.""" | ||
return self.api_wrapper.results(query) | ||
|
||
async def _arun( | ||
self, | ||
query: str, | ||
run_manager: Optional[AsyncCallbackManagerForToolRun] = None, | ||
) -> List[Document]: | ||
"""Use the you.com tool asynchronously.""" | ||
return await self.api_wrapper.results_async(query) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from unittest.mock import AsyncMock, patch | ||
|
||
import pytest | ||
import responses | ||
|
||
from langchain_community.tools.you import YouSearchTool | ||
from langchain_community.utilities.you import YouSearchAPIWrapper | ||
|
||
from ..utilities.test_you import ( | ||
LIMITED_PARSED_OUTPUT, | ||
MOCK_PARSED_OUTPUT, | ||
MOCK_RESPONSE_RAW, | ||
NEWS_RESPONSE_PARSED, | ||
NEWS_RESPONSE_RAW, | ||
TEST_ENDPOINT, | ||
) | ||
|
||
|
||
class TestYouSearchTool: | ||
@responses.activate | ||
def test_invoke(self) -> None: | ||
responses.add( | ||
responses.GET, f"{TEST_ENDPOINT}/search", json=MOCK_RESPONSE_RAW, status=200 | ||
) | ||
query = "Test query text" | ||
you_tool = YouSearchTool(api_wrapper=YouSearchAPIWrapper(ydc_api_key="test")) | ||
results = you_tool.invoke(query) | ||
expected_result = MOCK_PARSED_OUTPUT | ||
assert results == expected_result | ||
|
||
@responses.activate | ||
def test_invoke_max_docs(self) -> None: | ||
responses.add( | ||
responses.GET, f"{TEST_ENDPOINT}/search", json=MOCK_RESPONSE_RAW, status=200 | ||
) | ||
query = "Test query text" | ||
you_tool = YouSearchTool( | ||
api_wrapper=YouSearchAPIWrapper(ydc_api_key="test", k=2) | ||
) | ||
results = you_tool.invoke(query) | ||
expected_result = [MOCK_PARSED_OUTPUT[0], MOCK_PARSED_OUTPUT[1]] | ||
assert results == expected_result | ||
|
||
@responses.activate | ||
def test_invoke_limit_snippets(self) -> None: | ||
responses.add( | ||
responses.GET, f"{TEST_ENDPOINT}/search", json=MOCK_RESPONSE_RAW, status=200 | ||
) | ||
query = "Test query text" | ||
you_tool = YouSearchTool( | ||
api_wrapper=YouSearchAPIWrapper(ydc_api_key="test", n_snippets_per_hit=1) | ||
) | ||
results = you_tool.invoke(query) | ||
expected_result = LIMITED_PARSED_OUTPUT | ||
assert results == expected_result | ||
|
||
@responses.activate | ||
def test_invoke_news(self) -> None: | ||
responses.add( | ||
responses.GET, f"{TEST_ENDPOINT}/news", json=NEWS_RESPONSE_RAW, status=200 | ||
) | ||
|
||
query = "Test news text" | ||
you_tool = YouSearchTool( | ||
api_wrapper=YouSearchAPIWrapper(ydc_api_key="test", endpoint_type="news") | ||
) | ||
results = you_tool.invoke(query) | ||
expected_result = NEWS_RESPONSE_PARSED | ||
assert results == expected_result | ||
|
||
@pytest.mark.asyncio | ||
async def test_ainvoke(self) -> None: | ||
you_tool = YouSearchTool(api_wrapper=YouSearchAPIWrapper(ydc_api_key="test")) | ||
|
||
# Mock response object to simulate aiohttp response | ||
mock_response = AsyncMock() | ||
mock_response.__aenter__.return_value = ( | ||
mock_response # Make the context manager return itself | ||
) | ||
mock_response.__aexit__.return_value = None # No value needed for exit | ||
mock_response.status = 200 | ||
mock_response.json = AsyncMock(return_value=MOCK_RESPONSE_RAW) | ||
|
||
# Patch the aiohttp.ClientSession object | ||
with patch("aiohttp.ClientSession.get", return_value=mock_response): | ||
results = await you_tool.ainvoke("test query") | ||
assert results == MOCK_PARSED_OUTPUT |
Oops, something went wrong.