COHERE - CHATBOT
Simon-Pierre Boucher
2024-09-14

This Python code defines a ChatBotCohere class that interacts with the Cohere API to generate conversational responses using a history of conversation and a user-provided prompt. Here’s a detailed explanation of how the code works:

1. Environment Setup

  • API Key: The script loads environment variables from a .env file using load_dotenv() and retrieves the Cohere API key (COHERE_API_KEY) with os.getenv().

2. Text Generation Function (generate_cohere_text)

  • This function sends a request to Cohere’s API for text generation, using the specified parameters:

    • API key: Required for authentication.
    • Model: Specifies the model to use (e.g., "command-r-plus").
    • Message: The current user input to which the assistant should respond.
    • Chat History: A list of previous messages exchanged between the user and the assistant.
    • Preamble: Provides context or instructions for the assistant (e.g., "You are an AI-assistant chatbot.").
    • Temperature: Controls randomness in the output. A value of 1.0 gives balanced creativity and coherence.
    • Max Tokens: Specifies the maximum number of tokens (words/subwords) to generate in the response.
  • The API request is made via a POST request to the Cohere API's /v1/chat endpoint.

  • The function handles exceptions and returns the API response in JSON format if successful.

3. ChatBotCohere Class

  • Initialization: The class is initialized with the API key and parameters such as:
    • Model: The Cohere model used for text generation (default: "command-r-plus").
    • Preamble: A context for the assistant's role (default: "You are an AI-assistant chatbot.").
    • Temperature: Controls randomness (default: 1.0).
    • Max Tokens: The maximum number of tokens the assistant can generate (default: 2000).
    • Conversation History: A list to keep track of the conversation's messages (including roles of "USER" or "CHATBOT").

4. Adding Messages to Conversation History

  • The add_message() method adds each new message (user input or assistant response) to the conversation history, assigning it the appropriate role ("USER" or "CHATBOT").

5. Generating a Response (get_response)

  • The get_response() method takes the user's input, appends it to the conversation history as a "USER" message, and sends a request to Cohere’s API using the generate_cohere_text() function.
  • Once the API returns a response, the assistant’s generated reply is extracted and added to the conversation history as a "CHATBOT" message.
  • The assistant’s response is then returned to the user. If there’s an issue with the response (e.g., missing keys in the API response), an error message is displayed.

6. Example Workflow

  • A ChatBotCohere instance is created using the API key and default settings.
  • The user inputs the message: "Can you suggest 5 dinner ideas for this week?".
  • The bot sends the user input to the Cohere API, which generates a response.
  • The response is printed, and the conversation continues with the assistant replying based on both the user’s input and the conversation history.

Key Flow of Execution:

  1. User Input: The user enters a query (e.g., asking for dinner suggestions).
  2. Conversation History: The query is added to the conversation history.
  3. API Request: The query, conversation history, and preamble are sent to the Cohere API to generate a response.
  4. Response: The assistant’s response is extracted and added to the conversation history.
  5. Output: The response is printed for the user.

This chatbot maintains a history of the conversation and uses that history to produce contextually appropriate responses using Cohere's language models.

In [2]:
import os
import requests
from dotenv import load_dotenv

# Charger les variables d'environnement depuis le fichier .env
load_dotenv()

# Obtenir la clé API depuis les variables d'environnement
api_key = os.getenv("COHERE_API_KEY")

def generate_cohere_text(api_key, model, message, chat_history, preamble, temperature=1.0, max_tokens=2000):
    """
    Generate text using Cohere's API.
    
    Parameters:
    - api_key (str): The API key for Cohere.
    - model (str): The model to use for text generation.
    - message (str): The user's message.
    - chat_history (list): A list of previous messages in the conversation.
    - preamble (str): A preamble that sets the context for the chatbot.
    - temperature (float): Controls randomness in the output (0-1).
    - max_tokens (int): The maximum number of tokens to generate in the completion.
    
    Returns:
    - response (dict): The API response as a dictionary.
    """
    url = "https://api.cohere.com/v1/chat"
    headers = {
        "accept": "application/json",
        "content-type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }
    data = {
        "model": model,
        "message": message,
        "chat_history": chat_history,
        "preamble": preamble,
        "temperature": temperature,
        "max_tokens": max_tokens
    }

    # Supprimer ou commenter la ligne d'impression des données
    # print("Sending data to Cohere API:", data)

    try:
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")
        return None

class ChatBotCohere:
    def __init__(self, api_key, model="command-r-plus", preamble="You are an AI-assistant chatbot.", temperature=1.0, max_tokens=2000):
        """
        Initialize the ChatBotCohere with API key and parameters.
        
        Parameters:
        - api_key (str): The API key for Cohere.
        - model (str): The model to use for text generation.
        - preamble (str): A preamble that sets the context for the chatbot.
        - temperature (float): Controls randomness in the output (0-1).
        - max_tokens (int): The maximum number of tokens to generate in the completion.
        """
        self.api_key = api_key
        self.model = model
        self.preamble = preamble
        self.temperature = temperature
        self.max_tokens = max_tokens
        self.conversation_history = []

    def add_message(self, role, content):
        """
        Add a message to the conversation history.
        
        Parameters:
        - role (str): The role of the sender ("USER" or "CHATBOT").
        - content (str): The content of the message.
        """
        self.conversation_history.append({"message": content, "role": role})

    def get_response(self, user_input):
        """
        Get a response from the Cohere API based on the user input.
        
        Parameters:
        - user_input (str): The user's input message.
        
        Returns:
        - assistant_reply (str): The assistant's generated response.
        """
        # Add user input to conversation history with role "USER"
        self.add_message("USER", user_input)

        # Call the Cohere API to get a response
        response = generate_cohere_text(
            self.api_key,
            self.model,
            user_input,
            self.conversation_history,
            self.preamble,
            temperature=self.temperature,
            max_tokens=self.max_tokens
        )

        if response:
            # Extract and return only the message (text) generated by the chatbot
            try:
                assistant_reply = response["text"]
                # Add assistant's reply to conversation history with role "CHATBOT"
                self.add_message("CHATBOT", assistant_reply)
                return assistant_reply
            except KeyError:
                return "Sorry, I couldn't find the expected response key in the API response."
        else:
            return "Sorry, I couldn't generate a response."
In [3]:
bot = ChatBotCohere(api_key)
In [4]:
user_input = "Can you suggest 5 dinner ideas for this week?"
response = bot.get_response(user_input)
print("Assistant:", response)
Assistant: Sure! Here are five dinner ideas for this week:

1. Chicken stir-fry with vegetables and rice
2. Pasta Bolognese
3. Grilled salmon with roasted vegetables
4. Taco salad bowls
5. Lentil curry with naan bread

You can adapt these suggestions based on your dietary preferences or restrictions, and feel free to ask for more specific recipe ideas or additional dinner suggestions if you need further inspiration!
In [5]:
user_input = "Can you give me the recipe for the first idea?"
response = bot.get_response(user_input)
print("Assistant:", response)
Assistant: Certainly! Here's a simple recipe for a chicken stir-fry with vegetables and rice:

Ingredients:

 - 2 boneless, skinless chicken breasts, cut into thin strips
 - 2 tablespoons of soy sauce
 - 1 tablespoon of honey
 - 1 clove of garlic, minced
 - 1 teaspoon of grated ginger
 - 2 tablespoons of vegetable oil
 - 1 cup of broccoli florets
 - 1 red bell pepper, cut into thin strips
 - 1 carrot, peeled and sliced
 - 1/2 cup of snow peas
 - 1/2 cup of sliced onions
 - 2 cups of cooked rice (you can use white or brown rice)

Instructions:

1. In a bowl, combine soy sauce, honey, garlic, and ginger. Add the chicken strips and stir to coat. Marinate for 15 minutes to an hour in the refrigerator.

2. Heat one tablespoon of vegetable oil in a wok or large skillet over medium-high heat. Add the marinated chicken and stir-fry until cooked through, about 5-7 minutes. Remove the chicken from the wok and set aside.

3. Add the remaining tablespoon of vegetable oil to the wok. Toss in the broccoli, bell pepper, carrot, snow peas, and onions. Stir-fry the vegetables for about 3-4 minutes until they are crisp-tender.

4. Return the cooked chicken to the wok and add the cooked rice. Pour any remaining marinade over the mixture and stir everything together.

5. Continue cooking for an additional 2-3 minutes, stirring frequently, until the rice is heated through and has absorbed some of the flavors.

6. Serve the chicken and vegetable stir-fry immediately while it's hot, and enjoy!

Feel free to adjust the seasoning and vegetables to your taste, and you can even add other ingredients like cashews or sesame seeds for some extra crunch.
In [6]:
user_input = "Can you give me the recipe for the second idea?"
response = bot.get_response(user_input)
print("Assistant:", response)
Assistant: Absolutely! Here's a recipe for a delicious Pasta Bolognese:

Ingredients:

 - 1 tablespoon of olive oil
 - 1 onion, finely chopped
 - 2 cloves of garlic, minced
 - 1 carrot, peeled and finely chopped
 - 1 celery stalk, finely chopped
 - 1 pound of ground beef
 - 1 cup of red wine (optional)
 - 2 cups of crushed tomatoes
 - 1 tablespoon of tomato paste
 - 1 teaspoon of dried oregano
 - 1/2 teaspoon of dried basil
 - Salt and pepper to taste
 - 1 pound of your favorite pasta
 - Grated Parmesan cheese for serving (optional)

Instructions:

1. Heat the olive oil in a large saucepan over medium heat. Add the onion, garlic, carrot, and celery. Cook, stirring occasionally, until the vegetables are softened, about 5-7 minutes.

2. Add the ground beef to the saucepan and use a wooden spoon to break it up into small pieces. Cook until the beef is no longer pink, about 8-10 minutes. Make sure to stir occasionally to prevent sticking.

3. Pour in the red wine (if using) and let it simmer for a few minutes, scraping any browned bits from the bottom of the pan. Then, add the crushed tomatoes, tomato paste, oregano, basil, salt, and pepper. Stir everything together.

4. Reduce the heat to low and let the sauce simmer uncovered for at least 30 minutes, stirring occasionally. The longer it simmers, the more the flavors will develop.

5. While the sauce is simmering, bring a large pot of salted water to a boil. Add the pasta and cook according to the package instructions until al dente.

6. Drain the pasta and return it to the pot. Add a couple of ladlefuls of the Bolognese sauce to the pasta and mix well. This helps the pasta absorb some of the sauce's flavors.

7. Serve the pasta onto individual plates or bowls and top with the remaining Bolognese sauce. Sprinkle with grated Parmesan cheese if desired, and enjoy your homemade Pasta Bolognese!

Feel free to adjust the seasoning and ingredients to your taste, and you can even add other herbs or spices to make the sauce your own. Buon appetito!