
    h                    ,   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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jN                  e(      Z)dddZ*ddZ+ G d de      Z,y)    )annotationsN)Path)
AnyCallableDictIterableListOptionalSequenceSizedTupleUnion)Document)
Embeddings)run_in_executor)VectorStore)AddableMixinDocstore)InMemoryDocstore)DistanceStrategymaximal_marginal_relevancec                    | 0dt         j                  v rt        t        j                  d            } 	 | rddlm} |S ddl}	 |S # t        $ r t        d      w xY w)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)no_avx2r   s     d/var/www/html/eduruby.in/venv/lib/python3.12/site-packages/langchain_community/vectorstores/faiss.pydependable_faiss_importr#   '   si     ?bjj8ryy12

0 L  L  
H
 	

s   A A Ac                    t        | t              rUt        |t              rEt        |       t        |      k7  r.t        | d| d| dt        |        d| dt        |             y )Nz and z% expected to be equal length but len(z)=z	 and len()
isinstancer   len
ValueError)xyx_namey_names       r"   _len_check_if_sizedr,   B   sk    !U
1e 4Q3q69IheF8 $("SVHIfXRAxA
 	
     c                  4   e Zd ZdZddej
                  f	 	 	 	 	 	 	 	 	 	 	 	 	 d1dZed2d       Zd3dZ	d3dZ
d4dZd4d	Z	 	 d5	 	 	 	 	 	 	 	 	 d6d
Z	 	 d5	 	 	 	 	 	 	 	 	 d7dZ	 	 d5	 	 	 	 	 	 	 	 	 d7dZ	 	 d5	 	 	 	 	 	 	 	 	 d8dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d:dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d:dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d;dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d;dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d<dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d=dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d>dZ	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d>dZddddd	 	 	 	 	 	 	 	 	 	 	 d?dZddddd	 	 	 	 	 	 	 	 	 	 	 d?dZ	 	 	 	 d@	 	 	 	 	 	 	 	 	 	 	 	 	 dAdZ	 	 	 	 d@	 	 	 	 	 	 	 	 	 	 	 	 	 dAdZ	 	 	 	 d@	 	 	 	 	 	 	 	 	 	 	 	 	 dBdZ	 	 	 	 d@	 	 	 	 	 	 	 	 	 	 	 	 	 dBdZdCdDd ZdEd!Z e!dddej
                  f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dFd"       Z"e!	 	 d5	 	 	 	 	 	 	 	 	 	 	 dGd#       Z#e!	 	 d5	 	 	 	 	 	 	 	 	 	 	 dHd$       Z$e!	 	 d5	 	 	 	 	 	 	 	 	 	 	 dId%       Z%e!	 	 d5	 	 	 	 	 	 	 	 	 	 	 dId&       Z&dJdKd'Z'e!	 dJdd(	 	 	 	 	 	 	 	 	 	 	 dLd)       Z(dMd*Z)e!dd(	 	 	 	 	 	 	 	 	 dNd+       Z*dOd,Z+	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d;d-Z,	 	 	 d9	 	 	 	 	 	 	 	 	 	 	 d;d.Z-e.	 	 	 	 dPd/       Z/dQd0Z0y)R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')]

    NFc                J   t        |t              st        j                  d       || _        || _        || _        || _        || _        || _	        || _
        | j                  t        j                  k7  r0| j                  r#t        j                  d| j                          yyy)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warningembedding_functionindexdocstoreindex_to_docstore_iddistance_strategyoverride_relevance_score_fn_normalize_L2r   EUCLIDEAN_DISTANCEwarningswarn)selfr4   r5   r6   r7   relevance_score_fnnormalize_L2r8   s           r"   __init__zFAISS.__init__   s     ,j9NNB #5
 $8!!2+=()""&6&I&II""MM  $ 6 679 # Jr-   c                R    t        | j                  t              r| j                  S d S N)r%   r4   r   r>   s    r"   
embeddingszFAISS.embeddings   s.     $11:> ##	
 	
r-   c                    t        | j                  t              r| j                  j                  |      S |D cg c]  }| j                  |       c}S c c}w rC   )r%   r4   r   embed_documents)r>   textstexts      r"   _embed_documentszFAISS._embed_documents   sH    d--z:**::5AA>CDdD++D1DDDs   Ac                   K   t        | j                  t              r#| j                  j                  |       d {   S t	        d      7 wNr1   )r%   r4   r   aembed_documents	Exception)r>   rH   s     r"   _aembed_documentszFAISS._aembed_documents   sK     d--z:00AA%HHH
 B  I   9AAAc                    t        | j                  t              r| j                  j                  |      S | j                  |      S rC   )r%   r4   r   embed_queryr>   rI   s     r"   _embed_queryzFAISS._embed_query  s:    d--z:**66t<<**400r-   c                   K   t        | j                  t              r#| j                  j                  |       d {   S t	        d      7 wrL   )r%   r4   r   aembed_queryrN   rS   s     r"   _aembed_queryzFAISS._aembed_query  sK     d--z:00==dCCC B  DrP   c           
         t               }t        | j                  t              st	        d| j                   d      t        ||dd       |xs+ |D cg c]  }t        t        j                               ! c}}t        ||dd       |xs	 d |D        }t        |||      D 	
cg c]  \  }}	}
t        ||	|
       }}	}}
t        ||dd	       |r+t        |      t        t        |            k7  rt	        d
      t        j                  |t        j                        }| j                   r|j#                  |       | j$                  j'                  |       | j                  j'                  t        ||      D ci c]  \  }}||
 c}}       t        | j(                        }t+        |      D ci c]  \  }}||z   | }}}| j(                  j-                  |       |S c c}w c c}
}	}w c c}}w c c}}w )NzSIf trying to add texts, the underlying docstore should support adding items, which z	 does notrH   	metadatasidsc              3      K   | ]  }i   y wrC    ).0_s     r"   	<genexpr>zFAISS.__add.<locals>.<genexpr>+  s     "5!2"5s   )idpage_contentmetadata	documentsrE   z$Duplicate ids found in the ids list.dtype)r#   r%   r6   r   r'   r,   struuiduuid4zipr   r&   setnparrayfloat32r:   r@   r5   addr7   	enumerateupdate)r>   rH   rE   rY   rZ   r   r^   
_metadatasid_tmrc   vectordocstarting_lenjindex_to_ids                    r"   __addzFAISS.__add  s    ()$--6''+}}oY@ 
 	E9g{C77Ac$**,'7E375"5u"5
 !eZ8
 
Q !a8
	 

 	Iz;M3s8s3s8},CDD*BJJ7v&

v 	CY4GHS38HI4445;DS>JC|a',JJ!!((5
1 8
  IJs   $G('G- G4
8G:c                d    t        |      }| j                  |      }| j                  ||||      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.
        rY   rZ   )listrJ   _FAISS__addr>   rH   rY   rZ   kwargsrE   s         r"   	add_textszFAISS.add_textsB  s4    " U**51
zz%yczJJr-   c                   K   t        |      }| j                  |       d{   }| j                  ||||      S 7 w)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}   rO   r~   r   s         r"   
aadd_textszFAISS.aadd_textsW  s@     $ U11%88
zz%yczJJ 9s    ><>c                B    t        | \  }}| j                  ||||      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|   )ri   r~   )r>   text_embeddingsrY   rZ   r   rH   rE   s          r"   add_embeddingszFAISS.add_embeddingsm  s*    &  1zzz%yczJJr-         c                |   t               }t        j                  |gt        j                        }| j                  r|j                  |       | j                  j                  |||n|      \  }}	g }
|| j                  |      }t        |	d         D ]  \  }}|dk(  r| j                  |   }| j                  j                  |      }t        |t              st        d| d|       |- |j                        sl|
j!                  ||d   |   f       |
j!                  ||d   |   f        |j#                  d      }|k| j$                  t&        j(                  t&        j*                  fv rt,        j.                  nt,        j0                  }|
D cg c]  \  }} |||      r||f }
}}|
d| S c c}}w )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.
        rd   Nr   Could not find document for id , got score_threshold)r#   rk   rl   rm   r:   r@   r5   search_create_filter_funcro   r7   r6   r%   r   r'   rb   appendgetr8   r   MAX_INNER_PRODUCTJACCARDoperatorgele)r>   	embeddingkfilterfetch_kr   r   ru   scoresindicesdocsfilter_funcrx   i_idrv   r   cmp
similaritys                      r"   &similarity_search_with_score_by_vectorz,FAISS.similarity_search_with_score_by_vector  s   4 ()9+RZZ8v&**++FAWU226:Kgaj) 	1DAqBw++A.C--&&s+Cc8, #B3%vcU!STT!s||,KKfQil 34S&)A,/0	1 !**%67& ))$668H8P8PQR  [[	  (,#Cz?3 j!D 
 BQxs   F8c                V   K   t        d| j                  |f|||d| d{   S 7 w)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   )r>   r   r   r   r   r   s         r"   'asimilarity_search_with_score_by_vectorz-FAISS.asimilarity_search_with_score_by_vector  sH     : %77
 
 
 
 	
 
    )')c                V    | j                  |      } | 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   )rT   r   r>   queryr   r   r   r   r   r   s           r"   similarity_search_with_scorez"FAISS.similarity_search_with_score  sJ    0 %%e,	:t::
 	

 
 r-   c                   K   | j                  |       d{   } | j                  ||f||d| d{   }|S 7 %7 w)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   )rW   r   r   s           r"   asimilarity_search_with_scorez#FAISS.asimilarity_search_with_score  sa     0 ,,U33	ATAA
 	

 
 
  4
s   A=A?AAc                f     | j                   ||f||d|}|D cg c]  \  }}|	 c}}S c c}}w )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   )r   	r>   r   r   r   r   r   docs_and_scoresrv   r^   s	            r"   similarity_search_by_vectorz!FAISS.similarity_search_by_vector/  sN    . F$EE
 	

 
 #22Q222   -c                   K    | j                   ||f||d| d{   }|D cg c]  \  }}|	 c}}S 7 c c}}w w)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   N)r   r   s	            r"   asimilarity_search_by_vectorz"FAISS.asimilarity_search_by_vectorO  s^     . !M L L!
 	!

 !
 
 #22Q22
 3   ?7	?9??c                f     | j                   ||f||d|}|D cg c]  \  }}|	 c}}S c c}}w )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   )r   	r>   r   r   r   r   r   r   rv   r^   s	            r"   similarity_searchzFAISS.similarity_searcho  sG    ( <$;;1
#W
8>
 #22Q222r   c                   K    | j                   ||f||d| d{   }|D cg c]  \  }}|	 c}}S 7 c c}}w w)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   N)r   r   s	            r"   asimilarity_searchzFAISS.asimilarity_search  sX     ( !C B B1!
#W!
8>!
 
 #22Q22
 3r         ?r   r   lambda_multr   c                  | j                   j                  t        j                  |gt        j                        ||n|dz        \  }}|| j                  |      }g }	|d   D ]w  }
|
dk(  r	| j                  |
   }| j                  j                  |      }t        |t              st        d| d|        ||j                        sg|	j                  |
       y t        j                  |	g      }|d   D 
cg c],  }
|
dk7  s	| j                   j                  t        |
            . }}
t        t        j                  |gt        j                        |||      }g }|D ]x  }
|d   |
   dk(  r| j                  |d   |
      }| j                  j                  |      }t        |t              st        d| d|       |j                  ||d   |
   f       z |S c c}
w )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.
        rd      r   r   r   r   )r   r   )r5   r   rk   rl   rm   r   r7   r6   r%   r   r'   rb   r   reconstructintr   )r>   r   r   r   r   r   r   r   r   filtered_indicesr   r   rv   rE   mmr_selectedr   s                   r"   2max_marginal_relevance_search_with_score_by_vectorz8FAISS.max_marginal_relevance_search_with_score_by_vector  s   8 **++HHi[

3~G7Q;
 226:K!QZ 	/7//2mm**3/!#x0$'Fse6RUQV%WXXs||,$++A.	/ hh 012G>EajTAQSGdjj,,SV4T
T1HHi[

3#	
  	8Aqz!}"++GAJqM:C--&&s+Cc8, #B3%vcU!STT""C1#67	8 ' Us   <
G#&G#c          	     V   K   t        d| j                  |||||       d{   S 7 w)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   )r>   r   r   r   r   r   s         r"   3amax_marginal_relevance_search_with_score_by_vectorz9FAISS.amax_marginal_relevance_search_with_score_by_vector  s:     : %CC#
 
 	
 
r   c                d    | j                  |||||      }|D 	cg c]  \  }}	|	 c}	}S c c}	}w )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   )r   
r>   r   r   r   r   r   r   r   rv   r^   s
             r"   'max_marginal_relevance_search_by_vectorz-FAISS.max_marginal_relevance_search_by_vector  s?    4 QQGV R 
 #22Q222s   ,c                   K   | j                  |||||       d{   }|D 	cg c]  \  }}	|	 c}	}S 7 c c}	}w w)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   N)r   r   s
             r"   (amax_marginal_relevance_search_by_vectorz.FAISS.amax_marginal_relevance_search_by_vector+  sS     6 JJQ[QW K   	
 #22Q22	 3s   >6	>8>>c                X    | j                  |      } | 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   )rT   r   	r>   r   r   r   r   r   r   r   r   s	            r"   max_marginal_relevance_searchz#FAISS.max_marginal_relevance_searchL  sK    4 %%e,	;t;;
#
 
 r-   c                   K   | j                  |       d{   } | j                  |f||||d| d{   }|S 7 &7 w)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   )rW   r   r   s	            r"   amax_marginal_relevance_searchz$FAISS.amax_marginal_relevance_searchq  sb     4 ,,U33	BTBB
#
 
 
  4
s   A>AA A Ac                   |t        d      t        |      j                  | j                  j	                               }|rt        d|       | j                  j                         D ci c]  \  }}||
 }}}|D ch c]  }||   	 }}| j                  j                  t        j                  |t        j                               | j                  j                  |       t        | j                  j                               D cg c]  \  }}||vr| }	}}t        |	      D ci c]  \  }}||
 c}}| _        yc c}}w c c}w c c}}w c c}}w )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.
        zNo ids provided to delete.zESome specified ids do not exist in the current store. Ids not found: rd   T)r'   rj   
differencer7   valuesitemsr5   
remove_idsrk   fromiterint64r6   deletesortedro   )
r>   rZ   r   missing_idsidxrr   reversed_indexindex_to_deleter   remaining_idss
             r"   r   zFAISS.delete  sE    ;9::#h))$*C*C*J*J*LMW-! 
 483L3L3R3R3TUxsC#s(UU:=>3>#.>>

bkk/JKS! !!:!:!@!@!BC
3' 
 

 ;DM:R$S3QV$S! V>


 %Ts   -EEE/Ec           
        t        | j                  t              st        d      t	        | j
                        }| j                  j                  |j                         g }|j
                  j                         D ]R  \  }}|j                  j                  |      }t        |t              st        d      |j                  ||z   ||f       T | j                  j                  |D ci c]	  \  }}}|| c}}}       |D 	ci c]	  \  }	}}|	| }
}}	}| j
                  j                  |
       yc c}}}w c c}}}	w )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 returnedN)r%   r6   r   r'   r&   r7   r5   
merge_fromr   r   r   r   rn   rp   )r>   targetrw   	full_infor   	target_idrv   r^   r   r5   ry   s              r"   r   zFAISS.merge_from  s    $--6FGG4445 	

fll+ 	"77==? 	ALAy//((3Cc8, !>??lQ.	3?@		A 	yAA338AB7@AAmeS!uczAA!!((5 BAs   ,D7	D>c                V   t               }	|t        j                  k(  r|	j                  t	        |d               }
n|	j                  t	        |d               }
|j                  dt                     }|j                  di       } | ||
||f||d|}|j                  ||||       |S )Nr   r6   r7   )r@   r8   r|   )	r#   r   r   IndexFlatIPr&   IndexFlatL2popr   r~   )clsrH   rE   r   rY   rZ   r@   r8   r   r   r5   r6   r7   vecstores                 r"   __fromzFAISS.__from  s     () 0 B BB%%c*Q-&89E %%c*Q-&89E::j*:*<=%zz*@"E 	

 &/
 
 	ujI3Gr-   c                T    |j                  |      } | 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|   )rG   _FAISS__fromr   rH   r   rY   rZ   r   rE   s          r"   
from_textszFAISS.from_texts  sG    6 ..u5
szz
  
 
 	
r-   c                p   K   |j                  |       d{   } | j                  |||f||d|S 7 w)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|   )rM   r   r   s          r"   afrom_textszFAISS.afrom_texts  sS     6 %55e<<
szz
  
 
 	
 =s   646c                l    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|   )ri   r   r}   )r   r   r   rY   rZ   r   rH   rE   s           r"   from_embeddingszFAISS.from_embeddingsB  sO    :  1zszzK
  
 
 	
r-   c                8   K    | j                   ||f||d|S w)z:Construct FAISS wrapper from raw documents asynchronously.r|   )r   )r   r   r   rY   rZ   r   s         r"   afrom_embeddingszFAISS.afrom_embeddingsi  s:      #s""
  	

 
 	
s   c                P   t        |      }|j                  dd       t               }|j                  | j                  t        || dz               t        || dz  d      5 }t        j                  | j                  | j                  f|       ddd       y# 1 sw Y   yxY w)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_indexr5   rf   openpickledumpr6   r7   )r>   folder_path
index_namepathr   fs         r"   
save_localzFAISS.save_local{  s     K 

D$
/ ()$**c$J<v1F*F&GH $J<t,,d3 	GqKK(A(ABAF	G 	G 	Gs   &-BB%)allow_dangerous_deserializationc                  |st        d      t        |      }t               }|j                  t	        || dz              }t        || dz  d      5 }	t        j                  |	      \  }
}ddd        | ||
fi |S # 1 sw Y   xY w)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_indexrf   r   r   load)r   r  rE   r  r  r   r  r   r5   r  r6   r7   s               r"   
load_localzFAISS.load_local  s    . /	"  K ')  Tzl&,A%A!BC $J<t,,d3 	q $	 :uh0DOOO	 	s   BBc                n    t        j                  | j                  | j                  | j                  f      S )zCSerialize FAISS index, docstore, and index_to_docstore_id to bytes.)r   dumpsr5   r6   r7   rD   s    r"   serialize_to_byteszFAISS.serialize_to_bytes  s&    ||TZZ8Q8QRSSr-   c               f    |st        d      t        j                  |      \  }}} | ||||fi |S )zGDeserialize FAISS index, docstore, and index_to_docstore_id from bytes.r  )r'   r   loads)r   
serializedrE   r  r   r5   r6   r7   s           r"   deserialize_from_byteszFAISS.deserialize_from_bytes  sQ     /	"   LL
		
  :uh0DOOOr-   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.
        zJUnknown distance strategy, must be cosine, max_inner_product, or euclidean)
r9   r8   r   r   %_max_inner_product_relevance_score_fnr;   _euclidean_relevance_score_fnCOSINE_cosine_relevance_score_fnr'   rD   s    r"   _select_relevance_score_fnz FAISS._select_relevance_score_fn  s     ++7333 !!%5%G%GG===##'7'J'JJ555##'7'>'>>222  r-   c                    | j                         }|t        d       | j                  |f|||d|}|D 	cg c]  \  }}	| ||	      f }
}}	|
S c c}	}w )?Return docs and their similarity scores on a scale from 0 to 1.Lrelevance_score_fn must be provided to FAISS constructor to normalize scoresr   )r  r'   r   r>   r   r   r   r   r   r?   r   rv   scoredocs_and_rel_scoress              r"   (_similarity_search_with_relevance_scoresz.FAISS._similarity_search_with_relevance_scores  s     "<<>%9  <$;;
	

 
 @O
1;eS$U+,
 
 #"
s   Ac                   K   | j                         }|t        d       | j                  |f|||d| d{   }|D 	cg c]  \  }}	| ||	      f }
}}	|
S 7 "c c}	}w w)r  Nr  r   )r  r'   r   r  s              r"   )_asimilarity_search_with_relevance_scoresz/FAISS._asimilarity_search_with_relevance_scores  s      "<<>%9  !C B B!
	!

 !
 
 @O
1;eS$U+,
 
 #"

s!   8A%A	A%AA%A%c                   t        |       r| S t        | t              st        dt	        |              ddlm}m}m}m	}m
}m} ||||||d}d d d}||z  t        t              g dz         }	d	| D ])  }
|
s|
j                  d
      s|
|	vst        d|
        	 	 	 	 	 	 dfd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:
            A function that takes Document's metadata and returns True if it
            satisfies the filter conditions, otherwise False.

        Raises:
            ValueError: If the filter is invalid or contains unsupported operators.
        z5filter must be a dict of metadata or a callable, not r   )eqr   gtr   ltne)z$eqz$neqz$gtz$ltz$gtez$ltec                
    | |v S rC   r\   abs     r"   <lambda>z+FAISS._create_filter_func.<locals>.<lambda>`  s
    Q r-   c                
    | |vS rC   r\   r)  s     r"   r,  z+FAISS._create_filter_func.<locals>.<lambda>a  s
    ! r-   )z$inz$nin)$and$or$not
   $&filter contains unsupported operator: c                8    t        t              rKg j                         D ]-  \  }}|vrt        d|       j	                  |   |f       / d fd}|S t        t
              r%t              kD  rt               fdS  fdS  fdS )a  
            Creates a filter function based on field and condition.

            Args:
                field: The document field to filter on
                condition: Filter condition (dict for operators, list for in,
                           or direct value for equality)

            Returns:
                A filter function that takes a document and returns boolean
            r3  c                P    | j                        t        fdD              S )aW  
                    Evaluates a document against a set of predefined operators
                    and their values. This function applies multiple
                    comparison/sequence operators to a specific field value
                    from the document. All conditions must be satisfied for the
                    function to return True.

                    Args:
                        doc (Dict[str, Any]): The document to evaluate, containing
                        key-value pairs where keys are field names and values
                        are the field values. The document must contain the field
                        being filtered.

                    Returns:
                        bool: True if the document's field value satisfies all
                            operator conditions, False otherwise.
                    c              3  6   K   | ]  \  }} ||        y wrC   r\   )r]   opvalue	doc_values      r"   r_   zYFAISS._create_filter_func.<locals>.filter_func_cond.<locals>.filter_fn.<locals>.<genexpr>  s     O	Er)U3Os   )r   all)rv   r9  field	operatorss    @r"   	filter_fnzFFAISS._create_filter_func.<locals>.filter_func_cond.<locals>.filter_fn  s#    $ !$IOYOOOr-   c                *    | j                        v S rC   r   )rv   condition_setr;  s    r"   r,  zEFAISS._create_filter_func.<locals>.filter_func_cond.<locals>.<lambda>  s    swwu~'F r-   c                *    | j                        v S rC   r?  rv   	conditionr;  s    r"   r,  zEFAISS._create_filter_func.<locals>.filter_func_cond.<locals>.<lambda>  s    3775>Y#> r-   c                ,    | j                        k(  S rC   r?  rB  s    r"   r,  zEFAISS._create_filter_func.<locals>.filter_func_cond.<locals>.<lambda>  s    swwu~: r-   )rv   Dict[str, Any]returnr   )r%   dictr   r'   r   r}   r&   	frozenset)	r;  rC  r7  r8  r=  r@  r<  
OPERATIONSSET_CONVERT_THRESHOLDs	   ``   @@r"   filter_func_condz3FAISS._create_filter_func.<locals>.filter_func_condl  s     )T*	!*!2 >IB+(+QRTQU)VWW$$jne%<=>
P* ! )T*y>$99$-i$8MFF>>::r-   c                8   d| v r| d   D cg c]
  } |       c}fdS d| v r| d   D cg c]
  } |       c}fdS d| v r | d         fdS | j                         D cg c]  \  }} ||       c}}fdS c c}w c c}w c c}}w )a  
            Creates a filter function that evaluates documents against specified
            filter conditions.

            This function processes a dictionary of filter conditions and returns
            a callable that can evaluate documents against these conditions. It
            supports logical operators ($and, $or, $not) and field-level filtering.

            Args:
                filter (Dict[str, Any]): A dictionary containing filter conditions.
                Can include:
                    - Logical operators ($and, $or, $not) with lists of sub-filters
                    - Field-level conditions with comparison or sequence operators
                    - Direct field-value mappings for equality comparison

            Returns:
                Callable[[Dict[str, Any]], bool]: A function that takes a document
                (as a dictionary) and returns True if the document matches all
                filter conditions, False otherwise.
            r.  c                .     t         fdD              S )Nc              3  .   K   | ]  } |        y wrC   r\   r]   r  rv   s     r"   r_   zSFAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>.<locals>.<genexpr>       &?!qv&?   r:  rv   filterss   `r"   r,  z@FAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>      3&?w&?#? r-   r/  c                .     t         fdD              S )Nc              3  .   K   | ]  } |        y wrC   r\   rO  s     r"   r_   zSFAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>.<locals>.<genexpr>  rP  rQ  )anyrS  s   `r"   r,  z@FAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>  rU  r-   r0  c                     |        S rC   r\   )rv   conds    r"   r,  z@FAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>  s    tCy= r-   c                .     t         fdD              S )Nc              3  .   K   | ]  } |        y wrC   r\   )r]   rC  rv   s     r"   r_   zSFAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>.<locals>.<genexpr>  s     "Ni9S>"NrQ  rR  )rv   
conditionss   `r"   r,  z@FAISS._create_filter_func.<locals>.filter_func.<locals>.<lambda>  s    s"N:"NN r-   )r   )	r   
sub_filterr;  rC  rZ  r]  rT  r   rK  s	       @@@r"   r   z.FAISS._create_filter_func.<locals>.filter_func  s    * EKF^Tz;z2T??EKE]Sz;z2S??"6&>200 )/$E9 !	2J ON U Ts   BB0B)r;  rf   rC  z%Union[Dict[str, Any], List[Any], Any]rF   Callable[[Dict[str, Any]], bool])r   rE  rF  r_  )callabler%   rG  r'   typer   r$  r   r%  r   r&  r'  rH  r}   
startswith)r   r$  r   r%  r   r&  r'  COMPARISON_OPERATORSSEQUENCE_OPERATORSVALID_OPERATORSr7  rI  rJ  r   rK  s              @@@@r"   r   zFAISS._create_filter_func;  s    $ FM&$'GV~V  	43  
 '+
 *,>>
#D$47N$NO "  	PBbmmC(R-F #I"!NOO	P2	;2	;#H2	;-2	;h%	ON 6""r-   c                   |D cg c]  }| j                   j                  |       }}|D cg c]  }t        |t              s| c}S c c}w c c}w rC   )r6   r   r%   r   )r>   rZ   rr   r   rv   s        r"   
get_by_idszFAISS.get_by_ids  sF    589c$$S)99#Az#x'@AA :As   "A
AA)r4   z/Union[Callable[[str], List[float]], Embeddings]r5   r   r6   r   r7   zDict[int, str]r?   z"Optional[Callable[[float], float]]r@   r   r8   r   )rF  zOptional[Embeddings])rH   	List[str]rF  List[List[float]])rI   rf   rF  List[float])NN)
rH   Iterable[str]rE   zIterable[List[float]]rY   Optional[Iterable[dict]]rZ   Optional[List[str]]rF  rh  )
rH   rk  rY   Optional[List[dict]]rZ   rm  r   r   rF  rh  )
r   !Iterable[Tuple[str, List[float]]]rY   rn  rZ   rm  r   r   rF  rh  )r   Nr   )r   rj  r   r   r   )Optional[Union[Callable, Dict[str, Any]]]r   r   r   r   rF  List[Tuple[Document, float]])r   rf   r   r   r   rp  r   r   r   r   rF  rq  )r   rj  r   r   r   zOptional[Dict[str, Any]]r   r   r   r   rF  List[Document])r   rj  r   r   r   rp  r   r   r   r   rF  rr  )r   rf   r   r   r   rp  r   r   r   r   rF  rr  )r   rj  r   r   r   r   r   floatr   rp  rF  rq  )r   r   r   N)r   rj  r   r   r   r   r   rs  r   rp  r   r   rF  rr  )r   rf   r   r   r   r   r   rs  r   rp  r   r   rF  rr  rC   )rZ   rm  r   r   rF  Optional[bool])r   r/   rF  None)rH   rk  rE   ri  r   r   rY   rl  rZ   rm  r@   r   r8   r   r   r   rF  r/   )rH   rh  r   r   rY   rn  rZ   rm  r   r   rF  r/   )rH   z	list[str]r   r   rY   rn  rZ   rm  r   r   rF  r/   )r   ro  r   r   rY   rl  rZ   rm  r   r   rF  r/   )r5   )r  rf   r  rf   rF  ru  )r  rf   rE   r   r  rf   r  r   r   r   rF  r/   )rF  bytes)
r  rv  rE   r   r  r   r   r   rF  r/   )rF  zCallable[[float], float])r   rp  rF  r_  )rZ   zSequence[str]rF  zlist[Document])1__name__
__module____qualname____doc__r   r;   rA   propertyrE   rJ   rO   rT   rW   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   r  r  r  r  r  r   r"  staticmethodr   rg  r\   r-   r"   r/   r/   K   sd	   }P BF".>.Q.Q!
! ! ! -! ?! ! ,!F 
 
E
1 /3#'(( *( ,	(
 !( 
(Z +/#'	KK (K !	K
 K 
K0 +/#'	KK (K !	K
 K 
K2 +/#'	K:K (K !	K
 K 
K2 <@?? ? :	?
 ? ? 
&?H <@%
%
 %
 :	%

 %
 %
 
&%
T <@     :	 
     
& J <@     :	 
     
& J +/33 3 )	3
 3 3 
3F <@33 3 :	3
 3 3 
3F <@33 3 :	3
 3 3 
38 <@33 3 :	3
 3 3 
3:  <@BB 	B
 B B :B 
&BP  <@%
%
 	%

 %
 %
 :%
 
&%
T  <@33 3 	3
 3 :3 3 
3D  <@33 3 	3
 3 :3 3 
3H  <@## # 	#
 # :# # 
#P  <@## # 	#
 # :# # 
#J D6@  /3#'".>.Q.Q & 	
 , !  ,  
 > 
 +/#'"
"
 "
 (	"

 !"
 "
 
"
 "
H 
 +/#'"
"
 "
 (	"

 !"
 "
 
"
 "
H 
 /3#'$
:$
 $
 ,	$

 !$
 $
 
$
 $
L 
 /3#'
:
 
 ,	

 !
 
 

 
"G& 
 "	1P 161P1P 1P 	1P *.1P 1P 
1P 1PfT  16PP P
 *.P P 
P P>< <@## # :	#
 # # 
&#@ <@## # :	#
 # # 
&#: K#9K#	)K# K#ZBr-   r/   rC   )r!   rt  rF  r   )
r(   r   r)   r   r*   rf   r+   rf   rF  ru  )-
__future__r   loggingr   r   r   rg   r<   pathlibr   typingr   r   r   r   r	   r
   r   r   r   r   numpyrk   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   	getLoggerrw  r2   r#   r,   r/   r\   r-   r"   <module>r     sv    "   	        - 0 ; 3 D C
 
		8	$6@BK @Br-   