mirror of
https://github.com/Pythagora-io/gpt-pilot.git
synced 2026-01-10 13:37:55 -05:00
gpt-4 recommended renaming process_name as command_id and changing format in prompt
This commit is contained in:
@@ -44,7 +44,7 @@ def command_definition(description_command='A single command that needs to be ex
|
||||
description_timeout=
|
||||
'Timeout in milliseconds that represent the approximate time this command takes to finish. '
|
||||
'If you need to run a command that doesnt\'t finish by itself (eg. a command to run an app), '
|
||||
'set the timeout to to a value long enough to determine that it has started successfully and provide a process_name. '
|
||||
'set the timeout to to a value long enough to determine that it has started successfully and provide a command_id. '
|
||||
'If you need to create a directory that doesn\'t exist and is not the root project directory, '
|
||||
'always create it by running a command `mkdir`'):
|
||||
return {
|
||||
@@ -63,10 +63,10 @@ def command_definition(description_command='A single command that needs to be ex
|
||||
'type': 'string',
|
||||
'description': 'A message to look for in the output of the command to determine if successful or not.',
|
||||
},
|
||||
'process_name': {
|
||||
'command_id': {
|
||||
'type': 'string',
|
||||
'description': 'If the process needs to continue running after the command is executed provide '
|
||||
'a name which you can use to kill the process later.',
|
||||
'a unique command identifier which you can use to kill the process later.',
|
||||
}
|
||||
},
|
||||
'required': ['command', 'timeout'],
|
||||
@@ -193,7 +193,7 @@ IMPLEMENT_TASK = {
|
||||
'command': command_definition(),
|
||||
'kill_process': {
|
||||
'type': 'string',
|
||||
'description': 'To kill a process that was left running by a previous `command` step provide the `process_name` in this field and set `type` to "kill_process".',
|
||||
'description': 'To kill a process that was left running by a previous `command` step provide the `command_id` in this field and set `type` to "kill_process".',
|
||||
},
|
||||
'code_change': {
|
||||
'type': 'object',
|
||||
|
||||
@@ -103,12 +103,12 @@ class Developer(Agent):
|
||||
# TODO END
|
||||
additional_message = 'Let\'s start with the step #0:\n\n' if i == 0 else f'So far, steps { ", ".join(f"#{j}" for j in range(i)) } are finished so let\'s do step #{i + 1} now.\n\n'
|
||||
|
||||
process_name = data['process_name'] if 'process_name' in data else None
|
||||
command_id = data['command_id'] if 'command_id' in data else None
|
||||
success_message = data['success_message'] if 'success_message' in data else None
|
||||
|
||||
return run_command_until_success(convo, data['command'],
|
||||
timeout=data['timeout'],
|
||||
process_name=process_name,
|
||||
command_id=command_id,
|
||||
success_message=success_message,
|
||||
additional_message=additional_message)
|
||||
|
||||
@@ -136,7 +136,7 @@ class Developer(Agent):
|
||||
cbs={
|
||||
'r': lambda conv: run_command_until_success(conv,
|
||||
self.run_command,
|
||||
process_name='app',
|
||||
command_id='app',
|
||||
timeout=None,
|
||||
force=True,
|
||||
return_cli_response=True)
|
||||
@@ -328,7 +328,7 @@ class Developer(Agent):
|
||||
response = self.project.ask_for_human_intervention(
|
||||
user_description,
|
||||
cbs={'r': lambda convo: run_command_until_success(convo, self.run_command,
|
||||
process_name='app',
|
||||
command_id='app',
|
||||
timeout=None,
|
||||
force=True,
|
||||
return_cli_response=True, is_root_task=True)},
|
||||
|
||||
@@ -18,7 +18,7 @@ from const.code_execution import MIN_COMMAND_RUN_TIME, MAX_COMMAND_RUN_TIME, MAX
|
||||
interrupted = False
|
||||
|
||||
running_processes: Dict[str, tuple[str, int]] = {}
|
||||
"""Holds a list of (command, process ID)s, mapped to the `process_name` provided in the call to `execute_command()`."""
|
||||
"""Holds a list of (command, process ID)s, mapped to the `command_id` provided in the call to `execute_command()`."""
|
||||
|
||||
|
||||
def enqueue_output(out, q):
|
||||
@@ -72,14 +72,14 @@ def run_command(command, root_path, q_stdout, q_stderr) -> subprocess.Popen:
|
||||
return process
|
||||
|
||||
|
||||
def terminate_named_process(process_name: str) -> None:
|
||||
if process_name in running_processes:
|
||||
terminate_process(running_processes[process_name][1], process_name)
|
||||
def terminate_named_process(command_id: str) -> None:
|
||||
if command_id in running_processes:
|
||||
terminate_process(running_processes[command_id][1], command_id)
|
||||
|
||||
|
||||
def terminate_running_processes():
|
||||
for process_name in list(running_processes.keys()):
|
||||
terminate_process(running_processes[process_name][1], process_name)
|
||||
for command_id in list(running_processes.keys()):
|
||||
terminate_process(running_processes[command_id][1], command_id)
|
||||
|
||||
|
||||
def terminate_process(pid: int, name=None) -> None:
|
||||
@@ -99,12 +99,12 @@ def terminate_process(pid: int, name=None) -> None:
|
||||
except OSError as e:
|
||||
logger.error(f'Error while terminating process: {e}')
|
||||
|
||||
for process_name in list(running_processes.keys()):
|
||||
if running_processes[process_name][1] == pid:
|
||||
del running_processes[process_name]
|
||||
for command_id in list(running_processes.keys()):
|
||||
if running_processes[command_id][1] == pid:
|
||||
del running_processes[command_id]
|
||||
|
||||
|
||||
def execute_command(project, command, timeout=None, success_message=None, process_name: str = None, force=False) \
|
||||
def execute_command(project, command, timeout=None, success_message=None, command_id: str = None, force=False) \
|
||||
-> (str, str, int):
|
||||
"""
|
||||
Execute a command and capture its output.
|
||||
@@ -114,8 +114,7 @@ def execute_command(project, command, timeout=None, success_message=None, proces
|
||||
command (str): The command to run.
|
||||
timeout (int, optional): The maximum execution time in milliseconds. Default is None.
|
||||
success_message: A message to look for in the output of the command to determine if successful or not.
|
||||
process_name (str, optional): A name for the process.
|
||||
If `timeout` is not provided, can be used to terminate the process.
|
||||
command_id (str, optional): A unique identifier assigned by the LLM, can be used to terminate the process.
|
||||
force (bool, optional): Whether to execute the command without confirmation. Default is False.
|
||||
|
||||
Returns:
|
||||
@@ -178,9 +177,9 @@ def execute_command(project, command, timeout=None, success_message=None, proces
|
||||
q = queue.Queue()
|
||||
process = run_command(command, project.root_path, q, q_stderr)
|
||||
|
||||
if process_name is not None:
|
||||
terminate_named_process(process_name)
|
||||
running_processes[process_name] = (command, process.pid)
|
||||
if command_id is not None:
|
||||
terminate_named_process(command_id)
|
||||
running_processes[command_id] = (command, process.pid)
|
||||
|
||||
output = ''
|
||||
stderr_output = ''
|
||||
@@ -213,8 +212,8 @@ def execute_command(project, command, timeout=None, success_message=None, proces
|
||||
|
||||
# If timeout is reached, kill the process
|
||||
if timeout is not None and elapsed_time * 1000 > timeout:
|
||||
if process_name is not None:
|
||||
logger.info(f'Process "{process_name}" running after timeout as pid: {process.pid}')
|
||||
if command_id is not None:
|
||||
logger.info(f'Process "{command_id}" running after timeout as pid: {process.pid}')
|
||||
break
|
||||
|
||||
raise TimeoutError("Command exceeded the specified timeout.")
|
||||
@@ -340,7 +339,7 @@ def execute_command_and_check_cli_response(command, timeout, convo):
|
||||
|
||||
def run_command_until_success(convo, command,
|
||||
timeout: Union[int, None],
|
||||
process_name: Union[str, None] = None,
|
||||
command_id: Union[str, None] = None,
|
||||
success_message=None,
|
||||
additional_message=None,
|
||||
force=False,
|
||||
@@ -353,7 +352,7 @@ def run_command_until_success(convo, command,
|
||||
convo (AgentConvo): The conversation object.
|
||||
command (str): The command to run.
|
||||
timeout (int): The maximum execution time in milliseconds.
|
||||
process_name: A name for the process.
|
||||
command_id: A name for the process.
|
||||
If `timeout` is not provided, can be used to terminate the process.
|
||||
success_message: A message to look for in the output of the command to determine if successful or not.
|
||||
additional_message (str, optional): Additional message to include in the response.
|
||||
@@ -365,7 +364,7 @@ def run_command_until_success(convo, command,
|
||||
command,
|
||||
timeout=timeout,
|
||||
success_message=success_message,
|
||||
process_name=process_name,
|
||||
command_id=command_id,
|
||||
force=force)
|
||||
|
||||
if response is None:
|
||||
@@ -398,7 +397,7 @@ def run_command_until_success(convo, command,
|
||||
return convo.agent.debugger.debug(convo, {
|
||||
'command': command,
|
||||
'timeout': timeout,
|
||||
'process_name': process_name,
|
||||
'command_id': command_id,
|
||||
'success_message': success_message,
|
||||
})
|
||||
except TooDeepRecursionError as e:
|
||||
|
||||
@@ -3,10 +3,12 @@ The project directory tree looks like:
|
||||
|
||||
{{ directory_tree }}
|
||||
{% endif -%}
|
||||
{%- if running_processes %}
|
||||
{% if running_processes -%}
|
||||
Note that the following processes are already running:
|
||||
|
||||
{% for key, data in running_processes.items() -%}
|
||||
- "{{ key }}" (`{{ data[0] }}`)
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
{%- for key, data in running_processes.items() %}
|
||||
|
||||
command_id: {{ key }}
|
||||
command: {{ data[0] }}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
Ok, now, take your previous message and convert it to actionable items. An item might be a code change or a command run. When you need to change code, make sure that you put the entire content of the file in the value of `content` key even though you will likely copy and paste the most of the previous message. Note that the commands will run on a {{ os }} machine.
|
||||
{%- if running_processes %}
|
||||
{% if running_processes -%}
|
||||
Note that the following processes are already running:
|
||||
|
||||
{% for key, data in running_processes.items() -%}
|
||||
- "{{ key }}" (`{{ data[0] }}`)
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
{%- for key, data in running_processes.items() %}
|
||||
|
||||
command_id: {{ key }}
|
||||
command: {{ data[0] }}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
|
||||
@@ -66,4 +66,4 @@ def test_parse_task_with_processes():
|
||||
|
||||
# Then
|
||||
assert 'the following processes are already running:' in prompt
|
||||
assert '- "app" (`npm start`)\n- "mongo" (`mongod`)' in prompt
|
||||
assert 'command_id: app\ncommand: npm start\n\ncommand_id: mongo\ncommand: mongod' in prompt
|
||||
|
||||
Reference in New Issue
Block a user