-
Notifications
You must be signed in to change notification settings - Fork 3
/
genie.py
146 lines (123 loc) · 4.76 KB
/
genie.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import openai
import sys
import random
import string
import colorama
import shutil
import argparse
import readline
from src.extras import greeting, lamp
from src.prompts import prompts
from colorama import Fore, Back, Style
"""
Genie: A Python implementation of OpenAI's ChatGPT integrated into your shell.
Interact with the model interactively or pass questions to it from the terminal.
Supports custom prompts for honed interaction and switching of API model.
"""
def main():
openai.api_key = "API_KEY"
def parse_args():
parser = argparse.ArgumentParser(description="Genie: Chat with ChatGPT")
parser.add_argument(
"--model",
default="gpt-3.5-turbo",
choices=["gpt-4", "gpt-3.5-turbo", "code-davinci-002", "text-davinci-003"],
help="Choose the API model to use",
)
parser.add_argument(
"--temperature",
default=0.7,
type=float,
help="Control the randomness of the response (default: 0.7)",
)
parser.add_argument(
"question", nargs="*", help="Optional question for non-interactive mode"
)
return parser.parse_args()
def display_prompt_menu():
term_width = shutil.get_terminal_size((80, 20)).columns
num_columns = 3
column_width = term_width // num_columns
formatted_prompts = []
for i, prompt in enumerate(prompts):
formatted_prompt = f"{i + 1} - {prompt.split(':')[0]}"
padded_prompt = formatted_prompt.center(column_width)
formatted_prompts.append(padded_prompt)
print(
Fore.YELLOW
+ "Ask a question, choose a prompt, or 'q' to quit:".center(term_width)
+ "\n"
)
print(Fore.YELLOW + "=" * term_width)
for i, formatted_prompt in enumerate(formatted_prompts):
print(Fore.YELLOW + formatted_prompt, end="")
if (i + 1) % num_columns == 0 and i != len(formatted_prompts) - 1:
print()
print(Fore.YELLOW + "\n" + "=" * term_width + Style.RESET_ALL)
def center_multiline_string(s):
term_width = shutil.get_terminal_size((80, 20)).columns
centered_lines = []
for line in s.split("\n"):
padding_left = (term_width - len(line)) // 2
centered_line = " " * padding_left + line
centered_lines.append(centered_line)
return "\n".join(centered_lines)
def get_user_input(prompt):
try:
return input(prompt)
except (EOFError, KeyboardInterrupt):
return "q"
def print_centered_no_newline(text):
term_width = shutil.get_terminal_size((80, 20)).columns
padding_left = (term_width - len(text)) // 2
print(" " * padding_left + text, end="")
args = parse_args()
messages = []
randomgreeting = random.choice(greeting)
if args.question:
prompt = " ".join(args.question).rstrip(string.punctuation)
else:
print(Fore.YELLOW + center_multiline_string(lamp))
print(Fore.YELLOW + center_multiline_string(randomgreeting) + "\n")
display_prompt_menu()
print_centered_no_newline(Fore.BLUE + "You: ")
user_input = get_user_input(Fore.BLUE + "")
if user_input.strip().isdigit() and 1 <= int(user_input.strip()) <= len(
prompts
):
prompt = prompts[int(user_input.strip()) - 1]
else:
prompt = user_input.strip()
while True:
if prompt.lower() in ["quit", "q", "bye"]:
print(
Fore.YELLOW
+ "\nGenie: "
+ "Farewell, master. Until you drag me out of bed again...\n"
)
break
messages.append({"role": "user", "content": prompt})
response = openai.ChatCompletion.create(
model=args.model, messages=messages, temperature=args.temperature
)
reply = response["choices"][0]["message"]["content"]
messages.append({"role": "assistant", "content": reply})
print(Fore.YELLOW + "\nGenie: " + reply + "\n")
if args.question:
break
else:
prompt = get_user_input(Fore.BLUE + "You: ")
if prompt.lower() == "menu":
display_prompt_menu()
user_input = get_user_input(
Fore.BLUE
+ "Prompt (1-9), custom question, or 'q': ".center(
shutil.get_terminal_size((80, 20)).columns
)
).strip()
if user_input.isdigit() and 1 <= int(user_input) <= len(prompts):
prompt = prompts[int(user_input) - 1]
else:
prompt = user_input
if __name__ == "__main__":
main()