
    iX                         d Z ddlZddlmZmZ ddlmZmZmZm	Z	m
Z
mZ ddlmZmZmZ ddlmZ e G d d             Z G d	 d
e      Ze G d d             Z G d d      Zdededz  fdZy)z9Human-in-the-loop prompt service with pluggable channels.    N)	dataclassfield)AnyCallableDictListOptionalProtocol)MessageBlockMessageBlockTypeMessageContent)
LogManagerc                   h    e Zd ZU dZeed<   dZeee	      ed<    e
e      Zeeef   ed<   defdZy)	PromptResultz+Typed result returned from prompt channels.textNblocks)default_factorymetadatareturnc                 J    | j                   | j                   S | j                  S N)r   r   )selfs    ?/Users/bowang/.openclaw/workspace/ChatDev/utils/human_prompt.pyas_message_contentzPromptResult.as_message_content   s    "kk5t{{D499D    )__name__
__module____qualname____doc__str__annotations__r   r	   r   r   r   dictr   r   r   r   r    r   r   r   r      sC    5
I+/FHT,'(/$T:Hd38n:EN Er   r   c                   J    e Zd ZdZddddededee   deeeef      def
d	Z	y)
PromptChannelz<Channel interface that performs the actual user interaction.Ninputsr   node_idtaskr'   r   r   c                     y)z9Collect user feedback and return the structured response.Nr#   )r   r(   r)   r'   r   s        r   requestzPromptChannel.request   s    r   )
r   r   r   r   r    r	   r   r   r   r+   r#   r   r   r%   r%      s[    F !%-1H H 	H
 H 4S>*H 
Hr   r%   c                   f    e Zd ZU dZeZeegef   ed<   ddddedede	e   de	e
eef      d	ef
d
Zy)CliPromptChannelz:Default channel that prompts the operator via CLI input().
input_funcNr&   r(   r)   r'   r   r   c                R   dg}|r"|j                  d       |j                  |       |j                  d| d       |j                  |       |j                  d       dj                  |      dz   }| j                  |      }t        |t	        j
                  |xs d      g      S )	Nz ===== HUMAN INPUT REQUIRED =====z=== Node inputs ===z=== Task for human (z) ===z=== Your response: ===
 r   r   )appendjoinr.   r   r   
text_block)r   r(   r)   r'   r   headerpromptresponses           r   r+   zCliPromptChannel.request+   s     55MM/0MM&!,WIU;<d./6"T)??6* ++HN;<
 	
r   )r   r   r   r   inputr.   r   r    r!   r	   r   r   r   r+   r#   r   r   r-   r-   %   sj    D',J#$, !%-1
 
 	

 
 4S>*
 

r   r-   c                       e Zd ZdZdddededee   ddfdZddd	d
ededee   dee	ee
f      def
dZede
defd       Zdeez  e
z  defdZdeee      dedee   fdZy)HumanPromptServicez=Coordinates human feedback collection across nodes and tools.N)
session_idlog_managerchannelr<   r   c                `    || _         || _        || _        t        j                         | _        y r   )_log_manager_channel_session_id	threadingLock_lock)r   r=   r>   r<   s       r   __init__zHumanPromptService.__init__E   s)     (%^^%
r   r&   r(   task_descriptionr'   r   c                P   t        |xs i       }| j                  rd|vr| j                  |d<   | j                  5  | j                  j	                  |      5  | j
                  j                  ||||      }ddd       ddd       | j                        }| j                  |j                        }| j                  |j                  |      }	i |j                  |}
| j                  j                  |||d|i|
       t        ||	|
      S # 1 sw Y   xY w# 1 sw Y   xY w)z3Request human input through the configured channel.r<   )r(   r)   r'   r   NrG   )details)r   r   r   )r"   rB   rE   r@   human_timerrA   r+   _normalize_result_sanitize_responser   _normalize_blocksr   r   record_human_interactionr   )r   r(   rG   r'   r   meta
raw_resultprompt_resultsanitized_textnormalized_blockscombined_metadatas              r   r+   zHumanPromptService.requestQ   s-    HN#D 8!%!1!1DZZ""..w7!]]22#)!!	 3 
 8  ..z:001C1CD 22=3G3GX>}55>>22')9O=NO	 	3 	
 $&
 	
' 87 Zs#   D D7DD	DD%r8   c                     t        | t              r| n
t        |       }|j                  dd      j                  dd      S )Nzutf-8ignore)errors)
isinstancer    encodedecode)r8   r   s     r   rL   z%HumanPromptService._sanitize_responsey   s9    %h4x#h-{{78{4;;GH;UUr   rP   c                     t        |t              r|S | j                  |      }t        |t        j                  |      g      S )Nr2   )rX   r   rL   r   r5   )r   rP   r   s      r   rK   z$HumanPromptService._normalize_result~   s=    j,/&&z2|/F/Ft/L.MNNr   r   fallback_textc                    |st        j                  |      gS g }|D ]k  }|j                         }|j                  t        j
                  u r,|j                   | j                  |j                        |_        |j                  |       m |S r   )	r   r5   copytyper   TEXTr   rL   r3   )r   r   r\   
normalizedblockdups         r   rM   z$HumanPromptService._normalize_blocks   s}    
  ++M:;;)+
E**,Cxx+000SXX5I22388<c"	 
 r   )r   r   r   r   r   r%   r	   r    rF   r   r   r   r+   staticmethodrL   rK   r   r   rM   r#   r   r   r;   r;   B   s    G %)
&  
& 	
&
 SM
& 

&" !%-1&
&
 &

 &
 4S>*&
 
&
P VS VS V VOL3,>,D O Ol+,  
l		r   r;   workspace_hookr   c                 r    | yt        | dd      }t        |      r |       }||S t        | dd      }||S y)zCHelper to fetch a PromptChannel from a workspace hook if available.Nget_prompt_channelprompt_channel)getattrcallable)re   getterr>   s      r   resolve_prompt_channelrl      sS     ^%94@F(Nn&6=Gr   )r   rC   dataclassesr   r   typingr   r   r   r   r	   r
   entity.messagesr   r   r   utils.log_managerr   r   r%   r-   r;   rl   r#   r   r   <module>rq      s    ?  ( @ @ J J ( E E EHH H 
 
 
8O Od3 =43G r   