diff --git a/docs/components/llms.mdx b/docs/components/llms.mdx index 98dff333..fa872243 100644 --- a/docs/components/llms.mdx +++ b/docs/components/llms.mdx @@ -68,125 +68,75 @@ llm: ### Function Calling -To enable [function calling](https://platform.openai.com/docs/guides/function-calling) in your application using embedchain and OpenAI, you need to pass functions into `OpenAILlm` class as an array of functions. Here are several ways in which you can achieve that: +Embedchain supports OpenAI [Function calling](https://platform.openai.com/docs/guides/function-calling) with a single function. It accepts inputs in accordance with the [Langchain interface](https://python.langchain.com/docs/modules/model_io/chat/function_calling#legacy-args-functions-and-function_call). -Examples: - + ```python -import os -from embedchain import App -from embedchain.llm.openai import OpenAILlm -import requests -from pydantic import BaseModel, Field, ValidationError, field_validator + from pydantic import BaseModel -os.environ["OPENAI_API_KEY"] = "sk-xxx" + class multiply(BaseModel): + """Multiply two integers together.""" -class QA(BaseModel): - """ - A question and answer pair. - """ - - question: str = Field( - ..., description="The question.", example="What is a mountain?" - ) - answer: str = Field( - ..., description="The answer.", example="A mountain is a hill." - ) - person_who_is_asking: str = Field( - ..., description="The person who is asking the question.", example="John" - ) - - @field_validator("question") - def question_must_end_with_a_question_mark(cls, v): - """ - Validate that the question ends with a question mark. - """ - if not v.endswith("?"): - raise ValueError("question must end with a question mark") - return v - - @field_validator("answer") - def answer_must_end_with_a_period(cls, v): - """ - Validate that the answer ends with a period. - """ - if not v.endswith("."): - raise ValueError("answer must end with a period") - return v - -llm = OpenAILlm(config=None,functions=[QA]) -app = App(llm=llm) - -result = app.query("Hey I am Sid. What is a mountain? A mountain is a hill.") - -print(result) + a: int = Field(..., description="First integer") + b: int = Field(..., description="Second integer") ``` - + - + + ```python + def multiply(a: int, b: int) -> int: + """Multiply two integers together. + + Args: + a: First integer + b: Second integer + """ + return a * b + ``` + + + ```python + multiply = { + "type": "function", + "function": { + "name": "multiply", + "description": "Multiply two integers together.", + "parameters": { + "type": "object", + "properties": { + "a": { + "description": "First integer", + "type": "integer" + }, + "b": { + "description": "Second integer", + "type": "integer" + } + }, + "required": [ + "a", + "b" + ] + } + } + } + ``` + + +With any of the previous inputs, the OpenAI LLM can be queried to provide the appropriate arguments for the function. + ```python import os from embedchain import App from embedchain.llm.openai import OpenAILlm -import requests -from pydantic import BaseModel, Field, ValidationError, field_validator os.environ["OPENAI_API_KEY"] = "sk-xxx" -json_schema = { - "name": "get_qa", - "description": "A question and answer pair and the user who is asking the question.", - "parameters": { - "type": "object", - "properties": { - "question": {"type": "string", "description": "The question."}, - "answer": {"type": "string", "description": "The answer."}, - "person_who_is_asking": { - "type": "string", - "description": "The person who is asking the question.", - } - }, - "required": ["question", "answer", "person_who_is_asking"], - }, -} - -llm = OpenAILlm(config=None,functions=[json_schema]) +llm = OpenAILlm(tools=multiply) app = App(llm=llm) -result = app.query("Hey I am Sid. What is a mountain? A mountain is a hill.") - -print(result) - ``` - - - ```python -import os -from embedchain import App -from embedchain.llm.openai import OpenAILlm -import requests -from pydantic import BaseModel, Field, ValidationError, field_validator - -os.environ["OPENAI_API_KEY"] = "sk-xxx" - -def find_info_of_pokemon(pokemon: str): - """ - Find the information of the given pokemon. - Args: - pokemon: The pokemon. - """ - req = requests.get(f"https://pokeapi.co/api/v2/pokemon/{pokemon}") - if req.status_code == 404: - raise ValueError("pokemon not found") - return req.json() - -llm = OpenAILlm(config=None,functions=[find_info_of_pokemon]) -app = App(llm=llm) - -result = app.query("Tell me more about the pokemon pikachu.") - -print(result) +result = app.query("What is the result of 125 multiplied by fifteen?") ``` - ## Google AI diff --git a/embedchain/embedder/huggingface.py b/embedchain/embedder/huggingface.py index 83433c05..88bc2890 100644 --- a/embedchain/embedder/huggingface.py +++ b/embedchain/embedder/huggingface.py @@ -1,6 +1,6 @@ from typing import Optional -from langchain.embeddings import HuggingFaceEmbeddings +from langchain_community.embeddings import HuggingFaceEmbeddings from embedchain.config import BaseEmbedderConfig from embedchain.embedder.base import BaseEmbedder diff --git a/embedchain/embedder/openai.py b/embedchain/embedder/openai.py index 5f3114a3..29ca042e 100644 --- a/embedchain/embedder/openai.py +++ b/embedchain/embedder/openai.py @@ -2,7 +2,7 @@ import os from typing import Optional from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction -from langchain.embeddings import AzureOpenAIEmbeddings +from langchain_community.embeddings import AzureOpenAIEmbeddings from embedchain.config import BaseEmbedderConfig from embedchain.embedder.base import BaseEmbedder diff --git a/embedchain/embedder/vertexai.py b/embedchain/embedder/vertexai.py index c8eed7d9..4f1b7e8a 100644 --- a/embedchain/embedder/vertexai.py +++ b/embedchain/embedder/vertexai.py @@ -1,6 +1,6 @@ from typing import Optional -from langchain.embeddings import VertexAIEmbeddings +from langchain_community.embeddings import VertexAIEmbeddings from embedchain.config import BaseEmbedderConfig from embedchain.embedder.base import BaseEmbedder diff --git a/embedchain/llm/anthropic.py b/embedchain/llm/anthropic.py index aab38640..05a1f815 100644 --- a/embedchain/llm/anthropic.py +++ b/embedchain/llm/anthropic.py @@ -19,7 +19,7 @@ class AnthropicLlm(BaseLlm): @staticmethod def _get_answer(prompt: str, config: BaseLlmConfig) -> str: - from langchain.chat_models import ChatAnthropic + from langchain_community.chat_models import ChatAnthropic chat = ChatAnthropic( anthropic_api_key=os.environ["ANTHROPIC_API_KEY"], temperature=config.temperature, model=config.model diff --git a/embedchain/llm/aws_bedrock.py b/embedchain/llm/aws_bedrock.py index 200a8f39..de3da5d0 100644 --- a/embedchain/llm/aws_bedrock.py +++ b/embedchain/llm/aws_bedrock.py @@ -1,7 +1,7 @@ import os from typing import Optional -from langchain.llms import Bedrock +from langchain_community.llms import Bedrock from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/azure_openai.py b/embedchain/llm/azure_openai.py index 99588aa0..7cf095ba 100644 --- a/embedchain/llm/azure_openai.py +++ b/embedchain/llm/azure_openai.py @@ -16,7 +16,7 @@ class AzureOpenAILlm(BaseLlm): @staticmethod def _get_answer(prompt: str, config: BaseLlmConfig) -> str: - from langchain.chat_models import AzureChatOpenAI + from langchain_community.chat_models import AzureChatOpenAI if not config.deployment_name: raise ValueError("Deployment name must be provided for Azure OpenAI") diff --git a/embedchain/llm/cohere.py b/embedchain/llm/cohere.py index 7ddac928..be4407fd 100644 --- a/embedchain/llm/cohere.py +++ b/embedchain/llm/cohere.py @@ -2,7 +2,7 @@ import importlib import os from typing import Optional -from langchain.llms.cohere import Cohere +from langchain_community.llms.cohere import Cohere from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/gpt4all.py b/embedchain/llm/gpt4all.py index ce1e65bb..833f3e26 100644 --- a/embedchain/llm/gpt4all.py +++ b/embedchain/llm/gpt4all.py @@ -26,7 +26,8 @@ class GPT4ALLLlm(BaseLlm): @staticmethod def _get_instance(model): try: - from langchain.llms.gpt4all import GPT4All as LangchainGPT4All + from langchain_community.llms.gpt4all import \ + GPT4All as LangchainGPT4All except ModuleNotFoundError: raise ModuleNotFoundError( "The GPT4All python package is not installed. Please install it with `pip install --upgrade embedchain[opensource]`" # noqa E501 diff --git a/embedchain/llm/huggingface.py b/embedchain/llm/huggingface.py index 016485bf..a8cfe2da 100644 --- a/embedchain/llm/huggingface.py +++ b/embedchain/llm/huggingface.py @@ -3,8 +3,8 @@ import logging import os from typing import Optional -from langchain.llms.huggingface_endpoint import HuggingFaceEndpoint -from langchain.llms.huggingface_hub import HuggingFaceHub +from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint +from langchain_community.llms.huggingface_hub import HuggingFaceHub from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/jina.py b/embedchain/llm/jina.py index b09c0fd3..4925276e 100644 --- a/embedchain/llm/jina.py +++ b/embedchain/llm/jina.py @@ -1,8 +1,8 @@ import os from typing import Optional -from langchain.chat_models import JinaChat from langchain.schema import HumanMessage, SystemMessage +from langchain_community.chat_models import JinaChat from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/llama2.py b/embedchain/llm/llama2.py index 1e74d1bb..486dbc71 100644 --- a/embedchain/llm/llama2.py +++ b/embedchain/llm/llama2.py @@ -2,7 +2,7 @@ import importlib import os from typing import Optional -from langchain.llms.replicate import Replicate +from langchain_community.llms.replicate import Replicate from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/ollama.py b/embedchain/llm/ollama.py index 237a8797..e1065f4e 100644 --- a/embedchain/llm/ollama.py +++ b/embedchain/llm/ollama.py @@ -4,7 +4,7 @@ from typing import Optional, Union from langchain.callbacks.manager import CallbackManager from langchain.callbacks.stdout import StdOutCallbackHandler from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler -from langchain.llms.ollama import Ollama +from langchain_community.llms.ollama import Ollama from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/openai.py b/embedchain/llm/openai.py index 40f750c0..6af1e856 100644 --- a/embedchain/llm/openai.py +++ b/embedchain/llm/openai.py @@ -1,9 +1,11 @@ import json import os -from typing import Any, Optional +from typing import Any, Callable, Dict, Optional, Type, Union -from langchain.chat_models import ChatOpenAI -from langchain.schema import AIMessage, HumanMessage, SystemMessage +from langchain.schema import BaseMessage, HumanMessage, SystemMessage +from langchain_core.tools import BaseTool +from langchain_openai import ChatOpenAI +from pydantic import BaseModel from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable @@ -12,8 +14,12 @@ from embedchain.llm.base import BaseLlm @register_deserializable class OpenAILlm(BaseLlm): - def __init__(self, config: Optional[BaseLlmConfig] = None, functions: Optional[dict[str, Any]] = None): - self.functions = functions + def __init__( + self, + config: Optional[BaseLlmConfig] = None, + tools: Optional[Union[Dict[str, Any], Type[BaseModel], Callable[..., Any], BaseTool]] = None, + ): + self.tools = tools super().__init__(config=config) def get_llm_model_answer(self, prompt) -> str: @@ -38,21 +44,27 @@ class OpenAILlm(BaseLlm): from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler callbacks = config.callbacks if config.callbacks else [StreamingStdOutCallbackHandler()] - llm = ChatOpenAI(**kwargs, streaming=config.stream, callbacks=callbacks, api_key=api_key) + chat = ChatOpenAI(**kwargs, streaming=config.stream, callbacks=callbacks, api_key=api_key) else: - llm = ChatOpenAI(**kwargs, api_key=api_key) + chat = ChatOpenAI(**kwargs, api_key=api_key) + if self.tools: + return self._query_function_call(chat, self.tools, messages) - if self.functions is not None: - from langchain.chains.openai_functions import create_openai_fn_runnable - from langchain.prompts import ChatPromptTemplate + return chat.invoke(messages).content - structured_prompt = ChatPromptTemplate.from_messages(messages) - runnable = create_openai_fn_runnable(functions=self.functions, prompt=structured_prompt, llm=llm) - fn_res = runnable.invoke( - { - "input": prompt, - } - ) - messages.append(AIMessage(content=json.dumps(fn_res))) + def _query_function_call( + self, + chat: ChatOpenAI, + tools: Optional[Union[Dict[str, Any], Type[BaseModel], Callable[..., Any], BaseTool]], + messages: list[BaseMessage], + ) -> str: + from langchain.output_parsers.openai_tools import JsonOutputToolsParser + from langchain_core.utils.function_calling import \ + convert_to_openai_tool - return llm(messages).content + openai_tools = [convert_to_openai_tool(tools)] + chat = chat.bind(tools=openai_tools).pipe(JsonOutputToolsParser()) + try: + return json.dumps(chat.invoke(messages)[0]) + except IndexError: + return "Input could not be mapped to the function!" diff --git a/embedchain/llm/together.py b/embedchain/llm/together.py index 3ddac552..23462b1e 100644 --- a/embedchain/llm/together.py +++ b/embedchain/llm/together.py @@ -2,7 +2,7 @@ import importlib import os from typing import Optional -from langchain.llms import Together +from langchain_community.llms import Together from embedchain.config import BaseLlmConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/embedchain/llm/vertex_ai.py b/embedchain/llm/vertex_ai.py index c453c67b..f1221f91 100644 --- a/embedchain/llm/vertex_ai.py +++ b/embedchain/llm/vertex_ai.py @@ -24,7 +24,7 @@ class VertexAILlm(BaseLlm): @staticmethod def _get_answer(prompt: str, config: BaseLlmConfig) -> str: - from langchain.chat_models import ChatVertexAI + from langchain_community.chat_models import ChatVertexAI chat = ChatVertexAI(temperature=config.temperature, model=config.model) diff --git a/embedchain/loaders/docx_file.py b/embedchain/loaders/docx_file.py index d72e64b2..319819ff 100644 --- a/embedchain/loaders/docx_file.py +++ b/embedchain/loaders/docx_file.py @@ -1,7 +1,7 @@ import hashlib try: - from langchain.document_loaders import Docx2txtLoader + from langchain_community.document_loaders import Docx2txtLoader except ImportError: raise ImportError( 'Docx file requires extra dependencies. Install with `pip install --upgrade "embedchain[dataloaders]"`' diff --git a/embedchain/loaders/google_drive.py b/embedchain/loaders/google_drive.py index 5db6c8b8..2e75de6b 100644 --- a/embedchain/loaders/google_drive.py +++ b/embedchain/loaders/google_drive.py @@ -8,8 +8,8 @@ except ImportError: "Google Drive requires extra dependencies. Install with `pip install embedchain[googledrive]`" ) from None -from langchain.document_loaders import GoogleDriveLoader as Loader -from langchain.document_loaders import UnstructuredFileIOLoader +from langchain_community.document_loaders import GoogleDriveLoader as Loader +from langchain_community.document_loaders import UnstructuredFileIOLoader from embedchain.helpers.json_serializable import register_deserializable from embedchain.loaders.base_loader import BaseLoader diff --git a/embedchain/loaders/pdf_file.py b/embedchain/loaders/pdf_file.py index 77107764..edd56c85 100644 --- a/embedchain/loaders/pdf_file.py +++ b/embedchain/loaders/pdf_file.py @@ -1,7 +1,7 @@ import hashlib try: - from langchain.document_loaders import PyPDFLoader + from langchain_community.document_loaders import PyPDFLoader except ImportError: raise ImportError( 'PDF File requires extra dependencies. Install with `pip install --upgrade "embedchain[dataloaders]"`' diff --git a/embedchain/loaders/rss_feed.py b/embedchain/loaders/rss_feed.py index d92d7c29..767921f1 100644 --- a/embedchain/loaders/rss_feed.py +++ b/embedchain/loaders/rss_feed.py @@ -28,7 +28,7 @@ class RSSFeedLoader(BaseLoader): @staticmethod def get_rss_content(url: str): try: - from langchain.document_loaders import \ + from langchain_community.document_loaders import \ RSSFeedLoader as LangchainRSSFeedLoader except ImportError: raise ImportError( diff --git a/embedchain/loaders/unstructured_file.py b/embedchain/loaders/unstructured_file.py index b46eae60..80099105 100644 --- a/embedchain/loaders/unstructured_file.py +++ b/embedchain/loaders/unstructured_file.py @@ -10,7 +10,8 @@ class UnstructuredLoader(BaseLoader): def load_data(self, url): """Load data from an Unstructured file.""" try: - from langchain.document_loaders import UnstructuredFileLoader + from langchain_community.document_loaders import \ + UnstructuredFileLoader except ImportError: raise ImportError( 'Unstructured file requires extra dependencies. Install with `pip install --upgrade "embedchain[dataloaders]"`' # noqa: E501 diff --git a/embedchain/loaders/xml.py b/embedchain/loaders/xml.py index 5436d749..01bbd21a 100644 --- a/embedchain/loaders/xml.py +++ b/embedchain/loaders/xml.py @@ -1,7 +1,7 @@ import hashlib try: - from langchain.document_loaders import UnstructuredXMLLoader + from langchain_community.document_loaders import UnstructuredXMLLoader except ImportError: raise ImportError( 'XML file requires extra dependencies. Install with `pip install --upgrade "embedchain[dataloaders]"`' diff --git a/embedchain/loaders/youtube_video.py b/embedchain/loaders/youtube_video.py index 4c1a8453..1e8ba35e 100644 --- a/embedchain/loaders/youtube_video.py +++ b/embedchain/loaders/youtube_video.py @@ -1,7 +1,7 @@ import hashlib try: - from langchain.document_loaders import YoutubeLoader + from langchain_community.document_loaders import YoutubeLoader except ImportError: raise ImportError( 'YouTube video requires extra dependencies. Install with `pip install --upgrade "embedchain[dataloaders]"`' diff --git a/embedchain/vectordb/opensearch.py b/embedchain/vectordb/opensearch.py index e21bf220..18cf0d35 100644 --- a/embedchain/vectordb/opensearch.py +++ b/embedchain/vectordb/opensearch.py @@ -12,8 +12,8 @@ except ImportError: "OpenSearch requires extra dependencies. Install with `pip install --upgrade embedchain[opensearch]`" ) from None -from langchain.embeddings.openai import OpenAIEmbeddings -from langchain.vectorstores import OpenSearchVectorSearch +from langchain_community.embeddings.openai import OpenAIEmbeddings +from langchain_community.vectorstores import OpenSearchVectorSearch from embedchain.config import OpenSearchDBConfig from embedchain.helpers.json_serializable import register_deserializable diff --git a/poetry.lock b/poetry.lock index 6422356b..d398164a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3020,22 +3020,23 @@ adal = ["adal (>=1.0.2)"] [[package]] name = "langchain" -version = "0.0.336" +version = "0.1.4" description = "Building applications with LLMs through composability" optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langchain-0.0.336-py3-none-any.whl", hash = "sha256:cbc72c170c5eb67509bf44fb833412a3d4ccf4476136447abd4f10468ef7d4c4"}, - {file = "langchain-0.0.336.tar.gz", hash = "sha256:2cbb992b0a6975948d35616386d088c2920b66023cb94eb4f4b25e097fa1374d"}, + {file = "langchain-0.1.4-py3-none-any.whl", hash = "sha256:6befdd6221f5f326092e31a3c19efdc7ce3d7d1f2e2cab065141071451730ed7"}, + {file = "langchain-0.1.4.tar.gz", hash = "sha256:8767a9461e2b717ce9a35b1fa20659de89ea86ba9c2a4ff516e05d47ab2d195d"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" -anyio = "<4.0" async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} dataclasses-json = ">=0.5.7,<0.7" jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.0.63,<0.1.0" +langchain-community = ">=0.0.14,<0.1" +langchain-core = ">=0.1.16,<0.2" +langsmith = ">=0.0.83,<0.1" numpy = ">=1,<2" pydantic = ">=1,<3" PyYAML = ">=5.3" @@ -3044,14 +3045,13 @@ SQLAlchemy = ">=1.4,<3" tenacity = ">=8.1.0,<9.0.0" [package.extras] -all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "amadeus (>=8.1.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "awadb (>=0.3.9,<0.4.0)", "azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clarifai (>=9.1.0)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=4,<5)", "deeplake (>=3.8.3,<4.0.0)", "docarray[hnswlib] (>=0.32.0,<0.33.0)", "duckduckgo-search (>=3.8.3,<4.0.0)", "elasticsearch (>=8,<9)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-auth (>=2.18.1,<3.0.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "langkit (>=0.0.6,<0.1.0)", "lark (>=1.1.5,<2.0.0)", "librosa (>=0.10.0.post2,<0.11.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "marqo (>=1.2.4,<2.0.0)", "momento (>=1.13.0,<2.0.0)", "nebula3-python (>=3.4.0,<4.0.0)", "neo4j (>=5.8.1,<6.0.0)", "networkx (>=2.6.3,<4)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pymongo (>=4.3.3,<5.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "python-arango (>=7.5.9,<8.0.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.3.1,<2.0.0)", "rdflib (>=6.3.2,<7.0.0)", "redis (>=4,<5)", "requests-toolbelt (>=1.0.0,<2.0.0)", "sentence-transformers (>=2,<3)", "singlestoredb (>=0.7.1,<0.8.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tigrisdb (>=1.0.0b6,<2.0.0)", "tiktoken (>=0.3.2,<0.6.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"] -azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] clarifai = ["clarifai (>=9.1.0)"] cli = ["typer (>=0.9.0,<0.10.0)"] cohere = ["cohere (>=4,<5)"] docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] embeddings = ["sentence-transformers (>=2,<3)"] -extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "dashvector (>=1.0.1,<2.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.6.0,<0.7.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] javascript = ["esprima (>=4.0.1,<5.0.0)"] llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] @@ -3059,20 +3059,46 @@ qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] text-helpers = ["chardet (>=5.1.0,<6.0.0)"] [[package]] -name = "langchain-core" -version = "0.1.12" -description = "Building applications with LLMs through composability" -optional = true +name = "langchain-community" +version = "0.0.16" +description = "Community contributed LangChain integrations." +optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langchain_core-0.1.12-py3-none-any.whl", hash = "sha256:d11c6262f7a9deff7de8fdf14498b8a951020dfed3a80f2358ab731ad04abef0"}, - {file = "langchain_core-0.1.12.tar.gz", hash = "sha256:f18e9300e9a07589b3e280e51befbc5a4513f535949406e55eb7a2dc40c3ce66"}, + {file = "langchain_community-0.0.16-py3-none-any.whl", hash = "sha256:0f1dfc1a6205ce8d39931d3515974a208a9f69c16157c649f83490a7cc830b73"}, + {file = "langchain_community-0.0.16.tar.gz", hash = "sha256:c06512a93013a06fba7679cd5a1254ff8b927cddd2d1fbe0cc444bf7bbdf0b8c"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +langchain-core = ">=0.1.16,<0.2" +langsmith = ">=0.0.83,<0.1" +numpy = ">=1,<2" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +cli = ["typer (>=0.9.0,<0.10.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)", "zhipuai (>=1.0.7,<2.0.0)"] + +[[package]] +name = "langchain-core" +version = "0.1.16" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_core-0.1.16-py3-none-any.whl", hash = "sha256:c1b2e7363771d64a72cb45032ed5a46facf67de005017fb5e74595cbf433f834"}, + {file = "langchain_core-0.1.16.tar.gz", hash = "sha256:8cb546eed318009ee1a8a381d108074eddf0395ae61eb243db00d76e1e265e89"}, ] [package.dependencies] anyio = ">=3,<5" jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.0.63,<0.1.0" +langsmith = ">=0.0.83,<0.1" packaging = ">=23.2,<24.0" pydantic = ">=1,<3" PyYAML = ">=5.3" @@ -3097,6 +3123,23 @@ files = [ langchain-core = ">=0.1,<0.2" mistralai = ">=0.0.11,<0.0.12" +[[package]] +name = "langchain-openai" +version = "0.0.5" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_openai-0.0.5-py3-none-any.whl", hash = "sha256:93b37dfac274adad65e46d5d6e71411e00c6984bcc5e10f1d6bb58e7944dc01b"}, + {file = "langchain_openai-0.0.5.tar.gz", hash = "sha256:f317fee5b652949ad96ad7edf8ef7a044a6a3f0cc71d1e12f9d5261789fd68c4"}, +] + +[package.dependencies] +langchain-core = ">=0.1.16,<0.2" +numpy = ">=1,<2" +openai = ">=1.10.0,<2.0.0" +tiktoken = ">=0.5.2,<0.6.0" + [[package]] name = "langdetect" version = "1.0.9" @@ -3113,13 +3156,13 @@ six = "*" [[package]] name = "langsmith" -version = "0.0.65" +version = "0.0.83" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langsmith-0.0.65-py3-none-any.whl", hash = "sha256:92450957d1c6b6be814f9b726f3bc751deca684535fb404508ccad7aec1bb049"}, - {file = "langsmith-0.0.65.tar.gz", hash = "sha256:ef20e2e32392fb1a0fc5d171e8de595d868b4153a10cc119d7bf8418192c06b6"}, + {file = "langsmith-0.0.83-py3-none-any.whl", hash = "sha256:a5bb7ac58c19a415a9d5f51db56dd32ee2cd7343a00825bbc2018312eb3d122a"}, + {file = "langsmith-0.0.83.tar.gz", hash = "sha256:94427846b334ad9bdbec3266fee12903fe9f5448f628667689d0412012aaf392"}, ] [package.dependencies] @@ -4187,22 +4230,23 @@ sympy = "*" [[package]] name = "openai" -version = "1.1.2" -description = "Client library for the openai API" +version = "1.10.0" +description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.1.2-py3-none-any.whl", hash = "sha256:72fa414378913ca74432ac618ca6cdfd78a502fcfad1e06cc499b9dba8ff2c8e"}, - {file = "openai-1.1.2.tar.gz", hash = "sha256:bcb4d1fd471cf616031053636841acdc820cd42cbc6cd3e4036c85f682752656"}, + {file = "openai-1.10.0-py3-none-any.whl", hash = "sha256:aa69e97d0223ace9835fbf9c997abe9ee95318f684fd2de6d02c870700c71ebc"}, + {file = "openai-1.10.0.tar.gz", hash = "sha256:208886cb501b930dc63f48d51db9c15e5380380f80516d07332adad67c9f1053"}, ] [package.dependencies] -anyio = ">=3.5.0,<4" +anyio = ">=3.5.0,<5" distro = ">=1.7.0,<2" httpx = ">=0.23.0,<1" pydantic = ">=1.9.0,<3" +sniffio = "*" tqdm = ">4" -typing-extensions = ">=4.5,<5" +typing-extensions = ">=4.7,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] @@ -5676,6 +5720,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -5857,7 +5902,7 @@ full = ["numpy"] name = "regex" version = "2023.8.8" description = "Alternative regular expression module, to replace re." -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, @@ -6833,40 +6878,47 @@ files = [ [[package]] name = "tiktoken" -version = "0.4.0" +version = "0.5.2" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -optional = true +optional = false python-versions = ">=3.8" files = [ - {file = "tiktoken-0.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:176cad7f053d2cc82ce7e2a7c883ccc6971840a4b5276740d0b732a2b2011f8a"}, - {file = "tiktoken-0.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:450d504892b3ac80207700266ee87c932df8efea54e05cefe8613edc963c1285"}, - {file = "tiktoken-0.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d662de1e7986d129139faf15e6a6ee7665ee103440769b8dedf3e7ba6ac37f"}, - {file = "tiktoken-0.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5727d852ead18b7927b8adf558a6f913a15c7766725b23dbe21d22e243041b28"}, - {file = "tiktoken-0.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c06cd92b09eb0404cedce3702fa866bf0d00e399439dad3f10288ddc31045422"}, - {file = "tiktoken-0.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9ec161e40ed44e4210d3b31e2ff426b4a55e8254f1023e5d2595cb60044f8ea6"}, - {file = "tiktoken-0.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:1e8fa13cf9889d2c928b9e258e9dbbbf88ab02016e4236aae76e3b4f82dd8288"}, - {file = "tiktoken-0.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb2341836b725c60d0ab3c84970b9b5f68d4b733a7bcb80fb25967e5addb9920"}, - {file = "tiktoken-0.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ca30367ad750ee7d42fe80079d3092bd35bb266be7882b79c3bd159b39a17b0"}, - {file = "tiktoken-0.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dc3df19ddec79435bb2a94ee46f4b9560d0299c23520803d851008445671197"}, - {file = "tiktoken-0.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d980fa066e962ef0f4dad0222e63a484c0c993c7a47c7dafda844ca5aded1f3"}, - {file = "tiktoken-0.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:329f548a821a2f339adc9fbcfd9fc12602e4b3f8598df5593cfc09839e9ae5e4"}, - {file = "tiktoken-0.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b1a038cee487931a5caaef0a2e8520e645508cde21717eacc9af3fbda097d8bb"}, - {file = "tiktoken-0.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:08efa59468dbe23ed038c28893e2a7158d8c211c3dd07f2bbc9a30e012512f1d"}, - {file = "tiktoken-0.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3020350685e009053829c1168703c346fb32c70c57d828ca3742558e94827a9"}, - {file = "tiktoken-0.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba16698c42aad8190e746cd82f6a06769ac7edd415d62ba027ea1d99d958ed93"}, - {file = "tiktoken-0.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c15d9955cc18d0d7ffcc9c03dc51167aedae98542238b54a2e659bd25fe77ed"}, - {file = "tiktoken-0.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64e1091c7103100d5e2c6ea706f0ec9cd6dc313e6fe7775ef777f40d8c20811e"}, - {file = "tiktoken-0.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e87751b54eb7bca580126353a9cf17a8a8eaadd44edaac0e01123e1513a33281"}, - {file = "tiktoken-0.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e063b988b8ba8b66d6cc2026d937557437e79258095f52eaecfafb18a0a10c03"}, - {file = "tiktoken-0.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9c6dd439e878172dc163fced3bc7b19b9ab549c271b257599f55afc3a6a5edef"}, - {file = "tiktoken-0.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d1d97f83697ff44466c6bef5d35b6bcdb51e0125829a9c0ed1e6e39fb9a08fb"}, - {file = "tiktoken-0.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b6bce7c68aa765f666474c7c11a7aebda3816b58ecafb209afa59c799b0dd2d"}, - {file = "tiktoken-0.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a73286c35899ca51d8d764bc0b4d60838627ce193acb60cc88aea60bddec4fd"}, - {file = "tiktoken-0.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0394967d2236a60fd0aacef26646b53636423cc9c70c32f7c5124ebe86f3093"}, - {file = "tiktoken-0.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:dae2af6f03ecba5f679449fa66ed96585b2fa6accb7fd57d9649e9e398a94f44"}, - {file = "tiktoken-0.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:55e251b1da3c293432179cf7c452cfa35562da286786be5a8b1ee3405c2b0dd2"}, - {file = "tiktoken-0.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:c835d0ee1f84a5aa04921717754eadbc0f0a56cf613f78dfc1cf9ad35f6c3fea"}, - {file = "tiktoken-0.4.0.tar.gz", hash = "sha256:59b20a819969735b48161ced9b92f05dc4519c17be4015cfb73b65270a243620"}, + {file = "tiktoken-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c4e654282ef05ec1bd06ead22141a9a1687991cef2c6a81bdd1284301abc71d"}, + {file = "tiktoken-0.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b3134aa24319f42c27718c6967f3c1916a38a715a0fa73d33717ba121231307"}, + {file = "tiktoken-0.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6092e6e77730929c8c6a51bb0d7cfdf1b72b63c4d033d6258d1f2ee81052e9e5"}, + {file = "tiktoken-0.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ad8ae2a747622efae75837abba59be6c15a8f31b4ac3c6156bc56ec7a8e631"}, + {file = "tiktoken-0.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51cba7c8711afa0b885445f0637f0fcc366740798c40b981f08c5f984e02c9d1"}, + {file = "tiktoken-0.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3d8c7d2c9313f8e92e987d585ee2ba0f7c40a0de84f4805b093b634f792124f5"}, + {file = "tiktoken-0.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:692eca18c5fd8d1e0dde767f895c17686faaa102f37640e884eecb6854e7cca7"}, + {file = "tiktoken-0.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:138d173abbf1ec75863ad68ca289d4da30caa3245f3c8d4bfb274c4d629a2f77"}, + {file = "tiktoken-0.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7388fdd684690973fdc450b47dfd24d7f0cbe658f58a576169baef5ae4658607"}, + {file = "tiktoken-0.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a114391790113bcff670c70c24e166a841f7ea8f47ee2fe0e71e08b49d0bf2d4"}, + {file = "tiktoken-0.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca96f001e69f6859dd52926d950cfcc610480e920e576183497ab954e645e6ac"}, + {file = "tiktoken-0.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:15fed1dd88e30dfadcdd8e53a8927f04e1f6f81ad08a5ca824858a593ab476c7"}, + {file = "tiktoken-0.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:93f8e692db5756f7ea8cb0cfca34638316dcf0841fb8469de8ed7f6a015ba0b0"}, + {file = "tiktoken-0.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:bcae1c4c92df2ffc4fe9f475bf8148dbb0ee2404743168bbeb9dcc4b79dc1fdd"}, + {file = "tiktoken-0.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b76a1e17d4eb4357d00f0622d9a48ffbb23401dcf36f9716d9bd9c8e79d421aa"}, + {file = "tiktoken-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01d8b171bb5df4035580bc26d4f5339a6fd58d06f069091899d4a798ea279d3e"}, + {file = "tiktoken-0.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42adf7d4fb1ed8de6e0ff2e794a6a15005f056a0d83d22d1d6755a39bffd9e7f"}, + {file = "tiktoken-0.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3f894dbe0adb44609f3d532b8ea10820d61fdcb288b325a458dfc60fefb7db"}, + {file = "tiktoken-0.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:58ccfddb4e62f0df974e8f7e34a667981d9bb553a811256e617731bf1d007d19"}, + {file = "tiktoken-0.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58902a8bad2de4268c2a701f1c844d22bfa3cbcc485b10e8e3e28a050179330b"}, + {file = "tiktoken-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:5e39257826d0647fcac403d8fa0a474b30d02ec8ffc012cfaf13083e9b5e82c5"}, + {file = "tiktoken-0.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bde3b0fbf09a23072d39c1ede0e0821f759b4fa254a5f00078909158e90ae1f"}, + {file = "tiktoken-0.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2ddee082dcf1231ccf3a591d234935e6acf3e82ee28521fe99af9630bc8d2a60"}, + {file = "tiktoken-0.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35c057a6a4e777b5966a7540481a75a31429fc1cb4c9da87b71c8b75b5143037"}, + {file = "tiktoken-0.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c4a049b87e28f1dc60509f8eb7790bc8d11f9a70d99b9dd18dfdd81a084ffe6"}, + {file = "tiktoken-0.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5bf5ce759089f4f6521ea6ed89d8f988f7b396e9f4afb503b945f5c949c6bec2"}, + {file = "tiktoken-0.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0c964f554af1a96884e01188f480dad3fc224c4bbcf7af75d4b74c4b74ae0125"}, + {file = "tiktoken-0.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:368dd5726d2e8788e47ea04f32e20f72a2012a8a67af5b0b003d1e059f1d30a3"}, + {file = "tiktoken-0.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a2deef9115b8cd55536c0a02c0203512f8deb2447f41585e6d929a0b878a0dd2"}, + {file = "tiktoken-0.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2ed7d380195affbf886e2f8b92b14edfe13f4768ff5fc8de315adba5b773815e"}, + {file = "tiktoken-0.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76fce01309c8140ffe15eb34ded2bb94789614b7d1d09e206838fc173776a18"}, + {file = "tiktoken-0.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60a5654d6a2e2d152637dd9a880b4482267dfc8a86ccf3ab1cec31a8c76bfae8"}, + {file = "tiktoken-0.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41d4d3228e051b779245a8ddd21d4336f8975563e92375662f42d05a19bdff41"}, + {file = "tiktoken-0.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c1cdec2c92fcde8c17a50814b525ae6a88e8e5b02030dc120b76e11db93f13"}, + {file = "tiktoken-0.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:84ddb36faedb448a50b246e13d1b6ee3437f60b7169b723a4b2abad75e914f3e"}, + {file = "tiktoken-0.5.2.tar.gz", hash = "sha256:f54c581f134a8ea96ce2023ab221d4d4d81ab614efa0b2fbce926387deb56c80"}, ] [package.dependencies] @@ -8260,4 +8312,4 @@ youtube = ["youtube-transcript-api", "yt_dlp"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "a16addd3362ae70c79b15677c6815f708677f11f636093f4e1f5084ba44b5a36" +content-hash = "7efcfdf75c6295ff7fe98e6eb19f98f4dd3aab789033999ea0d90e621826e66a" diff --git a/pyproject.toml b/pyproject.toml index 00142127..bea985aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,7 +93,7 @@ color = true [tool.poetry.dependencies] python = ">=3.9,<3.12" python-dotenv = "^1.0.0" -langchain = "^0.0.336" +langchain = "^0.1.4" requests = "^2.31.0" openai = ">=1.1.1" chromadb = "^0.4.17" @@ -103,7 +103,7 @@ beautifulsoup4 = "^4.12.2" pypdf = "^3.11.0" gptcache = "^0.1.43" pysbd = "^0.3.4" -tiktoken = { version = "^0.4.0", optional = true } +tiktoken = { version = "^0.5.2", optional = true } youtube-transcript-api = { version = "^0.6.1", optional = true } pytube = { version = "^15.0.0", optional = true } duckduckgo-search = { version = "^3.8.5", optional = true } @@ -151,6 +151,7 @@ google-auth-httplib2 = { version = "^0.2.0", optional = true } google-api-core = { version = "^2.15.0", optional = true } boto3 = { version = "^1.34.20", optional = true } langchain-mistralai = { version = "^0.0.3", optional = true } +langchain-openai = "^0.0.5" [tool.poetry.group.dev.dependencies] black = "^23.3.0" diff --git a/tests/llm/test_anthrophic.py b/tests/llm/test_anthrophic.py index fa281dbf..d3a71715 100644 --- a/tests/llm/test_anthrophic.py +++ b/tests/llm/test_anthrophic.py @@ -24,7 +24,7 @@ def test_get_llm_model_answer(anthropic_llm): def test_get_answer(anthropic_llm): - with patch("langchain.chat_models.ChatAnthropic") as mock_chat: + with patch("langchain_community.chat_models.ChatAnthropic") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response") @@ -53,7 +53,7 @@ def test_get_messages(anthropic_llm): def test_get_answer_max_tokens_is_provided(anthropic_llm, caplog): - with patch("langchain.chat_models.ChatAnthropic") as mock_chat: + with patch("langchain_community.chat_models.ChatAnthropic") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response") diff --git a/tests/llm/test_azure_openai.py b/tests/llm/test_azure_openai.py index 9ab3479d..5004f846 100644 --- a/tests/llm/test_azure_openai.py +++ b/tests/llm/test_azure_openai.py @@ -28,7 +28,7 @@ def test_get_llm_model_answer(azure_openai_llm): def test_get_answer(azure_openai_llm): - with patch("langchain.chat_models.AzureChatOpenAI") as mock_chat: + with patch("langchain_community.chat_models.AzureChatOpenAI") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response") @@ -60,7 +60,7 @@ def test_get_messages(azure_openai_llm): def test_get_answer_top_p_is_provided(azure_openai_llm, caplog): - with patch("langchain.chat_models.AzureChatOpenAI") as mock_chat: + with patch("langchain_community.chat_models.AzureChatOpenAI") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response") diff --git a/tests/llm/test_gpt4all.py b/tests/llm/test_gpt4all.py index 11915912..a65f5aa5 100644 --- a/tests/llm/test_gpt4all.py +++ b/tests/llm/test_gpt4all.py @@ -1,5 +1,5 @@ import pytest -from langchain.llms.gpt4all import GPT4All as LangchainGPT4All +from langchain_community.llms.gpt4all import GPT4All as LangchainGPT4All from embedchain.config import BaseLlmConfig from embedchain.llm.gpt4all import GPT4ALLLlm diff --git a/tests/llm/test_openai.py b/tests/llm/test_openai.py index 73a3146a..c39d52da 100644 --- a/tests/llm/test_openai.py +++ b/tests/llm/test_openai.py @@ -74,3 +74,32 @@ def test_get_llm_model_answer_without_system_prompt(config, mocker): model_kwargs={"top_p": config.top_p}, api_key=os.environ["OPENAI_API_KEY"], ) + + +@pytest.mark.parametrize( + "mock_return, expected", + [ + ([{"test": "test"}], '{"test": "test"}'), + ([], "Input could not be mapped to the function!"), + ], +) +def test_get_llm_model_answer_with_tools(config, mocker, mock_return, expected): + mocked_openai_chat = mocker.patch("embedchain.llm.openai.ChatOpenAI") + mocked_convert_to_openai_tool = mocker.patch("langchain_core.utils.function_calling.convert_to_openai_tool") + mocked_json_output_tools_parser = mocker.patch("langchain.output_parsers.openai_tools.JsonOutputToolsParser") + mocked_openai_chat.return_value.bind.return_value.pipe.return_value.invoke.return_value = mock_return + + llm = OpenAILlm(config, tools={"test": "test"}) + answer = llm.get_llm_model_answer("Test query") + + mocked_openai_chat.assert_called_once_with( + model=config.model, + temperature=config.temperature, + max_tokens=config.max_tokens, + model_kwargs={"top_p": config.top_p}, + api_key=os.environ["OPENAI_API_KEY"], + ) + mocked_convert_to_openai_tool.assert_called_once_with({"test": "test"}) + mocked_json_output_tools_parser.assert_called_once() + + assert answer == expected diff --git a/tests/llm/test_vertex_ai.py b/tests/llm/test_vertex_ai.py index a9cfeeed..e21f969c 100644 --- a/tests/llm/test_vertex_ai.py +++ b/tests/llm/test_vertex_ai.py @@ -22,7 +22,7 @@ def test_get_llm_model_answer(vertexai_llm): def test_get_answer_with_warning(vertexai_llm, caplog): - with patch("langchain.chat_models.ChatVertexAI") as mock_chat: + with patch("langchain_community.chat_models.ChatVertexAI") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response") @@ -39,7 +39,7 @@ def test_get_answer_with_warning(vertexai_llm, caplog): def test_get_answer_no_warning(vertexai_llm, caplog): - with patch("langchain.chat_models.ChatVertexAI") as mock_chat: + with patch("langchain_community.chat_models.ChatVertexAI") as mock_chat: mock_chat_instance = mock_chat.return_value mock_chat_instance.return_value = MagicMock(content="Test Response")