diff --git a/docs/source/users/index.md b/docs/source/users/index.md index 2906fc074..898b6047b 100644 --- a/docs/source/users/index.md +++ b/docs/source/users/index.md @@ -471,6 +471,10 @@ use the `-a` or `--all-files` option. /learn -r arxiv 2404.18558 ``` +### Exporting chat history +Use the `/export` command to export the chat history from the current session to a markdown file named `chat_history-YYYY-MM-DD-HH-mm.md`. Using `/export ` will export the chat history to `-YYYY-MM-DD-HH-mm.md` instead. You can export chat history as many times as you like in a single session. Each successive export will include the entire chat history up to that point in the session. + + ### Additional chat commands To clear the chat panel, use the `/clear` command. This does not reset the AI model; the model may still remember previous messages that you sent it, and it may use them to inform its responses. diff --git a/packages/jupyter-ai/jupyter_ai/chat_handlers/export.py b/packages/jupyter-ai/jupyter_ai/chat_handlers/export.py index fc4fbad6f..54b81c5ef 100644 --- a/packages/jupyter-ai/jupyter_ai/chat_handlers/export.py +++ b/packages/jupyter-ai/jupyter_ai/chat_handlers/export.py @@ -1,4 +1,6 @@ +import argparse import os +from datetime import datetime from typing import List from jupyter_ai.models import AgentChatMessage, HumanChatMessage @@ -9,13 +11,15 @@ class ExportChatHandler(BaseChatHandler): id = "export" name = "Export chat messages" - help = "Export the chat messages in markdown format" + help = "Export the chat messages in markdown format with timestamps" routing_type = SlashCommandRoutingType(slash_id="export") uses_llm = False def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.parser.prog = "/export" + self.parser.add_argument("path", nargs=argparse.REMAINDER) def chat_message_to_markdown(self, message): if isinstance(message, AgentChatMessage): @@ -25,22 +29,15 @@ def chat_message_to_markdown(self, message): else: return "" - # Multiple chat histories in separate files - def get_chat_filename(self, path="./chat_history.md"): - filename, extension = os.path.splitext(path) - counter = 1 - while os.path.exists(path): - path = filename + "_" + str(counter) + ".md" - counter += 1 - return path - - async def process_message(self, _): + # Write the chat history to a markdown file with a timestamp + async def process_message(self, message: HumanChatMessage): markdown_content = "\n\n".join( self.chat_message_to_markdown(msg) for msg in self._chat_history ) - # Write the markdown content to a file or do whatever you want with it - chat_filename = self.get_chat_filename() - with open(chat_filename, "w") as chat_history: + args = self.parse_args(message) + chat_filename = args.path[0] if args.path else "chat_history" + chat_filename = f"{chat_filename}-{datetime.now():%Y-%m-%d-%H-%M}.md" + chat_file = os.path.join(self.root_dir, chat_filename) + with open(chat_file, "w") as chat_history: chat_history.write(markdown_content) - - self.reply(f"File saved to `{chat_filename}`") + self.reply(f"File saved to `{chat_file}`")