-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinscode.py
130 lines (112 loc) · 4.24 KB
/
inscode.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
# import json
import os
import openai
import re
import pyperclip
from settings import *
import requests
class InsCode:
def __init__(self, api_key=None):
if not api_key:
self.api_key = os.getenv("OPENAI_API_KEY")
else:
self.api_key = api_key
openai.api_key = self.api_key
with open('preference.json', 'r') as f:
self.preference = json.load(f)
self.preset_selected = self.preference["preset_selected"]
self.model = self.preference["model"]
self.is_keepitshort = self.preference["is_keepitshort"]
self.max_tokens = self.preference["max_tokens"]
self.presets = load_prompts()
self.is_clipboard = True
# test mode
self.is_fakeanswer = False
# store preference as file since Wox terminate process after window closed
def set_preset(self, preset):
self.preset_selected = preset
self.preference["preset_selected"] = preset
with open('preference.json', 'w+') as f:
json.dump(self.preference, f,sort_keys=True,indent=4)
def reload_presets(self):
self.presets = load_prompts()
def response_fn(self, question, preset=None, model=None):
if not preset:
preset = self.preset_selected
if not model:
model = self.model
preset_dict = self.presets.get(preset)
if not self.is_keepitshort:
content = preset_dict["content"]
content = re.sub(
r"(Remember do not include any explanations in your responses.)", "", content)
preset_dict["content"] = content
return_info = openai.ChatCompletion.create(
model=model,
max_tokens=self.max_tokens,
messages=[preset_dict, {"role": "user", "content": question}]
)
return return_info
def get_answer(self, question, **kwargs):
# only return first codeblock, return original if failed
if self.is_fakeanswer:
return "This is a fake answer. \n"
def extract_code(s):
try:
pos = re.search(r"(```.*\n)", s)
poss = pos.end()
pos2 = re.search(r"(```)", s[poss:])
pose = pos2.start()
return s[poss:poss+pose]
except:
return s
answer_raw = self.response_fn(
question, **kwargs)["choices"][0]["message"]['content']
if self.is_keepitshort:
answer = extract_code(answer_raw)
else:
answer = answer_raw
if self.is_clipboard:
pyperclip.copy(answer)
return answer
def test(self, question, preset_name=None, **kwargs):
# test all
if not preset_name:
for key, value in self.presets.items():
answer = self.get_answer(question=question, preset=key)
print(key, value, "\n", answer, "\n")
# test specific prompt
else:
answer = self.get_answer(question=question,
preset=preset_name, **kwargs)
print(preset_name, self.presets[preset_name], "\n", answer, "\n")
if __name__ == "__main__":
import sys
Bot = InsCode()
# query mode
# python inscode.py "your question"
# Usage: subprocess.Popen(["python", "inscode.py", "query"])
if len(sys.argv) > 1:
if sys.argv[1]=="query":
while True:
question = sys.stdin.readline().strip()
if not question:
break
answer = Bot.get_answer(question)
print("Received question: ", question)
print("Get answer: ", answer)
# interactive mode
# python inscode.py
else:
import time
start_time = time.time()
while True:
time_pass = time.time() - start_time
if time_pass > 300: # 5 minutes
break
question = input("Enter your question: (Type quit/q to quit)\n")
# question = input()
print(Bot.get_answer(question))
# print("Time pass: %d sec" % time_pass)
if question == "quit" or question=="q": # Exit loop if user enters "quit"
break