
    Rh6'                     8   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dl
mZmZmZmZ d dlmZmZ d dlmZ d dlmZmZmZmZ  e         ej2                  d      Z ej2                  d	      Z ej2                  d
d      ZdZdZdZdZ  G d d      Z!y)    N)load_dotenv)OpenAI)STORMWikiRunnerArgumentsSTORMWikiRunnerSTORMWikiLMConfigstruncate_filename)OpenAIModelDeepSeekModel)SerperRM)create_manifestread_txt_fileread_json_filesplit_markdown_sectionsOPENAI_API_KEYAPP_URLOUTPUT_FOLDERz./result
imscc_tempwiki_contentzgpt-3.5-turbozgpt-4oc                   v    e Zd ZdefdZd Zd Zd Zd Zd Z	dde
fd	Zd
 ZdefdZdefdZdededefdZy)StormRunnertopicc                    || _         t        |j                  dd      j                  dd            | _        t        j
                  j                  t        | j                        | _        t        j
                  j                  | j                  t              | _
        t	        j                  t        d       t	        j                  | j                  d       t        j
                  j                  t        | j                        }t        j
                  j                  |d      | _        t        j
                  j                  t        | j                   d      | _        t        j
                  j                  |d      | _        t	        j                   d	      d
k(  r| j#                         }n| j%                         }t'        t              }t)        t	        j                   d      dddd      }t+        |||      | _        y )N _/T)exist_okzstorm_gen_article_polished.txt.imscczurl_to_info.json
LLM_ENGINEDEEPSEEK)
output_dirSERPER_API_KEY
      )autocorrectnumpage)serper_search_api_keyquery_params)r   r   replacearticle_titleospathjoinworking_dirarticle_dircontent_dirwiki_content_dirmakedirsr   polished_article_pathoutput_pathurl_to_infogetenvdeepseek_infoopenai_infor   r   r   runner)selfr   	file_path
lm_configsengine_argsrms         3/var/www/html/sandstorm/dependencies/StormRunner.py__init__zStormRunner.__init__)   sm   
.MM#s#++C5
 77<<T5G5GH "T-=-={ K
K$/
D))D9GGLL0B0BC	%'WW\\)=]%^"77<<$:L:L9MV7TU77<<	3EF99\"j0++-J))+J.( "$)),<"=)-b!D
 &k*R@    c                    t        j                  d      ddd}t               }t        } |dt        dd|} |dt        dd|} |dt
        dd|} |dt
        dd|} |dt
        d	d|}|j                  |       |j                  |       |j                  |       |j                  |       |j                  |       t        t        t        
      }	|S )Nr         ??)api_keytemperaturetop_p  model
max_tokens      )rE   rJ    )r+   r6   r   r	   gpt_35_model_namegpt_4_model_nameset_conv_simulator_lmset_question_asker_lmset_outline_gen_lmset_article_gen_lmset_article_polish_lmr   )
r:   openai_kwargsr<   
ModelClassconv_simulator_lmquestion_asker_lmoutline_gen_lmarticle_gen_lmarticle_polish_lmrJ   s
             r?   r8   zStormRunner.openai_infoG   s   yy!12
 ()
 
& 
#
7D
 ' 
#
7D
 $\*:s\m\#\*:s\m\& 
"t
7D
 	(():;(():;%%n5%%n5(():; N:KLrA   c                 j   t               }t        j                  d      t        j                  dd      ddd}t        dt        j                  d      dd	|}t        dt        j                  d      dd	|}t        dt        j                  d      d
d	|}t        dt        j                  d      dd	|}t        dt        j                  d      dd	|}|j	                  |       |j                  |       |j                  |       |j                  |       |j                  |       |S )NDEEPSEEK_API_KEYDEEPSEEK_API_BASEzhttps://api.deepseek.comrC   rD   )rE   api_baserF   rG   DEEPSEEK_MODELrH   rI   rL   rM   rN   rO   )	r   r+   r6   r
   rR   rS   rT   rU   rV   )r:   r<   deepseek_kwargsrY   rZ   r[   r\   r]   s           r?   r7   zStormRunner.deepseek_infof   s@   ')
yy!34		"57QR	
 * 
)),-#
AP
 * 
)),-#
AP
 'lRYY7G-HUXl\kl&lRYY7G-HUXl\kl) 
)),-$
BQ
 	(():;(():;%%n5%%n5(():;rA   c                     | j                   j                  | j                        }|}t        j                  j                  || j                   d      }| j                         }|S )N)r   r   )r9   runr   r+   r,   r-   r*   generate_imscc)r:   resultr;   imscc_file_nameimscc_file_paths        r?   process_articlezStormRunner.process_article   s^     ** ! 
 	'',,yT5G5G4H2OP--/rA   c           	          | j                   }| j                          t        j                  j	                  | j
                        st        dd      | j                          t        || j                  t        t        j                  j                  | j                  d             t        j                  | j                  dt        j                         5 }t        j"                  | j                        D ]j  \  }}}|D ]_  }t        j                  j                  ||      }t        j                  j%                  || j                        }|j'                  ||       a l 	 ddd       | j                  S # 1 sw Y   | j                  S xY w)	zE
        Generate an IMSCC package from the article content.
          5Article not found. Please generate the article first.status_codedetailzimsmanifest.xml)course_titler0   wiki_diroutput_filew)startN)r   save_sections_as_htmlr+   r,   existsr3   HTTPExceptionprepare_article_questionr   r1   r0   r-   r/   zipfileZipFiler4   ZIP_DEFLATEDwalkrelpathwrite)	r:   r*   zfrootr   filesfile	full_patharcnames	            r?   rf   zStormRunner.generate_imscc   s8    

""$ww~~d889C8opp%%' 	&-- T%5%57HI		
 __T--sG4H4HI 	1R"$''$*?*?"@ 1a! 1D "T4 8I ggooit?T?ToUGHHY011	1 	1 s   BE99Fc                 *   t        | j                        }t        |      }|D ]  }|j                         }|s|d   j	                  d      j	                         }|j                         j                  dd       d}| j                  ||      }t        j                  j                  | j                  |      }t        |dd      5 }	|	j                  |       d	d	d	        t        d
t        |       d| j                          y	# 1 sw Y   xY w)zi
        Reads a markdown file, splits it into sections, and saves each section as an HTML file.
        r   z# r   r   .htmlrt   utf-8encodingNu   ✅ Exported z sections to: )r   r3   r   
splitlinesstriplowerr)   markdown_to_htmlr+   r,   r-   r1   openr   printlen)
r:   contentsectionssectionlines
title_linefilenamehtmlr4   outs
             r?   rv   z!StormRunner.save_sections_as_html   s       : :;*73 	 G&&(Eq-335J$**,44S#>?uEH((W=D'',,t'<'<hGKk39  S		$   	  	c(m_N4;P;P:QRS   s   D		D	num_questionsc                     t        | j                        }d| d| d}t               }|j                  j                  j                  dd|dgd      }|j                  d	   j                  j                  S )
Nz/
        Given the following article, generate a   quiz questions including:
        - Descriptive
        - Multiple choice (with 4 options)
        - Single choice
        - Fill in the blank
        - Optional (True/False)

        Format each question like:
        Type: <type>
        Question: <text>
        Options: <A, B, C, D> (only if applicable)
        Answer: <correct or expected answer>

        Article:
        """
        z
        """
        zgpt-4user)roler   gffffff?)rJ   messagesrF   r   )	r   r3   r   chatcompletionscreatechoicesmessager   )r:   r   article_textpromptopenai_clientresponses         r?   generate_questions_from_articlez+StormRunner.generate_questions_from_article   s    $T%?%?@//<o >	 
 	!& h %%1188%&9: 9 
 "**222rA   c                    t        | j                        }| j                  |      }d| j                  j	                         j                  dd       d}| j                  | j                  |      }t        j                  j                  | j                  |      }t        |dd      5 }|j                  |       ddd       y# 1 sw Y   yxY w)	zS
        Read the polished article content and generate questions from it.
        
questions_r   r   r   rt   r   r   N)r   r3   r   r*   r   r)   r   r+   r,   r-   r1   r   r   )r:   article_content	questionsquestion_filenamer   r4   r   s          r?   ry   z$StormRunner.prepare_article_question   s     ((B(BC88I	(););)A)A)C)K)KCQT)U(VV[\$$T%7%7Cggll4#8#8:KL+sW5 	IIdO	 	 	s   )CCreturnc                     t         j                  j                  | j                        st	        dd      t        | j                        S )zN
        Read the polished article content and return it as a string.
        rl   rm   rn   )r+   r,   rw   r3   rx   r   r:   s    r?   get_article_contentzStormRunner.get_article_content   s9     ww~~d889C8oppT7788rA   c                     t         j                  j                  | j                        st	        dd      t        | j                        S )zB
        Read the URL to info mapping from the JSON file.
        rl   zAURL to info mapping not found. Please generate the article first.rn   )r+   r,   rw   r5   rx   r   r   s    r?   get_url_to_infozStormRunner.get_url_to_info  s9     ww~~d../C8{||d..//rA   titler   c                 F    t        j                   |g d      }d| d| dS )N)extra
codehilitetablestoc)
extensionszL<html>
        <head>
            <meta charset="utf-8">
            <title>z4</title>
        </head>
        <body>
            z)
        </body>
        </html>
        )markdown)r:   r   r   	body_htmls       r?   r   zStormRunner.markdown_to_html  s<    %%g:bc	 7  K 		 		rA   N)r"   )__name__
__module____qualname__strr@   r8   r7   rj   rf   rv   intr   ry   r   dictr   r   rO   rA   r?   r   r   (   so    Ac A<>>
 BT63S 3@ 9S 90 0c C C rA   r   )"sysr+   uuidjsonrz   r   dotenvr   openair   knowledge_stormr   r   r   r   knowledge_storm.lmr	   r
   knowledge_storm.rmr   dependencies.helperr   r   r   r   r6   r   r   r   r.   r0   rP   rQ   r   rO   rA   r?   <module>r      s    
 	        :  +,
"))I
		/:6 $  r rrA   