Initial commit

This commit is contained in:
2026-03-25 11:37:46 -04:00
commit dfdbb54875
41 changed files with 5079 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
import json
import logging
import requests
from flask import Blueprint, request, jsonify, current_app
from flask_login import login_required, current_user
from app import db
from app.models import Ticket, TicketStatus, TicketPriority, TicketCategory
from app.services.notification_service import notify_new_ticket
from app.services.log_service import log_action
chatbot_bp = Blueprint('chatbot', __name__, url_prefix='/chatbot')
logger = logging.getLogger(__name__)
_SYSTEM_PROMPT = """You are an IT Helpdesk Assistant for an internal IT ticket system.
Your job is to:
1. Help employees report IT issues conversationally.
2. Gather all required information to create a support ticket:
- Issue title (short summary)
- Detailed description
- Category (hardware, software, network, access, email, printer, phone, security, other)
- Priority (low, medium, high, critical)
- Location (optional)
- Asset tag (optional device serial / asset number)
3. When you have enough information, respond with a JSON block like this (and ONLY this, no extra text):
{"action": "create_ticket", "title": "...", "description": "...", "category": "...", "priority": "...", "location": "...", "asset_tag": "..."}
4. For general IT questions, answer helpfully but briefly.
5. If the user seems frustrated or has a critical outage, set priority to "critical".
6. Keep your tone professional, friendly, and concise.
7. Always ask clarifying questions if you need more detail before creating a ticket.
"""
@chatbot_bp.route('/message', methods=['POST'])
@login_required
def chat():
data = request.get_json(force=True)
history = data.get('history', []) # [{role, content}, ...]
user_msg = data.get('message', '').strip()
if not user_msg:
return jsonify({'error': 'Empty message'}), 400
api_key = current_app.config.get('ANTHROPIC_API_KEY', '')
if not api_key:
return jsonify({'reply': "The AI assistant is not configured yet. Please contact your IT administrator.", 'ticket': None})
messages = history + [{'role': 'user', 'content': user_msg}]
try:
resp = requests.post(
'https://api.anthropic.com/v1/messages',
headers={
'x-api-key' : api_key,
'anthropic-version': '2023-06-01',
'content-type' : 'application/json',
},
json={
'model' : 'claude-sonnet-4-20250514',
'max_tokens': 1024,
'system' : _SYSTEM_PROMPT,
'messages' : messages,
},
timeout=30,
)
resp.raise_for_status()
reply_text = resp.json()['content'][0]['text'].strip()
except Exception as exc:
logger.error(f'[CHATBOT API ERROR] {exc}')
return jsonify({'reply': 'Sorry, I encountered an error. Please try again or submit a ticket manually.', 'ticket': None})
# Check if the AI wants to create a ticket
ticket_data = None
if '"action": "create_ticket"' in reply_text or "'action': 'create_ticket'" in reply_text:
try:
start = reply_text.find('{')
end = reply_text.rfind('}') + 1
parsed = json.loads(reply_text[start:end])
if parsed.get('action') == 'create_ticket':
ticket = Ticket(
title = parsed.get('title', 'Untitled Issue'),
description = parsed.get('description', ''),
category = parsed.get('category', TicketCategory.OTHER),
priority = parsed.get('priority', TicketPriority.MEDIUM),
location = parsed.get('location', ''),
asset_tag = parsed.get('asset_tag', ''),
created_by_id = current_user.id,
status = TicketStatus.OPEN,
ai_generated = True,
)
ticket.ticket_number = ticket.generate_ticket_number()
db.session.add(ticket)
db.session.commit()
log_action(current_user.id, 'ticket_create_chatbot', 'ticket', ticket.id,
f'ticket_number={ticket.ticket_number} ai_generated=True')
logger.info(f'[CHATBOT TICKET CREATE] ticket_id={ticket.id} number={ticket.ticket_number} user_id={current_user.id}')
notify_new_ticket(ticket)
ticket_data = {
'id' : ticket.id,
'ticket_number' : ticket.ticket_number,
'title' : ticket.title,
'url' : f'/tickets/{ticket.id}',
}
reply_text = (
f"✅ **Ticket Created!**\n\n"
f"I've submitted your ticket **{ticket.ticket_number}**: _{ticket.title}_\n\n"
f"Our IT team has been notified and will get back to you shortly. "
f"You can track your ticket [here](/tickets/{ticket.id})."
)
except (json.JSONDecodeError, KeyError) as exc:
logger.warning(f'[CHATBOT PARSE ERROR] Could not parse ticket JSON: {exc}')
return jsonify({'reply': reply_text, 'ticket': ticket_data})