mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-25 06:44:59 +00:00
Merge pull request #631 from daniel-vainsencher/dvf_llm_log
This commit is contained in:
commit
a596a32290
5 changed files with 52 additions and 12 deletions
|
@ -21,11 +21,17 @@ def get_parser(default_config_files, git_root):
|
|||
auto_env_var_prefix="AIDER_",
|
||||
)
|
||||
group = parser.add_argument_group("Main")
|
||||
group.add_argument(
|
||||
"--llm-history-file",
|
||||
metavar="LLM_HISTORY_FILE",
|
||||
default=None,
|
||||
help="Log the conversation with the LLM to this file (for example, .aider.llm.history)",
|
||||
)
|
||||
group.add_argument(
|
||||
"files",
|
||||
metavar="FILE",
|
||||
nargs="*",
|
||||
help="files to edit with an LLM (optional)",
|
||||
help="files to edit with an LLM (optional)"
|
||||
)
|
||||
group.add_argument(
|
||||
"--openai-api-key",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
|
@ -27,7 +28,7 @@ from aider.mdstream import MarkdownStream
|
|||
from aider.repo import GitRepo
|
||||
from aider.repomap import RepoMap
|
||||
from aider.sendchat import send_with_retries
|
||||
from aider.utils import is_image_file
|
||||
from aider.utils import is_image_file, format_messages, format_content
|
||||
|
||||
from ..dump import dump # noqa: F401
|
||||
|
||||
|
@ -783,6 +784,8 @@ class Coder:
|
|||
|
||||
messages = self.format_messages()
|
||||
|
||||
self.io.log_llm_history("TO LLM", format_messages(messages))
|
||||
|
||||
if self.verbose:
|
||||
utils.show_messages(messages, functions=self.functions)
|
||||
|
||||
|
@ -805,6 +808,9 @@ class Coder:
|
|||
exhausted = True
|
||||
else:
|
||||
raise err
|
||||
except Exception as err:
|
||||
self.io.tool_error(f"Unexpected error: {err}")
|
||||
return
|
||||
|
||||
if exhausted:
|
||||
self.show_exhausted_error()
|
||||
|
@ -824,6 +830,8 @@ class Coder:
|
|||
|
||||
self.io.tool_output()
|
||||
|
||||
self.io.log_llm_history("LLM RESPONSE", format_content("ASSISTANT", content))
|
||||
|
||||
if interrupted:
|
||||
content += "\n^C KeyboardInterrupt"
|
||||
self.cur_messages += [dict(role="assistant", content=content)]
|
||||
|
|
13
aider/io.py
13
aider/io.py
|
@ -107,6 +107,7 @@ class InputOutput:
|
|||
tool_error_color="red",
|
||||
encoding="utf-8",
|
||||
dry_run=False,
|
||||
llm_history_file=None,
|
||||
editingmode=EditingMode.EMACS,
|
||||
):
|
||||
self.editingmode = editingmode
|
||||
|
@ -128,6 +129,7 @@ class InputOutput:
|
|||
self.yes = yes
|
||||
|
||||
self.input_history_file = input_history_file
|
||||
self.llm_history_file = llm_history_file
|
||||
if chat_history_file is not None:
|
||||
self.chat_history_file = Path(chat_history_file)
|
||||
else:
|
||||
|
@ -209,10 +211,11 @@ class InputOutput:
|
|||
else:
|
||||
style = None
|
||||
|
||||
while True:
|
||||
completer_instance = AutoCompleter(
|
||||
root, rel_fnames, addable_rel_fnames, commands, self.encoding
|
||||
)
|
||||
|
||||
while True:
|
||||
if multiline_input:
|
||||
show = ". "
|
||||
|
||||
|
@ -271,6 +274,14 @@ class InputOutput:
|
|||
fh = FileHistory(self.input_history_file)
|
||||
return fh.load_history_strings()
|
||||
|
||||
def log_llm_history(self, role, content):
|
||||
if not self.llm_history_file:
|
||||
return
|
||||
timestamp = datetime.now().isoformat(timespec='seconds')
|
||||
with open(self.llm_history_file, 'a', encoding=self.encoding) as log_file:
|
||||
log_file.write(f"{role.upper()} {timestamp}\n")
|
||||
log_file.write(content + "\n")
|
||||
|
||||
def user_input(self, inp, log_only=True):
|
||||
if not log_only:
|
||||
style = dict(style=self.user_input_color) if self.user_input_color else dict()
|
||||
|
|
|
@ -261,6 +261,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
|
|||
tool_error_color=args.tool_error_color,
|
||||
dry_run=args.dry_run,
|
||||
encoding=args.encoding,
|
||||
llm_history_file=args.llm_history_file,
|
||||
editingmode=editing_mode,
|
||||
)
|
||||
|
||||
|
|
|
@ -84,24 +84,38 @@ def safe_abs_path(res):
|
|||
return str(res)
|
||||
|
||||
|
||||
def show_messages(messages, title=None, functions=None):
|
||||
def format_content(role, content):
|
||||
formatted_lines = []
|
||||
for line in content.splitlines():
|
||||
formatted_lines.append(f"{role} {line}")
|
||||
return "\n".join(formatted_lines)
|
||||
|
||||
|
||||
def format_messages(messages, title=None):
|
||||
output = []
|
||||
if title:
|
||||
print(title.upper(), "*" * 50)
|
||||
output.append(f"{title.upper()} {'*' * 50}")
|
||||
|
||||
for msg in messages:
|
||||
print()
|
||||
output.append("")
|
||||
role = msg["role"].upper()
|
||||
content = msg.get("content")
|
||||
if isinstance(content, list): # Handle list content (e.g., image messages)
|
||||
for item in content:
|
||||
if isinstance(item, dict) and "image_url" in item:
|
||||
print(role, "Image URL:", item["image_url"]["url"])
|
||||
output.append(f"{role} Image URL: {item['image_url']['url']}")
|
||||
elif isinstance(content, str): # Handle string content
|
||||
for line in content.splitlines():
|
||||
print(role, line)
|
||||
output.append(format_content(role, content))
|
||||
content = msg.get("function_call")
|
||||
if content:
|
||||
print(role, content)
|
||||
output.append(f"{role} {content}")
|
||||
|
||||
return "\n".join(output)
|
||||
|
||||
|
||||
def show_messages(messages, title=None, functions=None):
|
||||
formatted_output = format_messages(messages, title)
|
||||
print(formatted_output)
|
||||
|
||||
if functions:
|
||||
dump(functions)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue