mirror of
https://github.com/OMGeeky/gpt-pilot.git
synced 2026-02-23 15:49:50 +01:00
Merge branch 'ipc' into debugging_ipc
This commit is contained in:
7
pilot/const/ipc.py
Normal file
7
pilot/const/ipc.py
Normal file
@@ -0,0 +1,7 @@
|
||||
MESSAGE_TYPE = {
|
||||
'verbose': 'verbose',
|
||||
'stream': 'stream',
|
||||
'user_input_request': 'user_input_request',
|
||||
'info': 'info',
|
||||
'local': 'local',
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
from peewee import *
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow, red
|
||||
from functools import reduce
|
||||
import operator
|
||||
import psycopg2
|
||||
@@ -26,6 +26,28 @@ from database.models.command_runs import CommandRuns
|
||||
from database.models.user_inputs import UserInputs
|
||||
from database.models.files import File
|
||||
|
||||
DB_NAME = os.getenv("DB_NAME")
|
||||
DB_HOST = os.getenv("DB_HOST")
|
||||
DB_PORT = os.getenv("DB_PORT")
|
||||
DB_USER = os.getenv("DB_USER")
|
||||
DB_PASSWORD = os.getenv("DB_PASSWORD")
|
||||
|
||||
def get_created_apps():
|
||||
return [model_to_dict(app) for app in App.select()]
|
||||
|
||||
def get_created_apps_with_steps():
|
||||
apps = get_created_apps()
|
||||
for app in apps:
|
||||
app['id'] = str(app['id'])
|
||||
app['steps'] = get_progress_steps(app['id'])
|
||||
app['development_steps'] = get_all_app_development_steps(app['id'])
|
||||
# TODO this is a quick way to remove the unnecessary fields from the response
|
||||
app['steps'] = {outer_k: {k: v for k, v in inner_d.items() if k in {'created_at', 'completeted_at', 'completed'}} if inner_d is not None else None for outer_k, inner_d in app['steps'].items()}
|
||||
app['development_steps'] = [{k: v for k, v in dev_step.items() if k in {'id', 'created_at'}} for dev_step in app['development_steps']]
|
||||
return apps
|
||||
|
||||
def get_all_app_development_steps(app_id):
|
||||
return [model_to_dict(dev_step) for dev_step in DevelopmentSteps.select().where(DevelopmentSteps.app == app_id)]
|
||||
|
||||
def save_user(user_id, email, password):
|
||||
try:
|
||||
@@ -188,7 +210,7 @@ def hash_and_save_step(Model, app_id, hash_data_args, data_fields, message):
|
||||
.execute())
|
||||
|
||||
record = Model.get_by_id(inserted_id)
|
||||
logger.debug(colored(f"{message} with id {record.id}", "yellow"))
|
||||
logger.debug(yellow(f"{message} with id {record.id}"))
|
||||
except IntegrityError:
|
||||
print(f"A record with hash_id {hash_id} already exists for {Model.__name__}.")
|
||||
return None
|
||||
@@ -299,7 +321,7 @@ def delete_all_subsequent_steps(project):
|
||||
def delete_subsequent_steps(model, step):
|
||||
if step is None:
|
||||
return
|
||||
logger.info(colored(f"Deleting subsequent {model.__name__} steps after {step.id}", "red"))
|
||||
logger.info(red(f"Deleting subsequent {model.__name__} steps after {step.id}"))
|
||||
subsequent_steps = model.select().where(model.previous_step == step.id)
|
||||
for subsequent_step in subsequent_steps:
|
||||
if subsequent_step:
|
||||
@@ -335,7 +357,7 @@ def delete_unconnected_steps_from(step, previous_step_field_name):
|
||||
).order_by(DevelopmentSteps.id.desc())
|
||||
|
||||
for unconnected_step in unconnected_steps:
|
||||
print(colored(f"Deleting unconnected {step.__class__.__name__} step {unconnected_step.id}", "red"))
|
||||
print(red(f"Deleting unconnected {step.__class__.__name__} step {unconnected_step.id}"))
|
||||
unconnected_step.delete_instance()
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import re
|
||||
import subprocess
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow, bold
|
||||
|
||||
from database.database import get_development_step_from_hash_id, save_development_step, delete_all_subsequent_steps
|
||||
from helpers.files import get_files_content
|
||||
@@ -54,7 +54,7 @@ class AgentConvo:
|
||||
development_step = get_development_step_from_hash_id(self.agent.project, prompt_path, prompt_data, self.agent.project.llm_req_num)
|
||||
if development_step is not None and self.agent.project.skip_steps:
|
||||
# if we do, use it
|
||||
print(colored(f'Restoring development step with id {development_step.id}', 'yellow'))
|
||||
print(yellow(f'Restoring development step with id {development_step.id}'))
|
||||
self.agent.project.checkpoints['last_development_step'] = development_step
|
||||
self.agent.project.restore_files(development_step.id)
|
||||
response = development_step.llm_response
|
||||
@@ -120,7 +120,7 @@ class AgentConvo:
|
||||
|
||||
# Continue conversation until GPT response equals END_RESPONSE
|
||||
while response != END_RESPONSE:
|
||||
print(colored("Do you want to add anything else? If not, ", 'yellow') + colored('just press ENTER.', 'yellow', attrs=['bold']))
|
||||
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 == "":
|
||||
@@ -195,7 +195,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(colored("\nDev step ", 'yellow') + colored(str(self.agent.project.checkpoints['last_development_step']), 'yellow', attrs=['bold']) + '\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")
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
from termcolor import colored
|
||||
from fabulous.color import bold, green, yellow
|
||||
from const.common import IGNORE_FOLDERS, STEPS
|
||||
from database.models.app import App
|
||||
from database.database import get_app, delete_unconnected_steps_from, delete_all_app_development_data
|
||||
from helpers.ipc import IPCClient
|
||||
from const.ipc import MESSAGE_TYPE
|
||||
from utils.questionary import styled_text
|
||||
from helpers.files import get_files_content, clear_directory, update_file
|
||||
from helpers.cli import build_directory_tree
|
||||
@@ -20,7 +24,7 @@ from utils.files import get_parent_folder
|
||||
|
||||
class Project:
|
||||
def __init__(self, args, name=None, description=None, user_stories=None, user_tasks=None, architecture=None,
|
||||
development_plan=None, current_step=None):
|
||||
development_plan=None, current_step=None, ipc_client_instance=None):
|
||||
"""
|
||||
Initialize a project.
|
||||
|
||||
@@ -47,6 +51,9 @@ class Project:
|
||||
self.root_path = ''
|
||||
self.skip_until_dev_step = None
|
||||
self.skip_steps = None
|
||||
|
||||
self.ipc_client_instance = ipc_client_instance
|
||||
|
||||
# self.restore_files({dev_step_id_to_start_from})
|
||||
|
||||
if current_step is not None:
|
||||
@@ -64,15 +71,29 @@ class Project:
|
||||
# if development_plan is not None:
|
||||
# self.development_plan = development_plan
|
||||
|
||||
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')))
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Start the project.
|
||||
"""
|
||||
self.project_manager = ProductOwner(self)
|
||||
print(json.dumps({
|
||||
"project_stage": "project_description"
|
||||
}), type='info')
|
||||
self.project_manager.get_project_description()
|
||||
print(json.dumps({
|
||||
"project_stage": "user_stories"
|
||||
}), type='info')
|
||||
self.user_stories = self.project_manager.get_user_stories()
|
||||
# self.user_tasks = self.project_manager.get_user_tasks()
|
||||
|
||||
print(json.dumps({
|
||||
"project_stage": "architecture"
|
||||
}), type='info')
|
||||
self.architect = Architect(self)
|
||||
self.architecture = self.architect.get_architecture()
|
||||
|
||||
@@ -111,6 +132,15 @@ class Project:
|
||||
break
|
||||
# TODO END
|
||||
|
||||
self.developer = Developer(self)
|
||||
print(json.dumps({
|
||||
"project_stage": "environment_setup"
|
||||
}), type='info')
|
||||
self.developer.set_up_environment();
|
||||
|
||||
print(json.dumps({
|
||||
"project_stage": "coding"
|
||||
}), type='info')
|
||||
self.developer.start_coding()
|
||||
|
||||
def get_directory_tree(self, with_descriptions=False):
|
||||
@@ -275,7 +305,7 @@ class Project:
|
||||
delete_unconnected_steps_from(self.checkpoints['last_user_input'], 'previous_step')
|
||||
|
||||
def ask_for_human_intervention(self, message, description=None, cbs={}):
|
||||
print(colored(message, "yellow", attrs=['bold']))
|
||||
print(yellow(bold(message)))
|
||||
if description is not None:
|
||||
print('\n' + '-'*100 + '\n' +
|
||||
colored(description, 'white', attrs=['bold']) +
|
||||
@@ -291,3 +321,14 @@ class Project:
|
||||
return cbs[answer]()
|
||||
elif answer != '':
|
||||
return { 'user_input': answer }
|
||||
|
||||
def log(self, text, message_type):
|
||||
if self.ipc_client_instance is None or self.ipc_client_instance.client is None:
|
||||
print(text)
|
||||
else:
|
||||
self.ipc_client_instance.send({
|
||||
'type': MESSAGE_TYPE[message_type],
|
||||
'content': str(text),
|
||||
})
|
||||
if message_type == MESSAGE_TYPE['user_input_request']:
|
||||
return self.ipc_client_instance.listen()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from utils.utils import step_already_finished
|
||||
from helpers.Agent import Agent
|
||||
import json
|
||||
from termcolor import colored
|
||||
from fabulous.color import green, bold
|
||||
from const.function_calls import ARCHITECTURE
|
||||
|
||||
from utils.utils import execute_step, find_role_from_step, generate_app_data
|
||||
@@ -27,7 +27,7 @@ class Architect(Agent):
|
||||
return step['architecture']
|
||||
|
||||
# ARCHITECTURE
|
||||
print(colored(f"Planning project architecture...\n", "green", attrs=['bold']))
|
||||
print(green(bold(f"Planning project architecture...\n")))
|
||||
logger.info(f"Planning project architecture...")
|
||||
|
||||
architecture = self.convo_architecture.send_message('architecture/technologies.prompt',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
import uuid
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow, green, red, bold
|
||||
from helpers.exceptions.TokenLimitError import TokenLimitError
|
||||
from const.code_execution import MAX_COMMAND_DEBUG_TRIES
|
||||
from helpers.exceptions.TooDeepRecursionError import TooDeepRecursionError
|
||||
@@ -32,7 +32,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(colored(f"Ok, great, now, let's start with the actual development...\n", "green", attrs=['bold']))
|
||||
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):
|
||||
@@ -301,7 +301,7 @@ class Developer(Agent):
|
||||
})
|
||||
return
|
||||
# ENVIRONMENT SETUP
|
||||
print(colored(f"Setting up the environment...\n", "green"))
|
||||
print(green(f"Setting up the environment...\n"))
|
||||
logger.info(f"Setting up the environment...")
|
||||
|
||||
os_info = get_os_info()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from termcolor import colored
|
||||
from fabulous.color import bold, green, yellow
|
||||
|
||||
from helpers.AgentConvo import AgentConvo
|
||||
from helpers.Agent import Agent
|
||||
@@ -43,7 +43,7 @@ class ProductOwner(Agent):
|
||||
self.project,
|
||||
generate_messages_from_description(main_prompt, self.project.args['app_type'], self.project.args['name']))
|
||||
|
||||
print(colored('Project Summary:\n', 'green', attrs=['bold']))
|
||||
print(green(bold('Project Summary:\n')))
|
||||
high_level_summary = convo_project_description.send_message('utils/summary.prompt',
|
||||
{'conversation': '\n'.join([f"{msg['role']}: {msg['content']}" for msg in high_level_messages])})
|
||||
|
||||
@@ -73,7 +73,7 @@ class ProductOwner(Agent):
|
||||
|
||||
# USER STORIES
|
||||
msg = f"User Stories:\n"
|
||||
print(colored(msg, "green", attrs=['bold']))
|
||||
print(green(bold(msg)))
|
||||
logger.info(msg)
|
||||
|
||||
self.project.user_stories = self.convo_user_stories.continuous_conversation('user_stories/specs.prompt', {
|
||||
@@ -107,7 +107,7 @@ class ProductOwner(Agent):
|
||||
|
||||
# USER TASKS
|
||||
msg = f"User Tasks:\n"
|
||||
print(colored(msg, "green", attrs=['bold']))
|
||||
print(green(bold(msg)))
|
||||
logger.info(msg)
|
||||
|
||||
self.project.user_tasks = self.convo_user_stories.continuous_conversation('user_stories/user_tasks.prompt',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from utils.utils import step_already_finished
|
||||
from helpers.Agent import Agent
|
||||
import json
|
||||
from termcolor import colored
|
||||
from fabulous.color import green, bold
|
||||
from const.function_calls import DEV_STEPS
|
||||
from helpers.cli import build_directory_tree
|
||||
from helpers.AgentConvo import AgentConvo
|
||||
@@ -29,7 +29,7 @@ class TechLead(Agent):
|
||||
return step['development_plan']
|
||||
|
||||
# DEVELOPMENT PLANNING
|
||||
print(colored(f"Starting to create the action plan for development...\n", "green", attrs=['bold']))
|
||||
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
|
||||
|
||||
@@ -7,7 +7,7 @@ import time
|
||||
import uuid
|
||||
import platform
|
||||
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow, green, white, red, bold
|
||||
from database.database import get_command_run_from_hash_id, save_command_run
|
||||
from const.function_calls import DEBUG_STEPS_BREAKDOWN
|
||||
from helpers.exceptions.TooDeepRecursionError import TooDeepRecursionError
|
||||
@@ -100,8 +100,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(colored(f'\n--------- EXECUTE COMMAND ----------', 'yellow', attrs=['bold']))
|
||||
print(colored(f'Can i execute the command: `') + colored(command, 'yellow', attrs=['bold']) + colored(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,
|
||||
@@ -119,7 +119,7 @@ def execute_command(project, command, timeout=None, force=False):
|
||||
if command_run is not None and project.skip_steps:
|
||||
# if we do, use it
|
||||
project.checkpoints['last_command_run'] = command_run
|
||||
print(colored(f'Restoring command run response id {command_run.id}:\n```\n{command_run.cli_response}```', 'yellow'))
|
||||
print(yellow(f'Restoring command run response id {command_run.id}:\n```\n{command_run.cli_response}```'))
|
||||
return command_run.cli_response
|
||||
|
||||
return_value = None
|
||||
@@ -137,7 +137,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(colored(f'\rt: {round(elapsed_time * 1000)}ms : ', 'white', attrs=['bold']), 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:
|
||||
@@ -146,7 +146,7 @@ def execute_command(project, command, timeout=None, force=False):
|
||||
while not q.empty():
|
||||
output_line = q.get_nowait()
|
||||
if output_line not in output:
|
||||
print(colored('CLI OUTPUT:', 'green') + output_line, end='')
|
||||
print(green('CLI OUTPUT:') + output_line, end='')
|
||||
output += output_line
|
||||
break
|
||||
|
||||
@@ -163,7 +163,7 @@ def execute_command(project, command, timeout=None, force=False):
|
||||
|
||||
if line:
|
||||
output += line
|
||||
print(colored('CLI OUTPUT:', 'green') + line, end='')
|
||||
print(green('CLI OUTPUT:') + line, end='')
|
||||
|
||||
# Read stderr
|
||||
try:
|
||||
@@ -173,7 +173,7 @@ def execute_command(project, command, timeout=None, force=False):
|
||||
|
||||
if stderr_line:
|
||||
stderr_output += stderr_line
|
||||
print(colored('CLI ERROR:', 'red') + stderr_line, end='') # Print with different color for distinction
|
||||
print(red('CLI ERROR:') + stderr_line, end='') # Print with different color for distinction
|
||||
|
||||
except (KeyboardInterrupt, TimeoutError) as e:
|
||||
interrupted = True
|
||||
@@ -268,9 +268,9 @@ def run_command_until_success(command, timeout, convo, additional_message=None,
|
||||
{'cli_response': cli_response, 'command': command, 'additional_message': additional_message})
|
||||
|
||||
if response != 'DONE':
|
||||
print(colored(f'Got incorrect CLI response:', 'red'))
|
||||
print(red(f'Got incorrect CLI response:'))
|
||||
print(cli_response)
|
||||
print(colored('-------------------', 'red'))
|
||||
print(red('-------------------'))
|
||||
|
||||
try:
|
||||
# This catch is necessary to return the correct value (cli_response) to continue development function so
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from termcolor import colored
|
||||
from fabulous.color import green
|
||||
import os
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ def update_file(path, new_content):
|
||||
# Write content to the file
|
||||
with open(path, 'w') as file:
|
||||
file.write(new_content)
|
||||
print(colored(f"Updated file {path}", "green"))
|
||||
print(green(f"Updated file {path}"))
|
||||
|
||||
def get_files_content(directory, ignore=[]):
|
||||
return_array = []
|
||||
|
||||
45
pilot/helpers/ipc.py
Normal file
45
pilot/helpers/ipc.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# ipc.py
|
||||
import socket
|
||||
import json
|
||||
import time
|
||||
|
||||
from utils.utils import json_serial
|
||||
|
||||
class IPCClient:
|
||||
def __init__(self, port):
|
||||
self.ready = False
|
||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
print("Connecting to the external process...")
|
||||
try:
|
||||
client.connect(('localhost', int(port)))
|
||||
self.client = client
|
||||
print("Connected!")
|
||||
except ConnectionRefusedError:
|
||||
self.client = None
|
||||
print("Connection refused, make sure you started the external process")
|
||||
|
||||
def handle_request(self, message_content):
|
||||
print(f"Received request from the external process: {message_content}")
|
||||
return message_content # For demonstration, we're just echoing back the content
|
||||
|
||||
def listen(self):
|
||||
if self.client is None:
|
||||
print("Not connected to the external process!")
|
||||
return
|
||||
|
||||
while True:
|
||||
data = self.client.recv(4096)
|
||||
message = json.loads(data)
|
||||
|
||||
if message['type'] == 'response':
|
||||
# self.client.close()
|
||||
return message['content']
|
||||
|
||||
def send(self, data):
|
||||
serialized_data = json.dumps(data, default=json_serial)
|
||||
print(serialized_data, type='local')
|
||||
|
||||
data_length = len(serialized_data)
|
||||
self.client.sendall(data_length.to_bytes(4, byteorder='big'))
|
||||
self.client.sendall(serialized_data.encode('utf-8'))
|
||||
time.sleep(0.1)
|
||||
@@ -1,9 +1,15 @@
|
||||
# main.py
|
||||
from __future__ import print_function, unicode_literals
|
||||
import builtins
|
||||
import json
|
||||
|
||||
import sys
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from helpers.ipc import IPCClient
|
||||
from const.ipc import MESSAGE_TYPE
|
||||
from utils.utils import json_serial
|
||||
load_dotenv()
|
||||
|
||||
from helpers.Project import Project
|
||||
@@ -11,8 +17,7 @@ from helpers.Project import Project
|
||||
from utils.arguments import get_arguments
|
||||
from utils.exit import exit_gpt_pilot
|
||||
from logger.logger import logger
|
||||
from database.database import database_exists, create_database, tables_exist, create_tables
|
||||
|
||||
from database.database import database_exists, create_database, tables_exist, create_tables, get_created_apps_with_steps
|
||||
|
||||
def init():
|
||||
# Check if the "euclid" database exists, if not, create it
|
||||
@@ -30,11 +35,54 @@ def init():
|
||||
return arguments
|
||||
|
||||
|
||||
|
||||
|
||||
def get_custom_print(args):
|
||||
built_in_print = builtins.print
|
||||
|
||||
def print_to_external_process(*args, **kwargs):
|
||||
# message = " ".join(map(str, args))
|
||||
message = args[0]
|
||||
|
||||
if 'type' not in kwargs:
|
||||
kwargs['type'] = 'verbose'
|
||||
elif kwargs['type'] == MESSAGE_TYPE['local']:
|
||||
local_print(*args, **kwargs)
|
||||
return
|
||||
|
||||
ipc_client_instance.send({
|
||||
'type': MESSAGE_TYPE[kwargs['type']],
|
||||
'content': message,
|
||||
})
|
||||
if kwargs['type'] == MESSAGE_TYPE['user_input_request']:
|
||||
return ipc_client_instance.listen()
|
||||
|
||||
def local_print(*args, **kwargs):
|
||||
message = " ".join(map(str, args))
|
||||
if 'type' in kwargs:
|
||||
if kwargs['type'] == MESSAGE_TYPE['info']:
|
||||
return
|
||||
del kwargs['type']
|
||||
|
||||
built_in_print(message, **kwargs)
|
||||
|
||||
ipc_client_instance = None
|
||||
if '--external-log-process-port' in args:
|
||||
ipc_client_instance = IPCClient(args['--external-log-process-port'])
|
||||
return print_to_external_process, ipc_client_instance
|
||||
else:
|
||||
return local_print, ipc_client_instance
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
args = init()
|
||||
project = Project(args)
|
||||
project.start()
|
||||
builtins.print, ipc_client_instance = get_custom_print(args)
|
||||
if '--get-created-apps-with-steps' in args:
|
||||
print({ 'db_data': get_created_apps_with_steps() }, type='info')
|
||||
else:
|
||||
# TODO get checkpoint from database and fill the project with it
|
||||
project = Project(args, ipc_client_instance=ipc_client_instance)
|
||||
project.start()
|
||||
except KeyboardInterrupt:
|
||||
exit_gpt_pilot()
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# prompts/prompts.py
|
||||
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow
|
||||
import questionary
|
||||
|
||||
from const import common
|
||||
@@ -102,14 +102,13 @@ def get_additional_info_from_user(project, messages, role):
|
||||
while True:
|
||||
if isinstance(message, dict) and 'text' in message:
|
||||
message = message['text']
|
||||
print(colored(
|
||||
f"Please check this message and say what needs to be changed. If everything is ok just press ENTER",
|
||||
"yellow"))
|
||||
print(yellow(f"Please check this message and say what needs to be changed. If everything is ok just press ENTER",))
|
||||
answer = ask_user(project, message, False)
|
||||
if answer.lower() == '':
|
||||
break
|
||||
response = create_gpt_chat_completion(
|
||||
generate_messages_from_custom_conversation(role, [get_prompt('utils/update.prompt'), message, answer], 'user'), 'additional_info')
|
||||
generate_messages_from_custom_conversation(role, [get_prompt('utils/update.prompt'), message, answer], 'user'),
|
||||
'additional_info')
|
||||
|
||||
message = response
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from termcolor import colored
|
||||
|
||||
from database.database import get_app
|
||||
|
||||
|
||||
@@ -49,8 +47,4 @@ def get_arguments():
|
||||
if 'step' not in arguments:
|
||||
arguments['step'] = None
|
||||
|
||||
print(colored('\n------------------ STARTING NEW PROJECT ----------------------', 'green', attrs=['bold']))
|
||||
print(f"If you wish to continue with this project in future run:")
|
||||
print(colored(f'python main.py app_id={arguments["app_id"]}', 'green', attrs=['bold']))
|
||||
print(colored('--------------------------------------------------------------\n', 'green', attrs=['bold']))
|
||||
return arguments
|
||||
|
||||
@@ -10,16 +10,12 @@ 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 termcolor import colored
|
||||
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
|
||||
|
||||
|
||||
def connect_to_llm():
|
||||
pass
|
||||
|
||||
|
||||
def get_prompt(prompt_name, data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
@@ -78,8 +74,6 @@ def num_tokens_from_functions(functions, model=model):
|
||||
for o in v['enum']:
|
||||
function_tokens += 3
|
||||
function_tokens += len(encoding.encode(o))
|
||||
# else:
|
||||
# print(f"Warning: not supported field {field}")
|
||||
function_tokens += 11
|
||||
|
||||
num_tokens += function_tokens
|
||||
@@ -89,7 +83,8 @@ def num_tokens_from_functions(functions, model=model):
|
||||
|
||||
|
||||
def create_gpt_chat_completion(messages: List[dict], req_type, min_tokens=MIN_TOKENS_FOR_GPT_RESPONSE,
|
||||
function_calls=None):
|
||||
function_calls=None):
|
||||
|
||||
tokens_in_messages = round(get_tokens_in_messages(messages) * 1.2) # add 20% to account for not 100% accuracy
|
||||
if function_calls is not None:
|
||||
tokens_in_messages += round(
|
||||
@@ -173,7 +168,8 @@ def retry_on_exception(func):
|
||||
|
||||
@retry_on_exception
|
||||
def stream_gpt_completion(data, req_type):
|
||||
terminal_width = os.get_terminal_size().columns
|
||||
# TODO add type dynamically - this isn't working when connected to the external process
|
||||
terminal_width = 50#os.get_terminal_size().columns
|
||||
lines_printed = 2
|
||||
buffer = "" # A buffer to accumulate incoming data
|
||||
|
||||
@@ -187,6 +183,7 @@ def stream_gpt_completion(data, req_type):
|
||||
|
||||
# spinner = spinner_start(colored("Waiting for OpenAI API response...", 'yellow'))
|
||||
# print(colored("Stream response from OpenAI:", 'yellow'))
|
||||
api_key = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
logger.info(f'Request data: {data}')
|
||||
|
||||
@@ -217,6 +214,7 @@ def stream_gpt_completion(data, req_type):
|
||||
gpt_response = ''
|
||||
function_calls = {'name': '', 'arguments': ''}
|
||||
|
||||
|
||||
for line in response.iter_lines():
|
||||
# Ignore keep-alive new lines
|
||||
if line:
|
||||
@@ -252,7 +250,7 @@ def stream_gpt_completion(data, req_type):
|
||||
|
||||
if 'arguments' in json_line['function_call']:
|
||||
function_calls['arguments'] += json_line['function_call']['arguments']
|
||||
print(json_line['function_call']['arguments'], end='', flush=True)
|
||||
print(json_line['function_call']['arguments'], type='stream', end='', flush=True)
|
||||
|
||||
if 'content' in json_line:
|
||||
content = json_line.get('content')
|
||||
@@ -265,9 +263,9 @@ def stream_gpt_completion(data, req_type):
|
||||
buffer = "" # reset the buffer
|
||||
|
||||
gpt_response += content
|
||||
print(content, end='', flush=True)
|
||||
print(content, type='stream', end='', flush=True)
|
||||
|
||||
print('\n')
|
||||
print('\n', type='stream')
|
||||
if function_calls['arguments'] != '':
|
||||
logger.info(f'Response via function call: {function_calls["arguments"]}')
|
||||
function_calls['arguments'] = load_data_to_json(function_calls['arguments'])
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from prompt_toolkit.styles import Style
|
||||
import questionary
|
||||
from termcolor import colored
|
||||
from fabulous.color import yellow, bold
|
||||
|
||||
from database.database import save_user_input, get_user_input_from_hash_id
|
||||
from const.ipc import MESSAGE_TYPE
|
||||
|
||||
custom_style = Style.from_dict({
|
||||
'question': '#FFFFFF bold', # the color and style of the question
|
||||
@@ -25,14 +26,19 @@ 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(colored(f'Restoring user input id {user_input.id}: ', 'yellow'), end='')
|
||||
print(colored(f'{user_input.user_input}', 'yellow', attrs=['bold']))
|
||||
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
|
||||
|
||||
config = {
|
||||
'style': custom_style,
|
||||
}
|
||||
response = questionary.text(question, **config).unsafe_ask() # .ask() is included here
|
||||
if project.ipc_client_instance is None or project.ipc_client_instance.client is None:
|
||||
config = {
|
||||
'style': custom_style,
|
||||
}
|
||||
response = questionary.text(question, **config).unsafe_ask() # .ask() is included here
|
||||
else:
|
||||
response = print(question, type='user_input_request')
|
||||
print(response)
|
||||
|
||||
if not ignore_user_input_count:
|
||||
user_input = save_user_input(project, question, response)
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
# utils/utils.py
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import platform
|
||||
import uuid
|
||||
import distro
|
||||
import json
|
||||
import hashlib
|
||||
import re
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from termcolor import colored
|
||||
from fabulous.color import green
|
||||
|
||||
from const.llm import MAX_QUESTIONS, END_RESPONSE
|
||||
from const.common import ROLES, STEPS
|
||||
@@ -119,7 +121,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(colored(message, "green"))
|
||||
print(green(message))
|
||||
logger.info(message)
|
||||
|
||||
|
||||
@@ -171,3 +173,12 @@ def clean_filename(filename):
|
||||
cleaned_filename = re.sub(r'\s', '_', cleaned_filename)
|
||||
|
||||
return cleaned_filename
|
||||
|
||||
def json_serial(obj):
|
||||
"""JSON serializer for objects not serializable by default json code"""
|
||||
if isinstance(obj, (datetime.datetime, datetime.date)):
|
||||
return obj.isoformat()
|
||||
elif isinstance(obj, uuid.UUID):
|
||||
return str(obj)
|
||||
else:
|
||||
return str(obj)
|
||||
Reference in New Issue
Block a user