o
    g#l                     @   s  d 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
 ddlmZ ddlmZ ddlmZ dd	lmZmZ ejd
 ddlZddlmZmZmZmZm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(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 e  ddgZ4eeedZ5e6e7e58dZ9e: Z;G dd dZ<e=dkrdddgZ>e>D ]2Z?ddl@Z@e'jAe?d d ZBe@@ ZCe<eBe-e?d! D d"ZEe@@ ZCeEF  e@@ ZGeHeGeC  qdS dS )#"Service to generate PPT structure.    N)load_dotenv)ChatPromptTemplate)InMemoryDocstore)FAISSDocument)JsonOutputParser)
ChatOpenAIOpenAIEmbeddings.)EMBEDDING_MODELOPENAI_API_KEY	OPENAI_EFOPENAI_MODEL_4OOPENAI_MODEL_MINI)
LLMResults)	CreatePPT)PresentationOutlineSection_LLMSectionLLMWithSlidesSlideLLM)ProjectSectionSlide)presentation_types)ClientConfig)DynamoDB)redis_cache)
parsed_urlpublicprivate)modelapi_keyzhello worldc                   @   s  e Zd ZdZeededZeededZ	dZ
eZeZdGdedefdd	Zd
d Zdd Zdee fddZdd Zdedee dee defddZdee fddZdedefddZdefddZd d! Zd"d# Zd$ee defd%d&Zd'd( Zd)e deded*e!fd+d,Z"defd-d.Z#d/d0 Z$d1d2 Z%e&d3d4d5d6 Z'e&d3d4d7d8 Z(dGd9d:Z)d;d< Z*d=ed>efd?d@Z+dAdB Z,e-dCe.dDee fdEdFZ/dS )HPPTStructurer   g333333?r"   temperaturer#   z:services/ppt_generator/content_slide_layout_choices_v5.txtNprojectclientc                 C   s   |j tvr	td|j| jvrtdd| j  || _|  | _	|| _
| j
jdur1| j
jn| j| _| j
rB| j
j| jjdnd| _t| jddd}| | _W d   n1 s]w   Y  |   dS )zInitialize the service.z.public_status must be either public or privatezpitch_type must be , Nrzutf-8)encoding)public_statusPUBLIC_STATUS
ValueError
pitch_typeadditional_instructionsjoinkeysr'   get_main_companymain_companyclient_configlayout_choicesLAYOUT_CHOICESstructure_recommendationgetopenreadcontent_slide_layout_choicesget_project_docs)selfr'   r(   file r@   </var/www/html/XCapMarket/services/ppt_generator/structure.py__init__A   s.   



	zPPTStructure.__init__c                 C   s@   |   \| _}|  \| _}tttt i d| _| 	|| dS )z"Get the documents for the project.)embedding_functionindexdocstoreindex_to_docstore_idN)
 get_uploaded_documents_summariesproject_doc_summariesget_website_summariesproject_website_summariesr   
embeddingsrD   r   	doc_store_create_vector_storer>   docswebsitesr@   r@   rA   r=   e   s   zPPTStructure.get_project_docsc                 C   s
   | j  S )z&Add or update the structure in the DB.)r'   update_project_in_dbr>   r@   r@   rA   add_or_update_project_in_dbs   s   
z(PPTStructure.add_or_update_project_in_dbreturnc                 C   s  g d}| j rd| j }|dd| f | jr*d| j}|dd| f | jr8|dd| j f | jjdkrD|d n|d	 |d
 t|}t	t
d}|| jB |B }|| jj| jj| jjro| jjn| jd | jjr{| jjn| jd | jj| jd | jd | jj| jv r| j| jj nd| d	}zdd |d D | j_W n ttfy   |d d | j_Y nw |   dS )zGet the structure of the PPT.))systemal  
                    You are an Investment Banking Managing Director creating a slide deck outline.

                    The structure of the deck should be broken into sections which will contain different slides.

                    Don't include an introduction section. Always include a company and market overview section.

                    Each section should have multiple slides and a slide should only cover one topic.

                    You want to ensure you have an executive overivew section to start and a financial overview at the end.

                    {additional_instructions}
                )rU   zYou will answer in json format which will be provided below. You are only being tasked to provide the structure                    (sections) of the PPT with the theme or content that should be included in each section.)humanzYou are pitching {company}, more information on the company is provided below, which is {public_status} in the {industry} and sector {sector} options for {pitch_type}.)rV   zuCompany overview is below 
 {company_overview} 

 Company product and services overview is below 
 {company_products}

rV   z2Here are the summaries of the uploaded documents: z'Here are the summaries of the website: z;Ensure the sections could cover the slides from this list: ib)rV   z*You are going to limit your sections to 8.)rV   z*You are going to limit your sections to 5.)rU   z,You will answer in json format {json_format}pydantic_objectindustrysectoroverviewproducts )	companyr,   r[   r\   r/   company_overviewcompany_productsr0   json_formatc                 S      g | ]	}t d i |qS r@   )r   .0sectionr@   r@   rA   
<listcomp>   s    z.PPTStructure.get_structure.<locals>.<listcomp>sections
propertiesN)rH   r1   appendrJ   r8   r5   client_typer   from_messagesr	   r   
llm_model4invoker'   company_namer,   r[   r4   r\   r/   r0   get_format_instructionsrj   KeyErrorr.   rS   )r>   llm_messagerH   rJ   chat_promptparserchainresponser@   r@   rA   get_structurew   sl   






zPPTStructure.get_structurec              	      s   g }t  jjD ]G\}}dtdtt dtt f fdd}|dkr, jjd|d  ng }|t jjd k rB jj|d d ng }|t|||| q	tj	| I dH   j
  dS )	z#Flesh out the structure of the PPT.rh   previous_sectionsnext_sectionsc              
      s   zt d| j  | ||I dH  t d| j W dS  tyN } z(t d|  tjd|dd t| dddurCd| _W Y d}~dS W Y d}~dS d}~ww )	zFlesh out the section.zfleshing sectionNzfleshed out sectionzError in fleshing out section: !Error in fleshing out section: %sTexc_infoslides)printtitleflesh_out_sectionAttributeError
XCM_loggererrorgetattrr   )rh   rz   r{   erR   r@   rA   r      s"   
z:PPTStructure.flesh_out_sections.<locals>.flesh_out_sectionr   N   )	enumerater'   rj   r   listlenrl   asynciocreate_taskgatherrQ   )r>   tasksirh   r   rz   r{   r@   rR   rA   flesh_out_sections   s,    
zPPTStructure.flesh_out_sectionsrh   rz   r{   c                    sv  g d}|rd dd |D }|dd| df |r3d dd |D }|dd	| df | jjd
kr?|d n|d t|}ttd}tt	dt
d}	||	B |B }
|
| jjre| jjn| jd | jjrq| jjn| jd | jj| jj| jd |j|j| || d	I dH }zdd |d D |_|W S  ttfy } ztd| jj d|j |d}~ww )z"Flesh out this section of the PPT.))rU   zYou are an Investment Banking Managing Director who is an expert in the {industry}. Specifically, you are an expert in the {sector} sector.)rU   zjYou are going to be given a section of a {pitch_type} presentation and you are going to help flesh it out.)rU   z#One slide can only have one topic. )rU   z.You will return a json object as {json_output})rV   zTCompany you are working with is {company} with the products / services of {products})rV   zThe section you are working on is: {section_title} and the content of the section should be: {section_content}. Don't overlap with other sections.)rV   zYIn addition to your knowledge, you have the following documents to reference: {documents}r)   c                 S      g | ]}|j qS r@   r   rf   r@   r@   rA   ri   .      z2PPTStructure.flesh_out_section.<locals>.<listcomp>rV   z!The previous section titles are: z+. Don't overlap slides with other sections.c                 S   r   r@   r   rf   r@   r@   rA   ri   8  r   zThe next section titles are: rX   )rV   zTYou are going to limit your slides to 10 per section but you don't need all of them.)rV   zWYou are going to limit your slides to 10 per section but you don't need to all of them.rY   r   r%   r[   r\   r^   )	r[   r\   r/   r`   r^   section_titlesection_content	documentsjson_outputNc                 S   rd   re   )r   rg   slider@   r@   rA   ri   o  s    r   z*Error in fleshing out section for project z
, section )r1   rl   r5   rm   r   rn   r	   r   r
   r   r   ainvoker'   r[   r4   r\   r/   rq   r   contentfind_relevant_summaryrr   r   rs   r.   r   
project_id)r>   rh   rz   r{   prompt_messagesprevious_sections_strnext_sections_strpromptrv   llm_rw   rx   excr@   r@   rA   r     st   






zPPTStructure.flesh_out_sectionsectionsLLMc                    sn   g }t |D ]-\}}| |r| ||I dH }n| |I dH }tdd |jD r/d|_|| q|S )zWFlesh out new or updated sections and slides. Adds modification flags to track changes.Nc                 s   s    | ]	}t |d dV  qdS )
isModifiedFNr   r   r@   r@   rA   	<genexpr>  s    z5PPTStructure.flesh_out_new_section.<locals>.<genexpr>T)r   _is_item_modified_process_modified_section_process_existing_sectionanyr   r   rl   )r>   r   updatedSectionsr   rh   r@   r@   rA   flesh_out_new_sectionw  s   
z"PPTStructure.flesh_out_new_sectionrD   c              
      s   z:|dkr| j jd| ng }|t| j jd k r$| j j|d d ng }| j|||dI dH }| | d|_W |S  tym } z&td| tj	d|dd t
|d	ddurbd|_W Y d}~|S W Y d}~|S d}~ww )
z!Process a new or updated section.r   Nr   )rh   rz   r{   TzError in fleshing out section:r|   r}   r   )r'   rj   r   r   _clear_modification_flagsr   	Exceptionr   r   r   r   r   )r>   rh   rD   rz   r{   r   r@   r@   rA   r     s2   



z&PPTStructure._process_modified_sectionc                    s   t |dds	|S t fdd|jD du r|S g }t|jD ]\}} |r1|||d q  ||I dH }|D ]-}|d du rMd|j|d < q=|d	  |d  kr^d
|d _ 	|d |j|d < q=|S )z:Process existing section with potentially modified slides.r   Nc                 3   s    | ]}  |V  qd S )N)r   r   rR   r@   rA   r     s    z9PPTStructure._process_existing_section.<locals>.<genexpr>F)rD   r   outputrD   r   T)
r   r   r   r   r   rl   flesh_out_slidesdictr   r   )r>   rh   slide_tasksrD   r   
slide_taskr@   rR   rA   r     s,   
z&PPTStructure._process_existing_sectionc                 C   s   t |ddpt |ddS )z!Check if slide is new or updated.isNewF	isUpdatedr   )r>   itemr@   r@   rA   r     s   zPPTStructure._is_item_modifiedc                 C   s"   dD ]}t ||rt|| q|S )zFClear new/updated flags from an item but preserve modification status.)r   r   )hasattrdelattr)r>   r   flagr@   r@   rA   r     s
   

z&PPTStructure._clear_modification_flagsr   c                    s     }t|}ttd ttdtd}||B  B }| fdd|D I dH }t	|D ]8\}}	ztdi || |	d< W q1 t
yi }
 ztjd|	d	 jjjj|
d
d d|	d< W Y d}
~
q1d}
~
ww |S )z#Flesh out a batch of slides slides.rY   g      ?)openai_api_keyr&   
model_namec                    s$   g | ]} |d  |d  qS )r   rD   )_get_slide_chain_inputs)rg   r   rv   rh   r>   r@   rA   ri     s    z1PPTStructure.flesh_out_slides.<locals>.<listcomp>Nr   zKError in fleshing out slide: %s in section %s in Project %s. 
 Error was %sr   Tr}   r@   )_build_slide_prompt_messagesr   rn   r	   r   r
   r   r   abatchr   r   r   r   r   r'   r   )r>   r   rh   r   ru   llmrw   rx   r   r   r   r@   r   rA   r     s>   


	zPPTStructure.flesh_out_slidesc                 C   s@   dd| j j d| j j dfddg}|g d |d |S )	z+Build prompt messages for slide generation.rU   z,You are an investment banking expert in the z industry and the z sector.)rU   zZYou are going to be provided with guidance on how to create a new slide in a presentation.)rV   zThe section you are working on is: {section_title} and the content of the section is: {section_content}.                 Ensure this slide doesn't overlap with other slides in the section.))rV   zYou are going to be adding a brand new slide which is titled: {slide_title} and should contain the following content: {slide_content})rV   z6The slides before this one are titled: {slides_before})rV   z4The slides after this one are titled: {slides_after})rV   zFMake sure this slide doesn't overlap with other slides in the section.)rU   z2You will respond in a json object as {json_output})r'   r[   r\   extendrl   )r>   messagesr@   r@   rA   r     s   z)PPTStructure._build_slide_prompt_messagesr   rv   c                 C   s   |dkrdd |j d| D ng }|t|j d k r)dd |j |d d D ng }|j|j|j|jd|d|| dS )	z*Get inputs for the slide generation chain.r   c                 S   r   r@   r   rg   sr@   r@   rA   ri   '  r   z8PPTStructure._get_slide_chain_inputs.<locals>.<listcomp>Nr   c                 S   r   r@   r   r   r@   r@   rA   ri   )  r   z; )r   r   slide_titleslide_contentslides_beforeslides_afterr   )r   r   r   r   r1   rr   )r>   r   rh   rD   rv   previous_slidesnext_slidesr@   r@   rA   r   #  s   $z$PPTStructure._get_slide_chain_inputsc                 C   s4   | j jd|j d|j dd}ddd |D S )zFind the relevant summary.zSection title: z and Section content: mmr)querysearch_typerW   c                 S   r   r@   )page_content)rg   resultr@   r@   rA   ri   @  r   z6PPTStructure.find_relevant_summary.<locals>.<listcomp>)rL   searchr   r   r1   )r>   rh   resultsr@   r@   rA   r   8  s
   z"PPTStructure.find_relevant_summaryc                 C   s   t | j| j| j}| }|S )z"Create the PPT from the structure.)r   r'   r4   r5   convert_structure_to_ppt)r>   ppt_creatordeck_locationr@   r@   rA   
create_PPTB  s   zPPTStructure.create_PPTc                 C   s   t  }t| jjj}||j|}||j|}tdi |}d|d< d|d< |j	D ]}|j
dkr6|j|d< |j
dkr@|j|d< q*|S )zGet the main company.r_   r]   r^   Overview_StatsProductsNr@   )r   r   r'   company_urlurlget_itemcompany_info_table	llm_tabler   LLM_resultscategoryrx   )r>   dbr   r4   llm_info_itemr@   r@   rA   r3   H  s   




zPPTStructure.get_main_companyi  )ttlc                 C   sH   ddl m} t }||j| jj}g }|D ]	}||d  q||fS )z$Get the uploaded document summaries.r   Attrdoc_summary)boto3.dynamodb.conditionsr   r   query_itemsproject_docsr'   r   rl   )r>   r   r   r   doc_summariesdocr@   r@   rA   rG   \  s   z-PPTStructure.get_uploaded_documents_summariesc                 C   sJ   ddl m} t }|j|jd| jj|d| jjd}dd |D |fS )zGet the website summaries.r   r   zproject_id-indexr   )table
index_namesort_key_valueexpression_valuesc                 S   s   g | ]}| d dqS )summaryr_   )r9   )rg   websiter@   r@   rA   ri   v  s    z6PPTStructure.get_website_summaries.<locals>.<listcomp>)r   r   r   query_index	web_pagesr'   r   eq)r>   r   r   rP   r@   r@   rA   rI   j  s   z"PPTStructure.get_website_summariesc                 C   s@   |r| j jdd |D d |r| j jdd |D d dS dS )zCreate the vector store.c                 S   s*   g | ]}t |d  |d |d ddqS )r   	file_namedoc_pathr   r   r   metadatar   )rg   r   r@   r@   rA   ri   |  s    z5PPTStructure._create_vector_store.<locals>.<listcomp>)r   c                 S   s.   g | ]}t |d d|d |d ddqS )r   r_   r   r   r   )r   r9   )rg   siter@   r@   rA   ri     s    
N)rL   add_documentsrN   r@   r@   rA   rM   x  s   
z!PPTStructure._create_vector_storec                 C   sH   t d| jj t| j| j| j}|  |   t d| jj | jS )z&Conduct research for the presentation.z'Conducting research for presentation %sz&Research for presentation %s completed)	r   infor'   r   r   r4   r5   research_presentation_update_project)r>   r   r@   r@   rA   r     s   z"PPTStructure.research_presentationsection_numberslide_numberc                 C   sH   | j j|d  }|j|d  }t| j | j| j}|||_|   |S )zResearch the slide.r   )	r'   rj   r   r   r4   r5   conduct_researchresearchr   )r>   r   r  rh   r   r   r@   r@   rA   research_slide  s   zPPTStructure.research_slidec                 C   s   t di | j | _| jS )z)Update the project into the project classNr@   )r   r'   r   rR   r@   r@   rA   r     s   zPPTStructure._update_projectr   new_sectionsc                 C   s    t j|d}|du rtddS )z"Check if there are any new updatesr   Nz&Project does not exist in the database)r   check_project_in_dbr.   )r>   r   r  r'   r@   r@   rA   _check_new_updates  s   zPPTStructure._check_new_updates)NN)0__name__
__module____qualname____doc__r
   r   r   ro   r   
llm_model3r7   r   r0   r   r   rB   r=   rS   r   r   ry   r   r   r   intr   r   r   r   r   r   r   r   r	   r   r   r   r3   r   rG   rI   rM   r   r  r   staticmethodstrr  r@   r@   r@   rA   r$   1   sl    $k)
l((




	r$   __main__z0iti-digital-1b7107ab-9e73-4590-90ce-1ba6c6b6a791tequity)r   r(   r   r  r(   )r(   )Ir  r   jsonsysfaissdotenvr   langchain.promptsr   &langchain_community.docstore.in_memoryr    langchain_community.vectorstoresr   langchain_core.documentsr   langchain_core.output_parsersr	   langchain_openair
   r   pathrl   loggingconfigs.configr   r   r   r   r   1services.company_profile.data_classes.llm_resultsr   !services.ppt_generator.create_pptr   8services.ppt_generator.data_classes.presentation_outliner   r   r   r   +services.ppt_generator.data_classes.projectr   r   r   )services.ppt_generator.presentation_typesr   utils.client_checkr   utils.dynamo_dbr   utils.redis_cacher   utils.url_parserr   r-   rK   IndexFlatL2r   embed_queryrD   	getLoggerr   r$   r	  projectsproject_detailstimer  r'   startget_client_configppt_structurer   endr   r@   r@   r@   rA   <module>   sn         
