We have a really heavy project for you, please, let's accomplish it all based on the following description. Please notice all the nuances on the description and follow it exactly. If you have any glaring doubts ask me to clarify. It is in python.
We need to make a flask application that will help us build datasets for LLMs fine tuning. 
Our final output will have to be a JSONL file with the following structure: 

Copy
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}
A list of these examples. 
We need to make a modular flask application that will let the user set up the desired system content, which repeats in every entry of the JSONL. 
Then, we need to construct the pairs of user and assistant exchanges. 
We will achieve this in various ways. 
First we will have a database of generated User inputs, well organized in categories, from natural conversation to inputs of single words, memories, situations, questions, and don't forget to add a section for disparate topics and objects for the creation of an associative model. 
We will call MediaWiki Action API with "requests", for random images of Wikimedia commons of a varied selection of topics, making sure we don't repeat the images. We will do this once and save the results of the URL and prevent any other calls to be done again if we have the information. We need to make sure this images are all not repeated and from various topics. When we get these images we will then pass them to OpenAI for the model to describe them in text, we will save this description of the image appended to its URL and make sure we don't call OpenAI again if we already made the data. All these images and descriptions should be consistent in between sessions, so this image process should happen in an initialization event well displayed for the user the very first time they run the code. This initialization should consist of 50 images in total.
Now we have our two datasets, one of user prompts with different categories and one of images and the AI generated descriptions. The next thing we need to do is to make a selector of these different categories, from the images and the different prompts categories, as many as they want and a number input. When they make they selection and click some button to continue, we take the number and their selections and they will then be presented with the images and user inputs in a row for them to input their initial reaction or response to that. Making sure that the images we present and the user prompts we present all are well distributed in the amount show, we need to calculate based on the selection of the categories how many of each they should be shown. Make sure to only show the images when necessary and not their descriptions. 
The user will enter inputs for all of these images or text prompts, for the number of time for number they gave as an input, then, finally, when they finish all these inputs, we construct out final JSONL structure adding the inputs we gave the user and the image descriptions of the images they saw as the "user" input in out structure and the responses they wrote as the "assistant" responses. All well organized in the list with the original system prompt they defined. 
Here is how you call the OpenAI API for the initial construction of the image database. 
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
  model="gpt-4o-mini",
  messages=[
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "What’s in this image?"},
        {
          "type": "image_url",
          "image_url": {
            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
          },
        },
      ],
    }
  ],
  max_tokens=300,
)
print(response.choices[0])


make sure the images we retrieve are the smallest size possible