viruPVS/langchain-docs huggingface dataset:
try:
            found = self.pattern.search(text)
            if not found:
                # Fast fail to parse Final Answer.
                raise ValueError("action not found")
            action = found.group(1)
            response = json.loads(action.strip())
            includes_action = "action" in response
            if includes_answer and includes_action:
                raise OutputParserException(
                    "Parsing LLM output produced a final answer "
                    f"and a parse-able action: {text}"
                )
            return AgentAction(
                response["action"], response.get("action_input", {}), text
            )
        except Exception:
            if not includes_answer:
                raise OutputParserException(f"Could not parse LLM output: {text}")
            output = text.split(FINAL_ANSWER_ACTION)[-1].strip()
            return AgentFinish({"output": output}, text)
    @property
    def _type(self) -> str:
        return "react-json-single-input"
Source code for langchain.agents.output_parsers.react_single_input
import re
from typing import Union
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
from langchain.agents.agent import AgentOutputParser
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
FINAL_ANSWER_ACTION = "Final Answer:"
MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE = (
    "Invalid Format: Missing 'Action:' after 'Thought:"
)
MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE = (
    "Invalid Format: Missing 'Action Input:' after 'Action:'"
)
FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE = (
    "Parsing LLM output produced both a final answer and a parse-able action:"
)
[docs]class ReActSingleInputOutputParser(AgentOutputParser):
    """Parses ReAct-style LLM calls that have a single tool input.
    Expects output to be in one of two formats.
    If the output signals that an action should be taken,
    should be in the below format. This will result in an AgentAction
    being returned.
    ```
    Thought: agent thought here
    Action: search
    Action Input: what is the temperature in SF?
    ```
    If the output signals that a final answer should be given,
    should be in the below format. This will result in an AgentFinish
    being returned.
    ```
    Thought: agent thought here
    Final Answer: The temperature is 100 degrees
    ```
    """
[docs]    def get_format_instructions(self) -> str:
        return FORMAT_INSTRUCTIONS
[docs]    def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
        includes_answer = FINAL_ANSWER_ACTION in text
includes_answer = FINAL_ANSWER_ACTION in text
        regex = (
            r"Action\s*\d*\s*:[\s]*(.*?)[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
        )
        action_match = re.search(regex, text, re.DOTALL)
        if action_match:
            if includes_answer:
                raise OutputParserException(
                    f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
                )
            action = action_match.group(1).strip()
            action_input = action_match.group(2)
            tool_input = action_input.strip(" ")
            tool_input = tool_input.strip('"')
            return AgentAction(action, tool_input, text)
        elif includes_answer:
            return AgentFinish(
                {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
            )
        if not re.search(r"Action\s*\d*\s*:[\s]*(.*?)", text, re.DOTALL):
            raise OutputParserException(
                f"Could not parse LLM output: `{text}`",
                observation=MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE,
                llm_output=text,
                send_to_llm=True,
            )
        elif not re.search(
            r"[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)", text, re.DOTALL
        ):
            raise OutputParserException(
                f"Could not parse LLM output: `{text}`",
                observation=MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE,
                llm_output=text,
                send_to_llm=True,
            )
        else:
Source code for langchain.indexes.base
from __future__ import annotations
import uuid
from abc import ABC, abstractmethod
from typing import List, Optional, Sequence
NAMESPACE_UUID = uuid.UUID(int=1984)
[docs]class RecordManager(ABC):
    """An abstract base class representing the interface for a record manager."""
[docs]    def __init__(
        self,
        namespace: str,
    ) -> None:
        """Initialize the record manager.
        Args:
            namespace (str): The namespace for the record manager.
        """
        self.namespace = namespace
[docs]    @abstractmethod
    def create_schema(self) -> None:
        """Create the database schema for the record manager."""
[docs]    @abstractmethod
    async def acreate_schema(self) -> None:
        """Create the database schema for the record manager."""
[docs]    @abstractmethod
    def get_time(self) -> float:
        """Get the current server time as a high resolution timestamp!
        It's important to get this from the server to ensure a monotonic clock,
        otherwise there may be data loss when cleaning up old documents!
        Returns:
            The current server time as a float timestamp.
        """
[docs]    @abstractmethod
    async def aget_time(self) -> float:
        """Get the current server time as a high resolution timestamp!
        It's important to get this from the server to ensure a monotonic clock,
        otherwise there may be data loss when cleaning up old documents!
        Returns:
            The current server time as a float timestamp.
        """
[docs]    @abstractmethod
    def update(
        self,
        keys: Sequence[str],
        *,
        group_ids: Optional[Sequence[Optional[str]]] = None,
Source code for langchain.indexes.graph
"""Graph Index Creator."""
from typing import Optional, Type
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import BasePromptTemplate
from langchain_core.pydantic_v1 import BaseModel
from langchain.chains.llm import LLMChain
from langchain.graphs.networkx_graph import NetworkxEntityGraph, parse_triples
from langchain.indexes.prompts.knowledge_triplet_extraction import (
    KNOWLEDGE_TRIPLE_EXTRACTION_PROMPT,
)
[docs]class GraphIndexCreator(BaseModel):
    """Functionality to create graph index."""
    llm: Optional[BaseLanguageModel] = None
    graph_type: Type[NetworkxEntityGraph] = NetworkxEntityGraph
[docs]    def from_text(
        self, text: str, prompt: BasePromptTemplate = KNOWLEDGE_TRIPLE_EXTRACTION_PROMPT
    ) -> NetworkxEntityGraph:
        """Create graph index from text."""
        if self.llm is None:
            raise ValueError("llm should not be None")
        graph = self.graph_type()
        chain = LLMChain(llm=self.llm, prompt=prompt)
        output = chain.predict(text=text)
        knowledge = parse_triples(output)
        for triple in knowledge:
            graph.add_triple(triple)
        return graph
[docs]    async def afrom_text(
        self, text: str, prompt: BasePromptTemplate = KNOWLEDGE_TRIPLE_EXTRACTION_PROMPT
    ) -> NetworkxEntityGraph:
        """Create graph index from text asynchronously."""
        if self.llm is None:
            raise ValueError("llm should not be None")
        graph = self.graph_type()
        chain = LLMChain(llm=self.llm, prompt=prompt)
Source code for langchain.indexes.vectorstore
from typing import Any, Dict, List, Optional, Type
from langchain_core.documents import Document
from langchain_core.embeddings import Embeddings
from langchain_core.language_models import BaseLanguageModel
from langchain_core.pydantic_v1 import BaseModel, Extra, Field
from langchain_core.vectorstores import VectorStore
from langchain.chains.qa_with_sources.retrieval import RetrievalQAWithSourcesChain
from langchain.chains.retrieval_qa.base import RetrievalQA
from langchain.document_loaders.base import BaseLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms.openai import OpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter, TextSplitter
from langchain.vectorstores.chroma import Chroma
def _get_default_text_splitter() -> TextSplitter:
    return RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
[docs]class VectorStoreIndexWrapper(BaseModel):
    """Wrapper around a vectorstore for easy access."""
    vectorstore: VectorStore
    class Config:
        """Configuration for this pydantic object."""
        extra = Extra.forbid
        arbitrary_types_allowed = True
[docs]    def query(
        self,
        question: str,
        llm: Optional[BaseLanguageModel] = None,
        retriever_kwargs: Optional[Dict[str, Any]] = None,
        **kwargs: Any,
    ) -> str:
        """Query the vectorstore."""
        llm = llm or OpenAI(temperature=0)
        retriever_kwargs = retriever_kwargs or {}
        chain = RetrievalQA.from_chain_type(
            llm, retriever=self.vectorstore.as_retriever(**retriever_kwargs), **kwargs
)
        return chain.run(question)
[docs]    def query_with_sources(
        self,
        question: str,
        llm: Optional[BaseLanguageModel] = None,
        retriever_kwargs: Optional[Dict[str, Any]] = None,
        **kwargs: Any,
    ) -> dict:
        """Query the vectorstore and get back sources."""
        llm = llm or OpenAI(temperature=0)
        retriever_kwargs = retriever_kwargs or {}
        chain = RetrievalQAWithSourcesChain.from_chain_type(
            llm, retriever=self.vectorstore.as_retriever(**retriever_kwargs), **kwargs
        )
        return chain({chain.question_key: question})
[docs]class VectorstoreIndexCreator(BaseModel):
    """Logic for creating indexes."""
    vectorstore_cls: Type[VectorStore] = Chroma
    embedding: Embeddings = Field(default_factory=OpenAIEmbeddings)
    text_splitter: TextSplitter = Field(default_factory=_get_default_text_splitter)
    vectorstore_kwargs: dict = Field(default_factory=dict)
    class Config:
        """Configuration for this pydantic object."""
        extra = Extra.forbid
        arbitrary_types_allowed = True
[docs]    def from_loaders(self, loaders: List[BaseLoader]) -> VectorStoreIndexWrapper:
        """Create a vectorstore index from loaders."""
        docs = []
        for loader in loaders:
            docs.extend(loader.load())
        return self.from_documents(docs)
[docs]    def from_documents(self, documents: List[Document]) -> VectorStoreIndexWrapper:
        """Create a vectorstore index from documents."""
        sub_docs = self.text_splitter.split_documents(documents)
        vectorstore = self.vectorstore_cls.from_documents(
Source code for langchain.storage.file_system
import re
from pathlib import Path
from typing import Iterator, List, Optional, Sequence, Tuple, Union
from langchain_core.stores import ByteStore
from langchain.storage.exceptions import InvalidKeyException
[docs]class LocalFileStore(ByteStore):
    """BaseStore interface that works on the local file system.
    Examples:
        Create a LocalFileStore instance and perform operations on it:
        .. code-block:: python
            from langchain.storage import LocalFileStore
            # Instantiate the LocalFileStore with the root path
            file_store = LocalFileStore("/path/to/root")
            # Set values for keys
            file_store.mset([("key1", b"value1"), ("key2", b"value2")])
            # Get values for keys
            values = file_store.mget(["key1", "key2"])  # Returns [b"value1", b"value2"]
            # Delete keys
            file_store.mdelete(["key1"])
            # Iterate over keys
            for key in file_store.yield_keys():
                print(key)
    """
[docs]    def __init__(self, root_path: Union[str, Path]) -> None:
        """Implement the BaseStore interface for the local file system.
        Args:
            root_path (Union[str, Path]): The root path of the file store. All keys are
                interpreted as paths relative to this root.
        """
        self.root_path = Path(root_path)
    def _get_full_path(self, key: str) -> Path:
        """Get the full path for a given key relative to the root path.
        Args:
            key (str): The key relative to the root path.
        Returns:
            Path: The full path for the given key.
        """
Returns:
            Path: The full path for the given key.
        """
        if not re.match(r"^[a-zA-Z0-9_.\-/]+$", key):
            raise InvalidKeyException(f"Invalid characters in key: {key}")
        return self.root_path / key
[docs]    def mget(self, keys: Sequence[str]) -> List[Optional[bytes]]:
        """Get the values associated with the given keys.
        Args:
            keys: A sequence of keys.
        Returns:
            A sequence of optional values associated with the keys.
            If a key is not found, the corresponding value will be None.
        """
        values: List[Optional[bytes]] = []
        for key in keys:
            full_path = self._get_full_path(key)
            if full_path.exists():
                value = full_path.read_bytes()
                values.append(value)
            else:
                values.append(None)
        return values
[docs]    def mset(self, key_value_pairs: Sequence[Tuple[str, bytes]]) -> None:
        """Set the values for the given keys.
        Args:
            key_value_pairs: A sequence of key-value pairs.
        Returns:
            None
        """
        for key, value in key_value_pairs:
            full_path = self._get_full_path(key)
            full_path.parent.mkdir(parents=True, exist_ok=True)
            full_path.write_bytes(value)
[docs]    def mdelete(self, keys: Sequence[str]) -> None:
        """Delete the given keys and their associated values.
        Args:
            keys (Sequence[str]): A sequence of keys to delete.
        Returns:
            None
        """
        for key in keys:
            full_path = self._get_full_path(key)
for key in keys:
            full_path = self._get_full_path(key)
            if full_path.exists():
                full_path.unlink()
[docs]    def yield_keys(self, prefix: Optional[str] = None) -> Iterator[str]:
        """Get an iterator over keys that match the given prefix.
        Args:
            prefix (Optional[str]): The prefix to match.
        Returns:
            Iterator[str]: An iterator over keys that match the given prefix.
        """
        prefix_path = self._get_full_path(prefix) if prefix else self.root_path
        for file in prefix_path.rglob("*"):
            if file.is_file():
                relative_path = file.relative_to(self.root_path)
                yield str(relative_path)
Source code for langchain.storage.encoder_backed
from typing import (
    Any,
    Callable,
    Iterator,
    List,
    Optional,
    Sequence,
    Tuple,
    TypeVar,
    Union,
)
from langchain_core.stores import BaseStore
K = TypeVar("K")
V = TypeVar("V")
[docs]class EncoderBackedStore(BaseStore[K, V]):
    """Wraps a store with key and value encoders/decoders.
    Examples that uses JSON for encoding/decoding:
    .. code-block:: python
        import json
        def key_encoder(key: int) -> str:
            return json.dumps(key)
        def value_serializer(value: float) -> str:
            return json.dumps(value)
        def value_deserializer(serialized_value: str) -> float:
            return json.loads(serialized_value)
        # Create an instance of the abstract store
        abstract_store = MyCustomStore()
        # Create an instance of the encoder-backed store
        store = EncoderBackedStore(
            store=abstract_store,
            key_encoder=key_encoder,
            value_serializer=value_serializer,
            value_deserializer=value_deserializer
        )
        # Use the encoder-backed store methods
        store.mset([(1, 3.14), (2, 2.718)])
        values = store.mget([1, 2])  # Retrieves [3.14, 2.718]
        store.mdelete([1, 2])  # Deletes the keys 1 and 2
    """
[docs]    def __init__(
        self,
        store: BaseStore[str, Any],
        key_encoder: Callable[[K], str],
        value_serializer: Callable[[V], bytes],
value_serializer: Callable[[V], bytes],
        value_deserializer: Callable[[Any], V],
    ) -> None:
        """Initialize an EncodedStore."""
        self.store = store
        self.key_encoder = key_encoder
        self.value_serializer = value_serializer
        self.value_deserializer = value_deserializer
[docs]    def mget(self, keys: Sequence[K]) -> List[Optional[V]]:
        """Get the values associated with the given keys."""
        encoded_keys: List[str] = [self.key_encoder(key) for key in keys]
        values = self.store.mget(encoded_keys)
        return [
            self.value_deserializer(value) if value is not None else value
            for value in values
        ]
[docs]    def mset(self, key_value_pairs: Sequence[Tuple[K, V]]) -> None:
        """Set the values for the given keys."""
        encoded_pairs = [
            (self.key_encoder(key), self.value_serializer(value))
            for key, value in key_value_pairs
        ]
        self.store.mset(encoded_pairs)
[docs]    def mdelete(self, keys: Sequence[K]) -> None:
        """Delete the given keys and their associated values."""
        encoded_keys = [self.key_encoder(key) for key in keys]
        self.store.mdelete(encoded_keys)
[docs]    def yield_keys(
        self, *, prefix: Optional[str] = None
    ) -> Union[Iterator[K], Iterator[str]]:
        """Get an iterator over keys that match the given prefix."""
        # For the time being this does not return K, but str
        # it's for debugging purposes. Should fix this.
        yield from self.store.yield_keys(prefix=prefix)
Source code for langchain.storage.in_memory
"""In memory store that is not thread safe and has no eviction policy.
This is a simple implementation of the BaseStore using a dictionary that is useful
primarily for unit testing purposes.
"""
from typing import (
    Any,
    Dict,
    Generic,
    Iterator,
    List,
    Optional,
    Sequence,
    Tuple,
    TypeVar,
)
from langchain_core.stores import BaseStore
V = TypeVar("V")
[docs]class InMemoryBaseStore(BaseStore[str, V], Generic[V]):
    """In-memory implementation of the BaseStore using a dictionary.
    Attributes:
        store (Dict[str, Any]): The underlying dictionary that stores
            the key-value pairs.
    Examples:
        .. code-block:: python
            from langchain.storage import InMemoryStore
            store = InMemoryStore()
            store.mset([('key1', 'value1'), ('key2', 'value2')])
            store.mget(['key1', 'key2'])
            # ['value1', 'value2']
            store.mdelete(['key1'])
            list(store.yield_keys())
            # ['key2']
            list(store.yield_keys(prefix='k'))
            # ['key2']
    """
[docs]    def __init__(self) -> None:
        """Initialize an empty store."""
        self.store: Dict[str, V] = {}
[docs]    def mget(self, keys: Sequence[str]) -> List[Optional[V]]:
        """Get the values associated with the given keys.
        Args:
            keys (Sequence[str]): A sequence of keys.
        Returns:
            A sequence of optional values associated with the keys.
Returns:
            A sequence of optional values associated with the keys.
            If a key is not found, the corresponding value will be None.
        """
        return [self.store.get(key) for key in keys]
[docs]    def mset(self, key_value_pairs: Sequence[Tuple[str, V]]) -> None:
        """Set the values for the given keys.
        Args:
            key_value_pairs (Sequence[Tuple[str, V]]): A sequence of key-value pairs.
        Returns:
            None
        """
        for key, value in key_value_pairs:
            self.store[key] = value
[docs]    def mdelete(self, keys: Sequence[str]) -> None:
        """Delete the given keys and their associated values.
        Args:
            keys (Sequence[str]): A sequence of keys to delete.
        """
        for key in keys:
            if key in self.store:
                del self.store[key]
[docs]    def yield_keys(self, prefix: Optional[str] = None) -> Iterator[str]:
        """Get an iterator over keys that match the given prefix.
        Args:
            prefix (str, optional): The prefix to match. Defaults to None.
        Returns:
            Iterator[str]: An iterator over keys that match the given prefix.
        """
        if prefix is None:
            yield from self.store.keys()
        else:
            for key in self.store.keys():
                if key.startswith(prefix):
                    yield key
InMemoryStore = InMemoryBaseStore[Any]
InMemoryByteStore = InMemoryBaseStore[bytes]
Source code for langchain.chains.prompt_selector
from abc import ABC, abstractmethod
from typing import Callable, List, Tuple
from langchain_core.language_models import BaseLanguageModel
from langchain_core.language_models.chat_models import BaseChatModel
from langchain_core.language_models.llms import BaseLLM
from langchain_core.prompts import BasePromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
[docs]class BasePromptSelector(BaseModel, ABC):
    """Base class for prompt selectors."""
[docs]    @abstractmethod
    def get_prompt(self, llm: BaseLanguageModel) -> BasePromptTemplate:
        """Get default prompt for a language model."""
[docs]class ConditionalPromptSelector(BasePromptSelector):
    """Prompt collection that goes through conditionals."""
    default_prompt: BasePromptTemplate
    """Default prompt to use if no conditionals match."""
    conditionals: List[
        Tuple[Callable[[BaseLanguageModel], bool], BasePromptTemplate]
    ] = Field(default_factory=list)
    """List of conditionals and prompts to use if the conditionals match."""
[docs]    def get_prompt(self, llm: BaseLanguageModel) -> BasePromptTemplate:
        """Get default prompt for a language model.
        Args:
            llm: Language model to get prompt for.
        Returns:
            Prompt to use for the language model.
        """
        for condition, prompt in self.conditionals:
            if condition(llm):
                return prompt
        return self.default_prompt
[docs]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.
True if the language model is a BaseLLM model, False otherwise.
    """
    return isinstance(llm, BaseLLM)
[docs]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)