Merged in feature/update-exhibit-linking (pull request #732)
Feature/update exhibit linking * Update exhibit linking * prompt_calls refactor * remove test Approved-by: Karan Desai
This commit is contained in:
@@ -1,12 +1,8 @@
|
||||
import logging
|
||||
import re
|
||||
|
||||
import src.utils.llm_utils as llm_utils
|
||||
import src.utils.string_utils as string_utils
|
||||
from constants.delimiters import Delimiter
|
||||
from src.investment import table_funcs
|
||||
from src.prompts import prompt_templates
|
||||
|
||||
from src.investment import table_funcs, prompt_calls
|
||||
|
||||
def remove_page_indicators(contract_text: str) -> str:
|
||||
"""Clean textract output by removing page number indicators in the form of "Page X of Y"
|
||||
@@ -132,20 +128,12 @@ def get_exhibit_pages(
|
||||
first_page = False
|
||||
else:
|
||||
if "." not in page_num or ".0" in page_num:
|
||||
prompt = prompt_templates.EXHIBIT_HEADER(
|
||||
page_content[0:400], EXHIBIT_HEADER_MARKERS
|
||||
)
|
||||
claude_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, "sonnet_latest", filename, max_tokens=300
|
||||
)
|
||||
claude_answer_extracted = string_utils.extract_text_from_delimiters(
|
||||
claude_answer_raw, Delimiter.PIPE
|
||||
)
|
||||
if "N/A" in claude_answer_extracted:
|
||||
exhibit_header = prompt_calls.prompt_exhibit_header(page_content, EXHIBIT_HEADER_MARKERS, filename)
|
||||
if "N/A" in exhibit_header:
|
||||
is_exhibit = False
|
||||
else:
|
||||
exhibit_pages.append(page_num)
|
||||
exhibit_header_dict[page_num] = claude_answer_extracted
|
||||
exhibit_header_dict[page_num] = exhibit_header
|
||||
is_exhibit = True
|
||||
elif is_exhibit == True:
|
||||
exhibit_pages.append(page_num)
|
||||
@@ -212,13 +200,7 @@ def link_exhibit_pages(
|
||||
exhibit_is_different = "Y"
|
||||
previous_header = page_header
|
||||
else:
|
||||
prompt = prompt_templates.EXHIBIT_LINKAGE(page_header, previous_header)
|
||||
claude_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, "legacy_sonnet", filename
|
||||
)
|
||||
exhibit_is_different = string_utils.extract_text_from_delimiters(
|
||||
claude_answer_raw, Delimiter.PIPE
|
||||
)
|
||||
exhibit_is_different = prompt_calls.prompt_exhibit_linkage(page_header, previous_header, filename)
|
||||
previous_header = page_header
|
||||
|
||||
# If the prompt has identified that the current exhibit is meaningfully different than the previous
|
||||
|
||||
@@ -477,3 +477,25 @@ def prompt_dynamic(text, field_prompts, filename):
|
||||
logging.debug(f"Dynamic answer for {filename}: {llm_answer_raw}")
|
||||
llm_answer_final = string_utils.universal_json_load(llm_answer_raw)
|
||||
return llm_answer_final
|
||||
|
||||
def prompt_exhibit_linkage(page_header, previous_header, filename):
|
||||
prompt = prompt_templates.EXHIBIT_LINKAGE(page_header, previous_header)
|
||||
claude_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, "legacy_sonnet", filename
|
||||
)
|
||||
exhibit_is_different = string_utils.extract_text_from_delimiters(
|
||||
claude_answer_raw, Delimiter.PIPE
|
||||
)
|
||||
return exhibit_is_different
|
||||
|
||||
def prompt_exhibit_header(page_content, EXHIBIT_HEADER_MARKERS, filename):
|
||||
prompt = prompt_templates.EXHIBIT_HEADER(
|
||||
page_content[0:400], EXHIBIT_HEADER_MARKERS
|
||||
)
|
||||
llm_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, "sonnet_latest", filename, max_tokens=300
|
||||
)
|
||||
llm_answer_extracted = string_utils.extract_text_from_delimiters(
|
||||
llm_answer_raw, Delimiter.PIPE
|
||||
)
|
||||
return llm_answer_extracted
|
||||
@@ -818,19 +818,20 @@ def EXHIBIT_HEADER(context, EXHIBIT_HEADER_MARKERS):
|
||||
Capture the complete hierarchy of document identifiers present in the text. The following keywords and phrases should be considered as exhibit/attachment headers:
|
||||
* {'\n* '.join(EXHIBIT_HEADER_MARKERS)}
|
||||
|
||||
Include the following when present:
|
||||
Rules for Inclusion:
|
||||
* Include ALL text that appears to be part of the header
|
||||
* Full header names and numbers/letters (e.g., "Attachment C: Commercial-Exchange")
|
||||
* Any other relevant subtitles and identifiers
|
||||
* Any words in the header that may specify what type of information is contained, such as "Compensation Schedule" or "Definitions".
|
||||
* Provider/Entity names when listed with exhibit information
|
||||
* Keep exact capitalization and formatting as shown in document
|
||||
* Include any information referring to the current exhibit's relationship with another exhibit (e.g. "Exhibit 1: Provider Roster (see Exhibit 2 for Compensation Schedule)")
|
||||
|
||||
- Rules for inclusion:
|
||||
- Rules for Exclusion:
|
||||
* Do NOT abbreviate or summarize any part of the exhibit names
|
||||
* Do NOT include page numbers
|
||||
* Do NOT cherry-pick only certain parts - capture the complete hierarchy
|
||||
* Do NOT include docusign IDs and other metadata
|
||||
* Include ALL text that appears to be part of the header
|
||||
* Keep exact capitalization and formatting as shown in document
|
||||
* DO NOT include unrelated text written in lowercase or title case.
|
||||
|
||||
If there is no Exhibit Header present, return |N/A|. Do not fill in values from the examples above, these are only examples.
|
||||
@@ -852,6 +853,7 @@ def EXHIBIT_LINKAGE(header1, header2):
|
||||
* The headers may refer to Attachment, Exhibit, Schedule, Addendum, or similar. If the highest-level number is identical, then the Headers ARE meaningfully different. For example, "Exhibit B-1" and "Exhibit B-2" are meaningfully different because they are both Exhibit B but have different sub-exhibits.
|
||||
* If the headers have the same numbers, but different descriptors, they are NOT meaningfully different. For example, "Attachment A" and "Attachment A: Professional" are NOT meaningfully different because they are both attachment A.
|
||||
* If one header is a continuation of the other (e.g. "Continued", "CONT'D"), they are NOT meaningfully different.
|
||||
* If Header 1 directly references Header 2 in a way that links the two, then they are NOT meaningfully different. This linkage also applies if Header 2 references Header 1.
|
||||
* Return |Y| if the two Headers are meaningfully different. Return |N| if they are not.
|
||||
|
||||
[CONTEXT]
|
||||
|
||||
Reference in New Issue
Block a user