InfantAGI - An autonomous self improving python code writer and executer

I would like to share with you my proof-of-concept Python program that uses OpenAI’s ChatGPT API to generate self-improving Python code. The program essentially clones ChatGPT multiple times to:

  1. Refine the given task to include a better definition of task
  2. Instruct the AI models to write Python code for the task
  3. Write the code as per the instructions
  4. Execute the generated code
  5. Review the output and improve the code generation process by iterations

To use this program, you need to have an OpenAI API key, which you can enter in the code where it says “YOUR_API_KEY”. The program consists of several functions that define the agents’ roles and their interactions with each other, as well as a colored print function for better readability.

When you run the program, you will be prompted to give a task as input. The program will then refine the task by interacting with the first agent, who is responsible for this task. The refined task will be used as input for the second agent, who will create instructions for Python code to perform the task. The instructions will be provided to the third agent, who will write Python code based on the instructions.

The code will be executed, and the output will be captured. The fourth agent will check the code and its output and provide feedback to refine the instructions further. If the code and its output meet the requirements and conditions specified by the fourth agent, the program will terminate. Otherwise, the program will continue to refine the instructions and the code until they meet the requirements.

Depending on the given task, if the code output has no errors, the execution step may bring gpt 3.5 agents plug-in like abilities, which they normally don’t have. If the task requires a web page, execution of the code may result in finding an information from web or performing a text to speech operation or plotting a graph, which regular chatgpt is not capable of. This is where the real magic of this code happens. It does not always end up creating the code succesfully, but it is quite fascinating to watch the creation process.

In addition, to stop continous loops and excessive api usage costs, program asks for the user confirmation after each time the 4th agent gives response. If the user types ‘y’, then the loop starts from the code instructor, by handing over the already created work and critique to it.

You can find the code for this program on the GitHub repository called InfantAGI, you can clone the GitHub repository and run the code on your local machine. Before running the code, make sure you have installed the required Python packages, which are OpenAI, textwrap, subprocess, json, shutil, sys, os, and colorama. You also need to have an OpenAI API key, which you can obtain by creating an account on the OpenAI website.

Once you have the API key, enter it in the code where it says “YOUR_API_KEY”. Then, run the program and follow the prompts to give a task as input, refine the task, create instructions for Python code, write the code, execute it, and give feedback to refine the instructions further.

Note that this program involves multiple agents and may take some time to run, depending on the complexity of the task and the quality of the instructions and the code. Also, the program may require some modifications to fit your specific use case, as it is designed to be a general-purpose tool for refining tasks and writing Python code instructions.I have very limited knowledge of Python and coding parts of this project was mostly taken care of AI.

The Code:

import openai
import textwrap 
import subprocess
import json
import shutil
import sys
import os
import colorama
from colorama import Fore, Style

# Enter your own API key code instead of Your_API_Key below
openai.api_key='YOUR_API_KEY'

# Defining the shared parameters of the agents

def call_openai(messages, model="gpt-3.5-turbo", temperature=0.5, max_tokens=2000, n=1):
    response = openai.ChatCompletion.create(
         messages=messages,  
         model=model,
         max_tokens=max_tokens,
         temperature=temperature,
         n=n,
         stop=None
     )       
    return response

# Definition of chatbots for ease of use

def chatbot(number, role, input):
    messages = [  
      {"role": "system", "content" : role},
      {"role": "user", "content": input }   
    ]       
    response = call_openai(messages=messages)       
    text = response['choices'][0]['message']['content']       
    return text

# colored print function

colorama.init()

def print_color(text, color, nowrap=False):
    colors = {
        'red': Fore.RED,
        'green': Fore.GREEN,
        'yellow': Fore.YELLOW,
        'blue': Fore.BLUE,
        'magenta': Fore.MAGENTA,
        'cyan': Fore.CYAN,
        'paleblue': Fore.CYAN
    }
    try:
        color_code = colors[color.lower()]
        if nowrap:
            wrapped_lines = text.split('\n')
        else:
            width, _ = shutil.get_terminal_size()
            lines = text.split('\n')
            wrapped_lines = [textwrap.fill(line, width=width) for line in lines]
        wrapped_text = '\n'.join(wrapped_lines)
        
        # Check if running in an IDLE shell environment
        if 'idlelib.run' in sys.modules:
            print(wrapped_text)
        else:
            print(color_code + wrapped_text + Style.RESET_ALL)
            
    except KeyError:
        print(text)
    print("----------------")

# User input
user_input = input("Give me a task..." )
print_color("User input is: \n" + user_input, 'red')
# Agent role and input definition 

role1 = '''
        Your instructions are:
        You are responsible for refining the description of a task given to you to let a code instructor write instructions for a Python code to perform the given task. 
        Do not write the instructions, only refine the input which will be used for writing the instructions
        Always refine the task to be used as an input for creating Python code instructions.
        When the given task is to find an information, always consider search engines as a way to gather information and suggest their usage whenever applicable using beautifulsoup module.
        Consider the input, output, and overall goal but do not write them.
        Look for indirect or non-obvious ways to accomplish the task given your capabilities.
        '''     
input1 = user_input    

refined_input = chatbot(1, role1, input1)

print_color("Refined input is: \n" + refined_input, 'blue')

role2 = '''
        Your instructions are:
        You are responsible for creating a detailed code description for a chatgpt agent to perform the given task most effectively.
        Your job is to figure out how to perform the given task by writing a Python code, then create instructions for writing the code or correcting a given code or code error.
        You are not allowed to write any code. You only write instructions about how to write code.
        Let's follow a step-by-step approach to create smart instructions for the given task.
        You are allowed to give outputs as numbered lists only. Don't write anything else other than the instructions as numbered lists.
        You are not allowed to give any title to your list. Start from the list itself.
        If you will instruct to search for a term in a webpage using beautifulsoup module, you can use this search method:
            results = soup.find_all('p') # finds all <p> tags
            results = soup.find_all('div') # finds all <div> tags
            for result in results:
                if 'your text' in result.text:
                    # found it!
        Instruct to add a line break at the end of each line of the code.
        If there is any additional feedback, always prioritize it
        '''    

role3 = '''
        Your instructions are:
        You can only speak in Python language. You cannot express anything in any other language.
        Your job is to express any given task to you in Python code based on the provided instructions.
        Your code shall never start with a comment block.
        Add a line break at the end of each line of the code.
        Ensure the code is properly indented and formatted for execution.
        Your code must include at least two print statements:
          - One to display intermediate results or values.
          - A final print statement to display the full output or result.
        Your code must include print statements like:
          - print(n) # To display the input argument.
          - print(fib_list) # To display intermediate results.
          - print(fibonacci(n)) # To display the final output.
        Your code shall never start with anything other than a Python command.
        You are not allowed to write anything other than Python code. No Python comments either. Only write the code itself.
        ''' 

role4 = '''
        Your instructions are:
        Your job is to check a Python code and its output and provide feedback to refine the instructions for writing the code.
        Let's approach this task in a step-by-step way to give better feedback.
        If you receive a ModuleNotFoundError, advise how to install that module with a shell command using subprocess.run() function
        If you think the code satisfies the given task and has a successful output, write 'bazinga' with your final statement. If the output is an error or blank, write 'not ready'.
        I repeat, until the output is not an error or blank, do not mention or write the word 'bazinga!', write 'not ready' instead. This is important. 
        Do not write 'do not write or mention bazinga' or anything similar, too.
        '''

while True:

    # Code Instructor
    input2 = 'your task is:' + user_input + 'details of your task is:' + refined_input
    code_instruction = chatbot(2, role2, input2)   
    print_color("Code instruction: \n" + code_instruction, 'green')

    # Coder
    input3 = ' Given task is:' + user_input + ' Refined task description is:' + refined_input + ' Code instruction is: ' + code_instruction     
    code_solution = chatbot(3, role3, input3)   
    print("\033[95m", "Coder:\n" + code_solution + "\n---------------- " "\033[0m")

    # Execute the code and capture the output
    result = subprocess.run(['python', '-c', code_solution],
                            text=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)

    if result.returncode != 0:
        output = result.stderr.strip()
        print_color("Output: \n" + output, 'paleblue', nowrap=True)
    else:
        output = result.stdout.strip()
        print_color("Output: \n" + output, 'paleblue')

    # Code checker
    input4 = 'The instruction is: ' + user_input + ' The code to check is: ' + code_solution + ' The output or the error code is: ' + output      
    code_checker = chatbot(4, role4, input4)   
    print_color("Advisor: \n" + code_checker, 'red')

    # Check if the code_checker output contains 'bazinga' and meets additional conditions
    if ('bazinga' in code_checker.lower()) and (output or result.returncode != 0) and ('error' not in code_checker.lower()):
        break # Break the while loop


    user_input = ' Your code is: ' + code_solution + ' Refined task description is:' + refined_input + ' Output of your code is: ' + output + ' Review of your code is: ' + code_checker 

    # User input for continuation
    user_input2 = input("Continue or comment (y/n/?): ")
    user_input2 = user_input2.lower()

    if user_input2 == "n":
        break # End the while loop if user_input2 is 'n' or 'N'
    elif user_input2 == "y":
        continue # Go back to the beginning of the while loop if user_input2 is 'y' or 'Y'
    else:
        user_input = user_input + " Additional feedback: " + user_input2 # Assign user_input2 to user_input if it is anything else than y or no
4 Likes

Here are some output samples of the code for a given tasks:

A first try success for prime number calculation and plotting. Only the first line is the user input. the rest is written by the code and the ai agents.

Give me a task...calculate the first 100 prime numbers and plot them
User input is:
calculate the first 100 prime numbers and plot them
----------------
Refined input is:
Refined task: Write Python code to generate the first 100 prime numbers and plot
them using a suitable Python plotting library. Consider using the Sieve of
Eratosthenes algorithm to efficiently generate the prime numbers.
----------------
Code instruction:
Instructions to generate the first 100 prime numbers and plot them using Python:

1. Import the necessary libraries for generating and plotting prime numbers. You
can use the following code:
    ```
    import numpy as np
    import matplotlib.pyplot as plt
    ```

2. Define a function to generate prime numbers using the Sieve of Eratosthenes
algorithm. The function should take an integer `n` as input and return a list of
prime numbers up to `n`. You can use the following code:
    ```
    def generate_primes(n):
        primes = [True] * (n+1)
        primes[0] = primes[1] = False
        for i in range(2, int(np.sqrt(n))+1):
            if primes[i]:
                for j in range(i**2, n+1, i):
                    primes[j] = False
        return [i for i in range(2, n+1) if primes[i]]
    ```

3. Call the `generate_primes` function with `n=541` to generate the first 100
prime numbers. You can use the following code:
    ```
    primes = generate_primes(541)[:100]
    ```

4. Plot the prime numbers using a suitable Python plotting library, such as
Matplotlib. You can use the following code:
    ```
    x = np.arange(1, 101)
    plt.plot(x, primes, 'o')
    plt.xlabel('Index')
    plt.ylabel('Prime number')
    plt.title('First 100 prime numbers')
    plt.show()
    ```

5. Run the entire code to generate and plot the first 100 prime numbers. The
output should be a scatter plot of the prime numbers with the x-axis
representing their index and the y-axis representing the value of the prime
numbers.
----------------
 Coder:
import numpy as np
import matplotlib.pyplot as plt

def generate_primes(n):
    primes = [True] * (n+1)
    primes[0] = primes[1] = False
    for i in range(2, int(np.sqrt(n))+1):
        if primes[i]:
            for j in range(i**2, n+1, i):
                primes[j] = False
    return [i for i in range(2, n+1) if primes[i]]

primes = generate_primes(541)[:100]

x = np.arange(1, 101)
plt.plot(x, primes, 'o')
plt.xlabel('Index')
plt.ylabel('Prime number')
plt.title('First 100 prime numbers')
plt.show()
---------------- 
Output:
Figure(640x480)
----------------
Advisor:
bazinga!
----------------

Another example, unsuccesful attempt for finding a simple information from internet :

Give me a task...Find out the height of Eiffel Tower
User input is:
Find out the height of Eiffel Tower
----------------
Refined input is:
Refined task: Write Python code to scrape the height of the Eiffel Tower from a
reliable website using the Beautiful Soup module.
----------------
Code instruction:
Here are the instructions to scrape the height of the Eiffel Tower using Python
and Beautiful Soup module:

1. Import the required modules: requests and BeautifulSoup. Install them if not
already installed.

2. Use the requests module to send a GET request to a reliable website that
contains the information about the height of the Eiffel Tower. Save the response
in a variable.

3. Create a BeautifulSoup object by passing the response.text and specify the
parser to use. lxml is a commonly used parser.

4. Find the HTML tag that contains the height information of the Eiffel Tower.
This can be done by inspecting the webpage source code or using the developer
tools of a web browser.

5. Use the find() or find_all() method of the BeautifulSoup object to find the
tag that contains the height information. The method returns a ResultSet object
that contains all the tags that match the search criteria.

6. Extract the height information from the tag by using the text attribute of
the tag. The text attribute returns the text content of the tag.

7. Clean the extracted text by removing any unwanted characters such as
whitespace, newline characters, etc.

8. Convert the extracted text to the desired format if necessary. For example,
convert the height from feet to meters.

9. Print the extracted and cleaned height information.

10. Add error handling to the code to handle cases where the website is not
accessible or the height information is not found.

Here's an example code snippet that performs the above steps:


import requests
from bs4 import BeautifulSoup

# Send a GET request to the website that contains the height information
response = requests.get('htt ps:// www. toureiffel. paris/en/the-
monument/everything-about-the-tower/figures')

# Create a BeautifulSoup object
soup = BeautifulSoup(response.text, 'lxml')

# Find the HTML tag that contains the height information
height_tag = soup.find('div', {'class': 'field field--name-field-second-subtitle
field--type-string field--label-hidden field__item'})

# Extract the height information from the tag
height_text = height_tag.text.strip()

# Clean the extracted text
height = height_text.split()[0]

# Print the extracted and cleaned height information
print("The height of the Eiffel Tower is:", height, "meters")


Note: The above code snippet is just an example and may not work for all
websites. You may need to modify the code based on the structure of the website
you are scraping.
----------------
 Coder:
import requests
from bs4 import BeautifulSoup

# Send a GET request to the website that contains the height information
response = requests.get('https: / /www.  toureiffel. paris/en/the-monument/everything-about-the-tower/figures')

# Create a BeautifulSoup object
soup = BeautifulSoup(response.text, 'lxml')

# Find the HTML tag that contains the height information
height_tag = soup.find('div', {'class': 'field field--name-field-second-subtitle field--type-string field--label-hidden field__item'})

# Extract the height information from the tag
height_text = height_tag.text.strip()

# Clean the extracted text
height = height_text.split()[0]

# Print the extracted and cleaned height information
print("The height of the Eiffel Tower is:", height, "meters")
---------------- 
Output: 
Traceback (most recent call last):
  File "<string>", line 14, in <module>
AttributeError: 'NoneType' object has no attribute 'text'
----------------
Advisor:
The code seems to be correct. However, the error indicates that the height_tag
object is None. This might be due to the fact that the class name used to find
the tag ('field field--name-field-second-subtitle field--type-string field--
label-hidden field__item') might have changed on the website since the code was
written.

To fix this error, you can inspect the website and find the new class name for
the tag containing the height information. Once you have the new class name,
update the code with the new class name and try running it again.

If you receive a ModuleNotFoundError for 'requests' or 'bs4', you can install
them using the following shell commands:
- For requests: `python -m pip install requests`
- For bs4: `python -m pip install beautifulsoup4`

Until the output is not an error or blank, please write 'not ready'.
----------------
Continue or comment (y/n/?): 

Another unsuccesful first try: Asking AI to give a speech about AI and read it out loud:

Give me a task...give a speech about ai and read it with voice
User input is:
give a speech about ai and read it with voice
----------------
Refined input is:
I'm sorry, but as an AI language model, I do not have the capability to generate
an audio output of a speech. However, I can help you refine your task to create
a written speech about AI that can be read aloud by a text-to-speech software or
a voice actor.

To start, it's important to define the purpose and audience of the speech. Are
you trying to educate people about the basics of AI or are you discussing the
implications and potential risks of AI? Is your audience composed of experts or
general public?

Once you have identified your purpose and audience, you can start researching
and organizing your ideas. Consider using search engines and tools like the
beautifulsoup module to gather information from reliable sources.

When writing the speech, make sure to use clear and concise language that is
appropriate for your audience. Avoid technical jargon and explain any complex
concepts in a way that is easy to understand.

You can structure your speech in different ways, but it's generally a good idea
to start with an attention-grabbing introduction that sets the tone and topic of
the speech. Then, you can provide background information and examples to
illustrate your points. You can also include personal anecdotes or stories to
make the speech more engaging.

Finally, conclude the speech with a summary of the main points and a call to
action or a thought-provoking statement that leaves a lasting impression on your
audience.

With a well-written speech, you can use text-to-speech software or a voice actor
to bring your words to life and deliver your message to your intended audience.
----------------
Code instruction:
1. Define the purpose and audience of the speech.
2. Research and organize your ideas using reliable sources and tools like the
beautifulsoup module.
3. Use clear and concise language appropriate for your audience and avoid
technical jargon.
4. Structure your speech with an attention-grabbing introduction, background
information, examples, and personal anecdotes.
5. Conclude the speech with a summary of the main points and a call to action or
thought-provoking statement.
6. Use text-to-speech software or a voice actor to deliver your message to your
intended audience.
----------------
 Coder:
print("Purpose of the speech: To educate the general public about the basics of AI.")
print("Audience: Individuals with little to no prior knowledge about AI.")

# Research and organize ideas using reliable sources and the beautifulsoup module
import requests
from bs4 import BeautifulSoup

url = "https://www.sas.com/en_us/insights/analytics/what-is-artificial-intelligence.html"
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
article = soup.find('div', class_='article-content')
paragraphs = article.find_all('p')

# Use clear and concise language appropriate for the audience and avoid technical jargon
speech = "Good morning everyone. Today, I want to talk to you about one of the most exciting and rapidly advancing fields in technology - artificial intelligence or AI. AI is the development of computer systems that can perform tasks that would normally require human intelligence, such as visual perception, speech recognition, decision-making, and language translation. AI is already being used in many applications that we use every day, such as virtual assistants, search engines, and even social media. But how does AI actually work?"

# Structure the speech with an attention-grabbing introduction, background information, examples, and personal anecdotes
speech += "To understand AI, we need to first understand the concept of machine learning. Machine learning is a method of teaching computers to learn from data, without being explicitly programmed. This means that computers can learn from experience and improve their performance over time. For example, if we want to teach a computer to recognize images of cats, we can show it thousands of images of cats and non-cats, and the computer will learn to distinguish between the two. This is known as supervised learning."

speech += "Another type of machine learning is unsupervised learning, where the computer is given a set of data and must find patterns or relationships within the data. This is useful for tasks such as clustering or anomaly detection. Reinforcement learning is a third type of machine learning, where the computer learns through trial and error, by receiving feedback or rewards for its actions."

speech += "Now, you might be wondering - what are the implications of AI? Well, the potential benefits of AI are enormous. It has the potential to revolutionize many industries, such as healthcare, finance, and transportation. AI can help doctors diagnose diseases more accurately, predict stock prices, and even drive cars autonomously. However, there are also potential risks associated with AI, such as job displacement, bias, and misuse. It's important for us to consider these risks and work towards developing ethical and responsible AI."

# Conclude the speech with a summary of the main points and a call to action or thought-provoking statement
speech += "In conclusion, AI is an incredibly exciting field with enormous potential. We've discussed the basics of AI, including machine learning and its potential benefits and risks. As we continue to develop AI, it's important for us to work towards developing ethical and responsible AI that benefits society as a whole. Thank you for listening."

# Use text-to-speech software or a voice actor to deliver the message to the intended audience.
print(speech)
---------------- 
Output: 
Traceback (most recent call last):
  File "<string>", line 12, in <module>
AttributeError: 'NoneType' object has no attribute 'find_all'
----------------
Advisor:
The code is trying to scrape data from a webpage using BeautifulSoup module, but
it seems like the webpage structure has changed or the class name provided is
incorrect. Please check if the webpage still has the same structure and class
name as mentioned in the code. If not, update the code accordingly.

Also, it seems like the code is missing the text-to-speech conversion part.
Please add the necessary code to convert the speech text to voice using any
text-to-speech software or a voice actor.

Regarding the error, it seems like the 'find_all' function is not able to find
any elements with the specified class name. You can try printing the 'article'
variable to check if it contains any data or not. If not, you can try using a
different class name or structure to scrape the data.

If the code is missing any required modules, you can install them using
subprocess.run() function. For example, to install the 'beautifulsoup4' module,
you can use the following command:

subprocess.run(['pip', 'install', 'beautifulsoup4'])

Please make the necessary changes and try running the code again. If the output
is successful, write 'bazinga'. If not, write 'not ready'.
----------------
Continue or comment (y/n/?): 

2 Likes

Hi, this is great, thanks for sharing!

Quick question, how do you get ‘Coder’ to actually run the code?

I’ve tried in VSCode terminal and in Windows Terminal, and when it tries to execute the code it returns an error because the ‘Coder’ comments and backticks are included in the executed code.

For example,

----------------
 Coder:
```python
import math

def simplify_sqrt(n):
    if math.sqrt(n).is_integer():
        return int(math.sqrt(n))
    else:
        perfect_square = int(math.floor(math.sqrt(n))) ** 2
        quotient = n // perfect_square
        remainder = n % perfect_square
        simplified_quotient = simplify_sqrt(quotient)
        return str(int(math.sqrt(perfect_square))) + '√' + str(simplified_quotient) if remainder != 0 else str(int(math.sqrt(perfect_square)))

n = int(input("Enter the value of n: "))
simplified_expression = simplify_sqrt(n)
print("The simplified square root expression of sqrt({}) is: {}".format(n, simplified_expression))

----------------
Output:
File "<string>", line 1
    ```python
    ^
SyntaxError: invalid syntax
----------------
Advisor:
This error is not related to the code provided. It seems like there is some syntax error in the code that you are trying to run. Please check the code that you are trying to run.

Please run the code and provide the output.

I understand it’s asking me to manually paste the output to continue, but just checking if it’s meant to run the code autonomously and refine itself?

1 Like

Thanks for the comment. First of all, I have a very little coding experience and learnt all this from AI chatbots. But I will try to explain how it is handled in my code. The first step is to instruct the coder to output the code in a clean form so that when it is executed, it won’t give any syntax errors. I have given those instructions in role3 section and I mostly reached this final form by trial and error. In this form, it usually succesfully instruct chatgpt to output the code ready to execute.

Second step is to assign the coders output to a variable and execute it using python. I learnt that the common way to do that is to use exec command as exec(output). But after this execution, my intention was to assing the executed output to another variable and pass it to advisor for its review of the code as well as its output. Apparently, it is not possible to assing the output of the exec command to a variable in p ython, I don’t know why. But when I asked the solution to chatgpt, it advised me to use subprocess module instead of the exec command. So I ended up with the below solution which works as I expected.

    result = subprocess.run(['python', '-c', code_solution],
                            text=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)

    if result.returncode != 0:
        output = result.stderr.strip()
        print_color("Output: \n" + output, 'paleblue', nowrap=True)
    else:
        output = result.stdout.strip()
        print_color("Output: \n" + output, 'paleblue')

On a second look, I noticed a conflicting instruction in role 3, due to the trial and error methods I mentioned. You can remove the line in role 3: ‘Your code shall never start with anything other than a Python command.’ and see if it gets any better.

Here is an updated version inspired by your comment. There are 2 new additions in this version. 1st is the introduction of a new agent called the code_refiner who is responsible for removing any comments in the code and make it ready to execute. It still cannot always %100 follow this instruction but it significantly increases the succes rate. 2nd is the addition of a module installer. It checks if the output has any missing module error and it automatically attempts to install it. Before this addition, program was struggling if there was any missing module. this also increases the success rate of the code execution. you can give it a task of ‘say hello world using a tts’ and it most probably will manage to say those words using a text to speech module.

import openai
import textwrap 
import subprocess
import json
import shutil
import sys
import os
import colorama
import re
from colorama import Fore, Style

# Enter your own API key code instead of Your_API_Key below
openai.api_key='YOUR_API_KEY'

# Defining the shared parameters of the agents

def call_openai(messages, model="gpt-3.5-turbo", temperature=0.5, max_tokens=2000, n=1):
    response = openai.ChatCompletion.create(
         messages=messages,  
         model=model,
         max_tokens=max_tokens,
         temperature=temperature,
         n=n,
         stop=None
     )       
    return response

# Definition of chatbots for ease of use

def chatbot(number, role, input):
    messages = [  
      {"role": "system", "content" : role},
      {"role": "user", "content": input }   
    ]       
    response = call_openai(messages=messages)       
    text = response['choices'][0]['message']['content']       
    return text

# Missing module installer function

def check_and_install_module(module_name):
    try:
        __import__(module_name)
    except ImportError:
        print(f"Module '{module_name}' is missing. Installing...")
        subprocess.check_call(['pip', 'install', module_name])
        print(f"Module '{module_name}' has been installed.")
        return False
    return True

def extract_missing_module(error_message):
    pattern = r"No module named '(\w+)'"
    match = re.search(pattern, error_message)
    if match:
        return match.group(1)
    return None

# colored print function

colorama.init()

def print_color(text, color, nowrap=False):
    colors = {
        'red': Fore.RED,
        'green': Fore.GREEN,
        'yellow': Fore.YELLOW,
        'blue': Fore.BLUE,
        'magenta': Fore.MAGENTA,
        'lightmagenta': Fore.LIGHTMAGENTA_EX,
        'cyan': Fore.CYAN,
        'paleblue': Fore.LIGHTBLUE_EX,
        'gray': Fore.LIGHTBLACK_EX
    }
    try:
        color_code = colors[color.lower()]
        if nowrap:
            wrapped_lines = text.split('\n')
        else:
            width, _ = shutil.get_terminal_size()
            lines = text.split('\n')
            wrapped_lines = [textwrap.fill(line, width=width) for line in lines]
        wrapped_text = '\n'.join(wrapped_lines)
        
        # Check if running in an IDLE shell environment
        if 'idlelib.run' in sys.modules:
            print(wrapped_text)
        else:
            print(color_code + wrapped_text + Style.RESET_ALL)
            
    except KeyError:
        print(text)
    print("----------------")

# User input
user_input = input("Give me a task..." )
print_color("User input is: \n" + user_input, 'red')
# Agent role and input definition 

role_input_refiner = '''
        Your instructions are:
        You are responsible for refining the description of a task given to you to let a code instructor write instructions for a Python code to perform the given task. 
        Do not write the instructions, only refine the input which will be used for writing the instructions
        Always refine the task to be used as an input for creating Python code instructions.
        When the given task is to find an information, always consider search engines as a way to gather information and suggest their usage whenever applicable using beautifulsoup module.
        Consider the input, output, and overall goal but do not write them.
        Look for indirect or non-obvious ways to accomplish the task given your capabilities.
        '''     
input1 = user_input    

refined_input = chatbot(1, role_input_refiner, input1)

print_color("Refined input is: \n" + refined_input, 'blue')

role_code_instructor = '''
        Your instructions are:
        You are responsible for creating a detailed code description for a chatgpt agent to perform the given task most effectively.
        Your job is to figure out how to perform the given task by writing a Python code, then create instructions for writing the code or correcting a given code or code error.
        You are not allowed to write any code. You only write instructions about how to write code.
        Let's follow a step-by-step approach to create smart instructions for the given task.
        You are allowed to give outputs as numbered lists only. Don't write anything else other than the instructions as numbered lists.
        You are not allowed to give any title to your list. Start from the list itself.
        If you will instruct to search for a term in a webpage using beautifulsoup module, you can use this search method:
            results = soup.find_all('p') # finds all <p> tags
            results = soup.find_all('div') # finds all <div> tags
            for result in results:
                if 'your text' in result.text:
                    # found it!
        Instruct to add a line break at the end of each line of the code.
        If there is any additional feedback, always prioritize it
        '''    

role_coder = '''
        Your instructions are:
        You can only speak in Python language. You cannot express anything in any other language.
        Your job is to express any given task to you in Python code based on the provided instructions.
        Your code will be executed using exec comment in python automatically. Therefore it shall be written with correct formatting, indents and with no comments added.
        You never add ``` to your code
        Add a line break at the end of each line of the code.
        Ensure the code is properly indented and formatted for execution.
        Your code must include at least two print statements:
          - One to display intermediate results or values.
          - A final print statement to display the full output or result.
        Your code must include print statements like:
          - print(n) # To display the input argument.
          - print(fib_list) # To display intermediate results.
          - print(fibonacci(n)) # To display the final output.
        You are not allowed to write anything other than Python code. No Python comments either. Only write the code itself.
        ''' 


role_code_refiner = '''
        Your instructions are:
        You are a python code refiner.
        Your job is to make any python code ready for execution.
        You will remove any comments or comment blocks from the code and give a functional code, free from any comments
        Do not write any title or description. start writing directly from the code itself
        If you find any ``` in the code, you shall remove them.

        ''' 

role_advisor = '''
        Your instructions are:
        Your job is to check a Python code and its output and provide feedback to refine the instructions for writing the code.
        Let's approach this task in a step-by-step way to give better feedback.
        If you think the code satisfies the given task and has a successful output, write 'bazinga' with your final statement. If the output is an error or blank, write 'not ready'.
        I repeat, until the output is not an error or blank, do not mention or write the word 'bazinga!', write 'not ready' instead. This is important. 
        Do not write 'do not write or mention bazinga' or anything similar, too.
        '''

role_pip_installer = '''
        Your instructions are:
        You are a python module installer.
        Your job is to look at the code review and write a python subprocess call which can install the python modules mentioned in the code review
        An example for the termcolor module installation is subprocess.run(['pip', 'install', 'termcolor']). You can replace the mentioned module with termcolor in that example
        Do not write any explanation, description or comment. write only the installation code itself
        You do not need to import subprocess module, it is already imported
        If no module is mentioned in the code review, always only write 'No module installation is required'

        ''' 

while True:

    # Code Instructor
    input2 = 'your task is:' + user_input + 'details of your task is:' + refined_input
    code_instruction = chatbot(2, role_code_instructor, input2)   
    print_color("Code instruction: \n" + code_instruction, 'green')

    # Coder
    input3 = ' Given task is:' + user_input + ' Refined task description is:' + refined_input + ' Code instruction is: ' + code_instruction     
    code_solution0 = chatbot(3, role_coder, input3)   
    print("\033[35m", "Coder:\n" + code_solution0 + "\n---------------- " "\033[0m")

    # Refined Coder
    input4 = ' The code to refine is:' + code_solution0   
    code_solution = chatbot(4, role_code_refiner, input4)   
    print("\033[95m", "Refined Code:\n" + code_solution + "\n---------------- " "\033[0m")

    # Execute the code and capture the output
    result = subprocess.run(['python', '-c', code_solution],
                            text=True,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)

    if result.returncode != 0:
        output = result.stderr.strip()
        missing_module = extract_missing_module(output)
        if missing_module:
            module_installed = check_and_install_module(missing_module)
            if module_installed:
                output = ""
    else:
        output = result.stdout.strip()

    print_color("Output: \n" + output, 'paleblue', nowrap=True)

    # Code checker
    input5 = 'The instruction is: ' + user_input + ' The code to check is: ' + code_solution + ' The output or the error code is: ' + output      
    code_checker_input = {
        'input': input5,
        'module_installed': module_installed if 'module_installed' in locals() else True
    }
    code_checker_input_json = json.dumps(code_checker_input)  # Convert to JSON string
    code_checker = chatbot(5, role_advisor, code_checker_input_json)   
    print_color("Advisor: \n" + code_checker, 'red')

    # Check if the code_checker output contains 'bazinga' and meets additional conditions
    if ('bazinga' in code_checker.lower()) and (output or result.returncode != 0) and ('error' not in code_checker.lower()):
        break # Break the while loop

    user_input = ' Your code is: ' + code_solution + ' Refined task description is:' + refined_input +' The code is: ' + code_solution + ' Output of your code is: ' + output + ' Review of your code is: ' + code_checker 

    # User input for continuation
    user_input2 = input("Continue or comment (y/n/?): ")
    user_input2 = user_input2.lower()

    if user_input2 == "n":
        break # End the while loop if user_input2 is 'n' or 'N'
    elif user_input2 == "y":
        continue # Go back to the beginning of the while loop if user_input2 is 'y' or 'Y'
    else:
        user_input = user_input + " Additional feedback: " + user_input2 # Assign user_input2 to user_input if it is anything else than y or no
1 Like

Hey mate, thanks for the update. Unfortunately my free GPT $'s expired last night so I don’t have access to the API right now, only ChatGPT Plus. I’ll give it a run as soon as I can … I’m learning Python and I think your program will help a lot with advanced projects.

Thanks for the feedback mate. Glad that you liked it. Take care.

Eren,

This fascinating. I also did some work here, and even applied for some support/access from OpenAI.

I just copied your code to begin experimenting with it. I cannot paste in links here, but if you email me or look me up on LinkedIn, you can see what I did.

Are you still working on this? I would be nice to have someone else interested to discuss approaches with.

Rand Dannenberg
RaNDTek LLC
Please look me up on LinkedIn!