o
    |Žjh8  ã                   @   s¶   d dl Z d dlZd dlZ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 h d£Zdd„ eD ƒZeeed	d
�ZG dd„ dƒZG dd„ deƒZG dd„ deƒZdS )é    N)ÚListÚDictÚOptionalÚAnyÚCallable)ÚOpenAIEmbeddings)ÚFAISS)ÚDocument>   ú	Dairy Altú	Fat / Nutú	Fat / Oilú
Carb / Nutú
Fat / SeedúFat / DairyúFat / SpreadúCarb / LegumeúLegume / CarbúCarb / ProteinúDairy / ProteinúCarb / VegetableúLegume / ProteinúVegetable / CarbúVegetable / cornúFruit / SeasoningÚCarbÚHerbÚDairyÚFruitÚSpiceÚTreatÚProteinÚSeafoodÚBeverageÚ	SweetenerÚ	Vegetablec                 C   s   h | ]}|  ¡ ’qS © )Ústrip)Ú.0Úcr%   r%   úU/home/esfera/Desktop/Rishu/fitness/Fitness-lenito-AI-main/fitness_app/vector_store.pyÚ	<setcomp>   s    r*   T)ÚkeyÚreversec                
   @   s¢   e Zd Zddedefdd„Zededefdd	„ƒZd
ee	 fdd„Z
dd„ Zdefdd„Zdee fdd„Z		ddedeeegef  dedee	 fdd„ZdS )ÚBasePDFVectorStoreútext-embedding-ada-002Ú
index_pathÚembeddings_modelc                 C   s,   || _ t|d�| _d | _tj |d¡| _d S )N)Úmodelzmanifest.json)r/   r   Ú
embeddingsÚvectorstoreÚosÚpathÚjoinÚmanifest_path)Úselfr/   r0   r%   r%   r)   Ú__init__   s   zBasePDFVectorStore.__init__Ú	json_pathÚreturnc                 C   sV   t j | ¡std| › �ƒ‚t| ddd��}t |¡W  d   ƒ S 1 s$w   Y  d S )NzJSON file not found: Úrzutf-8)Úencoding)r4   r5   ÚexistsÚFileNotFoundErrorÚopenÚjsonÚload)r:   Úfr%   r%   r)   Ú_load_json_data$   s
   $ÿz"BasePDFVectorStore._load_json_dataÚ	documentsc                 C   s>   t  || j¡| _tjtj | j¡pddd� | j 	| j¡ d S )NÚ.T)Úexist_ok)
r   Úfrom_documentsr2   r3   r4   Úmakedirsr5   Údirnamer/   Ú
save_local)r8   rE   r%   r%   r)   Ú_build_faiss_from_docs+   s   z)BasePDFVectorStore._build_faiss_from_docsc                 C   s,   t j | j¡rtj| j| jdd�| _dS dS )NT)Úallow_dangerous_deserializationF)r4   r5   r>   r/   r   Ú
load_localr2   r3   )r8   r%   r%   r)   Ú_load_faiss_index0   s   þz$BasePDFVectorStore._load_faiss_indexÚinfoc                 C   sB   t | jdƒ�}tj||dd� W d   ƒ d S 1 sw   Y  d S )NÚwé   )Úindent)r@   r7   rA   Údump)r8   rP   rC   r%   r%   r)   Ú_save_manifest9   s   "ÿz!BasePDFVectorStore._save_manifestc                 C   sH   t j | j¡r"t| jdƒ�}t |¡W  d   ƒ S 1 sw   Y  d S )Nr<   )r4   r5   r>   r7   r@   rA   rB   )r8   rC   r%   r%   r)   Ú_load_manifest=   s
    ÿz!BasePDFVectorStore._load_manifestNé   ÚqueryÚ	filter_fnÚkc                 Ã   s&   �t  ¡ }| d | jj|||¡I d H S ©N)ÚasyncioÚget_running_loopÚrun_in_executorr3   Úsimilarity_search)r8   rX   rY   rZ   Úloopr%   r%   r)   Ú_similarity_search_asyncC   s
   €
ÿz+BasePDFVectorStore._similarity_search_async)r.   )NrW   )Ú__name__Ú
__module__Ú__qualname__Ústrr9   ÚstaticmethodÚlistrD   r   r	   rL   rO   ÚdictrU   r   rV   r   r   ÚboolÚintra   r%   r%   r%   r)   r-      s&    		üþýüûr-   c                       s4  e Zd Zd$def‡ fdd„Z		d%dedefd	d
„Zdefdd„Zdefdd„Z	dede
e fdd„Z		d&dedededededede
e fdd„Z					d'dededededededede
e fdd„Z			d(dededededede
e fd d!„Z			d(dededededede
e fd"d#„Z‡  ZS ))ÚMealGenVectorStoreÚfaiss_mealgenr/   c                    s   t ƒ  |¡ i | _d S r[   )Úsuperr9   Ú	food_dict©r8   r/   ©Ú	__class__r%   r)   r9   S   s   
zMealGenVectorStore.__init__ú'diet/meal_generation/mealgen_foods.jsonFr:   Úforce_rebuildc              
   C   s  |p|   ¡  }|sM|  ¡ }|rM| d¡|krMz| d¡tj |¡kr2td| j› �ƒ |  |¡ W dS W n t	yL } ztd|› �ƒ W Y d}~nd}~ww td|› d�ƒ |  
|¡}|  |¡}|  |¡ |  |¡ |tj |¡t ¡ dœ}|  |¡ td	t|ƒ› d
�ƒ dS )zBLoad JSON and build lookup dict + FAISS index for semantic search.r:   Ú
json_mtimeõ%   âœ… Loaded existing FAISS index from Nõ"   âš ï¸� Load failed, will rebuild: u    ðŸ”„ Building hybrid store from ú ...©r:   rt   Ú	timestampu   âœ… Hybrid store ready: z docs indexed, dict populated.)rO   rV   Úgetr4   r5   ÚgetmtimeÚprintr/   Ú_populate_dict_from_jsonÚ	ExceptionrD   Ú_create_documentsrL   Ú_populate_dict_from_rawÚtimerU   Úlen©r8   r:   rs   Úneed_rebuildÚmanifestÚeÚraw_datarE   r%   r%   r)   Úload_or_create_indexX   s2   
ý€ÿ




ý
z'MealGenVectorStore.load_or_create_indexc                 C   ó   |   |¡}|  |¡ d S r[   )rD   r€   ©r8   r:   r‡   r%   r%   r)   r}   v   ó   
z+MealGenVectorStore._populate_dict_from_jsonr‡   c                 C   sT   | j  ¡  |D ] }|d }|d }|d }| j  |i ¡ |i ¡ |g ¡ |¡ qdS )uL   Build fast lookup: blood â†’ diet â†’ classification â†’ list of food dicts.Ú
blood_typeÚ	diet_typeÚclassificationN)rn   ÚclearÚ
setdefaultÚappend)r8   r‡   ÚitemÚbÚdr(   r%   r%   r)   r€   z   s   
&üz*MealGenVectorStore._populate_dict_from_rawr;   c                 C   sn   g }|D ]0}dd|d |d |d |d |d |d |d	 |d
 |d dœ}t  |¡}| t||d�¡ q|S )NrA   Ú	food_itemrŒ   r�   rŽ   Ú	food_nameÚcategoryÚpriorityÚ	breakfastÚlunchÚdinner)ÚsourceÚsection_typerŒ   r�   rŽ   r–   r—   r˜   r™   rš   r›   ©Úpage_contentÚmetadata)rA   Údumpsr‘   r	   )r8   r‡   Údocsr’   r    Úcontentr%   r%   r)   r   ƒ   s"   õ
z$MealGenVectorStore._create_documentsNÚbloodÚdietrŽ   r—   Úmealr˜   c           
      C   sx   | j  |i ¡ |i ¡ |g ¡}g }|D ]&}	|r|	 d¡|krq|r*|	 |d¡dkr*q|r4|	 d¡|kr4q| |	¡ q|S )zQGet all foods matching blood, diet, classification from dict, then apply filters.r—   ÚMediumÚLowr˜   )rn   rz   r‘   )
r8   r¤   r¥   rŽ   r—   r¦   r˜   Ú	base_listÚresultÚfoodr%   r%   r)   Ú_get_matching_foodsš   s   z&MealGenVectorStore._get_matching_foodséd   Úlimitc              	   Ã   sˆ   �|r|   ||||||¡}n|   ||d|||¡|   ||d|||¡ }tƒ }	g }
|D ]}|d |	vr=|	 |d ¡ |
 |¡ q)|
d|… S )zCMain retrieval: uses dict for exact filters, returns up to `limit`.Ú
beneficialÚneutralr–   N)r¬   ÚsetÚaddr‘   )r8   r¤   r¥   rŽ   r—   r¦   r˜   r®   ÚfoodsÚseenÚuniquerC   r%   r%   r)   Ú	get_foodsª   s   €ÿ
€zMealGenVectorStore.get_foodsc                 Ã   ó   �| j ||d|||d�I d H S )Nr¯   ©r®   ©r¶   ©r8   r¤   r¥   r—   r¦   r®   r%   r%   r)   Úget_beneficial_foodsÁ   ó   €z'MealGenVectorStore.get_beneficial_foodsc                 Ã   r·   )Nr°   r¸   r¹   rº   r%   r%   r)   Úget_neutral_foodsÇ   r¼   z$MealGenVectorStore.get_neutral_foods)rl   )rr   F)NNN)NNNNr­   )NNr­   )rb   rc   rd   re   r9   ri   rˆ   r}   rg   r€   r   r	   r   rh   r¬   rj   r¶   r»   r½   Ú__classcell__r%   r%   rp   r)   rk   R   s~    ÿ
ÿ	þÿÿþ
þûÿþýüû
ûýÿþý
ýýÿþýýrk   c                       sê   e Zd Zd"def‡ fdd„Z		d#dedefd	d
„Zdefdd„Zdefdd„Z	dede
e fdd„Zdedeeeef  fdd„Zdede
e fdd„Zdede
e fdd„Zdede
e fdd„Zd$dedede
e fd d!„Z‡  ZS )%ÚScannerVectorStoreÚfaiss_scannerr/   c                    s(   t ƒ  |¡ i | _i | _i | _i | _d S r[   )rm   r9   Úcompat_dictÚ_beneficial_by_bloodÚ_neutral_by_bloodÚ_avoid_by_bloodro   rp   r%   r)   r9   Ò   s
   
zScannerVectorStore.__init__ú$diet/meal_scanner/scanner_foods.jsonFr:   rs   c              
   C   s  |p|   ¡  }|sM|  ¡ }|rM| d¡|krMz| d¡tj |¡kr2td| j› �ƒ |  |¡ W d S W n t	yL } ztd|› �ƒ W Y d }~nd }~ww td|› d�ƒ |  
|¡}|  |¡}|  |¡ |  |¡ |tj |¡t ¡ dœ}|  |¡ tdt|ƒ› d	�ƒ d S )
Nr:   rt   ru   rv   u(   ðŸ”„ Building hybrid scanner store from rw   rx   u    âœ… Hybrid scanner store ready: z docs, dict populated.)rO   rV   rz   r4   r5   r{   r|   r/   Ú _populate_scanner_dict_from_jsonr~   rD   Ú_create_scanner_documentsrL   Ú_populate_scanner_dict_from_rawr�   rU   r‚   rƒ   r%   r%   r)   rˆ   Ú   s2   
ý€ÿ




ý
z'ScannerVectorStore.load_or_create_indexc                 C   r‰   r[   )rD   rÈ   rŠ   r%   r%   r)   rÆ   ö   r‹   z3ScannerVectorStore._populate_scanner_dict_from_jsonr‡   c           
      C   sö   | j  ¡  |D ]!}|d }|d }|| j | ¡ < | dg ¡D ]	}|| j | ¡ < qqg d¢}|D ]I}g | j|< g | j|< g | j|< | j  ¡ D ]2\}}| |d¡ ¡ }	|	dkr^| j|  |¡ qE|	dkrk| j|  |¡ qE|	dkrw| j|  |¡ qEq/d S )Nr–   ÚcompatibilityÚvariants)ÚOÚAÚBÚABr°   r¯   Úavoid)	rÁ   r�   Úlowerrz   rÂ   rÃ   rÄ   Úitemsr‘   )
r8   r‡   r’   r«   ÚcompatÚvariantÚblood_typesÚbtÚ
food_lowerÚstatusr%   r%   r)   rÈ   ú   s0   
ÿ


€ùüz2ScannerVectorStore._populate_scanner_dict_from_rawr;   c              
   C   s€   g }|D ]9}|d }|  tt |d |dœ¡dd|d dœd�¡ | dg ¡D ]}|  tt ||dœ¡dd|dœd�¡ q'q|S )	NrÉ   r–   )r–   rÉ   rA   Úfood_compatibility)rœ   r�   r–   rž   rÊ   )r‘   r	   rA   r¡   rz   )r8   r‡   r¢   r’   rÒ   rÓ   r%   r%   r)   rÇ     s$   ÿþÿ
þÿz,ScannerVectorStore._create_scanner_documentsr–   c                 Ã   s   �| j  | ¡ ¡S r[   )rÁ   rz   rÐ   )r8   r–   r%   r%   r)   Úget_compatibility(  s   €z$ScannerVectorStore.get_compatibilityrŒ   c                 Ã   ó   �| j  |g ¡S r[   )rÂ   rz   ©r8   rŒ   r%   r%   r)   r»   +  ó   €z'ScannerVectorStore.get_beneficial_foodsc                 Ã   rÚ   r[   )rÃ   rz   rÛ   r%   r%   r)   r½   .  rÜ   z$ScannerVectorStore.get_neutral_foodsc                 Ã   rÚ   r[   )rÄ   rz   rÛ   r%   r%   r)   Úget_avoid_foods1  rÜ   z"ScannerVectorStore.get_avoid_foodsé
   rX   r®   c                 Ã   sf   �| j r	| j jjnd}| j|d|d�I dH }g }|D ]}z| t |j¡¡ W q   Y q|d|… S )z;Semantic search using FAISS (for unknown/misspelled foods).rW   N)rY   rZ   )r3   ÚindexÚntotalra   r‘   rA   ÚloadsrŸ   )r8   rX   r®   rZ   r¢   ÚresultsÚdocr%   r%   r)   Úsearch_foods4  s   €zScannerVectorStore.search_foods)rÀ   )rÅ   F)rÞ   )rb   rc   rd   re   r9   ri   rˆ   rÆ   rg   rÈ   r   r	   rÇ   r   r   rÙ   r»   r½   rÝ   rj   rä   r¾   r%   r%   rp   r)   r¿   Ñ   s    ÿ
ÿ$r¿   )r4   rA   r�   r\   Útypingr   r   r   r   r   Úlangchain_openair   Ú langchain_community.vectorstoresr   Úlangchain.schemar	   ÚMEAL_CATEGORIESÚsortedr‚   ÚSORTED_CATEGORIESr-   rk   r¿   r%   r%   r%   r)   Ú<module>   s    5