
    WiN,                       d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	m
Z
mZ d dlZd dlZ e	d      Z G d de      Z G d	 d
e
      Z G d de
      Z G d de
      Z G d de
      Zeeed   f   Zeeeeef   Z G d d      Zy)    )annotations)Enum)defaultdict)AnyLiteralTypeVarProtocolUnionNTc                       e Zd ZdZdZdZdZdZy)HookNamecompletion:kwargscompletion:responsecompletion:errorcompletion:last_attemptparse:errorN)__name__
__module____qualname__COMPLETION_KWARGSCOMPLETION_RESPONSECOMPLETION_ERRORCOMPLETION_LAST_ATTEMPTPARSE_ERROR     a/home/sietch6/trending-topics-pipeline/venv/lib/python3.12/site-packages/instructor/core/hooks.pyr   r      s    +/)7Kr   r   c                      e Zd ZdZddZy)CompletionKwargsHandlerz(Protocol for completion kwargs handlers.c                     y Nr   selfargskwargss      r   __call__z CompletionKwargsHandler.__call__       r   Nr$   r   r%   r   returnNoner   r   r   __doc__r&   r   r   r   r   r      s    2>r   r   c                      e Zd ZdZddZy)CompletionResponseHandlerz*Protocol for completion response handlers.c                     y r!   r   r#   responses     r   r&   z"CompletionResponseHandler.__call__   r'   r   Nr1   r   r)   r*   r+   r   r   r   r.   r.      s    42r   r.   c                      e Zd ZdZddZy)CompletionErrorHandlerz8Protocol for completion error and last attempt handlers.c                     y r!   r   r#   errors     r   r&   zCompletionErrorHandler.__call__$   r'   r   Nr7   	Exceptionr)   r*   r+   r   r   r   r4   r4   !   s    B5r   r4   c                      e Zd ZdZddZy)ParseErrorHandlerz"Protocol for parse error handlers.c                     y r!   r   r6   s     r   r&   zParseErrorHandler.__call__*   r'   r   Nr8   r+   r   r   r   r;   r;   '   s    ,5r   r;   )r   r   r   r   r   c                      e Zd ZdZddZ	 	 	 	 	 	 ddZddZddZddZddZ	ddZ
dd	Zdd
Z	 	 	 	 	 	 ddZ	 d	 	 	 ddZddZddZedd       ZddZy)Hooksz
    Hooks class for handling and emitting events related to completion processes.

    This class provides a mechanism to register event handlers and emit events
    for various stages of the completion process.
    c                ,    t        t              | _        y)zInitialize the hooks container.N)r   list	_handlers)r#   s    r   __init__zHooks.__init__J   s    CNtCTr   c                b    | j                  |      }| j                  |   j                  |       y)a  
        Register an event handler for a specific event.

        This method allows you to attach a handler function to a specific event.
        When the event is emitted, all registered handlers for that event will be called.

        Args:
            hook_name: The event to listen for. This can be either a HookName enum
                       value or a string representation of the event name.
            handler: The function to be called when the event is emitted.

        Raises:
            ValueError: If the hook_name is not a valid HookName enum or string representation.

        Example:
            >>> def on_completion_kwargs(*args: Any, **kwargs: Any) -> None:
            ...     print(f"Completion kwargs: {args}, {kwargs}")
            >>> hooks = Hooks()
            >>> hooks.on(HookName.COMPLETION_KWARGS, on_completion_kwargs)
            >>> hooks.emit_completion_arguments(model="gpt-3.5-turbo", temperature=0.7)
            Completion kwargs: (), {'model': 'gpt-3.5-turbo', 'temperature': 0.7}
        N)get_hook_namerA   appendr#   	hook_namehandlers      r   onzHooks.onN   s+    6 &&y1	y!((1r   c                ~    t        |t              r	 t        |      S |S # t        $ r}t        d|       |d}~ww xY w)aM  
        Convert a string hook name to its corresponding enum value.

        Args:
            hook_name: Either a HookName enum value or string representation.

        Returns:
            The corresponding HookName enum value.

        Raises:
            ValueError: If the string doesn't match any HookName enum value.
        zInvalid hook name: N)
isinstancestrr   
ValueError)r#   rG   errs      r   rD   zHooks.get_hook_namel   sP     i%M	**   M #6yk!BCLMs   
 	<7<c                    | j                   |   D ]  }	  ||i |  y# t        $ r> t        j                         }t	        j
                  d|j                   d| d       Y Uw xY w)z
        Generic method to emit events for any hook type.

        Args:
            hook_name: The hook to emit
            *args: Positional arguments to pass to handlers
            **kwargs: Keyword arguments to pass to handlers
        z	Error in z
 handler:
   )
stacklevelN)rA   r9   	traceback
format_excwarningswarnvalue)r#   rG   r$   r%   rH   error_tracebacks         r   emitz
Hooks.emit   sr     ~~i0 	G((	  "+"6"6"8	0O;LM s   AA&%A&c                L     | j                   t        j                  g|i | y)z
        Emit a completion arguments event.

        Args:
            *args: Positional arguments to pass to handlers
            **kwargs: Keyword arguments to pass to handlers
        N)rX   r   r   r"   s      r   emit_completion_argumentszHooks.emit_completion_arguments   s"     			(,,>t>v>r   c                D    | j                  t        j                  |       y)z
        Emit a completion response event.

        Args:
            response: The completion response to pass to handlers
        N)rX   r   r   r0   s     r   emit_completion_responsezHooks.emit_completion_response   s     			(..9r   c                D    | j                  t        j                  |       y)zt
        Emit a completion error event.

        Args:
            error: The exception to pass to handlers
        N)rX   r   r   r6   s     r   emit_completion_errorzHooks.emit_completion_error   s     			(++U3r   c                D    | j                  t        j                  |       y)z{
        Emit a completion last attempt event.

        Args:
            error: The exception to pass to handlers
        N)rX   r   r   r6   s     r   emit_completion_last_attemptz"Hooks.emit_completion_last_attempt   s     			(22E:r   c                D    | j                  t        j                  |       y)zo
        Emit a parse error event.

        Args:
            error: The exception to pass to handlers
        N)rX   r   r   r6   s     r   emit_parse_errorzHooks.emit_parse_error   s     			(&&.r   c                    | j                  |      }|| j                  v rN|| j                  |   v r<| j                  |   j                  |       | j                  |   s| j                  |= yyyy)z
        Remove a specific handler from an event.

        Args:
            hook_name: The name of the hook.
            handler: The handler to remove.
        N)rD   rA   removerF   s      r   offz	Hooks.off   so     &&y1	&$..33y)009~~i0y1 1 4 'r   Nc                    |.| j                  |      }| j                  j                  |d       y| j                  j                          y)z
        Clear handlers for a specific event or all events.

        Args:
            hook_name: The name of the event to clear handlers for.
                      If None, all handlers are cleared.
        N)rD   rA   popclear)r#   rG   s     r   rh   zHooks.clear   s>      **95INNy$/NN  "r   c                ~   t        |t              st        S t               }| j                  j	                         D ]1  \  }}|j                  |   j                  |j                                3 |j                  j	                         D ]1  \  }}|j                  |   j                  |j                                3 |S )aO  
        Combine two Hooks instances into a new one.

        This creates a new Hooks instance that contains all handlers from both
        the current instance and the other instance. Handlers are combined by
        appending the other's handlers after the current instance's handlers.

        Args:
            other: Another Hooks instance to combine with this one.

        Returns:
            A new Hooks instance containing all handlers from both instances.

        Example:
            >>> hooks1 = Hooks()
            >>> hooks2 = Hooks()
            >>> hooks1.on("completion:kwargs", lambda **kw: print("Hook 1"))
            >>> hooks2.on("completion:kwargs", lambda **kw: print("Hook 2"))
            >>> combined = hooks1 + hooks2
            >>> combined.emit_completion_arguments()  # Prints both "Hook 1" and "Hook 2"
        rK   r>   NotImplementedrA   itemsextendcopy)r#   othercombinedrG   handlerss        r   __add__zHooks.__add__   s    , %'!!7 $(>>#7#7#9 	BIxy)00A	B $)??#8#8#: 	BIxy)00A	B r   c                    t        |t              st        S |j                  j	                         D ]1  \  }}| j                  |   j                  |j                                3 | S )a  
        Add another Hooks instance to this one in-place.

        This modifies the current instance by adding all handlers from the other
        instance. The other instance's handlers are appended after the current
        instance's handlers for each event type.

        Args:
            other: Another Hooks instance to add to this one.

        Returns:
            This Hooks instance (for method chaining).

        Example:
            >>> hooks1 = Hooks()
            >>> hooks2 = Hooks()
            >>> hooks1.on("completion:kwargs", lambda **kw: print("Hook 1"))
            >>> hooks2.on("completion:kwargs", lambda **kw: print("Hook 2"))
            >>> hooks1 += hooks2
            >>> hooks1.emit_completion_arguments()  # Prints both "Hook 1" and "Hook 2"
        rj   )r#   ro   rG   rq   s       r   __iadd__zHooks.__iadd__
  s[    , %'!! $)??#8#8#: 	>IxNN9%,,X]]_=	> r   c                r     |        }|D ]*  }t        ||       st        dt        |             ||z  }, |S )a  
        Combine multiple Hooks instances into a new one.

        This class method creates a new Hooks instance that contains all handlers
        from all provided instances. Handlers are combined in the order of the
        provided instances.

        Args:
            *hooks_instances: Variable number of Hooks instances to combine.

        Returns:
            A new Hooks instance containing all handlers from all instances.

        Example:
            >>> hooks1 = Hooks()
            >>> hooks2 = Hooks()
            >>> hooks3 = Hooks()
            >>> hooks1.on("completion:kwargs", lambda **kw: print("Hook 1"))
            >>> hooks2.on("completion:kwargs", lambda **kw: print("Hook 2"))
            >>> hooks3.on("completion:kwargs", lambda **kw: print("Hook 3"))
            >>> combined = Hooks.combine(hooks1, hooks2, hooks3)
            >>> combined.emit_completion_arguments()  # Prints all three hooks
        zExpected Hooks instance, got )rK   	TypeErrortype)clshooks_instancesrp   hooks_instances       r   combinezHooks.combine)  sN    2 5- 	'Nnc2"?^@T?U VWW&H	'
 r   c                    t               }| j                  j                         D ]1  \  }}|j                  |   j                  |j	                                3 |S )av  
        Create a deep copy of this Hooks instance.

        Returns:
            A new Hooks instance with all the same handlers.

        Example:
            >>> original = Hooks()
            >>> original.on("completion:kwargs", lambda **kw: print("Hook"))
            >>> copy = original.copy()
            >>> copy.emit_completion_arguments()  # Prints "Hook"
        )r>   rA   rl   rm   rn   )r#   	new_hooksrG   rq   s       r   rn   z
Hooks.copyK  sS     G	#'>>#7#7#9 	CIx	*11(--/B	Cr   )r)   r*   )rG   HookNameTyperH   HandlerTyper)   r*   )rG   r~   r)   r   )rG   r   r$   r   r%   r   r)   r*   r(   r2   r8   r!   )rG   zHookNameType | Noner)   r*   )ro   r>   r)   r>   )ry   r>   r)   r>   )r)   r>   )r   r   r   r,   rB   rI   rD   rX   rZ   r\   r^   r`   rb   re   rh   rr   rt   classmethodr{   rn   r   r   r   r>   r>   B   s    U22 2 
	2<(&?:4;/22 2 
	2* *.#&# 
#"#J>  Br   r>   )
__future__r   enumr   collectionsr   typingr   r   r   r	   r
   rR   rT   r   r   r   r.   r4   r;   r~   r   r>   r   r   r   <module>r      s    "  # 9 9  CL t  ?h ?3 36X 66 6 		 Y Yr   