Merged in bugfix/dynamic-primary-issues (pull request #657)

Bugfix/dynamic primary issues

* Refactor TRIGGER_CAP special case configuration to utilize only trigger cap questions for two-stage processing

* Refactor get_special_cases to improve handling of N/A responses and merge methodology results with special case results

* Fix field type in get_special_cases for fee schedule breakout configuration

* Create fieldset.py - refactor

* Fix placeholders

* string concatenate new questions

* Update trigger cap questions output format

* Update TRIGGER_CAP_THRESHOLD_AMT prompt for clarity and specificity in reimbursement methodology

* Update constants class

* Update Field class

* Resolve constants passing

* Update field class - change Null criteria

* Add default

* Enhance documentation for get_special_cases function with detailed processing flow and architecture decisions

* Enhance get_special_cases and run_trigger_cap_breakout functions with detailed docstrings for clarity on processing methodologies

* Update constants passing

* Fix questions

* Update fs and mb questions"

* pass constanst correctly for dynamic

* Merge branch 'feature/trigger_cap_breakout' into bugfix/dynamic-primary-issues

* update constants

* only add questions if present

* ensure answer is a valid special_case

* Fix unit tests

* Remove test file


Approved-by: Alex Galarce
This commit is contained in:
Katon Minhas
2025-08-11 20:47:52 +00:00
parent 479e18b13f
commit 46be909642
27 changed files with 1149 additions and 766 deletions
+10 -11
View File
@@ -4,13 +4,12 @@ import re
import pandas as pd
import src.config as config
import src.prompts.investment_prompts as investment_prompts
import src.utils.embedding_utils as embedding_utils
import src.prompts.prompt_templates as prompt_templates
import src.utils.llm_utils as llm_utils
import src.utils.string_utils as string_utils
from constants.constants import Constants
from constants.delimiters import Delimiter
from src.prompts.investment_prompts import FieldSet
from src.prompts.fieldset import FieldSet
def clean_service(service, constants: Constants) -> str:
@@ -100,9 +99,9 @@ def code_explicit(service, filename):
# Prompt
code_primary_questions = FieldSet(
file_path=config.FIELD_JSON_PATH, field_type="code_primary_breakout"
).get_prompt_dict()
).print_prompt_dict()
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.CODE_EXPLICIT(service, code_primary_questions),
prompt_templates.CODE_EXPLICIT(service, code_primary_questions),
"sonnet_latest",
filename,
)
@@ -132,7 +131,7 @@ def code_category(service, proc_category, hcpcs_level2_mapping, filename):
if key.startswith(category)
]
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.CODE_CATEGORY(service, matching_values),
prompt_templates.CODE_CATEGORY(service, matching_values),
"sonnet_latest",
filename,
)
@@ -167,7 +166,7 @@ def code_implicit_special(service, filename):
"""
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.CODE_IMPLICIT_SPECIAL(service), "sonnet_latest", filename
prompt_templates.CODE_IMPLICIT_SPECIAL(service), "sonnet_latest", filename
)
claude_answer_final = string_utils.extract_text_from_delimiters(
claude_answer_raw, Delimiter.PIPE
@@ -183,7 +182,7 @@ def code_implicit_special(service, filename):
"ST": "ST Codes TBD",
}
code_answer_dict = {}
if not string_utils.is_empty(claude_answer_final):
if claude_answer_final in special_case_mapping:
code_answer_dict["PROCEDURE_CD"] = special_case_mapping[claude_answer_final]
code_answer_dict["PROCEDURE_CD_DESC"] = claude_answer_final
@@ -309,7 +308,7 @@ def code_implicit_rag(service, implicit_run_dict, filename, constants):
# Run Prompt
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.CODE_IMPLICIT(service, level_dict["match_list"]),
prompt_templates.CODE_IMPLICIT(service, level_dict["match_list"]),
"sonnet_latest",
filename,
)
@@ -386,7 +385,7 @@ def code_last_check(service, filename):
"""
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.CODE_LAST_CHECK(service), "sonnet_latest", filename
prompt_templates.CODE_LAST_CHECK(service), "sonnet_latest", filename
)
claude_answer_final = string_utils.extract_text_from_delimiters(
claude_answer_raw, Delimiter.PIPE
@@ -408,7 +407,7 @@ def fill_bill_type(service, answer_dict, BILL_TYPE_MAPPING, BILL_TYPE_REVERSE_MA
valid_bill_type = sorted(list(set(BILL_TYPE_MAPPING.values())))
claude_answer_raw = llm_utils.invoke_claude(
investment_prompts.FILL_BILL_TYPE(service, valid_bill_type), "sonnet_latest", ""
prompt_templates.FILL_BILL_TYPE(service, valid_bill_type), "sonnet_latest", ""
)
claude_answer_final = string_utils.universal_json_load(claude_answer_raw)