1
1
#!/usr/bin/env python
2
2
3
3
import os
4
+ from typing import List , Optional , cast
4
5
6
+ import openai
5
7
import typer
8
+ from pydantic import BaseModel
6
9
from revChatGPT .Official import Chatbot
7
10
8
11
API_KEY = os .environ .get ('OPENAI_API_KEY' ) or ''
9
12
10
13
14
+ class OpenAIResponseModel (BaseModel ):
15
+
16
+ class Choice (BaseModel ):
17
+ finish_reason : str
18
+ index : int
19
+ logprobs : Optional [None ]
20
+ text : Optional [str ]
21
+
22
+ class Usage (BaseModel ):
23
+ completion_tokens : int
24
+ prompt_tokens : int
25
+ total_tokens : int
26
+
27
+ choices : Optional [List [Choice ]]
28
+ created : int
29
+ id : str
30
+ model : str
31
+ object : str
32
+ usage : Usage
33
+
34
+
35
+ def get_os () -> str :
36
+ return os .uname ()[0 ]
37
+
38
+
11
39
def make_executable_command (command : str ) -> str :
12
40
# starting '\n' or trailing '\n' should be replaced as ''
13
41
# starting ' ' or trailing ' ' should be replaced as ''
@@ -25,28 +53,54 @@ def make_executable_command(command: str) -> str:
25
53
26
54
27
55
def ask_chatgpt (text : str ) -> str :
56
+
57
+ def _construct_prompt (requirements : str ) -> str :
58
+ return f'''You are now a translater from human language to { get_os ()} shell command.
59
+ No explanation required, respond with only the raw shell command.
60
+ What should I type to shell for: { requirements } , in one line.'''
61
+
62
+ prompt = _construct_prompt (text )
28
63
chatbot = Chatbot (api_key = API_KEY )
29
- response_text : str = chatbot .ask (text )['choices' ][0 ]['text' ]
64
+ response_text : str = chatbot .ask (prompt )['choices' ][0 ]['text' ]
30
65
return make_executable_command (response_text )
31
66
32
67
33
- def get_os () -> str :
34
- return os .uname ()[0 ]
68
+ def ask_gpt3 (text : str ) -> str :
69
+
70
+ def _construct_prompt (text : str ) -> str :
71
+ return f'''User: You are now a translater from human language to { get_os ()} shell command.
72
+ No explanation required, respond with only the raw shell command.
73
+ What should I type to shell for: { text } , in one line.
35
74
75
+ You: '''
36
76
37
- def make_prompt (requirements : str ) -> str :
38
- return f'''You are now a translater from human language to { get_os } shell command.
39
- No explanation required, respond with only the raw shell command.
40
- What should I type to shell for: { requirements } , in one line.'''
77
+ prompt = _construct_prompt (text )
78
+
79
+ completion : OpenAIResponseModel = cast (
80
+ OpenAIResponseModel ,
81
+ openai .Completion .create (
82
+ engine = 'text-davinci-003' ,
83
+ prompt = prompt ,
84
+ temperature = 0.5 ,
85
+ max_tokens = 4000 - len (prompt ),
86
+ stop = ['\n \n \n ' ],
87
+ ),
88
+ )
89
+ if not completion .choices or len (completion .choices ) == 0 or not completion .choices [0 ].text :
90
+ raise RuntimeError ('No response from OpenAI' )
91
+ response_text : str = completion .choices [0 ].text
92
+ return make_executable_command (response_text )
41
93
42
94
43
95
app = typer .Typer ()
44
96
45
97
46
98
@app .command ()
47
- def ask (text : str ):
48
- question = make_prompt (text )
49
- response = ask_chatgpt (question )
99
+ def ask (question : str , use_chatgpt : bool = False ):
100
+ if use_chatgpt :
101
+ response = ask_chatgpt (question )
102
+ else :
103
+ response = ask_gpt3 (question )
50
104
typer .echo (f'\033 [3mexecuting: { response } \033 [0m' )
51
105
os .system (response )
52
106
0 commit comments