From 31319dd2731a5f4e44644ca66af928865b85a5b5 Mon Sep 17 00:00:00 2001 From: juleshenry Date: Tue, 11 Apr 2023 21:02:39 -0500 Subject: [PATCH 1/6] Address Examples Initiative --- README.md | 2 +- buggy_script.py => examples/buggy_script.py | 4 ++++ examples/buggy_script_2.py | 26 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) rename buggy_script.py => examples/buggy_script.py (82%) create mode 100644 examples/buggy_script_2.py diff --git a/README.md b/README.md index 55813f7..8c06537 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Add your openAI api key to `openai_key.txt` - _warning!_ by default this uses GP To run with gpt-4 (the default, tested option): - python wolverine.py buggy_script.py "subtract" 20 3 + python wolverine.py examples/buggy_script.py "subtract" 20 3 You can also run with other models, but be warned they may not adhere to the edit format as well: diff --git a/buggy_script.py b/examples/buggy_script.py similarity index 82% rename from buggy_script.py rename to examples/buggy_script.py index 3eeb6bb..d85445d 100644 --- a/buggy_script.py +++ b/examples/buggy_script.py @@ -1,5 +1,9 @@ import sys import fire +""" +Run With: `wolverine examples/buggy_script.py "subtract" 20 3` +Purpose: Show self-regenerating fixing of subtraction operator +""" def add_numbers(a, b): return a + b diff --git a/examples/buggy_script_2.py b/examples/buggy_script_2.py new file mode 100644 index 0000000..6891bf6 --- /dev/null +++ b/examples/buggy_script_2.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +import fire + +""" +Run With: with `wolverine examples/buggy_script_2.py "return_2"` +Purpose: Fix singleton code bug in Python +""" + +class SingletonClass(object): + def __new__(cls): + if not hasattr(cls, 'instance'): + cls.instance = super(SingletonClass, cls).__new__(cls) + return cls.instance + +def return_2(): + """ + Always returns 2 + """ + singleton = SingletonClass() + new_singleton = SingletonClass() + singleton.a = 1 + new_singleton.a = 2 + return singleton.a + singleton.a + +if __name__=="__main__": + fire.Fire() \ No newline at end of file From 6bc85a41e2782b45a18d74dfcabd13179d08ca07 Mon Sep 17 00:00:00 2001 From: ksfi Date: Fri, 14 Apr 2023 00:07:57 +0200 Subject: [PATCH 2/6] switch to gpt3 if gpt4 not available --- wolverine.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/wolverine.py b/wolverine.py index 42f7ff8..435c4bd 100644 --- a/wolverine.py +++ b/wolverine.py @@ -13,7 +13,6 @@ from termcolor import cprint with open("openai_key.txt") as f: openai.api_key = f.read().strip() - def run_script(script_name, script_args): script_args = [str(arg) for arg in script_args] try: @@ -113,8 +112,18 @@ def apply_changes(file_path, changes_json): else: print(line, end="") +def avaibility(openaiObj): + models_available = [x['id'] for x in openai.Model.list()['data']] + if "gpt-4" not in models_available: + model = "gpt-3.5-turbo" + else: + model = "gpt-4" + return model -def main(script_name, *script_args, revert=False, model="gpt-4"): + + +def main(script_name, *script_args, revert=False): + model = avaibility(openai) if revert: backup_file = script_name + ".bak" if os.path.exists(backup_file): @@ -135,10 +144,10 @@ def main(script_name, *script_args, revert=False, model="gpt-4"): cprint("Script ran successfully.", "blue") print("Output:", output) break + else: cprint("Script crashed. Trying to fix...", "blue") print("Output:", output) - json_response = send_error_to_gpt( file_path=script_name, args=script_args, @@ -151,3 +160,4 @@ def main(script_name, *script_args, revert=False, model="gpt-4"): if __name__ == "__main__": fire.Fire(main) + From 23e53dbb878e82a8ad86cd94163f3076b51a503a Mon Sep 17 00:00:00 2001 From: ksfi Date: Fri, 14 Apr 2023 01:55:29 +0200 Subject: [PATCH 3/6] let model in default --- wolverine.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/wolverine.py b/wolverine.py index 435c4bd..e63d06c 100644 --- a/wolverine.py +++ b/wolverine.py @@ -113,17 +113,13 @@ def apply_changes(file_path, changes_json): print(line, end="") def avaibility(openaiObj): - models_available = [x['id'] for x in openai.Model.list()['data']] - if "gpt-4" not in models_available: + if "gpt-4" not in [x['id'] for x in openai.Model.list()['data']]: model = "gpt-3.5-turbo" else: model = "gpt-4" return model - - -def main(script_name, *script_args, revert=False): - model = avaibility(openai) +def main(script_name, *script_args, revert=False, model=avaibility(openai)): if revert: backup_file = script_name + ".bak" if os.path.exists(backup_file): From f46701623f86c336c30466bf5a5c7eca3f79d20d Mon Sep 17 00:00:00 2001 From: Julian Henry Date: Thu, 20 Apr 2023 07:01:59 -0500 Subject: [PATCH 4/6] Update buggy_script_2.py @biobootloader, now fails due to singleton modification of attributes --- examples/buggy_script_2.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/buggy_script_2.py b/examples/buggy_script_2.py index 6891bf6..d36cff5 100644 --- a/examples/buggy_script_2.py +++ b/examples/buggy_script_2.py @@ -20,7 +20,9 @@ def return_2(): new_singleton = SingletonClass() singleton.a = 1 new_singleton.a = 2 - return singleton.a + singleton.a + would_be_2 = (singleton.a + singleton.a) + assert would_be_2 == 2 + return would_be_2 if __name__=="__main__": - fire.Fire() \ No newline at end of file + fire.Fire() From bb8c6f8e3e9c7e0f46992739f1f2ffe41ba0bc43 Mon Sep 17 00:00:00 2001 From: BioBootloader Date: Sat, 22 Apr 2023 17:24:47 -0700 Subject: [PATCH 5/6] switch singleton example to have a bug in singleton implementation --- examples/buggy_script_2.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/examples/buggy_script_2.py b/examples/buggy_script_2.py index d36cff5..0cf9128 100644 --- a/examples/buggy_script_2.py +++ b/examples/buggy_script_2.py @@ -2,27 +2,26 @@ import fire """ -Run With: with `wolverine examples/buggy_script_2.py "return_2"` +Run With: with `python wolverine.py examples/buggy_script_2.py` Purpose: Fix singleton code bug in Python """ class SingletonClass(object): - def __new__(cls): - if not hasattr(cls, 'instance'): - cls.instance = super(SingletonClass, cls).__new__(cls) - return cls.instance - -def return_2(): - """ - Always returns 2 - """ - singleton = SingletonClass() - new_singleton = SingletonClass() - singleton.a = 1 - new_singleton.a = 2 - would_be_2 = (singleton.a + singleton.a) - assert would_be_2 == 2 - return would_be_2 + def __new__(cls): + cls.instance = super(SingletonClass, cls).__new__(cls) + return cls.instance + +def check_singleton_works(): + """ + check that singleton pattern is working + """ + singleton = SingletonClass() + new_singleton = SingletonClass() + singleton.a = 1 + new_singleton.a = 2 + should_be_4 = (singleton.a + new_singleton.a) + assert should_be_4 == 4 if __name__=="__main__": - fire.Fire() + fire.Fire(check_singleton_works) + From a1fb03ea81f46e3ee8268804768cf5615bfa49b7 Mon Sep 17 00:00:00 2001 From: BioBootloader Date: Sat, 22 Apr 2023 17:41:13 -0700 Subject: [PATCH 6/6] don't show diff twice, show explanations before diff --- wolverine.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/wolverine.py b/wolverine.py index 8f729fe..8dc2f89 100644 --- a/wolverine.py +++ b/wolverine.py @@ -70,7 +70,10 @@ def json_validated_response(model, messages): messages.append( { "role": "user", - "content": "Your response could not be parsed by json.loads. Please restate your last message as pure JSON.", + "content": ( + "Your response could not be parsed by json.loads. " + "Please restate your last message as pure JSON." + ), } ) # rerun the api call @@ -146,9 +149,13 @@ def apply_changes(file_path, changes: list, confirm=False): elif operation == "InsertAfter": file_lines.insert(line, content + "\n") - # Ask for user confirmation before writing changes - print("\nChanges to be made:") + # Print explanations + cprint("Explanations:", "blue") + for explanation in explanations: + cprint(f"- {explanation}", "blue") + # Display changes diff + print("\nChanges to be made:") diff = difflib.unified_diff(original_file_lines, file_lines, lineterm="") for line in diff: if line.startswith("+"): @@ -158,8 +165,8 @@ def apply_changes(file_path, changes: list, confirm=False): else: print(line, end="") - # Checking if user used confirm flag if confirm: + # check if user wants to apply changes or exit confirmation = input("Do you want to apply these changes? (y/n): ") if confirmation.lower() != "y": print("Changes not applied") @@ -167,24 +174,6 @@ def apply_changes(file_path, changes: list, confirm=False): with open(file_path, "w") as f: f.writelines(file_lines) - - # Print explanations - cprint("Explanations:", "blue") - for explanation in explanations: - cprint(f"- {explanation}", "blue") - - # Show the diff - print("\nChanges:") - diff = difflib.unified_diff( - original_file_lines, file_lines, lineterm="") - for line in diff: - if line.startswith("+"): - cprint(line, "green", end="") - elif line.startswith("-"): - cprint(line, "red", end="") - else: - print(line, end="") - print("Changes applied.")