
    iV                     F   d Z ddlZddlZddlmZ ddl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 ddlmZ d	Zd
ZdZdZdedeeef   fdZdedeeef   fdZdedeeef   fdZdedeeef   ddfdZdedeeef   dedefdZ	 dFdee ed      f   dee ed      f   dee ed      f   dee ed      f   d eeef   dz  defd!Z 	 dFd eeef   dz  defd"Z!	 dFdee ed#      f   d eeef   dz  defd$Z"	 dFdee ed%      f   d&ee	e    ed'      f   d eeef   dz  defd(Z#dede	e   fd)Z$ded*e	e   ddfd+Z%d,edee&ef   fd-Z'd*e	e   d.edee&e&f   fd/Z(	 dFd eeef   dz  defd0Z)	 dFdee ed1      f   d eeef   dz  defd2Z*	 dFd eeef   dz  defd3Z+	 dFdee ed4      f   d5ee& ed6      f   d7ee ed8      f   d eeef   dz  def
d9Z,	 dFdee ed:      f   d7ee ed;      f   d eeef   dz  defd<Z-	 dFdee ed=      f   d7ee ed>      f   d eeef   dz  defd?Z.	 dFd@ee	e    edA      f   d eeef   dz  defdBZ/	 dFdee edC      f   d eeef   dz  defdDZ0	 dFd eeef   dz  de	e   fdEZ1y)Gz=Deep research tools for search results and report management.    N)Path)	AnnotatedAnyDictListOptionalTuple)FileLock)MessageBlockMessageBlockType)FileToolContext)	ParamMetaz!deep_research/search_results.jsonz!deep_research/search_results.lockzdeep_research/report.mdzdeep_research/report.lockctxreturnc                 ^    | j                  t              }| j                  t              }||fS N)resolve_under_workspaceSEARCH_RESULTS_FILEREPORT_FILE)r   search_filereport_files      U/Users/bowang/.openclaw/workspace/ChatDev/functions/function_calling/deep_research.py
_get_filesr      s.    --.ABK--k:K##    c                 ^    | j                  t              }| j                  t              }||fS r   )r   SEARCH_LOCK_FILEREPORT_LOCK_FILE)r   search_lockreport_locks      r   
_get_locksr       s/    --.>?K--.>?K##r   	file_pathc                     | j                         si S 	 t        j                  | j                  d            S # t        j                  $ r i cY S w xY wNutf-8encoding)existsjsonloads	read_textJSONDecodeErrorr!   s    r   _load_search_resultsr-   !   sO    	zz)--w-?@@ 	s   $9 AAdatac                     | j                   j                  dd       | j                  t        j                  |dd      d       y )NTparentsexist_ok   F)indentensure_asciir$   r%   )parentmkdir
write_textr(   dumps)r!   r.   s     r   _save_search_resultsr:   *   s<    4$7DGRYZr   urlconcisec                 B   |j                  dg       }|rddj                  |       dnd}|r0d|  | d|j                  dd       d	|j                  d
d       dd 	S d|  | d|j                  dd       d	|j                  d
d       d|j                  dd       dd S )Nhighlight_keysz [IMPORTANT MATCHES: z, ] zURL: z
Title: titlez
Abstract: abs
z(----------------------------------------z	
Detail: detail)getjoin)r;   r.   r<   keyshighlight_strs        r   _format_search_resultrI   /   s    88$b)DBF+DIIdO+<A>BMC5 (hhw+, -%,-Rj	
 C5 (hhw+, -%,- .xx"-.bj		
r   z&URL of the search result (used as key))descriptionrA   zTitle of the search resultrB   zAbstract/Summary of the contentrD   zDetailed content_contextc                 $   t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }	|	j                  | i       }
|
j                  dg       }||||d|	| <   t        ||	       ddd       d|  S # 1 sw Y   xY w)z)
    Save or update a search result.
    r>   )rA   rB   rD   r>   NzSaved result for )r   r   r    r
   r-   rE   r:   )r;   rA   rB   rD   rK   r   r   _r   r.   currentr>   s               r   search_save_resultrO   D   s     (
#C_NK_NK	+	#K0((3# !%5r: ,	
S	 	[$/ 
 se$$ 
	s   ABBc                 <   t        |       }t        |      \  }}t        |      \  }}t        |      5  t	        |      }ddd       syg }|j                         D ]"  \  }}|j                  t        ||d             $ dj                  |      S # 1 sw Y   TxY w)z(
    Load all saved search results.
    NzNo search results found.Tr<   z

)	r   r   r    r
   r-   itemsappendrI   rF   )	rK   r   r   rM   r   r.   resultsr;   contents	            r   search_load_allrV   d   s     (
#C_NK_NK	+	#K0 
 )G

W,S'4HI % ;;w 
	s   BBzURL to retrievec                     t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }ddd       | vrd|  S t        | ||    d      S # 1 sw Y   #xY w)z/
    Load a specific search result by URL.
    NzNo result found for FrQ   )r   r   r    r
   r-   rI   )r;   rK   r   r   rM   r   r.   s          r   search_load_by_urlrX   |   sq     (
#C_NK_NK	+	#K0 
 $%cU++ d3i?? 
	s   A!!A*zURL to highlight keys forrG   zList of keys/terms to highlightc                    t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }| |vrd|  dcddd       S t        ||    j                  dg             }|j                  |       t        |      ||    d<   t        ||       ddd       d|  dt               S # 1 sw Y   xY w)z=
    Save highlighted keys for a specific search result.
    zURL z, not found in results. Please save it first.Nr>   zUpdated highlights for z: )
r   r   r    r
   r-   setrE   updatelistr:   )	r;   rG   rK   r   r   rM   r   r.   current_keyss	            r   search_high_light_keyr^      s     (
#C_NK_NK	+	#K0d?#JK	 
	 49==)92>?D!&*<&8S	"#[$/ 
 %SED,>+?@@ 
	s   B7AB77C c                 f    | j                         sg S | j                  d      j                         S r#   )r'   r*   
splitlinesr,   s    r   _read_report_linesra      s0    	0;;==r   linesc                     | j                   j                  dd       dj                  |      }|r|j                  d      s|dz  }| j	                  |d       y )NTr0   rC   r$   r%   )r6   r7   rF   endswithr8   )r!   rb   rU   s      r   _save_reportre      sU    4$7iiGw''-473r   linec                     t        j                  d|       }|r9t        |j                  d            |j                  d      j	                         fS y)z9Returns (level, title) if line is a header, else (0, "").z^(#+)\s+(.+)$   r3   )r   r@   )rematchlengroupstrip)rf   rj   s     r   _parse_headerrn      sB    HH%t,E5;;q>"EKKN$8$8$:::r   
title_pathc                    |j                  d      D cg c]  }|j                          }}d}d}d}t        |      D ]_  \  }}d}	t        |t	        |             D ]<  }
t        | |
         \  }}|dkD  s||k(  s |
dz   }d}	|t	        |      dz
  k(  r|
}|} n |	r_ y |dk(  ryt	        |       }t        |dz   t	        |             D ]%  }
t        | |
         \  }}|dkD  s||k  s |
} ||fS  ||fS c c}w )zz
    Find the start and end indices (inclusive, exclusive) of a chapter.
    title_path is like "Chapter 1/Section 2"
    /r   Frh   T)rr   rr   )splitrm   	enumeraterangerk   rn   )rb   ro   ttitlescurrent_level_idx	start_idxsearch_startitarget_titlefoundidxleveltextend_idxrM   s                  r   _find_chapter_ranger      s5   
 ",!1!1#!67!6Aaggi!6F7I L$V,<s5z2C'c
3KE4qyT\1"QwFa' #I(-% 3  -" B %jGY]CJ/ s,q19"33Gg 0 gG 8s   C5c                     t        |       }t        |      \  }}t        |      \  }}t        |      5  |j	                         s
	 ddd       y|j                  d      cddd       S # 1 sw Y   yxY w)z1
    Read the current content of the report.
    NzReport is empty.r$   r%   )r   r   r    r
   r'   r*   )rK   r   rM   r   r   s        r   report_readr      sf     (
#C_NA{_NA{	+	!!#% 
	 $$g$6 
		s   A)A))A2zJChapter title to read (supports multi-level index e.g. 'Intro/Background')c                    t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }t        ||       \  }}|dk(  rd|  dcddd       S dj                  ||dz   |       cddd       S # 1 sw Y   yxY w)z1
    Read the content of a specific chapter.
    rr   	Chapter '' not found.Nz\nrh   )r   r   r    r
   ra   r   rF   	rA   rK   r   rM   r   r   rb   startends	            r   report_read_chapterr      s     (
#C_NA{_NA{	+	";/(6
sB;ug\2 
	 zz%a,- 
		s   %B"BBc                 :   t        |       }t        |      \  }}t        |      \  }}t        |      5  t	        |      }ddd       g }D ]/  }t        |      \  }}	|dkD  s|j                  d|z   d|	        1 |sydj                  |      S # 1 sw Y   SxY w)z2
    Get the outline of the report (headers).
    Nr   # zNo headers found in report.rC   )r   r   r    r
   ra   rn   rS   rF   )
rK   r   rM   r   r   rb   outlinerf   r   rA   s
             r   report_outliner     s     (
#C_NA{_NA{	+	";/ 
 G$T*u19NNcEk]!E734 
 ,99W 
	s   BBzChapter title (supports 'Parent/NewChild' to insert into existing). Use '|' to specify insertion point e.g. 'Prev|New' to insert after 'Prev', or '|New' to insert at start.r   zHeader level (1-6)rU   zContent of the chapterc                 2   t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }d}	| }
dt        |      }}d| v r=| j                  dd      \  }	}t        ||	      \  }}|dk(  rd|	 d| dcddd       S |}
d}d|
v r|
j                  dd      \  }}|}
|}d}|||d	k(  rF|	rA|}t        |dz   t        |            D ]#  }||k\  r n`t        ||         \  }}|d
kD  s!|} nE nCd
}n@|}|	r|	 d| }t        ||      \  }}|dk(  rd| dcddd       S |}n|	r|n
t        |      }d|z   d|
 }|g|j                         z   d	gz   }|||| t        ||       ddd       	r|	 d
 n
}d| d| S # 1 sw Y   xY w)z-
    Create a new chapter in the report.
    Nrr   rq   rh   zParent chapter 'z' not found. Cannot create 'z' inside it.|r@   r   zTarget chapter 'r   r   r   zCreated chapter 'z' at level )r   r   r    r
   ra   rk   rsplitr   rs   ru   rn   r`   re   )rA   r   rU   rK   r   rM   r   r   rb   parent_pathdisplay_titlep_startp_end	new_titleinsert_after_targettarget
real_title
insert_idxr~   lvlsearch_targeta_starta_endheadernew_section
final_paths                             r   report_create_chapterr   -  s)    (
#C_NA{_NA{	+	";/ SZ%<%*\\#q%9"K0DNGU"})+6RS\R]]ij 
	  &M #-!.!4!4S!!<FJ&M"( 
*"b(!&J  %Wq[#e*=%<!!.uSz!:Q7),J!  > "#J !4(3}A6I5J%K]!4UM!Jb=-m_LIw 
	x #
 #.3u:J%K=-1h!3!3!55< (3j$[%(O 
R 6AK=-1mJzl+eW==U 
	s    AFA&F6-F-AFFzMChapter title to rewrite (supports multi-level index e.g. 'Intro/Background')zNew contentc                 P   t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }t        ||       \  }}	|dk(  rd|  dcddd       S ||   g|j                         z   dgz   }
|
|||	 t        ||       ddd       d|  dS # 1 sw Y   xY w)z5
    Rewrite the content of an existing chapter.
    rr   r   r   Nr@   zRewrote chapter ''r   r   r    r
   ra   r   r`   re   )rA   rU   rK   r   rM   r   r   rb   r   r   new_bodys              r   report_rewrite_chapterr     s     (
#C_NA{_NA{	+	";/(6
sB;ug\2 
	 %L>G$6$6$88B4? $eC[%( 
 ugQ'' 
	s   %B",BB%zOChapter title to append to (supports multi-level index e.g. 'Intro/Background')zContent to appendc                 B   t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }t        ||       \  }}	|dk(  rd|  dcddd       S |j                         dgz   }
|
||	|	 t        ||       ddd       d|  dS # 1 sw Y   xY w)z0
    Append content to an existing chapter.
    rr   r   r   Nr@   zAppended content to chapter 'r   r   )rA   rU   rK   r   rM   r   r   rb   r   r   	new_liness              r   report_continue_chapterr     s     (
#C_NA{_NA{	+	";/(6
sB;ug\2 
	 &&(B4/	"c#[%( 
 +5'33 
	s   %B"%BB	new_orderz/List of chapter titles in the new desired orderc           
         t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }g }t        |       D ]D  \  }}	t        ||	      \  }
}|
dk(  rd|	 dc cddd       S |j                  ||	||
| |
|d       F t        |d       }t        t        |      dz
        D ]4  }||   }||dz      }|d	   |d
   kD  sd|d    d|d    dc cddd       S  g }d}t        |      D ]:  \  }}|j                  |||d
           ||   }|j                  |d          |d	   }< |j                  ||d        t        ||       ddd       y# 1 sw Y   yxY w)a   
    Reorder chapters in the report.
    This swaps the positions of the specified chapters, preserving their content and valid text between them.
    All specified chapters must exist and must not overlap (e.g. cannot reorder a parent and its child).
    rr   r   r   N)target_order_idxrA   rU   r   r   c                     | d   S )Nr    )xs    r   <lambda>z)report_reorder_chapters.<locals>.<lambda>  s    '
r   )keyrh   r   r   z
Chapters 'rA   z' and 'z9' overlap. Cannot reorder nested or overlapping chapters.r   rU   z Reordered chapters successfully.)r   r   r    r
   ra   rt   r   rS   sortedru   rk   extendre   )r   rK   r   rM   r   r   rb   chaptersr{   rA   sechapters_sorted_by_poscurrnext_chresult_linescurrent_idxkoriginal_slot_holderdesired_chapters                       r   report_reorder_chaptersr     s    (
#C_NA{_NA{	+	";/ !),HAu&ue4DAqBw"5'66 
	 OO$% 1: 	 - "(6J!K s12Q67A)!,D,QqS1GE{WW--#DM?''':J9K  LE  F  F3 
	* 8 '01G'H#A#k4H4Q RS 'qkO	 :;.u5K (I 	E+,/0[,/[ 
^ ._ 
^ .s   :E$7AE$E$.A-E$$E-zLChapter title to delete (supports multi-level index e.g. 'Intro/Background')c                    t        |      }t        |      \  }}t        |      \  }}t        |      5  t	        |      }t        ||       \  }}|dk(  rd|  dcddd       S |||= t        ||       ddd       d|  dS # 1 sw Y   xY w)z+
    Delete a chapter and its content.
    rr   r   r   NzDeleted chapter 'r   )r   r   r    r
   ra   r   re   r   s	            r   report_del_chapterr     s     (
#C_NA{_NA{	+	";/(6
sB;ug\2 
	 %)[%( 
 ugQ'' 
	s   %B"BB
c                 r   t        |       }t        |      \  }}t        |      \  }}t        |      5  |j	                         st        d      |j                  d      }ddd       t        j                  dd      }t        j                  dd|      }	 ddl	}dd	l
m} |j                  d      }g d}	|j                  ||	      }
d|
 d}	 t        |d      5 }|j                  ||      }ddd       j                   rt#        d      	 |j&                  j)                  |t*        j,                  |j.                  dddddt1        |      d      }|j3                         gS # 1 sw Y   
xY w# t        $ r t        d
      w xY w# 1 sw Y   xY w# t$        $ r}t#        d|       d}~ww xY w)z#
    Export the report to PDF.
    zReport file does not exist.r$   r%   Nz([^\n])\n(#{1,6}\s)z\1\n\n\2z9(?m)^(?!\s*(?:[*+-]|\d+\.)\s)(.+)\n(\s*(?:[*+-]|\d+\.)\s)r   )pisazBError: strict dependencies 'markdown' and 'xhtml2pdf' are missing.z.pdf)extra
codehilitenl2brtables)
extensionsa  
        <html>
        <head>
            <style>
                @page {
                    size: A4;
                    margin: 2cm;
                }
                body { 
                    font-family: sans-serif; 
                    line-height: 1.6; 
                    font-size: 10pt;
                    word-wrap: break-word; 
                    word-break: break-all;
                }
                h1, h2, h3 { 
                    color: #2c3e50; 
                    margin-top: 25px; /* Add spacing above the title */
                    margin-bottom: 15px; 
                    border-bottom: 1px solid #eee; /* Add an underline to the main title for clarity */
                    padding-bottom: 5px;
                }

                /* --- Table style fixes --- */
                table {
                    width: 100%;
                    border-collapse: collapse;
                    margin-bottom: 20px;
                    border: 1px solid #ddd;
                }
                th, td {
                    border: 1px solid #ddd; /* Explicitly add borders */
                    padding: 8px;
                    text-align: left;
                    vertical-align: top;
                }
                th {
                    background-color: #f2f2f2;
                    font-weight: bold;
                    color: #333;
                }
                /* ------------------ */

                code { background-color: #f4f4f4; padding: 2px 5px; border-radius: 3px; font-family: monospace; }
                pre { background-color: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; white-space: pre-wrap; }
                ul, ol { margin-top: 8px; margin-bottom: 8px; padding-left: 20px; }
                li { margin-bottom: 4px; }
                blockquote { border-left: 4px solid #ccc; padding-left: 10px; color: #666; margin: 10px 0; }
            </style>
        </head>
        <body>
            z)
        </body>
        </html>
        wb)destz'Failed to generate PDF: xhtml2pdf errorzFailed to generate PDF: zapplication/pdfFTgenerated_report)sourceworkspace_path)kinddisplay_name	mime_type	copy_filepersistdeduplicater   )r   r   r    r
   r'   FileNotFoundErrorr*   ri   submarkdown	xhtml2pdfr   ImportErrorwith_suffixopen	CreatePDFerrRuntimeError	Exceptionattachment_storeregister_filer   FILEnamestras_message_block)rK   r   rM   r   r   r   r   r   pdf_filer   html_contentstyled_htmlfpisa_statusr   records                   r   report_export_pdfr     s    (
#C_NA{_NA{	+	!!##$ABB$$g$6 

 66(+t<D66NP[]abD
" &&v.H <J$$Tj$AL3f N 	g6Kr;(D!Q..1.=K " ??HII 
 !!//""]]#(!(m
 0 F ##%&&K 
	  
P
 	

J "!
  ;5aS9::;sG   .E)
E6 F F1F )E36FFF 	F6#F11F6r   )2__doc__r(   ri   pathlibr   typingr   r   r   r   r   r	   filelockr
   entity.messagesr   r   functions.function_calling.filer   utils.function_catalogr   r   r   r   r   r   r    r   r-   r:   boolrI   rO   rV   rX   r^   ra   re   intrn   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      sR   C  	  > >  : ; , : 6 '. $O $dDj(9 $$O $dDj(9 $D T#s(^ [D [S#X [4 [

s 
$sCx. 
4 
C 
4 '+%	3	.VWW	X%S)0LMMN% 
3	.OPP	Q% c91CDDE	%
 38nt#% 	%D '+ 38nt#  	 4 '+@	3	.?@@	A@38nt#@ 	@. '+A	3	.IJJ	KA
DIy5VWW
XA 38nt#A 		A8>$ >49 >4D 4c 4t 4 c3h (tCy (c (eCHo (X '+738nt#77$ '+.S)0|}}~.38nt#. 	.0 '+38nt#8 '+	W>S)  1_  `  `  aW>S)0DEEFW> sI2JKKLW> 38nt#	W>
 	W>z '+(S)0  A  A  B(sI-@@A( 38nt#( 		(B '+4S)  1B  C  C  D4sI2EFFG4 38nt#4 		4: '+<.cI:k$llm<.38nt#<. 	<.B '+(S)0~  A(38nt#( 	(0 '+o'38nt#o'	,o'r   