+
    is(                         ^ RI Ht ^ RIHt ^ RIHt ^ RIHtHt ^ RI	H
t
 ^RIHtHtHt ^RIHtHtHt ^ RIHt ^ R	IHtHt R
 R ltR R lt ! R R]P4                  4      t ! R R]P4                  4      t ! R R]P4                  4      tR# )    )connections)FileSystemStorage)timezone)statusviewsets)Response)ChunkDocumentKnowledgeBase)ChunkSerializerDocumentSerializerKnowledgeBaseSerializer)AgentConfig)_q_identensure_business_cluster_tablesc          
      T    V ^8  d   QhR\         R\        R\         R\         R\        /# )   tablebusiness_id_intdoc_namedoc_urlreturn)strint)formats   "EE:\live-kit-agent\livekit_voicebot\backend\apps\knowledge_base\api.py__annotate__r      s:     ' '''
 ' ' 	'    c           
        \         R,          P                  4       ;_uu_ 4       pVP                  R\        V 4       R24       VP                   Uu. uF  qw^ ,          NK  	  ppRRR4       \        X4      p	\        P                  ! 4       p
R\        T;'       g    R4      RTR\        T;'       g    R4      R	VR
V/pRV	9   d   WR&   RV	9   d   WR&   V Uu. uF  qV	9   g   K  VR8w  g   K  VNK  	  ppV'       g   \        R4      hRP                  R.\        V4      ,          4      pRP                  R V 4       4      pR\        V 4       RV RV R2pV Uu. uF  qV,          NK  	  pp\         R,          P                  4       ;_uu_ 4       pVP                  VV4       VP                  uuRRR4       # u upi   + '       g   i     ELe; iu upi u upi   + '       g   i     R# ; i)z
Insert into `{bid}_knowledgebase` using only columns that exist.
Sets created_at/updated_at explicitly when present (legacy tables may omit DEFAULT).
clusterSELECT * FROM z LIMIT 0Ndoc_id r   r   bot_idbusiness_id
created_at
updated_atidz-knowledgebase table has no insertable columnsz, z%sc              3   8   "   T F  p\        V4      x  K  	  R # 5i)N)r   ).0ks   & r   	<genexpr>)_cluster_kb_insert_row.<locals>.<genexpr>.   s     9[[s   zINSERT INTO z (z
) VALUES ())r   cursorexecuter   descriptionsetr   nowr   
ValueErrorjoinlen	lastrowid)r   r   
bot_id_valr"   r   r   curc	col_namescols_setr3   row_valsr+   insert_keysplaceholderscol_sqlsqlparamss   &&&&&&            r   _cluster_kb_insert_rowrC      s    
Y		&	&	(	(CnXe_$5X>?#&??3?aqTT?	3 
) 9~H
,,.C#fll#H3w}}"%*H x!$x!$&Fhx-1AI11hKFHII99dVc+&667Lii9[99G%)G9J|nA
NC#./;aqkk;F/	Y		&	&	(	(CC }} 
)	(/ 4 
)	(	(" G 0	(	(	(sA   -G F;"G G%G.GGG;G  G	G/	c                0    V ^8  d   QhR\         R\         /# )r   rowr   )dict)r   s   "r   r   r   7   s      4 D r   c                (   \        V 4      pVP                  R4      ;'       g    RVR&   VP                  R4      ;'       g    RVR&   VP                  R4      '       d4   \        VR,          4      P                  R4      '       d   VR,          VR&   V# )zGShape cluster `{bid}_knowledgebase` rows like `Document` API responses.r   r#   namer   	file_pathweb_url)zhttp://zhttps://)rF   getr   
startswith)rE   outs   & r   _normalize_cluster_kb_rowrN   7   s{    
s)C''*%++CKwwy)//RC
wwyc#i.1<<=TUUYIJr   c                   l    ] tR t^At]P
                  P                  4       P                  R4      t]	t
RtR# )KnowledgeBaseViewSet-updated_at N)__name__
__module____qualname____firstlineno__r   objectsallorder_byquerysetr   serializer_class__static_attributes__rR   r   r   rP   rP   A   s'    $$((*33MBH.r   rP   c                      a a ] tR t^Ft o]P
                  P                  R4      P                  4       P                  R4      t	]
tV 3R ltV 3R ltV 3R ltR tRtVtV ;t# )DocumentViewSetknowledge_baserQ   c                   < VP                   P                  R4      pVP                   P                  R4      pVR9  d   VR9  d    \        V4      p\        V4      p\        V4       V R2p\        R,          P                  4       ;_uu_ 4       p	V	P                  R\        V4       R2V.4       V	P                   U
u. uF  q^ ,          NK  	  pp
V	P                  4        Uu. uF   p\        \        \        W4      4      4      NK"  	  ppRRR4       \        X4      # \$        SV `L  ! V.VO5/ VB # u up
i u upi   + '       g   i     L9; i  \         d3   p\        RR	R
\        T4      /\         P"                  R7      u Rp?# Rp?ii ; i)z}
With `business_id` + `bot_id`, list rows from cluster `{business_id}_knowledgebase`.
Otherwise list master `Document` rows.
r%   r$   N_knowledgebaser    r!   z# WHERE bot_id = %s ORDER BY id DESCmessagez0Failed to load knowledge documents from cluster.errorr   Nr#   )query_paramsrK   r   r   r   r/   r0   r   r1   fetchallrN   rF   zipr   	Exceptionr   r   HTTP_500_INTERNAL_SERVER_ERRORsuperlist)selfrequestargskwargsbid_rawbot_rawbidr$   r   r9   r:   colsrrowse	__class__s   &&*,           r   rl   DocumentViewSet.listJ   si   
 &&**=9&&**84*$)C'lW.s3%~. +2244KK(%(99\] +.//:/QaDD/D:SVS_S_SabSaa5d3t<6HISaDb 5  ~% w|G5d5f55 ;b 54   RT[]`ab]cd!@@ sU   A	E /D=?D3D=$&D8
D=E 3
D==E	E F'FFFc           
     (  < VP                   P                  R 4      pVP                  R4      pVR9  d   Ve    \        V4      p\        V4       V R2p\        R,          P                  4       ;_uu_ 4       pVP                  R\        V4       R2V.4       VP                  4       p	V	'       g(   \        RR/\        P                  R	7      uuRRR4       # VP                   U
u. uF  q^ ,          NK  	  pp
RRR4       \        \        \        \        XX	4      4      4      4      # \&        SV `P  ! V.VO5/ VB # u up
i   + '       g   i     LP; i  \          d3   p\        R
RR\#        T4      /\        P$                  R	7      u Rp?# Rp?ii ; i)r%   pkNra   r    r!    WHERE id = %sdetailz
Not found.rd   rb   z%Failed to load document from cluster.rc   re   )rf   rK   r   r   r   r/   r0   r   fetchoner   r   HTTP_404_NOT_FOUNDr1   rN   rF   rh   ri   r   rj   rk   retrieve)rm   rn   ro   rp   rq   r{   rs   r   r9   rE   r:   rt   rw   rx   s   &&*,         r   r   DocumentViewSet.retrievef   s\   &&**=9ZZ*$'l.s3%~. +2244KK.%0A PSURVW,,.C'<(@IbIbc	 54
 +.//:/QaDD/D: 5   9$s4~:N OPP w9$9&99 ; 54   GRUVWRXY!@@ sT   >E 8AE
E E&D<7E9.E <EE	E F'FFFc           	       < VP                   P                  R 4      ;'       g    VP                  P                  R 4      pVP                  R4      pVR9  d   Ve    \        V4      p\	        V4       V R2p\
        R,          P                  4       ;_uu_ 4       pVP                  R\        V4       R2V.4       RRR4       \        \        P                  R7      # \        S
V `@  ! V.VO5/ VB #   + '       g   i     L>; i  \         d3   p	\        RR	R
\        T	4      /\        P                  R7      u Rp	?	# Rp	?	ii ; i)r%   r{   Nra   r    zDELETE FROM r|   rd   rb   z'Failed to delete document from cluster.rc   re   )rf   rK   datar   r   r   r/   r0   r   r   r   HTTP_204_NO_CONTENTri   r   rj   rk   destroy)rm   rn   ro   rp   rq   r{   rs   r   r9   rw   rx   s   &&*,      r   r   DocumentViewSet.destroy|   s   &&**=9\\W\\=M=Mm=\ZZ*$'l.s3%~. +2244KK,x.?~ NQSPTU 5v'A'ABB ww8888 54   I7TWXYTZ[!@@ s6   >D !C2<!D 2D	=D E'D=7E=Ec                   VP                   P                  4       pVP                  R4      pVR$9  Ed    \        V4      pTP                  R4      pTP                  R4      p\        TP                  R4      ;'       g    R4      p	TP                  P                  R	4      p
\        T4       T R
2pRpT
e   \        T4      p\        T;'       g-    \        \        P                  ! 4       P                  4       4      4      p\        4       pTP!                  RT RT RT
P"                   2T
4      p\%        TR4      '       d   TP'                  T4      MTpM`\        TP                  R4      ;'       g5    TP                  R4      ;'       g    TP                  R4      ;'       g    R4      ;'       g    Rp\        T;'       g    R4      P)                  4       R8w  d   \        T4      MRp\+        TTTTT	\        T;'       g    R4      4      p\,        R,          P/                  4       ;_uu_ 4       pTP1                  R\3        T4       R2T.4       TP5                  4       pTP6                   Uu. uF  pT^ ,          NK  	  ppRRR4       \9        \;        \=        XX4      4      4      pTP                  R4      ;'       g    T
'       d   R	MRTR&   RTR&   T P?                  RTP                  R4      /4      p\        T\        P@                  TR7      # VP                  R4      pVP                  R4      pVP                  R4      pVR%9   d   RpVR%9  dF    \B        PD                  PG                  R4      P                  \        V4      R7      pVPH                  pVfE   \L        PD                  PO                  R\        P                  ! 4       PQ                  4        2R7      pVPR                  VR&   VP                  P                  R	4      p
V
Ee   \        VP                  R4      ;'       g    R4      p\        T;'       g-    \        \        P                  ! 4       P                  4       4      4      p\        4       pVP!                  RV RV RV
P"                   2V
4      p\%        VR4      '       d   VP'                  V4      MTVR&   VP                  R4      ;'       g    \U        V
RR4      ;'       g    RVR&   VP                  R4      ;'       g    \U        V
R R4      VR&   V PW                  VR!7      pVPY                  R"R#7       V P[                  V4       V P?                  VP                   4      p\        VP                   \        P@                  VR7      #   \        \
        3 d"    \        RR./\        P                  R7      u # i ; iu upi   + '       g   i     EL_; i  \J         d    Rp ELai ; i)&z
With `business_id`: store metadata + file path only in cluster `{business_id}_knowledgebase`
(livekitvoicebot_cluster). Skips master `Document` / `KnowledgeBase` rows.

Without `business_id`: legacy master-DB behavior.
r%   Nr#   zInvalid business_id.rd   r$   r"   rH   filera   zkb_uploads//_urlrI   rJ   r   r    r!   r|   source_typer_   r(   )r   headers)r{   zKB )rH   unknown	mime_typecontent_type	file_sizesize)r   T)raise_exceptionre   )Nr#   r   0).r   copyrK   r   	TypeErrorr4   r   r   HTTP_400_BAD_REQUESTr   FILESr   r   r3   	timestampr   saverH   hasattrr   striprC   r   r/   r0   r   r~   r1   rN   rF   rh   get_success_headersHTTP_201_CREATEDr   rW   select_relatedr_   ri   r   create	isoformatr{   getattrget_serializeris_validperform_create)rm   rn   ro   rp   r   business_id_rawr   
bot_id_rawr"   r   uploadedr   r   rs   safe_prefixstorage
saved_namer8   new_idr9   fetchedr:   rt   rE   r   kb_valkb_objbot
serializers   &&*,                         r   r   DocumentViewSet.create   s&    ||  "((=1+-"%o"6 (+JXXh'F488F+11r2H}}((0H*?;&'~6EG#/*!&"K"KC0H0H0J,KL+-$\\KuAk]!HMM?*[]ef
5<We5L5L'++j1R\ -aa)1DaaQZH[aa_ab   
 -0
0@0@b,A,G,G,IR,OZUYJ+GMMr"F Y'..00CnXe_,=^LvhW,,.&)oo6o!o6 1
 ,DT71C,DEC!%-!8!_!_xVU^C$(C !..cggdm/DEGC(?(?QQ *+XXh'
(#''F!33"%--<<=MNRRVYZdVeRfC //F ~&..55SAYAYA[@\;]5^%+YYD!"==$$V,dhh}-::;CfGGHLLN,D,D,F(GHK')G C5+a&WYabJ;B7E;R;RJ 7XbD $ 5 d d>[]9^ d dbdD $ 5 X X6SW9XD((d(3
D1J'**:??;
0G0GQXYY_ z* "%;$<=!66 P 7 100, ! "!F"sB   V  1?W0WWAW.  /WWWW+	.W?>W?rR   )rS   rT   rU   rV   r
   rW   r   rX   rY   rZ   r   r[   rl   r   r   r   r\   __classdictcell____classcell__)rx   __classdict__s   @@r   r^   r^   F   sT     ../?@DDFOOP]^H)68:,9$\Z \Zr   r^   c                       ] tR t^t]P
                  P                  RR4      P                  4       P                  R4      t	]
tRtR# )ChunkViewSetr_   documentz-idrR   N)rS   rT   rU   rV   r	   rW   r   rX   rY   rZ   r   r[   r\   rR   r   r   r   r      s4    }}++,<jIMMOXXY^_H&r   r   N)	django.dbr   django.core.files.storager   django.utilsr   rest_frameworkr   r   rest_framework.responser   modelsr	   r
   r   serializersr   r   r   apps.agents.modelsr   apps.cluster.dynamic_tablesr   r   rC   rN   ModelViewSetrP   r^   r   rR   r   r   <module>r      sl    ! 7 ! + , 2 2 U U * P'T/800 /
dZh++ dZN'8(( 'r   