From 6838804116a45198b53856a95d00464bc9e3e99a Mon Sep 17 00:00:00 2001 From: Appletree24 <91041770+Appletree24@users.noreply.github.com> Date: Sat, 15 Jun 2024 20:24:50 +0800 Subject: [PATCH 1/6] docs:Fix mispelling in streaming doc (#22936) Description: Fix mispelling Issue: None Dependencies: None Twitter handle: None Co-authored-by: qcloud --- docs/docs/how_to/streaming.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how_to/streaming.ipynb b/docs/docs/how_to/streaming.ipynb index 3ee7283bbcab2..6a9a9da824634 100644 --- a/docs/docs/how_to/streaming.ipynb +++ b/docs/docs/how_to/streaming.ipynb @@ -1003,7 +1003,7 @@ "id": "798ea891-997c-454c-bf60-43124f40ee1b", "metadata": {}, "source": [ - "Because both the model and the parser support streaming, we see sreaming events from both components in real time! Kind of cool isn't it? 🦜" + "Because both the model and the parser support streaming, we see streaming events from both components in real time! Kind of cool isn't it? 🦜" ] }, { From 7a0af561772c1c1474119bb447dbb677b1529cda Mon Sep 17 00:00:00 2001 From: maang-h <55082429+maang-h@users.noreply.github.com> Date: Sat, 15 Jun 2024 21:12:21 +0800 Subject: [PATCH 2/6] docs: update ZhipuAI ChatModel docstring (#22934) - **Description:** Update ZhipuAI ChatModel rich docstring - **Issue:** the issue #22296 --- .../chat_models/zhipuai.py | 116 ++++++++++++++++-- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/libs/community/langchain_community/chat_models/zhipuai.py b/libs/community/langchain_community/chat_models/zhipuai.py index 797bd1cb54f5c..e13851f0e788b 100644 --- a/libs/community/langchain_community/chat_models/zhipuai.py +++ b/libs/community/langchain_community/chat_models/zhipuai.py @@ -163,23 +163,115 @@ def _truncate_params(payload: Dict[str, Any]) -> None: class ChatZhipuAI(BaseChatModel): - """ - `ZhipuAI` large language chat models API. + """ZhipuAI chat model integration. - To use, you should have the ``PyJWT`` python package installed. + Setup: + Install ``PyJWT`` and set environment variable ``ZHIPUAI_API_KEY`` - Example: - .. code-block:: python + .. code-block:: bash - from langchain_community.chat_models import ChatZhipuAI + pip install pyjwt + export ZHIPUAI_API_KEY="your-api-key" - zhipuai_chat = ChatZhipuAI( - temperature=0.5, - api_key="your-api-key", - model="glm-4" - ) + Key init args — completion params: + model: Optional[str] + Name of OpenAI model to use. + temperature: float + Sampling temperature. + max_tokens: Optional[int] + Max number of tokens to generate. - """ + Key init args — client params: + api_key: Optional[str] + ZhipuAI API key. If not passed in will be read from env var ZHIPUAI_API_KEY. + api_base: Optional[str] + Base URL for API requests. + + See full list of supported init args and their descriptions in the params section. + + Instantiate: + .. code-block:: python + + from langchain_community.chat_models import ChatZhipuAI + + zhipuai_chat = ChatZhipuAI( + temperature=0.5, + api_key="your-api-key", + model="glm-4", + # api_base="...", + # other params... + ) + + Invoke: + .. code-block:: python + + messages = [ + ("system", "你是一名专业的翻译家,可以将用户的中文翻译为英文。"), + ("human", "我喜欢编程。"), + ] + zhipuai_chat.invoke(messages) + + .. code-block:: python + + AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-c5d9af91-55c6-470e-9545-02b2fa0d7f9d-0') + + Stream: + .. code-block:: python + + for chunk in zhipuai_chat.stream(messages): + print(chunk) + + .. code-block:: python + + content='I' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content=' enjoy' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content=' programming' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content='.' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content='' response_metadata={'finish_reason': 'stop'} id='run-4df71729-618f-4e2b-a4ff-884682723082' + + .. code-block:: python + + stream = llm.stream(messages) + full = next(stream) + for chunk in stream: + full += chunk + full + + .. code-block:: + + AIMessageChunk(content='I enjoy programming.', response_metadata={'finish_reason': 'stop'}, id='run-20b05040-a0b4-4715-8fdc-b39dba9bfb53') + + Async: + .. code-block:: python + + await zhipuai_chat.ainvoke(messages) + + # stream: + # async for chunk in zhipuai_chat.astream(messages): + # print(chunk) + + # batch: + # await zhipuai_chat.abatch([messages]) + + .. code-block:: python + + [AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-ba06af9d-4baa-40b2-9298-be9c62aa0849-0')] + + Response metadata + .. code-block:: python + + ai_msg = zhipuai_chat.invoke(messages) + ai_msg.response_metadata + + .. code-block:: python + + {'token_usage': {'completion_tokens': 6, + 'prompt_tokens': 23, + 'total_tokens': 29}, + 'model_name': 'glm-4', + 'finish_reason': 'stop'} + + """ # noqa: E501 @property def lc_secrets(self) -> Dict[str, str]: From 1c661fd84991a44e042a7e559393caa7e72ab16e Mon Sep 17 00:00:00 2001 From: Tomaz Bratanic Date: Sat, 15 Jun 2024 12:33:26 -0700 Subject: [PATCH 3/6] Improve llm graph transformer docstring (#22939) --- .../langchain_experimental/graph_transformers/llm.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/experimental/langchain_experimental/graph_transformers/llm.py b/libs/experimental/langchain_experimental/graph_transformers/llm.py index 10c65ef7b9c2e..56e3010f52fbb 100644 --- a/libs/experimental/langchain_experimental/graph_transformers/llm.py +++ b/libs/experimental/langchain_experimental/graph_transformers/llm.py @@ -610,6 +610,13 @@ class LLMGraphTransformer: strict_mode (bool, optional): Determines whether the transformer should apply filtering to strictly adhere to `allowed_nodes` and `allowed_relationships`. Defaults to True. + node_properties (Union[bool, List[str]]): If True, the LLM can extract any + node properties from text. Alternatively, a list of valid properties can + be provided for the LLM to extract, restricting extraction to those specified. + relationship_properties (Union[bool, List[str]]): If True, the LLM can extract + any relationship properties from text. Alternatively, a list of valid + properties can be provided for the LLM to extract, restricting extraction to + those specified. Example: .. code-block:: python From e09c6bb58bd8d1f71870fe01281bdb2bdc180b33 Mon Sep 17 00:00:00 2001 From: ccurme Date: Sat, 15 Jun 2024 15:52:43 -0400 Subject: [PATCH 4/6] infra: update integration test workflow (#22945) --- .github/workflows/_integration_test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/_integration_test.yml b/.github/workflows/_integration_test.yml index 7cf6e425126e6..700a8d10146eb 100644 --- a/.github/workflows/_integration_test.yml +++ b/.github/workflows/_integration_test.yml @@ -12,7 +12,6 @@ env: jobs: build: - environment: Scheduled testing defaults: run: working-directory: ${{ inputs.working-directory }} @@ -53,8 +52,15 @@ jobs: shell: bash env: AI21_API_KEY: ${{ secrets.AI21_API_KEY }} + FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }} GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + AZURE_OPENAI_API_VERSION: ${{ secrets.AZURE_OPENAI_API_VERSION }} + AZURE_OPENAI_API_BASE: ${{ secrets.AZURE_OPENAI_API_BASE }} + AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} + AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_CHAT_DEPLOYMENT_NAME }} + AZURE_OPENAI_LLM_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_LLM_DEPLOYMENT_NAME }} + AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME: ${{ secrets.AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME }} MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} From ada03dd27382cccdec8108ee80a43b290627601f Mon Sep 17 00:00:00 2001 From: Christopher Tee Date: Sat, 15 Jun 2024 16:05:19 -0400 Subject: [PATCH 5/6] community(you): Better support for You.com News API (#22622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description While `YouRetriever` supports both You.com's Search and News APIs, news is supported as an afterthought. More specifically, not all of the News API parameters are exposed for the user, only those that happen to overlap with the Search API. This PR: - improves support for both APIs, exposing the remaining News API parameters while retaining backward compatibility - refactor some REST parameter generation logic - updates the docstring of `YouSearchAPIWrapper` - add input validation and warnings to ensure parameters are properly set by user - 🚨 Breaking: Limit the news results to `k` items If no one reviews your PR within a few days, please @-mention one of baskaryan, efriis, eyurtsev, ccurme, vbarda, hwchase17. --- .../langchain_community/utilities/you.py | 147 +++++++++++++----- 1 file changed, 105 insertions(+), 42 deletions(-) diff --git a/libs/community/langchain_community/utilities/you.py b/libs/community/langchain_community/utilities/you.py index b74841c868b17..6fefecc29398d 100644 --- a/libs/community/langchain_community/utilities/you.py +++ b/libs/community/langchain_community/utilities/you.py @@ -2,6 +2,8 @@ In order to set this up, follow instructions at: """ + +import warnings from typing import Any, Dict, List, Literal, Optional import aiohttp @@ -44,11 +46,11 @@ class YouDocument(BaseModel): class YouSearchAPIWrapper(BaseModel): - """Wrapper for you.com Search API. + """Wrapper for you.com Search and News API. To connect to the You.com api requires an API key which you can get at https://api.you.com. - You can check out the docs at https://documentation.you.com. + You can check out the docs at https://documentation.you.com/api-reference/. You need to set the environment variable `YDC_API_KEY` for retriever to operate. @@ -56,33 +58,50 @@ class YouSearchAPIWrapper(BaseModel): ---------- ydc_api_key: str, optional you.com api key, if YDC_API_KEY is not set in the environment + endpoint_type: str, optional + you.com endpoints: search, news, rag; + `web` and `snippet` alias `search` + `rag` returns `{'message': 'Forbidden'}` + @todo `news` endpoint num_web_results: int, optional - The max number of web results to return, must be under 20 + The max number of web results to return, must be under 20. + This is mapped to the `count` query parameter for the News API. safesearch: str, optional Safesearch settings, one of off, moderate, strict, defaults to moderate country: str, optional - Country code, ex: 'US' for united states, see api docs for list + Country code, ex: 'US' for United States, see api docs for list + search_lang: str, optional + (News API) Language codes, ex: 'en' for English, see api docs for list + ui_lang: str, optional + (News API) User interface language for the response, ex: 'en' for English, + see api docs for list + spellcheck: bool, optional + (News API) Whether to spell check query or not, defaults to True k: int, optional max number of Documents to return using `results()` n_hits: int, optional, deprecated Alias for num_web_results n_snippets_per_hit: int, optional limit the number of snippets returned per hit - endpoint_type: str, optional - you.com endpoints: search, news, rag; - `web` and `snippet` alias `search` - `rag` returns `{'message': 'Forbidden'}` - @todo `news` endpoint """ ydc_api_key: Optional[str] = None + + # @todo deprecate `snippet`, not part of API + endpoint_type: Literal["search", "news", "rag", "snippet"] = "search" + + # Common fields between Search and News API num_web_results: Optional[int] = None - safesearch: Optional[str] = None + safesearch: Optional[Literal["off", "moderate", "strict"]] = None country: Optional[str] = None + + # News API specific fields + search_lang: Optional[str] = None + ui_lang: Optional[str] = None + spellcheck: Optional[bool] = None + k: Optional[int] = None n_snippets_per_hit: Optional[int] = None - # @todo deprecate `snippet`, not part of API - endpoint_type: Literal["search", "news", "rag", "snippet"] = "search" # should deprecate n_hits n_hits: Optional[int] = None @@ -94,6 +113,74 @@ def validate_environment(cls, values: Dict) -> Dict: return values + @root_validator + def warn_if_set_fields_have_no_effect(cls, values: Dict) -> Dict: + if values["endpoint_type"] != "news": + news_api_fields = ("search_lang", "ui_lang", "spellcheck") + for field in news_api_fields: + if values[field]: + warnings.warn( + ( + f"News API-specific field '{field}' is set but " + f"`endpoint_type=\"{values['endpoint_type']}\"`. " + "This will have no effect." + ), + UserWarning, + ) + if values["endpoint_type"] not in ("search", "snippet"): + if values["n_snippets_per_hit"]: + warnings.warn( + ( + "Field 'n_snippets_per_hit' only has effect on " + '`endpoint_type="search"`.' + ), + UserWarning, + ) + return values + + @root_validator + def warn_if_deprecated_endpoints_are_used(cls, values: Dict) -> Dict: + if values["endpoint_type"] == "snippets": + warnings.warn( + ( + f"`endpoint_type=\"{values['endpoint_type']}\"` is deprecated. " + 'Use `endpoint_type="search"` instead.' + ), + DeprecationWarning, + ) + return values + + def _generate_params(self, query: str, **kwargs: Any) -> Dict: + """ + Parse parameters required for different You.com APIs. + + Args: + query: The query to search for. + """ + params = { + "safesearch": self.safesearch, + "country": self.country, + **kwargs, + } + + # Add endpoint-specific params + if self.endpoint_type in ("search", "snippet"): + params.update( + query=query, + num_web_results=self.num_web_results, + ) + elif self.endpoint_type == "news": + params.update( + q=query, + count=self.num_web_results, + search_lang=self.search_lang, + ui_lang=self.ui_lang, + spellcheck=self.spellcheck, + ) + + params = {k: v for k, v in params.items() if v is not None} + return params + def _parse_results(self, raw_search_results: Dict) -> List[Document]: """ Extracts snippets from each hit and puts them in a Document @@ -105,9 +192,12 @@ def _parse_results(self, raw_search_results: Dict) -> List[Document]: # return news results if self.endpoint_type == "news": + news_results = raw_search_results["news"]["results"] + if self.k is not None: + news_results = news_results[: self.k] return [ Document(page_content=result["description"], metadata=result) - for result in raw_search_results["news"]["results"] + for result in news_results ] docs = [] @@ -138,26 +228,10 @@ def raw_results( Args: query: The query to search for. - num_web_results: The maximum number of results to return. - safesearch: Safesearch settings, - one of off, moderate, strict, defaults to moderate - country: Country code Returns: YouAPIOutput """ headers = {"X-API-Key": self.ydc_api_key or ""} - params = { - "query": query, - "num_web_results": self.num_web_results, - "safesearch": self.safesearch, - "country": self.country, - **kwargs, - } - - params = {k: v for k, v in params.items() if v is not None} - # news endpoint expects `q` instead of `query` - if self.endpoint_type == "news": - params["q"] = params["query"] - del params["query"] + params = self._generate_params(query, **kwargs) # @todo deprecate `snippet`, not part of API if self.endpoint_type == "snippet": @@ -192,18 +266,7 @@ async def raw_results_async( """Get results from the you.com Search API asynchronously.""" headers = {"X-API-Key": self.ydc_api_key or ""} - params = { - "query": query, - "num_web_results": self.num_web_results, - "safesearch": self.safesearch, - "country": self.country, - **kwargs, - } - params = {k: v for k, v in params.items() if v is not None} - # news endpoint expects `q` instead of `query` - if self.endpoint_type == "news": - params["q"] = params["query"] - del params["query"] + params = self._generate_params(query, **kwargs) # @todo deprecate `snippet`, not part of API if self.endpoint_type == "snippet": From 892bd4c29be34c0cc095ed178be6d60c6858e2ec Mon Sep 17 00:00:00 2001 From: Daniel Glogowski <167348611+dglogo@users.noreply.github.com> Date: Sat, 15 Jun 2024 16:38:28 -0400 Subject: [PATCH 6/6] docs: nim model name update (#22943) NIM Model name change in a notebook and mdx file. Thanks! --- docs/docs/integrations/chat/nvidia_ai_endpoints.ipynb | 4 ++-- docs/docs/integrations/providers/nvidia.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/integrations/chat/nvidia_ai_endpoints.ipynb b/docs/docs/integrations/chat/nvidia_ai_endpoints.ipynb index 561e3bd7ec544..d346d035f11e8 100644 --- a/docs/docs/integrations/chat/nvidia_ai_endpoints.ipynb +++ b/docs/docs/integrations/chat/nvidia_ai_endpoints.ipynb @@ -134,7 +134,7 @@ "from langchain_nvidia_ai_endpoints import ChatNVIDIA\n", "\n", "# connect to an embedding NIM running at localhost:8000, specifying a specific model\n", - "llm = ChatNVIDIA(base_url=\"http://localhost:8000/v1\", model=\"meta-llama3-8b-instruct\")" + "llm = ChatNVIDIA(base_url=\"http://localhost:8000/v1\", model=\"meta/llama3-8b-instruct\")" ] }, { @@ -658,7 +658,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.10.2" } }, "nbformat": 4, diff --git a/docs/docs/integrations/providers/nvidia.mdx b/docs/docs/integrations/providers/nvidia.mdx index 0e9fa2e9dd3c1..70f1123c41483 100644 --- a/docs/docs/integrations/providers/nvidia.mdx +++ b/docs/docs/integrations/providers/nvidia.mdx @@ -62,7 +62,7 @@ When ready to deploy, you can self-host models with NVIDIA NIM—which is includ from langchain_nvidia_ai_endpoints import ChatNVIDIA, NVIDIAEmbeddings, NVIDIARerank # connect to an chat NIM running at localhost:8000, specifyig a specific model -llm = ChatNVIDIA(base_url="http://localhost:8000/v1", model="meta-llama3-8b-instruct") +llm = ChatNVIDIA(base_url="http://localhost:8000/v1", model="meta/llama3-8b-instruct") # connect to an embedding NIM running at localhost:8080 embedder = NVIDIAEmbeddings(base_url="http://localhost:8080/v1")