
     *i                     &   d Z ddlZddlZddl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  ej$                  d	      Zg d
Zd ed      j-                  d eD               dZdedee   fdZdeddfdZdeddfdZdeddfdZy)u  
Coba 自動標籤服務(階段 3e)。

每則新訊息都會被丟給 Haiku 4.5 做分類,產生 1-3 個 tag。

設計原則:
  - 用 Haiku(便宜、快、足夠準)
  - 標準 tag 集合(讓 filter pill 穩定)+ 可動態加 entity tag(人名 / 專案名)
  - 庫柏自己的訊息不重新標(它生成時就會帶 tag)
  - 失敗時靜默忽略(tag 不是核心功能,不影響對話)
    N)UUID)select)settings)manager)AsyncSessionLocal)Messagezcoba.tagger)u   📢 公告u   🆘 求助u   💡 靈感u   🤝 客戶u   📌 決策u   🚀 進度   💬 閒聊u   你是分類助手。讀使用者訊息,產出 JSON 陣列形式的標籤。

【規則】
1. 從以下「類型標籤」**只選 1 個**(就算同時像兩種,也只選最主要的):

   c              #   &   K   | ]	  }d |   yw)z   - N ).0ts     </volume1/homes/robertsu/coba/app/app/services/coba_tagger.py	<genexpr>r   -   s     6#5aaSk#5s   ue  

2. 額外可以加 0-2 個「實體標籤」(人名、客戶名、專案名、技術名、產品名等)。
   實體標籤不要 emoji,純文字。例如:客戶A、React、Q4預算、阿明

【輸出格式】嚴格 JSON 陣列,不要 markdown,不要解釋。範例:

訊息「客戶 A 剛回信說合約要修第三條」
回:["📢 公告", "客戶A", "合約"]

訊息「我 useEffect 噴 warning 怎解」
回:["🆘 求助", "React"]

訊息「今天好累哈哈」
回:["💬 閒聊"]

訊息「我覺得我們的定位應該調整成 B2B」
回:["💡 靈感", "定位"]

只回陣列,不要其他字。
rawreturnc                 J   | j                         } t        j                  d| t        j                        }|sg S 	 t	        j
                  |j                  d            }t        |t              sg S g }|D ]R  }t        |t              s|j                         s%t        |      dk  s4|j                  |j                                T t               }g }|D ])  }||vs|j                  |       |j                  |       + |dd S # t        j                  $ r g cY S w xY w)u7   容錯地把 Haiku 回傳的字串解析成 tag list。z\[.*?\])flagsr      N   )stripresearchDOTALLjsonloadsgroupJSONDecodeError
isinstanceliststrlenappendsetadd)r   mresultcleaneditemseenoutr   s           r   _parse_tagsr,   D   s    
))+C
		*c3A	AGGAJ' fd#	GdC TZZ\c$i2oNN4::<(  5D
CD=HHQKJJqM  r7N!  	s   $D
 
D"!D"
message_idc                 2  K   t         j                  syt               4 d{   }|j                  t	        t
              j                  t
        j                  | k(               d{   j                         }||j                  r	 ddd      d{    y|j                  	 ddd      d{    yt        |j                  j                               dk  rEdg|_	        |j                          d{    t        |       d{    	 ddd      d{    y	 t!        j"                  t         j                        }|j$                  j'                  t         j(                  dt*        d|j                  dg       d{   }d	j-                  d
 |j                  D              }t/        |      }|sdg}||_	        |j                          d{    t        |       d{    |j0                  }|j2                  dz  dz  |j4                  dz  dz  z   }t6        j9                  dt;        |       dd ||j2                  |j4                  |       	 ddlm}	 t               4 d{   }
|
jA                   |	d|j                  ddj-                  |       dt;        |       |d|             |
j                          d{    ddd      d{    ddd      d{    y7 7 7 h7 M7 	7 7 7 7 37 #7 7 E7 7# 1 d{  7  sw Y   GxY w# tB        $ r t6        jE                  d       Y jw xY w# tB        $ r }t6        jG                  d|       Y d}~d}~ww xY w7 # 1 d{  7  sw Y   yxY ww)u>   背景任務:把 Haiku 標好的 tags 寫回訊息 + 廣播。N   r	   )api_key   user)rolecontent)model
max_tokenssystemmessages c              3   T   K   | ]   }|j                   d k(  s|j                   " yw)textN)typer;   )r   bs     r   r   ztag_message.<locals>.<genexpr>}   s"     O*:Qaff>N!&&*:s   ((i@B g      ?g      @z,tag msg=%s tags=%s tokens=%d/%d cost=US$%.6f   r   )AgentActivityauto_tagu   標籤:z, T)r-   tags)activity_typeuser_idsummarysuccessextracost_usdu#   寫 AgentActivity (auto_tag) 失敗ztag failed: %s)$r   ANTHROPIC_API_KEYr   executer   r   whereidscalar_one_or_nonerA   rC   r"   r4   r   commit_broadcast_tags	anthropicAsyncAnthropicr8   createCLAUDE_MODEL_HAIKUTAG_SYSTEM_PROMPTjoinr,   usageinput_tokensoutput_tokensloggerinfor!   app.models.agent_activityr?   r%   	Exception	exceptionwarning)r-   dbmsgclientresponser   rA   rU   costr?   _adbes               r   tag_messagere   `   s    %% ""bZZ7O!!'**
":;
 
 	 ;#(( #"" ;; #"" s{{  "#q(%CH))+!#&&& #"" &	0--h6P6PQF#__3311(#)ckkBC	 4  H ''O(*:*:OOCs#D%CH))+!#&&&NNE&&2c9U=P=PS\=\`c<ccDKK>J#T5+=+=u?R?RTX
HC,..$HH]&0 #")$))D/): ; $-0_dK!%  ++-'' /.S #""
 #" & #$ & / ( /...  H  !FGH 	0NN+Q//	0k #"""s   NK7NAN(K:)!N
NK=NN(N3L 4N9AN:L;NLNNL	N%A&MLAMLM/L0A/M L04L5L08ALLLL0!L"L0&N1N 2N:N=N NNN	NMMML0LL0L-	!L$"L-	)L00MMMM	M=M83N8M==N NNN	NNr_   c                    K   t        j                  dt        | j                        t        | j                        | j
                  xs g d       d{    y7 w)uC   廣播 message_tagged event(前端依此即時更新 tag 顯示)。message_tagged)r<   
channel_idr-   rA   N)
ws_manager	broadcastr!   rh   rK   rA   )r_   s    r   rN   rN      sH     


 #..)#&&kB	    s   AAAAc                 @    ddl }|j                  t        |              y)u-   同步入口,起背景任務不阻塞 HTTP。r   N)asynciocreate_taskre   )r-   rl   s     r   trigger_taggingrn      s    J/0    )__doc__r   loggingr   uuidr   rO   
sqlalchemyr   
app.configr   app.core.ws_managerr   ri   app.databaser   app.models.channelr   	getLoggerrX   STANDARD_TYPE_TAGSchrrT   rS   r!   r    r,   re   rN   rn   r   ro   r   <module>r{      s   
   	     5 * & 
		=	)  R6#566 7 8	 6S T#Y 8;0$ ;04 ;0|w 4 1 1 1ro   