""" Template Auto-Selection API Analyze seed data and recommend the best simulation template """ import json import os from flask import Blueprint, request, jsonify from ..utils.llm_client import LLMClient from ..utils.locale import t, get_locale, get_language_instruction from ..utils.logger import get_logger logger = get_logger('crowdsight.template') template_bp = Blueprint('template', __name__) # Load templates _templates_path = os.path.join(os.path.dirname(__file__), '..', 'templates.json') with open(_templates_path, 'r', encoding='utf-8') as f: _templates_data = json.load(f) _templates = _templates_data['templates'] @template_bp.route('/list', methods=['GET']) def list_templates(): """Return all available templates""" locale = get_locale() lang_key = f'prompt_{locale}' if locale in ('th', 'en', 'zh') else 'prompt_en' result = [] for tmpl in _templates: result.append({ 'id': tmpl['id'], 'icon': tmpl['icon'], 'category': tmpl['category'], 'prompt': tmpl.get(lang_key, tmpl['prompt_en']), 'placeholders': tmpl['placeholders'], 'name': t(f'templates.{tmpl["id"]}'), }) return jsonify({'success': True, 'templates': result}) @template_bp.route('/auto-select', methods=['POST']) def auto_select_template(): """ Analyze seed data and recommend the best template + pre-fill prompt. Request JSON: { "text": "extracted text from uploaded documents", "simulation_requirement": "optional user requirement" } Response JSON: { "success": true, "template_id": "news_event", "prompt": "pre-filled prompt with actual values", "confidence": 0.85, "reasoning": "why this template was selected" } """ try: data = request.get_json() or {} text = data.get('text', '')[:5000] # Limit to 5000 chars simulation_requirement = data.get('simulation_requirement', '') if not text: return jsonify({'success': False, 'error': 'No text provided'}), 400 locale = get_locale() lang_instruction = get_language_instruction() # Build template descriptions for the LLM template_desc = [] lang_key = f'prompt_{locale}' if locale in ('th', 'en', 'zh') else 'prompt_en' for tmpl in _templates: template_desc.append(f"- {tmpl['id']}: {tmpl.get(lang_key, tmpl['prompt_en'])}") templates_list = '\n'.join(template_desc) system_prompt = f"""You are a smart assistant that analyzes document content and recommends the best simulation template. Available templates: {templates_list} Your task: 1. Analyze the document content 2. Select the MOST appropriate template 3. Fill in the template placeholders with actual values from the document 4. Return the result in JSON format {lang_instruction}""" user_prompt = f"""Document content: {text[:3000]} {f'User requirement: {simulation_requirement}' if simulation_requirement else ''} Return JSON: {{ "template_id": "best_template_id", "prompt": "the template with placeholders filled in with actual values from the document", "confidence": 0.0-1.0, "reasoning": "brief explanation of why this template was chosen" }}""" llm = LLMClient() result = llm.chat_json( messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ], temperature=0.3 ) # Validate template_id valid_ids = [t['id'] for t in _templates] if result.get('template_id') not in valid_ids: result['template_id'] = 'news_event' # Default fallback return jsonify({ 'success': True, 'template_id': result.get('template_id', 'news_event'), 'prompt': result.get('prompt', ''), 'confidence': result.get('confidence', 0.5), 'reasoning': result.get('reasoning', ''), }) except Exception as e: logger.error(f"Template auto-select failed: {e}") return jsonify({'success': False, 'error': str(e)}), 500 @template_bp.route('//filter-rules', methods=['GET']) def get_filter_rules(template_id): """Return entity filter rules for a template (used by Step 1)""" for tmpl in _templates: if tmpl['id'] == template_id: return jsonify({ 'success': True, 'template_id': template_id, 'filter_rules': tmpl.get('entity_filter', {}) }) return jsonify({'success': False, 'error': 'Template not found'}), 404