Jun 30 - Add chat to AI analysis result
This commit is contained in:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user