diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..f1d12eb --- /dev/null +++ b/.flake8 @@ -0,0 +1,6 @@ +[flake8] +exclude = .git,__pycache__,.venv +per-file-ignores = __init__.py:F401 +max-line-length = 140 +max-complexity = 10 +select = B,C,E,F,W,T4,B9 diff --git a/README.md b/README.md index 5c6923f..13142a8 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,18 @@ You can install these requirements using `pip`: pip install -r requirements.txt ``` +## Installation + +You can install the package with the requirements using `pip`: + +``` +pip install . +``` + ## Usage ``` -python main.py [-h] [-p PRINT | -q QUESTION | -D | -d] [-c CONFIG] [-m MAX_TOKENS] [-T TEMPERATURE] [-M MODEL] [-n NUMBER] [-t [TAGS [TAGS ...]]] [-e [EXTAGS [EXTAGS ...]]] [-o [OTAGS [OTAGS ...]]] +cmm [-h] [-p PRINT | -q QUESTION | -D | -d] [-c CONFIG] [-m MAX_TOKENS] [-T TEMPERATURE] [-M MODEL] [-n NUMBER] [-t [TAGS [TAGS ...]]] [-e [EXTAGS [EXTAGS ...]]] [-o [OTAGS [OTAGS ...]]] ``` ### Arguments @@ -43,37 +51,37 @@ python main.py [-h] [-p PRINT | -q QUESTION | -D | -d] [-c CONFIG] [-m MAX_TOKEN 1. Print the contents of a YAML file: ``` -python main.py -p example.yaml +cmm -p example.yaml ``` 2. Ask a question: ``` -python main.py -q "What is the meaning of life?" -t philosophy -e religion +cmm -q "What is the meaning of life?" -t philosophy -e religion ``` 3. Display the chat history as a Python structure: ``` -python main.py -D +cmm -D ``` 4. Display the chat history as readable text: ``` -python main.py -d +cmm -d ``` 5. Filter chat history by tags: ``` -python main.py -d -t tag1 tag2 +cmm -d -t tag1 tag2 ``` 6. Exclude chat history by tags: ``` -python main.py -d -e tag3 tag4 +cmm -d -e tag3 tag4 ``` ## Configuration @@ -96,7 +104,7 @@ The configuration file (`.config.yaml`) should contain the following fields: To activate autocompletion for tags, add the following line to your shell's configuration file (e.g., `.bashrc`, `.zshrc`, or `.profile`): ``` -eval "$(register-python-argcomplete chatmastermind)" +eval "$(register-python-argcomplete cmm)" ``` After adding this line, restart your shell or run `source ` to enable autocompletion for the `chatmastermind` script. diff --git a/chatmastermind/main.py b/chatmastermind/main.py index e0524f1..33b1114 100755 --- a/chatmastermind/main.py +++ b/chatmastermind/main.py @@ -3,7 +3,6 @@ # vim: set fileencoding=utf-8 : import yaml -import os import io import sys import shutil @@ -155,16 +154,48 @@ def save_answers(question: str, default_flow_style=False) -def main(args: argparse.Namespace) -> int: +def create_parser() -> argparse.ArgumentParser: + default_config = '.config.yaml' + parser = argparse.ArgumentParser( + description="ChatMastermind is a Python application that automates conversation with AI") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-p', '--print', help='YAML file to print') + group.add_argument('-q', '--question', help='Question to ask') + group.add_argument('-D', '--chat-dump', help="Print chat as Python structure", action='store_true') + group.add_argument('-d', '--chat', help="Print chat as readable text", action='store_true') + parser.add_argument('-c', '--config', help='Config file name.', default=default_config) + parser.add_argument('-m', '--max-tokens', help='Max tokens to use', type=int) + parser.add_argument('-T', '--temperature', help='Temperature to use', type=float) + parser.add_argument('-M', '--model', help='Model to use') + parser.add_argument('-n', '--number', help='Number of answers to produce', type=int, default=3) + tags_arg = parser.add_argument('-t', '--tags', nargs='*', help='List of tag names', metavar='TAGS') + tags_arg.completer = tags_completer # type: ignore + extags_arg = parser.add_argument('-e', '--extags', nargs='*', help='List of tag names to exclude', metavar='EXTAGS') + extags_arg.completer = tags_completer # type: ignore + otags_arg = parser.add_argument('-o', '--output-tags', nargs='*', help='List of output tag names, default is input', metavar='OTAGS') + otags_arg.completer = tags_completer # type: ignore + argcomplete.autocomplete(parser) + return parser + + +def main() -> int: + parser = create_parser() + args = parser.parse_args() + with open(args.config, 'r') as f: config = yaml.load(f, Loader=yaml.FullLoader) + openai.api_key = config['openai']['api_key'] + if args.max_tokens: config['openai']['max_tokens'] = args.max_tokens + if args.temperature: config['openai']['temperature'] = args.temperature + if args.model: config['openai']['model'] = args.model + if args.print: run_print_command(args, config) elif args.question: @@ -173,6 +204,7 @@ def main(args: argparse.Namespace) -> int: process_and_display_chat(args, config, dump=True) elif args.chat: process_and_display_chat(args, config) + return 0 @@ -194,52 +226,4 @@ def tags_completer(prefix, parsed_args, **kwargs): if __name__ == '__main__': - args_parser = argparse.ArgumentParser(description="Handle chats") - default_config = '.config.yaml' - group = args_parser.add_mutually_exclusive_group(required=True) - group.add_argument('-p', '--print', - help='YAML file to print') - group.add_argument('-q', '--question', - help='Question to ask') - group.add_argument('-D', '--chat-dump', - help="Print chat as Python structure", - action='store_true') - group.add_argument('-d', '--chat', - help="Print chat as readable text", - action='store_true') - args_parser.add_argument('-c', '--config', - help='Config file name.', - default=default_config) - args_parser.add_argument('-m', '--max-tokens', - help='Max tokens to use', - type=int) - args_parser.add_argument('-T', '--temperature', - help='Temperature to use', - type=float) - args_parser.add_argument('-M', '--model', - help='Model to use') - args_parser.add_argument('-n', '--number', - help='Number of answers to produce', - type=int, - default=3) - tags_arg = args_parser.add_argument( - '-t', '--tags', - nargs='*', - help='List of tag names', - metavar='TAGS') - tags_arg.completer = tags_completer # type: ignore - extags_arg = args_parser.add_argument( - '-e', '--extags', - nargs='*', - help='List of tag names to exclude', - metavar='EXTAGS') - extags_arg.completer = tags_completer # type: ignore - otags_arg = args_parser.add_argument( - '-o', '--output-tags', - nargs='*', - help='List of output tag names, default is input', - metavar='OTAGS') - otags_arg.completer = tags_completer # type: ignore - argcomplete.autocomplete(args_parser) - args = args_parser.parse_args() - sys.exit(main(args)) + sys.exit(main()) diff --git a/db/004_readme.yaml b/db/004_readme.yaml index 3e7e037..7e8d9c5 100644 --- a/db/004_readme.yaml +++ b/db/004_readme.yaml @@ -26,7 +26,7 @@ answer: |- ## Usage ``` - python main.py [-h] [-p PRINT | -q QUESTION | -D | -d] [-c CONFIG] [-m MAX_TOKENS] [-T TEMPERATURE] [-M MODEL] [-n NUMBER] [-t [TAGS [TAGS ...]]] [-e [EXTAGS [EXTAGS ...]]] [-o [OTAGS [OTAGS ...]]] + cmm [-h] [-p PRINT | -q QUESTION | -D | -d] [-c CONFIG] [-m MAX_TOKENS] [-T TEMPERATURE] [-M MODEL] [-n NUMBER] [-t [TAGS [TAGS ...]]] [-e [EXTAGS [EXTAGS ...]]] [-o [OTAGS [OTAGS ...]]] ``` ### Arguments @@ -49,37 +49,37 @@ answer: |- 1. Print the contents of a YAML file: ``` - python main.py -p example.yaml + cmm -p example.yaml ``` 2. Ask a question: ``` - python main.py -q "What is the meaning of life?" -t philosophy -e religion + cmm -q "What is the meaning of life?" -t philosophy -e religion ``` 3. Display the chat history as a Python structure: ``` - python main.py -D + cmm -D ``` 4. Display the chat history as readable text: ``` - python main.py -d + cmm -d ``` 5. Filter chat history by tags: ``` - python main.py -d -t tag1 tag2 + cmm -d -t tag1 tag2 ``` 6. Exclude chat history by tags: ``` - python main.py -d -e tag3 tag4 + cmm -d -e tag3 tag4 ``` ## Configuration diff --git a/setup.py b/setup.py index 8353263..252f277 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( test_suite="tests", entry_points={ "console_scripts": [ - "chatmastermind=chatmastermind.main:main", + "cmm=chatmastermind.main:main", ], }, )