from langchain_core.tools import tool @tool def get_botanical_classification(item_name): """ Provides the botanical classification (fruit, vegetable, or other) for a given food item, adhering to botanical definitions. Args: item_name (str): The name of the food item (e.g., "bell pepper", "sweet potato"). Returns: dict: A dictionary containing: - 'item': The normalized item name. - 'botanical_category': 'fruit', 'vegetable', 'other', or 'unclassified'. - 'botanical_part': The botanical part of the plant (e.g., 'matured ovary', 'root', 'leaf'), or 'N/A' if not applicable/unknown. - 'notes': Any additional botanical notes or clarifications. """ # --- Curated Botanical Database --- # This dictionary holds the botanical classifications. # It's crucial this data is accurate according to botanical science. # You will need to expand this as needed for your full grocery list. botanical_data = { "sweet potatoes": { "botanical_category": "vegetable", "botanical_part": "root/tuber", "notes": "Edible root of the plant." }, "fresh basil": { "botanical_category": "vegetable", "botanical_part": "leaf", "notes": "Edible leaves of the herb." }, "plums": { "botanical_category": "fruit", "botanical_part": "matured ovary", "notes": "Simple fleshy fruit (drupe)." }, "green beans": { "botanical_category": "fruit", "botanical_part": "matured ovary (legume)", "notes": "Botanically a fruit (legume) containing seeds." }, "rice": { "botanical_category": "fruit", "botanical_part": "matured ovary (caryopsis)", "notes": "A grain, which is botanically a dry fruit (caryopsis)." }, "corn": { "botanical_category": "fruit", "botanical_part": "matured ovary (caryopsis)", "notes": "A grain, which is botanically a dry fruit (caryopsis)." }, "bell pepper": { "botanical_category": "fruit", "botanical_part": "matured ovary", "notes": "Developed from the flower's ovary and contains seeds." }, "whole allspice": { # Allspice berries "botanical_category": "fruit", "botanical_part": "dried berry", "notes": "Dried unripe berries of the Pimenta dioica plant." }, "acorns": { "botanical_category": "fruit", "botanical_part": "nut (type of dry fruit)", "notes": "A nut, which is botanically a type of dry fruit." }, "broccoli": { "botanical_category": "vegetable", "botanical_part": "flower/stem", "notes": "Edible flower heads and stalks." }, "celery": { "botanical_category": "vegetable", "botanical_part": "stem/petiole", "notes": "Edible leaf stalks." }, "zucchini": { "botanical_category": "fruit", "botanical_part": "matured ovary", "notes": "A type of berry (pepo) from a flowering plant." }, "lettuce": { "botanical_category": "vegetable", "botanical_part": "leaf", "notes": "Edible leaves." }, "peanuts": { "botanical_category": "fruit", "botanical_part": "legume (matured ovary)", "notes": "Botanically a fruit (legume), despite growing underground." }, # Non-plant items or items not strictly fruit/vegetable botanically "milk": { "botanical_category": "other", "botanical_part": "N/A", "notes": "Dairy product (animal)." }, "eggs": { "botanical_category": "other", "botanical_part": "N/A", "notes": "Animal product." }, "flour": { "botanical_category": "other", "botanical_part": "N/A", "notes": "Processed grain product (typically wheat, which is a fruit)." }, "whole bean coffee": { "botanical_category": "other", # The bean itself is a seed, not the entire fruit "botanical_part": "seed", "notes": "The coffee 'bean' is botanically the seed of the coffee cherry (a fruit)." }, "oreos": { "botanical_category": "other", "botanical_part": "N/A", "notes": "Processed food item." } } # Normalize the input item name for lookup normalized_item = item_name.strip().lower() # Handle pluralization/singularization for common cases if not explicitly in data # This is a simple approach; for more robustness, you'd need a proper NLP library. if normalized_item.endswith("s") and normalized_item[:-1] in botanical_data: normalized_item = normalized_item[:-1] elif normalized_item + "s" in botanical_data: # Check if the plural form exists if input is singular if item_name.strip().lower() + "s" in botanical_data: normalized_item = item_name.strip().lower() + "s" # Retrieve classification classification = botanical_data.get(normalized_item) if classification: return { "item": item_name, "botanical_category": classification["botanical_category"], "botanical_part": classification["botanical_part"], "notes": classification["notes"] } else: # If the item is not found in the database return { "item": item_name, "botanical_category": "unclassified", "botanical_part": "N/A", "notes": "Classification not found in the current database." } # --- Example Usage --- if __name__ == "__main__": grocery_list = [ "milk", "eggs", "flour", "whole bean coffee", "Oreos", "sweet potatoes", "fresh basil", "plums", "green beans", "rice", "corn", "bell pepper", "whole allspice", "acorns", "broccoli", "celery", "zucchini", "lettuce", "peanuts" ] botanical_fruits = [] botanical_vegetables = [] other_items = [] unclassified_items = [] print("--- Botanical Classifications ---") for item in grocery_list: classification = get_botanical_classification(item) print(f"'{classification['item']}' -> Category: {classification['botanical_category']}, Part: {classification['botanical_part']} ({classification['notes']})") if classification['botanical_category'] == 'fruit': botanical_fruits.append(classification['item']) elif classification['botanical_category'] == 'vegetable': botanical_vegetables.append(classification['item']) elif classification['botanical_category'] == 'other': other_items.append(classification['item']) else: # unclassified unclassified_items.append(classification['item']) print("\n--- Summary ---") print(f"Botanical Fruits: {', '.join(sorted(botanical_fruits))}") print(f"Botanical Vegetables: {', '.join(sorted(botanical_vegetables))}") print(f"Other Groceries: {', '.join(sorted(other_items))}") if unclassified_items: print(f"Unclassified Items: {', '.join(sorted(unclassified_items))}") print(get_botanical_classification('fresh basil'))