Jun 30 - Add chat to AI analysis result (content from raw data)

This commit is contained in:
2026-06-30 11:45:22 -04:00
parent 5719bcf06e
commit c5078cc5f8
3 changed files with 41 additions and 11 deletions
+18
View File
@@ -409,6 +409,24 @@ def initialize_database():
conn.commit()
logger.info("Migration: added idx_activity_log_time index to activity_log.")
# ── ai_analysis_log: add document_text column if missing ──────────────
cursor.execute(
"""
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'ai_analysis_log'
AND COLUMN_NAME = 'document_text'
"""
)
(has_doc_text,) = cursor.fetchone()
if not has_doc_text:
cursor.execute(
"ALTER TABLE ai_analysis_log "
"ADD COLUMN document_text MEDIUMTEXT NULL AFTER criteria_snapshot"
)
conn.commit()
logger.info("Migration: added document_text column to ai_analysis_log.")
# ── Seed app_settings from environment variables (first-run bootstrap) ─
# Uses INSERT IGNORE so values already saved via the Admin UI are never
# overwritten — .env only fills in keys that are completely absent.
+6 -4
View File
@@ -1367,15 +1367,17 @@ def delete_criterion(admin_id: int, criterion_id: int):
def save_ai_analysis(user_id: int, file_names: str, model: str,
verdict, criteria_snapshot, summary_text: str) -> int:
verdict, criteria_snapshot, summary_text: str,
document_text: str = None) -> int:
conn = None
try:
conn = get_connection()
cur = conn.cursor()
cur.execute(
"INSERT INTO ai_analysis_log (user_id, file_names, model, verdict, criteria_snapshot, summary_text) "
"VALUES (%s,%s,%s,%s,%s,%s)",
(user_id, file_names, model, verdict, criteria_snapshot, summary_text),
"INSERT INTO ai_analysis_log "
"(user_id, file_names, model, verdict, criteria_snapshot, document_text, summary_text) "
"VALUES (%s,%s,%s,%s,%s,%s,%s)",
(user_id, file_names, model, verdict, criteria_snapshot, document_text, summary_text),
)
conn.commit()
new_id = cur.lastrowid
+16 -6
View File
@@ -100,7 +100,8 @@ def analyze():
])
analysis_id = save_ai_analysis(
user["id"], ", ".join(file_names), model,
result.get("verdict"), criteria_snap, result.get("summary", "")
result.get("verdict"), criteria_snap, result.get("summary", ""),
document_text=combined,
)
log_action(user["id"], "AI_ANALYSIS", "ai_analysis_log", analysis_id,
f"AI analysis on {len(file_names)} file(s). Verdict: {result.get('verdict')}.")
@@ -473,14 +474,23 @@ def chat():
return jsonify({"error": "Groq API key is not configured."}), 400
model = get_setting("groq.model", GROQ_MODELS[0])
summary = (record.get("summary_text") or "")[:8000]
# Prefer raw document text so the AI can answer questions from source material.
# Fall back to the stored summary for analyses run before this feature was added.
raw_text = (record.get("document_text") or "").strip()
if raw_text:
context_label = "ORIGINAL DOCUMENT CONTENT"
context_body = raw_text[:12000]
else:
context_label = "ANALYZED DOCUMENT SUMMARY"
context_body = (record.get("summary_text") or "")[:8000]
system_msg = (
"You are a government procurement analyst assistant. "
"The user has questions about a solicitation document that has already been analyzed. "
"Answer questions based solely on the analysis summary below. "
"If the information is not in the summary, say so clearly. Be concise and direct.\n\n"
"## ANALYZED DOCUMENT SUMMARY\n\n" + summary
"The user has questions about a solicitation document. "
"Answer based solely on the document content provided below. "
"If the information is not present, say so clearly. Be concise and direct.\n\n"
f"## {context_label}\n\n" + context_body
)
# Sanitize and cap conversation history at 20 turns