|
|
from data import debug_print,eligibility_lookup,llm1
|
|
|
from nodes.intent import get_pretty_state_string,CreditCardState
|
|
|
from langchain_core.messages import SystemMessage, HumanMessage
|
|
|
|
|
|
|
|
|
async def compare_node_fn(state: CreditCardState) -> CreditCardState:
|
|
|
debug_print("NODE", f"Entering compare_node_fn with state:\n {get_pretty_state_string(state)}\n")
|
|
|
|
|
|
selected_cards = state.get("selected_cards", [])
|
|
|
card_lookup = state.get("card_lookup", {})
|
|
|
|
|
|
debug_print("COMPARE_NODE", f"Selected cards: {selected_cards}")
|
|
|
debug_print("COMPARE_NODE", f"Card lookup keys: {list(card_lookup.keys())}")
|
|
|
if not selected_cards or len(selected_cards) < 2:
|
|
|
debug_print("COMPARE_NODE", "Not enough cards selected for comparison")
|
|
|
state["comparison_result"] = "Please select at least two cards to compare."
|
|
|
return state
|
|
|
|
|
|
comparison_details = []
|
|
|
for name in selected_cards:
|
|
|
eligibility_info = eligibility_lookup.get(name, "No eligibility or fee information available.")
|
|
|
desc = card_lookup.get(name, "No description available.")
|
|
|
full_desc = f"{desc}\n\nEligibility & Fees:\n{eligibility_info}"
|
|
|
comparison_details.append(f"{name}: {full_desc}")
|
|
|
debug_print("COMPARE_NODE", f"Added card '{name}' with description length: {len(desc)}")
|
|
|
|
|
|
use_table_format = len(selected_cards) <= 3
|
|
|
|
|
|
|
|
|
if use_table_format:
|
|
|
comparison_prompt = (
|
|
|
"Compare the following credit cards using a clean and concise **markdown table**. The table should have the following structure:\n\n"
|
|
|
"| Feature | [Card 1 Name] | [Card 2 Name] |\n"
|
|
|
"|---------|---------------|---------------|\n"
|
|
|
"| Benefits | [3-4 key benefits]<br>[as concise bullet points] | [3-4 key benefits]<br>[as concise bullet points] |\n"
|
|
|
"| Fees & Eligibility | [Key fees & eligibility as bullet points] | [Key fees & eligibility as bullet points] |\n"
|
|
|
"| Limitations | [List any limitations as bullet points] | [List any limitations as bullet points] |\n"
|
|
|
"| Ideal User | [A single short sentence] | [A single short sentence] |\n\n"
|
|
|
"Instructions:\n"
|
|
|
"1. **STRICTLY adhere to the table structure.**\n"
|
|
|
"2. **DO NOT GUESS OR HALLUCINATE.** Use only the card data provided below.\n"
|
|
|
"3. For `Benefits`, extract and list **ONLY** the 3-4 most important benefits. Keep each bullet point very short.\n"
|
|
|
"4. For `Fees & Eligibility`, list the key fees (joining/annual) and income/age as separate concise bullet points.\n"
|
|
|
"5. For `Limitations`, extract only the top 1-2 limitations. If none are listed, write 'None listed in the provided data.'.\n"
|
|
|
"6. For `Ideal User`, provide a single sentence describing the best fit for the card.\n"
|
|
|
"7. After the table, give a brief, one-sentence recommendation.\n"
|
|
|
"8. Use `<br>` for line breaks inside table cells. Do not use newline characters (`\\n`) or extra `|` inside any cell.\n\n"
|
|
|
"CARD DATA:\n\n"
|
|
|
+ "\n\n".join(comparison_details)
|
|
|
)
|
|
|
else:
|
|
|
comparison_prompt = (
|
|
|
"Compare the following credit cards based on their benefits, fees, eligibility, and ideal use cases.\n\n"
|
|
|
"Instructions:\n"
|
|
|
"1. **STRICTLY** use only the card data provided below. Do NOT guess, assume, or hallucinate any information.\n"
|
|
|
"2. Keep the output short, structured, and highly readable.\n"
|
|
|
"3. Use markdown format with clear section headers like 'Comparison' and 'Recommendation'.\n"
|
|
|
"4. Use a concise list of bullet points for each card's benefits, fees, and limitations.\n"
|
|
|
"5. Conclude with a recommendation on which card suits which type of user.\n\n"
|
|
|
"CARD DATA:\n\n"
|
|
|
+ "\n\n".join(comparison_details)
|
|
|
)
|
|
|
|
|
|
debug_print("COMPARE_NODE", "Calling Llama for comparison")
|
|
|
|
|
|
try:
|
|
|
messages = [
|
|
|
SystemMessage(content="You are an expert in comparing credit card products."),
|
|
|
HumanMessage(content=comparison_prompt)
|
|
|
]
|
|
|
|
|
|
response_obj = await llm1.ainvoke(
|
|
|
messages,
|
|
|
config={"max_tokens": 2048, "temperature": 0.0}
|
|
|
)
|
|
|
response_content = response_obj.content
|
|
|
debug_print("COMPARE_NODE", f"Response received with length: {len(response_content)}")
|
|
|
print(response_content)
|
|
|
state["comparison_result"] = response_content
|
|
|
|
|
|
except Exception as e:
|
|
|
debug_print("ERROR", f"Error during comparison: {e}")
|
|
|
state["comparison_result"] = "An error occurred while comparing the cards. Please try again."
|
|
|
|
|
|
return state |