Skip to content

Instantly share code, notes, and snippets.

@ZiweiXU
Last active March 3, 2023 13:30
Show Gist options
  • Select an option

  • Save ZiweiXU/336cbd03bc8113f9500da5de3d1b3077 to your computer and use it in GitHub Desktop.

Select an option

Save ZiweiXU/336cbd03bc8113f9500da5de3d1b3077 to your computer and use it in GitHub Desktop.

Revisions

  1. ZiweiXU revised this gist Mar 3, 2023. No changes.
  2. ZiweiXU revised this gist Mar 3, 2023. 1 changed file with 59 additions and 50 deletions.
    109 changes: 59 additions & 50 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -3,11 +3,12 @@
    GPT-3.5 client for Python 3.6+.
    Usage: python gpt.py [command] [options] [text]
    Commands:
    qa - Ask a single question, no context is saved.
    rephrase - Rephrase text with GPT-3.
    another-word - Find another word with GPT-3.
    interactive - Start an interactive chat with GPT-3.
    talk - Alias for interactive.
    another-word Find another word with GPT-3.
    qa Ask a single question then exit.
    q Alias for qa.
    rephrase Rephrase text with GPT-3.
    interactive Start an interactive chat with GPT-3.
    talk Alias for interactive.
    Options:
    -h, --help - Print help message.
    Examples:
    @@ -17,13 +18,13 @@
    python gpt.py interactive
    python gpt.py talk
    Commands for an interactive session:
    !help: Print this help message.
    !quit: Exit the program.
    !usage: Print the total usage in this session.
    !clear: Clear the context.
    !save: Save the context to a file.
    !load: Load the context from a file.
    !save_dialog: Save the dialog to a file.
    !help Print this help message.
    !quit Exit the program.
    !usage Print the total usage in this session.
    !clear Clear the context.
    !save Save the context to a file.
    !load Load the context from a file.
    !save_dialog Save the dialog to a file.
    All context is autosaved to $HOME/.gpt_cli/autosave.
    @@ -48,6 +49,7 @@
    """

    import sys
    from sys import exit
    import os
    import readline
    import json
    @@ -62,6 +64,17 @@
    print('pip install openai')
    exit(1)


    MODEL = 'gpt-3.5-turbo'
    MAX_TOKENS = 3096
    USD_PER_TOKEN = 0.000002
    CONTEXT_AUTOSAVE = True
    CONTEXT_AUTOSAVE_DIR = os.path.join(os.environ['HOME'], '.gpt_cli/autosave')
    if CONTEXT_AUTOSAVE:
    if not os.path.exists(CONTEXT_AUTOSAVE_DIR):
    os.makedirs(CONTEXT_AUTOSAVE_DIR)


    try:
    openai.api_key = os.environ['OPENAI_API_KEY']
    except KeyError:
    @@ -72,48 +85,44 @@
    print(help_str)
    exit(1)

    MODEL = 'gpt-3.5-turbo'
    MAX_TOKENS = 3096
    USD_PER_TOKEN = 0.000002
    CONTEXT_AUTOSAVE = True
    CONTEXT_AUTOSAVE_DIR = os.path.join(os.environ['HOME'], '.gpt_cli/autosave')
    if CONTEXT_AUTOSAVE:
    if not os.path.exists(CONTEXT_AUTOSAVE_DIR):
    os.makedirs(CONTEXT_AUTOSAVE_DIR)

    def timestamp():
    return datetime.now().strftime('%Y-%m-%d %H:%M:%S')


    class GPTClient(object):
    def __init__(self) -> None:
    self.context = []
    self.total_usage = 0

    # generate session name
    self.session_name = str(uuid.uuid4())

    # parse command
    parser = ArgumentParser(
    description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument(
    'command', nargs='?', help='qa, rephrase, another-word, interactive, talk')
    'command', nargs='?', help='q, qa, rephrase, another-word, interactive, talk')

    args = parser.parse_args(sys.argv[1:2])
    if not args.command or not hasattr(self, args.command):
    print('Missing or unrecognized command')
    parser.print_help()
    exit(1)

    # generate session name
    self.session_name = str(uuid.uuid4())
    print(f'Session {self.session_name} started.')
    print()

    # run command
    getattr(self, args.command)()

    def q(self):
    self.qa()

    def qa(self):
    parser = ArgumentParser(description='Chat with GPT-3')
    parser = ArgumentParser(description='Ask GPT-3 a question')
    parser.add_argument(
    'text', help='Ask a single question, no context is saved.')
    'text', help='Ask a single question then exit.')
    args = parser.parse_args(sys.argv[2:])

    self.context.append({"role": "user", "content": args.text})
    self.context.append({"role": "user", "datetime": timestamp(), "content": args.text})
    self._chat()

    def rephrase(self):
    @@ -122,8 +131,8 @@ def rephrase(self):
    args = parser.parse_args(sys.argv[2:])

    prompt = "Rephrase text. Use British English. Make it fluent and concise. Keep its original meaning. The text is: "
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})

    self.context.append({"role": "user", "datetime": timestamp(), "content": f'{prompt} \"{args.text}\"'})
    self._chat()

    def another_word(self):
    @@ -132,8 +141,8 @@ def another_word(self):
    args = parser.parse_args(sys.argv[2:])

    prompt = "Find another word for: "
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})

    self.context.append({"role": "user", "datetime": timestamp(), "content": f'{prompt} {args.text}'})
    self._chat()

    def _save_context(self, fn='context.json', verbose=True):
    @@ -172,11 +181,11 @@ def _chat(self):
    )

    for choice in response['choices']:
    print('GPT-3:', end=' ')
    print(choice['message']['content'].lstrip('\n'))
    print()
    date_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    self.context.append({"role": "assistant", "datetime": date_time,
    print(f'🤖 GPT-3:')
    print(choice['message']['content'].lstrip('\n'))

    self.context.append({"role": "assistant", "datetime": timestamp(),
    "content": choice['message']['content'].lstrip('\n')})

    self.total_usage += response['usage']['total_tokens']
    @@ -190,20 +199,20 @@ def __del__(self):
    self._print_usage()

    def _print_usage(self):
    print(f'{self.session_name}: {self.total_usage} tokens ({USD_PER_TOKEN * self.total_usage:.4f} USD).')
    print(f'Session ID {self.session_name}: {self.total_usage} tokens ({USD_PER_TOKEN * self.total_usage:.4f} USD).')

    def talk(self):
    self.interactive()

    def interactive_print_help(self):
    help_str = """Commands:
    !help: Print this help message.
    !quit: Exit the program.
    !usage: Print the total usage in this session.
    !clear: Clear the context.
    !save: Save the context to a file.
    !load: Load the context from a file.
    !save_dialog: Save the dialog to a file.
    !help Print this help message.
    !quit Exit the program.
    !usage Print the total usage in this session.
    !clear Clear the context.
    !save Save the context to a file.
    !load Load the context from a file.
    !save_dialog Save the dialog to a file for viewing.
    """
    print(help_str)

    @@ -212,9 +221,10 @@ def interactive(self):
    print('Type !help to see a list of commands.')
    print('Type !quit or Ctrl-D to exit.')

    session_name = input(
    f'Name this chat or hit ENTER to use session ID as its name [{self.session_name}]: ')
    print()
    session_name = input(
    f'Name this session or hit ENTER to skip [{self.session_name}]: ')

    if session_name:
    self.session_name = session_name

    @@ -230,8 +240,8 @@ def interactive(self):

    # The main loop
    while True:
    text = input('You: ')
    print()
    text = input(f'🧠 You: ')
    # Check for commands
    if text.startswith('!'):
    command = text[1:].split(' ')[0]
    @@ -242,9 +252,8 @@ def interactive(self):
    continue

    # Add message to context
    date_time = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
    self.context.append(
    {"role": "user", "datetime": date_time, "content": text})
    {"role": "user", "datetime": timestamp(), "content": text})
    self._chat()


  3. ZiweiXU revised this gist Mar 3, 2023. 1 changed file with 80 additions and 40 deletions.
    120 changes: 80 additions & 40 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,54 @@
    #!/usr/bin/env python3
    """ GPT-3 client for Python 3.6+.
    Usage: python gpt.py [command] [options] [text]
    Commands:
    qa - Ask a single question, no context is saved.
    rephrase - Rephrase text with GPT-3.
    another-word - Find another word with GPT-3.
    interactive - Start an interactive chat with GPT-3.
    talk - Alias for interactive.
    Options:
    -h, --help - Print help message.
    Examples:
    python gpt.py qa "What is the meaning of life?"
    python gpt.py rephrase "I am a cat."
    python gpt.py another-word "cat"
    python gpt.py interactive
    """
    GPT-3.5 client for Python 3.6+.
    Usage: python gpt.py [command] [options] [text]
    Commands:
    qa - Ask a single question, no context is saved.
    rephrase - Rephrase text with GPT-3.
    another-word - Find another word with GPT-3.
    interactive - Start an interactive chat with GPT-3.
    talk - Alias for interactive.
    Options:
    -h, --help - Print help message.
    Examples:
    python gpt.py qa "What is the meaning of life?"
    python gpt.py rephrase "I am a cat."
    python gpt.py another-word "cat"
    python gpt.py interactive
    python gpt.py talk
    Commands for an interactive session:
    !help: Print this help message.
    !quit: Exit the program.
    !usage: Print the total usage in this session.
    !clear: Clear the context.
    !save: Save the context to a file.
    !load: Load the context from a file.
    !save_dialog: Save the dialog to a file.
    All context is autosaved to $HOME/.gpt_cli/autosave.
    Copyright (c) 2023 Ziwei Xu
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    """

    import sys, os
    import sys
    import os
    import readline
    import json
    import uuid
    @@ -49,37 +81,41 @@
    if not os.path.exists(CONTEXT_AUTOSAVE_DIR):
    os.makedirs(CONTEXT_AUTOSAVE_DIR)


    class GPTClient(object):
    def __init__(self) -> None:
    self.context = []
    self.total_usage = 0

    # parse command
    parser = ArgumentParser(description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument('command', nargs='?', help='qa, rephrase, another-word, interactive, talk')
    parser = ArgumentParser(
    description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument(
    'command', nargs='?', help='qa, rephrase, another-word, interactive, talk')

    args = parser.parse_args(sys.argv[1:2])
    if not args.command or not hasattr(self, args.command):
    print('Missing or unrecognized command')
    parser.print_help()
    exit(1)

    # generate session name
    self.session_name = str(uuid.uuid4())
    print(f'Session {self.session_name} started.')
    print()

    # run command
    getattr(self, args.command)()

    def qa(self):
    parser = ArgumentParser(description='Chat with GPT-3')
    parser.add_argument('text', help='Ask a single question, no context is saved.')
    parser.add_argument(
    'text', help='Ask a single question, no context is saved.')
    args = parser.parse_args(sys.argv[2:])

    self.context.append({"role": "user", "content": args.text})
    self._chat()

    def rephrase(self):
    parser = ArgumentParser(description='Rephrase text with GPT-3.')
    parser.add_argument('text', help='Text to rephrase')
    @@ -89,7 +125,7 @@ def rephrase(self):
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def another_word(self):
    parser = ArgumentParser(description='Find another word with GPT-3.')
    parser.add_argument('text', help='Text to rephrase')
    @@ -99,24 +135,24 @@ def another_word(self):
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def _save_context(self, fn='context.json', verbose=True):
    with open(f'{fn}.json', 'w') as f:
    json.dump(self.context, f)
    if verbose:
    print(f'Context saved to {fn}.json')

    def _save_dialog(self, fn='dialog.txt', verbose=True):
    with open(f'{fn}.txt', 'w') as f:
    for message in self.context:
    f.write(f'{message["role"]} ({message["datetime"]}):\n')
    f.write(f'{message["role"]} ({message["datetime"]}):\n')
    for line in message["content"].splitlines():
    f.write(f'\t{line}\n')
    f.write('\n')
    if verbose:
    print(f'Context saved to {fn}.txt')
    print('Note that this is only intended for viewing.')

    def _load_context(self, fn='context.json', verbose=True):
    fn = input('Enter filename: ')
    with open(f'{fn}', 'r') as f:
    @@ -126,31 +162,33 @@ def _load_context(self, fn='context.json', verbose=True):

    def _chat(self):
    # keep role and content only
    context = [{"role": message["role"], "content": message["content"]} for message in self.context]
    context = [{"role": message["role"], "content": message["content"]}
    for message in self.context]
    response = openai.ChatCompletion.create(
    model=MODEL,
    messages=context,
    n=1,
    max_tokens=MAX_TOKENS,
    )

    for choice in response['choices']:
    print('GPT-3:', end=' ')
    print(choice['message']['content'].lstrip('\n'))
    print()
    date_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    self.context.append({"role": "assistant", "datetime": date_time,"content": choice['message']['content'].lstrip('\n')})

    self.context.append({"role": "assistant", "datetime": date_time,
    "content": choice['message']['content'].lstrip('\n')})

    self.total_usage += response['usage']['total_tokens']

    # Save context
    if CONTEXT_AUTOSAVE:
    path = os.path.join(CONTEXT_AUTOSAVE_DIR, self.session_name)
    self._save_context(f'{path}', verbose=False)

    def __del__(self):
    self._print_usage()

    def _print_usage(self):
    print(f'{self.session_name}: {self.total_usage} tokens ({USD_PER_TOKEN * self.total_usage:.4f} USD).')

    @@ -168,17 +206,18 @@ def interactive_print_help(self):
    !save_dialog: Save the dialog to a file.
    """
    print(help_str)

    def interactive(self):
    print('This is an interactive chat with GPT-3.')
    print('Type !help to see a list of commands.')
    print('Type !quit or Ctrl-D to exit.')

    session_name = input(f'Name this chat or hit ENTER to use session ID as its name [{self.session_name}]: ')

    session_name = input(
    f'Name this chat or hit ENTER to use session ID as its name [{self.session_name}]: ')
    print()
    if session_name:
    self.session_name = session_name

    command_registry = {
    'help': self.interactive_print_help,
    'quit': exit,
    @@ -201,10 +240,11 @@ def interactive(self):
    else:
    print('Unrecognized command.')
    continue

    # Add message to context
    date_time = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
    self.context.append({"role": "user", "datetime": date_time, "content": text})
    self.context.append(
    {"role": "user", "datetime": date_time, "content": text})
    self._chat()


  4. ZiweiXU revised this gist Mar 3, 2023. 1 changed file with 63 additions and 30 deletions.
    93 changes: 63 additions & 30 deletions gpt.py
    100644 → 100755
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,6 @@

    import sys, os
    import readline
    import atexit
    import json
    import uuid
    from argparse import ArgumentParser
    @@ -34,20 +33,28 @@
    try:
    openai.api_key = os.environ['OPENAI_API_KEY']
    except KeyError:
    print('Please set the OPENAI_API_KEY environment variable.')
    print('You can get an API key at https://beta.openai.com/account/api-keys')
    print('You can set the environment variable by running:')
    print('export OPENAI_API_KEY=<your API key>')
    help_str = """Please set the OPENAI_API_KEY environment variable.
    You can get your API key from https://platform.openai.com/account/api-keys
    You can set the environment variable by running:
    export OPENAI_API_KEY=<your API key>"""
    print(help_str)
    exit(1)

    MODEL = 'gpt-3.5-turbo'
    MAX_TOKENS = 2048
    MAX_TOKENS = 3096
    USD_PER_TOKEN = 0.000002
    CONTEXT_AUTOSAVE = True
    CONTEXT_AUTOSAVE_DIR = os.path.join(os.environ['HOME'], '.gpt_cli/autosave')
    if CONTEXT_AUTOSAVE:
    if not os.path.exists(CONTEXT_AUTOSAVE_DIR):
    os.makedirs(CONTEXT_AUTOSAVE_DIR)

    class GPTClient(object):
    def __init__(self) -> None:
    self.context = []
    self.total_usage = 0

    # parse command
    parser = ArgumentParser(description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument('command', nargs='?', help='qa, rephrase, another-word, interactive, talk')

    @@ -56,7 +63,13 @@ def __init__(self) -> None:
    print('Missing or unrecognized command')
    parser.print_help()
    exit(1)

    # generate session name
    self.session_name = str(uuid.uuid4())
    print(f'Session {self.session_name} started.')
    print()

    # run command
    getattr(self, args.command)()

    def qa(self):
    @@ -72,7 +85,7 @@ def rephrase(self):
    parser.add_argument('text', help='Text to rephrase')
    args = parser.parse_args(sys.argv[2:])

    prompt = "Rephrase text. Use British English. Make it fluent and concise. Keep its meaning. The text is: "
    prompt = "Rephrase text. Use British English. Make it fluent and concise. Keep its original meaning. The text is: "
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()
    @@ -87,29 +100,31 @@ def another_word(self):
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def _save_context(self, fn='context.json'):
    def _save_context(self, fn='context.json', verbose=True):
    with open(f'{fn}.json', 'w') as f:
    json.dump(self.context, f)
    print(f'Context saved to {fn}.json')
    if verbose:
    print(f'Context saved to {fn}.json')

    def _save_dialog(self, fn='dialog.txt'):
    def _save_dialog(self, fn='dialog.txt', verbose=True):
    with open(f'{fn}.txt', 'w') as f:
    for message in self.context:
    f.write(f'{message["role"]} ({message["datetime"]}):\n')
    for line in message["content"].splitlines():
    f.write(f'\t{line}\n')
    f.write('\n')
    print(f'Context saved to {fn}.txt')
    print('Note that this is only intended for viewing.')
    if verbose:
    print(f'Context saved to {fn}.txt')
    print('Note that this is only intended for viewing.')

    def _load_context(self, fn='context.json'):
    def _load_context(self, fn='context.json', verbose=True):
    fn = input('Enter filename: ')
    with open(f'{fn}', 'r') as f:
    self.context = json.load(f)
    print(f'Context loaded from {fn}')
    if verbose:
    print(f'Context loaded from {fn}')

    def _chat(self):

    # keep role and content only
    context = [{"role": message["role"], "content": message["content"]} for message in self.context]
    response = openai.ChatCompletion.create(
    @@ -122,54 +137,72 @@ def _chat(self):
    for choice in response['choices']:
    print('GPT-3:', end=' ')
    print(choice['message']['content'].lstrip('\n'))
    print()
    date_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    self.context.append({"role": "assistant", "datetime": date_time,"content": choice['message']['content'].lstrip('\n')})

    self.total_usage += response['usage']['total_tokens']

    # Save context
    if CONTEXT_AUTOSAVE:
    path = os.path.join(CONTEXT_AUTOSAVE_DIR, self.session_name)
    self._save_context(f'{path}', verbose=False)

    def __del__(self):
    print(f'Total usage in this session: {self.total_usage} tokens.')
    self._print_usage()

    def _print_usage(self):
    print(f'{self.session_name}: {self.total_usage} tokens ({USD_PER_TOKEN * self.total_usage:.4f} USD).')

    def talk(self):
    self.interactive()

    def interactive_print_help(self):
    print('!help - Print this help message')
    print('!quit - Quit the interactive mode')
    print('!usage - Print total usage')
    print('!clear - Clear the context')
    print('!save - Save the context to a file')
    print('!load - Load the context from a file')
    print('!save_dialog - Save the context as a readable dialog')
    help_str = """Commands:
    !help: Print this help message.
    !quit: Exit the program.
    !usage: Print the total usage in this session.
    !clear: Clear the context.
    !save: Save the context to a file.
    !load: Load the context from a file.
    !save_dialog: Save the dialog to a file.
    """
    print(help_str)

    def interactive(self):
    print('This is an interactive chat with GPT-3.')
    print('Type !help to see a list of commands.')
    print('Type !quit or Ctrl-D to exit.')

    default_session_name = str(uuid.uuid4())
    session_name = input(f'Enter a name for this chat [{default_session_name}]: ')
    if not session_name:
    session_name = default_session_name
    session_name = input(f'Name this chat or hit ENTER to use session ID as its name [{self.session_name}]: ')
    print()
    if session_name:
    self.session_name = session_name

    command_registry = {
    'help': self.interactive_print_help,
    'quit': exit,
    'usage': lambda: print(f'Total usage: {self.total_usage} tokens.'),
    'usage': self._print_usage,
    'clear': lambda: self.context.clear(),
    'save': lambda fn=f'{default_session_name}': self._save_context(fn),
    'save': lambda fn=f'{self.session_name}': self._save_context(fn),
    'load': self._load_context,
    'save_dialog': lambda fn=f'{default_session_name}': self._save_dialog(fn),
    'save_dialog': lambda fn=f'{self.session_name}': self._save_dialog(fn),
    }

    # The main loop
    while True:
    text = input('You: ')
    print()
    # Check for commands
    if text.startswith('!'):
    command = text[1:].split(' ')[0]
    if command in command_registry:
    command_registry[command]()
    else:
    print('Unrecognized command.')
    continue

    # Add message to context
    date_time = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
    self.context.append({"role": "user", "datetime": date_time, "content": text})
    self._chat()
  5. ZiweiXU revised this gist Mar 3, 2023. 1 changed file with 15 additions and 5 deletions.
    20 changes: 15 additions & 5 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,7 @@
    rephrase - Rephrase text with GPT-3.
    another-word - Find another word with GPT-3.
    interactive - Start an interactive chat with GPT-3.
    talk - Alias for interactive.
    Options:
    -h, --help - Print help message.
    Examples:
    @@ -17,6 +18,7 @@

    import sys, os
    import readline
    import atexit
    import json
    import uuid
    from argparse import ArgumentParser
    @@ -47,13 +49,14 @@ def __init__(self) -> None:
    self.total_usage = 0

    parser = ArgumentParser(description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument('command', nargs='?', help='qa, rephrase, another-word, interactive')
    parser.add_argument('command', nargs='?', help='qa, rephrase, another-word, interactive, talk')

    args = parser.parse_args(sys.argv[1:2])
    if not hasattr(self, args.command):
    print('Unrecognized command')
    if not args.command or not hasattr(self, args.command):
    print('Missing or unrecognized command')
    parser.print_help()
    exit(1)

    getattr(self, args.command)()

    def qa(self):
    @@ -125,8 +128,11 @@ def _chat(self):
    self.total_usage += response['usage']['total_tokens']

    def __del__(self):
    print(f'Total usage: {self.total_usage} tokens.')
    print(f'Total usage in this session: {self.total_usage} tokens.')

    def talk(self):
    self.interactive()

    def interactive_print_help(self):
    print('!help - Print this help message')
    print('!quit - Quit the interactive mode')
    @@ -139,6 +145,7 @@ def interactive_print_help(self):
    def interactive(self):
    print('This is an interactive chat with GPT-3.')
    print('Type !help to see a list of commands.')
    print('Type !quit or Ctrl-D to exit.')

    default_session_name = str(uuid.uuid4())
    session_name = input(f'Enter a name for this chat [{default_session_name}]: ')
    @@ -169,4 +176,7 @@ def interactive(self):


    if __name__ == '__main__':
    GPTClient()
    try:
    GPTClient()
    except EOFError:
    exit(0)
  6. ZiweiXU revised this gist Mar 2, 2023. 1 changed file with 21 additions and 13 deletions.
    34 changes: 21 additions & 13 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -18,6 +18,7 @@
    import sys, os
    import readline
    import json
    import uuid
    from argparse import ArgumentParser
    from datetime import datetime

    @@ -91,7 +92,10 @@ def _save_context(self, fn='context.json'):
    def _save_dialog(self, fn='dialog.txt'):
    with open(f'{fn}.txt', 'w') as f:
    for message in self.context:
    f.write(f'{message["role"]}: {message["content"]}\n')
    f.write(f'{message["role"]} ({message["datetime"]}):\n')
    for line in message["content"].splitlines():
    f.write(f'\t{line}\n')
    f.write('\n')
    print(f'Context saved to {fn}.txt')
    print('Note that this is only intended for viewing.')

    @@ -100,24 +104,23 @@ def _load_context(self, fn='context.json'):
    with open(f'{fn}', 'r') as f:
    self.context = json.load(f)
    print(f'Context loaded from {fn}')
    # with open(f'{fn}', 'r') as f:
    # for line in f:
    # role, content = line.split(': ', 1)
    # self.context.append({"role": role, "content": content})

    def _chat(self):


    # keep role and content only
    context = [{"role": message["role"], "content": message["content"]} for message in self.context]
    response = openai.ChatCompletion.create(
    model=MODEL,
    messages=self.context,
    messages=context,
    n=1,
    max_tokens=MAX_TOKENS,
    )

    for choice in response['choices']:
    print('GPT-3:', end=' ')
    print(choice['message']['content'].lstrip('\n'))
    self.context.append({"role": "assistant", "content": choice['message']['content'].lstrip('\n')})
    date_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    self.context.append({"role": "assistant", "datetime": date_time,"content": choice['message']['content'].lstrip('\n')})

    self.total_usage += response['usage']['total_tokens']

    @@ -134,18 +137,22 @@ def interactive_print_help(self):
    print('!save_dialog - Save the context as a readable dialog')

    def interactive(self):
    date_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    print('This is an interactive chat with GPT-3.')
    print('The chat is identified by {date_time}.')
    print('Type !help to see a list of commands.')

    default_session_name = str(uuid.uuid4())
    session_name = input(f'Enter a name for this chat [{default_session_name}]: ')
    if not session_name:
    session_name = default_session_name

    command_registry = {
    'help': self.interactive_print_help,
    'quit': exit,
    'usage': lambda: print(f'Total usage: {self.total_usage} tokens.'),
    'clear': lambda: self.context.clear(),
    'save': lambda fn=f'{date_time}': self._save_context(fn),
    'save': lambda fn=f'{default_session_name}': self._save_context(fn),
    'load': self._load_context,
    'save_dialog': lambda fn=f'{date_time}': self._save_dialog(fn),
    'save_dialog': lambda fn=f'{default_session_name}': self._save_dialog(fn),
    }
    while True:
    text = input('You: ')
    @@ -156,7 +163,8 @@ def interactive(self):
    else:
    print('Unrecognized command.')
    continue
    self.context.append({"role": "user", "content": text})
    date_time = str(datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
    self.context.append({"role": "user", "datetime": date_time, "content": text})
    self._chat()


  7. ZiweiXU revised this gist Mar 2, 2023. 1 changed file with 22 additions and 9 deletions.
    31 changes: 22 additions & 9 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -17,6 +17,7 @@

    import sys, os
    import readline
    import json
    from argparse import ArgumentParser
    from datetime import datetime

    @@ -82,19 +83,27 @@ def another_word(self):
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def _save_context(self):
    date_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    with open(f'{date_time}.txt', 'w') as f:
    def _save_context(self, fn='context.json'):
    with open(f'{fn}.json', 'w') as f:
    json.dump(self.context, f)
    print(f'Context saved to {fn}.json')

    def _save_dialog(self, fn='dialog.txt'):
    with open(f'{fn}.txt', 'w') as f:
    for message in self.context:
    f.write(f'{message["role"]}: {message["content"]}\n')
    print(f'Context saved to {date_time}.txt')
    print(f'Context saved to {fn}.txt')
    print('Note that this is only intended for viewing.')

    def _load_context(self):
    def _load_context(self, fn='context.json'):
    fn = input('Enter filename: ')
    with open(f'{fn}', 'r') as f:
    for line in f:
    role, content = line.split(': ', 1)
    self.context.append({"role": role, "content": content})
    self.context = json.load(f)
    print(f'Context loaded from {fn}')
    # with open(f'{fn}', 'r') as f:
    # for line in f:
    # role, content = line.split(': ', 1)
    # self.context.append({"role": role, "content": content})

    def _chat(self):

    @@ -122,17 +131,21 @@ def interactive_print_help(self):
    print('!clear - Clear the context')
    print('!save - Save the context to a file')
    print('!load - Load the context from a file')
    print('!save_dialog - Save the context as a readable dialog')

    def interactive(self):
    date_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    print('This is an interactive chat with GPT-3.')
    print('The chat is identified by {date_time}.')
    print('Type !help to see a list of commands.')
    command_registry = {
    'help': self.interactive_print_help,
    'quit': exit,
    'usage': lambda: print(f'Total usage: {self.total_usage} tokens.'),
    'clear': lambda: self.context.clear(),
    'save': self._save_context,
    'save': lambda fn=f'{date_time}': self._save_context(fn),
    'load': self._load_context,
    'save_dialog': lambda fn=f'{date_time}': self._save_dialog(fn),
    }
    while True:
    text = input('You: ')
  8. ZiweiXU revised this gist Mar 2, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gpt.py
    Original file line number Diff line number Diff line change
    @@ -36,7 +36,7 @@
    print('export OPENAI_API_KEY=<your API key>')
    exit(1)

    MODEL = 'GPT-3.5-Turbo'
    MODEL = 'gpt-3.5-turbo'
    MAX_TOKENS = 2048

    class GPTClient(object):
  9. ZiweiXU revised this gist Mar 2, 2023. 1 changed file with 15 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,19 @@
    #!/usr/bin/env python3
    """ GPT-3 client for Python 3.6+.
    Usage: python gpt.py [command] [options] [text]
    Commands:
    qa - Ask a single question, no context is saved.
    rephrase - Rephrase text with GPT-3.
    another-word - Find another word with GPT-3.
    interactive - Start an interactive chat with GPT-3.
    Options:
    -h, --help - Print help message.
    Examples:
    python gpt.py qa "What is the meaning of life?"
    python gpt.py rephrase "I am a cat."
    python gpt.py another-word "cat"
    python gpt.py interactive
    """

    import sys, os
    import readline
  10. ZiweiXU created this gist Mar 2, 2023.
    136 changes: 136 additions & 0 deletions gpt.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    #!/usr/bin/env python3

    import sys, os
    import readline
    from argparse import ArgumentParser
    from datetime import datetime

    try:
    import openai
    except ImportError:
    print('Please install the OpenAI Python library:')
    print('pip install openai')
    exit(1)

    try:
    openai.api_key = os.environ['OPENAI_API_KEY']
    except KeyError:
    print('Please set the OPENAI_API_KEY environment variable.')
    print('You can get an API key at https://beta.openai.com/account/api-keys')
    print('You can set the environment variable by running:')
    print('export OPENAI_API_KEY=<your API key>')
    exit(1)

    MODEL = 'GPT-3.5-Turbo'
    MAX_TOKENS = 2048

    class GPTClient(object):
    def __init__(self) -> None:
    self.context = []
    self.total_usage = 0

    parser = ArgumentParser(description='Chat with GPT-3', usage='%(prog)s [command] [options] [text]')
    parser.add_argument('command', nargs='?', help='qa, rephrase, another-word, interactive')

    args = parser.parse_args(sys.argv[1:2])
    if not hasattr(self, args.command):
    print('Unrecognized command')
    parser.print_help()
    exit(1)
    getattr(self, args.command)()

    def qa(self):
    parser = ArgumentParser(description='Chat with GPT-3')
    parser.add_argument('text', help='Ask a single question, no context is saved.')
    args = parser.parse_args(sys.argv[2:])

    self.context.append({"role": "user", "content": args.text})
    self._chat()

    def rephrase(self):
    parser = ArgumentParser(description='Rephrase text with GPT-3.')
    parser.add_argument('text', help='Text to rephrase')
    args = parser.parse_args(sys.argv[2:])

    prompt = "Rephrase text. Use British English. Make it fluent and concise. Keep its meaning. The text is: "
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def another_word(self):
    parser = ArgumentParser(description='Find another word with GPT-3.')
    parser.add_argument('text', help='Text to rephrase')
    args = parser.parse_args(sys.argv[2:])

    prompt = "Find another word for: "
    text = f'"{args.text}"'
    self.context.append({"role": "user", "content": f'{prompt} {text}'})
    self._chat()

    def _save_context(self):
    date_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    with open(f'{date_time}.txt', 'w') as f:
    for message in self.context:
    f.write(f'{message["role"]}: {message["content"]}\n')
    print(f'Context saved to {date_time}.txt')

    def _load_context(self):
    fn = input('Enter filename: ')
    with open(f'{fn}', 'r') as f:
    for line in f:
    role, content = line.split(': ', 1)
    self.context.append({"role": role, "content": content})

    def _chat(self):

    response = openai.ChatCompletion.create(
    model=MODEL,
    messages=self.context,
    n=1,
    max_tokens=MAX_TOKENS,
    )

    for choice in response['choices']:
    print('GPT-3:', end=' ')
    print(choice['message']['content'].lstrip('\n'))
    self.context.append({"role": "assistant", "content": choice['message']['content'].lstrip('\n')})

    self.total_usage += response['usage']['total_tokens']

    def __del__(self):
    print(f'Total usage: {self.total_usage} tokens.')

    def interactive_print_help(self):
    print('!help - Print this help message')
    print('!quit - Quit the interactive mode')
    print('!usage - Print total usage')
    print('!clear - Clear the context')
    print('!save - Save the context to a file')
    print('!load - Load the context from a file')

    def interactive(self):
    print('This is an interactive chat with GPT-3.')
    print('Type !help to see a list of commands.')
    command_registry = {
    'help': self.interactive_print_help,
    'quit': exit,
    'usage': lambda: print(f'Total usage: {self.total_usage} tokens.'),
    'clear': lambda: self.context.clear(),
    'save': self._save_context,
    'load': self._load_context,
    }
    while True:
    text = input('You: ')
    if text.startswith('!'):
    command = text[1:].split(' ')[0]
    if command in command_registry:
    command_registry[command]()
    else:
    print('Unrecognized command.')
    continue
    self.context.append({"role": "user", "content": text})
    self._chat()


    if __name__ == '__main__':
    GPTClient()