
    Zǻi0E                    D   d dl mZ d dlZd dlZd dlmZmZ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mZmZ d dlmZmZmZm Z  d d	l!m"Z" e	r
d d
l#m$Z$m%Z%m&Z&  ed      Z' ed      Z(ddZ) G d de      Z* G d dee*      Z+ G d de+e      Z,y)    )annotationsN)ABCABCMetaabstractmethod)
TYPE_CHECKINGAnyCallableOptionalTypeVarget_args
get_originUnionDictget_type_hints)	ParamSpec)Neo4jVersionError)RawSearchResultRetrieverResultRetrieverResultItem)get_versionhas_metadata_filtering_supporthas_vector_index_supportis_version_5_23_or_above)driver_config)ObjectParameterToolToolParameterTPc                    t        j                  | j                  | j                  | j                  | j
                  | j                        }|j                  j                  | j                         |S )z-Based on https://stackoverflow.com/a/30714299)nameargdefsclosure)	typesFunctionType__code____globals____name____defaults____closure____dict__update)fgs     \/opt/lhia/marcimex/agent/venv/lib/python3.12/site-packages/neo4j_graphrag/retrievers/base.pycopy_functionr0   9   sR    	

	ZZ	A JJajj!H    c                  (    e Zd ZdZ	 	 	 	 	 	 	 	 ddZy)RetrieverMetaclasszThis metaclass is used to copy the docstring from the
    `get_search_results` method, instantiated in all subclasses,
    to the `search` method in the base class.
    c                >   d|v rt         j                  | |||      S |j                  d      }d }|D ]  }t        |dd       }| n |r=|r;t	        |      }|j
                  |_        t        j                  |      |_        ||d<   t         j                  | |||      S )Nsearchget_search_results)	type__new__getgetattrr0   __doc__inspect	signature__signature__)metar!   basesattrsget_search_results_methodsearch_methodbnew_search_methods           r/   r8   zRetrieverMetaclass.__new__M   s     u<<dE599 %*II.B$C! 	A#Ax6M(	 6 -m <(A(I(I%.5.?.?)/+ 0E(O||D$u55r1   N)r!   strr@   ztuple[type, ...]rA   zdict[str, Any]returnr7   )r(   
__module____qualname__r;   r8    r1   r/   r3   r3   G   s,    
66 069G6	6r1   r3   c                      e Zd ZU dZded<   dZdddZddZddZe	dd	       Z
dd
ZddZ	 d	 	 	 ddZ	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 ddZy)	Retrieverz-
    Abstract class for Neo4j retrievers
    rF   
index_nameTNc                
   t        j                  |      | _        || _        | j                  rVt        | j                  | j                        \  }}}t        |      | _        t        |      rt        ||      s
t               y y N)r   override_user_agentdriverneo4j_databaseVERIFY_NEO4J_VERSIONr   r   neo4j_version_is_5_23_or_abover   r   r   )selfrQ   rR   version_tupleis_aura_s         r/   __init__zRetriever.__init__m   s}    #77?,$$(3DKKATAT(U%M7A2J3D/ ,3M7K')) L %r1   c                L   d}| j                   j                  |d|i| j                  t        j                  j
                        }	 |j                  d   }|d   d   | _        |d   d   | _        |d   | _	        y
# t        $ r}t        d| j                   d	      |d
}~ww xY w)zFetch the node label and embedding property from the index definition

        Args:
            vector_index_name (str): Name of the vector index
        zSHOW VECTOR INDEXES YIELD name, labelsOrTypes, properties, options WHERE name = $index_name RETURN labelsOrTypes as labels, properties, options.indexConfig.`vector.dimensions` as dimensionsrM   )	database_routing_r   labels
properties
dimensionszNo index with name z foundN)rQ   execute_queryrR   neo4jRoutingControlREADrecords_node_label_embedding_node_property_embedding_dimension
IndexError	ExceptionrM   )rU   vector_index_namequeryquery_resultresultes         r/   _fetch_index_infoszRetriever._fetch_index_infosz   s    D 	 {{00,-))))..	 1 
	R!))!,F%h/2D,2<,@,CD)(.|(<D% 	R1$//1B&IJPQQ	Rs   3A; ;	B#BB#c                     | j                   |i |}| j                         }|j                  D cg c]
  } ||       }}|j                  xs i }| j                  j
                  |d<   t        ||      S c c}w )zSearch method. Call the `get_search_results` method that returns
        a list of `neo4j.Record`, and format them using the function returned by
        `get_result_formatter` to return `RetrieverResult`.
        __retriever)itemsmetadata)r6   get_result_formatterrd   rs   	__class__r(   r   )rU   argskwargs
raw_result	formatterrecordsearch_itemsrs   s           r/   r5   zRetriever.search   s    
 -T,,d=f=
--/	8B8J8JKf	&)KK&&,""&.."9"9
 	
 Ls   A8c                     y)a  This method must be implemented in each child class. It will
        receive the same parameters provided to the public interface via
        the `search` method, after validation. It returns a `RawSearchResult`
        object which comprises a list of `neo4j.Record` objects and an optional
        `metadata` dictionary that can contain retriever-level information.

        Note that, even though this method is not intended to be called from
        outside the class, we make it public to make it clearer for the developers
        that it should be implemented in child classes.

        Returns:
            RawSearchResult: List of Neo4j Records and optional metadata dict
        NrJ   )rU   rv   rw   s      r/   r6   zRetriever.get_search_results   s     	r1   c                f    t        | d      r| j                  xs | j                  S | j                  S )zc
        Returns the function to use to transform a neo4j.Record to a RetrieverResultItem.
        result_formatter)hasattrr~   default_record_formatter)rU   s    r/   rt   zRetriever.get_result_formatter   s2     4+,((ID,I,II,,,r1   c                L    t        t        |      |j                  d            S )z
        Best effort to guess the node-to-text method. Inherited classes
        can override this method to implement custom text formatting.
        rs   )contentrs   )r   rF   r9   )rU   rz   s     r/   r   z"Retriever.default_record_formatter   s    
 #3v;JAWXXr1   c                ,    | j                  |xs i       S )a  Return the parameters that this retriever expects for tool conversion.

        This method automatically infers parameters from the get_search_results method signature.

        Args:
            parameter_descriptions (Optional[Dict[str, str]]): Custom descriptions for parameters.
                Keys should match parameter names from get_search_results method.

        Returns:
            ObjectParameter: The parameter definition for this retriever
        ) _infer_parameters_from_signature)rU   parameter_descriptionss     r/   get_parameterszRetriever.get_parameters   s     445K5QrRRr1   c                x   ddl m} t        j                  | j                        }	 t        | j                        }i }g }|j                  j                         D ]  \  }}|dk(  r|j                  t        j                  j                  k(  r4|j                  t        j                  j                  u }	|j                  ||j                         }
| j#                  ||
|	|      }|s|||<   |	s|j%                  |         |d| j&                  j(                   ||d      S # t        t        f$ r i }Y w xY w)z>Infer parameters from the get_search_results method signature.r   )r   rU   zParameters for F)descriptionr^   required_propertiesadditional_properties)neo4j_graphrag.toolr   r<   r=   r6   r   	NameErrorAttributeError
parametersrr   kind	ParameterVAR_KEYWORDdefaultemptyr9   
annotation _create_tool_parameter_from_typeappendru   r(   )rU   r   r   sig
type_hintsr^   r   
param_nameparamis_requiredtype_annotation
tool_params               r/   r   z*Retriever._infer_parameters_from_signature   sC   
	

  7 78	'(?(?@J
 24
 !$!5!5!7 	;JV# zzW..:::  --7+<+<+B+BBK )nnZ9I9IJO >>O[:PJ )3
:&'..z:/	;2 )$..*A*A)BC! 3"'	
 	
A >* 	J	s   D% %D98D9c                b   ddl m}m}m}m}m}	 |t        j                  j                  u s| ||j                  |d|       |      S t        |      }
t        |      }|
t        u rr|D cg c]  }|t        d      us| }}t        |      dk(  r|d   }t        |      }
t        |      }n+t        |      dkD  r ||j                  |d|       |      S |t        u r ||j                  |d|       |      S |t         u r* ||j                  |d|       |dv rd|      S d|      S |t"        u r8i }|d	k(  r|j%                  d
d        |d|j                  |d|       |d|S |
t&        u s@|t&        u s8t)        |d      r|j*                  t&        u st        |      j-                  d      rR|r1|d   t"        u r& | |dd      |j                  |d|       |      S  |	|j                  |d|       i d|      S |
t.        u st)        |d      r1|j*                  t.        u r |	|j                  |d|       i d|      S t        |      t1        fddD              r |	|j                  |d|       i d|      S  ||j                  |d|       |      S c c}w )z/Create a tool parameter from a type annotation.r   )StringParameterIntegerParameterNumberParameterArrayParameterr   Nz
Parameter )r   required   )top_keffective_search_ratio)r   minimumr   alphag        g      ?)r   maximum
__origin__zlist[zA single vector componentF)rr   r   r   T)r   r^   r   r   c              3  B   K   | ]  }|j                         v   y wrO   )lower).0keyword	type_names     r/   	<genexpr>z=Retriever._create_tool_parameter_from_type.<locals>.<genexpr>  s%       9??,,s   )dictlistzoptional[dictzoptional[listrJ   )r   r   r   r   r   r   r<   r   r   r9   r   r   r   r7   lenrF   intfloatr,   r   r   r   
startswithr   any)rU   r   r   r   r   r   r   r   r   r   originrv   argnon_none_argsconstraintsr   s                  @r/   r   z*Retriever._create_tool_parameter_from_type  s   	
 	
 g//5559P"266*ZL 9 %	  O,( U?,0JSCtDz4ISJMJ=!Q&"/"2#O40]#a'& 6 : :"j$=! )	  c!"266*ZL 9 %	  ##266*ZL 9 !DD  %  $  %*,KW$""3"<" 266*ZL 9 %	
   dN$&6#..$6?#..w7 Q5(%)$?!& !7 : :"j$=! )	 	 ' 6 : :"j$=!  "*.(  t^O\2**d2"266*ZL 9 &*$  O,I Q  ' 6 : :"j$=!  "*.(  #266*ZL 9 %	 Q Ks   -J, J,c                ^     ddl m}  j                  |xs i       }d fd} |||||      S )a  Convert this retriever to a Tool object.

        Args:
            name (str): Name for the tool.
            description (str): Description of what the tool does.
            parameter_descriptions (Optional[Dict[str, str]]): Optional descriptions for each parameter.
                Keys should match parameter names from get_search_results method.

        Returns:
            Tool: A Tool object configured to use this retriever's search functionality.
        r   )r   c                 (     j                   di | S )NrJ   )r5   )rw   rU   s    r/   execute_funcz/Retriever.convert_to_tool.<locals>.execute_func  s    4;;(((r1   )r!   r   r   r   )rw   r   rG   r   )r   r   r   )rU   r!   r   r   r   r   r   s   `      r/   convert_to_toolzRetriever.convert_to_tool  s@    $ 	- (()?)E2F
	) #%!	
 	
r1   rO   )rQ   neo4j.DriverrR   Optional[str])rj   rF   rG   None)rv   r   rw   r   rG   r   )rv   r   rw   r   rG   r   )rG   z-Callable[[neo4j.Record], RetrieverResultItem])rz   zneo4j.RecordrG   r   )r   Optional[Dict[str, str]]rG   'ObjectParameter')r   Dict[str, str]rG   r   )
r   rF   r   r   r   boolr   r   rG   zOptional['ToolParameter'])r!   rF   r   rF   r   r   rG   z'Tool')r(   rH   rI   r;   __annotations__rS   rY   ro   r5   r   r6   rt   r   r   r   r   r   rJ   r1   r/   rL   rL   e   s     O*R6
   -Y BFS&>S	S 2
&42
	2
hNN N 	N
 !/N 
#Nh <@	!
!
 !
 !9	!

 
!
r1   rL   )	metaclassc                  l     e Zd ZdZdZ	 	 d	 	 	 	 	 	 	 	 	 d fdZe	 	 	 d	 	 	 	 	 	 	 	 	 dd       Z xZS )	ExternalRetrieverz3
    Abstract class for External Vector Stores
    Fc                \    t         |   |       || _        || _        || _        || _        y rO   )superrY   id_property_externalid_property_neo4jnode_label_neo4jrR   )rU   rQ   r   r   rR   r   ru   s         r/   rY   zExternalRetriever.__init__  s2     	 $8!!2 0,r1   c                     y)zn

        Returns:
                RawSearchResult: List of Neo4j Records and optional metadata dict

        NrJ   )rU   query_vector
query_textr   rw   s        r/   r6   z$ExternalRetriever.get_search_results  s     	r1   )NN)
rQ   r   r   rF   r   rF   rR   r   r   r   )NN   )
r   zOptional[list[float]]r   r   r   r   rw   r   rG   r   )	r(   rH   rI   r;   rS   rY   r   r6   __classcell__)ru   s   @r/   r   r     s     ! )-*.-- "- 	-
 &- (-  /3$(	+ " 	
  
 r1   r   )r-   Callable[T, P]rG   r   )-
__future__r   r<   r$   abcr   r   r   typingr   r   r	   r
   r   r   r   r   r   r   ra   typing_extensionsr   neo4j_graphrag.exceptionsr   neo4j_graphrag.typesr   r   r   "neo4j_graphrag.utils.version_utilsr   r   r   r   neo4j_graphrag.utilsr   r   r   r   r   r   r   r0   r3   rL   r   rJ   r1   r/   <module>r      s    #   , ,    ' 7 V V  /  cNCL6 6<T
1 T
n
#	3 #r1   