Ë
    õ¡Ÿjz  ã                  ó¬   — d Z ddlm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  ej                  e«      Zdd„Zdd„Z	 	 	 	 	 	 dd	„Z	 	 	 	 	 	 	 	 dd
„Zy)zã
author: Yagnik Poshiya
organization: Webbrains Technologies Private Limited

Load and select predefined query templates for live database connections
(`database_connections.query_mode`, `database_connection_query_templates`).
é    )ÚannotationsN)ÚAny)ÚClient)Ú	LLMClientÚLLMUsagec           	     óü  — t        t        j                  dt        | xs d«      j	                  «       «      «      }|syd}d}t        |«      D �]–  \  }}t        |j                  d«      xs d«      t        |j                  d«      xs d«      t        |j                  d«      xs d«      g}|j                  d«      }t        |t        «      rµ	 |j                  t        |j                  d	«      xs d«      «       |j                  t        |j                  d
«      xs d«      «       |j                  t        |j                  d«      xs d«      «       |j                  t        |j                  d«      xs d«      «       t        t        j                  ddj                  |«      j	                  «       «      «      }	t        |j                  |	«      «      }
|
|kD  s�Œ“|
}|}�Œ™ |dk  ry|S # t        $ r Y Œww xY w)z˜
    Deterministic fallback when LLM template picker returns no match.
    Scores overlap between question tokens and template metadata/query text.
    z
[a-z0-9_]+Ú Nr   ÚnameÚdescriptionÚsql_textÚ
query_bodyÚ
collectionÚ	operationÚpipelineÚfilterú é   )ÚsetÚreÚfindallÚstrÚlowerÚ	enumerateÚgetÚ
isinstanceÚdictÚappendÚ	ExceptionÚjoinÚlenÚintersection)Úuser_messageÚ	templatesÚtokensÚbest_idxÚ
best_scoreÚiÚtÚ
text_partsÚbodyÚ
hay_tokensÚscores              úR/var/www/html/agent-engine/apps/agents/rag-agent/src/agent/live_query_templates.pyÚ_keyword_fallback_indexr.      s´  € ô
 ”—‘˜M¬3¨|Ò/A¸rÓ+B×+HÑ+HÓ+JÓKÓL€FÙØà€HØ€JÜ˜)Ó$ó ‰ˆˆ1ä�—‘�f“Ò# Ó$Ü�—‘�mÓ$Ò*¨Ó+Ü�—‘�jÓ!Ò' RÓ(ð
ˆ
ð
 �u‰u�\Ó"ˆÜ�dœDÔ!ðØ×!Ñ!¤# d§h¡h¨|Ó&<Ò&BÀÓ"CÔDØ×!Ñ!¤# d§h¡h¨{Ó&;Ò&A¸rÓ"BÔCØ×!Ñ!¤# d§h¡h¨zÓ&:Ò&@¸bÓ"AÔBØ×!Ñ!¤# d§h¡h¨xÓ&8Ò&>¸BÓ"?Ô@ô œŸ™ M°3·8±8¸JÓ3G×3MÑ3MÓ3OÓPÓQˆ
Ü�F×'Ñ'¨
Ó3Ó4ˆØ�:ÔØˆJØŠHð)ð. �A‚~ØØ€Oøô ò Ùðús   ÃB4G/Ç/	G;Ç:G;c                ó˜  — t        |xs d«      j                  «       }|sg S | j                  d«      j                  d«      j	                  d|«      j	                  dd«      j	                  dd«      j                  d	d¬
«      j                  «       }t        |j                  xs g «      }t        j                  dt        |«      |«       |S )zEActive, non-deleted templates ordered by priority then creation time.r	   Ú#database_connection_query_templateszZid,name,description,sql_text,query_kind,query_body,parameter_schema,card_config,sort_orderÚconnection_idÚ
is_deletedFÚ	is_activeTÚ
sort_order)Údescz7Loaded %d active query template(s) for connection_id=%s)r   ÚstripÚtableÚselectÚeqÚorderÚexecuteÚlistÚdataÚloggerÚinfor    )Úsupabaser1   ÚcidÚresÚrowss        r-   Úload_active_query_templatesrD   =   s§   € ä
ˆmÒ!˜rÓ
"×
(Ñ
(Ó
*€CÙØˆ	à�‰Ð<Ó=ß	‰ÐlÓ	mß	‰ˆO˜SÓ	!ß	‰ˆL˜%Ó	 ß	‰ˆK˜Ó	ß	‰ˆ| %ˆÓ	(ß	‰‹ð ô �—‘’˜BÓ€DÜ
‡K�KÐIÌ3ÈtË9ÐVYÔZØ€Kó    c                óŠ  — t        |xs d«      j                  «       j                  «       }g }g }| D ]Ï  }t        |j                  d«      xs d«      j                  «       j                  «       }t        |j                  d«      xs |j                  d«      xs d«      }|dk(  r/|dk(  r|j	                  |«       ŒŠ|j	                  |› d	|› d
�«       Œ¢|dk7  r|j	                  |«       Œ¹|j	                  |› d	|› d
�«       ŒÑ |r=t
        j                  d|t        |«      t        |«      dj                  |dd «      «       |S )zKKeep SQL templates for relational live connections; mongo_json for MongoDB.ÚmysqlÚ
query_kindÚsqlr
   Úidú?ÚmongodbÚ
mongo_jsonz(kind=ú)zJfilter_templates_by_dialect dialect=%s kept=%d skipped=%d skipped_names=%sz, Né
   )	r   r6   r   r   r   r>   r?   r    r   )r#   Úlive_dialectÚdÚoutÚskippedr(   ÚkindÚtnames           r-   Úfilter_templates_by_dialectrV   P   s&  € ô
 	ˆLÒ#˜GÓ$×*Ñ*Ó,×2Ñ2Ó4€AØ "€CØ€GØò 8ˆÜ�1—5‘5˜Ó&Ò/¨%Ó0×6Ñ6Ó8×>Ñ>Ó@ˆÜ�A—E‘E˜&“MÒ7 Q§U¡U¨4£[Ò7°CÓ8ˆØ�	Š>Ø�|Ò#Ø—
‘
˜1•à—‘ % ¨¨t¨f°AÐ6Õ7à�|Ò#Ø—
‘
˜1•à—‘ % ¨¨t¨f°AÐ6Õ7ð8ñ Ü�‰ØXØŒs�3‹xœ˜W› t§y¡y°¸¸"°Ó'>ô	
ð €JrE   c                ód  — t        |«      }|dk(  rdt        «       fS g }t        |«      D �]'  \  }}t        |j	                  d«      xs d«      j                  «       j                  «       }t        |j	                  d«      xs d«      j                  «       j                  dd«      }t        |«      d	kD  r|dd	 › d
�}d}	|j	                  d«      }
t        |
t        «      r-	 t        |
j	                  d«      |
j	                  d«      dœ«      }	|j                  |dz   › d|j	                  dd«      ›d|j	                  dd«      ›d|› d|› d|	› �«       �Œ* dj                  |«      }d|› d|› d|› d|› d�	}| j                  |«      \  }}	 t        |j	                  d«      «      }|dk(  rdt'        ||«      }|�=t"        j)                  d|dz   t        ||   j	                  d«      xs d«      «       ||fS t"        j)                  d«       d|fS |dk  s||kD  rt"        j%                  d ||«       d|fS |dz
  }t"        j)                  d!|t        ||   j	                  d«      xs d«      «       ||fS # t        $ r d}	Y �Œrw xY w# t        t         f$ r t"        j%                  d|«       d|fcY S w xY w)"z
    LLM chooses the best template by 1-based index, or 0 for no match.
    Returns 0-based index into templates, or None.
    r   NrH   rI   r   r	   ú
r   éÜ   z...r   r   r   )r   r   é   z. name=r
   z | description=r   z | kind=z | sql=z	 | mongo=zChoose which predefined read-only database query template best answers the visitor question.

Templates (respond with index 1..z, to use that template, or 0 if none apply):
z

Visitor question:
z7

Respond with JSON only: {"index": <integer 0 through z>}Úindexz.query_template pick: invalid index payload: %szCquery_template pick: llm_index=0 fallback_index=%d template_name=%sz2query_template pick: llm_index=0 no fallback matchz2query_template pick: index out of range: %s (n=%d)z2query_template pick: llm_index=%d template_name=%s)r    r   r   r   r   r6   r   Úreplacer   r   r   r   r   Úgenerate_jsonÚintÚ	TypeErrorÚ
ValueErrorr>   Úwarningr.   r?   )Ú
llm_clientr"   r#   ÚnÚblock_linesr'   r(   rT   Úsql_previewÚbody_previewr*   ÚblockÚpromptr=   ÚusageÚidxÚfallback_idxÚchosens                     r-   Úpick_query_template_indexrm   m   sÿ  € ô 	ˆI‹€AØˆA‚vØ”X“ZÐÐà€KÜ˜)Ó$ó 
‰ˆˆ1Ü�1—5‘5˜Ó&Ò/¨%Ó0×6Ñ6Ó8×>Ñ>Ó@ˆÜ˜!Ÿ%™% 
Ó+Ò1¨rÓ2×8Ñ8Ó:×BÑBÀ4ÈÓMˆÜˆ{Ó˜cÒ!Ø(¨¨#Ð.Ð/¨sÐ3ˆKØˆØ�u‰u�\Ó"ˆÜ�dœDÔ!ð"Ü"à&*§h¡h¨|Ó&<Ø%)§X¡X¨kÓ%:ñó �ð 	×ÑØ�1‰uˆgð Ø—E‘E˜& "Ó%Ð(ð )ØŸ5™5 °Ó3Ð6ð 7Ø�6ð Ø�-ð  Ø!�Nð$ö	
ð#
ð2 �I‰I�kÓ"€Eð"à"# ð %Ø€ð ð €ð 7à78°c¸ð@€Fð ×*Ñ*¨6Ó2�K€Dˆ%ðÜ�$—(‘(˜7Ó#Ó$ˆð ˆa‚xÜ.¨|¸YÓGˆØÐ#Ü�K‰KØUØ˜qÑ Ü�I˜lÑ+×/Ñ/°Ó7Ò=¸2Ó>ôð
   Ð&Ð&Ü�‰ÐHÔIØ�Uˆ{ÐØ
ˆQ‚w�#˜’'Ü�‰ÐKÈSÐRSÔTØ�Uˆ{ÐØ�1‰W€FÜ
‡K�KØ<ØÜˆI�fÑ×!Ñ! &Ó)Ò/¨RÓ0ôð
 �5ˆ=Ðøô] ò "Ø!“ð"ûô. ”zÐ"ò Ü�‰ÐGÈÔNØ�Uˆ{Òðús$   Ã!,I1Æ
J É1J É?J Ê)J/Ê.J/)r"   r   r#   úlist[dict[str, Any]]Úreturnz
int | None)r@   r   r1   r   ro   rn   )r#   rn   rP   r   ro   rn   )rb   r   r"   r   r#   rn   ro   ztuple[int | None, LLMUsage])Ú__doc__Ú
__future__r   Úloggingr   Útypingr   r@   r   Úllm.baser   r   Ú	getLoggerÚ__name__r>   r.   rD   rV   rm   © rE   r-   ú<module>rx      sˆ   ðñõ #ã Û 	Ý å ç (à	ˆ×	Ñ	˜8Ó	$€ó$óNð&Ø#ðàðð óð:KØðKàðKð $ðKð !ô	KrE   