"""V2 API routes - Enhanced implementation with structured results.""" from __future__ import annotations import time from flask import Blueprint, jsonify, request from concurrent.futures import ThreadPoolExecutor from lawrisk.services.lawrisk_v2_service import search_v2, list_regions from lawrisk.services.licensing_repo import list_permits_for_region from lawrisk.services.lawrisk_service import suggest_questions_embed v2_bp = Blueprint('lawrisk_v2', __name__, url_prefix='/fs-ai-asistant/api/workflow/lawrisk') @v2_bp.route('/v2', methods=['POST', 'GET']) def lawrisk_search_v2(): """V2 search endpoint with structured results.""" query, debug_flag, top_k_int, _mode, region_filter = _extract_params() if not query or not isinstance(query, str): return jsonify({"error": "query is required"}), 400 try: t0 = time.time() with ThreadPoolExecutor(max_workers=2) as ex: fut_subject = ex.submit(search_v2, query, debug_flag, region_filter) fut_questions = ex.submit(suggest_questions_embed, query, max(1, top_k_int)) result_v2 = fut_subject.result() rec_questions = fut_questions.result() or [] risk_subject = result_v2.get("risk_subject", []) if isinstance(result_v2, dict) else [] found = bool(risk_subject) exec_time = int((time.time() - t0) * 1000) data = { "llmRespond": "" if found else "抱歉,无法检索到相关答案", "lawRisk": "", "questionExtend": rec_questions, "conversationId": "", "messageId": "", "roundNumber": 0, "conversationInfo": {}, "knowledgeSources": [], "totalKnowledgeSources": 0, "executionTime": exec_time, "workflowStatus": "ok" if found else "no_match", "executionSteps": [], "costStatistics": {}, "workflowTrackingId": "", "risk_subject": risk_subject, "debug": result_v2.get("debug", {}) if (debug_flag and isinstance(result_v2, dict)) else {}, } resp = {"success": True, "message": "OK", "data": data} return jsonify(resp) except Exception as e: print(f"lawrisk_search_v2 error: {e}") return jsonify({"success": False, "message": str(e), "data": {}}), 500 @v2_bp.get('/v2/regions') def lawrisk_regions(): """Get list of available regions.""" try: regions = list_regions() return jsonify({"success": True, "data": {"regions": regions}}) except Exception as exc: print(f"lawrisk_regions error: {exc}") return jsonify({"success": False, "message": str(exc)}), 500 @v2_bp.route('/getPermits', methods=['GET', 'POST']) def lawrisk_get_permits(): """Get permits for a specific region.""" if request.method == "GET": region_value = request.args.get("region") or request.args.get("region_id") else: if request.is_json: payload = request.get_json(silent=True) or {} else: payload = request.form.to_dict(flat=True) if request.form else {} region_value = payload.get("region") or payload.get("region_id") if not region_value or (isinstance(region_value, str) and not region_value.strip()): return jsonify({"success": False, "message": "region is required", "data": {}}), 400 region_token = region_value.strip() if isinstance(region_value, str) else str(region_value) try: permits = list_permits_for_region(region_token) return jsonify({"success": True, "data": {"region": region_token, "permits": permits}}) except Exception as exc: print(f"lawrisk_get_permits error: {exc}") return jsonify({"success": False, "message": str(exc)}), 500 def _extract_params(): """Extract parameters from request.""" if request.method == "GET": query = request.args.get("query") or request.args.get("q") or request.args.get("text") debug_flag = request.args.get("debug") in {"1", "true", "yes", "on"} top_k = request.args.get("top") try: top_k_int = int(top_k) if top_k else 5 except Exception: top_k_int = 5 mode_value = (request.args.get("mode") or "llm").lower() region_value = request.args.get("region") or request.args.get("region_id") region_list = request.args.getlist("region") if region_list and (not region_value or len(region_list) > 1): region_value = region_list else: if request.is_json: payload = request.get_json(silent=True) or {} else: payload = request.form.to_dict(flat=True) if request.form else {} query = payload.get("query") or payload.get("q") or payload.get("text") debug_flag = str(payload.get("debug", "")).strip().lower() in {"1", "true", "yes", "on"} try: top_k_int = int(payload.get("top", 5)) except Exception: top_k_int = 5 mode_value = str(payload.get("mode", "llm")).lower() region_value = payload.get("region") or payload.get("region_id") return query, debug_flag, top_k_int, mode_value, region_value