Ë
    õ¡Ÿj/#  ã                  óV  — U d Z ddlm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  ej                   e«      Zd	Z ed
h«      ZddddœZded<   	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Zdd„Zd
dddœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zd
dœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zy)aB  
author: Yagnik Poshiya
organization: Webbrains Technologies Private Limited

Optional LangChain SQL path (kept separate from custom 3-LLM and LlamaIndex pipelines).
Uses LangChain's SQL Database Chain to convert visitor questions into SELECT queries.
Dialect-aware: supports MySQL now; architecture ready for PostgreSQL.
é    )ÚannotationsN)ÚAny)Ú
quote_plus)Úverify_sql_result)ÚSettings)ÚLLMUsageé   Úmysqlzmysql+pymysqlzpostgresql+psycopg2)r
   Ú
postgresqlÚpostgreszdict[str, str]Ú_SQLALCHEMY_DRIVERSc                ó†   — t         j                  | t         d   «      }|› dt        |«      › dt        |«      › d|› d|› d|› �S )Nr
   z://ú:ú@ú/)r   Úgetr   )ÚdialectÚuserÚpasswordÚhostÚportÚdatabaseÚdrivers          úK/var/www/html/agent-engine/apps/agents/rag-agent/src/agent/sql_langchain.pyÚ_build_connection_urir   #   sS   € ô !×$Ñ$ WÔ.AÀ'Ñ.JÓK€FØˆX�Sœ DÓ)Ð*¨!¬J°xÓ,@Ð+AÀÀ4À&ÈÈ$ÈÈqÐQYÐPZÐ[Ð[ó    c                ó   — | dv ryy)z,Human-readable dialect name for LLM prompts.)r   r   Ú
PostgreSQLÚMySQL© ©r   s    r   Ú_dialect_labelr"   *   s   € àÐ,Ñ,ØØr   c                ó  — t        | j                  xs d«      j                  «       j                  «       }t        | j                  xs d«      j                  «       }|dk(  rFt        | j
                  xs d«      j                  «       }|st        d«      ‚	 ddlm}  |||d¬«      S |d	k(  rFt        | j                  xs d«      j                  «       }|st        d
«      ‚	 ddlm}  |||d¬«      S |dk(  rFt        | j                  xs d«      j                  «       }|st        d«      ‚	 ddlm}  |||d¬«      S |dk(  rGt        | j                   xs d«      j                  «       }|st        d«      ‚	 ddlm}  |||dd¬«      S t        d«      ‚# t        $ r}t        d«      |‚d }~ww xY w# t        $ r}t        d«      |‚d }~ww xY w# t        $ r}t        d«      |‚d }~ww xY w# t        $ r}t        d«      |‚d }~ww xY w)NÚ ÚgooglezAGOOGLE_LLM_API_KEY is required for LANGCHAIN_SQL_PROVIDER=google.r   )ÚChatGoogleGenerativeAIz+Missing dependency: langchain-google-genai.g        )ÚmodelÚgoogle_api_keyÚtemperatureÚopenaizAOPENAI_LLM_API_KEY is required for LANGCHAIN_SQL_PROVIDER=openai.)Ú
ChatOpenAIz%Missing dependency: langchain-openai.)r'   Úapi_keyr)   Ú	anthropiczGANTHROPIC_LLM_API_KEY is required for LANGCHAIN_SQL_PROVIDER=anthropic.)ÚChatAnthropicz(Missing dependency: langchain-anthropic.)r'   Úanthropic_api_keyr)   Ú
openrouterzIOPENROUTER_LLM_API_KEY is required for LANGCHAIN_SQL_PROVIDER=openrouter.zhttps://openrouter.ai/api/v1)r'   r,   Úbase_urlr)   zUUnsupported LANGCHAIN_SQL_PROVIDER. Supported: google, openai, anthropic, openrouter.)ÚstrÚlangchain_sql_providerÚstripÚlowerÚlangchain_sql_modelÚgoogle_llm_api_keyÚ
ValueErrorÚlangchain_google_genair&   ÚImportErrorÚopenai_llm_api_keyÚlangchain_openair+   Úanthropic_llm_api_keyÚlangchain_anthropicr.   Úopenrouter_llm_api_key)ÚsettingsÚproviderr'   r,   r&   Úer+   r.   s           r   Ú_build_langchain_llmrC   1   s(  € Ü�8×2Ñ2Ò8°bÓ9×?Ñ?ÓA×GÑGÓI€HÜ�×,Ñ,Ò2°Ó3×9Ñ9Ó;€Eà�8ÒÜ�h×1Ñ1Ò7°RÓ8×>Ñ>Ó@ˆÙÜÐ`ÓaÐað	SÝEñ &¨EÀ'ÐWZÔ[Ð[à�8ÒÜ�h×1Ñ1Ò7°RÓ8×>Ñ>Ó@ˆÙÜÐ`ÓaÐað	MÝ3ñ  ¨wÀCÔHÐHà�;ÒÜ�h×4Ñ4Ò:¸Ó;×AÑAÓCˆÙÜÐfÓgÐgð	PÝ9ñ  5¸GÐQTÔUÐUà�<ÒÜ�h×5Ñ5Ò;¸Ó<×BÑBÓDˆÙÜÐhÓiÐið	MÝ3ñ ØØØ3Øô	
ð 	
ô Ø_óð øôO ò 	SÜÐJÓKÐQRÐRûð	Sûô ò 	MÜÐDÓEÈ1ÐLûð	Mûô ò 	PÜÐGÓHÈaÐOûð	Pûô ò 	MÜÐDÓEÈ1ÐLûð	Mús`   ÂF Ã"F2 Ä-G Å8G, Æ	F/ÆF*Æ*F/Æ2	GÆ;GÇGÇ	G)ÇG$Ç$G)Ç,	HÇ5HÈHc                ó^  — | j                  «       } t        j                  d| t        j                  t        j                  z  «      }|r|j                  d«      j                  «       } t        j                  d| «      }|r.|j                  d«      j                  «       j                  d«      S y)Nz```(?:sql)?\s*\n?(.*?)```é   z(?is)\bSELECT\b.+r   ú;r$   )r4   ÚreÚsearchÚDOTALLÚ
IGNORECASEÚgroupÚrstrip)ÚtextÚfenceÚms      r   Ú_extract_sql_from_textrP   g   s   € Ø�:‰:‹<€DÜ�I‰IÐ2°D¼"¿)¹)ÄbÇmÁmÑ:SÓT€EÙØ�{‰{˜1‹~×#Ñ#Ó%ˆÜ
�	‰	Ð&¨Ó-€AÙØ�w‰w�q‹z×ÑÓ!×(Ñ(¨Ó-Ð-Ør   )r   Úprevious_sqlÚprevious_errorc               ó  — 	 ddl m} ddlm}	 ddlm}
 t        |«      }t        | «      } ||«      } |	|t        |«      ¬«      } |
||«      }|r2|r0d|› d|› d	d
j                  t        |«      «      › d|› d|› d|› d|› �}n)d|› d|› d	d
j                  t        |«      «      › d|› d|› �
}|j                  d|i«      }t        |xs d«      j                  «       }t        |«      S # t        $ r}t        d«      |‚d }~ww xY w)Nr   )Úcreate_engine)ÚSQLDatabase)Úcreate_sql_query_chainzcLangChain SQL dependencies are not installed. Install langchain + langchain-community + sqlalchemy.)ÚengineÚinclude_tableszGiven the following z database schema:
z

Use ONLY these tables: ú, z

Previous SQL attempt:
z

Problem with that attempt:
z

Generate a corrected single z SELECT query for:
z

Generate a single Úquestionr$   )Ú
sqlalchemyrT   Úlangchain_community.utilitiesrU   Úlangchain.chainsrV   r:   r8   r"   rC   ÚsortedÚjoinÚinvoker2   r4   rP   )r@   Úuser_messageÚschema_detailÚallowÚconnection_urir   rQ   rR   rT   rU   rV   rB   ÚlabelÚllmrW   ÚdbÚchainÚpromptÚresultÚraws                       r   Ú_langchain_generate_sqlrl   r   sQ  € ðÝ,Ý=Ý;ô ˜7Ó#€EÜ
˜xÓ
(€CÙ˜>Ó*€FÙ	˜F´6¸%³=Ô	A€Bá" 3¨Ó+€Eá™à" 5 'Ð)<¸]¸Oð L&Ø&*§i¡i´°u³Ó&>Ð%?ð @&Ø&2 ^ð 4+Ø+9Ð*:ð ;+Ø+0¨'Ð1EÀlÀ^ð	Uñ 	ð # 5 'Ð)<¸]¸Oð L&Ø&*§i¡i´°u³Ó&>Ð%?ð @!Ø!& Ð';¸L¸>ðKð 	ð �\‰\˜: vÐ.Ó/€FÜ
ˆfŠl˜Ó
×
!Ñ
!Ó
#€CÜ! #Ó&Ð&øô= ò ÜðDó
ð ð	ûðús   ‚C& Ã&	D Ã/C;Ã;D r!   c               óÖ  — |t         vr.t        d|› ddj                  t        t         «      «      › d�«      ‚ddlm} d}d}	d}
d}t        «       }t        |j                  d	«      xs d«      }t        |j                  d
«      xs d«      }t        |j                  d«      xs d«      }t        |j                  d«      xs d«      }t        ||||||«      }t        t        «      D �]H  }t        | |||||||
¬«      }|st        j                  d||«        �n|}	t        j!                  d||	|«       	  |||||||	|t        |j                  d«      xs d«      t        |j                  d«      xs d«      d¬«
      \  }}|r t#        j$                  ||dœdt        ¬«      }nd}t'        | |||	|¬«      \  }}t        j!                  d|||j                  d«      |j                  d «      «       |j                  d«      d!k(  r n-|	}|j                  d"«      xs |j                  d «      xs |}
�ŒK ||	|fS # t        $ r(}t        j                  d|||«       d|› d�}Y d}~Œ¾d}~ww xY w)#zn
    LangChain SQL pipeline for live databases (dialect-aware).
    Returns (db_answer, sql_used, usage).
    z5LangChain SQL pipeline does not yet support dialect 'z'. Supported: rY   ú.r   )Úrun_select_mysqlr$   NÚusernamer   r   r   iê  )ra   rb   rc   rd   r   rQ   rR   zFDB pipeline source=langchain dialect=%s generated empty SQL attempt=%dzCDB pipeline source=langchain dialect=%s generated_sql=%s attempt=%dÚssl_modeÚrequiredÚ
ssl_ca_peméÈ   )
r   r   r   r   r   ÚsqlÚallowed_tablesrq   rs   Úmax_rows)ÚcolumnsÚrowsF)Úensure_asciiÚdefaultz[Query returned 0 rows]z@DB pipeline source=langchain dialect=%s exec_error=%s attempt=%dz[SQL error: ú])ra   rb   ru   Úquery_resultzPDB pipeline source=langchain dialect=%s verifier attempt=%d verdict=%s reason=%sÚverdictÚreasonÚpassÚfeedback)Ú_SUPPORTED_DIALECTSr8   r_   r^   Úagent.mysql_runnerro   r   r2   r   Úintr   ÚrangeÚMAX_LANGCHAIN_ATTEMPTSrl   ÚloggerÚwarningÚinfoÚjsonÚdumpsr   )r@   ra   rb   Údb_labelÚlive_ctxrc   r   ro   Ú	db_answerÚsql_usedÚ
prev_errorÚprev_sqlÚusager   r   r   r   rd   ÚattemptÚsql_used_newÚcolsry   rB   r~   Ú_s                            r   Úrun_langchain_live_sqlr—   ¢   s•  € ð Ô)Ñ)ÜØCÀGÀ9ð MØŸ)™)¤FÔ+>Ó$?Ó@ÐAÀðDó
ð 	
õ
 4à€IØ€HØ!€JØ€HÜ‹J€Eäˆx�|‰|˜JÓ'Ò-¨2Ó.€DÜ�8—<‘< 
Ó+Ò1¨rÓ2€HÜˆx�|‰|˜FÓ#Ò) rÓ*€DÜˆx�|‰|˜FÓ#Ò+ tÓ,€DÜ*¨7°D¸(ÀDÈ$ÐPXÓY€NäÔ/Ó0ó :SˆÜ.ØØ%Ø'ØØ)ØØ!Ø%ô	
ˆñ Ü�N‰NÐcÐelÐnuÔvÚØˆÜ�‰ÐYÐ[bÐdlÐnuÔvð	,Ù)ØØØØ!Ø!ØØ$Ü˜XŸ\™\¨*Ó5ÒC¸ÓDÜ˜xŸ|™|¨LÓ9Ò?¸RÓ@Øô‰JˆD�$ñ Ü ŸJ™JØ $¨dÑ3Ø!&Üô‘	ð 6�	ô
 'ØØ%Ø'ØØ"ô
‰
ˆ�ô 	�‰Ø^Ø�W˜gŸk™k¨)Ó4°g·k±kÀ(Ó6Kô	
ð
 �;‰;�yÓ! VÒ+ÙàˆØ—[‘[ Ó,ÒR°·±¸HÓ0EÒRÈŠ
ðu:Sðx �h Ð%Ð%øô- ò 	,Ü�N‰NÐ]Ð_fÐhiÐkrÔsØ& q c¨Ð+�Iûð	,ús   Ä4A1H7È7	I(É I#É#I()r   r2   r   r2   r   r2   r   r2   r   r„   r   r2   Úreturnr2   )r   r2   r˜   r2   )r@   r   r˜   r   )rM   r2   r˜   r2   )r@   r   ra   r2   rb   r2   rc   úset[str]rd   r2   r   r2   rQ   ú
str | NonerR   rš   r˜   r2   )r@   r   ra   r2   rb   r2   rŒ   r2   r�   zdict[str, Any]rc   r™   r   r2   r˜   ztuple[str, str, LLMUsage])Ú__doc__Ú
__future__r   rŠ   ÚloggingrG   Útypingr   Úurllib.parser   Úagent.sql_verifierr   Úconfig.settingsr   Úllm.baser   Ú	getLoggerÚ__name__r‡   r†   Ú	frozensetr‚   r   Ú__annotations__r   r"   rC   rP   rl   r—   r    r   r   ú<module>r§      s…  ðòõ #ã Û Û 	Ý Ý #å 0Ý $Ý à	ˆ×	Ñ	˜8Ó	$€àÐ á  	Ó*Ð ð Ø'Ø%ñ'Ð �^ó ð\Øð\Øð\Ø'*ð\Ø25ð\Ø=@ð\ØLOð\àó\óó3ólð$ Ø#Ø!%ñ-'Øð-'ð ð-'ð ð	-'ð
 ð-'ð ð-'ð ð-'ð ð-'ð ð-'ð 	ó-'ðp ñ^&Øð^&ð ð^&ð ð	^&ð
 ð^&ð ð^&ð ð^&ð ð^&ð ô^&r   