diff --git a/chatmastermind/commands/question.py b/chatmastermind/commands/question.py index faba681..c380016 100644 --- a/chatmastermind/commands/question.py +++ b/chatmastermind/commands/question.py @@ -1,3 +1,4 @@ +import sys import argparse from pathlib import Path from itertools import zip_longest @@ -51,7 +52,7 @@ def add_file_as_code(question_parts: list[str], file: str) -> None: def create_message(chat: ChatDB, args: argparse.Namespace) -> Message: """ - Creates a new message from the given arguments and writes it + Create a new message from the given arguments and write it to the cache directory. """ question_parts = [] @@ -73,10 +74,37 @@ def create_message(chat: ChatDB, args: argparse.Namespace) -> Message: tags=args.output_tags, # FIXME ai=args.AI, model=args.model) - chat.cache_add([message]) + # only write the new message to the cache, + # don't add it to the internal list + chat.cache_write([message]) return message +def make_request(ai: AI, chat: ChatDB, message: Message, args: argparse.Namespace) -> None: + """ + Make an AI request with the given AI, chat history, message and arguments. + Write the response(s) to the cache directory, without appending it to the + given chat history. Then print the response(s). + """ + # print history and message question before making the request + ai.print() + chat.print(paged=False) + print(message.to_str()) + response: AIResponse = ai.request(message, + chat, + args.num_answers, # FIXME + args.output_tags) # FIXME + # only write the response messages to the cache, + # don't add them to the internal list + chat.cache_write(response.messages) + for idx, msg in enumerate(response.messages): + print(f"=== ANSWER {idx+1} ===") + print(msg.answer) + if response.tokens: + print("===============") + print(response.tokens) + + def question_cmd(args: argparse.Namespace, config: Config) -> None: """ Handler for the 'question' command. @@ -95,28 +123,29 @@ def question_cmd(args: argparse.Namespace, config: Config) -> None: # create the correct AI instance ai: AI = create_ai(args, config) + + # === ASK === if args.ask: - ai.print() - chat.print(paged=False) - response: AIResponse = ai.request(message, - chat, - args.num_answers, # FIXME - args.output_tags) # FIXME - chat.msg_update([response.messages[0]]) - chat.cache_add(response.messages[1:]) - for idx, msg in enumerate(response.messages): - print(f"=== ANSWER {idx+1} ===") - print(msg.answer) - if response.tokens: - print("===============") - print(response.tokens) + make_request(ai, chat, message, args) + # === REPEAT === elif args.repeat is not None: - lmessage = chat.msg_latest() - assert lmessage - # TODO: repeat either the last question or the - # one(s) given in 'args.repeat' (overwrite - # existing ones if 'args.overwrite' is True) - pass + lmessage = chat.msg_latest(loc='cache') + if lmessage is None: + print("No message found to repeat!") + sys.exit(1) + else: + print(f"Repeating message '{lmessage.msg_id()}':") + # overwrite the latest message if requested or empty + if lmessage.answer is None or args.overwrite is True: + lmessage.clear_answer() + make_request(ai, chat, lmessage, args) + # otherwise create a new one + else: + args.ask = [lmessage.question] + message = create_message(chat, args) + make_request(ai, chat, message, args) + + # === PROCESS === elif args.process is not None: # TODO: process either all questions without an # answer or the one(s) given in 'args.process' diff --git a/chatmastermind/message.py b/chatmastermind/message.py index 498de88..c9e1525 100644 --- a/chatmastermind/message.py +++ b/chatmastermind/message.py @@ -540,6 +540,9 @@ class Message(): if self.tags: self.tags = rename_tags(self.tags, tags_rename) + def clear_answer(self) -> None: + self.answer = None + def msg_id(self) -> str: """ Returns an ID that is unique throughout all messages in the same (DB) directory.