Ë
    tPêjŠ  ã                   ó`  — U d Z ddlZddlZddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZmZ erddlmZ  G d„ de
«      Z G d„ de
«      Z G d„ de
«      Z  G d„ de«      Z! e!«       Z"e	e#d<   ddl$Z$e$jJ                  jM                  e"«       y)a  
Skills Injection Hook for LiteLLM Proxy

Main hook that orchestrates skill processing:
- Fetches skills from LiteLLM DB
- Injects SKILL.md content into system prompt
- Adds litellm_code_execution tool for automatic code execution
- Handles agentic loop internally when litellm_code_execution is called

For non-Anthropic models (e.g., Bedrock, OpenAI, etc.):
- Skills are converted to OpenAI-style tools
- Skill file content (SKILL.md) is extracted and injected into the system prompt
- litellm_code_execution tool is added - when model calls it, LiteLLM handles
  execution automatically and returns final response with file_ids

Usage:
    # Simple - LiteLLM handles everything automatically via proxy
    # The container parameter triggers the SkillsInjectionHook
    response = await litellm.acompletion(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Create a bouncing ball GIF"}],
        container={"skills": [{"skill_id": "litellm_skill_abc123"}]},
    )
    # Response includes file_ids for generated files
é    N)ÚMappingÚSequence)ÚTYPE_CHECKINGÚAnyÚFinalÚProtocol)Úverbose_proxy_logger)Ú	DualCache)ÚCustomLogger)ÚLITELLM_SKILL_ID_PREFIX)ÚSkillPromptInjectionHandler)ÚLiteLLM_SkillsTableÚUserAPIKeyAuth)Ú	CallTypesÚCallTypesLiteralÚLLMResponseTypes©ÚSkillsSandboxExecutorc                   ó8   — e Zd Zedefd„«       Zedefd„«       Zy)Ú_ToolCallFunctionÚreturnc                  ó   — y ©N© ©Úselfs    úl/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/hooks/litellm_skills/main.pyÚnamez_ToolCallFunction.name/   s   € Øó    c                  ó   — y r   r   r   s    r   Ú	argumentsz_ToolCallFunction.arguments2   s   € Ø #r   N)Ú__name__Ú
__module__Ú__qualname__ÚpropertyÚstrr   r!   r   r   r   r   r   .   s(   „ ØØ�cÒó ØàØ#˜3Ò#ó Ù#r   r   c                   ó8   — e Zd Zedefd„«       Zedefd„«       Zy)Ú_ChatToolCallr   c                  ó   — y r   r   r   s    r   Úidz_ChatToolCall.id7   s   € Ør   c                  ó   — y r   r   r   s    r   Úfunctionz_ChatToolCall.function:   s   € Ø-0r   N)r"   r#   r$   r%   r&   r*   r   r,   r   r   r   r(   r(   6   s)   „ ØØ�CÒó ØàØ0Ð+Ò0ó Ù0r   r(   c                   óJ   — e Zd Zededz  fd„«       Zedee   dz  fd„«       Zy)Ú_ChatMessager   Nc                  ó   — y r   r   r   s    r   Úcontentz_ChatMessage.content?   s   € Ø%(r   c                  ó   — y r   r   r   s    r   Ú
tool_callsz_ChatMessage.tool_callsB   s   € Ø<?r   )	r"   r#   r$   r%   r&   r0   r   r(   r2   r   r   r   r.   r.   >   s6   „ ØØ(˜˜t™Ò(ó Ø(àØ?˜H ]Ñ3°dÑ:Ò?ó Ù?r   r.   c                   ó  ‡ — e Zd ZdZˆ fd„Zdedededede	e
z  ez  dz  f
d	„Z	 d$ded
ee   dedefd„Zded
ee   defd„Zde
dededz  fd„Zde
defd„Zdedededz  dedz  fd„Zdedeee
ef      fd„Zdededee
ef   dedz  fd„Zde
dee
ef   dddeee
ef      de
f
d„Zde
dee
e
f   dee
ef   dddeee
ef      de
fd„Zdededee
ef   defd „Zd!edee
ef   dddeee
ef      de
f
d"„Z dedeee
ef      defd#„Z!ˆ xZ"S )%ÚSkillsInjectionHooka¾  
    Pre/Post-call hook that processes skills from container.skills parameter.

    Pre-call (async_pre_call_hook):
    - Skills with 'litellm_skill_' prefix are fetched from LiteLLM DB
    - For Anthropic models: native skills pass through, LiteLLM skills converted to tools
    - For non-Anthropic models: LiteLLM skills are converted to tools + execute_code tool

    Post-call (async_post_call_success_deployment_hook):
    - If response has litellm_code_execution tool call, automatically execute code
    - Continue conversation loop until model gives final response
    - Return response with generated files inline

    This hook is called automatically by litellm during completion calls.
    c                 ó¼   •— ddl m}m} || _        t	        «       | _        |j                  d|«      | _        |j                  d|«      | _        t        ‰| �(  di |¤Ž y )Nr   )ÚDEFAULT_MAX_ITERATIONSÚDEFAULT_SANDBOX_TIMEOUTÚmax_iterationsÚsandbox_timeoutr   )Ú+litellm.llms.litellm_proxy.skills.constantsr6   r7   Úoptional_paramsr   Úprompt_handlerÚgetr8   r9   ÚsuperÚ__init__)r   Úkwargsr6   r7   Ú	__class__s       €r   r?   zSkillsInjectionHook.__init__W   sW   ø€ ÷	
ð
  &ˆÔÜ9Ó;ˆÔØ$Ÿj™jÐ)9Ð;QÓRˆÔØ%Ÿz™zÐ*;Ð=TÓUˆÔÜ‰ÑÑ"˜6Ó"r   Úuser_api_key_dictÚcacheÚdataÚ	call_typer   Nc              ƒ   ór  K  — |dvr|S |j                  d«      }|rt        |t        «      s|S |j                  d«      }|rt        |t        «      s|S t	        j
                  dt        |«      «       g }g }|D ]‘  }	t        |	t        «      sŒ|	j                  dd«      }
|
j                  t        «      rF| j                  |
|¬«      ƒ d{  –—† }|r|j                  |«       Œjt	        j                  d	|
«       Œ�|j                  |	«       Œ“ |d
k(  }t        |«      dkD  r| j                  |||¬«      }|S 7 Œk­w)a‹  
        Process skills from container.skills before the LLM call.

        1. Check if container.skills exists in request
        2. Separate skills by prefix (litellm_skill_ vs native)
        3. Fetch LiteLLM skills from database
        4. For Anthropic: keep native skills in container
        5. For non-Anthropic: convert LiteLLM skills to tools, inject content, add execute_code
        )Ú
completionÚacompletionÚanthropic_messagesÚ	containerÚskillsz)SkillsInjectionHook: Processing %s skillsÚskill_idÚ ©rB   Nz7SkillsInjectionHook: Skill '%s' not found in LiteLLM DBrI   r   )rD   Úlitellm_skillsÚuse_anthropic_format)r=   Ú
isinstanceÚdictÚlistr	   ÚdebugÚlenÚ
startswithr   Ú_fetch_skill_from_dbÚappendÚwarningÚ_process_for_messages_api)r   rB   rC   rD   rE   rJ   rK   rO   Úanthropic_skillsÚskillrL   Údb_skillrP   s                r   Úasync_pre_call_hookz'SkillsInjectionHook.async_pre_call_hookc   sN  è ø€ ð" ÐOÑOØˆKàŸ8™8 KÓ0ˆ	Ù¤
¨9´dÔ ;ØˆKà!Ÿ™ hÓ/ˆÙœZ¨´Ô5ØˆKä×"Ñ"Ð#NÔPSÐTZÓP[Ô\à;=ˆØ;=Ðð ò 	/ˆEÜ˜e¤TÔ*Øà—y‘y ¨RÓ0ˆHØ×"Ñ"Ô#:Ô;à!%×!:Ñ!:ØØ&7ð ";ó "÷ �ñ Ø"×)Ñ)¨(Õ3ä(×0Ñ0Ð1jÐltÕuð !×'Ñ'¨Õ.ð#	/ð* '0Ð3GÑ&GÐäˆ~Ó Ò"Ø×1Ñ1ØØ-Ø%9ð 2ó ˆDð ˆð/ús   ‚CD7Ã	D5Ã
A,D7rO   rP   c                 ó  — ddl m} |j                  dg «      }g }i }g }|D ]±  }	|j                  | j                  j                  |	«      «       | j                  j                  |	«      }
|
r|j                  |
«       | j                  j                  |	«      }|sŒy|||	j                  <   |D ]%  }|j                  d«      sŒ|j                  |«       Œ' Œ³ |r||d<   |r| j                  j                  |||¬«      }|rE |«       }|j                  dg «      |gz   |d<   |j                  di «      |d<   ||d   d<   d|d   d	<   |j                  d
d«       t        j                  dt        |«      t        |«      t        |«      «       |S )aa  
        Process skills for messages API (Anthropic format tools).

        - Converts skills to Anthropic-style tools (name, description, input_schema)
        - Extracts and injects SKILL.md content into system prompt
        - Adds litellm_code_execution tool for code execution
        - Stores skill files in metadata for sandbox execution
        r   )Ú)get_litellm_code_execution_tool_anthropicÚtoolsú.py)rP   Úlitellm_metadataÚ_skill_filesTÚ_litellm_code_execution_enabledrJ   Nz™SkillsInjectionHook: Messages API - converted %s skills to Anthropic tools, injected %s skill contents, added litellm_code_execution tool with %s modules)Ú0litellm.llms.litellm_proxy.skills.code_executionr`   r=   rX   r<   Úconvert_skill_to_anthropic_toolÚextract_skill_contentÚextract_all_filesrL   ÚendswithÚ inject_skill_content_to_messagesÚpopr	   rT   rU   )r   rD   rO   rP   r`   ra   Úskill_contentsÚall_skill_filesÚall_module_pathsr\   r0   Úskill_filesÚpathÚcode_exec_tools                 r   rZ   z-SkillsInjectionHook._process_for_messages_api¥   s®  € õ	
ð —x‘x ¨Ó,ˆØ+-ˆØ>@ˆØ-/Ðà#ò 	6ˆEà�L‰L˜×,Ñ,×LÑLÈUÓSÔTð ×)Ñ)×?Ñ?ÀÓFˆGÙØ×%Ñ% gÔ.ð ×-Ñ-×?Ñ?ÀÓFˆKÚØ2=� §¡Ñ/Ø'ò 6�DØ—}‘} UÕ+Ø(×/Ñ/°Õ5ñ6ð	6ñ" Ø!ˆD�‰Mñ Ø×&Ñ&×GÑGØ�nÐ;Oð Hó ˆDñ
 Ù$MÓ$OˆNØ ŸH™H W¨bÓ1°^Ð4DÑDˆD�‰Mð (,§x¡xÐ0BÀBÓ'GˆDÐ#Ñ$Ø7FˆDÐ#Ñ$ ^Ñ4ØJNˆDÐ#Ñ$Ð%FÑGð 	�‰�˜dÔ#ä×"Ñ"ð hÜ�ÓÜ�ÓÜÐ Ó!ô		
ð ˆr   c                 ó  — |j                  dg «      }g }i }g }|D ]±  }|j                  | j                  j                  |«      «       | j                  j	                  |«      }|r|j                  |«       | j                  j                  |«      }	|	sŒy|	||j                  <   |	D ]%  }
|
j                  d«      sŒ|j                  |
«       Œ' Œ³ |r||d<   |r| j                  j                  ||«      }|rIddl	m
} |j                  dg «       |«       gz   |d<   |j                  di «      |d<   ||d   d<   d|d   d<   |j                  d	d
«       t        j                  dt        |«      t        |«      t        |«      «       |S )a$  
        Process skills for non-Anthropic models (OpenAI format tools).

        - Converts skills to OpenAI-style tools
        - Extracts and injects SKILL.md content
        - Adds execute_code tool for code execution
        - Stores skill files in metadata for sandbox execution
        ra   rb   r   )Úget_litellm_code_execution_toolrc   rd   Tre   rJ   NzŒSkillsInjectionHook: Non-Anthropic model - converted %s skills to tools, injected %s skill contents, added execute_code tool with %s modules)r=   rX   r<   Úconvert_skill_to_toolrh   ri   rL   rj   rk   rf   rt   rl   r	   rT   rU   )r   rD   rO   ra   rm   rn   ro   r\   r0   rp   rq   rt   s               r   Ú_process_non_anthropic_modelz0SkillsInjectionHook._process_non_anthropic_modelí   s   € ð —x‘x ¨Ó,ˆØ+-ˆØ>@ˆØ-/Ðà#ò 	6ˆEà�L‰L˜×,Ñ,×BÑBÀ5ÓIÔJð ×)Ñ)×?Ñ?ÀÓFˆGÙØ×%Ñ% gÔ.ð ×-Ñ-×?Ñ?ÀÓFˆKÚØ2=� §¡Ñ/à'ò 6�DØ—}‘} UÕ+Ø(×/Ñ/°Õ5ñ6ð	6ñ$ Ø!ˆD�‰Mñ Ø×&Ñ&×GÑGÈÈnÓ]ˆDñ õð !ŸH™H W¨bÓ1Ñ5TÓ5VÐ4WÑWˆD�‰Mð (,§x¡xÐ0BÀBÓ'GˆDÐ#Ñ$Ø7FˆDÐ#Ñ$ ^Ñ4ØJNˆDÐ#Ñ$Ð%FÑGð 	�‰�˜dÔ#ä×"Ñ"ð [Ü�ÓÜ�ÓÜÐ Ó!ô		
ð ˆr   rL   c              ƒ   ó¬   K  — 	 ddl m} |j                  ||¬«      ƒ d{  –—† S 7 Œ# t        $ r!}t	        j
                  d||«       Y d}~yd}~ww xY w­w)zÛ
        Fetch a skill from the LiteLLM database.

        Args:
            skill_id: The skill ID (including the 'litellm_skill_' prefix)

        Returns:
            LiteLLM_SkillsTable or None if not found
        r   )ÚLiteLLMSkillsHandlerrN   Nz0SkillsInjectionHook: Error fetching skill %s: %s)Ú)litellm.llms.litellm_proxy.skills.handlerrx   Úfetch_skill_from_dbÚ	Exceptionr	   rY   )r   rL   rB   rx   Úes        r   rW   z(SkillsInjectionHook._fetch_skill_from_db2  s`   è ø€ ð		ÝVà-×AÑAØØ"3ð Bó ÷ ð ð ùô ò 	Ü ×(Ñ(Ð)[Ð]eÐghÔiÜûð	üs6   ‚A„'  %¡' ¤A¥' §	A°AÁAÁAÁAÚmodelc                 óº   — 	 ddl m}  ||¬«      \  }}}}|dk(  S # t        $ r6 d|j                  «       v xs |j                  «       j	                  d«      cY S w xY w)zÕ
        Check if the model is an Anthropic model using get_llm_provider.

        Args:
            model: The model name/identifier

        Returns:
            True if Anthropic model, False otherwise
        r   )Úget_llm_provider)r}   Ú	anthropicÚclaudez
anthropic/)Ú1litellm.litellm_core_utils.get_llm_provider_logicr   r{   ÚlowerrV   )r   r}   r   Ú_Úcustom_llm_providers        r   Ú_is_anthropic_modelz'SkillsInjectionHook._is_anthropic_modelK  sf   € ð		Wõñ ,<À%Ô+HÑ(ˆAÐ" A qØ&¨+Ñ5Ð5øÜò 	Wà˜uŸ{™{›}Ð,ÒV°·±³×0HÑ0HÈÓ0VÒVð	Wús   ‚ ›<AÁAÚrequest_dataÚresponsec              ƒ   ó°  K  — ddl m} |j                  d«      xs i }|j                  d«      xs i }|j                  d«      xs |j                  d«      }|sy|j                  d«      xs |j                  di «      }i }	|j                  «       D ]  }
|	j	                  |
«       Œ |	st        j                  d«       y| j                  |«      }|syd	}|D ]F  }|j                  d
d«      }||j                  j                  k(  s|j                  t        «      sŒDd} n |syt        j                  d«       | j                  |||	¬«      ƒ d{  –—† S 7 Œ­w)aè  
        Post-call hook to handle automatic code execution.

        Handles both OpenAI format (response.choices) and Anthropic/messages API
        format (response["content"]).

        If the response contains a tool call (litellm_code_execution or skill tool):
        1. Execute the code in sandbox
        2. Add result to messages
        3. Make another LLM call
        4. Repeat until model gives final response
        5. Return modified response with generated files
        r   ©ÚLiteLLMInternalToolsrc   Úmetadatare   Nrd   z>SkillsInjectionHook: No skill files found, cannot execute codeFr   rM   Tz@SkillsInjectionHook: Detected tool call, starting execution loop)rD   rˆ   rp   )rf   r‹   r=   ÚvaluesÚupdater	   rY   Ú_extract_tool_callsÚCODE_EXECUTIONÚvaluerV   r   rT   Ú_execute_code_loop_messages_api)r   r‡   rˆ   rE   r‹   rc   rŒ   Úcode_exec_enabledÚskill_files_by_idrn   Ú
files_dictr2   Úhas_executable_toolÚtcÚ	tool_names                  r   Ú'async_post_call_success_deployment_hookz;SkillsInjectionHook.async_post_call_success_deployment_hook`  s€  è ø€ õ&	
ð
 #/×"2Ñ"2Ð3EÓ"FÒ"LÈ"ÐØ&×*Ñ*¨:Ó6Ò<¸"ˆà#3×#7Ñ#7Ð8YÓ#Zò $
Ð^f×^jÑ^jØ-ó_
Ðñ !Øð $4×#7Ñ#7¸Ó#GÒ#kÈ8Ï<É<ÐXfÐhjÓKkÐØ35ˆØ+×2Ñ2Ó4ò 	/ˆJØ×"Ñ" :Õ.ð	/ñ Ü ×(Ñ(Ð)iÔjØð !×4Ñ4°XÓ>ˆ
ÙØð $ÐØò 	ˆBØŸV™V F¨BÓ/ˆIàÐ0×?Ñ?×EÑEÒEÈ×I]ÑI]Ô^uÕIvØ&*Ð#Ùð	ñ #Øä×"Ñ"Ð#eÔfð ×9Ñ9ØØØ'ð :ó 
÷ 
ð 	
ð 
ús   ‚DEÄ4EÅEÅEc           
      óª  — g }d}t        |t        «      r|j                  dg «      }nt        |d«      r|j                  }|rÃ|D ]¾  }t        |t        «      rX|j                  d«      dk(  rD|j                  |j                  d«      |j                  d«      |j                  di «      dœ«       Œkt        |d«      sŒxt        |dd«      dk(  sŒ‰|j                  t        |dd«      t        |dd«      t        |di «      dœ«       ŒÀ |sÌt        |d	«      rÀ|j                  r´|j                  d
   j                  }t        |d«      r�|j                  rƒ|j                  D ]t  }|j                  |j                  |j                  j                  |j                  j                  r)t        j                  |j                  j                  «      ni dœ«       Œv |S )z8Extract tool calls from response, handling both formats.Nr0   ÚtypeÚtool_user*   r   Úinput)r*   r   r�   Úchoicesr   r2   )rQ   rR   r=   Úhasattrr0   rX   Úgetattrrž   Úmessager2   r*   r,   r   r!   ÚjsonÚloads)r   rˆ   r2   r0   ÚblockÚmsgr—   s          r   r�   z'SkillsInjectionHook._extract_tool_calls¥  sš  € àˆ
ð ˆÜ�h¤Ô%Ø—l‘l 9¨bÓ1‰GÜ�X˜yÔ)Ø×&Ñ&ˆGñ Ø ò �Ü˜e¤TÔ*¨u¯y©y¸Ó/@ÀJÒ/NØ×%Ñ%à"'§)¡)¨D£/Ø$)§I¡I¨fÓ$5Ø%*§Y¡Y¨w¸Ó%;ñõô ˜U FÕ+´¸¸vÀtÓ0LÐPZÓ0ZØ×%Ñ%ä")¨%°°tÓ"<Ü$+¨E°6¸4Ó$@Ü%,¨U°G¸RÓ%@ñõðñ& œg h°	Ô:¸x×?OÒ?OØ!×)Ñ)¨!Ñ,×4Ñ4ˆCÜ�s˜LÔ)¨c¯nªnØŸ.™.ò �BØ×%Ñ%à"$§%¡%Ø$&§K¡K×$4Ñ$4ØKMÏ;É;×K`ÒK`¤d§j¡j°·±×1FÑ1FÔ&GÐfhñõðð Ðr   rp   c           	   ƒ   óÔ  K  — ddl }ddlm} ddlm} |€t        j                  d«       y|j                  dd«      }t        |j                  dg «      «      }|j                  d	g «      }	|j                  d
d«      }
 || j                  ¬«      }g }|}t        | j                  «      D �]Ã  }| j                  |«      }t        |t        «      r|j                  d«      nt        |dd«      }t        |t        «      r|j                  dg «      nt        |dg «      }g }|xs g D ]ž  }t        |t        «      r|j!                  |«       Œ%t#        |d«      r |j!                  |j%                  «       «       ŒQt#        |d«      r%|j!                  t        |j&                  «      «       Œ‚|j!                  dt)        |«      dœ«       Œ  d|dœ}|j!                  |«       |dk7  s|s7t        j*                  d|dz   t-        |«      «       | j/                  ||«      c S g }|D ]Î  }|j                  dd«      }|j                  dd«      }|j                  di «      }||j0                  j2                  k(  r/|j                  dd«      }| j5                  ||||«      ƒ d{  –—† }n9|j7                  t8        «      r| j;                  |||||«      ƒ d{  –—† }nd|› d�}|j!                  d||dœ«       ŒÐ |j!                  d |dœ«       t        j*                  d!|d"z   «       	 |j<                  j?                  |||	|
¬#«      ƒ d{  –—† }|€)t        j                  d$«       | j/                  ||«      c S �ŒÆ t        jB                  d&| j                  «       | j/                  ||«      S 7 �Œ7 ŒÚ7 Œi# t@        $ r4}t        j                  d%|«       | j/                  ||«      cY d}~c S d}~ww xY w­w)'z—
        Execute the code execution loop for messages API (Anthropic format).

        Returns the final response with generated files inline.
        r   NrŠ   r   z?SkillsInjectionHook: Response is None, cannot execute code loopr}   rM   Úmessagesra   Ú
max_tokensé   ©ÚtimeoutÚstop_reasonr0   Ú
model_dumpÚ__dict__Útext)r›   r¯   Ú	assistant©Úroler0   rœ   zKSkillsInjectionHook: Loop completed after %s iterations, %s files generatedé   r   r*   r�   ÚcodeúTool 'z' not handledÚtool_result)r›   Útool_use_idr0   Úuserú1SkillsInjectionHook: Making LLM call iteration %sé   ©r}   r§   ra   r¨   z+SkillsInjectionHook: LLM call returned Nonez(SkillsInjectionHook: LLM call failed: %sú0SkillsInjectionHook: Max iterations (%s) reached)"Úlitellmrf   r‹   Ú2litellm.llms.litellm_proxy.skills.sandbox_executorr   r	   Úerrorr=   rS   r9   Úranger8   r�   rQ   rR   r    rX   rŸ   r­   r®   r&   rT   rU   Ú_attach_files_to_responser�   r‘   Ú_execute_coderV   r   Ú_execute_skill_toolr€   Úacreater{   rY   )r   rD   rˆ   rp   r½   r‹   r   r}   r§   ra   r¨   ÚexecutorÚgenerated_filesÚcurrent_responseÚ	iterationr2   r¬   Úraw_contentÚcontent_blocksr¤   Úassistant_msgÚtool_resultsr—   r˜   Útool_idÚ
tool_inputr´   Úresultr|   s                                r   r’   z3SkillsInjectionHook._execute_code_loop_messages_apiÓ  só  è ø€ ó 	õ	
õ	
ð
 ÐÜ ×&Ñ&Ð'hÔiØà—x‘x ¨Ó,ˆÜ˜tŸx™x¨
°BÓ7Ó8ˆØ—x‘x ¨Ó,ˆØ ŸH™H \°4Ó8ˆ
á/¸×8LÑ8LÔMˆØ:<ˆØ#Ðä˜t×2Ñ2Ó3ó S	QˆIà×1Ñ1Ð2BÓCˆJô Ð.´Ô5ð !×$Ñ$ ]Ô3äÐ-¨}¸dÓCð ô Ð.´Ô5ð !×$Ñ$ Y°Ô3äÐ-¨y¸"Ó=ð ð
  ˆNØ$Ò*¨ò P�Ü˜e¤TÔ*Ø"×)Ñ)¨%Õ0Ü˜U LÔ1Ø"×)Ñ)¨%×*:Ñ*:Ó*<Õ=Ü˜U JÔ/Ø"×)Ñ)¬$¨u¯~©~Ó*>Õ?à"×)Ñ)°6Ä3ÀuÃ:Ñ*NÕOðPð &1¸^ÑLˆMØ�O‰O˜MÔ*ð ˜jÒ(±
Ü$×*Ñ*ØaØ ‘MÜ˜Ó(ôð
 ×5Ñ5Ð6FÈÓXÒXð ˆLØ ò �Ø!#§¡¨°Ó!3�	ØŸ&™&  rÓ*�Ø02·±°wÀÓ0C�
ð Ð 4× CÑ C× IÑ IÒIØ%Ÿ>™>¨&°"Ó5�DØ#'×#5Ñ#5°d¸KÈÐSbÓ#c×c‘FØ×)Ñ)Ô*AÔBà#'×#;Ñ#;Ø! :¨{¸HÀoó$÷ ‘Fð  & i [°Ð>�Fà×#Ñ#à -Ø'.Ø#)ñõð#ð4 �O‰O V¸ÑEÔFô !×&Ñ&Ð'ZÐ\eÐhiÑ\iÔjðQØ)0×):Ñ):×)BÑ)BØØ%ØØ)ð	 *Có *÷ $Ð ð $Ð+Ü(×.Ñ.Ð/\Ô]Ø×9Ñ9¸(ÀOÓTÒTñ ,ð]S	Qôj 	×$Ñ$Ð%WÐY]×YlÑYlÔmØ×-Ñ-Ð.>ÀÓPÐPðK dùðøð($ùô ò QÜ$×*Ñ*Ð+UÐWXÔYØ×5Ñ5°hÀÓP×PûðQüsg   ‚JO(ÊN!Ê2O(Ë	N$Ë
AO(Ì"N(Ì<N&Ì=,N(Í)9O(Î$O(Î&N(Î(	O%Î1'O ÏO%ÏO(Ï O%Ï%O(r´   rÅ   r   rÆ   c              ƒ   óâ  K  — 	 t        j                  dt        |«      «       |j                  ||¬«      }|j	                  dd«      xs d}|j	                  d«      rU|d   }|D ]K  }|j                  |d   |d   |d   t        t        j                  |d   «      «      d	œ«       |d
|d   › �z  }ŒM |j	                  d«      r|d|d   › �z  }|xs dS # t        $ r}	d|	› �cY d}	~	S d}	~	ww xY w­w)z1Execute code in sandbox and return result string.ú.SkillsInjectionHook: Executing code (%s chars)©r´   rp   ÚoutputrM   Úfilesr   Ú	mime_typeÚcontent_base64©r   rÕ   rÖ   Úsizez

Generated file: r¿   z	

Error: zCode executed successfullyúCode execution failed: N)	r	   rT   rU   Úexecuter=   rX   Úbase64Ú	b64decoder{   )
r   r´   rp   rÅ   rÆ   Úexec_resultrÏ   rÔ   Úfr|   s
             r   rÂ   z!SkillsInjectionHook._execute_codeL  s  è ø€ ð	1Ü ×&Ñ&Ð'WÔY\Ð]aÓYbÔcà!)×!1Ñ!1°tÈÐ!1Ó!UˆKà —_‘_ X¨rÓ2Ò8°bˆFð �‰˜wÔ'Ø<GÈÑ<P�Øò 	A�AØ#×*Ñ*à$% f¡IØ)*¨;©Ø./Ð0@Ñ.AÜ$'¬×(8Ñ(8¸Ð;KÑ9LÓ(MÓ$Nñ	ôð Ð 4°Q°v±Y°KÐ@Ñ@‘Fð	Að �‰˜wÔ'Ø˜K¨°GÑ(<Ð'=Ð>Ñ>�àÒ9Ð9Ð9øÜò 	1Ø,¨Q¨CÐ0Õ0ûð	1üs5   ‚C/„CC ÃC/Ã	C,ÃC'Ã!C,Ã"C/Ã'C,Ã,C/r˜   rÎ   c              ƒ   ó®  K  — |D �cg c](  }|j                  d«      sŒ|j                  d«      rŒ'|‘Œ* }}d}|D ]<  }	d|	j                  «       v s%d|	j                  «       v sd|	j                  «       v sŒ:|	} n |s|r|d   }|r,|j                  dd	«      j                  dd
«      }
d|
› d|
› d�}nd}| j                  ||||«      ƒ d{  –—† S c c}w 7 Œ	­w)zKExecute a skill tool by generating and running code based on skill content.rb   z__init__.pyNÚbuilderÚcreatorÚ	generatorr   ú/ú.rM   zX
# Auto-generated code to execute skill
import sys
sys.path.insert(0, '/sandbox')

from z] import *

# Try to find and use a Builder/Creator class
import inspect
module = __import__('aE  ', fromlist=[''])

for name, obj in inspect.getmembers(module):
    if inspect.isclass(obj) and name != 'object':
        try:
            instance = obj()
            # Try common methods
            if hasattr(instance, 'create'):
                result = instance.create()
            elif hasattr(instance, 'build'):
                result = instance.build()
            elif hasattr(instance, 'generate'):
                result = instance.generate()
            elif hasattr(instance, 'save'):
                instance.save('output.gif')
            print(f'Used {name} class')
            break
        except Exception as e:
            print(f'Error with {name}: {e}')
            continue

# List generated files
import os
for f in os.listdir('.'):
    if f.endswith(('.gif', '.png', '.jpg')):
        print(f'Generated: {f}')
z+
print('No executable skill module found')
)rj   rƒ   ÚreplacerÂ   )r   r˜   rÎ   rp   rÅ   rÆ   ÚpÚpython_modulesÚmain_moduleÚmodÚimport_pathr´   s               r   rÃ   z'SkillsInjectionHook._execute_skill_toolp  s  è ø€ ð -8Ö o q¸1¿:¹:ÀeÕ;LÐUV×U_ÑU_Ð`mÕUn¢Ð oˆÐ oð ˆØ!ò 	ˆCØ˜CŸI™I›KÑ'¨9¸¿	¹	»Ñ+CÀ{ÐVY×V_ÑV_ÓVaÒGaØ!�Ùð	ñ
 ™~à(¨Ñ+ˆKáà!,×!4Ñ!4°S¸#Ó!>×!FÑ!FÀuÈbÓ!QˆKðð
 €]ð ð "�]ð #ð#‰DðLˆDð ×'Ñ'¨¨k¸8À_ÓU×UÐUùòy !pðx Vús,   ‚C‡CžC°C´?CÁ4ACÃ	CÃ

Cc           
   ƒ   ó˜  K  — ddl }ddlm} ddlm} |j                  dd«      }t        |j                  dg «      «      }|j                  dg «      }	t        h d	£«      }
|j                  «       D ��ci c]  \  }}||
vsŒ||“Œ }}} || j                  ¬
«      }g }|}t        | j                  «      D �]Ò  }|j                  d   j                  }|j                  d   j                  }d|j                  dœ}|j                   rV|j                   D �cg c]=  }|j"                  d|j$                  j&                  |j$                  j(                  dœdœ‘Œ? c}|d<   |j+                  |«       |dk7  s|j                   s7t-        j.                  d|dz   t1        |«      «       | j3                  ||«      c S |j                   D ]t  }|j$                  j&                  }||j4                  j6                  k(  r| j9                  ||||¬«      ƒ d{  –—† }nd|› d�}|j+                  d|j"                  |dœ«       Œv t-        j.                  d|dz   «       |j:                  j=                  |||	|j                  dd«      ¬«      ƒ d{  –—† }�ŒÕ t-        j>                  d| j                  «       | j3                  ||«      S c c}}w c c}w 7 Œ¼7 ŒF­w)z”
        Execute the code execution loop until model gives final response.

        Returns the final response with generated files inline.
        r   NrŠ   r   r}   rM   r§   ra   >   r}   ra   r§   rŒ   rJ   rc   rª   r°   r±   r,   )r   r!   )r*   r›   r,   r2   zZSkillsInjectionHook: Code execution loop completed after %s iterations, %s files generatedr³   )Ú	tool_callrp   rÅ   rÆ   rµ   z' not handled automaticallyÚtool)r²   Útool_call_idr0   r¹   rº   r¨   r©   r»   r¼   ) r½   rf   r‹   r¾   r   r=   rS   Ú	frozensetÚitemsr9   rÀ   r8   rž   r¡   Úfinish_reasonr0   r2   r*   r,   r   r!   rX   r	   rT   rU   rÁ   r�   r‘   Ú_execute_code_toolr€   rÄ   rY   )r   rD   rˆ   rp   r½   r‹   r   r}   r§   ra   Ú_EXCLUDED_ACOMPLETION_KEYSÚkÚvr@   rÅ   rÆ   rÇ   rÈ   Úassistant_messager¬   Úassistant_msg_dictr—   rì   r˜   r¶   s                            r   Ú_execute_code_loopz&SkillsInjectionHook._execute_code_loop¹  så  è ø€ ó 	õ	
õ	
ð —x‘x ¨Ó,ˆÜ˜tŸx™x¨
°BÓ7Ó8ˆØ—x‘x ¨Ó,ˆô -6òó	-
Ð"ð +/¯*©*«,×^¡$ ! Q¸!ÐC]Ò:]˜˜A™Ð^ˆÑ^á/¸×8LÑ8LÔMˆØ:<ˆØ (Ðä˜t×2Ñ2Ó3ó @	ˆIà.>×.FÑ.FÀqÑ.I×.QÑ.QÐØ&6×&>Ñ&>¸qÑ&A×&OÑ&OˆKð $Ø,×4Ñ4ñ5Ðð !×+Ò+ð 0×:Ñ:ö
4ð ð !Ÿe™eØ *à$&§K¡K×$4Ñ$4Ø)+¯©×)>Ñ)>ñ%óò
4Ð" <Ñ0ð �O‰OÐ.Ô/ð ˜lÒ*Ð2C×2NÒ2NÜ$×*Ñ*ØpØ ‘MÜ˜Ó(ôð ×5Ñ5Ð6FÈÓXÒXð /×9Ñ9ò �	Ø%×.Ñ.×3Ñ3�	àÐ 4× CÑ C× IÑ IÒIØ(,×(?Ñ(?Ø"+Ø$/Ø!)Ø(7ð	 )@ó )÷ #‘Kð %+¨9¨+Ð5PÐ"Q�Kà—‘à &Ø(1¯©Ø#.ñõðô. !×&Ñ&Ð'ZÐ\eÐhiÑ\iÔjØ%,×%6Ñ%6×%>Ñ%>ØØ!ØØ!Ÿ:™: l°DÓ9ð	 &?ó &÷  Òðw@	ôF 	×$Ñ$Ð%WÐY]×YlÑYlÔmØ×-Ñ-Ð.>ÀÓPÐPùóU _ùò"
4ð8#øð( úsG   ‚A0K
Á2J;Á?J;ÂBK
ÄAKÅB5K
È	KÈ
A7K
ÊKÊAK
ËK
rì   c           	   ƒ   óê  K  — 	 t        j                  |j                  j                  «      }|j	                  dd«      }t        j                  dt        |«      «       |j                  ||¬«      }|j	                  dd«      xs d}|j	                  d«      rŒ|dz  }|d   }	|	D ]}  }
t        j                  |
d   «      }|j                  |
d	   |
d
   |
d   t        |«      dœ«       |d|
d	   › dt        |«      › d�z  }t        j                  d|
d	   t        |«      «       Œ |j	                  d«      r|d|d   › �z  }|S # t        $ r%}t        j                  d|«       d|› �cY d}~S d}~ww xY w­w)zDExecute a litellm_code_execution tool call and return result string.r´   rM   rÑ   rÒ   rÓ   rÔ   z

Generated files:rÖ   r   rÕ   r×   z
- z (z bytes)z1SkillsInjectionHook: Generated file %s (%s bytes)r¿   z	

Error:
z.SkillsInjectionHook: Code execution failed: %srÙ   N)r¢   r£   r,   r!   r=   r	   rT   rU   rÚ   rÛ   rÜ   rX   r{   r¿   )r   rì   rp   rÅ   rÆ   Úargsr´   rÝ   r¶   rÔ   rÞ   Úfile_contentr|   s                r   rò   z&SkillsInjectionHook._execute_code_tool)  s—  è ø€ ð)	1Ü-1¯Z©Z¸	×8JÑ8J×8TÑ8TÓ-UˆDØ#Ÿx™x¨°Ó3ˆDä ×&Ñ&Ð'WÔY\Ð]aÓYbÔcà!)×!1Ñ!1ØØ'ð "2ó "ˆKð &Ÿ/™/¨(°BÓ7Ò=¸2ˆKð �‰˜wÔ'ØÐ5Ñ5�Ø<GÈÑ<P�Øò �AÜ#)×#3Ñ#3°AÐ6FÑ4GÓ#H�LØ#×*Ñ*à$% f¡IØ)*¨;©Ø./Ð0@Ñ.AÜ$'¨Ó$5ñ	ôð   T¨!¨F©)¨°B´s¸<Ó7HÐ6IÈÐ#QÑQ�Kä(×.Ñ.ØKÈQÈvÉYÔX[Ð\hÓXiõðð  �‰˜wÔ'Ø ¨k¸'Ñ.BÐ-CÐDÑD�àÐøäò 	1Ü ×&Ñ&Ð'WÐYZÔ[Ø,¨Q¨CÐ0Õ0ûð	1üs5   ‚E3„D=E ÅE3Å	E0ÅE+Å%E0Å&E3Å+E0Å0E3c                 óF  — |s|S |}t        |t        «      r&||d<   t        j                  dt	        |«      «       |S 	 ||_        t        |d«      r"|j                  €i |_        ||j                  d<   t        j                  dt	        |«      «       |S # t        $ r Y ŒZw xY w)zÅ
        Attach generated files to the response object.

        Files are added to response._litellm_generated_files for easy access.
        For dict responses, files are added as a key.
        Ú_litellm_generated_filesz7SkillsInjectionHook: Attached %s files to dict responseÚmodel_extraz2SkillsInjectionHook: Attached %s files to response)	rQ   rR   r	   rT   rU   rý   ÚAttributeErrorrŸ   rþ   )r   rˆ   rÆ   Úraw_responses       r   rÁ   z-SkillsInjectionHook._attach_files_to_response\  sµ   € ñ ØˆOà&ˆô �h¤Ô%Ø3BˆHÐ/Ñ0Ü ×&Ñ&Ð'`ÔbeÐfuÓbvÔwØÐð	Ø0?ˆHÔ-ô
 �8˜]Ô+Ø×#Ñ#Ð+Ø')�Ô$Ø?NˆH× Ñ Ð!;Ñ<ä×"Ñ"Ð#WÔY\Ð]lÓYmÔnàˆøô ò 	Ùð	ús   ¾B Â	B ÂB )T)#r"   r#   r$   Ú__doc__r?   r   r
   rR   r   r{   r&   r^   rS   r   ÚboolrZ   rv   rW   r†   r   r   r™   r   r�   ÚobjectÚbytesr’   rÂ   r   rÃ   rø   r(   rò   rÁ   Ú__classcell__)rA   s   @r   r4   r4   F   s  ø„ ñô 
#ð@à)ð@ð ð@ð ð	@ð
 $ð@ð 
�S‰˜4Ñ	 $Ñ	&ó@ðL &*ñ	FàðFð Ð0Ñ1ðFð #ð	Fð
 
óFðPCàðCð Ð0Ñ1ðCð 
ó	CðJàðð *ðð 
˜tÑ	#ó	ð2W¨ð W°ó Wð*C
àðC
ð #ðC
ð ˜tÑ#ð	C
ð
 
˜DÑ	 óC
ðJ,¨Cð ,°D¸¸cÀ3¸h¹Ñ4Hó ,ð\wQàðwQð ðwQð ˜#˜u˜*Ñ%ð	wQð
 
˜DÑ	 ówQðr"1àð"1ð ˜#˜u˜*Ñ%ð"1ð *ð	"1ð
 ˜d 3¨ ;Ñ/Ñ0ð"1ð 
ó"1ðHGVàðGVð ˜C ˜HÑ%ðGVð ˜#˜u˜*Ñ%ð	GVð
 *ðGVð ˜d 3¨ ;Ñ/Ñ0ðGVð 
óGVðRnQàðnQð ðnQð ˜#˜u˜*Ñ%ð	nQð
 
ónQð`11à ð11ð ˜#˜u˜*Ñ%ð11ð *ð	11ð
 ˜d 3¨ ;Ñ/Ñ0ð11ð 
ó11ðf$àð$ð ˜d 3¨ ;Ñ/Ñ0ð$ð 
÷	$r   r4   Úskills_injection_hook)'r  rÛ   r¢   Úcollections.abcr   r   Útypingr   r   r   r   Úlitellm._loggingr	   Úlitellm.caching.cachingr
   Ú"litellm.integrations.custom_loggerr   r:   r   Ú2litellm.llms.litellm_proxy.skills.prompt_injectionr   Úlitellm.proxy._typesr   r   Úlitellm.types.utilsr   r   r   r¾   r   r   r(   r.   r4   r  Ú__annotations__r½   Úlogging_callback_managerÚadd_litellm_callbackr   r   r   ú<module>r     s›   ðòó4 Û ß -ß 6Ó 6å 1Ý -Ý ;Ý Oõ÷ Eß MÑ MáÝXô$˜ô $ô1�Hô 1ô@�8ô @ôz˜,ô zñ|  3Ó4Ð �uÓ 4ã à ×  Ñ  × 5Ñ 5Ð6KÕ Lr   