
    i=                        d dl Z d dlZd dlmZ d dlZd dlZd dlmZmZ d dl	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZ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'm(Z( d dl)Z)d d
l*m+Z+m,Z, d dl-m.Z/ d dl-m0Z1  ejd                  e3      Z4d dl5Z5de6dee7   fdZ8de6de6fdZ9de6de6fdZ:de7de;fdZ< G d d      Z= G d de      Z>y)    N)Optional)ActionModelActionResult)Registry)InputTextActionOpenAppActionAppleScriptActionPressActionPressCombinedAction
DragActionRightClickPixelLeftClickPixelScrollDownActionScrollUpActionMoveToActionRecordAction)	type_intopress_scroll_invisible_at_positionmove_toleft_click_pixelright_click_pixelpress_combination
drag_pixel)MacUITreeBuilder)time_execution_asynctime_execution_sync)pinyinStyle)AXUIElementCreateApplicationAXUIElementCopyAttributeValue)process)fuzz	user_normreturnc                 f   |j                         }t        j                  d|        i }|D ]q  }|j                         }|j	                         xs d}|j                         xs d}t        |      }t        |      }	|r| d| }
||f||
<   |	sd|	 d| }
||f||
<   s |st        j                  d       yt        j                  | |j                         t        j                        }d}d}|rE|\  }}}t        j                  d|  d	| d
| d       |dk\  r||}}n+t        j                  d       nt        j                  d       |sqt        j                  | |j                         t        j                        }|st        j                  d       y|\  }}}t        j                  d|  d	| d
| d       |dk  rt        j                  d| d       y||   \  }}t        |      r@t        j                  d| d|j	                          d|j                          d| d	       |S y)zs
    Return a PID for the best matching running app (with visible window),
    or None if no good match found.
    zRunning apps:  :zNo candidate apps found.N)scorerr   zRatio best match: 'z' -> 'z' (conf=)P   z8Ratio confidence too low, falling back to partial_ratio.z4No match using ratio, falling back to partial_ratio.z,No fuzzy matches using partial_ratio either.zPartial best match: 'zBest confidence only z, returning None.zUsing best fuzzy match => PID: ,  / z, confidence=z, windows=YES)runningApplicationsloggerdebugprocessIdentifierbundleIdentifierlocalizedNamenormalize_for_matchingrapidfuzz_process
extractOnekeysrapidfuzz_fuzzratiopartial_ratiohas_app_windowsinfo)r$   	workspacerunning_appscandidate_mapapppid	bundle_idnamenorm_bundle_id	norm_namekeyratio_matchbest_candidate_keybest_confidencetmp_keytmp_conf_partial_matchcandidate_apps                      H/Users/mibo/.openclaw/workspace/data/TuriX-CUA/src/controller/service.pyfuzzy_find_pidrP   &   st   
 002L
LL>,01M##%((*0b	  "(b/	:*40	#$AcU+C"%sM#Kq&C"%sM#   /0 $..##K O*1*9+VG9HXJVWXYr>298LLSTKL )44 !//

 LLGH1>.OQ#I;f5G4HQ`Paabc	

 ,_,==NOP ''9:C s-cU"--/0M4O4O4Q3R S)*-9	

 
     sc                 d    dj                  d t        | t        j                        D              S )N c              3   &   K   | ]	  }|d      yw)r   N ).0sylls     rO   	<genexpr>z$chinese_to_pinyin.<locals>.<genexpr>~   s     F(EDG(Es   )style)joinr   r   NORMALrR   s    rO   chinese_to_pinyinr^   |   s"    88Fq(EFFFrQ   c                     t        j                  d|       rt        |       } | j                         } t        j                  dd|       } | S )Nz[\u4e00-\u9fff]z[^\w]r'   )researchr^   lowersubr]   s    rO   r4   r4      s=    	yy#Q'a 		A
xQAHrQ   rA   c                 V    t        |       }t        |dd       }|t        |      dkD  ryy)N	AXWindowsr   TF)r    r!   len)rA   app_refwindowss      rO   r;   r;      s1    *3/G+G[$GGs7|a/rQ   c                       e Zd Zg fdee   fdZd ZdefdZ ed      	 ddee	   de
d	ed
ee   fd       Z ed      de	de
d
efd       Zy)
Controllerexclude_actionsc                 p    || _         t        |      | _        | j                          t	               | _        y N)rk   r   registry_register_default_actionsr   mac_tree_builder)selfrk   s     rO   __init__zController.__init__   s/     )$?+$-  "*,$rQ   c           	      ~   | j                   j                  dt              d        }| j                   j                  dt        d      dt        fd       }| j                   j                  d	t
              d
t        fd       }| j                   j                  dt              dt        fd       }| j                   j                  dt              d/dt        fd       }| j                   j                  dt              d0dt        dt        dt        t           fd       }| j                   j                  dt        d      ddgfdt        fd       }| j                   j                  dt        d      ddgfdt        fd       }| j                   j                  dt        d      ddgddgfdt        d t        fd!       }	| j                   j                  d"t        d      ddgfdt        fd#       }
| j                   j                  d$t              d1d%t         d&t         fd'       }| j                   j                  d(t"              d1d%t         d&t         fd)       }| j                   j                  d*t$              dt        d+t        fd,       }| j                   j                  d-t              d.        }y)2z Register all default cua actionszComplete task)param_modelc                  $   K   t        dd      S w)NdoneT)extracted_contentis_doner   rV   rQ   rO   rv   z2Controller._register_default_actions.<locals>.done   s      
>>s   TypeF)rt   requires_mac_buildertextc                    K   	 t        |        d {   }|rt        d      S d}t        ||      S 7 !# t        $ r:}dt        |       }t	        j
                  |       t        ||      cY d }~S d }~ww xY ww)NzSuccessfully input textrw   u   ❌ Input failedrw   error   ❌ An error occurred: )r   r   	Exceptionstrloggingr   )r|   input_successfulmsges       rO   
input_textz8Controller._register_default_actions.<locals>.input_text   sx     

:&t_,-DFFS3c:: -  :#CF8
,CMM##S99:sE   A<6 46 A<6 A<6 	A9/A4.A9/A<4A99A<zOpen a mac appapp_namec                 J  K   | }t         j                  j                         }t        j	                  d| d       |j                  |      }|s(d| d}t        j                  |       t        ||      S d}d| d| }t        j	                  |       t        ||	      S w)
z
			Attempt to open a macOS app by name. Then:
			1) Try pgrep-based PID lookup first.
			2) If that fails or the process has no visible window, fallback to fuzzy matching
			against NSWorkspace.sharedWorkspace().runningApplications().
			z
Launching app: z...u   ❌ Failed to launch ''r   Nu   ✅ Launched z, PID=)rw   current_app_pid)CocoaNSWorkspacesharedWorkspacer/   r<   launchApplication_r   r   )r   
user_inputr=   successr   rA   success_msgs          rO   open_appz6Controller._register_default_actions.<locals>.open_app   s      :  0029	;;":,c23 ))*57
":,a
0C
LL#S99	3 F3%8;	;;{
c
JJs   B!B#zRun an AppleScriptscriptc                   K   t         j                  d|         d|  d}	 t        j                  dd|gdd      }|j                  dk(  rl|j
                  j                         }|d	k(  rt        d
      S |j                  d      r$|}t         j                  |       t        ||      S t        |      S d|j                   d|j                  j                          }t         j                  |       t        ||      S # t        $ r:}dt        |       }t         j                  |       t        ||      cY d }~S d }~ww xY ww)NzRunning AppleScript: z
				try
					zT
					return "OK"
				on error errMsg
					return "ERROR: " & errMsg
				end try
				osascriptz-eT)capture_outputr|   r   OKSuccessr~   zERROR:r   z$AppleScript failed with return code : zFailed to run AppleScript: )r/   r0   
subprocessrun
returncodestdoutstripr   
startswithr   stderrr   r   )r   wrapped_scriptresultoutput	error_msgr   s         rO   run_apple_scriptz>Controller._register_default_actions.<locals>.run_apple_script   s;    
 
<<'x01X >F^^4(
F Amm!!#V$I66


H
%ill9IYGGF3378I8I7J"V]]M`M`MbLcdY\\)9IFF
 F-c!fX6I
LL)9EEFsZ   E
AD 6E
74D +E
,D 7E
8AD E
	E/E<E=E
EE
zSingle HotkeyrF   c                    K   | j                  dd      }t        |       d {   }|r't        j                  d|         t	        d|        S y 7 .w)NKey.r'   u   ✅ pressed key code: *Successfully press keyboard with key code r~   )replacer   r   r<   r   )rF   	key_presspress_successfuls      rO   Hotkeyz4Controller._register_default_actions.<locals>.Hotkey   s\      {{62&9!),,LL)#/0,VWZV[*\]]  -s   !AA/AzPress Multiple HotkeyNkey1key2key3c                   K   dt         d z  dt         d z  fd} ||       }  ||      } ||      }ddddt         dt         ffd} ||       }  ||      }| ||      nd }|Jt        | ||       d {   }|rt        j                  d	|  d
| d|        t	        d|  d
| d|       S t        | |d        d {   }|rt        j                  d	|  d|        t	        d|  d|       S 7 ~7 5w)Nrawr%   c                 J    | y| j                  dd      j                  d      S )z2Strip the `Key.` prefix and any stray quote marks.Nr   r'   z'")r   r   )r   s    rO   	clean_keyzMController._register_default_actions.<locals>.multi_Hotkey.<locals>.clean_key  s&    
{;;vr"((//rQ   command	backspace)cmddeleterF   c                 D    j                  | j                         |       S rm   )getrb   )rF   key_maps    rO   map_keyzKController._register_default_actions.<locals>.multi_Hotkey.<locals>.map_key  s    ;;syy{C((rQ   u   ✅ pressed combination key: r,   z and r   r~   )r   )r   r   r   r<   r   )r   r   r   r   r   r   r   s         @rO   multi_Hotkeyz:Controller._register_default_actions.<locals>.multi_Hotkey  s?    
0cDj 0S4Z 0
 D/4
D/4
D/47
)C )C ) $-4
$-4+'$-4
.tT4@@\\1$r$uTFKL,VW[V\\^_c^ddijnio*pqq.tDdCC\\1$uTFCD,VW[V\\abfag*hii A
 Ds%   A4C:7C68A
C:C84C:8C:z#RightSingle click at specific pixelr   positionc                 h  K   t         j                  d|         	 t        |        d {   }|r't        j                  d|         t        d|        S d|  }t        ||      S 7 ?# t        $ r:}dt        |       }t        j                  |       t        ||      cY d }~S d }~ww xY ww)N Correct clicking pixel position u#   ✅ Finished right click at pixel: Successfully clicked pixel r~   u0   ❌ Right click failed for pixel with position: r   r   )	r/   r0   r   r   r<   r   r   r   r   r   click_successfulr   r   s       rO   RightSinglez9Controller._register_default_actions.<locals>.RightSingle*  s      
<<28*=>:.x88\\7zBC-H
+STT=hZHS3c:: 9  :#CF8
,CMM##S99:P   B2A, A*,A, B2A, )B2*A, ,	B/5/B*$B/%B2*B//B2zLeft click at specific pixelc                 h  K   t         j                  d|         	 t        |        d {   }|r't        j                  d|         t        d|        S d|  }t        ||      S 7 ?# t        $ r:}dt        |       }t        j                  |       t        ||      cY d }~S d }~ww xY ww)Nr   u"   ✅ Finished left click at pixel: r   r~   u/   ❌ Left click failed for pixel with position: r   r   )	r/   r0   r   r   r<   r   r   r   r   r   s       rO   Clickz3Controller._register_default_actions.<locals>.Click>  s      
<<28*=>:-h77\\6xjAB-H
+STT<XJGS3c:: 8  :#CF8
,CMM##S99:r   z(Drag an object from one pixel to another	position1	position2c                 F  K   	 t        | |       d {   }|r-t        j                  d|  d|        t        d|  d|       S d|  }t        ||      S 7 E# t        $ r:}dt        |       }t        j                  |       t        ||      cY d }~S d }~ww xY ww)Nz$Correct draging pixel from position z to zSuccessfully drag pixel r~   u)   ❌ Drag failed for pixel with position: r   r   )r   r/   r<   r   r   r   r   r   )r   r   drag_successfulr   r   s        rO   Dragz2Controller._register_default_actions.<locals>.DragR  s     :&y)<<O[[7	{$ykRS-Ei[PTU^T_+`aa6ykBS3c:: =  :#CF8
,CMM##S99:sP   B!A A2A B!A B!A 	B$/BBB!BB!zMove mouse to specific pixelc                 h  K   t         j                  d|         	 t        |        d {   }|r't        j                  d|         t        d|        S d|  }t        ||      S 7 ?# t        $ r:}dt        |       }t        j                  |       t        ||      cY d }~S d }~ww xY ww)NzCorrect move mouse to position u"   ✅ Finished move mouse to pixel: zSuccessfully move mouse to r~   u.   ❌ Failed move mouse to pixel with position: r   r   )	r/   r0   r   r   r<   r   r   r   r   )r   move_successfulr   r   s       rO   
move_mousez8Controller._register_default_actions.<locals>.move_mousee  s      
<<1(<=:#H--O\\6xjAB-H
+STT;H:FS3c:: .  :#CF8
,CMM##S99:r   z	Scroll updxdyc                    K   | \  }}|}t        |||       d {   }|r't        j                  d|        t        d|       S y 7 .w)Nu   ✅ Scrolled up by zSuccessfully scrolled up by r~   r   r   r<   r   r   r   r   xyamountscroll_successfuls          rO   	scroll_upz7Controller._register_default_actions.<locals>.scroll_upy  s]     
 
31Q6:1QvFFLL&vh/0,H*QRR  Gs   AA	/AzScroll downc                    K   | \  }}|}t        |||        d {   }|r't        j                  d|        t        d|       S y 7 .w)Nu   ✅ Scrolled down by zSuccessfully scrolled down by r~   r   r   s          rO   scroll_downz9Controller._register_default_actions.<locals>.scroll_down  s_     
 
31Q6:1QHHLL(12,J6(*STT  Is   AA
/Az8Tell the short memory that you are recording information	file_namec                 ,   K   t        | d|        S w)Nr   r~   ry   )r|   r   s     rO   record_infoz9Controller._register_default_actions.<locals>.record_info  s     
 I;b)?
@@s   Waitc                  "   K   t        d      S w)NWaitingr~   ry   rV   rQ   rO   waitz2Controller._register_default_actions.<locals>.wait  s     
 7
44s   )enterrm   )i   )rn   actionNoParamsActionr   r   r   r	   r
   r   r   r   listr   r   r   r   intr   r   )rq   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   s                  rO   ro   z$Controller._register_default_actions   sV    ==   ? ?==
   :S :	 : ==(mDKs K EK2 ==   &FS &F	&FP ==  ^ ^	^ =="  js j# jXc] j	j> ==(  
 +,A :$ :
: ==!  
 %&a5 :D :
: ==-  
 %&a5QqE :D :T :
: =="  
 *+1 : :
: ==  SC S3 S	S ==  Uc US U	U ===  Ac Ac A	A ==	  5	5rQ   descriptionc                 <     | j                   j                  |fi |S )zDecorator for registering custom actions

		@param description: Describe the LLM what the function does (better description == better function calling)
		)rn   r   )rq   r   kwargss      rO   r   zController.action  s     
 
		k	4V	44rQ   z--multi-actactionsrp   action_validr%   c           	        K   g }|rt        |      D ]  \  }}|j                  | j                  ||       d{          t        j                  d       d{    t
        j                  d|dz    dt        |              |d   j                  s!|d   j                  s|t        |      dz
  k(  s |S  |S t        dd	      gS 7 7 qw)
zExecute multiple actionsNg      ?zExecuted action    r-   zpInvalid action, index is out of the UI Tree. Please use the screenshot to determine the correct pixel to act on.T)r   include_in_memory)	enumerateappendactasynciosleepr/   r0   rf   rx   r   r   )rq   r   rp   r   resultsir   s          rO   	multi_actzController.multi_act  s     
 'g&yq&NN&*:;;<
--

LL#AE7#c'l^<=r{gbk//1Gq8H3H

> ' >  Q  dh  i  j  j <s(   6CC	
 CCAC5CCz--actr   c                   K   	 |j                  d      j                         D ]  \  }}|	| j                  j                  |||       d{   }t	        |t
              rt        |      c S t	        |t              r|c S |t               c S t        dt        |       d|        t               S 7 i# t        $ r:}dt        |       }t        j                  |       t        ||	      cY d}~S d}~ww xY ww)
zExecute an actionT)exclude_unsetN)rp   r~   zInvalid action result type: z of zError executing action: r   )
model_dumpitemsrn   execute_action
isinstancer   r   
ValueErrortyper   r/   r   )rq   r   rp   action_nameparamsr   r   r   s           rO   r   zController.act  s     9$//d/CIIK{FMM00fWg0hhV63F33
V\
*m
.^5d6l^4xPQQ L . i 
 9#CF8	,3	<<
C
889so   D (B: !B: B8!B: 0D 1B: D B: D $B: 7D 8B: :	C=/C82C=3D 8C==D N)T)__name__
__module____qualname__r   r   rr   ro   r   r   r   r   boolr   r   r   r   rV   rQ   rO   rj   rj      s      "-9-B5H5s 5 }%]ajk"j6FjVZj
<j &j$ g9[ 9<L 9Q] 9 9rQ   rj   c                       e Zd ZdZy)r   z2
	Simple parameter model requiring no arguments.
	N)r  r  r  __doc__rV   rQ   rO   r   r     s     rQ   r   )?r   r   typingr   r   r   src.agent.viewsr   r   src.controller.registry.servicer   src.controller.viewsr   r   r	   r
   r   r   r   r   r   r   r   r   src.mac.actionsr   r   r   r   r   r   r   r   src.mac.treer   	src.utilsr   r   pypinyinr   r   r`   ApplicationServicesr    r!   	rapidfuzzr"   r5   r#   r8   	getLoggerr  r/   timer   r   rP   r^   r4   r  r;   rj   r   rV   rQ   rO   <module>r     s         5 4     Y  Y  Y ) ? " 	 [ 2 ,			8	$ Sc S# SlG G Gc c   {9 {9z	[ rQ   