
    q%jm*                        d Z ddlmZ ddl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 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  ej:                  d      ZddZddZ ddZ!ddl"Z"	 d	 	 	 	 	 ddZ#ddZ$y)u  庫柏 SDK 路徑 — LINE 訊息進來的入口。

階段 10-B 重構:
  - 不再每次 LINE 訊息 spawn claude CLI 子程序(75s)
  - 改用 cooper_client_manager 的全域 ClaudeSDKClient(暖機 + 常駐,~5-10s)
  - 工具呼叫的 requester_id 透過 ContextVar 傳(取代每次重建 closure)
  - session_id = "line:<channel_id>" 區分多群組對話狀態

行為對 caller 透明:跟舊版一樣 signature。caller 不用改。
    )annotationsN)date)UUID)select)settings)manager)AsyncSessionLocal)Message)	detect_name_matchdetect_coba_mentionis_in_engagement_dbmark_engagement_build_messages_context_build_rag_context_build_system_prompt_save_coba_message_load_line_image_b64zcoba.ai.sdkc                   g }| D ]  }|j                  dd      }|j                  dd      }t        |t              rg }|D ]o  }t        |t              s|j                  d      dk(  r"|j	                  |j                  dd             J|j                  d      dk(  s_|j	                  d       q d	j                  |      }|d
k(  r|j	                  d|        |j	                  |        dj                  |      S )u   把 anthropic-style messages list 壓成 SDK 用的 single string prompt。

    每則訊息一行,有 [姓名] prefix。圖片暫時 fallback 成「(對方傳了一張圖)」。
    roleusercontent typetextimageu6   (對方傳了一張圖,你目前看不到實際內容)
	assistantu   [庫柏 自己之前說] z

)get
isinstancelistdictappendjoin)claude_messageslinesmr   r   
text_partsblocks          >/volume1/homes/robertsu/coba/app/app/services/coba_chat_sdk.py_flatten_history_to_promptr*   (   s    
 EuuVV$%%	2&gt$J eT*yy(F2"))%))FB*?@6*g5"))*bc ! ii
+G;LL4WI>?LL!   ;;u    c                  K   t         j                  st        j                  d       yddlm} t        j                  dt        |       d       d{    d}d}d}d}g }d}t               4 d{   }		 |	j                  t        t              j                  t        j                  |k(               d{   j                         }
|
r|
j                   r|
j                   nd}|>d	}t#        |	| |       d{   }t%        |	| |       d{    	 ddd      d{    ydd
lm} t+        |	j                  t        |      j                  |j,                  j/                  d      |j0                  j/                  d                   d{   j3                         j5                               }dj7                  d |D              }t9        |	|        d{   }t;        |      }d}|
rt=        | |
j>                         d{   }dtA        jB                         jE                          d| d| }g }	 |	j                  t        t              j                  t        jF                  | k(  t        j0                  j/                  d      t        jH                  dk(        jK                  t        jL                  jO                               jQ                  d             d{   j3                         j5                         }|D ];  }tS        |      dk\  r n+tU        |jV                        }|s+|jY                  |       = |r)|j[                          dtS        |       d}| d| | }n| d| }d|  }|ja                  ||||xs d       d{   }|d   }|d   }|d   }|d   }|d   }	 ddl1m2} t               4 d{   }|jg                   |d ||r|dd! nddt        |       d"|tS        |      d#|||d$k(  rd%n|d&nd'| |d(	d)             |ji                          d{    ddd      d{    t#        |	| |       d{   }
r"|
j                   rtu        | |
j                          t%        |	| |       d{    ddd      d{    y7 W7 ;7 7 7 7 7 *7 7 7 # t\        $ r" t        j_                  d       g }| d| }Y vw xY w7 Y7 )7 7 # 1 d{  7  sw Y   xY w# t\        $ r t        j_                  d*       Y w xY w# t\        $ rv}ddl5}|jm                         }to        d+tq        |      jr                   d,| d| d-       t        j_                  d.       d/tq        |      jr                   d0}Y d}~hd}~ww xY w7 `7 *7 # 1 d{  7  sw Y   yxY ww)1uE   SDK 版本入口:用全域常駐 ClaudeSDKClient 跑 Cooper 對話。u6   CLAUDE_CODE_OAUTH_TOKEN 沒設,跳過庫柏 SDK 回應Nr   )cooper_client_managercoba_typing)r   
channel_idu   (庫柏沒說話)g        u*   (庫柏無法判定誰下令,先不執行))UserTr   c              3  V   K   | ]!  }d |j                    d|j                   d # yw)z- ()N)display_namer   ).0us     r)   	<genexpr>z.coba_respond_to_mention_sdk.<locals>.<genexpr>k   s)     "REqR'7q#BEs   ')r   u   【今日日期】u   

【目前團隊成員】
r   
      u*   

【附圖】我會附上群組裡近期 uX    張圖讓你直接看,請對圖片內容做具體回應(不要說「我看不到」)。u   

【近期對話】
u3   build image blocks 失敗,降級成純文字 promptzline:)prompt_text
session_idrequester_idimage_blocksresponse_textrate_limit_typerate_limit_statustotal_cost_usd
tool_calls)AgentActivityline_responsex   zclaude-sonnet-4-5claude_agent_sdk_persistent	five_hourmax_subscription_5h_pool"max_subscription_5h_pool_inheritedzunknown:)	r/   modelrB   images_sentviar?   r@   billingsdk_inference_cost_usd)activity_typeuser_idsummarysuccessextracost_usdu,   寫 AgentActivity (line_response sdk) 失敗z[COOPER_SDK_FAIL] z: )flushu   Cooper SDK 失敗u$   (庫柏現在抽風了,稍後再試:r3   );r   CLAUDE_CODE_OAUTH_TOKENloggerwarningapp.services.cooper_clientr-   
ws_manager	broadcaststrr	   executer   r
   whereidscalar_one_or_nonerP   r   _broadcast_msgapp.models.userr0   r    	is_activeis_
deleted_atscalarsallr#   r   r*   r   r   r   today	isoformatr/   message_typeorder_by
created_atdesclimitlenr   line_message_idr"   reverse	Exception	exceptionrespondapp.models.agent_activityrC   addcommit	traceback
format_excprintr   __name__r   ) r/   triggered_by_message_idr-   r>   r?   r@   rA   rB   r<   dbtriggered_msgmsgr0   users
team_lineshistory_messageshistory_promptrag_textdynamic_prefixr=   recent_image_msgsr&   r(   
image_notefull_promptr;   resultrC   _adberx   tbs                                    r)   coba_respond_to_mention_sdkr   A   s    ++OP A 

*o    
 (M"&O$(NJ $L ""by	W#%::w%%gjj4K&KL$ !!#  5BmF[F[=00aeL# L.r:}MM$RS999 #""  -

t""4>>#5#5d#;T__=P=PQU=VW! wy E "RE"RRJ%<R%LL78HINH!3J@U@U!VV %TZZ\%;%;%=$> ?--7L*  (*LZ+-::7O))**j8**..t4,,7 hw116689%%), & 79SSU " +A<(A-01B1BCE$++E2 +   ((*Fs<GXFY Z\ ]  &4$44L^L\]g\h"iK%3$44L^L\"]K !-J088'%))1T	 9  F #?3M$%67O &': ;#$45N-J!QC,..$HH]&5 ,7Dds 3" $*-j/%8*4+.|+<#@/>1B $3k#A !; (7'> %I+3O3D)E 7E'* "%5 8 ++-''; /.R 'r:}EE]22J(=(=>RS111A #"" # N9 #"
  M
 W&,  Z  !VW!!/ 00HHXYZ /: (; /...<  Q  !OPQ  	W%%'B&tAw'7'7&81#RtDDQ01B47CSCSBTTUVM	W F 	2A #"""s  AWR*W2R-3W6W8AT99R0:AT9<R3=T9R6T9W"R9#W(A*T9R<
AT9R?,T9S1T9>B+S)S*AS7AS<!T9S6T9<TS9TA"T 6S<7T ;TS>TWV;8WV>WW$W%W-W0T93T96T99W<T9?T9T9S'S3/T92S33T99T<T >T T	T	T	TT63T95T66T99	V8A+V3-W3V88W>WWW
WWWc                   K   ddl m}m}m}m}  |||        d {   } || |||            }t        j                   |dt        |      |d             d {    y 7 E7 w)Nr   )_build_read_by_get_channel_read_states_serialize_message_ws_safemessage_new)r   r/   message)app.api.messagesr   r   r   r   rZ   r[   r\   )	r}   r/   r   r   r   r   r   member_reads
serializeds	            r)   ra   ra      sq       2*bAAL#C\)JKJ


x*o)      Bs!   A%A!?A%A#A%#A%c                    t        |      r t        j                  t        | |             y |y t        j                  t	        | ||             y N)r   asynciocreate_taskr   "_check_engagement_then_respond_sdk)r/   
message_idr   rP   s       r)   trigger_coba_if_mentioned_sdkr      sD    !7
JOP::zSZ[\r+   c                   K   t               4 d {   }t        | ||       d {   rt        | |       d {    d d d       d {    y 7 >7 +7 7 # 1 d {  7  sw Y   y xY wwr   )r	   r   r   )r/   r   rP   r}   s       r)   r   r      sV      ""b$Z"===-j*EEE #""=E #"""sc   A-AA-AAAAAA-
AA-AAA-A*A!A*&A-)r$   z
list[dict]returnr\   )r/   r   r|   r   r   None)r/   r   r   r   r   )
r/   r   r   r   r   r\   rP   zUUID | Noner   r   )r/   r   r   r   rP   r   r   r   )%__doc__
__future__r   loggingdatetimer   uuidr   
sqlalchemyr   
app.configr   app.core.ws_managerr   rZ   app.databaser	   app.models.channelr
   app.services.coba_chatr   r   r   r   r   r   r   r   r   	getLoggerrW   r*   r   ra   r   r   r    r+   r)   <module>r      s   	 #      5 * &
 
 
 
		=	)2V2r
  IM],/]:E]QU]Fr+   