singlewholefile-func

This commit is contained in:
Paul Gauthier 2023-06-29 18:13:42 -07:00
parent 271807123a
commit ddac41f106
4 changed files with 158 additions and 1 deletions

View file

@ -1,7 +1,15 @@
from .base_coder import Coder from .base_coder import Coder
from .editblock_coder import EditBlockCoder from .editblock_coder import EditBlockCoder
from .editblock_func_coder import EditBlockFunctionCoder from .editblock_func_coder import EditBlockFunctionCoder
from .single_wholefile_func_coder import SingleWholeFileFunctionCoder
from .wholefile_coder import WholeFileCoder from .wholefile_coder import WholeFileCoder
from .wholefile_func_coder import WholeFileFunctionCoder from .wholefile_func_coder import WholeFileFunctionCoder
__all__ = [Coder, EditBlockCoder, WholeFileCoder, WholeFileFunctionCoder, EditBlockFunctionCoder] __all__ = [
Coder,
EditBlockCoder,
WholeFileCoder,
WholeFileFunctionCoder,
EditBlockFunctionCoder,
SingleWholeFileFunctionCoder,
]

View file

@ -59,6 +59,7 @@ class Coder:
from . import ( from . import (
EditBlockCoder, EditBlockCoder,
EditBlockFunctionCoder, EditBlockFunctionCoder,
SingleWholeFileFunctionCoder,
WholeFileCoder, WholeFileCoder,
WholeFileFunctionCoder, WholeFileFunctionCoder,
) )
@ -87,6 +88,8 @@ class Coder:
return WholeFileCoder(main_model, io, **kwargs) return WholeFileCoder(main_model, io, **kwargs)
elif edit_format == "whole-func": elif edit_format == "whole-func":
return WholeFileFunctionCoder(main_model, io, **kwargs) return WholeFileFunctionCoder(main_model, io, **kwargs)
elif edit_format == "single-whole-func":
return SingleWholeFileFunctionCoder(main_model, io, **kwargs)
elif edit_format == "diff-func": elif edit_format == "diff-func":
return EditBlockFunctionCoder("list", main_model, io, **kwargs) return EditBlockFunctionCoder("list", main_model, io, **kwargs)
elif edit_format == "diff-func-string": elif edit_format == "diff-func-string":

View file

@ -0,0 +1,119 @@
import os
from aider import diffs
from ..dump import dump # noqa: F401
from .base_coder import Coder
from .single_wholefile_func_prompts import SingleWholeFileFunctionPrompts
class SingleWholeFileFunctionCoder(Coder):
functions = [
dict(
name="write_file",
description="write new content into the file",
parameters=dict(
type="object",
required=["explanation", "content"],
properties=dict(
explanation=dict(
type="string",
description=(
"Step by step plan for the changes to be made to the code (future"
" tense, markdown format)"
),
),
content=dict(
type="string",
description="Content to write to the file",
),
),
),
),
]
def __init__(self, *args, **kwargs):
self.gpt_prompts = SingleWholeFileFunctionPrompts()
super().__init__(*args, **kwargs)
def update_cur_messages(self, content, edited):
if edited:
self.cur_messages += [
dict(role="assistant", content=self.gpt_prompts.redacted_edit_message)
]
else:
self.cur_messages += [dict(role="assistant", content=content)]
def get_context_from_history(self, history):
context = ""
if history:
context += "# Context:\n"
for msg in history:
if msg["role"] == "user":
context += msg["role"].upper() + ": " + msg["content"] + "\n"
return context
def render_incremental_response(self, final=False):
if self.partial_response_content:
return self.partial_response_content
args = self.parse_partial_args()
return str(args)
if not args:
return
explanation = args.get("explanation")
files = args.get("files", [])
res = ""
if explanation:
res += f"{explanation}\n\n"
for i, file_upd in enumerate(files):
path = file_upd.get("path")
if not path:
continue
content = file_upd.get("content")
if not content:
continue
this_final = (i < len(files) - 1) or final
res += self.live_diffs(path, content, this_final)
return res
def live_diffs(self, fname, content, final):
lines = content.splitlines(keepends=True)
# ending an existing block
full_path = os.path.abspath(os.path.join(self.root, fname))
with open(full_path, "r") as f:
orig_lines = f.readlines()
show_diff = diffs.diff_partial_update(
orig_lines,
lines,
final,
fname=fname,
).splitlines()
return "\n".join(show_diff)
def update_files(self):
name = self.partial_response_function_call.get("name")
if name and name != "write_file":
raise ValueError(f'Unknown function_call name="{name}", use name="write_file"')
args = self.parse_partial_args()
if not args:
return
content = args["content"]
path = self.get_inchat_relative_files()[0]
if self.allowed_to_edit(path, content):
return set([path])
return set()

View file

@ -0,0 +1,27 @@
# flake8: noqa: E501
from .base_prompts import CoderPrompts
class SingleWholeFileFunctionPrompts(CoderPrompts):
main_system = """Act as an expert software developer.
Take requests for changes to the supplied code.
If the request is ambiguous, ask questions.
Once you understand the request you MUST use the `write_file` function to update the file to make the changes.
"""
system_reminder = """
ONLY return code using the `write_file` function.
NEVER return code outside the `write_file` function.
"""
files_content_prefix = "Here is the current content of the file:\n"
files_no_full_files = "I am not sharing any files yet."
redacted_edit_message = "No changes are needed."
# TODO: should this be present for using this with gpt-4?
repo_content_prefix = None
# TODO: fix the chat history, except we can't keep the whole file