
    ~hR                     h   d dl Z d dl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 d dlmZmZ d dlmZmZmZ d dlmZ d	eez  d
edefdZdedefdZdedefdZdd	ededefdZdd	ededefdZd	edefdZdd	eez  ez  defdZ	 	 	 ddede dz  dede!dz  def
dZ" G d d      Z#ddgZ$y)     N)Path)	Generator)
AgentAudio
AgentImage	AgentText)MultiStepAgentPlanningStep)
ActionStepFinalAnswerStep)ChatMessageStreamDeltaMessageRoleagglomerate_stream_deltas)_is_package_availablestep_log	step_namereturnc                 0   d| d}| j                   5|d| j                   j                  dd| j                   j                  dz  }|| j                  j                  r-dt        t        | j                  j                        d       dndz  }d	| d
}|S )zHGet a footnote string for a step log with duration and token information**z | Input tokens: ,z | Output tokens: z | Duration:    s z/<span style="color: #bbbbc2; font-size: 12px;">z</span> )token_usageinput_tokensoutput_tokenstimingdurationroundfloat)r   r   step_footnotestep_footnote_contents       P/opt/mcp/mcp-sentiment/venv/lib/python3.12/site-packages/smolagents/gradio_ui.pyget_step_footnote_contentr#      s    2&M',X-A-A-N-Nq,QQcdldxdx  eG  eG  HI  dJ  K  	KU]UdUdUmUm}U51I1I+JA%N$OqQsuuM OP]^fi      model_outputc                     | sy| j                         } t        j                  dd|       } t        j                  dd|       } t        j                  dd|       } | j                         S )z
    Clean up model output by removing trailing tags and extra backticks.

    Args:
        model_output (`str`): Raw model output.

    Returns:
        `str`: Cleaned model output.
    r   z```\s*<end_code>z```z<end_code>\s*```z```\s*\n\s*<end_code>)stripresub)r%   s    r"   _clean_model_outputr*   '   s`     %%'L66-ulCL66-ulCL662E<HLr$   contentc                     | j                         } t        j                  dd|       } t        j                  dd|       } | j                         } | j                  d      sd|  d} | S )z
    Format code content as Python code block if it's not already formatted.

    Args:
        content (`str`): Code content to format.

    Returns:
        `str`: Code content formatted as a Python code block.
    z```.*?\nr   z\s*<end_code>\s*z	```pythonz
```python
z
```)r'   r(   r)   
startswith)r+   s    r"   _format_code_contentr.   ;   s`     mmoGff["g.Gff("g6GmmoGk*y.Nr$   skip_model_outputsc           	   #     K   ddl }d| j                   }|s*|j                  t        j                  d| dddi       |sHt        | dd	      r;t        | j                        }|j                  t        j                  |ddi       t        | d
g       r| j                  d   }|j                  dk(  }|j                  }t        |t              r%t        |j                  dt        |                  }nt        |      j                         }|rt!        |      }|j                  t        j                  |d|j                   dd      }	|	 t        | dd	      rx| j"                  j                         r^| j"                  j                         }
|
rBt%        j&                  dd	|
      }
|j                  t        j                  d|
 dddd       t        | dg       ri| j(                  D ]Z  }t+        |      j-                         }|j                  t        j                  |d|j/                  d      d    dddd       \ t        | dd      r:|j                  t        j                  t        | j0                        ddd       |j                  t        j                  t3        | |      ddi       |j                  t        j                  dddi       yw)a;  
    Process an [`ActionStep`] and yield appropriate Gradio ChatMessage objects.

    Args:
        step_log ([`ActionStep`]): ActionStep to process.
        skip_model_outputs (`bool`): Whether to skip model outputs.

    Yields:
        `gradio.ChatMessage`: Gradio ChatMessages representing the action step.
    r   NzStep r   statusdoneroler+   metadatar%   r   
tool_callspython_interpreteransweru   🛠️ Used tool )titler1   observationsz^Execution logs:\s*z```bash

u   📝 Execution Logsobservations_imageszimage/.path	mime_typeu   🖼️ Output Imageerroru
   💥 Error-----)gradiostep_numberChatMessager   	ASSISTANTgetattrr*   r%   r6   name	arguments
isinstancedictstrgetr'   r.   r:   r(   r)   r<   r   	to_stringsplitrB   r#   )r   r/   grrE   r%   first_tool_call	used_codeargsr+   parent_message_toollog_contentimage
path_images                r"   _process_action_steprY   P   s      (../0Knn+"7"72k]RTAUaikq`rnss '(NB"G*8+@+@Ann+"7"7YaciXjnkk xr*"--a0#((,@@	 ((dD!$((8SY78G$ioo'G *73G !nn&&-o.B.B-CD  - 
 "! x,1F1F1L1L1N++113&&!7[IK.. **#K=3#8FK !   x.311 	E#E*446J.. **!+F:CSCSTWCXY[C\B]:^_#9VL !  	 x$'nn&&HNN0CXdpvNw  
 	

 .."")(K@F#   
 ..k33WPXZ`Oa.
bbs   K+K-c              #   p  K   ddl }|sV|j                  t        j                  dddi       |j                  t        j                  | j                  ddi       |j                  t        j                  t        | d      ddi       |j                  t        j                  dddi       yw)	z
    Process a [`PlanningStep`] and yield appropriate gradio.ChatMessage objects.

    Args:
        step_log ([`PlanningStep`]): PlanningStep to process.

    Yields:
        `gradio.ChatMessage`: Gradio ChatMessages representing the planning step.
    r   Nz**Planning step**r1   r2   r3   zPlanning steprC   )rD   rF   r   rG   planr#   )r   r/   rQ   s      r"   _process_planning_stepr\      s      nn+"7"7AT`hjp_qnrrnn+"7"7ZbdjYknll
.."")(ODF#   
 ..k33WPXZ`Oa.
bbs   B4B6c              #   B  K   ddl }| j                  }t        |t              r9|j	                  t
        j                  d|j                          dddi       yt        |t              r8|j	                  t
        j                  |j                         dd	ddi       yt        |t              r8|j	                  t
        j                  |j                         d
d	ddi       y|j	                  t
        j                  dt        |       ddi       yw)a  
    Process a [`FinalAnswerStep`] and yield appropriate gradio.ChatMessage objects.

    Args:
        step_log ([`FinalAnswerStep`]): FinalAnswerStep to process.

    Yields:
        `gradio.ChatMessage`: Gradio ChatMessages representing the final answer.
    r   Nz**Final answer:**
r;   r1   r2   r3   z	image/pngr?   z	audio/wavz**Final answer:** )rD   outputrK   r   rF   r   rG   rO   r   r   rM   )r   rQ   final_answers      r"   _process_final_answer_stepr`      s     ??L,	*nn&&),*@*@*B)C2F'  
 	

 
L*	-nn&&)335KP'  
 	

 
L*	-nn&&)335KP'  
 	
 nn&&2DSEVDW0Xdlntcu  
 	
s   DDc              #   L  K   t        d      st        d      t        | t              rt	        | |      E d{    yt        | t
              rt        | |      E d{    yt        | t              rt        |       E d{    yt        dt        |              7 e7 B7  w)ac  Extract Gradio ChatMessage objects from agent steps with proper nesting.

    Args:
        step_log: The step log to display as gr.ChatMessage objects.
        skip_model_outputs: If True, skip the model outputs when creating the gr.ChatMessage objects:
            This is used for instance when streaming model outputs have already been displayed.
    rD   UPlease install 'gradio' extra to use the GradioUI: `pip install 'smolagents[gradio]'`NzUnsupported step type: )r   ModuleNotFoundErrorrK   r
   rY   r	   r\   r   r`   
ValueErrortype)r   r/   s     r"   pull_messages_from_steprf      s      !*!c
 	
 (J''2DEEE	Hl	+)(4FGGG	Ho	.-h77724>2BCDD 	FG7s3   6B$B$B$B #B$B"B$ B$"B$tasktask_imagesreset_agent_memoryadditional_argsc           	   #   t  K   t        d      st        d      g }| j                  ||d||      D ]  }t        |t        t
        z  t        z        r$t        |t        | dd            D ]  }|  g }Et        |t              sV|j                  |       t        |      j                         }|  yw)	zaRuns an agent with the given task and streams the messages from the agent as gradio ChatMessages.rD   rb   T)imagesstreamresetrj   stream_outputsF)r/   N)r   rc   runrK   r
   r	   r   rf   rH   r   appendr   render_as_markdown)	agentrg   rh   ri   rj   accumulated_eventseventmessagetexts	            r"   stream_to_gradiorx      s      !*!c
 	
 8:[5GYh    eZ,6HI2#*52BE#J 
  "$56%%e,,-?@SSUDJs   BB81B8c                   T    e Zd ZdZddededz  defdZd ZddZ	d	 Z
dd
efdZd Zy)GradioUIa  
    Gradio interface for interacting with a [`MultiStepAgent`].

    This class provides a web interface to interact with the agent in real-time, allowing users to submit prompts, upload files, and receive responses in a chat-like format.
    It  can reset the agent's memory at the start of each interaction if desired.
    It supports file uploads, which are saved to a specified folder.
    It uses the [`gradio.Chatbot`] component to display the conversation history.
    This class requires the `gradio` extra to be installed: `smolagents[gradio]`.

    Args:
        agent ([`MultiStepAgent`]): The agent to interact with.
        file_upload_folder (`str`, *optional*): The folder where uploaded files will be saved.
            If not provided, file uploads are disabled.
        reset_agent_memory (`bool`, *optional*, defaults to `False`): Whether to reset the agent's memory at the start of each interaction.
            If `True`, the agent will not remember previous interactions.

    Raises:
        ModuleNotFoundError: If the `gradio` extra is not installed.

    Example:
        ```python
        from smolagents import CodeAgent, GradioUI, InferenceClientModel

        model = InferenceClientModel(model_id="meta-llama/Meta-Llama-3.1-8B-Instruct")
        agent = CodeAgent(tools=[], model=model)
        gradio_ui = GradioUI(agent, file_upload_folder="uploads", reset_agent_memory=True)
        gradio_ui.launch()
        ```
    Nrs   file_upload_folderri   c                 L   t        d      st        d      || _        |t        |      nd | _        || _        t        |d      xs d| _        t        |dd       | _        | j                  9| j                  j                         s| j                  j                  dd       y y y )NrD   rb   rI   zAgent interfacedescriptionT)parentsexist_ok)r   rc   rs   r   r{   ri   rH   rI   r}   existsmkdir)selfrs   r{   ri   s       r"   __init__zGradioUI.__init__6  s    $X.%g  
>P>\$'9":bf"4E6*?.?	"5->"".**113''--dT-J 4 /r$   c           	   #     K   dd l }d|vr| j                  |d<   	 |j                  |j                  d|ddi             | t	        |d   || j
                        D ]  }t        ||j                        r$d|d   j                  d<   |j                  |       nt        |t              ru|j                  d	d
      j                  dd      }|d   j                  d   dk(  r||d   _
        n3|j                  |j                  t        j                  |ddi             |  | y # t        $ r&}| |j                  dt        |             d }~ww xY ww)Nr   rs   userr1   r2   r3   )rg   ri   r>   <z\<>z\>pendingzError in interaction: )rD   rs   rq   rF   rx   ri   rK   r5   rM   replacer+   r   rG   	ExceptionError)r   promptmessagessession_staterQ   msges          r"   interact_with_agentzGradioUI.interact_with_agentD  sU     -'%)ZZM'"	>OOBNNRZ\bQcNdeN'g&VH_H_  c2>>26<HRL))(3OOC(S)++c5199#uEC|,,X6)C/2, NN0E0Es^fhq]rNs   N 	>N((3CF8<==	>s)   EDD, +E,	E5!EEEc                 p   ddl }||j                  dd      |fS |g d}t        j                  j	                  |j
                        d   j                         }||vr|j                  dd	      |fS t        j                  j                  |j
                        }t        j                  d
d|      }t        j                  j                  | j                  t        j                  j                  |            }t        j                  |j
                  |       |j                  d| d	      ||gz   fS )a  
        Upload a file and add it to the list of uploaded files in the session state.

        The file is saved to the `self.file_upload_folder` folder.
        If the file type is not allowed, it returns a message indicating the disallowed file type.

        Args:
            file (`gradio.File`): The uploaded file.
            file_uploads_log (`list`): A list to log uploaded files.
            allowed_file_types (`list`, *optional*): List of allowed file extensions. Defaults to [".pdf", ".docx", ".txt"].
        r   NzNo file uploadedT)valuevisible)z.pdfz.docxz.txt   zFile type disallowed)r   z[^\w\-.]_zFile uploaded: )rD   Textboxosr@   splitextrI   lowerbasenamer(   r)   joinr{   shutilcopy)	r   filefile_uploads_logallowed_file_typesrQ   file_extoriginal_namesanitized_name	file_paths	            r"   upload_filezGradioUI.upload_filed  s    	<::$6:EGWWW%!:77##DII.q1779--::4d:CEUUU ((3m

 GGLL!8!8"'':J:J>:Z[	DIIy)zzOI;7zFHX\e[fHfffr$   c                 `    dd l }|t        |      dkD  rd| ndz   d|j                  d      fS )Nr   zI
You have been provided with these files, which might be helpful or not: r   Finteractive)rD   lenButton)r   
text_inputr   rQ   s       r"   log_user_messagezGradioUI.log_user_message  sN      '(1, ]]m\no	 II%I(	
 		
r$   sharec                 J     | j                         j                  dd|d| y)z
        Launch the Gradio app with the agent interface.

        Args:
            share (`bool`, defaults to `True`): Whether to share the app publicly.
            **kwargs: Additional keyword arguments to pass to the Gradio launch method.
        T)debugr   N )
create_applaunch)r   r   kwargss      r"   r   zGradioUI.launch  s%     	!  Ct5CFCr$   c                   
 dd l 

j                  dd      5 }
j                  i       }
j                  g       }
j                  g       }
j                         5  
j	                  d| j
                  j                  dd      j                          d| j                  rd	| j                   nd
z          
j                         5  
j	                  dd       
j                  dddd      }
j                  dd      }d d d        | j                  G
j                  d      }
j                  ddd      }|j                  | j                  ||g||g       
j!                  d       d d d        
j#                  dddddddddd d ddd!d"ddd#d$ddg%      }	j%                  | j&                  ||g||g      j)                  | j*                  ||	|g|	g      j)                  
fd&d ||g       |j-                  | j&                  ||g|||g      j)                  | j*                  ||	|g|	g      j)                  
fd'd ||g       d d d        |S # 1 sw Y   YxY w# 1 sw Y   xY w# 1 sw Y   S xY w)(Nr   oceanT)themefill_heightz# r    zw
> This web ui allows you to interact with a `smolagents` agent that can use tools and execute steps to complete tasks.z

**Agent description:**
r   z**Your request**)	container   zChat MessageFz@Enter your prompt here and press Shift+Enter or press the button)lineslabelr   placeholderSubmitprimary)variantzUpload a file)r   zUpload Status)r   r   r   z<br><br><h4><center>Powered by <a target='_blank' href='https://github.com/huggingface/smolagents'><b>smolagents</b></a></center></h4>Agentr   )Nzhhttps://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/mascot_smol.pngr   z$$)leftrightdisplay$z\[z\]z\(z\))r   re   avatar_images
resizeablescalelatex_delimitersc                  N     j                  dd       j                  d      fS NTz:Enter your prompt here and press Shift+Enter or the button)r   r   r   r   r   rQ   s   r"   <lambda>z%GradioUI.create_app.<locals>.<lambda>  1    JJ$(6r   II$I/	 r$   c                  N     j                  dd       j                  d      fS r   r   r   s   r"   r   z%GradioUI.create_app.<locals>.<lambda>  r   r$   )rD   BlocksStateSidebarMarkdownrI   r   
capitalizer}   Groupr   r   r{   Filechanger   HTMLChatbotsubmitr   thenr   click)r   demor   stored_messagesr   r   
submit_btnr   upload_statuschatbotrQ   s             @r"   r   zGradioUI.create_app  s   YYW$Y7 T	4HHRLM hhrlO!xx| **34??AB OOLPL\L\5d6F6F5GHbdf XXZ HKK 2dKC!#,"'$f	 ", "J "$8Y!GJH **6"$'''"@K$&JJ_RWafJ$gM&&(($&67&(89  ]7@ jj  "UtD!DUC"UtD"UuE	" ! G$ %%-. *j9 d4++ow-VY`Xabcgcg Z(	d %%-. *j9 d4++ow-VY`Xabcgcg Z(	dWT	l SH H T	l s?   AI5A,I)	<IA,I)1C!I5I&!I))I2	.I55I?)NF)N)T)__name__
__module____qualname____doc__r   rM   boolr   r   r   r   r   r   r   r$   r"   rz   rz     sP    <Kn K#* Kim K>@"gH
DD DYr$   rz   rx   )F)NFN)%r   r(   r   pathlibr   typingr   smolagents.agent_typesr   r   r   smolagents.agentsr   r	   smolagents.memoryr
   r   smolagents.modelsr   r   r   smolagents.utilsr   rM   r#   r*   r.   r   rY   r\   r`   rf   listrL   rx   rz   __all__r   r$   r"   <module>r      sJ    
 	    D D : 9 \ \ 2!
\(A !c !VY ! c  c  (# # *Sc: Sc4 ScT] Sclc\ ct cXa c."
 "
Y "
JEj<&?/&Q Egk E2  $$#'
  	
 D[ >b bJ z
*r$   