
    $jx                     n    d Z ddlmZmZ ddlmZ ddlmZmZ  G d de          Z	 G d d	e
          Zd
S )z
Abstract interface for LLM providers.

This module defines the interface that all LLM providers must implement,
enabling support for multiple LLM backends (OpenAI, Anthropic, Gemini, Codex, etc.)
    )ABCabstractmethod)Any   )LLMToolCallResult
TokenUsagec                   >   e Zd ZdZ	 d/dedededededefd	Zed0d            Ze	 	 	 	 	 	 	 	 	 	 d1de	e
eef                  dedz  dedz  dedz  dededededededed
efd            Ze	 	 	 	 	 	 	 d2de	e
eef                  de	e
eef                  dedz  dedz  dedededed"ee
eef         z  d
efd#            Zd
efd$Z	 	 d3d'e	e
eef                  d(ed)ed
e
eef         fd*Zd+ed
e
eef         fd,Zd+ed
e	e
eef                  fd-Zed0d.            ZdS )4LLMInterfacez
    Abstract interface for LLM providers.

    All LLM provider implementations must inherit from this class and implement
    the required methods.
    lowproviderapi_keybase_urlmodelreasoning_effortkwargsc                 p    |                                 | _        || _        || _        || _        || _        dS )a  
        Initialize LLM provider.

        Args:
            provider: Provider name (e.g., "openai", "codex", "anthropic", "gemini").
            api_key: API key or authentication token.
            base_url: Base URL for the API.
            model: Model name.
            reasoning_effort: Reasoning effort level for supported providers.
            **kwargs: Additional provider-specific parameters.
        N)lowerr   r   r   r   r   )selfr   r   r   r   r   r   s          j/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/engine/llm_interface.py__init__zLLMInterface.__init__   s8    ( !(( 
 0    returnNc                 
   K   dS )z
        Verify that the LLM provider is configured correctly by making a simple test call.

        Raises:
            RuntimeError: If the connection test fails.
        N r   s    r   verify_connectionzLLMInterface.verify_connection0   s       	r   memory
         ?      N@Fmessagesresponse_formatmax_completion_tokenstemperaturescopemax_retriesinitial_backoffmax_backoffskip_validationstrict_schemareturn_usagec                 
   K   dS )a  
        Make an LLM API call with retry logic.

        Args:
            messages: List of message dicts with 'role' and 'content'.
            response_format: Optional Pydantic model for structured output.
            max_completion_tokens: Maximum tokens in response.
            temperature: Sampling temperature (0.0-2.0).
            scope: Scope identifier for tracking.
            max_retries: Maximum retry attempts.
            initial_backoff: Initial backoff time in seconds.
            max_backoff: Maximum backoff time in seconds.
            skip_validation: Return raw JSON without Pydantic validation.
            strict_schema: Use strict JSON schema enforcement (OpenAI only).
            return_usage: If True, return tuple (result, TokenUsage) instead of just result.

        Returns:
            If return_usage=False: Parsed response if response_format is provided, otherwise text content.
            If return_usage=True: Tuple of (result, TokenUsage) with token counts.

        Raises:
            OutputTooLongError: If output exceeds token limits.
            Exception: Re-raises API errors after retries exhausted.
        Nr   )r   r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   s               r   callzLLMInterface.call:   s      N 	r   tools         >@autotool_choicec
                 
   K   dS )a  
        Make an LLM API call with tool/function calling support.

        Args:
            messages: List of message dicts. Can include tool results with role='tool'.
            tools: List of tool definitions in OpenAI format.
            max_completion_tokens: Maximum tokens in response.
            temperature: Sampling temperature (0.0-2.0).
            scope: Scope identifier for tracking.
            max_retries: Maximum retry attempts.
            initial_backoff: Initial backoff time in seconds.
            max_backoff: Maximum backoff time in seconds.
            tool_choice: How to choose tools - "auto", "none", "required", or specific function.

        Returns:
            LLMToolCallResult with content and/or tool_calls.
        Nr   )
r   r!   r.   r#   r$   r%   r&   r'   r(   r2   s
             r   call_with_toolszLLMInterface.call_with_toolsc   s      < 	r   c                 
   K   dS )z
        Check if this provider supports batch API operations.

        Returns:
            True if provider supports submit_batch/get_batch_status/retrieve_batch_results
        Fr   r   s    r   supports_batch_apizLLMInterface.supports_batch_api   s       ur   /v1/chat/completions24hrequestsendpointcompletion_windowc                 4   K   t          d| j                   )a  
        Submit a batch of requests to the provider's batch API.

        Args:
            requests: List of request dicts in JSONL format (custom_id, method, url, body)
            endpoint: API endpoint for the batch (e.g., "/v1/chat/completions")
            completion_window: Completion window (e.g., "24h")

        Returns:
            Dict with batch metadata: {"batch_id": str, "status": str, ...}

        Raises:
            NotImplementedError: If provider doesn't support batch API
        &Batch API not supported for provider: NotImplementedErrorr   )r   r9   r:   r;   s       r   submit_batchzLLMInterface.submit_batch   s!      ( ""Z4="Z"Z[[[r   batch_idc                 4   K   t          d| j                   )aI  
        Get the status of a batch job.

        Args:
            batch_id: Batch identifier returned from submit_batch

        Returns:
            Dict with status info: {"batch_id": str, "status": str, "completed_at": str, ...}

        Raises:
            NotImplementedError: If provider doesn't support batch API
        r=   r>   r   rA   s     r   get_batch_statuszLLMInterface.get_batch_status   !       ""Z4="Z"Z[[[r   c                 4   K   t          d| j                   )a7  
        Retrieve completed batch results.

        Args:
            batch_id: Batch identifier returned from submit_batch

        Returns:
            List of result dicts (one per request, matched by custom_id)

        Raises:
            NotImplementedError: If provider doesn't support batch API
        r=   r>   rC   s     r   retrieve_batch_resultsz#LLMInterface.retrieve_batch_results   rE   r   c                 
   K   dS )z-Clean up resources (close connections, etc.).Nr   r   s    r   cleanupzLLMInterface.cleanup   s       	r   )r   )r   N)
NNNr   r   r   r    FFF)NNr.   r/   r   r0   r1   )r7   r8   )__name__
__module____qualname____doc__strr   r   r   r   listdictintfloatboolr-   r   r4   r6   r@   rD   rG   rI   r   r   r   r
   r
      s=         !&1 11 1 	1
 1 1 1 1 1 14    ^  '+,0$(!$! %#"& &tCH~&& t&  #Tz	&
 T\& & & & & & & & 
& & & ^&P 
 -1$(!$!,2 tCH~& DcN#  #Tz	
 T\     4S>) 
   ^>$     /!&	\ \tCH~&\ \ 	\
 
c3h\ \ \ \,\s \tCH~ \ \ \ \\S \T$sCx.=Q \ \ \ \    ^  r   r
   c                       e Zd ZdZdS )OutputTooLongErrora	  
    Bridge exception raised when LLM output exceeds token limits.

    This wraps provider-specific errors (e.g., OpenAI's LengthFinishReasonError)
    to allow callers to handle output length issues without depending on
    provider-specific implementations.
    N)rJ   rK   rL   rM   r   r   r   rU   rU      s          	Dr   rU   N)rM   abcr   r   typingr   response_modelsr   r   r
   	ExceptionrU   r   r   r   <module>rZ      s     $ # # # # # # #       : : : : : : : :u u u u u3 u u up		 		 		 		 		 		 		 		 		 		r   