Merged in feature/further-phase-1-and-2-fixes (pull request #624)
Sonnet 4 and model aliasing * Add EXHIBIT_HEADER_MARKERS for improved document header recognition in table handling * Refactor EXHIBIT_HEADER_MARKERS definition for improved clarity and organization * remove unused page span tracking code; add unit tests for new functionality * remove debugging logs from combine_continuous_tables function * Refactor logging setup and update test file configuration in investment field testing notebook * Merge remote-tracking branch 'origin/main' into feature/further-phase-1-and-2-fixes * Merge remote-tracking branch 'origin/main' into feature/further-phase-1-and-2-fixes * Refactor model ID handling and add support for model aliases in llm_utils * Update model IDs to use alias in LLM invocation functions in one_to_n_funcs * change pre-and-post-processing to new model alias method * Update model ID references to use 'sonnet_latest' in LLM invocation functions * Update LLM invocation functions to use 'sonnet_latest' model ID * Update LLM invocation functions to use 'sonnet_latest' and 'haiku_latest' model IDs * update invoke_claude function docstring * Fix caller frame to address mypy error Approved-by: Katon Minhas
This commit is contained in:
@@ -236,7 +236,21 @@ MODEL_ID_CLAUDE35_SONNET = "anthropic.claude-3-5-sonnet-20240620-v1:0"
|
||||
MODEL_ID_CLAUDE2 = "anthropic.claude-instant-v1"
|
||||
MODEL_ID_CLAUDE35_SONNET_V2 = "anthropic.claude-3-5-sonnet-20241022-v2:0"
|
||||
MODEL_ID_CLAUDE37_SONNET = "anthropic.claude-3-7-sonnet-20250219-v1:0"
|
||||
MODEL_ID_CLAUDE4_SONNET = "anthropic.claude-sonnet-4-20250514-v1:0"
|
||||
MODEL_ID_CLAUDE4_SONNET = "us.anthropic.claude-sonnet-4-20250514-v1:0"
|
||||
|
||||
# Model aliases for easy upgrades
|
||||
MODEL_ALIASES = {
|
||||
"sonnet_latest": MODEL_ID_CLAUDE4_SONNET,
|
||||
"haiku_latest": MODEL_ID_CLAUDE3_HAIKU,
|
||||
"legacy_sonnet": MODEL_ID_CLAUDE35_SONNET,
|
||||
}
|
||||
|
||||
def resolve_model_id(model_identifier: str) -> str:
|
||||
"""
|
||||
Resolve a model identifier to its actual model ID.
|
||||
Supports both direct model IDs and aliases.
|
||||
"""
|
||||
return MODEL_ALIASES.get(model_identifier, model_identifier)
|
||||
|
||||
######################################## CLAUDE AND PROMPT TRACKING ########################################
|
||||
ENABLE_ANSWER_TRACKING = False
|
||||
|
||||
@@ -126,7 +126,7 @@ def get_aarete_derived(aarete_derived_fields: FieldSet,
|
||||
# Invoke Claude and extract answer
|
||||
field_answer_raw = llm_utils.invoke_claude(
|
||||
field_prompt,
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename,
|
||||
8192
|
||||
)
|
||||
|
||||
@@ -147,7 +147,7 @@ def code_primary(service, code_primary_questions, filename):
|
||||
if not string_utils.is_empty(service):
|
||||
claude_answer_raw = llm_utils.invoke_claude(
|
||||
investment_prompts.CODE_PRIMARY_BREAKOUT(str(service), code_primary_questions),
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename
|
||||
)
|
||||
code_answer_dict = string_utils.universal_json_load(claude_answer_raw)
|
||||
@@ -290,7 +290,7 @@ def code_implicit(service, filename):
|
||||
list: Updated list of dictionaries with mapped CPT4 procedure codes and descriptions.
|
||||
"""
|
||||
if not string_utils.is_empty(service):
|
||||
claude_answer_raw = llm_utils.invoke_claude(investment_prompts.CODE_IMPLICIT(service), config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
claude_answer_raw = llm_utils.invoke_claude(investment_prompts.CODE_IMPLICIT(service), "sonnet_latest", filename)
|
||||
code_answer_final = string_utils.universal_json_load(claude_answer_raw)
|
||||
else:
|
||||
code_answer_final = ""
|
||||
|
||||
@@ -20,7 +20,7 @@ def prompt_dynamic(text, field_prompts, filename):
|
||||
dict: A dictionary containing field names as keys and extracted answers as values.
|
||||
"""
|
||||
prompt = investment_prompts.EXHIBIT_LEVEL(text, field_prompts)
|
||||
llm_answer_raw = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename) # Returns dictionary of lists
|
||||
llm_answer_raw = llm_utils.invoke_claude(prompt, "sonnet_latest", filename) # Returns dictionary of lists
|
||||
llm_answer_final = string_utils.universal_json_load(llm_answer_raw)
|
||||
return llm_answer_final
|
||||
|
||||
@@ -45,7 +45,7 @@ def get_dynamic_one_to_one_fields(answer_dicts):
|
||||
def prompt_dynamic_primary(exhibit_text, field, filename):
|
||||
# Prompt Exhibit Header
|
||||
prompt = investment_prompts.DYNAMIC_PRIMARY(exhibit_text, field.field_name, field.get_prompt())
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, "sonnet_latest", filename)
|
||||
claude_answer_final = string_utils.extract_text_from_delimiters(claude_answer_raw, string_utils.Delimiter.PIPE)
|
||||
if "," in claude_answer_final:
|
||||
claude_answer_final = "|".join([item.strip() for item in claude_answer_final.split(",")])
|
||||
|
||||
@@ -474,7 +474,7 @@ def update_lob_for_duals(answer_dicts):
|
||||
# Check if the SERVICE_TERM contains "Medicare" and "Medicaid" - case insensitive
|
||||
if 'medicare' in service_term and 'medicaid' in service_term:
|
||||
prompt = investment_prompts.DUAL_LOB_CHECK(service_term)
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, model_id=config.MODEL_ID_CLAUDE35_SONNET, filename="", max_tokens=200)
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, model_id="sonnet_latest", filename="", max_tokens=200)
|
||||
claude_answer_extracted = string_utils.extract_text_from_delimiters(claude_answer_raw, Delimiter.PIPE)
|
||||
answer_dict["AARETE_DERIVED_LOB"] = claude_answer_extracted
|
||||
final_answer_dicts.append(answer_dict)
|
||||
|
||||
@@ -34,7 +34,7 @@ def get_exhibit_level_answers(exhibit_chunk, filename):
|
||||
|
||||
prompt = EXHIBIT_LEVEL(exhibit_chunk, exhibit_level_fields.print_prompt_dict())
|
||||
llm_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, max_tokens=8192
|
||||
prompt, "sonnet_latest", filename, max_tokens=8192
|
||||
)
|
||||
logging.debug(f"LLM raw output for {filename}: {llm_answer_raw}")
|
||||
llm_answer_final = string_utils.universal_json_load(llm_answer_raw)
|
||||
@@ -50,7 +50,7 @@ def get_reimbursement_primary(reimbursement_level_fields, exhibit_text, filename
|
||||
{prompt}"""
|
||||
)
|
||||
llm_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, max_tokens=25000
|
||||
prompt, "sonnet_latest", filename, max_tokens=25000
|
||||
)
|
||||
logging.debug(
|
||||
f"""LLM raw output for {filename}:
|
||||
@@ -95,7 +95,7 @@ def get_special_cases(
|
||||
investment_prompts.SPECIAL_CASE_CHECK(
|
||||
contract_service_cd, contract_reimbursement_method
|
||||
),
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename,
|
||||
)
|
||||
special_case_answer = string_utils.extract_text_from_delimiters(
|
||||
@@ -106,7 +106,7 @@ def get_special_cases(
|
||||
investment_prompts.CARVEOUT_CHECK(
|
||||
contract_service_cd, contract_reimbursement_method
|
||||
),
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename,
|
||||
)
|
||||
carveout_answer = string_utils.extract_text_from_delimiters(
|
||||
@@ -289,7 +289,7 @@ def methodology_breakout_single_row(
|
||||
logging.debug(f"Methodology Breakout Prompt for {filename}: {prompt}")
|
||||
llm_response = llm_utils.invoke_claude(
|
||||
prompt,
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename,
|
||||
)
|
||||
logging.debug(f"LLM Response for {filename}: {llm_response}")
|
||||
@@ -327,7 +327,7 @@ def methodology_breakout_single_row(
|
||||
methodology_breakout_dict.get("FEE_SCHEDULE"),
|
||||
fs_breakout_questions,
|
||||
),
|
||||
config.MODEL_ID_CLAUDE35_SONNET,
|
||||
"sonnet_latest",
|
||||
filename,
|
||||
)
|
||||
)
|
||||
@@ -619,7 +619,7 @@ def validate_reimbursements_for_llm(answer_dict: dict, filename: str) -> bool:
|
||||
prompt = investment_prompts.VALIDATE_REIMBURSEMENTS_PROMPT(service_term, reimb_term)
|
||||
|
||||
llm_response = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE3_HAIKU, filename # try haiku for speed/cost
|
||||
prompt, "haiku_latest", filename # try haiku for speed/cost
|
||||
)
|
||||
|
||||
final_answer = string_utils.extract_text_from_delimiters(
|
||||
@@ -689,7 +689,7 @@ def split_compound_reimbursement_llm(answer_dict: dict, filename: str) -> list[d
|
||||
service_term, reimb_term)
|
||||
try:
|
||||
llm_response = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE3_HAIKU, filename, max_tokens=4096
|
||||
prompt, "haiku_latest", filename, max_tokens=4096
|
||||
)
|
||||
|
||||
split_data = string_utils.universal_json_load(llm_response)
|
||||
@@ -904,6 +904,6 @@ def is_exhibit_lesser_of_redundant(reimb_term: str, exhibit_lesser_of: str, file
|
||||
|
||||
prompt = investment_prompts.CHECK_REDUNDANT_LESSER(reimb_term, exhibit_lesser_of)
|
||||
|
||||
response = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE3_HAIKU, filename=filename)
|
||||
response = llm_utils.invoke_claude(prompt, "haiku_latest", filename=filename)
|
||||
# logging.debug(f"LLM response for redundancy check in {filename}: {response}")
|
||||
return string_utils.extract_text_from_delimiters(response, Delimiter.PIPE).strip().upper() == "YES"
|
||||
@@ -38,7 +38,7 @@ def extract_global_lesser_of(contract_text: str, filename:str) -> dict:
|
||||
|
||||
logging.debug(f"Extracting global lesser of statement for {filename} with prompt: {prompt}")
|
||||
|
||||
response = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
response = llm_utils.invoke_claude(prompt, "sonnet_latest", filename)
|
||||
|
||||
logging.debug(f"Response for global lesser of statement extraction: {response}")
|
||||
return {"GLOBAL_LESSER_OF_STATEMENT": string_utils.extract_text_from_delimiters(response, Delimiter.PIPE) or "N/A"}
|
||||
@@ -142,7 +142,7 @@ def run_smart_chunked_fields(one_to_one_fields: FieldSet,
|
||||
|
||||
try:
|
||||
field_group_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, 8192
|
||||
prompt, "sonnet_latest", filename, 8192
|
||||
)
|
||||
if len(fields) == 1:
|
||||
field_group_answer_parsed = string_utils.extract_text_from_delimiters(field_group_answer_raw, Delimiter.PIPE)
|
||||
@@ -306,7 +306,7 @@ def run_global_lesser_of_breakout(global_lesser_of_stmt: str, filename: str) ->
|
||||
prompt = REIMB_TERM_BREAKOUT(mock_service, global_lesser_of_stmt, METHODOLOGY_BREAKOUT_QUESTIONS)
|
||||
logging.debug(f"Running global lesser of breakout for {filename} with prompt: {prompt}")
|
||||
|
||||
llm_response = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
llm_response = llm_utils.invoke_claude(prompt, "sonnet_latest", filename)
|
||||
|
||||
try:
|
||||
breakout_results = string_utils.universal_json_load(llm_response)
|
||||
|
||||
@@ -241,7 +241,7 @@ def identify_group_provider(text_dict: dict, providers: list[dict], filename: st
|
||||
prompt = investment_prompts.GROUP_TIN_NPI_TEMPLATE(key_sections=key_sections, provider_list=provider_list)
|
||||
|
||||
# Get response and parse
|
||||
response = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
response = llm_utils.invoke_claude(prompt, "sonnet_latest", filename)
|
||||
try:
|
||||
group_info = json.loads(string_utils.extract_text_from_delimiters(response, Delimiter.PIPE))
|
||||
|
||||
@@ -336,7 +336,7 @@ def get_provider_info(text_dict: dict, page_num : str, filename: str) -> list:
|
||||
|
||||
provider_fields = FieldSet(file_path=config.FIELD_JSON_PATH, field_type="provider_info")
|
||||
prompt = investment_prompts.TIN_NPI_TEMPLATE(chunk, provider_fields.print_prompt_dict())
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, max_tokens=8192) # Sometimes rosters can have 50+ provider
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, "sonnet_latest", filename, max_tokens=8192) # Sometimes rosters can have 50+ provider
|
||||
|
||||
# Defensive programming for any json parsing errors
|
||||
try:
|
||||
|
||||
@@ -943,7 +943,7 @@ def clean_lob(df, filename):
|
||||
):
|
||||
prompt = postprocessing_prompts.LOB_SWEEPER(row["EXHIBIT"])
|
||||
answer = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, 256
|
||||
prompt, "sonnet_latest", filename, 256
|
||||
)
|
||||
return answer # Return the value from 'EXHIBIT' if condition is met
|
||||
return row["CONTRACT_LOB"]
|
||||
@@ -1184,7 +1184,7 @@ def date_postprocessing(date: str) -> str:
|
||||
return "N/A"
|
||||
|
||||
prompt = investment_prompts.DATE_FIX_PROMPT(date)
|
||||
response = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, "date_fix")
|
||||
response = llm_utils.invoke_claude(prompt, "sonnet_latest", "date_fix")
|
||||
return extract_text_from_delimiters(response, Delimiter.PIPE)
|
||||
|
||||
def generate_reimb_ids(df: pd.DataFrame) -> pd.DataFrame:
|
||||
|
||||
@@ -243,7 +243,7 @@ def get_exhibit_pages(text_dict: dict[str, str], filename: str) -> tuple[list[st
|
||||
if "." not in page_num or ".0" in page_num:
|
||||
prompt = investment_prompts.EXHIBIT_HEADER(page_content[0:400])
|
||||
claude_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename, max_tokens=300
|
||||
prompt, "sonnet_latest", filename, max_tokens=300
|
||||
)
|
||||
claude_answer_extracted = string_utils.extract_text_from_delimiters(
|
||||
claude_answer_raw, Delimiter.PIPE
|
||||
@@ -304,7 +304,7 @@ def link_exhibit_pages(all_exhibit_headers, filename):
|
||||
previous_header = page_header
|
||||
else:
|
||||
prompt = investment_prompts.EXHIBIT_LINKAGE(page_header, previous_header)
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, config.MODEL_ID_CLAUDE35_SONNET, filename)
|
||||
claude_answer_raw = llm_utils.invoke_claude(prompt, "sonnet_latest", filename)
|
||||
exhibit_is_different = string_utils.extract_text_from_delimiters(claude_answer_raw, Delimiter.PIPE)
|
||||
previous_header = page_header
|
||||
|
||||
@@ -502,7 +502,7 @@ def get_exhibit_headers(exhibit_dict: dict[str, str], filename: str) -> dict[str
|
||||
else:
|
||||
prompt = investment_prompts.EXHIBIT_HEADER(exhibit_chunk[0:400])
|
||||
llm_answer_raw = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE35_SONNET, filename
|
||||
prompt, "sonnet_latest", filename
|
||||
)
|
||||
llm_answer_final = string_utils.extract_text_from_delimiters(
|
||||
llm_answer_raw, Delimiter.PIPE
|
||||
|
||||
@@ -6,7 +6,6 @@ import pandas as pd
|
||||
import src.constants.valid as valid
|
||||
import src.utils.llm_utils as llm_utils
|
||||
import src.utils.string_utils as string_utils
|
||||
from src.config import MODEL_ID_CLAUDE35_SONNET
|
||||
from src.constants.investment_values import (
|
||||
EXHIBIT_HEADER_MARKERS,
|
||||
VALID_AARETE_DERIVED_FEE_SCHEDULE,
|
||||
@@ -782,7 +781,7 @@ def DERIVED_TERM_DATE_PROMPT(effective_date:str=None, termination_information:st
|
||||
@cache
|
||||
def invoke_derived_term_date(effective_date:str=None, termination_information:str=None) -> str:
|
||||
prompt = DERIVED_TERM_DATE_PROMPT(effective_date, termination_information)
|
||||
response = llm_utils.invoke_claude(prompt, MODEL_ID_CLAUDE35_SONNET, "derive_term_date")
|
||||
response = llm_utils.invoke_claude(prompt, "sonnet_latest", "derive_term_date")
|
||||
return extract_text_from_delimiters(response, Delimiter.PIPE)
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import hashlib
|
||||
import inspect
|
||||
import csv
|
||||
import base64
|
||||
import logging
|
||||
|
||||
def update_stats(filename, tokens_sent, tokens_received, elapsed_time, model_type):
|
||||
# Update per-file statistics
|
||||
@@ -110,7 +111,29 @@ def get_cache_key(prompt, model_id):
|
||||
"""Generates a unique hash key for caching."""
|
||||
return hashlib.sha256(f"{model_id}:{prompt}".encode()).hexdigest()
|
||||
|
||||
def invoke_claude(prompt, model_id, filename, max_tokens=4096):
|
||||
def invoke_claude(prompt: str, model_id: str, filename: str, max_tokens: int = 4096) -> str:
|
||||
"""Invokes the Claude model with the given parameters.
|
||||
|
||||
Args:
|
||||
prompt (str): The input prompt to send to the model.
|
||||
model_id (str): The ID of the model to use. Supports both direct model IDs
|
||||
(e.g. 'anthropic.claude-3-5-sonnet-20240620-v1:0') as well as aliases (e.g.
|
||||
'sonnet_latest', 'haiku_latest', etc.).
|
||||
filename (str): The name of the file being processed, for cost logging purposes.
|
||||
max_tokens (int, optional): The maximum number of tokens to generate. Defaults to 4096.
|
||||
|
||||
Raises:
|
||||
ValueError: If the model_id is not supported after alias resolution
|
||||
|
||||
Returns:
|
||||
str: The model's response.
|
||||
|
||||
Note:
|
||||
- Responses are cached using LRU eviction (limit: 20,000 entries)
|
||||
- Includes automatic retry logic with exponential backoff for throttling
|
||||
- Cost logging is performed automatically for all successful requests
|
||||
- Model aliases are resolved via config.resolve_model_id()
|
||||
"""
|
||||
cache_key = get_cache_key(prompt, model_id)
|
||||
|
||||
# Check cache first - use get() method from LRUCache
|
||||
@@ -118,40 +141,43 @@ def invoke_claude(prompt, model_id, filename, max_tokens=4096):
|
||||
claude_cache.move_to_end(cache_key) # Mark as recently used
|
||||
return claude_cache[cache_key]
|
||||
|
||||
# Resolve alias to actual model ID
|
||||
resolved_model_id = config.resolve_model_id(model_id)
|
||||
|
||||
# Select execution mode
|
||||
if config.RUN_MODE == "local":
|
||||
if model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = local_claude_2(prompt, model_id, filename, max_tokens)
|
||||
if resolved_model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = local_claude_2(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.008, 0.024
|
||||
elif model_id == config.MODEL_ID_CLAUDE3_HAIKU:
|
||||
response = local_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE3_HAIKU:
|
||||
response = local_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.00025, 0.00125
|
||||
elif model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = local_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = local_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
elif model_id == config.MODEL_ID_CLAUDE37_SONNET:
|
||||
response = local_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE37_SONNET:
|
||||
response = local_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
elif model_id == config.MODEL_ID_CLAUDE4_SONNET:
|
||||
response = local_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE4_SONNET:
|
||||
response = local_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
else:
|
||||
raise ValueError(f"Unsupported model_id: {model_id}")
|
||||
elif config.RUN_MODE == "ec2":
|
||||
if model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = ec2_claude2(prompt, model_id, filename, max_tokens)
|
||||
if resolved_model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = ec2_claude2(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.008, 0.024
|
||||
elif model_id == config.MODEL_ID_CLAUDE3_HAIKU:
|
||||
response = ec2_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE3_HAIKU:
|
||||
response = ec2_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.00025, 0.00125
|
||||
elif model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
elif model_id == config.MODEL_ID_CLAUDE37_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE37_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
elif model_id == config.MODEL_ID_CLAUDE4_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, model_id, filename, max_tokens)
|
||||
elif resolved_model_id == config.MODEL_ID_CLAUDE4_SONNET:
|
||||
response = ec2_claude_3_and_up(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
else:
|
||||
raise ValueError(f"Unsupported model_id: {model_id}")
|
||||
@@ -167,9 +193,12 @@ def invoke_claude(prompt, model_id, filename, max_tokens=4096):
|
||||
|
||||
# Cost logging
|
||||
current_frame = inspect.currentframe()
|
||||
caller_frame = current_frame.f_back
|
||||
caller_name = caller_frame.f_code.co_name
|
||||
del current_frame, caller_frame # Avoid reference cycles
|
||||
if current_frame is not None and current_frame.f_back is not None:
|
||||
caller_name = current_frame.f_back.f_code.co_name
|
||||
else:
|
||||
caller_name = "unknown"
|
||||
|
||||
del current_frame # Avoid reference cycles
|
||||
|
||||
cost_log_entry = create_cost_log_entry(
|
||||
filename, caller_name, prompt, response, input_cost_per_1k, output_cost_per_1k
|
||||
@@ -193,16 +222,23 @@ def invoke_claude_with_image_array(prompt, model_id, filename, base64_images,max
|
||||
claude_cache.move_to_end(cache_key) # Mark as recently used
|
||||
return claude_cache[cache_key]
|
||||
|
||||
# Resolve alias to actual model ID
|
||||
resolved_model_id = config.resolve_model_id(model_id)
|
||||
|
||||
# Select execution mode
|
||||
if config.RUN_MODE == "local":
|
||||
if model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = local_claude_3_and_up_with_image_array(prompt, model_id, filename, max_tokens,base64_images)
|
||||
print(f"Eff Dt Response from local Claude 3 for {filename}", response)
|
||||
if resolved_model_id == config.MODEL_ID_CLAUDE35_SONNET:
|
||||
response = local_claude_3_and_up_with_image_array(prompt, resolved_model_id, filename, max_tokens,base64_images)
|
||||
logging.info(f"Effective Date Response from local Claude 3 for {filename}: {response}")
|
||||
input_cost_per_1k, output_cost_per_1k = 0.003, 0.015
|
||||
else:
|
||||
raise ValueError(f"Unsupported model_id for image array: {resolved_model_id}")
|
||||
elif config.RUN_MODE == "ec2":
|
||||
if model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = ec2_claude2(prompt, model_id, filename, max_tokens)
|
||||
if resolved_model_id == config.MODEL_ID_CLAUDE2:
|
||||
response = ec2_claude2(prompt, resolved_model_id, filename, max_tokens)
|
||||
input_cost_per_1k, output_cost_per_1k = 0.008, 0.024
|
||||
else:
|
||||
raise ValueError(f"Unsupported model_id for image array: {resolved_model_id}")
|
||||
|
||||
else:
|
||||
print("Usage: python local_main.py <-local> OR python main.py <ec2>")
|
||||
@@ -216,9 +252,12 @@ def invoke_claude_with_image_array(prompt, model_id, filename, base64_images,max
|
||||
|
||||
# Cost logging
|
||||
current_frame = inspect.currentframe()
|
||||
caller_frame = current_frame.f_back
|
||||
caller_name = caller_frame.f_code.co_name
|
||||
del current_frame, caller_frame # Avoid reference cycles
|
||||
if current_frame is not None and current_frame.f_back is not None:
|
||||
caller_name = current_frame.f_back.f_code.co_name
|
||||
else:
|
||||
caller_name = "unknown"
|
||||
|
||||
del current_frame # Avoid reference cycles
|
||||
|
||||
cost_log_entry = create_cost_log_entry(
|
||||
filename, caller_name, prompt, response, input_cost_per_1k, output_cost_per_1k
|
||||
|
||||
@@ -214,7 +214,7 @@ def secondary_string_to_dict(dict_string: str, filename: str) -> dict:
|
||||
try:
|
||||
prompt = preprocessing_prompts.FIX_JSON(dict_substring)
|
||||
dict_substring = llm_utils.invoke_claude(
|
||||
prompt, config.MODEL_ID_CLAUDE3_HAIKU, filename
|
||||
prompt, "haiku_latest", filename
|
||||
)
|
||||
result_dict = json.loads(dict_substring)
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user