diff --git a/docs/trulens_eval/all_tools.ipynb b/docs/trulens_eval/all_tools.ipynb index 39bde7bc5..51eb60527 100644 --- a/docs/trulens_eval/all_tools.ipynb +++ b/docs/trulens_eval/all_tools.ipynb @@ -28,7 +28,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval openai langchain langchain-openai faiss-cpu bs4 tiktoken" + "# ! pip install trulens_eval openai langchain langchain-openai langchain_community faiss-cpu bs4 tiktoken" ] }, { diff --git a/trulens_eval/examples/expositional/end2end_apps/trubot/webindex.ipynb b/trulens_eval/examples/expositional/end2end_apps/trubot/webindex.ipynb index 911cdc46f..2482f0c10 100644 --- a/trulens_eval/examples/expositional/end2end_apps/trubot/webindex.ipynb +++ b/trulens_eval/examples/expositional/end2end_apps/trubot/webindex.ipynb @@ -10,7 +10,7 @@ "## Additional requirements:\n", "\n", "```bash\n", - "pip install humanize pdfreader url_normalize tabulate unstructured\n", + "pip install humanize pdfreader url_normalize tabulate unstructured langchain_community\n", "```" ] }, @@ -20,7 +20,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install humanize pdfreader url_normalize tabulate unstructured" + "# ! pip install humanize pdfreader url_normalize tabulate unstructured langchain_community" ] }, { diff --git a/trulens_eval/examples/expositional/frameworks/langchain/langchain_groundtruth.ipynb b/trulens_eval/examples/expositional/frameworks/langchain/langchain_groundtruth.ipynb index 88ee0119e..bcd2794b9 100644 --- a/trulens_eval/examples/expositional/frameworks/langchain/langchain_groundtruth.ipynb +++ b/trulens_eval/examples/expositional/frameworks/langchain/langchain_groundtruth.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Import from LlamaIndex and TruLens" + "### Import from _LangChain_ and TruLens" ] }, { @@ -28,7 +28,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval==0.18.1 langchain>=0.0.342" + "# ! pip install trulens_eval==0.18.1 langchain>=0.0.342 langchain_community" ] }, { diff --git a/trulens_eval/examples/expositional/frameworks/langchain/langchain_model_comparison.ipynb b/trulens_eval/examples/expositional/frameworks/langchain/langchain_model_comparison.ipynb index 731ef6d73..1926cd03d 100644 --- a/trulens_eval/examples/expositional/frameworks/langchain/langchain_model_comparison.ipynb +++ b/trulens_eval/examples/expositional/frameworks/langchain/langchain_model_comparison.ipynb @@ -28,7 +28,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval==0.11.0 langchain==0.0.283" + "# ! pip install trulens_eval==0.11.0 langchain==0.0.283 langchain_community" ] }, { diff --git a/trulens_eval/examples/expositional/frameworks/langchain/langchain_summarize.ipynb b/trulens_eval/examples/expositional/frameworks/langchain/langchain_summarize.ipynb index 7c451eb3c..6e3b865b7 100644 --- a/trulens_eval/examples/expositional/frameworks/langchain/langchain_summarize.ipynb +++ b/trulens_eval/examples/expositional/frameworks/langchain/langchain_summarize.ipynb @@ -26,7 +26,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval==0.11.0 langchain==0.0.283" + "# ! pip install trulens_eval==0.11.0 langchain==0.0.283 langchain_community" ] }, { diff --git a/trulens_eval/examples/expositional/models/Vectara_HHEM_evaluator.ipynb b/trulens_eval/examples/expositional/models/Vectara_HHEM_evaluator.ipynb index bcb7a9387..12d527d25 100644 --- a/trulens_eval/examples/expositional/models/Vectara_HHEM_evaluator.ipynb +++ b/trulens_eval/examples/expositional/models/Vectara_HHEM_evaluator.ipynb @@ -33,7 +33,7 @@ "metadata": {}, "outputs": [], "source": [ - "#!pip install langchain==0.0.354 ,langchain-community==0.0.20 ,langchain-core==0.1.23,trulens_eval" + "#!pip install 'langchain==0.0.354' 'langchain-community==0.0.20' 'langchain-core==0.1.23' 'trulens_eval'" ] }, { diff --git a/trulens_eval/examples/expositional/use_cases/pii_detection.ipynb b/trulens_eval/examples/expositional/use_cases/pii_detection.ipynb index c40271a7e..f209da7b1 100644 --- a/trulens_eval/examples/expositional/use_cases/pii_detection.ipynb +++ b/trulens_eval/examples/expositional/use_cases/pii_detection.ipynb @@ -18,7 +18,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval==0.14.0 langchain>=0.0.263" + "# ! pip install 'trulens_eval==0.14.0' 'langchain>=0.0.263' langchain_community" ] }, { diff --git a/trulens_eval/examples/expositional/vector-dbs/pinecone/pinecone_evals_build_better_rags.ipynb b/trulens_eval/examples/expositional/vector-dbs/pinecone/pinecone_evals_build_better_rags.ipynb index f49c90918..751405b72 100644 --- a/trulens_eval/examples/expositional/vector-dbs/pinecone/pinecone_evals_build_better_rags.ipynb +++ b/trulens_eval/examples/expositional/vector-dbs/pinecone/pinecone_evals_build_better_rags.ipynb @@ -41,7 +41,7 @@ "metadata": {}, "outputs": [], "source": [ - "!pip install -qU trulens-eval==0.16.0 langchain==0.0.315 openai==0.28.1 tiktoken==0.5.1 \"pinecone-client[grpc]==2.2.4\" pinecone-datasets==0.5.1 datasets==2.14.5" + "!pip install -qU trulens-eval==0.16.0 langchain==0.0.315 openai==0.28.1 tiktoken==0.5.1 \"pinecone-client[grpc]==2.2.4\" pinecone-datasets==0.5.1 datasets==2.14.5 langchain_community" ] }, { diff --git a/trulens_eval/examples/quickstart/langchain_quickstart.ipynb b/trulens_eval/examples/quickstart/langchain_quickstart.ipynb index 58cafe9a4..b717c5c23 100644 --- a/trulens_eval/examples/quickstart/langchain_quickstart.ipynb +++ b/trulens_eval/examples/quickstart/langchain_quickstart.ipynb @@ -28,7 +28,7 @@ "metadata": {}, "outputs": [], "source": [ - "# ! pip install trulens_eval openai langchain langchain-openai faiss-cpu bs4 tiktoken" + "# ! pip install trulens_eval openai langchain langchain-openai langchain_community faiss-cpu bs4 tiktoken" ] }, { @@ -434,7 +434,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.12.3" }, "vscode": { "interpreter": { diff --git a/trulens_eval/trulens_eval/Example_TruBot.py b/trulens_eval/trulens_eval/Example_TruBot.py index 914ce29b2..a090bf271 100644 --- a/trulens_eval/trulens_eval/Example_TruBot.py +++ b/trulens_eval/trulens_eval/Example_TruBot.py @@ -3,11 +3,8 @@ os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python' from langchain.chains import ConversationalRetrievalChain -from langchain.embeddings.openai import OpenAIEmbeddings from langchain.memory import ConversationSummaryBufferMemory -from langchain_community.callbacks import get_openai_callback -from langchain_community.llms import OpenAI -from langchain_community.vectorstores import Pinecone + import numpy as np import streamlit as st @@ -22,8 +19,14 @@ with OptionalImports(messages=REQUIREMENT_PINECONE): import pinecone + import langchain_community + from langchain_community.callbacks import get_openai_callback + from langchain_community.llms import OpenAI + from langchain.embeddings.openai import OpenAIEmbeddings -OptionalImports(messages=REQUIREMENT_PINECONE).assert_installed(pinecone) +OptionalImports(messages=REQUIREMENT_PINECONE).assert_installed( + mods=[pinecone, langchain_community, OpenAIEmbeddings] +) check_keys("OPENAI_API_KEY", "PINECONE_API_KEY", "PINECONE_ENV") diff --git a/trulens_eval/trulens_eval/feedback/provider/endpoint/openai.py b/trulens_eval/trulens_eval/feedback/provider/endpoint/openai.py index 5918271d5..677f84d55 100644 --- a/trulens_eval/trulens_eval/feedback/provider/endpoint/openai.py +++ b/trulens_eval/trulens_eval/feedback/provider/endpoint/openai.py @@ -25,7 +25,6 @@ import pprint from typing import Any, Callable, ClassVar, Dict, List, Optional, Union -from langchain.callbacks.openai_info import OpenAICallbackHandler from langchain.schema import Generation from langchain.schema import LLMResult import pydantic @@ -44,8 +43,13 @@ with OptionalImports(messages=REQUIREMENT_OPENAI): import openai as oai -# check that oai is not a dummy: -OptionalImports(messages=REQUIREMENT_OPENAI).assert_installed(oai) + # This is also required for running openai endpoints in trulens_eval: + from langchain.callbacks.openai_info import OpenAICallbackHandler + +# check that oai is not a dummy, also the langchain component required for handling openai endpoint +OptionalImports(messages=REQUIREMENT_OPENAI).assert_installed( + mods=[oai, OpenAICallbackHandler] +) logger = logging.getLogger(__name__) diff --git a/trulens_eval/trulens_eval/requirements.optional.txt b/trulens_eval/trulens_eval/requirements.optional.txt index 39eb9c0cb..11aa51561 100644 --- a/trulens_eval/trulens_eval/requirements.optional.txt +++ b/trulens_eval/trulens_eval/requirements.optional.txt @@ -9,7 +9,7 @@ evaluate >= 0.4.0 # same # Apps: LangChain (optional parts) langchainhub >= 0.1.14 # example notebooks -langchain_community >= 0.0.17 # example notebooks, now required for Pinecone, others +langchain_community >= 0.0.17 # example notebooks, openai endpoint, now required for Pinecone, others langchain_openai >= 0.0.5 # unit tests, sample apps # Apps: LlamaIndex diff --git a/trulens_eval/trulens_eval/utils/imports.py b/trulens_eval/trulens_eval/utils/imports.py index 6fd7421b4..e378a1d2e 100644 --- a/trulens_eval/trulens_eval/utils/imports.py +++ b/trulens_eval/trulens_eval/utils/imports.py @@ -13,14 +13,13 @@ from pathlib import Path from pprint import PrettyPrinter import sys -from typing import Any, Dict, Optional, Sequence, Type, Union +from typing import Any, Dict, Iterable, Optional, Sequence, Type, Union from packaging import requirements from packaging import version from pip._internal.req import parse_requirements from trulens_eval import __name__ as trulens_name -from trulens_eval.utils.text import retab logger = logging.getLogger(__name__) pp = PrettyPrinter() @@ -338,7 +337,7 @@ def format_import_errors( REQUIREMENT_PINECONE = format_import_errors( # package name is "pinecone-client" but module is "pinecone" - 'pinecone-client', + ['pinecone-client', 'langchain_community'], purpose="running TruBot" ) @@ -355,7 +354,7 @@ def format_import_errors( ) REQUIREMENT_OPENAI = format_import_errors( - 'openai', purpose="using OpenAI models" + ['openai', 'langchain_community'], purpose="using OpenAI models" ) REQUIREMENT_GROUNDEDNESS = format_import_errors( @@ -445,7 +444,7 @@ def __init__(self, name: str, *args, **kwargs): self.original_exception = original_exception def __call__(self, *args, **kwargs): - raise self.exception_class(self.message) + raise self.exception_class(self.message) from self.original_exception def __instancecheck__(self, __instance: Any) -> bool: """Nothing is an instance of this dummy. @@ -463,7 +462,7 @@ def __subclasscheck__(self, __subclass: type) -> bool: return False def _wasused(self, *args, **kwargs): - raise self.exception_class(self.message) + raise self.exception_class(self.message) from self.original_exception # If someone tries to use dummy in an expression, raise our usage exception: __add__ = _wasused @@ -536,12 +535,15 @@ class OptionalImports(object): specified message (unless llama_index is installed of course). """ - def assert_installed(self, mod): + def assert_installed(self, mods: Union[Any, Iterable[Any]]): """ - Check that the given module `mod` is not a dummy. If it is, show the + Check that the given modules `mods` are not dummies. If any is, show the optional requirement message. """ - if isinstance(mod, Dummy): + if not isinstance(mods, Iterable): + mods = [mods] + + if any(isinstance(mod, Dummy) for mod in mods): raise ModuleNotFoundError(self.messages.module_not_found) def __init__(self, messages: ImportErrorMessages, fail: bool = False): @@ -659,9 +661,7 @@ def __exit__(self, exc_type, exc_value, exc_tb): raise exc_value raise ModuleNotFoundError( - self.messages.module_not_found + - "\nError that caused this problem:\n\n" + - retab(tab=" ", s=repr(exc_value)) + self.messages.module_not_found ) from exc_value elif isinstance(exc_value, ImportError): @@ -670,9 +670,7 @@ def __exit__(self, exc_type, exc_value, exc_tb): raise exc_value raise ImportError( - self.messages.import_error + - "\nError that caused this problem:\n\n" + - retab(tab=" ", s=repr(exc_value)) + self.messages.import_error ) from exc_value # Exception will be propagated unless we return True so we don't return it.