import os from dotenv import dotenv_values from langchain_openai import ChatOpenAI from langgraph.prebuilt import ToolNode from langchain_core.tools import tool import stripe import json # Load values directly from .env file without setting environment variables env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), '.env') env_vars = dotenv_values(env_path) stripe.api_key = env_vars.get("STRIPE_API_KEY") #product_name is the name of the product in the payments/products.json file def generate_payment_link(product_quantities_str: str) -> str: """Generate a Stripe payment link for specified products. Args: product_quantities_str: String with format "(product_1,k_1),(product_2,k_2),...,(product_n,k_n)" where product_i must match a key in products.json and k_i is the quantity. Example: "(finasteride,1),(NP_consultation,1)" """ # Parse the input string product_quantities = [] pairs = product_quantities_str.strip().split("),(") for pair in pairs: # Clean up the pair string pair = pair.replace("(", "").replace(")", "") if not pair: continue parts = pair.split(",") if len(parts) != 2: raise ValueError(f"Invalid format in pair: {pair}. Expected 'product,quantity'") product_id, quantity_str = parts try: quantity = int(quantity_str) except ValueError: raise ValueError(f"Quantity must be an integer: {quantity_str}") product_quantities.append((product_id, quantity)) # Load the product catalog - adjust path based on script location import os script_dir = os.path.dirname(os.path.abspath(__file__)) catalog_path = os.path.join(script_dir, "products.json") catalog = json.load(open(catalog_path)) # Create line items for the payment link # Use a dictionary to track and combine items with the same price_id price_quantities = {} for product_id, quantity in product_quantities: if product_id not in catalog: raise ValueError(f"Product '{product_id}' not found in catalog") price_id = catalog[product_id]["price_id"] if price_id in price_quantities: price_quantities[price_id] += quantity else: price_quantities[price_id] = quantity # Create line items from the consolidated price_quantities line_items = [ {"price": price_id, "quantity": quantity} for price_id, quantity in price_quantities.items() ] # Create the payment link payment_link = stripe.PaymentLink.create( line_items=line_items, phone_number_collection={"enabled": True}, after_completion={ "type": "hosted_confirmation", "hosted_confirmation": { "custom_message": "Thank you for your order! 🎉.\n A nurse practitioner will review your order and contact you shortly." } } ) return payment_link.url def process_purchase_request(user_input): """ Process a purchase request from a user input string. Args: user_input (str): A string containing purchase intent like "I want to buy 3 items of product_i and 2 of product_k" Returns: dict: The response from the tool node containing payment information """ # Use the API key directly from the loaded .env values llm = ChatOpenAI(model='gpt-4o-mini', api_key=env_vars.get("OPENAI_API_KEY"), temperature=0) # Tool creation tools = [generate_payment_link] tool_node = ToolNode(tools) # Tool binding model_with_tools = llm.bind_tools(tools) # Get the LLM to understand the request and format it for tool calling llm_response = model_with_tools.invoke(user_input) print(llm_response) # Pass the LLM's response to the tool node for execution tool_response = tool_node.invoke({"messages": [llm_response]}) print(tool_response) return tool_response # Example usage if __name__ == "__main__": sample_request = '1 Finasteride consultation, 1 Minoxidil consultation' result = process_purchase_request(sample_request) print(result) # You can test with other examples # result2 = process_purchase_request("I want to buy 3 items of product_i and 2 of product_k") # print(result2)