From 06602440178b5b646d2d650f3fddf30862a73402 Mon Sep 17 00:00:00 2001 From: Nicholas Albion Date: Wed, 20 Sep 2023 22:14:59 +1000 Subject: [PATCH] fabulous does not work on Windows --- pilot/database/database.py | 2 +- pilot/helpers/AgentConvo.py | 6 ++-- pilot/helpers/Project.py | 12 ++++---- pilot/helpers/agents/Architect.py | 4 +-- pilot/helpers/agents/Developer.py | 26 ++++++++-------- pilot/helpers/agents/ProductOwner.py | 8 ++--- pilot/helpers/agents/TechLead.py | 4 +-- pilot/helpers/cli.py | 8 ++--- pilot/helpers/files.py | 2 +- pilot/main.py | 4 +-- pilot/prompts/prompts.py | 5 +--- pilot/utils/llm_connection.py | 2 +- pilot/utils/questionary.py | 6 ++-- pilot/utils/style.py | 45 ++++++++++++++++++++++++++++ pilot/utils/utils.py | 4 +-- 15 files changed, 89 insertions(+), 49 deletions(-) create mode 100644 pilot/utils/style.py diff --git a/pilot/database/database.py b/pilot/database/database.py index 83bd5d9..fce5602 100644 --- a/pilot/database/database.py +++ b/pilot/database/database.py @@ -1,6 +1,6 @@ from playhouse.shortcuts import model_to_dict from peewee import * -from fabulous.color import yellow, red +from utils.style import yellow, red from functools import reduce import operator import psycopg2 diff --git a/pilot/helpers/AgentConvo.py b/pilot/helpers/AgentConvo.py index ceffb6d..48f2682 100644 --- a/pilot/helpers/AgentConvo.py +++ b/pilot/helpers/AgentConvo.py @@ -1,7 +1,7 @@ import re import subprocess import uuid -from fabulous.color import yellow, bold +from utils.style import yellow, yellow_bold from database.database import get_saved_development_step, save_development_step, delete_all_subsequent_steps from helpers.files import get_files_content @@ -126,7 +126,7 @@ class AgentConvo: # Continue conversation until GPT response equals END_RESPONSE while response != END_RESPONSE: - print(yellow("Do you want to add anything else? If not, ") + yellow(bold('just press ENTER.'))) + print(yellow("Do you want to add anything else? If not, ") + yellow_bold('just press ENTER.')) user_message = ask_user(self.agent.project, response, False) if user_message == "": @@ -204,7 +204,7 @@ class AgentConvo: print_msg = capitalize_first_word_with_underscores(self.high_level_step) if self.log_to_user: if self.agent.project.checkpoints['last_development_step'] is not None: - print(yellow("\nDev step ") + yellow(bold(str(self.agent.project.checkpoints['last_development_step']))) + '\n', end='') + print(yellow("\nDev step ") + yellow_bold(str(self.agent.project.checkpoints['last_development_step'])) + '\n', end='') print(f"\n{content}\n") logger.info(f"{print_msg}: {content}\n") diff --git a/pilot/helpers/Project.py b/pilot/helpers/Project.py index 4843c93..7497cd0 100644 --- a/pilot/helpers/Project.py +++ b/pilot/helpers/Project.py @@ -1,6 +1,6 @@ import json -from fabulous.color import bold, green, yellow, cyan, white +from utils.style import green_bold, yellow_bold, cyan, white_bold from const.common import IGNORE_FOLDERS, STEPS from database.database import delete_unconnected_steps_from, delete_all_app_development_data from const.ipc import MESSAGE_TYPE @@ -67,10 +67,10 @@ class Project: # if development_plan is not None: # self.development_plan = development_plan - print(green(bold('\n------------------ STARTING NEW PROJECT ----------------------'))) + print(green_bold('\n------------------ STARTING NEW PROJECT ----------------------')) print(f"If you wish to continue with this project in future run:") - print(green(bold(f'python main.py app_id={args["app_id"]}'))) - print(green(bold('--------------------------------------------------------------\n'))) + print(green_bold(f'python main.py app_id={args["app_id"]}')) + print(green_bold('--------------------------------------------------------------\n')) def start(self): """ @@ -306,10 +306,10 @@ class Project: reset_branch_id = convo.save_branch() while answer != 'continue': - print(yellow(bold(message))) + print(yellow_bold(message)) if description is not None: print('\n' + '-'*100 + '\n' + - white(bold(description)) + + white_bold(description) + '\n' + '-'*100 + '\n') answer = styled_text( diff --git a/pilot/helpers/agents/Architect.py b/pilot/helpers/agents/Architect.py index 667fa64..0d4be05 100644 --- a/pilot/helpers/agents/Architect.py +++ b/pilot/helpers/agents/Architect.py @@ -1,7 +1,7 @@ from utils.utils import step_already_finished from helpers.Agent import Agent import json -from fabulous.color import green, bold +from utils.style import green_bold from const.function_calls import ARCHITECTURE from utils.utils import should_execute_step, find_role_from_step, generate_app_data @@ -28,7 +28,7 @@ class Architect(Agent): return step['architecture'] # ARCHITECTURE - print(green(bold(f"Planning project architecture...\n"))) + print(green_bold(f"Planning project architecture...\n")) logger.info(f"Planning project architecture...") self.convo_architecture = AgentConvo(self) diff --git a/pilot/helpers/agents/Developer.py b/pilot/helpers/agents/Developer.py index db42aae..19af737 100644 --- a/pilot/helpers/agents/Developer.py +++ b/pilot/helpers/agents/Developer.py @@ -1,5 +1,5 @@ import uuid -from fabulous.color import yellow, green, red, bold, blue, white +from utils.style import yellow, green, red, blue, white, green_bold, yellow_bold, red_bold, blue_bold, white_bold from helpers.exceptions.TokenLimitError import TokenLimitError from const.code_execution import MAX_COMMAND_DEBUG_TRIES from helpers.exceptions.TooDeepRecursionError import TooDeepRecursionError @@ -31,7 +31,7 @@ class Developer(Agent): self.project.skip_steps = False if ('skip_until_dev_step' in self.project.args and self.project.args['skip_until_dev_step'] == '0') else True # DEVELOPMENT - print(green(bold(f"Ok, great, now, let's start with the actual development...\n"))) + print(green_bold(f"Ok, great, now, let's start with the actual development...\n")) logger.info(f"Starting to create the actual code...") for i, dev_task in enumerate(self.project.development_plan): @@ -42,7 +42,7 @@ class Developer(Agent): logger.info('The app is DONE!!! Yay...you can use it now.') def implement_task(self, i, development_task=None): - print(green(bold(f'Implementing task #{i + 1}: ')) + green(f' {development_task["description"]}\n')) + print(green_bold(f'Implementing task #{i + 1}: ') + green(f' {development_task["description"]}\n')) convo_dev_task = AgentConvo(self) task_description = convo_dev_task.send_message('development/task/breakdown.prompt', { @@ -96,7 +96,7 @@ class Developer(Agent): def step_human_intervention(self, convo, step): while True: - human_intervention_description = step['human_intervention_description'] + yellow(bold('\n\nIf you want to run the app, just type "r" and press ENTER and that will run `' + self.run_command + '`')) if self.run_command is not None else step['human_intervention_description'] + human_intervention_description = step['human_intervention_description'] + yellow_bold('\n\nIf you want to run the app, just type "r" and press ENTER and that will run `' + self.run_command + '`') if self.run_command is not None else step['human_intervention_description'] response = self.project.ask_for_human_intervention('I need human intervention:', human_intervention_description, cbs={ 'r': lambda conv: run_command_until_success(self.run_command, None, conv, force=True, return_cli_response=True) }, @@ -151,8 +151,8 @@ class Developer(Agent): if step_implementation_try >= MAX_COMMAND_DEBUG_TRIES: self.dev_help_needed(step) - print(red(bold(f'\n--------- LLM Reached Token Limit ----------'))) - print(red(bold(f'Can I retry implementing the entire development step?'))) + print(red_bold(f'\n--------- LLM Reached Token Limit ----------')) + print(red_bold(f'Can I retry implementing the entire development step?')) answer = '' while answer != 'y': @@ -169,9 +169,9 @@ class Developer(Agent): def dev_help_needed(self, step): if step['type'] == 'command': - help_description = (red(bold(f'I tried running the following command but it doesn\'t seem to work:\n\n')) + - white(bold(step['command']['command'])) + - red(bold(f'\n\nCan you please make it work?'))) + help_description = (red_bold(f'I tried running the following command but it doesn\'t seem to work:\n\n') + + white_bold(step['command']['command']) + + red_bold(f'\n\nCan you please make it work?')) elif step['type'] == 'code_change': help_description = step['code_change_description'] elif step['type'] == 'human_intervention': @@ -190,9 +190,9 @@ class Developer(Agent): answer = '' while answer != 'continue': - print(red(bold(f'\n----------------------------- I need your help ------------------------------'))) + print(red_bold(f'\n----------------------------- I need your help ------------------------------')) print(extract_substring(str(help_description))) - print(red(bold(f'\n-----------------------------------------------------------------------------'))) + print(red_bold(f'\n-----------------------------------------------------------------------------')) answer = styled_text( self.project, 'Once you\'re done, type "continue"?' @@ -256,8 +256,8 @@ class Developer(Agent): def continue_development(self, iteration_convo, last_branch_name, continue_description=''): while True: iteration_convo.load_branch(last_branch_name) - user_description = ('Here is a description of what should be working: \n\n' + blue(bold(continue_description)) + '\n') if continue_description != '' else '' - user_description = 'Can you check if the app works please? ' + user_description + '\nIf you want to run the app, ' + yellow(bold('just type "r" and press ENTER and that will run `' + self.run_command + '`')) + user_description = ('Here is a description of what should be working: \n\n' + blue_bold(continue_description) + '\n') if continue_description != '' else '' + user_description = 'Can you check if the app works please? ' + user_description + '\nIf you want to run the app, ' + yellow_bold('just type "r" and press ENTER and that will run `' + self.run_command + '`') # continue_description = '' response = self.project.ask_for_human_intervention( user_description, diff --git a/pilot/helpers/agents/ProductOwner.py b/pilot/helpers/agents/ProductOwner.py index b69bbd4..956e1ff 100644 --- a/pilot/helpers/agents/ProductOwner.py +++ b/pilot/helpers/agents/ProductOwner.py @@ -1,4 +1,4 @@ -from fabulous.color import bold, green, yellow +from utils.style import green_bold from helpers.AgentConvo import AgentConvo from helpers.Agent import Agent @@ -48,7 +48,7 @@ class ProductOwner(Agent): self.project, generate_messages_from_description(main_prompt, self.project.args['app_type'], self.project.args['name'])) - print(green(bold('Project Summary:\n'))) + print(green_bold('Project Summary:\n')) convo_project_description = AgentConvo(self) high_level_summary = convo_project_description.send_message('utils/summary.prompt', {'conversation': '\n'.join( @@ -80,7 +80,7 @@ class ProductOwner(Agent): # USER STORIES msg = f"User Stories:\n" - print(green(bold(msg))) + print(green_bold(msg)) logger.info(msg) self.project.user_stories = self.convo_user_stories.continuous_conversation('user_stories/specs.prompt', { @@ -114,7 +114,7 @@ class ProductOwner(Agent): # USER TASKS msg = f"User Tasks:\n" - print(green(bold(msg))) + print(green_bold(msg)) logger.info(msg) self.project.user_tasks = self.convo_user_stories.continuous_conversation('user_stories/user_tasks.prompt', diff --git a/pilot/helpers/agents/TechLead.py b/pilot/helpers/agents/TechLead.py index 6e8eb45..6423718 100644 --- a/pilot/helpers/agents/TechLead.py +++ b/pilot/helpers/agents/TechLead.py @@ -1,7 +1,7 @@ from utils.utils import step_already_finished from helpers.Agent import Agent import json -from fabulous.color import green, bold +from utils.style import green_bold from const.function_calls import DEV_STEPS from helpers.cli import build_directory_tree from helpers.AgentConvo import AgentConvo @@ -32,7 +32,7 @@ class TechLead(Agent): return step['development_plan'] # DEVELOPMENT PLANNING - print(green(bold(f"Starting to create the action plan for development...\n"))) + print(green_bold(f"Starting to create the action plan for development...\n")) logger.info(f"Starting to create the action plan for development...") # TODO add clarifications diff --git a/pilot/helpers/cli.py b/pilot/helpers/cli.py index 8fbf44c..e85fa0b 100644 --- a/pilot/helpers/cli.py +++ b/pilot/helpers/cli.py @@ -7,7 +7,7 @@ import time import uuid import platform -from fabulous.color import yellow, green, white, red, bold +from utils.style import yellow, green, white, red, yellow_bold, white_bold from database.database import get_saved_command_run, save_command_run from const.function_calls import DEBUG_STEPS_BREAKDOWN from helpers.exceptions.TooDeepRecursionError import TooDeepRecursionError @@ -101,8 +101,8 @@ def execute_command(project, command, timeout=None, force=False): timeout = min(max(timeout, MIN_COMMAND_RUN_TIME), MAX_COMMAND_RUN_TIME) if not force: - print(yellow(bold(f'\n--------- EXECUTE COMMAND ----------'))) - print(f'Can i execute the command: `' + yellow(bold(command)) + f'` with {timeout}ms timeout?') + print(yellow_bold(f'\n--------- EXECUTE COMMAND ----------')) + print(f'Can i execute the command: `' + yellow_bold(command) + f'` with {timeout}ms timeout?') answer = styled_text( project, @@ -143,7 +143,7 @@ def execute_command(project, command, timeout=None, force=False): while True and return_value is None: elapsed_time = time.time() - start_time if timeout is not None: - print(white(bold(f'\rt: {round(elapsed_time * 1000)}ms : ')), end='', flush=True) + print(white_bold(f'\rt: {round(elapsed_time * 1000)}ms : '), end='', flush=True) # Check if process has finished if process.poll() is not None: diff --git a/pilot/helpers/files.py b/pilot/helpers/files.py index 9145e99..b594887 100644 --- a/pilot/helpers/files.py +++ b/pilot/helpers/files.py @@ -1,4 +1,4 @@ -from fabulous.color import green +from utils.style import green import os diff --git a/pilot/main.py b/pilot/main.py index 973c153..ea485f4 100644 --- a/pilot/main.py +++ b/pilot/main.py @@ -11,7 +11,7 @@ from termcolor import colored from helpers.ipc import IPCClient from const.ipc import MESSAGE_TYPE from utils.utils import json_serial -from fabulous.color import red +from utils.style import red from helpers.Project import Project from utils.arguments import get_arguments @@ -36,8 +36,6 @@ def init(): return arguments - - def get_custom_print(args): built_in_print = builtins.print diff --git a/pilot/prompts/prompts.py b/pilot/prompts/prompts.py index 38a88b1..4466891 100644 --- a/pilot/prompts/prompts.py +++ b/pilot/prompts/prompts.py @@ -1,8 +1,5 @@ # prompts/prompts.py - -from fabulous.color import yellow -import questionary - +from utils.style import yellow from const import common from const.llm import MAX_QUESTIONS, END_RESPONSE from utils.llm_connection import create_gpt_chat_completion, get_prompt diff --git a/pilot/utils/llm_connection.py b/pilot/utils/llm_connection.py index bb84a4c..2cb6a4e 100644 --- a/pilot/utils/llm_connection.py +++ b/pilot/utils/llm_connection.py @@ -7,12 +7,12 @@ import json import tiktoken import questionary +from utils.style import red from typing import List from jinja2 import Environment, FileSystemLoader from const.llm import MIN_TOKENS_FOR_GPT_RESPONSE, MAX_GPT_MODEL_TOKENS, MAX_QUESTIONS, END_RESPONSE from logger.logger import logger -from fabulous.color import red from helpers.exceptions.TokenLimitError import TokenLimitError from utils.utils import get_prompt_components, fix_json from utils.spinner import spinner_start, spinner_stop diff --git a/pilot/utils/questionary.py b/pilot/utils/questionary.py index d29214c..fbfcd86 100644 --- a/pilot/utils/questionary.py +++ b/pilot/utils/questionary.py @@ -1,6 +1,6 @@ from prompt_toolkit.styles import Style import questionary -from fabulous.color import yellow, bold +from utils.style import yellow_bold from database.database import save_user_input, get_saved_user_input from const.ipc import MESSAGE_TYPE @@ -26,8 +26,8 @@ def styled_text(project, question, ignore_user_input_count=False): if user_input is not None and user_input.user_input is not None and project.skip_steps: # if we do, use it project.checkpoints['last_user_input'] = user_input - print(yellow(bold(f'Restoring user input id {user_input.id}: ')), end='') - print(yellow(bold(f'{user_input.user_input}'))) + print(yellow_bold(f'Restoring user input id {user_input.id}: '), end='') + print(yellow_bold(f'{user_input.user_input}')) return user_input.user_input if project.ipc_client_instance is None or project.ipc_client_instance.client is None: diff --git a/pilot/utils/style.py b/pilot/utils/style.py new file mode 100644 index 0000000..157c255 --- /dev/null +++ b/pilot/utils/style.py @@ -0,0 +1,45 @@ +from termcolor import colored + + +def red(text): + return colored(text, 'red') + + +def red_bold(text): + return colored(text, 'red', attrs=['bold']) + + +def yellow(text): + return colored(text, 'yellow') + + +def yellow_bold(text): + return colored(text, 'yellow', attrs=['bold']) + + +def green(text): + return colored(text, 'green') + + +def green_bold(text): + return colored(text, 'green', attrs=['bold']) + + +def blue(text): + return colored(text, 'blue') + + +def blue_bold(text): + return colored(text, 'blue', attrs=['bold']) + + +def cyan(text): + return colored(text, 'light_cyan') + + +def white(text): + return colored(text, 'white') + + +def white_bold(text): + return colored(text, 'white', attrs=['bold']) diff --git a/pilot/utils/utils.py b/pilot/utils/utils.py index db4b09a..89f019d 100644 --- a/pilot/utils/utils.py +++ b/pilot/utils/utils.py @@ -9,7 +9,7 @@ import json import hashlib import re from jinja2 import Environment, FileSystemLoader -from fabulous.color import green +from termcolor import colored from const.llm import MAX_QUESTIONS, END_RESPONSE from const.common import ROLES, STEPS @@ -126,7 +126,7 @@ def step_already_finished(args, step): args.update(step['app_data']) message = f"{capitalize_first_word_with_underscores(step['step'])} already done for this app_id: {args['app_id']}. Moving to next step..." - print(green(message)) + print(colored(message, 'green')) logger.info(message)