diff --git a/src/pipelines/saas/prompts/prompt_calls.py b/src/pipelines/saas/prompts/prompt_calls.py index df9688b..8fa213e 100644 --- a/src/pipelines/saas/prompts/prompt_calls.py +++ b/src/pipelines/saas/prompts/prompt_calls.py @@ -749,7 +749,7 @@ def prompt_lesser_of_check( "exhibit_reference": None, } - logging.info( + logging.debug( f"LESSER_OF_CHECK classification: scope={llm_answer_final['scope']}, " f"target={llm_answer_final['target_exhibit']}, " f"exhibit_ref={llm_answer_final.get('exhibit_reference')}, " @@ -862,3 +862,21 @@ def provider_name_match_check( ) return False +def prompt_split_reimb_dates(date_range: str, filename: str) -> dict: + prompt, _parser = prompt_templates.SPLIT_REIMB_DATES(date_range) + + # Invoke LLM to split the date range + llm_answer_raw = llm_utils.invoke_claude( + prompt, + model_id="sonnet_latest", + filename=filename, + max_tokens=200, + cache=True, + instruction=prompt_templates.SPLIT_REIMB_DATES_INSTRUCTION(), + usage_label="SPLIT_REIMB_DATES", + ) + + # Extract the effective and termination dates from the LLM output + llm_answer_final = _parser(llm_answer_raw) + return llm_answer_final + diff --git a/src/pipelines/shared/extraction/dynamic_funcs.py b/src/pipelines/shared/extraction/dynamic_funcs.py index df412a3..55f3d55 100644 --- a/src/pipelines/shared/extraction/dynamic_funcs.py +++ b/src/pipelines/shared/extraction/dynamic_funcs.py @@ -54,13 +54,7 @@ def dynamic_primary( if not string_utils.is_empty(exhibit_text_answer): # Special handling for LOB: If both Medicare and Medicaid are detected, add Duals if field.field_name == "LOB": - # Parse the discovered values (pipe-delimited or comma-separated) - values_list = [ - val.strip() - for val in exhibit_text_answer.replace(",", "|").split("|") - if val.strip() - ] - values_lower = [val.lower() for val in values_list] + values_lower = [val.lower() for val in exhibit_text_answer] # Check if both Medicare and Medicaid are present (case-insensitive) has_medicare = any("medicare" in val for val in values_lower) @@ -69,16 +63,16 @@ def dynamic_primary( # If both are present and Duals is not already in the list, add it if has_medicare and has_medicaid: if "duals" not in values_lower: - exhibit_text_answer = ( - exhibit_text_answer + " | Duals" - if exhibit_text_answer - else "Duals" - ) + if exhibit_text_answer: + exhibit_text_answer.append("Duals") + else: + exhibit_text_answer = ["Duals"] logging.debug( f"Added 'Duals' to LOB valid values because both Medicare and Medicaid were detected" ) - field.update_valid_values(exhibit_text_answer + " | N/A") + + field.update_valid_values(exhibit_text_answer + ["N/A"]) dynamic_reimbursement_fields.add_field(field) dynamic_primary_fields.remove_field(field.field_name) # If the field is not found, add to Exhibit-Level answers (the answer will be N/A or similar) diff --git a/src/pipelines/shared/extraction/one_to_n_funcs.py b/src/pipelines/shared/extraction/one_to_n_funcs.py index 24bf816..c04bf73 100644 --- a/src/pipelines/shared/extraction/one_to_n_funcs.py +++ b/src/pipelines/shared/extraction/one_to_n_funcs.py @@ -675,29 +675,16 @@ def split_reimb_dates(one_to_n_results: list, filename: str) -> list: date_range = str(record["REIMB_DATES"]).strip() try: - # Invoke LLM to split the date range - llm_output_raw = llm_utils.invoke_claude( - prompt_templates.SPLIT_REIMB_DATES(date_range), - model_id="sonnet_latest", - filename=filename, - max_tokens=200, - cache=True, - instruction=prompt_templates.SPLIT_REIMB_DATES_INSTRUCTION(), - usage_label="SPLIT_REIMB_DATES", - ) - - # Extract the effective and termination dates from the LLM output - llm_output_cleaned = string_utils.universal_json_load(llm_output_raw) - + llm_answer_final = prompt_calls.prompt_split_reimb_dates(date_range, filename) # Update the specific record with parsed dates - if llm_output_cleaned and isinstance(llm_output_cleaned, dict): - if "start_date" in llm_output_cleaned: - record["REIMB_EFFECTIVE_DT"] = llm_output_cleaned["start_date"] - if "end_date" in llm_output_cleaned: - record["REIMB_TERMINATION_DT"] = llm_output_cleaned["end_date"] + if llm_answer_final and isinstance(llm_answer_final, dict): + if "start_date" in llm_answer_final: + record["REIMB_EFFECTIVE_DT"] = llm_answer_final["start_date"] + if "end_date" in llm_answer_final: + record["REIMB_TERMINATION_DT"] = llm_answer_final["end_date"] else: logging.error( - f"Invalid LLM output format for index {index}: {llm_output_cleaned}" + f"Invalid LLM output format for index {index}: {llm_answer_final}" ) except Exception as e: @@ -856,26 +843,26 @@ def lesser_of_distribution( # GLOBAL: Store for cross-exhibit, don't add to results if scope == "GLOBAL": exhibit.add_lesser_of_statement(lesser_of_answer_dict) - logging.info( + logging.debug( f"Stored GLOBAL template from page {page_num} - NOT added to results" ) # EXHIBIT_SPECIFIC (OTHER): Store for cross-exhibit, don't add to results elif scope == "EXHIBIT_SPECIFIC" and target == "OTHER": exhibit.add_lesser_of_statement(lesser_of_answer_dict) - logging.info( + logging.debug( f"Stored cross-exhibit template from page {page_num} - NOT added to results" ) # EXHIBIT_SPECIFIC (CURRENT): Don't store (race condition), don't add to results elif scope == "EXHIBIT_SPECIFIC" and target == "CURRENT": - logging.info( + logging.debug( f"CURRENT template from page {page_num} - handled via text search - NOT added to results" ) # STANDALONE: Complete rate - ADD to results elif scope == "STANDALONE": - logging.info(f"STANDALONE rate from page {page_num} - ADDED to results") + logging.debug(f"STANDALONE rate from page {page_num} - ADDED to results") final_reimbursement_level_answers.append( answer_dict ) # ← Only this gets added