o
    i{                      @   s   d Z ddlZddlmZmZmZ ddlmZ ddlm	Z	m
Z
mZmZmZ ddlmZ ddlmZmZ ddlmZ G d	d
 d
eZdS )zBase AI service implementation.

Provides the foundation for all AI services in the Pipecat framework, including
model management, settings handling, and frame processing lifecycle methods.
    N)AnyAsyncGeneratorDict)logger)CancelFrameEndFrame
ErrorFrameFrame
StartFrame)MetricsData)FrameDirectionFrameProcessor)ServiceSettingsc                       s   e Zd ZdZd'dedB f fddZdd Zdefd	d
Zde	fddZ
defddZdedeeef fddZ		d(dededB defddZdd Zdedef fddZdeedB df fdd Zdefd!d"Zde	fd#d$Zdefd%d&Z  ZS ))	AIServicea'  Base class for all AI services.

    Provides common functionality for AI services including model management,
    settings handling, session properties, and frame processing lifecycle.
    Subclasses should implement specific AI functionality while leveraging
    this base infrastructure.
    Nsettingsc                    s<   t  jdi | |pt | _|   i | _d| _d| _dS )zInitialize the AI service.

        Args:
            settings: The runtime-updatable settings for the AI service.
            **kwargs: Additional arguments passed to the parent FrameProcessor.
        FN )super__init__r   	_settings_sync_model_name_to_metrics_session_properties_tracing_enabled_tracing_context)selfr   kwargs	__class__r   O/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/ai_service.pyr   '   s   
zAIService.__init__c                 C   s    |  t| j| jjp
dd dS )ak  Sync the current AI model name (in `self._settings.model`) for usage in metrics.

        We don't store model name here because there's already a single source
        of truth for it in `self._settings.model`. This method is just for
        syncing the model name to the metrics data.

        Args:
            model: The name of the AI model to use.
         )	processormodelN)set_core_metrics_datar   namer   r    )r   r   r   r   r   :   s   
z%AIService._sync_model_name_to_metricsframec                    s    | j   |j| _|j| _dS )a  Start the AI service.

        Called when the service should begin processing. Subclasses should
        override this method to perform service-specific initialization.

        Args:
            frame: The start frame containing initialization parameters.
        N)r   validate_completeenable_tracingr   tracing_contextr   r   r#   r   r   r   startH   s   
	zAIService.startc                       dS )zStop the AI service.

        Called when the service should stop processing. Subclasses should
        override this method to perform cleanup operations.

        Args:
            frame: The end frame.
        Nr   r'   r   r   r   stopU      	zAIService.stopc                    r)   )zCancel the AI service.

        Called when the service should cancel all operations. Subclasses should
        override this method to handle cancellation logic.

        Args:
            frame: The cancel frame.
        Nr   r'   r   r   r   cancel`   r+   zAIService.canceldeltareturnc                    s@   | j |}d|v r|   |rt| j dt|  |S )ag  Apply a settings delta and return the changed fields.

        The delta is applied to ``_settings`` and a dict mapping each changed
        field name to its **pre-update** value is returned.  The ``model``
        field is handled specially: when it changes, ``set_model_name`` is
        called.

        Concrete services should override this method (calling ``super()``)
        to react to specific changed fields (e.g. reconnect on voice change).

        Args:
            delta: A delta-mode settings object.

        Returns:
            Dict mapping changed field names to their previous values.
        r    z: updated settings fields: )r   apply_updater   r   infor"   set)r   r-   changedr   r   r   _update_settingsk   s   zAIService._update_settings   
param_namesettings_field
stacklevelc                 C   s   t | j d}|rd| d| d| d}n	d| d| d}t  td tj|t|d W d	   d	S 1 s=w   Y  d	S )
a  Warn that an ``__init__`` param has moved to ``Settings``.

        Emits a ``DeprecationWarning`` directing users to the canonical
        ``settings=ServiceClass.Settings(field=...)`` API.

        Args:
            param_name: Name of the deprecated ``__init__`` parameter.
            settings_field: The corresponding field on the ``Settings``
                dataclass, if different from *param_name*.  When ``None``
                the message omits the field hint.
            stacklevel: Stack depth for the warning.  Default ``3`` targets
                the caller's caller (i.e. user code that instantiated the
                service).
        z	.SettingszThe `z)` parameter is deprecated. Use `settings=(zB=...)` instead. If both are provided, `settings` takes precedence.zB(...)` instead. If both are provided, `settings` takes precedence.always)r7   N)type__name__warningscatch_warningssimplefilterwarnDeprecationWarning)r   r5   r6   r7   labelmsgr   r   r   "_warn_init_param_moved_to_settings   s    

"z,AIService._warn_init_param_moved_to_settingsc                 C   s2   |rd t|}t| j d| d dS dS )a;  Log a warning for settings changes that won't take effect at runtime.

        Convenience helper for ``_update_settings`` overrides.  Accepts any
        iterable of field names (a ``dict``, ``set``, ``dict_keys``, etc.).

        Args:
            unhandled: Field names that changed but are not applied.
        z, z: runtime update of [z] is not currently supportedN)joinsortedr   warningr"   )r   	unhandledfieldsr   r   r    _warn_unhandled_updated_settings   s   	z*AIService._warn_unhandled_updated_settings	directionc                    st   t  ||I dH  t|tr| |I dH  dS t|tr)| |I dH  dS t|tr8| |I dH  dS dS )a"  Process frames and handle service lifecycle.

        Automatically handles StartFrame, EndFrame, and CancelFrame by calling
        the appropriate lifecycle methods.

        Args:
            frame: The frame to process.
            direction: The direction of frame processing.
        N)	r   process_frame
isinstancer
   _startr   _stopr   _cancel)r   r#   rJ   r   r   r   rK      s   



zAIService.process_frame	generatorc                    sJ   |2 z3 dH W }|r!t |tr| |I dH  q| |I dH  q6 dS )a  Process frames from an async generator.

        Takes an async generator that yields frames and processes each one,
        handling error frames specially by pushing them as errors.

        Args:
            generator: An async generator that yields Frame objects or None.
        N)rL   r   push_error_frame
push_frame)r   rP   fr   r   r   process_generator   s   	
zAIService.process_generatorc              
      Z   z|  |I d H  W d S  ty, } zt|  d| d|  W Y d }~d S d }~ww Nz: exception processing z: )r(   	Exceptionr   errorr   r#   er   r   r   rM         (zAIService._startc              
      rU   rV   )r*   rW   r   rX   rY   r   r   r   rN      r[   zAIService._stopc              
      rU   rV   )r,   rW   r   rX   rY   r   r   r   rO      r[   zAIService._cancel)N)Nr4   )r;   
__module____qualname____doc__r   r   r   r
   r(   r   r*   r   r,   r   strr   r3   intrC   rI   r	   r   rK   r   rT   rM   rN   rO   __classcell__r   r   r   r   r      s.    
%r   )r^   r<   typingr   r   r   logurur   pipecat.frames.framesr   r   r   r	   r
   pipecat.metrics.metricsr   "pipecat.processors.frame_processorr   r   pipecat.services.settingsr   r   r   r   r   r   <module>   s   