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

Dedicated SQL verification / quality-gate LLM â€” system-controlled model that
inspects the generated SQL, the query result, and the visitor's original
question, then decides whether the answer is acceptable or whether a retry
is needed (with actionable feedback for the SQL generator).
é    )ÚannotationsN)ÚAny)ÚSettings)ÚGenerationConfigÚ	LLMClientÚLLMUsage)Úbuild_llm_clientuD
  You are an SQL result quality-gate for a RAG agent that answers website
visitor questions from a relational database.

You receive:
- The visitor's original question (plain text).
- The database schema (tables and columns).
- The SQL query that was generated.
- The query result (JSON with columns + rows, an error message, or
  "[Query returned 0 rows]").

YOUR TASK:
Decide whether the query result adequately answers the visitor's question.

OUTPUT â€” a single JSON object with exactly these fields:
{
  "verdict": "pass" | "retry",
  "reason": "one-line explanation",
  "feedback": "actionable hint for the SQL generator (only when verdict=retry)"
}

RULES:
1. verdict = "pass" when the result rows contain data that can reasonably
   answer the question, even if not perfect.
2. verdict = "retry" when:
   a. The query returned an SQL error.
   b. The query returned 0 rows but the schema suggests data should exist.
   c. The query columns are obviously wrong (e.g. selected IDs instead of
      names, missed a required JOIN, wrong aggregation).
   d. The SQL is syntactically valid but semantically misaligned with the
      question (wrong table, wrong filter, etc.).
   e. The result appears to expose raw identifier columns instead of
      human-readable fields when the visitor is asking for descriptive
      values (e.g., "name", "title", "label", "display", "status",
      "category", "location").
   f. The SQL references table names or column names that are not present in
      the provided schema snapshot context.
3. When verdict = "retry", the "feedback" field MUST contain a concrete,
   actionable correction hint â€” e.g. "JOIN the `orders` table on
   `customer_id` to get order counts" â€” NOT generic advice like
   "try again".
4. Do NOT output anything except the JSON object.
5. Be lenient: partial results are "pass" as long as they're relevant.
6. Do NOT enforce strict exact-keyword matching on visitor terms. If the SQL
   result is semantically close and useful (about 80-90% relevant), prefer
   verdict = "pass" instead of "retry".
7. For place names or text fields, minor spelling differences or partial
   matches are acceptable when the returned data is still clearly relevant.

HEURISTIC FOR e:
- If the selected column names include exactly `id` or end with `_id`,
  and the visitor question is asking for a descriptive field (name/title/
  label/display/etc.), set verdict = "retry".
- In verdict="retry", set feedback to instruct replacing those raw IDs
  with JOINs to the relevant lookup/entity tables and selecting their
  descriptive columns (usually named `name` or `title`).
c                óB   — t        | j                  | j                  «      S )N)r	   Úsql_verifier_providerÚsql_verifier_model)Úsettingss    úJ/var/www/html/agent-engine/apps/agents/rag-agent/src/agent/sql_verifier.pyÚ_build_verifier_clientr   R   s   € Ü˜H×:Ñ:¸H×<WÑ<WÓXÐXó    c               ó&  — t        | «      }d|› d|› d|› d|› �}t        › d|› �}|j                  |t        dd¬«      ¬	«      }|j                  j                  «       }	|	sd
ddœ|j                  fS 	 t        j                  |	«      }
t        |
t        «      s>t        j                  dt        |
«      j                  |	dd «       d
ddœ|j                  fS t!        |
j#                  d«      xs d
«      j%                  «       }|dvrd
}|t!        |
j#                  d«      xs d«      t!        |
j#                  d«      xs d«      dœ|j                  fS # t        j                  $ r- t        j                  d|	dd «       d
ddœ|j                  fcY S w xY w)zjReturn (verdict_dict, usage).

    verdict_dict has keys: verdict ("pass"|"retry"), reason, feedback.
    zVisitor's question:
z

Database schema:
z

Generated SQL:
z

Query result:
z

gš™™™™™¹?T)ÚtemperatureÚresponse_json)ÚconfigÚpassz verifier returned empty response)ÚverdictÚreasonz#sql_verifier: non-JSON response: %sNéÈ   zverifier returned non-JSONz.sql_verifier: expected JSON object, got %s: %sz!verifier returned non-object JSONr   )r   Úretryr   Ú Úfeedback)r   r   r   )r   Ú_SYSTEM_INSTRUCTIONÚgenerater   ÚtextÚstripÚusageÚjsonÚloadsÚJSONDecodeErrorÚloggerÚwarningÚ
isinstanceÚdictÚtypeÚ__name__ÚstrÚgetÚlower)r   Úuser_messageÚschema_detailÚsqlÚquery_resultÚclientÚ
user_blockÚpromptÚrespr   Údatar   s               r   Úverify_sql_resultr6   V   s·  € ô $ HÓ-€Fð   ˜~ð .Ø*˜Oð ,Ø˜%ð  Ø&˜ð	)ð ô $Ð$ D¨¨Ð5€Fà�?‰?ØÜ¨C¸tÔDð ó €Dð �9‰9�?‰?Ó€DÙØ!Ð-OÑPÐRV×R\ÑR\Ð\Ð\ðWÜ�z‰z˜$Óˆô
 �dœDÔ!Ü�‰ÐGÌÈdË×I\ÑI\Ð^bÐcgÐdgÐ^hÔiØ!Ð-PÑQÐSW×S]ÑS]Ð]Ð]ä�$—(‘(˜9Ó%Ò/¨Ó0×6Ñ6Ó8€GØÐ'Ñ'Øˆð Ü�d—h‘h˜xÓ(Ò.¨BÓ/Ü˜Ÿ™ Ó,Ò2°Ó3ñð ‡z�zð	ð øô ×Ñò WÜ�‰Ð<¸dÀ4ÀC¸jÔIØ!Ð-IÑJÈDÏJÉJÐVÒVðWús   Á1E Å=FÆF)r   r   Úreturnr   )r   r   r-   r*   r.   r*   r/   r*   r0   r*   r7   ztuple[dict[str, Any], LLMUsage])Ú__doc__Ú
__future__r   r!   ÚloggingÚtypingr   Úconfig.settingsr   Úllm.baser   r   r   Úllm.factoryr	   Ú	getLoggerr)   r$   r   r   r6   © r   r   ú<module>rA      s„   ðñõ #ã Û Ý å $ß :Ñ :Ý (à	ˆ×	Ñ	˜8Ó	$€ð8Ð óvYð2Øð2ð ð2ð ð	2ð
 
ð2ð ð2ð %ô2r   