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})