mirror of
https://github.com/Mintplex-Labs/langchain-python.git
synced 2026-07-18 10:24:29 -04:00
added docstrings where they missed (#6626)
This PR targets the `API Reference` documentation.
- Several classes and functions missed `docstrings`. These docstrings
were created.
- In several places this
```
except ImportError:
raise ValueError(
```
was replaced to
```
except ImportError:
raise ImportError(
```
This commit is contained in:
@@ -2,6 +2,8 @@ from enum import Enum
|
||||
|
||||
|
||||
class AgentType(str, Enum):
|
||||
"""Enumerator with the Agent types."""
|
||||
|
||||
ZERO_SHOT_REACT_DESCRIPTION = "zero-shot-react-description"
|
||||
REACT_DOCSTORE = "react-docstore"
|
||||
SELF_ASK_WITH_SEARCH = "self-ask-with-search"
|
||||
|
||||
@@ -352,10 +352,23 @@ def load_huggingface_tool(
|
||||
remote: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> BaseTool:
|
||||
"""Loads a tool from the HuggingFace Hub.
|
||||
|
||||
Args:
|
||||
task_or_repo_id: Task or model repo id.
|
||||
model_repo_id: Optional model repo id.
|
||||
token: Optional token.
|
||||
remote: Optional remote. Defaults to False.
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
A tool.
|
||||
|
||||
"""
|
||||
try:
|
||||
from transformers import load_tool
|
||||
except ImportError:
|
||||
raise ValueError(
|
||||
raise ImportError(
|
||||
"HuggingFace tools require the libraries `transformers>=4.29.0`"
|
||||
" and `huggingface_hub>=0.14.1` to be installed."
|
||||
" Please install it with"
|
||||
|
||||
@@ -6,6 +6,7 @@ from langchain.schema import AgentAction, AgentFinish, LLMResult
|
||||
|
||||
|
||||
def import_aim() -> Any:
|
||||
"""Import the aim python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import aim
|
||||
except ImportError:
|
||||
|
||||
@@ -17,6 +17,7 @@ from langchain.schema import AgentAction, AgentFinish, LLMResult
|
||||
|
||||
|
||||
def import_clearml() -> Any:
|
||||
"""Import the clearml python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import clearml # noqa: F401
|
||||
except ImportError:
|
||||
|
||||
@@ -20,6 +20,7 @@ from langchain.utils import get_from_dict_or_env
|
||||
|
||||
|
||||
def import_mlflow() -> Any:
|
||||
"""Import the mlflow python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import mlflow
|
||||
except ImportError:
|
||||
|
||||
@@ -52,6 +52,17 @@ def standardize_model_name(
|
||||
model_name: str,
|
||||
is_completion: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
Standardize the model name to a format that can be used in the OpenAI API.
|
||||
Args:
|
||||
model_name: Model name to standardize.
|
||||
is_completion: Whether the model is used for completion or not.
|
||||
Defaults to False.
|
||||
|
||||
Returns:
|
||||
Standardized model name.
|
||||
|
||||
"""
|
||||
model_name = model_name.lower()
|
||||
if "ft-" in model_name:
|
||||
return model_name.split(":")[0] + "-finetuned"
|
||||
@@ -66,6 +77,18 @@ def standardize_model_name(
|
||||
def get_openai_token_cost_for_model(
|
||||
model_name: str, num_tokens: int, is_completion: bool = False
|
||||
) -> float:
|
||||
"""
|
||||
Get the cost in USD for a given model and number of tokens.
|
||||
|
||||
Args:
|
||||
model_name: Name of the model
|
||||
num_tokens: Number of tokens.
|
||||
is_completion: Whether the model is used for completion or not.
|
||||
Defaults to False.
|
||||
|
||||
Returns:
|
||||
Cost in USD.
|
||||
"""
|
||||
model_name = standardize_model_name(model_name, is_completion=is_completion)
|
||||
if model_name not in MODEL_COST_PER_1K_TOKENS:
|
||||
raise ValueError(
|
||||
|
||||
@@ -7,6 +7,16 @@ from langchain.input import get_bolded_text, get_colored_text
|
||||
|
||||
|
||||
def try_json_stringify(obj: Any, fallback: str) -> str:
|
||||
"""
|
||||
Try to stringify an object to JSON.
|
||||
Args:
|
||||
obj: Object to stringify.
|
||||
fallback: Fallback string to return if the object cannot be stringified.
|
||||
|
||||
Returns:
|
||||
A JSON string if the object can be stringified, otherwise the fallback string.
|
||||
|
||||
"""
|
||||
try:
|
||||
return json.dumps(obj, indent=2, ensure_ascii=False)
|
||||
except Exception:
|
||||
@@ -14,6 +24,16 @@ def try_json_stringify(obj: Any, fallback: str) -> str:
|
||||
|
||||
|
||||
def elapsed(run: Any) -> str:
|
||||
"""Get the elapsed time of a run.
|
||||
|
||||
Args:
|
||||
run: any object with a start_time and end_time attribute.
|
||||
|
||||
Returns:
|
||||
A string with the elapsed time in seconds or
|
||||
milliseconds if time is less than a second.
|
||||
|
||||
"""
|
||||
elapsed_time = run.end_time - run.start_time
|
||||
milliseconds = elapsed_time.total_seconds() * 1000
|
||||
if milliseconds < 1000:
|
||||
@@ -22,6 +42,8 @@ def elapsed(run: Any) -> str:
|
||||
|
||||
|
||||
class ConsoleCallbackHandler(BaseTracer):
|
||||
"""Tracer that prints to the console."""
|
||||
|
||||
name = "console_callback_handler"
|
||||
|
||||
def _persist_run(self, run: Run) -> None:
|
||||
|
||||
@@ -137,6 +137,8 @@ def _replace_type_with_kind(data: Any) -> Any:
|
||||
|
||||
|
||||
class WandbRunArgs(TypedDict):
|
||||
"""Arguments for the WandbTracer."""
|
||||
|
||||
job_type: Optional[str]
|
||||
dir: Optional[StrPath]
|
||||
config: Union[Dict, str, None]
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Any, Dict, Iterable, Tuple, Union
|
||||
|
||||
|
||||
def import_spacy() -> Any:
|
||||
"""Import the spacy python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import spacy
|
||||
except ImportError:
|
||||
@@ -15,6 +16,7 @@ def import_spacy() -> Any:
|
||||
|
||||
|
||||
def import_pandas() -> Any:
|
||||
"""Import the pandas python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import pandas
|
||||
except ImportError:
|
||||
@@ -26,6 +28,7 @@ def import_pandas() -> Any:
|
||||
|
||||
|
||||
def import_textstat() -> Any:
|
||||
"""Import the textstat python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import textstat
|
||||
except ImportError:
|
||||
|
||||
@@ -17,6 +17,7 @@ from langchain.schema import AgentAction, AgentFinish, LLMResult
|
||||
|
||||
|
||||
def import_wandb() -> Any:
|
||||
"""Import the wandb python package and raise an error if it is not installed."""
|
||||
try:
|
||||
import wandb # noqa: F401
|
||||
except ImportError:
|
||||
|
||||
@@ -18,6 +18,16 @@ def import_langkit(
|
||||
toxicity: bool = False,
|
||||
themes: bool = False,
|
||||
) -> Any:
|
||||
"""Import the langkit python package and raise an error if it is not installed.
|
||||
|
||||
Args:
|
||||
sentiment: Whether to import the langkit.sentiment module. Defaults to False.
|
||||
toxicity: Whether to import the langkit.toxicity module. Defaults to False.
|
||||
themes: Whether to import the langkit.themes module. Defaults to False.
|
||||
|
||||
Returns:
|
||||
The imported langkit module.
|
||||
"""
|
||||
try:
|
||||
import langkit # noqa: F401
|
||||
import langkit.regexes # noqa: F401
|
||||
|
||||
@@ -18,6 +18,14 @@ INTERMEDIATE_STEPS_KEY = "intermediate_steps"
|
||||
|
||||
|
||||
def extract_cypher(text: str) -> str:
|
||||
"""
|
||||
Extract Cypher code from a text.
|
||||
Args:
|
||||
text: Text to extract Cypher code from.
|
||||
|
||||
Returns:
|
||||
Cypher code extracted from the text.
|
||||
"""
|
||||
# The pattern to find Cypher code enclosed in triple backticks
|
||||
pattern = r"```(.*?)```"
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ black_listed_elements: Set[str] = {
|
||||
|
||||
|
||||
class ElementInViewPort(TypedDict):
|
||||
"""A typed dictionary containing information about elements in the viewport."""
|
||||
|
||||
node_index: str
|
||||
backend_node_id: int
|
||||
node_name: Optional[str]
|
||||
@@ -51,7 +53,7 @@ class Crawler:
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
except ImportError:
|
||||
raise ValueError(
|
||||
raise ImportError(
|
||||
"Could not import playwright python package. "
|
||||
"Please install it with `pip install playwright`."
|
||||
)
|
||||
|
||||
@@ -64,6 +64,14 @@ class QuestionAnswer(BaseModel):
|
||||
|
||||
|
||||
def create_citation_fuzzy_match_chain(llm: BaseLanguageModel) -> LLMChain:
|
||||
"""Create a citation fuzzy match chain.
|
||||
|
||||
Args:
|
||||
llm: Language model to use for the chain.
|
||||
|
||||
Returns:
|
||||
Chain (LLMChain) that can be used to answer questions with citations.
|
||||
"""
|
||||
output_parser = PydanticOutputFunctionsParser(pydantic_schema=QuestionAnswer)
|
||||
schema = QuestionAnswer.schema()
|
||||
function = {
|
||||
|
||||
@@ -40,6 +40,15 @@ Passage:
|
||||
|
||||
|
||||
def create_extraction_chain(schema: dict, llm: BaseLanguageModel) -> Chain:
|
||||
"""Creates a chain that extracts information from a passage.
|
||||
|
||||
Args:
|
||||
schema: The schema of the entities to extract.
|
||||
llm: The language model to use.
|
||||
|
||||
Returns:
|
||||
Chain that can be used to extract information from a passage.
|
||||
"""
|
||||
function = _get_extraction_function(schema)
|
||||
prompt = ChatPromptTemplate.from_template(_EXTRACTION_TEMPLATE)
|
||||
output_parser = JsonKeyOutputFunctionsParser(key_name="info")
|
||||
@@ -56,6 +65,16 @@ def create_extraction_chain(schema: dict, llm: BaseLanguageModel) -> Chain:
|
||||
def create_extraction_chain_pydantic(
|
||||
pydantic_schema: Any, llm: BaseLanguageModel
|
||||
) -> Chain:
|
||||
"""Creates a chain that extracts information from a passage using pydantic schema.
|
||||
|
||||
Args:
|
||||
pydantic_schema: The pydantic schema of the entities to extract.
|
||||
llm: The language model to use.
|
||||
|
||||
Returns:
|
||||
Chain that can be used to extract information from a passage.
|
||||
"""
|
||||
|
||||
class PydanticSchema(BaseModel):
|
||||
info: List[pydantic_schema] # type: ignore
|
||||
|
||||
|
||||
@@ -29,6 +29,18 @@ def create_qa_with_structure_chain(
|
||||
output_parser: str = "base",
|
||||
prompt: Optional[Union[PromptTemplate, ChatPromptTemplate]] = None,
|
||||
) -> LLMChain:
|
||||
"""Create a question answering chain that returns an answer with sources.
|
||||
|
||||
Args:
|
||||
llm: Language model to use for the chain.
|
||||
schema: Pydantic schema to use for the output.
|
||||
output_parser: Output parser to use. Should be one of `pydantic` or `base`.
|
||||
Default to `base`.
|
||||
prompt: Optional prompt to use for the chain.
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if output_parser == "pydantic":
|
||||
if not (isinstance(schema, type) and issubclass(schema, BaseModel)):
|
||||
raise ValueError(
|
||||
@@ -79,4 +91,13 @@ def create_qa_with_structure_chain(
|
||||
|
||||
|
||||
def create_qa_with_sources_chain(llm: BaseLanguageModel, **kwargs: Any) -> LLMChain:
|
||||
"""Create a question answering chain that returns an answer with sources.
|
||||
|
||||
Args:
|
||||
llm: Language model to use for the chain.
|
||||
**kwargs: Keyword arguments to pass to `create_qa_with_structure_chain`.
|
||||
|
||||
Returns:
|
||||
Chain (LLMChain) that can be used to answer questions with citations.
|
||||
"""
|
||||
return create_qa_with_structure_chain(llm, AnswerWithSources, **kwargs)
|
||||
|
||||
@@ -27,6 +27,15 @@ Passage:
|
||||
|
||||
|
||||
def create_tagging_chain(schema: dict, llm: BaseLanguageModel) -> Chain:
|
||||
"""Creates a chain that extracts information from a passage.
|
||||
|
||||
Args:
|
||||
schema: The schema of the entities to extract.
|
||||
llm: The language model to use.
|
||||
|
||||
Returns:
|
||||
Chain (LLMChain) that can be used to extract information from a passage.
|
||||
"""
|
||||
function = _get_tagging_function(schema)
|
||||
prompt = ChatPromptTemplate.from_template(_TAGGING_TEMPLATE)
|
||||
output_parser = JsonOutputFunctionsParser()
|
||||
@@ -43,6 +52,15 @@ def create_tagging_chain(schema: dict, llm: BaseLanguageModel) -> Chain:
|
||||
def create_tagging_chain_pydantic(
|
||||
pydantic_schema: Any, llm: BaseLanguageModel
|
||||
) -> Chain:
|
||||
"""Creates a chain that extracts information from a passage.
|
||||
|
||||
Args:
|
||||
pydantic_schema: The pydantic schema of the entities to extract.
|
||||
llm: The language model to use.
|
||||
|
||||
Returns:
|
||||
Chain (LLMChain) that can be used to extract information from a passage.
|
||||
"""
|
||||
openai_schema = pydantic_schema.schema()
|
||||
function = _get_tagging_function(openai_schema)
|
||||
prompt = ChatPromptTemplate.from_template(_TAGGING_TEMPLATE)
|
||||
|
||||
@@ -29,4 +29,12 @@ def _convert_schema(schema: dict) -> dict:
|
||||
|
||||
|
||||
def get_llm_kwargs(function: dict) -> dict:
|
||||
"""Returns the kwargs for the LLMChain constructor.
|
||||
|
||||
Args:
|
||||
function: The function to use.
|
||||
|
||||
Returns:
|
||||
The kwargs for the LLMChain constructor.
|
||||
"""
|
||||
return {"functions": [function], "function_call": {"name": function["name"]}}
|
||||
|
||||
@@ -31,8 +31,24 @@ class ConditionalPromptSelector(BasePromptSelector):
|
||||
|
||||
|
||||
def is_llm(llm: BaseLanguageModel) -> bool:
|
||||
"""Check if the language model is a LLM.
|
||||
|
||||
Args:
|
||||
llm: Language model to check.
|
||||
|
||||
Returns:
|
||||
True if the language model is a BaseLLM model, False otherwise.
|
||||
"""
|
||||
return isinstance(llm, BaseLLM)
|
||||
|
||||
|
||||
def is_chat_model(llm: BaseLanguageModel) -> bool:
|
||||
"""Check if the language model is a chat model.
|
||||
|
||||
Args:
|
||||
llm: Language model to check.
|
||||
|
||||
Returns:
|
||||
True if the language model is a BaseChatModel model, False otherwise.
|
||||
"""
|
||||
return isinstance(llm, BaseChatModel)
|
||||
|
||||
@@ -123,6 +123,22 @@ def load_query_constructor_chain(
|
||||
enable_limit: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> LLMChain:
|
||||
"""
|
||||
Load a query constructor chain.
|
||||
Args:
|
||||
llm: BaseLanguageModel to use for the chain.
|
||||
document_contents: The contents of the document to be queried.
|
||||
attribute_info: A list of AttributeInfo objects describing
|
||||
the attributes of the document.
|
||||
examples: Optional list of examples to use for the chain.
|
||||
allowed_comparators: An optional list of allowed comparators.
|
||||
allowed_operators: An optional list of allowed operators.
|
||||
enable_limit: Whether to enable the limit operator. Defaults to False.
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
A LLMChain that can be used to construct queries.
|
||||
"""
|
||||
prompt = _get_prompt(
|
||||
document_contents,
|
||||
attribute_info,
|
||||
|
||||
@@ -60,12 +60,16 @@ class Expr(BaseModel):
|
||||
|
||||
|
||||
class Operator(str, Enum):
|
||||
"""Enumerator of the operations."""
|
||||
|
||||
AND = "and"
|
||||
OR = "or"
|
||||
NOT = "not"
|
||||
|
||||
|
||||
class Comparator(str, Enum):
|
||||
"""Enumerator of the comparison operators."""
|
||||
|
||||
EQ = "eq"
|
||||
GT = "gt"
|
||||
GTE = "gte"
|
||||
|
||||
@@ -57,6 +57,9 @@ GRAMMAR = """
|
||||
|
||||
@v_args(inline=True)
|
||||
class QueryTransformer(Transformer):
|
||||
"""Transforms a query string into an IR representation
|
||||
(intermediate representation)."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*args: Any,
|
||||
@@ -136,6 +139,16 @@ def get_parser(
|
||||
allowed_comparators: Optional[Sequence[Comparator]] = None,
|
||||
allowed_operators: Optional[Sequence[Operator]] = None,
|
||||
) -> Lark:
|
||||
"""
|
||||
Returns a parser for the query language.
|
||||
|
||||
Args:
|
||||
allowed_comparators: Optional[Sequence[Comparator]]
|
||||
allowed_operators: Optional[Sequence[Operator]]
|
||||
|
||||
Returns:
|
||||
Lark parser for the query language.
|
||||
"""
|
||||
transformer = QueryTransformer(
|
||||
allowed_comparators=allowed_comparators, allowed_operators=allowed_operators
|
||||
)
|
||||
|
||||
@@ -36,6 +36,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ChatGooglePalmError(Exception):
|
||||
"""Error raised when there is an issue with the Google PaLM API."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ from langchain.document_loaders.base import BaseLoader
|
||||
|
||||
|
||||
class BlockchainType(Enum):
|
||||
"""Enumerator of the supported blockchains."""
|
||||
|
||||
ETH_MAINNET = "eth-mainnet"
|
||||
ETH_GOERLI = "eth-goerli"
|
||||
POLYGON_MAINNET = "polygon-mainnet"
|
||||
|
||||
@@ -8,6 +8,15 @@ from langchain.document_loaders.base import BaseLoader
|
||||
|
||||
|
||||
def concatenate_rows(message: dict, title: str) -> str:
|
||||
"""
|
||||
Combine message information in a readable format ready to be used.
|
||||
Args:
|
||||
message: Message to be concatenated
|
||||
title: Title of the conversation
|
||||
|
||||
Returns:
|
||||
Concatenated message
|
||||
"""
|
||||
if not message:
|
||||
return ""
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ContentFormat(str, Enum):
|
||||
"""Enumerator of the content formats of Confluence page."""
|
||||
|
||||
STORAGE = "body.storage"
|
||||
VIEW = "body.view"
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ class EmbaasDocumentExtractionParameters(TypedDict):
|
||||
|
||||
|
||||
class EmbaasDocumentExtractionPayload(EmbaasDocumentExtractionParameters):
|
||||
"""Payload for the Embaas document extraction API."""
|
||||
|
||||
bytes: str
|
||||
"""The base64 encoded bytes of the document to extract text from."""
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ from langchain.document_loaders.base import BaseLoader
|
||||
|
||||
|
||||
class FaunaLoader(BaseLoader):
|
||||
"""
|
||||
"""FaunaDB Loader.
|
||||
|
||||
Attributes:
|
||||
query (str): The FQL query string to execute.
|
||||
page_content_field (str): The field that contains the content of each page.
|
||||
|
||||
@@ -17,6 +17,8 @@ IUGU_ENDPOINTS = {
|
||||
|
||||
|
||||
class IuguLoader(BaseLoader):
|
||||
"""Loader that fetches data from IUGU."""
|
||||
|
||||
def __init__(self, resource: str, api_token: Optional[str] = None) -> None:
|
||||
self.resource = resource
|
||||
api_token = api_token or get_from_env("api_token", "IUGU_API_TOKEN")
|
||||
|
||||
@@ -27,6 +27,8 @@ incoming_payment_details",
|
||||
|
||||
|
||||
class ModernTreasuryLoader(BaseLoader):
|
||||
"""Loader that fetches data from Modern Treasury."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
resource: str,
|
||||
|
||||
@@ -7,6 +7,8 @@ from langchain.schema import Document
|
||||
|
||||
|
||||
class TextParser(BaseBlobParser):
|
||||
"""Parser for text blobs."""
|
||||
|
||||
def lazy_parse(self, blob: Blob) -> Iterator[Document]:
|
||||
"""Lazily parse the blob."""
|
||||
yield Document(page_content=blob.as_string(), metadata={"source": blob.source})
|
||||
|
||||
@@ -20,6 +20,8 @@ SPREEDLY_ENDPOINTS = {
|
||||
|
||||
|
||||
class SpreedlyLoader(BaseLoader):
|
||||
"""Loader that fetches data from Spreedly API."""
|
||||
|
||||
def __init__(self, access_token: str, resource: str) -> None:
|
||||
self.access_token = access_token
|
||||
self.resource = resource
|
||||
|
||||
@@ -18,6 +18,8 @@ STRIPE_ENDPOINTS = {
|
||||
|
||||
|
||||
class StripeLoader(BaseLoader):
|
||||
"""Loader that fetches data from Stripe."""
|
||||
|
||||
def __init__(self, resource: str, access_token: Optional[str] = None) -> None:
|
||||
self.resource = resource
|
||||
access_token = access_token or get_from_env(
|
||||
|
||||
@@ -30,6 +30,14 @@ class _DocumentWithState(Document):
|
||||
def get_stateful_documents(
|
||||
documents: Sequence[Document],
|
||||
) -> Sequence[_DocumentWithState]:
|
||||
"""Convert a list of documents to a list of documents with state.
|
||||
|
||||
Args:
|
||||
documents: The documents to convert.
|
||||
|
||||
Returns:
|
||||
A list of documents with state.
|
||||
"""
|
||||
return [_DocumentWithState.from_document(doc) for doc in documents]
|
||||
|
||||
|
||||
|
||||
@@ -18,8 +18,17 @@ class BaseAutoGPTOutputParser(BaseOutputParser):
|
||||
|
||||
|
||||
def preprocess_json_input(input_str: str) -> str:
|
||||
# Replace single backslashes with double backslashes,
|
||||
# while leaving already escaped ones intact
|
||||
"""Preprocesses a string to be parsed as json.
|
||||
|
||||
Replace single backslashes with double backslashes,
|
||||
while leaving already escaped ones intact.
|
||||
|
||||
Args:
|
||||
input_str: String to be preprocessed
|
||||
|
||||
Returns:
|
||||
Preprocessed string
|
||||
"""
|
||||
corrected_str = re.sub(
|
||||
r'(?<!\\)\\(?!["\\/bfnrt]|u[0-9a-fA-F]{4})', r"\\\\", input_str
|
||||
)
|
||||
|
||||
@@ -23,6 +23,18 @@ def load_agent_executor(
|
||||
verbose: bool = False,
|
||||
include_task_in_prompt: bool = False,
|
||||
) -> ChainExecutor:
|
||||
"""
|
||||
Load an agent executor.
|
||||
|
||||
Args:
|
||||
llm: BaseLanguageModel
|
||||
tools: List[BaseTool]
|
||||
verbose: bool. Defaults to False.
|
||||
include_task_in_prompt: bool. Defaults to False.
|
||||
|
||||
Returns:
|
||||
ChainExecutor
|
||||
"""
|
||||
input_variables = ["previous_steps", "current_step", "agent_scratchpad"]
|
||||
template = HUMAN_MESSAGE_TEMPLATE
|
||||
|
||||
|
||||
@@ -32,6 +32,15 @@ class PlanningOutputParser(PlanOutputParser):
|
||||
def load_chat_planner(
|
||||
llm: BaseLanguageModel, system_prompt: str = SYSTEM_PROMPT
|
||||
) -> LLMPlanner:
|
||||
"""
|
||||
Load a chat planner.
|
||||
Args:
|
||||
llm: Language model.
|
||||
system_prompt: System prompt.
|
||||
|
||||
Returns:
|
||||
LLMPlanner
|
||||
"""
|
||||
prompt_template = ChatPromptTemplate.from_messages(
|
||||
[
|
||||
SystemMessage(content=system_prompt),
|
||||
|
||||
@@ -5,6 +5,8 @@ from langchain.load.serializable import Serializable, to_json_not_implemented
|
||||
|
||||
|
||||
def default(obj: Any) -> Any:
|
||||
"""Return a default value for a Serializable object or
|
||||
a SerializedNotImplemented object."""
|
||||
if isinstance(obj, Serializable):
|
||||
return obj.to_json()
|
||||
else:
|
||||
@@ -12,6 +14,7 @@ def default(obj: Any) -> Any:
|
||||
|
||||
|
||||
def dumps(obj: Any, *, pretty: bool = False) -> str:
|
||||
"""Return a json string representation of an object."""
|
||||
if pretty:
|
||||
return json.dumps(obj, default=default, indent=2)
|
||||
else:
|
||||
@@ -19,4 +22,5 @@ def dumps(obj: Any, *, pretty: bool = False) -> str:
|
||||
|
||||
|
||||
def dumpd(obj: Any) -> Dict[str, Any]:
|
||||
"""Return a json dict representation of an object."""
|
||||
return json.loads(dumps(obj))
|
||||
|
||||
@@ -5,24 +5,34 @@ from pydantic import BaseModel, PrivateAttr
|
||||
|
||||
|
||||
class BaseSerialized(TypedDict):
|
||||
"""Base class for serialized objects."""
|
||||
|
||||
lc: int
|
||||
id: List[str]
|
||||
|
||||
|
||||
class SerializedConstructor(BaseSerialized):
|
||||
"""Serialized constructor."""
|
||||
|
||||
type: Literal["constructor"]
|
||||
kwargs: Dict[str, Any]
|
||||
|
||||
|
||||
class SerializedSecret(BaseSerialized):
|
||||
"""Serialized secret."""
|
||||
|
||||
type: Literal["secret"]
|
||||
|
||||
|
||||
class SerializedNotImplemented(BaseSerialized):
|
||||
"""Serialized not implemented."""
|
||||
|
||||
type: Literal["not_implemented"]
|
||||
|
||||
|
||||
class Serializable(BaseModel, ABC):
|
||||
"""Serializable base class."""
|
||||
|
||||
@property
|
||||
def lc_serializable(self) -> bool:
|
||||
"""
|
||||
@@ -130,6 +140,14 @@ def _replace_secrets(
|
||||
|
||||
|
||||
def to_json_not_implemented(obj: object) -> SerializedNotImplemented:
|
||||
"""Serialize a "not implemented" object.
|
||||
|
||||
Args:
|
||||
obj: object to serialize
|
||||
|
||||
Returns:
|
||||
SerializedNotImplemented
|
||||
"""
|
||||
_id: List[str] = []
|
||||
try:
|
||||
if hasattr(obj, "__name__"):
|
||||
|
||||
@@ -15,6 +15,8 @@ DEFAULT_CONNECTION_STRING = "postgresql://postgres:mypassword@localhost/chat_his
|
||||
|
||||
|
||||
class PostgresChatMessageHistory(BaseChatMessageHistory):
|
||||
"""Chat message history stored in a Postgres database."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session_id: str,
|
||||
|
||||
@@ -13,6 +13,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RedisChatMessageHistory(BaseChatMessageHistory):
|
||||
"""Chat message history stored in a Redis database."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session_id: str,
|
||||
|
||||
@@ -21,6 +21,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_message_model(table_name, DynamicBase): # type: ignore
|
||||
"""
|
||||
Create a message model for a given table name.
|
||||
Args:
|
||||
table_name: The name of the table to use.
|
||||
DynamicBase: The base class to use for the model.
|
||||
|
||||
Returns:
|
||||
The model class.
|
||||
|
||||
"""
|
||||
|
||||
# Model decleared inside a function to have a dynamic table name
|
||||
class Message(DynamicBase):
|
||||
__tablename__ = table_name
|
||||
@@ -32,6 +43,8 @@ def create_message_model(table_name, DynamicBase): # type: ignore
|
||||
|
||||
|
||||
class SQLChatMessageHistory(BaseChatMessageHistory):
|
||||
"""Chat message history stored in an SQL database."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
session_id: str,
|
||||
|
||||
@@ -4,6 +4,16 @@ from langchain.schema import get_buffer_string # noqa: 401
|
||||
|
||||
|
||||
def get_prompt_input_key(inputs: Dict[str, Any], memory_variables: List[str]) -> str:
|
||||
"""
|
||||
Get the prompt input key.
|
||||
|
||||
Args:
|
||||
inputs: Dict[str, Any]
|
||||
memory_variables: List[str]
|
||||
|
||||
Returns:
|
||||
A prompt input key.
|
||||
"""
|
||||
# "stop" is a special key that can be passed as input but is not used to
|
||||
# format the prompt.
|
||||
prompt_input_keys = list(set(inputs).difference(memory_variables + ["stop"]))
|
||||
|
||||
@@ -8,6 +8,15 @@ from langchain.schema import OutputParserException
|
||||
|
||||
|
||||
def parse_json_markdown(json_string: str) -> dict:
|
||||
"""
|
||||
Parse a JSON string from a Markdown string.
|
||||
|
||||
Args:
|
||||
json_string: The Markdown string.
|
||||
|
||||
Returns:
|
||||
The parsed JSON object as a Python dictionary.
|
||||
"""
|
||||
# Try to find JSON string within triple backticks
|
||||
match = re.search(r"```(json)?(.*?)```", json_string, re.DOTALL)
|
||||
|
||||
@@ -28,6 +37,17 @@ def parse_json_markdown(json_string: str) -> dict:
|
||||
|
||||
|
||||
def parse_and_check_json_markdown(text: str, expected_keys: List[str]) -> dict:
|
||||
"""
|
||||
Parse a JSON string from a Markdown string and check that it
|
||||
contains the expected keys.
|
||||
|
||||
Args:
|
||||
text: The Markdown string.
|
||||
expected_keys: The expected keys in the JSON string.
|
||||
|
||||
Returns:
|
||||
The parsed JSON object as a Python dictionary.
|
||||
"""
|
||||
try:
|
||||
json_obj = parse_json_markdown(text)
|
||||
except json.JSONDecodeError as e:
|
||||
|
||||
@@ -28,6 +28,14 @@ def jinja2_formatter(template: str, **kwargs: Any) -> str:
|
||||
|
||||
|
||||
def validate_jinja2(template: str, input_variables: List[str]) -> None:
|
||||
"""
|
||||
Validate that the input variables are valid for the template.
|
||||
Raise an exception if missing or extra variables are found.
|
||||
|
||||
Args:
|
||||
template: The template string.
|
||||
input_variables: The input variables.
|
||||
"""
|
||||
input_variables_set = set(input_variables)
|
||||
valid_variables = _get_jinja2_variables_from_template(template)
|
||||
missing_variables = valid_variables - input_variables_set
|
||||
|
||||
@@ -7,6 +7,8 @@ from langchain.schema import BaseRetriever, Document
|
||||
|
||||
|
||||
class DataberryRetriever(BaseRetriever):
|
||||
"""Retriever that uses the Databerry API."""
|
||||
|
||||
datastore_url: str
|
||||
top_k: Optional[int]
|
||||
api_key: Optional[str]
|
||||
|
||||
@@ -10,6 +10,8 @@ from langchain.vectorstores.utils import maximal_marginal_relevance
|
||||
|
||||
|
||||
class SearchType(str, Enum):
|
||||
"""Enumerator of the types of search to perform."""
|
||||
|
||||
similarity = "similarity"
|
||||
mmr = "mmr"
|
||||
|
||||
|
||||
@@ -15,11 +15,23 @@ from langchain.schema import BaseRetriever, Document
|
||||
|
||||
|
||||
def create_index(contexts: List[str], embeddings: Embeddings) -> np.ndarray:
|
||||
"""
|
||||
Create an index of embeddings for a list of contexts.
|
||||
|
||||
Args:
|
||||
contexts: List of contexts to embed.
|
||||
embeddings: Embeddings model to use.
|
||||
|
||||
Returns:
|
||||
Index of embeddings.
|
||||
"""
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
return np.array(list(executor.map(embeddings.embed_query, contexts)))
|
||||
|
||||
|
||||
class KNNRetriever(BaseRetriever, BaseModel):
|
||||
"""KNN Retriever."""
|
||||
|
||||
embeddings: Embeddings
|
||||
index: Any
|
||||
texts: List[str]
|
||||
|
||||
@@ -4,6 +4,8 @@ from langchain.schema import BaseRetriever, Document
|
||||
|
||||
|
||||
class MetalRetriever(BaseRetriever):
|
||||
"""Retriever that uses the Metal API."""
|
||||
|
||||
def __init__(self, client: Any, params: Optional[dict] = None):
|
||||
from metal_sdk.metal import Metal
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ from langchain.vectorstores.milvus import Milvus
|
||||
|
||||
|
||||
class MilvusRetriever(BaseRetriever):
|
||||
"""Retriever that uses the Milvus API."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
embedding_function: Embeddings,
|
||||
@@ -45,6 +47,15 @@ class MilvusRetriever(BaseRetriever):
|
||||
|
||||
|
||||
def MilvusRetreiver(*args: Any, **kwargs: Any) -> MilvusRetriever:
|
||||
"""Deprecated MilvusRetreiver. Please use MilvusRetriever ('i' before 'e') instead.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
MilvusRetriever
|
||||
"""
|
||||
warnings.warn(
|
||||
"MilvusRetreiver will be deprecated in the future. "
|
||||
"Please use MilvusRetriever ('i' before 'e') instead.",
|
||||
|
||||
@@ -9,6 +9,14 @@ from langchain.schema import BaseRetriever, Document
|
||||
|
||||
|
||||
def hash_text(text: str) -> str:
|
||||
"""Hash a text using SHA256.
|
||||
|
||||
Args:
|
||||
text: Text to hash.
|
||||
|
||||
Returns:
|
||||
Hashed text.
|
||||
"""
|
||||
return str(hashlib.sha256(text.encode("utf-8")).hexdigest())
|
||||
|
||||
|
||||
@@ -20,6 +28,18 @@ def create_index(
|
||||
ids: Optional[List[str]] = None,
|
||||
metadatas: Optional[List[dict]] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Create a Pinecone index from a list of contexts.
|
||||
Modifies the index argument in-place.
|
||||
|
||||
Args:
|
||||
contexts: List of contexts to embed.
|
||||
index: Pinecone index to use.
|
||||
embeddings: Embeddings model to use.
|
||||
sparse_encoder: Sparse encoder to use.
|
||||
ids: List of ids to use for the documents.
|
||||
metadatas: List of metadata to use for the documents.
|
||||
"""
|
||||
batch_size = 32
|
||||
_iterator = range(0, len(contexts), batch_size)
|
||||
try:
|
||||
|
||||
@@ -13,6 +13,16 @@ from langchain.chains.query_constructor.ir import (
|
||||
|
||||
|
||||
def DEFAULT_COMPOSER(op_name: str) -> Callable:
|
||||
"""
|
||||
Default composer for logical operators.
|
||||
|
||||
Args:
|
||||
op_name: Name of the operator.
|
||||
|
||||
Returns:
|
||||
Callable that takes a list of arguments and returns a string.
|
||||
"""
|
||||
|
||||
def f(*args: Any) -> str:
|
||||
args_: map[str] = map(str, args)
|
||||
return f" {op_name} ".join(args_)
|
||||
@@ -21,6 +31,15 @@ def DEFAULT_COMPOSER(op_name: str) -> Callable:
|
||||
|
||||
|
||||
def FUNCTION_COMPOSER(op_name: str) -> Callable:
|
||||
"""
|
||||
Composer for functions.
|
||||
Args:
|
||||
op_name: Name of the function.
|
||||
|
||||
Returns:
|
||||
Callable that takes a list of arguments and returns a string.
|
||||
"""
|
||||
|
||||
def f(*args: Any) -> str:
|
||||
args_: map[str] = map(str, args)
|
||||
return f"{op_name}({','.join(args_)})"
|
||||
|
||||
@@ -15,11 +15,22 @@ from langchain.schema import BaseRetriever, Document
|
||||
|
||||
|
||||
def create_index(contexts: List[str], embeddings: Embeddings) -> np.ndarray:
|
||||
"""
|
||||
Create an index of embeddings for a list of contexts.
|
||||
Args:
|
||||
contexts: List of contexts to embed.
|
||||
embeddings: Embeddings model to use.
|
||||
|
||||
Returns:
|
||||
Index of embeddings.
|
||||
"""
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
return np.array(list(executor.map(embeddings.embed_query, contexts)))
|
||||
|
||||
|
||||
class SVMRetriever(BaseRetriever, BaseModel):
|
||||
"""SVM Retriever."""
|
||||
|
||||
embeddings: Embeddings
|
||||
index: Any
|
||||
texts: List[str]
|
||||
|
||||
@@ -11,6 +11,8 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class VespaRetriever(BaseRetriever):
|
||||
"""Retriever that uses the Vespa."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
app: Vespa,
|
||||
|
||||
@@ -10,6 +10,8 @@ from langchain.vectorstores.zilliz import Zilliz
|
||||
|
||||
|
||||
class ZillizRetriever(BaseRetriever):
|
||||
"""Retriever that uses the Zilliz API."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
embedding_function: Embeddings,
|
||||
@@ -45,6 +47,15 @@ class ZillizRetriever(BaseRetriever):
|
||||
|
||||
|
||||
def ZillizRetreiver(*args: Any, **kwargs: Any) -> ZillizRetriever:
|
||||
"""
|
||||
Deprecated ZillizRetreiver. Please use ZillizRetriever ('i' before 'e') instead.
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
ZillizRetriever
|
||||
"""
|
||||
warnings.warn(
|
||||
"ZillizRetreiver will be deprecated in the future. "
|
||||
"Please use ZillizRetriever ('i' before 'e') instead.",
|
||||
|
||||
@@ -145,6 +145,14 @@ def _message_to_dict(message: BaseMessage) -> dict:
|
||||
|
||||
|
||||
def messages_to_dict(messages: List[BaseMessage]) -> List[dict]:
|
||||
"""Convert messages to dict.
|
||||
|
||||
Args:
|
||||
messages: List of messages to convert.
|
||||
|
||||
Returns:
|
||||
List of dicts.
|
||||
"""
|
||||
return [_message_to_dict(m) for m in messages]
|
||||
|
||||
|
||||
@@ -163,6 +171,14 @@ def _message_from_dict(message: dict) -> BaseMessage:
|
||||
|
||||
|
||||
def messages_from_dict(messages: List[dict]) -> List[BaseMessage]:
|
||||
"""Convert messages from dict.
|
||||
|
||||
Args:
|
||||
messages: List of messages (dicts) to convert.
|
||||
|
||||
Returns:
|
||||
List of messages (BaseMessages).
|
||||
"""
|
||||
return [_message_from_dict(m) for m in messages]
|
||||
|
||||
|
||||
@@ -308,6 +324,8 @@ class Document(Serializable):
|
||||
|
||||
|
||||
class BaseRetriever(ABC):
|
||||
"""Base interface for retrievers."""
|
||||
|
||||
@abstractmethod
|
||||
def get_relevant_documents(self, query: str) -> List[Document]:
|
||||
"""Get documents relevant for a query.
|
||||
|
||||
@@ -258,11 +258,15 @@ class CharacterTextSplitter(TextSplitter):
|
||||
|
||||
|
||||
class LineType(TypedDict):
|
||||
"""Line type as typed dict."""
|
||||
|
||||
metadata: Dict[str, str]
|
||||
content: str
|
||||
|
||||
|
||||
class HeaderType(TypedDict):
|
||||
"""Header type as typed dict."""
|
||||
|
||||
level: int
|
||||
name: str
|
||||
data: str
|
||||
|
||||
@@ -75,6 +75,16 @@ class DuckDuckGoSearchResults(BaseTool):
|
||||
|
||||
|
||||
def DuckDuckGoSearchTool(*args: Any, **kwargs: Any) -> DuckDuckGoSearchRun:
|
||||
"""
|
||||
Deprecated. Use DuckDuckGoSearchRun instead.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
|
||||
Returns:
|
||||
DuckDuckGoSearchRun
|
||||
"""
|
||||
warnings.warn(
|
||||
"DuckDuckGoSearchTool will be deprecated in the future. "
|
||||
"Please use DuckDuckGoSearchRun instead.",
|
||||
|
||||
@@ -14,6 +14,8 @@ from langchain.tools.gmail.utils import clean_email_body
|
||||
|
||||
|
||||
class Resource(str, Enum):
|
||||
"""Enumerator of Resources to search."""
|
||||
|
||||
THREADS = "threads"
|
||||
MESSAGES = "messages"
|
||||
|
||||
|
||||
@@ -16,12 +16,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def import_google() -> Tuple[Request, Credentials]:
|
||||
"""Import google libraries.
|
||||
|
||||
Returns:
|
||||
Tuple[Request, Credentials]: Request and Credentials classes.
|
||||
"""
|
||||
# google-auth-httplib2
|
||||
try:
|
||||
from google.auth.transport.requests import Request # noqa: F401
|
||||
from google.oauth2.credentials import Credentials # noqa: F401
|
||||
except ImportError:
|
||||
raise ValueError(
|
||||
raise ImportError(
|
||||
"You need to install google-auth-httplib2 to use this toolkit. "
|
||||
"Try running pip install --upgrade google-auth-httplib2"
|
||||
)
|
||||
@@ -29,6 +34,11 @@ def import_google() -> Tuple[Request, Credentials]:
|
||||
|
||||
|
||||
def import_installed_app_flow() -> InstalledAppFlow:
|
||||
"""Import InstalledAppFlow class.
|
||||
|
||||
Returns:
|
||||
InstalledAppFlow: InstalledAppFlow class.
|
||||
"""
|
||||
try:
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
except ImportError:
|
||||
@@ -40,6 +50,11 @@ def import_installed_app_flow() -> InstalledAppFlow:
|
||||
|
||||
|
||||
def import_googleapiclient_resource_builder() -> build_resource:
|
||||
"""Import googleapiclient.discovery.build function.
|
||||
|
||||
Returns:
|
||||
build_resource: googleapiclient.discovery.build function.
|
||||
"""
|
||||
try:
|
||||
from googleapiclient.discovery import build
|
||||
except ImportError:
|
||||
|
||||
@@ -19,6 +19,13 @@ else:
|
||||
|
||||
|
||||
def lazy_import_playwright_browsers() -> Tuple[Type[AsyncBrowser], Type[SyncBrowser]]:
|
||||
"""
|
||||
Lazy import playwright browsers.
|
||||
|
||||
Returns:
|
||||
Tuple[Type[AsyncBrowser], Type[SyncBrowser]]:
|
||||
AsyncBrowser and SyncBrowser classes.
|
||||
"""
|
||||
try:
|
||||
from playwright.async_api import Browser as AsyncBrowser # noqa: F401
|
||||
from playwright.sync_api import Browser as SyncBrowser # noqa: F401
|
||||
|
||||
@@ -12,6 +12,15 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
async def aget_current_page(browser: AsyncBrowser) -> AsyncPage:
|
||||
"""
|
||||
Asynchronously get the current page of the browser.
|
||||
|
||||
Args:
|
||||
browser: The browser (AsyncBrowser) to get the current page from.
|
||||
|
||||
Returns:
|
||||
AsyncPage: The current page.
|
||||
"""
|
||||
if not browser.contexts:
|
||||
context = await browser.new_context()
|
||||
return await context.new_page()
|
||||
@@ -23,6 +32,14 @@ async def aget_current_page(browser: AsyncBrowser) -> AsyncPage:
|
||||
|
||||
|
||||
def get_current_page(browser: SyncBrowser) -> SyncPage:
|
||||
"""
|
||||
Get the current page of the browser.
|
||||
Args:
|
||||
browser: The browser to get the current page from.
|
||||
|
||||
Returns:
|
||||
SyncPage: The current page.
|
||||
"""
|
||||
if not browser.contexts:
|
||||
context = browser.new_context()
|
||||
return context.new_page()
|
||||
@@ -34,6 +51,15 @@ def get_current_page(browser: SyncBrowser) -> SyncPage:
|
||||
|
||||
|
||||
def create_async_playwright_browser(headless: bool = True) -> AsyncBrowser:
|
||||
"""
|
||||
Create a async playwright browser.
|
||||
|
||||
Args:
|
||||
headless: Whether to run the browser in headless mode. Defaults to True.
|
||||
|
||||
Returns:
|
||||
AsyncBrowser: The playwright browser.
|
||||
"""
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
browser = run_async(async_playwright().start())
|
||||
@@ -41,6 +67,15 @@ def create_async_playwright_browser(headless: bool = True) -> AsyncBrowser:
|
||||
|
||||
|
||||
def create_sync_playwright_browser(headless: bool = True) -> SyncBrowser:
|
||||
"""
|
||||
Create a playwright browser.
|
||||
|
||||
Args:
|
||||
headless: Whether to run the browser in headless mode. Defaults to True.
|
||||
|
||||
Returns:
|
||||
SyncBrowser: The playwright browser.
|
||||
"""
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
browser = sync_playwright().start()
|
||||
@@ -51,5 +86,13 @@ T = TypeVar("T")
|
||||
|
||||
|
||||
def run_async(coro: Coroutine[Any, Any, T]) -> T:
|
||||
"""
|
||||
|
||||
Args:
|
||||
coro: The coroutine to run. Coroutine[Any, Any, T]
|
||||
|
||||
Returns:
|
||||
T: The result of the coroutine.
|
||||
"""
|
||||
event_loop = asyncio.get_event_loop()
|
||||
return event_loop.run_until_complete(coro)
|
||||
|
||||
@@ -42,7 +42,14 @@ class AIPlugin(BaseModel):
|
||||
|
||||
|
||||
def marshal_spec(txt: str) -> dict:
|
||||
"""Convert the yaml or json serialized spec to a dict."""
|
||||
"""Convert the yaml or json serialized spec to a dict.
|
||||
|
||||
Args:
|
||||
txt: The yaml or json serialized spec.
|
||||
|
||||
Returns:
|
||||
dict: The spec as a dict.
|
||||
"""
|
||||
try:
|
||||
return json.loads(txt)
|
||||
except json.JSONDecodeError:
|
||||
|
||||
@@ -22,7 +22,15 @@ def _get_default_python_repl() -> PythonREPL:
|
||||
|
||||
|
||||
def sanitize_input(query: str) -> str:
|
||||
# Remove whitespace, backtick & python (if llm mistakes python console as terminal)
|
||||
"""Sanitize input to the python REPL.
|
||||
Remove whitespace, backtick & python (if llm mistakes python console as terminal)
|
||||
|
||||
Args:
|
||||
query: The query to sanitize
|
||||
|
||||
Returns:
|
||||
str: The sanitized query
|
||||
"""
|
||||
|
||||
# Removes `, whitespace & python from start
|
||||
query = re.sub(r"^(\s|`)*(?i:python)?\s*", "", query)
|
||||
|
||||
@@ -66,6 +66,14 @@ def raise_for_status_with_text(response: Response) -> None:
|
||||
|
||||
|
||||
def stringify_value(val: Any) -> str:
|
||||
"""Stringify a value.
|
||||
|
||||
Args:
|
||||
val: The value to stringify.
|
||||
|
||||
Returns:
|
||||
str: The stringified value.
|
||||
"""
|
||||
if isinstance(val, str):
|
||||
return val
|
||||
elif isinstance(val, dict):
|
||||
@@ -77,6 +85,14 @@ def stringify_value(val: Any) -> str:
|
||||
|
||||
|
||||
def stringify_dict(data: dict) -> str:
|
||||
"""Stringify a dictionary.
|
||||
|
||||
Args:
|
||||
data: The dictionary to stringify.
|
||||
|
||||
Returns:
|
||||
str: The stringified dictionary.
|
||||
"""
|
||||
text = ""
|
||||
for key, value in data.items():
|
||||
text += key + ": " + stringify_value(value) + "\n"
|
||||
|
||||
@@ -72,6 +72,14 @@ class AlibabaCloudOpenSearchSettings:
|
||||
|
||||
|
||||
def create_metadata(fields: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Create metadata from fields.
|
||||
|
||||
Args:
|
||||
fields: The fields of the document. The fields must be a dict.
|
||||
|
||||
Returns:
|
||||
metadata: The metadata of the document. The metadata must be a dict.
|
||||
"""
|
||||
metadata: Dict[str, Any] = {}
|
||||
for key, value in fields.items():
|
||||
if key == "id" or key == "document" or key == "embedding":
|
||||
@@ -81,6 +89,8 @@ def create_metadata(fields: Dict[str, Any]) -> Dict[str, Any]:
|
||||
|
||||
|
||||
class AlibabaCloudOpenSearch(VectorStore):
|
||||
"""Alibaba Cloud OpenSearch Vector Store"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
embedding: Embeddings,
|
||||
|
||||
@@ -26,8 +26,8 @@ Base = declarative_base() # type: Any
|
||||
|
||||
|
||||
class AnalyticDB(VectorStore):
|
||||
"""
|
||||
VectorStore implementation using AnalyticDB.
|
||||
"""VectorStore implementation using AnalyticDB.
|
||||
|
||||
AnalyticDB is a distributed full PostgresSQL syntax cloud-native database.
|
||||
- `connection_string` is a postgres connection string.
|
||||
- `embedding_function` any embedding function implementing
|
||||
|
||||
@@ -18,6 +18,15 @@ logger = logging.getLogger()
|
||||
|
||||
|
||||
def has_mul_sub_str(s: str, *args: Any) -> bool:
|
||||
"""
|
||||
Check if a string contains multiple substrings.
|
||||
Args:
|
||||
s: string to check.
|
||||
*args: substrings to check.
|
||||
|
||||
Returns:
|
||||
True if all substrings are in the string, False otherwise.
|
||||
"""
|
||||
for a in args:
|
||||
if a not in s:
|
||||
return False
|
||||
|
||||
@@ -104,8 +104,8 @@ document text);"""
|
||||
|
||||
|
||||
class Hologres(VectorStore):
|
||||
"""
|
||||
VectorStore implementation using Hologres.
|
||||
"""VectorStore implementation using Hologres.
|
||||
|
||||
- `connection_string` is a hologres connection string.
|
||||
- `embedding_function` any embedding function implementing
|
||||
`langchain.embeddings.base.Embeddings` interface.
|
||||
|
||||
@@ -17,6 +17,15 @@ logger = logging.getLogger()
|
||||
|
||||
|
||||
def has_mul_sub_str(s: str, *args: Any) -> bool:
|
||||
"""
|
||||
Check if a string contains multiple substrings.
|
||||
Args:
|
||||
s: string to check.
|
||||
*args: substrings to check.
|
||||
|
||||
Returns:
|
||||
True if all substrings are in the string, False otherwise.
|
||||
"""
|
||||
for a in args:
|
||||
if a not in s:
|
||||
return False
|
||||
|
||||
@@ -93,6 +93,8 @@ class QueryResult:
|
||||
|
||||
|
||||
class DistanceStrategy(str, enum.Enum):
|
||||
"""Enumerator of the Distance strategies."""
|
||||
|
||||
EUCLIDEAN = EmbeddingStore.embedding.l2_distance
|
||||
COSINE = EmbeddingStore.embedding.cosine_distance
|
||||
MAX_INNER_PRODUCT = EmbeddingStore.embedding.max_inner_product
|
||||
|
||||
@@ -22,6 +22,8 @@ from langchain.vectorstores.base import VectorStore, VectorStoreRetriever
|
||||
|
||||
|
||||
class DistanceStrategy(str, enum.Enum):
|
||||
"""Enumerator of the Distance strategies for SingleStoreDB."""
|
||||
|
||||
EUCLIDEAN_DISTANCE = "EUCLIDEAN_DISTANCE"
|
||||
DOT_PRODUCT = "DOT_PRODUCT"
|
||||
|
||||
@@ -37,6 +39,7 @@ ORDERING_DIRECTIVE: dict = {
|
||||
class SingleStoreDB(VectorStore):
|
||||
"""
|
||||
This class serves as a Pythonic interface to the SingleStore DB database.
|
||||
|
||||
The prerequisite for using this class is the installation of the ``singlestoredb``
|
||||
Python package.
|
||||
|
||||
@@ -445,6 +448,8 @@ class SingleStoreDB(VectorStore):
|
||||
|
||||
|
||||
class SingleStoreDBRetriever(VectorStoreRetriever):
|
||||
"""Retriever for SingleStoreDB vector stores."""
|
||||
|
||||
vectorstore: SingleStoreDB
|
||||
k: int = 4
|
||||
allowed_search_types: ClassVar[Collection[str]] = ("similarity",)
|
||||
|
||||
@@ -119,6 +119,8 @@ SERIALIZER_MAP: Dict[str, Type[BaseSerializer]] = {
|
||||
|
||||
|
||||
class SKLearnVectorStoreException(RuntimeError):
|
||||
"""Exception raised by SKLearnVectorStore."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,15 @@ DEBUG = False
|
||||
|
||||
|
||||
def has_mul_sub_str(s: str, *args: Any) -> bool:
|
||||
"""
|
||||
Check if a string has multiple substrings.
|
||||
Args:
|
||||
s: The string to check
|
||||
*args: The substrings to check for in the string
|
||||
|
||||
Returns:
|
||||
bool: True if all substrings are present in the string, False otherwise
|
||||
"""
|
||||
for a in args:
|
||||
if a not in s:
|
||||
return False
|
||||
@@ -26,11 +35,25 @@ def has_mul_sub_str(s: str, *args: Any) -> bool:
|
||||
|
||||
|
||||
def debug_output(s: Any) -> None:
|
||||
"""
|
||||
Print a debug message if DEBUG is True.
|
||||
Args:
|
||||
s: The message to print
|
||||
"""
|
||||
if DEBUG:
|
||||
print(s)
|
||||
|
||||
|
||||
def get_named_result(connection: Any, query: str) -> List[dict[str, Any]]:
|
||||
"""
|
||||
Get a named result from a query.
|
||||
Args:
|
||||
connection: The connection to the database
|
||||
query: The query to execute
|
||||
|
||||
Returns:
|
||||
List[dict[str, Any]]: The result of the query
|
||||
"""
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
columns = cursor.description
|
||||
|
||||
@@ -19,6 +19,8 @@ def _uuid_key() -> str:
|
||||
|
||||
|
||||
class Tair(VectorStore):
|
||||
"""Wrapper around Tair Vector store."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
embedding_function: Embeddings,
|
||||
@@ -34,7 +36,7 @@ class Tair(VectorStore):
|
||||
try:
|
||||
from tair import Tair as TairClient
|
||||
except ImportError:
|
||||
raise ValueError(
|
||||
raise ImportError(
|
||||
"Could not import tair python package. "
|
||||
"Please install it with `pip install tair`."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user