# INITIALIZATION

# LangChain imports
import langchain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.chains import SequentialChain

# General imports
import os
from dotenv import load_dotenv

# Load API key from .env
load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

# LangChain debugging settings
langchain.debug = False
langchain.verbose = False

"""
NOTE

LangChain applications can be debugged easily either
1. by enabling the debug mode or
2. by enabling verbose outputs (recommended for agents).

Turn on (switch to True) one of the above and see what happens when the chain executes.

Reference: https://python.langchain.com/docs/guides/debugging
"""


# MODEL

llm = OpenAI(temperature=0.6)


# PROMPT MANAGEMENT


def generate_recipe_names(selected_items):
    """
    Generate a list of recipe names using a list of selected ingredients
    by executing an LLMChain.

    Args:
        selected_items (list): A list of ingredients selected by the user

    Returns:
        dict: A dictionary of recipe names
    """

    # Set up prompt template
    prompt_template_recipe_name = PromptTemplate(
        input_variables=["ingredients"],
        template="Generate a list of meal names that can be prepared using the provided ingredients. "
        "Ingredients are {ingredients}. "
        "It's not necessary to use all of the ingredients, "
        "and the list can include both simple and complex meal names. "
        "Please consider the ingredients provided and suggest meal names accordingly.",
    )

    # Set up chain
    recipe_name_chain = LLMChain(
        llm=llm, prompt=prompt_template_recipe_name, output_key="recipe_name"
    )

    # Set up multichain workflow with inputs
    chain = SequentialChain(
        chains=[recipe_name_chain],
        input_variables=["ingredients"],
        output_variables=["recipe_name"],
    )

    # Execute workflow and get response
    response = chain({"ingredients": selected_items})

    return response


def generate_recipe(recipe_name):
    """
    Generate a comprehensive recipe using a name of a recipe as input
    by executing an LLMChain

    Args:
        recipe_name (str): The name of the recipe to be generated

    Returns:
        dict: A recipe (as a dictionary object)
    """

    # Set up prompt template
    prompt_template_recipe = PromptTemplate(
        input_variables=["recipe_name"],
        template="Generate a recipe for {recipe_name}. Please include a list of ingredients and "
        "step-by-step instructions for preparing {recipe_name}. "
        "Please include the cooking time and any special instructions.",
    )

    # Set up chain
    recipe_chain = LLMChain(llm=llm, prompt=prompt_template_recipe, output_key="recipe")

    # Set up multichain workflow with inputs
    chain = SequentialChain(
        chains=[recipe_chain],
        input_variables=["recipe_name"],
        output_variables=["recipe"],
    )

    # Execute workflow and get response
    response = chain({"recipe_name": recipe_name})

    return response

langchain.chains.SequentialChain langchain.chains.LLMChain langchain.prompts.PromptTemplate langchain.llms.OpenAI
[((303, 316), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (314, 316), False, 'from dotenv import load_dotenv\n'), ((348, 375), 'os.getenv', 'os.getenv', (['"""OPENAI_API_KEY"""'], {}), "('OPENAI_API_KEY')\n", (357, 375), False, 'import os\n'), ((785, 808), 'langchain.llms.OpenAI', 'OpenAI', ([], {'temperature': '(0.6)'}), '(temperature=0.6)\n', (791, 808), False, 'from langchain.llms import OpenAI\n'), ((1201, 1572), 'langchain.prompts.PromptTemplate', 'PromptTemplate', ([], {'input_variables': "['ingredients']", 'template': '"""Generate a list of meal names that can be prepared using the provided ingredients. Ingredients are {ingredients}. It\'s not necessary to use all of the ingredients, and the list can include both simple and complex meal names. Please consider the ingredients provided and suggest meal names accordingly."""'}), '(input_variables=[\'ingredients\'], template=\n    "Generate a list of meal names that can be prepared using the provided ingredients. Ingredients are {ingredients}. It\'s not necessary to use all of the ingredients, and the list can include both simple and complex meal names. Please consider the ingredients provided and suggest meal names accordingly."\n    )\n', (1215, 1572), False, 'from langchain.prompts import PromptTemplate\n'), ((1674, 1753), 'langchain.chains.LLMChain', 'LLMChain', ([], {'llm': 'llm', 'prompt': 'prompt_template_recipe_name', 'output_key': '"""recipe_name"""'}), "(llm=llm, prompt=prompt_template_recipe_name, output_key='recipe_name')\n", (1682, 1753), False, 'from langchain.chains import LLMChain\n'), ((1826, 1940), 'langchain.chains.SequentialChain', 'SequentialChain', ([], {'chains': '[recipe_name_chain]', 'input_variables': "['ingredients']", 'output_variables': "['recipe_name']"}), "(chains=[recipe_name_chain], input_variables=['ingredients'],\n    output_variables=['recipe_name'])\n", (1841, 1940), False, 'from langchain.chains import SequentialChain\n'), ((2433, 2697), 'langchain.prompts.PromptTemplate', 'PromptTemplate', ([], {'input_variables': "['recipe_name']", 'template': '"""Generate a recipe for {recipe_name}. Please include a list of ingredients and step-by-step instructions for preparing {recipe_name}. Please include the cooking time and any special instructions."""'}), "(input_variables=['recipe_name'], template=\n    'Generate a recipe for {recipe_name}. Please include a list of ingredients and step-by-step instructions for preparing {recipe_name}. Please include the cooking time and any special instructions.'\n    )\n", (2447, 2697), False, 'from langchain.prompts import PromptTemplate\n'), ((2772, 2841), 'langchain.chains.LLMChain', 'LLMChain', ([], {'llm': 'llm', 'prompt': 'prompt_template_recipe', 'output_key': '"""recipe"""'}), "(llm=llm, prompt=prompt_template_recipe, output_key='recipe')\n", (2780, 2841), False, 'from langchain.chains import LLMChain\n'), ((2900, 3004), 'langchain.chains.SequentialChain', 'SequentialChain', ([], {'chains': '[recipe_chain]', 'input_variables': "['recipe_name']", 'output_variables': "['recipe']"}), "(chains=[recipe_chain], input_variables=['recipe_name'],\n    output_variables=['recipe'])\n", (2915, 3004), False, 'from langchain.chains import SequentialChain\n')]