diff --git a/README.md b/README.md index ef7d3c5..3e920cd 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,8 @@ Once you have it all set up, here's how to use it. `fabric -h` ```bash -usage: fabric [-h] [--text TEXT] [--copy] [--agents] [--output [OUTPUT]] [--gui] [--stream] [--list] [--temp TEMP] [--top_p TOP_P] [--frequency_penalty FREQUENCY_PENALTY] +usage: fabric -h +usage: fabric [-h] [--text TEXT] [--copy] [--agents] [--output [OUTPUT]] [--session [SESSION]] [--gui] [--stream] [--list] [--temp TEMP] [--top_p TOP_P] [--frequency_penalty FREQUENCY_PENALTY] [--presence_penalty PRESENCE_PENALTY] [--update] [--pattern PATTERN] [--setup] [--changeDefaultModel CHANGEDEFAULTMODEL] [--model MODEL] [--listmodels] [--remoteOllamaServer REMOTEOLLAMASERVER] [--context] @@ -222,6 +223,8 @@ options: --agents, -a Use praisonAI to create an AI agent and then use it. ex: 'write me a movie script' --output [OUTPUT], -o [OUTPUT] Save the response to a file + --session [SESSION], -S [SESSION] + Continue your previous conversation. Default is your previous conversation --gui Use the GUI (Node and npm need to be installed) --stream, -s Use this option if you want to see the results in realtime. NOTE: You will not be able to pipe the output into another command. --list, -l List available patterns @@ -238,7 +241,7 @@ options: --changeDefaultModel CHANGEDEFAULTMODEL Change the default model. For a list of available models, use the --listmodels flag. --model MODEL, -m MODEL - Select the model to use. NOTE: Will not work if you have set a default model. please use --clear to clear persistence before using this flag + Select the model to use --listmodels List all available models --remoteOllamaServer REMOTEOLLAMASERVER The URL of the remote ollamaserver to use. ONLY USE THIS if you are using a local ollama server in an non-deault location or port diff --git a/analyzepaper.txt b/analyzepaper.txt new file mode 100644 index 0000000..e69de29 diff --git a/installer/client/cli/fabric.py b/installer/client/cli/fabric.py index 97fb1cd..4f49464 100755 --- a/installer/client/cli/fabric.py +++ b/installer/client/cli/fabric.py @@ -28,6 +28,8 @@ def main(): const="analyzepaper.txt", default=None, ) + parser.add_argument('--session', '-S', + help="Continue your previous conversation. Default is your previous conversation", nargs="?", const="default") parser.add_argument( "--gui", help="Use the GUI (Node and npm need to be installed)", action="store_true") parser.add_argument( @@ -57,7 +59,7 @@ def main(): help="Change the default model. For a list of available models, use the --listmodels flag.") parser.add_argument( - "--model", "-m", help="Select the model to use. NOTE: Will not work if you have set a default model. please use --clear to clear persistence before using this flag" + "--model", "-m", help="Select the model to use" ) parser.add_argument( "--listmodels", help="List all available models", action="store_true" @@ -112,6 +114,15 @@ def main(): standalone = Standalone(args) standalone.agents(text) sys.exit() + if args.session: + from .helper import Session + session = Session() + if args.session == "default": + session_file = session.find_most_recent_file() + if session_file is None: + args.session = "default" + else: + args.session = session_file.split("/")[-1] standalone = Standalone(args, args.pattern) if args.list: try: diff --git a/installer/client/cli/helper.py b/installer/client/cli/helper.py new file mode 100644 index 0000000..b746f72 --- /dev/null +++ b/installer/client/cli/helper.py @@ -0,0 +1,46 @@ +import os +import sys + + +class Session: + def __init__(self): + home_folder = os.path.expanduser("~") + config_folder = os.path.join(home_folder, ".config", "fabric") + self.sessions_folder = os.path.join(config_folder, "sessions") + if not os.path.exists(self.sessions_folder): + os.makedirs(self.sessions_folder) + + def find_most_recent_file(self): + # Ensure the directory exists + directory = self.sessions_folder + if not os.path.exists(directory): + print("Directory does not exist:", directory) + return None + + # List all files in the directory + full_path_files = [os.path.join(directory, file) for file in os.listdir( + directory) if os.path.isfile(os.path.join(directory, file))] + + # If no files are found, return None + if not full_path_files: + print("No files found in the directory.") + return None + + # Find the file with the most recent modification time + most_recent_file = max(full_path_files, key=os.path.getmtime) + + return most_recent_file + + def save_to_session(self, system, user, response, fileName): + file = os.path.join(self.sessions_folder, fileName) + with open(file, "a+") as f: + f.write(f"{system}\n") + f.write(f"{user}\n") + f.write(f"{response}\n") + + def read_from_session(self, filename): + file = os.path.join(self.sessions_folder, filename) + if not os.path.exists(file): + return None + with open(file, "r") as f: + return f.read() diff --git a/installer/client/cli/utils.py b/installer/client/cli/utils.py index db7f59a..51bf436 100644 --- a/installer/client/cli/utils.py +++ b/installer/client/cli/utils.py @@ -112,12 +112,18 @@ class Standalone: if self.args.output: with open(self.args.output, "w") as f: f.write(buffer) + if self.args.session: + from .helper import Session + session = Session() + session.save_to_session( + system, user, buffer, self.args.session) message = await stream.get_final_message() async def claudeChat(self, system, user, copy=False): from anthropic import Anthropic self.claudeApiKey = os.environ["CLAUDE_API_KEY"] client = Anthropic(api_key=self.claudeApiKey) + message = None message = client.messages.create( max_tokens=4096, system=system, @@ -132,6 +138,11 @@ class Standalone: if self.args.output: with open(self.args.output, "w") as f: f.write(message.content[0].text) + if self.args.session: + from .helper import Session + session = Session() + session.save_to_session( + system, user, message.content[0].text, self.args.session) def streamMessage(self, input_data: str, context="", host=''): """ Stream a message and handle exceptions. @@ -149,23 +160,38 @@ class Standalone: wisdomFilePath = os.path.join( config_directory, f"patterns/{self.pattern}/system.md" ) + session_message = "" + if self.args.session: + from .helper import Session + session = Session() + session_message = session.read_from_session( + self.args.session) + user = session_message + '\n' + input_data + user = input_data user_message = {"role": "user", "content": f"{input_data}"} wisdom_File = os.path.join(current_directory, wisdomFilePath) - system = "" buffer = "" + system = "" if self.pattern: try: with open(wisdom_File, "r") as f: if context: system = context + '\n\n' + f.read() + if session_message: + system = session_message + '\n' + system else: system = f.read() + if session_message: + system = session_message + '\n' + system system_message = {"role": "system", "content": system} messages = [system_message, user_message] except FileNotFoundError: print("pattern not found") return else: + if session_message: + user_message['content'] = session_message + \ + '\n' + user_message['content'] if context: messages = [ {"role": "system", "content": context}, user_message] @@ -219,6 +245,11 @@ class Standalone: if self.args.output: with open(self.args.output, "w") as f: f.write(buffer) + if self.args.session: + from .helper import Session + session = Session() + session.save_to_session( + system, user, buffer, self.args.session) def sendMessage(self, input_data: str, context="", host=''): """ Send a message using the input data and generate a response. @@ -236,22 +267,38 @@ class Standalone: wisdomFilePath = os.path.join( config_directory, f"patterns/{self.pattern}/system.md" ) + user = input_data user_message = {"role": "user", "content": f"{input_data}"} wisdom_File = os.path.join(current_directory, wisdomFilePath) system = "" + session_message = "" + if self.args.session: + from .helper import Session + session = Session() + session_message = session.read_from_session( + self.args.session) if self.pattern: try: with open(wisdom_File, "r") as f: if context: - system = context + '\n\n' + f.read() + if session_message: + system = session_message + '\n' + context + '\n\n' + f.read() + else: + system = context + '\n\n' + f.read() else: - system = f.read() + if session_message: + system = session_message + '\n' + f.read() + else: + system = f.read() system_message = {"role": "system", "content": system} messages = [system_message, user_message] except FileNotFoundError: print("pattern not found") return else: + if session_message: + user_message['content'] = session_message + \ + '\n' + user_message['content'] if context: messages = [ {'role': 'system', 'content': context}, user_message] @@ -280,6 +327,11 @@ class Standalone: if self.args.output: with open(self.args.output, "w") as f: f.write(response.choices[0].message.content) + if self.args.session: + from .helper import Session + session = Session() + session.save_to_session( + system, user, response.choices[0], self.args.session) except Exception as e: if "All connection attempts failed" in str(e): print(