a
    bg@                     @  s   d dl m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 erd dlZG d	d
 d
eZdS )    )annotationsN)repeat)	TYPE_CHECKINGAnyDictIterableListOptionalTupleTypeUnionDocument)
Embeddings)VectorStore)maximal_marginal_relevancec                   @  s  e Zd ZdZdRdddddd	d
ddZeddddZdSddddddddZedTddddddddddddd d!Z	d"d#ddd$d%d&Z
dUddd(dd#d)d*d+ZdVd,dd(dd#d-d.d/ZdWddd(dd0d)d1d2Zd,d(d3d4d5d6ZdXd,dd(dd7d0d8d9d:ZdYd,dd(dd;d<d=d>ZedZdd?d#d@dAdBZeddd"d#dddddCdDdEZd[d,dddHdd#dIdJdKZd\ddddHdd#dLdMdNZd]ddd	dOdPdQZdS )^SupabaseVectorStorea  `Supabase Postgres` vector store.

    It assumes you have the `pgvector`
    extension installed and a `match_documents` (or similar) function. For more details:
    https://integrations.langchain.com/vectorstores?integration_name=SupabaseVectorStore

    You can implement your own `match_documents` function in order to limit the search
    space to a subset of documents based on your own authorization or business logic.

    Note that the Supabase Python client does not yet support async operations.

    If you'd like to use `max_marginal_relevance_search`, please review the instructions
    below on modifying the `match_documents` function to return matched embeddings.


    Examples:

    .. code-block:: python

        from langchain_community.embeddings.openai import OpenAIEmbeddings
        from langchain_core.documents import Document
        from langchain_community.vectorstores import SupabaseVectorStore
        from supabase.client import create_client

        docs = [
            Document(page_content="foo", metadata={"id": 1}),
        ]
        embeddings = OpenAIEmbeddings()
        supabase_client = create_client("my_supabase_url", "my_supabase_key")
        vector_store = SupabaseVectorStore.from_documents(
            docs,
            embeddings,
            client=supabase_client,
            table_name="documents",
            query_name="match_documents",
            chunk_size=500,
        )

    To load from an existing table:

    .. code-block:: python

        from langchain_community.embeddings.openai import OpenAIEmbeddings
        from langchain_community.vectorstores import SupabaseVectorStore
        from supabase.client import create_client


        embeddings = OpenAIEmbeddings()
        supabase_client = create_client("my_supabase_url", "my_supabase_key")
        vector_store = SupabaseVectorStore(
            client=supabase_client,
            embedding=embeddings,
            table_name="documents",
            query_name="match_documents",
        )

      Nzsupabase.client.Clientr   strintzUnion[str, None]None)client	embedding
table_name
chunk_size
query_namereturnc                 C  sV   zddl }W n ty&   tdY n0 || _|| _|p:d| _|pDd| _|pNd| _dS )z Initialize with supabase client.r   NzXCould not import supabase python package. Please install it with `pip install supabase`.	documentsmatch_documentsr   )supabaseImportError_client
_embeddingr   r   r   )selfr   r   r   r   r   r    r$   w/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/vectorstores/supabase.py__init__X   s    	


zSupabaseVectorStore.__init__)r   c                 C  s   | j S N)r"   )r#   r$   r$   r%   
embeddingsq   s    zSupabaseVectorStore.embeddingszIterable[str]zOptional[List[Dict[Any, Any]]]zOptional[List[str]]r   z	List[str])texts	metadatasidskwargsr   c                 K  s<   |pdd |D }|  ||}| jt|}| |||S )Nc                 S  s   g | ]}t t qS r$   r   uuiduuid4.0_r$   r$   r%   
<listcomp>|       z1SupabaseVectorStore.add_texts.<locals>.<listcomp>)_texts_to_documentsr"   embed_documentslistadd_vectors)r#   r)   r*   r+   r,   docsvectorsr$   r$   r%   	add_textsu   s    zSupabaseVectorStore.add_textsr   r   zType['SupabaseVectorStore']zOptional[List[dict]]z Optional[supabase.client.Client]zOptional[str]z'SupabaseVectorStore')clsr)   r   r*   r   r   r   r   r+   r,   r   c	                 K  sj   |st d|st d||}
dd |D }| ||}| j|||
|||fi |	 | |||||dS )z9Return VectorStore initialized from texts and embeddings.zSupabase client is required.z)Supabase document table_name is required.c                 S  s   g | ]}t t qS r$   r-   r0   r$   r$   r%   r3      r4   z2SupabaseVectorStore.from_texts.<locals>.<listcomp>)r   r   r   r   r   )
ValueErrorr6   r5   _add_vectors)r<   r)   r   r*   r   r   r   r   r+   r,   r(   r9   r$   r$   r%   
from_texts   s&    
zSupabaseVectorStore.from_textszList[List[float]]zList[Document])r:   r   r+   r   c                 C  s   |  | j| j|||| jS r'   )r>   r!   r   r   )r#   r:   r   r+   r$   r$   r%   r8      s    zSupabaseVectorStore.add_vectors   zOptional[Dict[str, Any]])querykfilterr,   r   c                 K  s$   | j |}| j|f||d|S NrB   rC   )r"   embed_querysimilarity_search_by_vectorr#   rA   rB   rC   r,   Zvectorr$   r$   r%   similarity_search   s    z%SupabaseVectorStore.similarity_searchzList[float])r   rB   rC   r,   r   c                 K  s*   | j |f||d|}dd |D }|S )NrE   c                 S  s   g | ]\}}|qS r$   r$   )r1   docr2   r$   r$   r%   r3      r4   zCSupabaseVectorStore.similarity_search_by_vector.<locals>.<listcomp>)1similarity_search_by_vector_with_relevance_scores)r#   r   rB   rC   r,   resultr   r$   r$   r%   rG      s    z/SupabaseVectorStore.similarity_search_by_vectorzList[Tuple[Document, float]]c                 K  s$   | j |}| j|f||d|S rD   )r"   rF   rK   rH   r$   r$   r%   'similarity_search_with_relevance_scores   s    z;SupabaseVectorStore.similarity_search_with_relevance_scoreszDict[str, Any])rA   rC   r   c                 C  s   t |d}|r||d< |S )N)Zquery_embeddingrC   )dict)r#   rA   rC   retr$   r$   r%   
match_args   s    
zSupabaseVectorStore.match_argszOptional[float])rA   rB   rC   postgrest_filterscore_thresholdr   c                   s  |rr|  D ]d\}}t|trd|v r|d }ddd |D }	d| d|	 d}
|rld| d	|
 d}q|
}q| ||}| j| j|}|r|j	d
d| d|_|j	d||_|
 }dd |jD } d ur fdd|D }t|dkrtd   |S )Nz$in,c                 s  s   | ]}d t | d V  qdS )'N)r   )r1   vr$   r$   r%   	<genexpr>   r4   zXSupabaseVectorStore.similarity_search_by_vector_with_relevance_scores.<locals>.<genexpr>zmetadata->>z IN ()(z) and (andlimitc                 S  s>   g | ]6}| d rt| di | d dd| ddfqS )contentmetadata r\   page_content
similarity        )getr   r1   searchr$   r$   r%   r3     s   



zYSupabaseVectorStore.similarity_search_by_vector_with_relevance_scores.<locals>.<listcomp>c                   s    g | ]\}}| kr||fqS r$   r$   )r1   rJ   r`   rR   r$   r%   r3     s   r   zDNo relevant docs were retrieved using the relevance score threshold )items
isinstancerN   joinrP   r!   rpcr   paramssetexecutedatalenwarningswarn)r#   rA   rB   rC   rQ   rR   keyvalueZ	in_valuesZ
values_strZ
new_filtermatch_documents_paramsquery_builderresmatch_resultr$   re   r%   rK      s>    	

zESupabaseVectorStore.similarity_search_by_vector_with_relevance_scoresz(List[Tuple[Document, float, np.ndarray]])rA   rB   rC   rQ   r   c           	      C  sd   |  ||}| j| j|}|r8|jdd| d|_|jd||_| }dd |jD }|S )NrY   rX   rW   rZ   c              	   S  s\   g | ]T}| d rt| di | d dd| ddtj| dddtjdd	fqS )
r[   r\   r]   r^   r`   ra   r   z[]rS   )sep)rb   r   npZ
fromstringstripfloat32rc   r$   r$   r%   r3   .  s   



zXSupabaseVectorStore.similarity_search_by_vector_returning_embeddings.<locals>.<listcomp>)rP   r!   ri   r   rj   rk   rl   rm   )	r#   rA   rB   rC   rQ   rs   rt   ru   rv   r$   r$   r%   0similarity_search_by_vector_returning_embeddings  s    zDSupabaseVectorStore.similarity_search_by_vector_returning_embeddingsz"Optional[Iterable[Dict[Any, Any]]])r)   r*   r   c                 C  s(   |du rt i }dd t| |D }|S )z:Return list of Documents from list of texts and metadatas.Nc                 S  s   g | ]\}}t ||d qS )r_   r\   r   )r1   textr\   r$   r$   r%   r3   J  s   z;SupabaseVectorStore._texts_to_documents.<locals>.<listcomp>)r   zip)r)   r*   r9   r$   r$   r%   r5   A  s    z'SupabaseVectorStore._texts_to_documents)r   r   r:   r   r+   r   r,   r   c                   s    fddt |D }g }tdt||D ]X}	||	|	|  }
| ||
 }t|jdkrltddd |jD | q.|S )zAdd vectors to Supabase table.c                   s2   g | ]*\}}|  | j | | jd qS ))idr[   r   r\   r|   )r1   idxr   r   r+   r,   r$   r%   r3   ]  s   z4SupabaseVectorStore._add_vectors.<locals>.<listcomp>r   zError inserting: No rows addedc                 S  s$   g | ]}| d rt| d qS r   )rb   r   r1   ir$   r$   r%   r3   q  r4   )		enumeraterangern   from_Zupsertrl   rm   	Exceptionextend)r   r   r:   r   r+   r   r,   rowsZid_listr   chunkrL   r$   r   r%   r>   Q  s    
z SupabaseVectorStore._add_vectors         ?float)r   rB   fetch_klambda_multr,   r   c           
        s\   |  ||}dd |D  dd |D }ttj|gtjd|||d} fd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 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.
        c                 S  s   g | ]}|d  qS )r   r$   r1   Z	doc_tupler$   r$   r%   r3     r4   zOSupabaseVectorStore.max_marginal_relevance_search_by_vector.<locals>.<listcomp>c                 S  s   g | ]}|d  qS )   r$   r   r$   r$   r%   r3     r4   )Zdtype)rB   r   c                   s   g | ]} | qS r$   r$   r   Zmatched_documentsr$   r%   r3     r4   )r{   r   rx   arrayrz   )
r#   r   rB   r   r   r,   rL   Zmatched_embeddingsZmmr_selectedZfiltered_documentsr$   r   r%   'max_marginal_relevance_search_by_vectorw  s    z;SupabaseVectorStore.max_marginal_relevance_search_by_vector)rA   rB   r   r   r,   r   c                 K  s"   | j |}| j||||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 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.

        `max_marginal_relevance_search` requires that `query_name` returns matched
        embeddings alongside the match documents. The following function
        demonstrates how to do this:

        ```sql
        CREATE FUNCTION match_documents_embeddings(query_embedding vector(1536),
                                                   match_count int)
            RETURNS TABLE(
                id uuid,
                content text,
                metadata jsonb,
                embedding vector(1536),
                similarity float)
            LANGUAGE plpgsql
            AS $$
            # variable_conflict use_column
        BEGIN
            RETURN query
            SELECT
                id,
                content,
                metadata,
                embedding,
                1 -(docstore.embedding <=> query_embedding) AS similarity
            FROM
                docstore
            ORDER BY
                docstore.embedding <=> query_embedding
            LIMIT match_count;
        END;
        $$;
        ```
        )r   )r"   rF   r   )r#   rA   rB   r   r   r,   r   r9   r$   r$   r%   max_marginal_relevance_search  s
    9z1SupabaseVectorStore.max_marginal_relevance_search)r+   r,   r   c                 K  sN   |du rt ddd |D }|D ]&}| j| j d|d   q"dS )zUDelete by vector IDs.

        Args:
            ids: List of ids to delete.
        NzNo ids provided to delete.c                 S  s   g | ]}d |iqS r   r$   )r1   r   r$   r$   r%   r3     s   z.SupabaseVectorStore.delete.<locals>.<listcomp>r   )r=   r!   r   r   deleteeqrl   )r#   r+   r,   r   rowr$   r$   r%   r     s    zSupabaseVectorStore.delete)r   N)NN)NNr   r   r   N)r@   N)r@   N)r@   N)NNN)NN)N)r@   r   r   )r@   r   r   )N)__name__
__module____qualname____doc__r&   propertyr(   r;   classmethodr?   r8   rI   rG   rM   rP   rK   r{   staticmethodr5   r>   r   r   r   r$   r$   r$   r%   r      sb   ?          &#         B  & (   -   ?r   )
__future__r   r.   ro   	itertoolsr   typingr   r   r   r   r   r	   r
   r   r   numpyrx   Zlangchain_core.documentsr   Zlangchain_core.embeddingsr   Zlangchain_core.vectorstoresr   Z&langchain_community.vectorstores.utilsr   r   r   r$   r$   r$   r%   <module>   s   ,