05/22 Enhance codes and fix bugs 3
This commit is contained in:
+40
-4
@@ -4,7 +4,7 @@ import requests
|
||||
from flask import Blueprint, request, jsonify, current_app
|
||||
from flask_login import login_required, current_user
|
||||
from app import db, limiter
|
||||
from app.models import Ticket, TicketStatus, TicketPriority, TicketCategory
|
||||
from app.models import Ticket, TicketStatus, TicketPriority, TicketCategory, KnowledgeBase
|
||||
from app.services.notification_service import notify_new_ticket
|
||||
from app.services.log_service import log_action
|
||||
|
||||
@@ -35,7 +35,28 @@ _GROQ_API_URL = 'https://api.groq.com/openai/v1/chat/completions'
|
||||
_GROQ_MODEL = 'llama-3.3-70b-versatile'
|
||||
|
||||
|
||||
def _call_groq(api_key, history, user_msg):
|
||||
def _search_kb(query, limit=3):
|
||||
"""Return up to `limit` published KB articles relevant to the user query.
|
||||
|
||||
Uses a simple keyword presence check against the title and tags columns.
|
||||
This avoids full-text indexes and works across all MySQL configs.
|
||||
"""
|
||||
import re
|
||||
words = [w for w in re.split(r'\W+', query.lower()) if len(w) > 3]
|
||||
if not words:
|
||||
return []
|
||||
articles = KnowledgeBase.query.filter_by(is_published=True).all()
|
||||
scored = []
|
||||
for art in articles:
|
||||
haystack = (art.title + ' ' + (art.tags or '')).lower()
|
||||
score = sum(1 for w in words if w in haystack)
|
||||
if score:
|
||||
scored.append((score, art))
|
||||
scored.sort(key=lambda x: -x[0])
|
||||
return [art for _, art in scored[:limit]]
|
||||
|
||||
|
||||
def _call_groq(api_key, history, user_msg, kb_context=''):
|
||||
"""
|
||||
Call the Groq API (OpenAI-compatible) and return the assistant's reply text.
|
||||
|
||||
@@ -78,8 +99,12 @@ def _call_groq(api_key, history, user_msg):
|
||||
for msg in clean_history
|
||||
]
|
||||
|
||||
system_content = _SYSTEM_PROMPT
|
||||
if kb_context:
|
||||
system_content += '\n\n' + kb_context
|
||||
|
||||
messages = (
|
||||
[{'role': 'system', 'content': _SYSTEM_PROMPT}]
|
||||
[{'role': 'system', 'content': system_content}]
|
||||
+ clean_history
|
||||
+ [{'role': 'user', 'content': user_msg[:_MAX_MSG_CHARS]}]
|
||||
)
|
||||
@@ -119,8 +144,19 @@ def chat():
|
||||
'ticket': None,
|
||||
})
|
||||
|
||||
# Inject relevant KB articles as context so the chatbot can reference
|
||||
# self-help content before suggesting a ticket is needed.
|
||||
kb_articles = _search_kb(user_msg)
|
||||
kb_context = ''
|
||||
if kb_articles:
|
||||
lines = ['RELEVANT KNOWLEDGE BASE ARTICLES (reference these if applicable):']
|
||||
base_url = current_app.config.get('APP_BASE_URL', '')
|
||||
for art in kb_articles:
|
||||
lines.append(f'- {art.title}: {base_url}/kb/{art.id}')
|
||||
kb_context = '\n'.join(lines)
|
||||
|
||||
try:
|
||||
reply_text = _call_groq(api_key, history, user_msg)
|
||||
reply_text = _call_groq(api_key, history, user_msg, kb_context=kb_context)
|
||||
except Exception as exc:
|
||||
logger.error(f'[CHATBOT API ERROR] {exc}')
|
||||
return jsonify({
|
||||
|
||||
Reference in New Issue
Block a user