
    Ng|                    ,   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZmZmZmZmZmZmZmZmZ d dlZd dlmZ d dlmZ d dlmZ d dlmZ d d	lmZm Z  d d
l!m"Z" d dl#m$Z$m%Z%  ej&        e'          Z(dddZ)ddZ* G d de          Z+dS )    )annotationsN)Path)	AnyCallableDictIterableListOptionalSizedTupleUnionDocument)
Embeddings)run_in_executor)VectorStore)AddableMixinDocstore)InMemoryDocstore)DistanceStrategymaximal_marginal_relevanceno_avx2Optional[bool]returnr   c                    | /dt           j        v r!t          t          j        d                    } 	 | rddlm} nddl}n# t          $ r t          d          w xY w|S )aM  
    Import faiss if available, otherwise raise error.
    If FAISS_NO_AVX2 environment variable is set, it will be considered
    to load FAISS with no AVX2 optimization.

    Args:
        no_avx2: Load FAISS strictly with no AVX2 optimization
            so that the vectorstore is portable and compatible with other devices.
    NFAISS_NO_AVX2r   )	swigfaisszCould not import faiss python package. Please install it with `pip install faiss-gpu` (for CUDA supported GPU) or `pip install faiss-cpu` (depending on Python version).)osenvironboolgetenvfaissr   ImportError)r   r"   s     b/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain_community/vectorstores/faiss.pydependable_faiss_importr%   &   s     ?bj88ry1122

 	0000000LLL 
 
 
H
 
 	

 Ls   A Axyx_namestry_nameNonec                   t          | t                    rot          |t                    rZt          |           t          |          k    r:t          | d| d| dt          |            d| dt          |                     d S )Nz and z% expected to be equal length but len(z)=z	 and len()
isinstancer   len
ValueError)r&   r'   r(   r*   s       r$   _len_check_if_sizedr0   A   s    !U 

1e 4 4 
Q3q669I9I A AF A AA A VVA A.4A A8;AA A
 
 	
 F    c                     e Zd ZdZddej        fdidZedjd            ZdkdZ	dkdZ
dldZdldZ	 	 dmdnd'Z	 	 dmdod*Z	 	 dmdod+Z	 	 dmdpd.Z	 	 	 dqdrd8Z	 	 	 dqdrd9Z	 	 	 dqdsd;Z	 	 	 dqdsd<Z	 	 	 dqdtd?Z	 	 	 dqdud@Z	 	 	 dqdvdAZ	 	 	 dqdvdBZd/d0dCddDdwdGZd/d0dCddDdwdHZ	 	 	 	 dxdydIZ	 	 	 	 dxdydJZ	 	 	 	 dxdzdKZ	 	 	 	 dxdzdLZd{d|dNZd}dQZ e!dddej        fd~dS            Z"e!	 	 dmddT            Z#e!	 	 dmddV            Z$e!	 	 dmddW            Z%e!	 	 dmddX            Z&ddd[Z'e!	 ddd\dd^            Z(dd`Z)e!dd\ddb            Z*dddZ+	 	 	 dqdsdeZ,	 	 	 dqdsdfZ-e.ddh            Z/dS )FAISSu  FAISS vector store integration.

    See [The FAISS Library](https://arxiv.org/pdf/2401.08281) paper.

    Setup:
        Install ``langchain_community`` and ``faiss-cpu`` python packages.

        .. code-block:: bash

            pip install -qU langchain_community faiss-cpu

    Key init args — indexing params:
        embedding_function: Embeddings
            Embedding function to use.

    Key init args — client params:
        index: Any
            FAISS index to use.
        docstore: Docstore
            Docstore to use.
        index_to_docstore_id: Dict[int, str]
            Mapping of index to docstore id.

    Instantiate:
        .. code-block:: python

            import faiss
            from langchain_community.vectorstores import FAISS
            from langchain_community.docstore.in_memory import InMemoryDocstore
            from langchain_openai import OpenAIEmbeddings

            index = faiss.IndexFlatL2(len(OpenAIEmbeddings().embed_query("hello world")))

            vector_store = FAISS(
                embedding_function=OpenAIEmbeddings(),
                index=index,
                docstore= InMemoryDocstore(),
                index_to_docstore_id={}
            )

    Add Documents:
        .. code-block:: python

            from langchain_core.documents import Document

            document_1 = Document(page_content="foo", metadata={"baz": "bar"})
            document_2 = Document(page_content="thud", metadata={"bar": "baz"})
            document_3 = Document(page_content="i will be deleted :(")

            documents = [document_1, document_2, document_3]
            ids = ["1", "2", "3"]
            vector_store.add_documents(documents=documents, ids=ids)

    Delete Documents:
        .. code-block:: python

            vector_store.delete(ids=["3"])

    Search:
        .. code-block:: python

            results = vector_store.similarity_search(query="thud",k=1)
            for doc in results:
                print(f"* {doc.page_content} [{doc.metadata}]")

        .. code-block:: python

            * thud [{'bar': 'baz'}]

    Search with filter:
        .. code-block:: python

            results = vector_store.similarity_search(query="thud",k=1,filter={"bar": "baz"})
            for doc in results:
                print(f"* {doc.page_content} [{doc.metadata}]")

        .. code-block:: python

            * thud [{'bar': 'baz'}]

    Search with score:
        .. code-block:: python

            results = vector_store.similarity_search_with_score(query="qux",k=1)
            for doc, score in results:
                print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")

        .. code-block:: python

            * [SIM=0.335304] foo [{'baz': 'bar'}]

    Async:
        .. code-block:: python

            # add documents
            # await vector_store.aadd_documents(documents=documents, ids=ids)

            # delete documents
            # await vector_store.adelete(ids=["3"])

            # search
            # results = vector_store.asimilarity_search(query="thud",k=1)

            # search with score
            results = await vector_store.asimilarity_search_with_score(query="qux",k=1)
            for doc,score in results:
                print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")

        .. code-block:: python

            * [SIM=0.335304] foo [{'baz': 'bar'}]

    Use as Retriever:
        .. code-block:: python

            retriever = vector_store.as_retriever(
                search_type="mmr",
                search_kwargs={"k": 1, "fetch_k": 2, "lambda_mult": 0.5},
            )
            retriever.invoke("thud")

        .. code-block:: python

            [Document(metadata={'bar': 'baz'}, page_content='thud')]

    NFembedding_function/Union[Callable[[str], List[float]], Embeddings]indexr   docstorer   index_to_docstore_idDict[int, str]relevance_score_fn"Optional[Callable[[float], float]]normalize_L2r    distance_strategyr   c                >   t          |t                    st                              d           || _        || _        || _        || _        || _        || _	        || _
        | j        t          j        k    r%| j
        r t          j        d| j                    dS dS dS )z%Initialize with necessary components.t`embedding_function` is expected to be an Embeddings object, support for passing in a function will soon be removed.z2Normalizing L2 is not applicable for metric type: N)r-   r   loggerwarningr4   r6   r7   r8   r=   override_relevance_score_fn_normalize_L2r   EUCLIDEAN_DISTANCEwarningswarn)selfr4   r6   r7   r8   r:   r<   r=   s           r$   __init__zFAISS.__init__   s     ,j99 	NNB   #5
 $8!!2+=()"&6&III" J M9 $ 69 9     JIIIr1   r   Optional[Embeddings]c                H    t          | j        t                    r| j        nd S N)r-   r4   r   rG   s    r$   
embeddingszFAISS.embeddings   s)     $1:>>D##	
r1   texts	List[str]List[List[float]]c                     t           j        t                    r j                            |          S  fd|D             S )Nc                :    g | ]}                     |          S  )r4   ).0textrG   s     r$   
<listcomp>z*FAISS._embed_documents.<locals>.<listcomp>   s'    DDDdD++D11DDDr1   )r-   r4   r   embed_documentsrG   rN   s   ` r$   _embed_documentszFAISS._embed_documents   sJ    d-z:: 	E*::5AAADDDDeDDDDr1   c                   K   t          | j        t                    r | j                            |           d {V S t	          d          Nr?   )r-   r4   r   aembed_documents	ExceptionrX   s     r$   _aembed_documentszFAISS._aembed_documents   s^      d-z:: 		0AA%HHHHHHHHH
 B  r1   rU   r)   List[float]c                    t          | j        t                    r| j                            |          S |                     |          S rK   )r-   r4   r   embed_queryrG   rU   s     r$   _embed_queryzFAISS._embed_query  sB    d-z:: 	1*66t<<<**4000r1   c                   K   t          | j        t                    r | j                            |           d {V S t	          d          r[   )r-   r4   r   aembed_queryr]   rb   s     r$   _aembed_queryzFAISS._aembed_query  s^      d-z:: 	0==dCCCCCCCCC B  r1   Iterable[str]rM   Iterable[List[float]]	metadatasOptional[Iterable[dict]]idsOptional[List[str]]c                ~  
 t                      }t          | j        t                    st	          d| j         d          t          ||dd           |pd |D             }d t          ||          D             }t          ||dd           t          ||dd	           |r<t          |          t          t          |                    k    rt	          d
          t          j
        |t          j                  }| j        r|                    |           | j                            |           |pd |D             }| j                            d t          ||          D                        t          | j                  

fdt#          |          D             }	| j                            |	           |S )NzSIf trying to add texts, the underlying docstore should support adding items, which z	 does notrN   ri   c              3     K   | ]}i V  d S rK   rS   rT   _s     r$   	<genexpr>zFAISS.__add.<locals>.<genexpr>'  s"      "5"5!2"5"5"5"5"5"5r1   c                6    g | ]\  }}t          ||           S ))page_contentmetadatar   )rT   tms      r$   rV   zFAISS.__add.<locals>.<listcomp>(  s6     
 
 
59QH!a000
 
 
r1   	documentsrM   rk   z$Duplicate ids found in the ids list.dtypec                N    g | ]"}t          t          j                              #S rS   )r)   uuiduuid4ro   s     r$   rV   zFAISS.__add.<locals>.<listcomp>9  s&    777Ac$*,,''777r1   c                    i | ]\  }}||	S rS   rS   )rT   id_docs      r$   
<dictcomp>zFAISS.__add.<locals>.<dictcomp>:  s    HHHS3HHHr1   c                "    i | ]\  }}|z   |S rS   rS   )rT   jr~   starting_lens      r$   r   zFAISS.__add.<locals>.<dictcomp><  s$    JJJC|a'JJJr1   )r%   r-   r7   r   r/   r0   zipr.   setnparrayfloat32rC   r<   r6   addr8   	enumerateupdate)rG   rN   rM   ri   rk   r"   
_metadatasrw   vectorindex_to_idr   s             @r$   __addzFAISS.__add  s    ())$-66 	@'+}@ @ @  
 	E9g{CCC5"5"5u"5"5"5

 
=@
=S=S
 
 
	 	Iz;MMMIsK??? 	E3s88s3s88}},,CDDD *BJ777 	'v&&&
v 777777HHCY4G4GHHHIII4455JJJJ9S>>JJJ!((555
r1   Optional[List[dict]]kwargsc                |    t          |          }|                     |          }|                     ||||          S )al  Run more texts through the embeddings and add to the vectorstore.

        Args:
            texts: Iterable of strings to add to the vectorstore.
            metadatas: Optional list of metadatas associated with the texts.
            ids: Optional list of unique IDs.

        Returns:
            List of ids from adding the texts into the vectorstore.
        ri   rk   )listrY   _FAISS__addrG   rN   ri   rk   r   rM   s         r$   	add_textszFAISS.add_texts@  s<    " U**511
zz%yczJJJr1   c                   K   t          |          }|                     |           d{V }|                     ||||          S )a  Run more texts through the embeddings and add to the vectorstore
            asynchronously.

        Args:
            texts: Iterable of strings to add to the vectorstore.
            metadatas: Optional list of metadatas associated with the texts.
            ids: Optional list of unique IDs.

        Returns:
            List of ids from adding the texts into the vectorstore.
        Nr   )r   r^   r   r   s         r$   
aadd_textszFAISS.aadd_textsU  sR      $ U11%88888888
zz%yczJJJr1   text_embeddings!Iterable[Tuple[str, List[float]]]c                L    t          | \  }}|                     ||||          S )a  Add the given texts and embeddings to the vectorstore.

        Args:
            text_embeddings: Iterable pairs of string and embedding to
                add to the vectorstore.
            metadatas: Optional list of metadatas associated with the texts.
            ids: Optional list of unique IDs.

        Returns:
            List of ids from adding the texts into the vectorstore.
        r   )r   r   )rG   r   ri   rk   r   rN   rM   s          r$   add_embeddingszFAISS.add_embeddingsk  s-    &  1zzz%yczJJJr1         	embeddingkintfilter)Optional[Union[Callable, Dict[str, Any]]]fetch_kList[Tuple[Document, float]]c                x   t                      }t          j        |gt          j                  }| j        r|                    |           | j                            |||n|          \  }}	g }
||                     |          }t          |	d                   D ]\  }}|dk    r| j
        |         }| j                            |          }t          |t                    st          d| d|           |4 ||j                  r#|
                    ||d         |         f           |
                    ||d         |         f           |                    d          F| j        t&          j        t&          j        fv rt,          j        nt,          j        fd|
D             }
|
d|         S )	a  Return docs most similar to query.

        Args:
            embedding: Embedding vector to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Union[Callable, Dict[str, Any]]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.
            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.
            **kwargs: kwargs to be passed to similarity search. Can include:
                score_threshold: Optional, a floating point value between 0 to 1 to
                    filter the resulting set of retrieved docs

        Returns:
            List of documents most similar to the query text and L2 distance
            in float for each. Lower score represents more similarity.
        rx   Nr   Could not find document for id , got score_thresholdc                6    g | ]\  }} |          ||fS rS   rS   )rT   r   
similaritycmpr   s      r$   rV   z@FAISS.similarity_search_with_score_by_vector.<locals>.<listcomp>  sD       #C3z?33j!  r1   )r%   r   r   r   rC   r<   r6   search_create_filter_funcr   r8   r7   r-   r   r/   rt   appendgetr=   r   MAX_INNER_PRODUCTJACCARDoperatorgele)rG   r   r   r   r   r   r"   r   scoresindicesdocsfilter_funcr   i_idr   r   r   s                   @@r$   &similarity_search_with_score_by_vectorz,FAISS.similarity_search_with_score_by_vector  s   4 ())9+RZ888 	'v&&&*++FAAWUU226::Kgaj)) 	1 	1DAqBww+A.C-&&s++Cc8,, U !S3!S!Sc!S!STTT!;s|,, 5KKfQil 3444S&)A,/0000 **%677& )$68H8PQR R  [	     '+  D
 BQBxr1   c                B   K   t          d| j        |f|||d| d{V S )a  Return docs most similar to query asynchronously.

        Args:
            embedding: Embedding vector to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, Any]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.

            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.
            **kwargs: kwargs to be passed to similarity search. Can include:
                score_threshold: Optional, a floating point value between 0 to 1 to
                    filter the resulting set of retrieved docs

        Returns:
            List of documents most similar to the query text and L2 distance
            in float for each. Lower score represents more similarity.
        Nr   r   r   )r   r   )rG   r   r   r   r   r   s         r$   'asimilarity_search_with_score_by_vectorz-FAISS.asimilarity_search_with_score_by_vector  sc      : %7
 
 
 
 
 
 
 
 
 
 
 	
r1   queryc                T    |                      |          } | j        ||f||d|}|S )a  Return docs most similar to query.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.

            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of documents most similar to the query text with
            L2 distance in float. Lower score represents more similarity.
        r   r   )rc   r   rG   r   r   r   r   r   r   r   s           r$   similarity_search_with_scorez"FAISS.similarity_search_with_score  sT    0 %%e,,	:t:
 	
 

 
 
 r1   c                p   K   |                      |           d{V } | j        ||f||d| d{V }|S )a  Return docs most similar to query asynchronously.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.

            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of documents most similar to the query text with
            L2 distance in float. Lower score represents more similarity.
        Nr   )rf   r   r   s           r$   asimilarity_search_with_scorez#FAISS.asimilarity_search_with_score  s      0 ,,U33333333	ATA
 	
 

 
 
 
 
 
 
 
 
 r1   Optional[Dict[str, Any]]List[Document]c                >     | j         ||f||d|}d |D             S )aY  Return docs most similar to embedding vector.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.

            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of Documents most similar to the embedding.
        r   c                    g | ]\  }}|S rS   rS   rT   r   rp   s      r$   rV   z5FAISS.similarity_search_by_vector.<locals>.<listcomp>K      222Q222r1   )r   rG   r   r   r   r   r   docs_and_scoress          r$   similarity_search_by_vectorz!FAISS.similarity_search_by_vector-  sQ    . F$E
 	
 

 
 
 32/2222r1   c                N   K    | j         ||f||d| d{V }d |D             S )ah  Return docs most similar to embedding vector asynchronously.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata.
                Defaults to None. If a callable, it must take as input the
                metadata dict of Document and return a bool.

            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of Documents most similar to the embedding.
        r   Nc                    g | ]\  }}|S rS   rS   r   s      r$   rV   z6FAISS.asimilarity_search_by_vector.<locals>.<listcomp>k  r   r1   )r   r   s          r$   asimilarity_search_by_vectorz"FAISS.asimilarity_search_by_vectorM  ss      . !M L!
 	!
 !

 !
 !
 
 
 
 
 
 
 32/2222r1   c                >     | j         ||f||d|}d |D             S )a  Return docs most similar to query.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter: (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.
            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of Documents most similar to the query.
        r   c                    g | ]\  }}|S rS   rS   r   s      r$   rV   z+FAISS.similarity_search.<locals>.<listcomp>  r   r1   )r   rG   r   r   r   r   r   r   s          r$   similarity_searchzFAISS.similarity_searchm  sJ    ( <$;1
#W
 
8>
 
 32/2222r1   c                N   K    | j         ||f||d| d{V }d |D             S )a  Return docs most similar to query asynchronously.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter: (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.
            fetch_k: (Optional[int]) Number of Documents to fetch before filtering.
                      Defaults to 20.

        Returns:
            List of Documents most similar to the query.
        r   Nc                    g | ]\  }}|S rS   rS   r   s      r$   rV   z,FAISS.asimilarity_search.<locals>.<listcomp>  r   r1   )r   r   s          r$   asimilarity_searchzFAISS.asimilarity_search  sm      ( !C B1!
#W!
 !
8>!
 !
 
 
 
 
 
 
 32/2222r1         ?r   r   lambda_multr   r   floatc                    j                             t          j        |gt          j                  ||n|dz            \  }}|                     |          }g }	|d         D ]}
|
dk    r	 j        |
         } j                            |          }t          |t                    st          d| d|            ||j                  r|	                    |
           t          j        |	g          } fd|d         D             }t          t          j        |gt          j                  |||	          }g }|D ]}
|d         |
         dk    r j        |d         |
                  } j                            |          }t          |t                    st          d| d|           |                    ||d         |
         f           |S )
az  Return docs and their similarity scores selected using the maximal marginal
            relevance.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents and similarity scores selected by maximal marginal
                relevance and score for each.
        rx   N   r   r   r   r   c                j    g | ]/}|d k    j                             t          |                    0S )r   )r6   reconstructr   )rT   r   rG   s     r$   rV   zLFAISS.max_marginal_relevance_search_with_score_by_vector.<locals>.<listcomp>  s5    TTTAQSGGdj,,SVV44GGGr1   )r   r   )r6   r   r   r   r   r   r8   r7   r-   r   r/   rt   r   r   )rG   r   r   r   r   r   r   r   r   filtered_indicesr   r   r   rM   mmr_selectedr   s   `               r$   2max_marginal_relevance_search_with_score_by_vectorz8FAISS.max_marginal_relevance_search_with_score_by_vector  s   8 *++Hi[
333~GG7Q;
 
 226::K!QZ 	/ 	/77/2m**3//!#x00 Y$%Ws%W%WRU%W%WXXX;s|,, /$++A...h 0122GTTTTgajTTT
1Hi[
333#	
 
 
  	8 	8Aqz!}""+GAJqM:C-&&s++Cc8,, U !S3!S!Sc!S!STTT""C1#67777r1   c          	     H   K   t          d| j        |||||           d{V S )a  Return docs and their similarity scores selected using the maximal marginal
            relevance asynchronously.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents and similarity scores selected by maximal marginal
                relevance and score for each.
        Nr   )r   r   )rG   r   r   r   r   r   s         r$   3amax_marginal_relevance_search_with_score_by_vectorz9FAISS.amax_marginal_relevance_search_with_score_by_vector  sU      : %C#
 
 
 
 
 
 
 
 
 	
r1   c                N    |                      |||||          }d |D             S )a  Return docs selected using the maximal marginal relevance.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents selected by maximal marginal relevance.
        r   c                    g | ]\  }}|S rS   rS   r   s      r$   rV   zAFAISS.max_marginal_relevance_search_by_vector.<locals>.<listcomp>'  r   r1   )r   rG   r   r   r   r   r   r   r   s           r$   'max_marginal_relevance_search_by_vectorz-FAISS.max_marginal_relevance_search_by_vector
  s@    4 QQGV R 
 
 32/2222r1   c                ^   K   |                      |||||           d{V }d |D             S )a(  Return docs selected using the maximal marginal relevance asynchronously.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents selected by maximal marginal relevance.
        r   Nc                    g | ]\  }}|S rS   rS   r   s      r$   rV   zBFAISS.amax_marginal_relevance_search_by_vector.<locals>.<listcomp>H  r   r1   )r   r   s           r$   (amax_marginal_relevance_search_by_vectorz.FAISS.amax_marginal_relevance_search_by_vector)  sf      6 JJQ[QW K         	
 32/2222r1   c                V    |                      |          } | j        |f||||d|}|S )a  Return docs selected using the maximal marginal relevance.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering (if needed) to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents selected by maximal marginal relevance.
        r   )rc   r   	rG   r   r   r   r   r   r   r   r   s	            r$   max_marginal_relevance_searchz#FAISS.max_marginal_relevance_searchJ  sU    4 %%e,,	;t;
#
 
 
 
 r1   c                r   K   |                      |           d{V } | j        |f||||d| d{V }|S )a+  Return docs selected using the maximal marginal relevance asynchronously.

        Maximal marginal relevance optimizes for similarity to query AND diversity
        among selected documents.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            fetch_k: Number of Documents to fetch before filtering (if needed) to
                     pass to MMR algorithm.
            lambda_mult: Number between 0 and 1 that determines the degree
                        of diversity among the results with 0 corresponding
                        to maximum diversity and 1 to minimum diversity.
                        Defaults to 0.5.
        Returns:
            List of Documents selected by maximal marginal relevance.
        Nr   )rf   r   r   s	            r$   amax_marginal_relevance_searchz$FAISS.amax_marginal_relevance_searcho  s      4 ,,U33333333	BTB
#
 
 
 
 
 
 
 
 
 
 r1   r   c                l   |t          d          t          |                              | j                                                  }|rt          d|           d | j                                        D             fd|D             | j                            t          j	        t          j
                             | j                            |           fdt          | j                                                  D             }d t          |          D             | _        d	S )
zDelete by ID. These are the IDs in the vectorstore.

        Args:
            ids: List of ids to delete.

        Returns:
            Optional[bool]: True if deletion is successful,
            False otherwise, None if not implemented.
        NzNo ids provided to delete.zESome specified ids do not exist in the current store. Ids not found: c                    i | ]\  }}||	S rS   rS   )rT   idxr~   s      r$   r   z FAISS.delete.<locals>.<dictcomp>  s    UUUxsC#sUUUr1   c                     h | ]
}|         S rS   rS   )rT   r~   reversed_indexs     r$   	<setcomp>zFAISS.delete.<locals>.<setcomp>  s    >>>3>#.>>>r1   rx   c                "    g | ]\  }}|v	|S rS   rS   )rT   r   r~   index_to_deletes      r$   rV   z FAISS.delete.<locals>.<listcomp>  s2     
 
 
3'' '''r1   c                    i | ]\  }}||	S rS   rS   )rT   r   r~   s      r$   r   z FAISS.delete.<locals>.<dictcomp>  s    $S$S$S3Q$S$S$Sr1   T)r/   r   
differencer8   valuesitemsr6   
remove_idsr   fromiterint64r7   deletesortedr   )rG   rk   r   missing_idsremaining_idsr   r   s        @@r$   r  zFAISS.delete  sN    ;9:::#hh))$*C*J*J*L*LMM 	!! !  
 VU43L3R3R3T3TUUU>>>>#>>>
bk/JJJKKKS!!!
 
 
 
 !:!@!@!B!BCC
 
 

 %T$S)M:R:R$S$S$S!tr1   targetr+   c                F   t          | j        t                    st          d          t	          | j                  }| j                            |j                   g }|j                                        D ]^\  }}|j        	                    |          }t          |t                    st          d          |                    ||z   ||f           _| j                            d |D                        d |D             }| j                            |           dS )zMerge another FAISS object with the current one.

        Add the target FAISS to the current one.

        Args:
            target: FAISS object you wish to merge into the current one

        Returns:
            None.
        z'Cannot merge with this type of docstorezDocument should be returnedc                    i | ]	\  }}}||
S rS   rS   )rT   rp   r   r   s       r$   r   z$FAISS.merge_from.<locals>.<dictcomp>  s     AAA33AAAr1   c                    i | ]	\  }}}||
S rS   rS   )rT   r6   r   rp   s       r$   r   z$FAISS.merge_from.<locals>.<dictcomp>  s     AAAmeS!ucAAAr1   N)r-   r7   r   r/   r.   r8   r6   
merge_fromr   r   r   r   r   r   )rG   r  r   	full_infor   	target_idr   r   s           r$   r  zFAISS.merge_from  s.    $-66 	HFGGG4455 	
fl+++ 	"7==?? 	A 	ALAy/((33Cc8,, @ !>???lQ.	3?@@@@ 	AAyAAABBBAAyAAA!((55555r1   r   c                   t                      }	|t          j        k    r)|	                    t	          |d                             }
n(|	                    t	          |d                             }
|                    dt                                }|                    di           } | ||
||f||d|}|                    ||||           |S )Nr   r7   r8   )r<   r=   r   )	r%   r   r   IndexFlatIPr.   IndexFlatL2popr   r   )clsrN   rM   r   ri   rk   r<   r=   r   r"   r6   r7   r8   vecstores                 r$   __fromzFAISS.__from  s     ()) 0 BBB%%c*Q-&8&899EE %%c*Q-&8&899E::j*:*<*<==%zz*@"EE3 	

 &/
 
 
 
 	ujI3GGGr1   c                R    |                     |          } | j        |||f||d|S )aO  Construct FAISS wrapper from raw documents.

        This is a user friendly interface that:
            1. Embeds documents.
            2. Creates an in memory docstore
            3. Initializes the FAISS database

        This is intended to be a quick way to get started.

        Example:
            .. code-block:: python

                from langchain_community.vectorstores import FAISS
                from langchain_community.embeddings import OpenAIEmbeddings

                embeddings = OpenAIEmbeddings()
                faiss = FAISS.from_texts(texts, embeddings)
        r   )rW   _FAISS__fromr  rN   r   ri   rk   r   rM   s          r$   
from_textszFAISS.from_texts  sR    6 ..u55
sz
  
 
 
 
 	
r1   	list[str]c                b   K   |                     |           d{V } | j        |||f||d|S )ae  Construct FAISS wrapper from raw documents asynchronously.

        This is a user friendly interface that:
            1. Embeds documents.
            2. Creates an in memory docstore
            3. Initializes the FAISS database

        This is intended to be a quick way to get started.

        Example:
            .. code-block:: python

                from langchain_community.vectorstores import FAISS
                from langchain_community.embeddings import OpenAIEmbeddings

                embeddings = OpenAIEmbeddings()
                faiss = await FAISS.afrom_texts(texts, embeddings)
        Nr   )r\   r  r  s          r$   afrom_textszFAISS.afrom_texts  sh      6 %55e<<<<<<<<
sz
  
 
 
 
 	
r1   c                t    t          | \  }} | j        t          |          t          |          |f||d|S )a  Construct FAISS wrapper from raw documents.

        This is a user friendly interface that:
            1. Embeds documents.
            2. Creates an in memory docstore
            3. Initializes the FAISS database

        This is intended to be a quick way to get started.

        Example:
            .. code-block:: python

                from langchain_community.vectorstores import FAISS
                from langchain_community.embeddings import OpenAIEmbeddings

                embeddings = OpenAIEmbeddings()
                text_embeddings = embeddings.embed_documents(texts)
                text_embedding_pairs = zip(texts, text_embeddings)
                faiss = FAISS.from_embeddings(text_embedding_pairs, embeddings)
        r   )r   r  r   )r  r   r   ri   rk   r   rN   rM   s           r$   from_embeddingszFAISS.from_embeddings@  s\    :  1zszKK
  
 
 
 
 	
r1   c                *   K    | j         ||f||d|S )z:Construct FAISS wrapper from raw documents asynchronously.r   )r  )r  r   r   ri   rk   r   s         r$   afrom_embeddingszFAISS.afrom_embeddingsg  sA       #s"
  	
 

 
 
 	
r1   folder_path
index_namec                j   t          |          }|                    dd           t                      }|                    | j        t          || dz                       t          || dz  d          5 }t          j        | j	        | j
        f|           ddd           dS # 1 swxY w Y   dS )a  Save FAISS index, docstore, and index_to_docstore_id to disk.

        Args:
            folder_path: folder path to save index, docstore,
                and index_to_docstore_id to.
            index_name: for saving with a specific index file name
        T)exist_okparents.faiss.pklwbN)r   mkdirr%   write_indexr6   r)   openpickledumpr7   r8   )rG   r!  r"  pathr"   fs         r$   
save_localzFAISS.save_localy  s    K  

D$
/// ())$*c$J1F1F1F*F&G&GHHH $J,,,,d33 	GqK(ABAFFF	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	G 	Gs   9"B((B,/B,)allow_dangerous_deserializationr1  c               P   |st          d          t          |          }t                      }|                    t	          || dz                      }t          || dz  d          5 }	t          j        |	          \  }
}ddd           n# 1 swxY w Y    | |||
|fi |S )a  Load FAISS index, docstore, and index_to_docstore_id from disk.

        Args:
            folder_path: folder path to load index, docstore,
                and index_to_docstore_id from.
            embeddings: Embeddings to use when generating queries
            index_name: for saving with a specific index file name
            allow_dangerous_deserialization: whether to allow deserialization
                of the data which involves loading a pickle file.
                Pickle files can be modified by malicious actors to deliver a
                malicious payload that results in execution of
                arbitrary code on your machine.
        B  The de-serialization relies loading a pickle file. Pickle files can be modified to deliver a malicious payload that results in execution of arbitrary code on your machine.You will need to set `allow_dangerous_deserialization` to `True` to enable deserialization. If you do this, make sure that you trust the source of the data. For example, if you are loading a file that you created, and know that no one else has modified the file, then this is safe to do. Do not set this to `True` if you are loading a file from an untrusted source (e.g., some random site on the internet.).r&  r'  rbN)r/   r   r%   
read_indexr)   r+  r,  load)r  r!  rM   r"  r1  r   r.  r"   r6   r/  r7   r8   s               r$   
load_localzFAISS.load_local  s   . / 		"   K  '))  Tz,A,A,A%A!B!BCC $J,,,,d33 	q  $	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 s:uh0DOOOOOs   -BBBbytesc                N    t          j        | j        | j        | j        f          S )zCSerialize FAISS index, docstore, and index_to_docstore_id to bytes.)r,  dumpsr6   r7   r8   rL   s    r$   serialize_to_byteszFAISS.serialize_to_bytes  s     |TZ8QRSSSr1   
serializedc               l    |st          d          t          j        |          \  }}} | ||||fi |S )zGDeserialize FAISS index, docstore, and index_to_docstore_id from bytes.r3  )r/   r,  loads)r  r<  rM   r1  r   r6   r7   r8   s           r$   deserialize_from_byteszFAISS.deserialize_from_bytes  sf     / 		"    L
 
		
  s:uh0DOOOOOr1   Callable[[float], float]c                    | j         | j         S | j        t          j        k    r| j        S | j        t          j        k    r| j        S | j        t          j        k    r| j        S t          d          )a8  
        The 'correct' relevance function
        may differ depending on a few things, including:
        - the distance / similarity metric used by the VectorStore
        - the scale of your embeddings (OpenAI's are unit normed. Many others are not!)
        - embedding dimensionality
        - etc.
        NzJUnknown distance strategy, must be cosine, max_inner_product, or euclidean)
rB   r=   r   r   %_max_inner_product_relevance_score_fnrD   _euclidean_relevance_score_fnCOSINE_cosine_relevance_score_fnr/   rL   s    r$   _select_relevance_score_fnz FAISS._select_relevance_score_fn  s     +733 !%5%GGG==#'7'JJJ55#'7'>>>22   r1   c                    |                                  t          d           | j        |f|||d|}fd|D             }|S )?Return docs and their similarity scores on a scale from 0 to 1.NLrelevance_score_fn must be provided to FAISS constructor to normalize scoresr   c                0    g | ]\  }}| |          fS rS   rS   rT   r   scorer:   s      r$   rV   zBFAISS._similarity_search_with_relevance_scores.<locals>.<listcomp>  ;     
 
 
1;eS$$U++,
 
 
r1   )rF  r/   r   	rG   r   r   r   r   r   r   docs_and_rel_scoresr:   s	           @r$   (_similarity_search_with_relevance_scoresz.FAISS._similarity_search_with_relevance_scores  s     "<<>>%9   <$;
	
 

 
 

 
 
 
?N
 
 
 #"r1   c                   K   |                                  t          d           | j        |f|||d| d{V }fd|D             }|S )rH  NrI  r   c                0    g | ]\  }}| |          fS rS   rS   rK  s      r$   rV   zCFAISS._asimilarity_search_with_relevance_scores.<locals>.<listcomp>4  rM  r1   )rF  r/   r   rN  s	           @r$   )_asimilarity_search_with_relevance_scoresz/FAISS._asimilarity_search_with_relevance_scores  s       "<<>>%9   !C B!
	!
 !

 !
 !
 
 
 
 
 
 

 
 
 
?N
 
 
 #"r1    Callable[[Dict[str, Any]], bool]c                     t                     r S t           t                    st          dt	                                d fd}|S )a  
        Create a filter function based on the provided filter.

        Args:
            filter: A callable or a dictionary representing the filter
            conditions for documents.

        Returns:
            Callable[[Dict[str, Any]], bool]: A function that takes Document's metadata
            and returns True if it satisfies the filter conditions, otherwise False.
        z5filter must be a dict of metadata or a callable, not rt   Dict[str, Any]r   r    c                `     t           fd                                D                       S )Nc              3     K   | ]L\  }}t          |t                    r                    |          |v n                    |          |k    V  Md S rK   )r-   r   r   )rT   keyvaluert   s      r$   rq   zAFAISS._create_filter_func.<locals>.filter_func.<locals>.<genexpr>Q  sv         C eT**0S!!U**\\#&&%/     r1   )allr   )rt   r   s   `r$   r   z.FAISS._create_filter_func.<locals>.filter_funcP  sF         #),,..	     r1   )rt   rV  r   r    )callabler-   dictr/   type)r   r   s   ` r$   r   zFAISS._create_filter_func9  su     F 	M&$'' 	VVVV  	 	 	 	 	 	 r1   )r4   r5   r6   r   r7   r   r8   r9   r:   r;   r<   r    r=   r   )r   rI   )rN   rO   r   rP   )rU   r)   r   r_   )NN)
rN   rg   rM   rh   ri   rj   rk   rl   r   rO   )
rN   rg   ri   r   rk   rl   r   r   r   rO   )
r   r   ri   r   rk   rl   r   r   r   rO   )r   Nr   )r   r_   r   r   r   r   r   r   r   r   r   r   )r   r)   r   r   r   r   r   r   r   r   r   r   )r   r_   r   r   r   r   r   r   r   r   r   r   )r   r_   r   r   r   r   r   r   r   r   r   r   )r   r)   r   r   r   r   r   r   r   r   r   r   )r   r_   r   r   r   r   r   r   r   r   r   r   )r   r   r   N)r   r_   r   r   r   r   r   r   r   r   r   r   r   r   )r   r)   r   r   r   r   r   r   r   r   r   r   r   r   rK   )rk   rl   r   r   r   r   )r  r3   r   r+   )rN   rg   rM   rP   r   r   ri   rj   rk   rl   r<   r    r=   r   r   r   r   r3   )rN   rO   r   r   ri   r   rk   rl   r   r   r   r3   )rN   r  r   r   ri   r   rk   rl   r   r   r   r3   )r   r   r   r   ri   rj   rk   rl   r   r   r   r3   )r6   )r!  r)   r"  r)   r   r+   )r!  r)   rM   r   r"  r)   r1  r    r   r   r   r3   )r   r8  )
r<  r8  rM   r   r1  r    r   r   r   r3   )r   r@  )r   r   r   rT  )0__name__
__module____qualname____doc__r   rD   rH   propertyrM   rY   r^   rc   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  classmethodr  r  r  r  r   r0  r7  r;  r?  rF  rP  rS  staticmethodr   rS   r1   r$   r3   r3   J   s       } }P BF".>.Q! ! ! ! !F 
 
 
 X
E E E E
 
 
 
1 1 1 1    /3#'' ' ' ' 'X +/#'	K K K K K0 +/#'	K K K K K2 +/#'	K K K K K2 <@? ? ? ? ?H <@%
 %
 %
 %
 %
T <@         J <@         J +/3 3 3 3 3F <@3 3 3 3 3F <@3 3 3 3 38 <@3 3 3 3 3:  <@B B B B B BP  <@%
 %
 %
 %
 %
 %
T  <@3 3 3 3 3D  <@3 3 3 3 3H  <@# # # # #P  <@# # # # #J         D6 6 6 6@  /3#'".>.Q    [> 
 +/#'"
 "
 "
 "
 ["
H 
 +/#'"
 "
 "
 "
 ["
H 
 /3#'$
 $
 $
 $
 [$
L 
 /3#'
 
 
 
 [
"G G G G G& 
 "	1P 161P 1P 1P 1P 1P [1PfT T T T  16P P P P P [P>   < <@# # # # #@ <@# # # # #:    \  r1   r3   rK   )r   r   r   r   )
r&   r   r'   r   r(   r)   r*   r)   r   r+   ),
__future__r   loggingr   r   r,  r{   rE   pathlibr   typingr   r   r   r   r	   r
   r   r   r   numpyr   langchain_core.documentsr   langchain_core.embeddingsr   langchain_core.runnables.configr   langchain_core.vectorstoresr   !langchain_community.docstore.baser   r   &langchain_community.docstore.in_memoryr   &langchain_community.vectorstores.utilsr   r   	getLoggerr_  r@   r%   r0   r3   rS   r1   r$   <module>rs     s   " " " " " "   				         
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
     - - - - - - 0 0 0 0 0 0 ; ; ; ; ; ; 3 3 3 3 3 3 D D D D D D D D C C C C C C       
 
	8	$	$    6   N N N N NK N N N N Nr1   