# Copyright (c) 2025 Patrick Motsch # All rights reserved. """Test KPI extraction with incomplete JSON""" import json import sys import os import pytest # Add gateway directory to path _gateway_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) if _gateway_path not in sys.path: sys.path.insert(0, _gateway_path) from modules.services.serviceAi.subJsonResponseHandling import JsonResponseHandler from modules.datamodels.datamodelAi import JsonAccumulationState from modules.shared.jsonUtils import extractJsonString, repairBrokenJson # Load actual incomplete JSON response json_file = os.path.join( os.path.dirname(__file__), "..", "..", "..", "local", "debug", "prompts", "20251130-211706-078-document_generation_response.txt" ) if not os.path.exists(json_file): pytest.skip(f"Test data file not found: {json_file}", allow_module_level=True) with open(json_file, 'r', encoding='utf-8') as f: content = f.read() print("="*60) print("KPI EXTRACTION WITH INCOMPLETE JSON TEST") print("="*60) # Step 1: Try to extract and parse JSON print(f"\nStep 1: Extracting JSON string...") extracted = extractJsonString(content) print(f" Extracted length: {len(extracted)} chars") # Step 2: Try to parse print(f"\nStep 2: Attempting to parse...") parsedJson = None try: parsedJson = json.loads(extracted) print(f" ✅ JSON parsed successfully") except json.JSONDecodeError as e: print(f" ❌ JSON parsing failed: {e}") print(f" Attempting repair...") try: parsedJson = repairBrokenJson(extracted) if parsedJson: print(f" ✅ JSON repaired successfully") else: print(f" ❌ JSON repair failed") except Exception as e2: print(f" ❌ Repair error: {e2}") if not parsedJson: pytest.skip("Cannot proceed - JSON cannot be parsed or repaired", allow_module_level=True) # Step 3: Check if path exists print(f"\nStep 3: Checking if KPI path exists...") path = "documents[0].sections[0].elements[0].rows" try: value = JsonResponseHandler._extractValueByPath(parsedJson, path) print(f" ✅ Path exists: {type(value)}") if isinstance(value, list): print(f" ✅ Value is list with {len(value)} items") if len(value) > 0: print(f" ✅ First item: {value[0]}") else: print(f" ⚠️ Value is not a list: {value}") except Exception as e: print(f" ❌ Path extraction failed: {e}") import traceback traceback.print_exc() pytest.skip(f"Path extraction failed: {e}", allow_module_level=True) # Step 4: Test KPI extraction print(f"\nStep 4: Testing KPI extraction...") kpiDefinitions = [{ "id": "prime_numbers_count", "description": "Number of prime numbers generated and organized in the table", "jsonPath": "documents[0].sections[0].elements[0].rows", "targetValue": 4000 }] accumulationState = JsonAccumulationState( accumulatedJsonString="", isAccumulationMode=True, lastParsedResult=parsedJson, allSections=[], kpis=[{**kpi, "currentValue": 0} for kpi in kpiDefinitions] ) print(f" Initial KPI currentValue: {accumulationState.kpis[0].get('currentValue', 'N/A')}") updatedKpis = JsonResponseHandler.extractKpiValuesFromJson( parsedJson, accumulationState.kpis ) print(f" Updated KPI currentValue: {updatedKpis[0].get('currentValue', 'N/A')}") # Step 5: Test validation print(f"\nStep 5: Testing KPI validation...") shouldProceed, reason = JsonResponseHandler.validateKpiProgression( accumulationState, updatedKpis ) print(f" Result: shouldProceed={shouldProceed}, reason={reason}") if not shouldProceed: print(f"\n❌ VALIDATION FAILED - This is the problem!") print(f" Let's debug why...") # Check what's being compared lastValues = {kpi.get("id"): kpi.get("currentValue", 0) for kpi in accumulationState.kpis} print(f" Last values from accumulationState: {lastValues}") for updatedKpi in updatedKpis: kpiId = updatedKpi.get("id") currentValue = updatedKpi.get("currentValue", 0) print(f" Updated KPI {kpiId}: currentValue={currentValue}") if kpiId in lastValues: lastValue = lastValues[kpiId] print(f" Comparing: {lastValue} vs {currentValue}") if currentValue > lastValue: print(f" ✅ Should detect progress!") else: print(f" ❌ No progress detected (currentValue <= lastValue)")