Jun 30 - Add chat to AI analysis result

This commit is contained in:
2026-06-30 11:12:52 -04:00
parent 57b11b2aa9
commit 5719bcf06e
2 changed files with 241 additions and 3 deletions
+66
View File
@@ -450,6 +450,72 @@ def delete_criterion_view(criterion_id):
return redirect(url_for("ai_summary.ai_summary"))
@ai_summary_bp.route("/chat", methods=["POST"])
@login_required
def chat():
"""Follow-up Q&A about a previously analyzed document."""
user = session["user"]
data = request.get_json(silent=True) or {}
analysis_id = data.get("analysis_id")
messages = data.get("messages") or []
if not analysis_id:
return jsonify({"error": "analysis_id is required."}), 400
if not messages or not isinstance(messages, list):
return jsonify({"error": "messages is required."}), 400
record = get_ai_analysis_detail(int(analysis_id))
if not record:
return jsonify({"error": "Analysis not found."}), 404
api_key = (os.environ.get("GROQ_API_KEY") or "").strip() or get_setting("groq.api_key", "").strip()
if not api_key:
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]
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
)
# Sanitize and cap conversation history at 20 turns
api_messages = []
for m in messages[-20:]:
role = m.get("role") if isinstance(m, dict) else None
content = (m.get("content") or "").strip() if isinstance(m, dict) else ""
if role in ("user", "assistant") and content:
api_messages.append({"role": role, "content": content})
if not api_messages or api_messages[-1]["role"] != "user":
return jsonify({"error": "Last message must be from the user."}), 400
try:
response = http_requests.post(
"https://api.groq.com/openai/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"model": model,
"messages": [{"role": "system", "content": system_msg}] + api_messages,
"max_tokens": 1024,
"temperature": 0.2,
},
timeout=60,
)
if not response.ok:
logger.error(f"Groq chat {response.status_code}: {response.text[:200]}")
response.raise_for_status()
reply = response.json()["choices"][0]["message"]["content"] or ""
return jsonify({"reply": reply})
except Exception as e:
logger.error(f"AI chat error: {e}")
return jsonify({"error": f"Chat failed: {e}"}), 500
@ai_summary_bp.route("/history/<int:analysis_id>")
@login_required
def analysis_detail(analysis_id):