From 75bd6ba48a939dbd9d9eca87f425168b4b2688ff Mon Sep 17 00:00:00 2001 From: Quentin Leblanc Date: Tue, 8 Jul 2025 18:49:46 +0200 Subject: [PATCH] Need testing for outputs --- src/model.py | 116 +++++++++++++++++++++++++++++++++------------------ src/utils.py | 8 +++- 2 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/model.py b/src/model.py index e049a4c..2d5a240 100644 --- a/src/model.py +++ b/src/model.py @@ -10,7 +10,7 @@ from typing import Any from mistralai import Mistral -from .utils import create_message, encode_image +from .utils import create_message, encode_image, response2text def text_recipe_analysis(recipe: str, **kwargs) -> dict[str, Any]: @@ -75,43 +75,77 @@ def img_recipe_analysis(recipe: str, **kwargs) -> dict[str, Any]: return text_recipe_analysis(text, **kwargs) -# def replace_ingredients(ingredients: list[str], **kwargs) -> dict[str, Any]: -# """ -# Ask a model to find replacements for the ingredients indicated -# :param ingredients: List of ingredients to replace -# :param kwargs: -# :return: a dict with a list of replacements and indications about these replacements -# """ -# task = """Your task is to find replacements for the ingredients that will be provided. -# You have to search the web to do so. -# For each ingredient, find 3 replacements. -# For each replacement give the name of the ingredient found and the quantity used to replace 1g of the ingredient. -# You also have to list the pros and the cons of using this replacement. -# You will return a list with each ingredient and its replacement. -# -# Your answer must be formatted so that it can be stored in a json format. -# The json must be containing the fields: -# - 'ingredient': that is the ingredient to be replaced. -# -# under 'ingredient', you will have the following field: -# - 'replacements': that is the list of 'replacement' ingredients. -# -# Each 'replacement' will have the fields: -# - 'name': that is the name of the particular replacement; -# - 'quantity': that is the quantity of the particular replacement; -# - 'pros': A list of different benefits for this particular replacement; -# - 'cons': A list of different drawbacks for this particular replacement; -# -# Here are the ingredients you hae to replace: -# """ -# -# for ingredient in ingredients: -# task += f"- {ingredient};\n" -# -# client = Mistral(api_key=kwargs["api_key"]) -# return json.loads(client.chat.complete( -# model=kwargs["model"], -# messages=[create_message("user", task)], -# tools=[{"type": "web_search"}], -# response_format={"type": "json_object"} -# ).choices[0].message.content) \ No newline at end of file +def find_replacement(ingredients: list[str], **kwargs) -> dict[str, Any]: + """ + Ask a model to find replacements for the ingredients indicated + :param ingredients: List of ingredients to replace + :param kwargs: + :return: a dict with a list of replacements and indications about these replacements + """ + client = Mistral(api_key=kwargs["api_key"]) + + agent = client.beta.agents.create( + name="GoodRecipe Agent", + description="Agent to retrieve ingredient replacements with web search", + model=kwargs["model"], + instructions="You have the ability to perform web searches with `web_search` to find up-to-date information.", + tools=[{"type": "web_search"}], + completion_args={ + "temperature": 0.1, + "top_p": 0.95, + } + ) + replacements = {} + + for ingredient in ingredients: + task = f"""You have the ability to perform web searches with `web_search` to find up-to-date information. +Your task is to find replacements for a provided ingredient. +You have to find at most three replacement with their benefits and drawbacks. +Give your answer in the form: +*[Replacement]* +- **pros** + - list of pros ... +- **cons** + - list of cons ... + +INGREDIENT: {ingredient} + """ + response = response2text(client.beta.conversations.start(agent_id=agent.id, inputs=[{'role': 'user', 'content': task}])) + + json_task = """You have to transform a markdown text into a list of json objects. +The markdown text is a list of ingredients with their pros and cons in a substitution context. +You will list each replacement in the following manner: +- name: name of the substitute ingredient; +- pros: benefits for this substitute; +- cons: drawbacks for this substitute; + +The answer should look like: +{ "substitutes": + [ + { + "name": ... + "pros": ... + "cons": ... + }, + { + "name": ... + "pros": ... + "cons": ... + }, + ... + ] +} + +TEXT: + + """ + response + + answer = client.chat.complete( + model=kwargs["model"], + messages=[create_message("user", json_task)], + response_format={"type": "json_object"} + ).choices[0].message.content + + replacements[ingredient] = json.loads(answer)['substitutes'] + + return replacements \ No newline at end of file diff --git a/src/utils.py b/src/utils.py index 9f94f9c..38ecaa1 100644 --- a/src/utils.py +++ b/src/utils.py @@ -5,6 +5,8 @@ """ import base64 +from mistralai import ConversationResponse, TextChunk + def create_message(role: str, content: str) -> dict[str, str]: """ @@ -26,4 +28,8 @@ def encode_image(image_path): return None except Exception as e: # Added general exception handling print(f"Error: {e}") - return None \ No newline at end of file + return None + +def response2text(response: ConversationResponse) -> str: + text = [output.text for output in response.outputs[1].content if type(output) is TextChunk] + return "".join(text) \ No newline at end of file