forked from TheR1D/shell_gpt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
211 lines (193 loc) · 6.09 KB
/
app.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# To allow users to use arrow keys in the REPL.
import readline # noqa: F401
import sys
import os
import typer
from click import BadArgumentUsage, MissingParameter
from click.types import Choice
from sgpt.config import cfg
from sgpt.handlers.chat_handler import ChatHandler
from sgpt.handlers.default_handler import DefaultHandler
from sgpt.handlers.repl_handler import ReplHandler
from sgpt.role import DefaultRoles, SystemRole
from sgpt.utils import get_edited_prompt, install_shell_integration, run_command
def main(
prompt: str = typer.Argument(
None,
show_default=False,
help="The prompt to generate completions for.",
),
model: str = typer.Option(
cfg.get("DEFAULT_MODEL"),
help="Large language model to use.",
),
temperature: float = typer.Option(
0.1,
min=0.0,
max=2.0,
help="Randomness of generated output.",
),
top_probability: float = typer.Option(
1.0,
min=0.1,
max=1.0,
help="Limits highest probable tokens (words).",
),
shell: bool = typer.Option(
False,
"--shell",
"-s",
help="Generate and execute shell commands.",
rich_help_panel="Assistance Options",
),
describe_shell: bool = typer.Option(
False,
"--describe-shell",
"-d",
help="Describe a shell command.",
rich_help_panel="Assistance Options",
),
code: bool = typer.Option(
False,
help="Generate only code.",
rich_help_panel="Assistance Options",
),
editor: bool = typer.Option(
False,
help="Open $EDITOR to provide a prompt.",
),
cache: bool = typer.Option(
True,
help="Cache completion results.",
),
chat: str = typer.Option(
None,
help="Follow conversation with id, " 'use "temp" for quick session.',
rich_help_panel="Chat Options",
),
repl: str = typer.Option(
None,
help="Start a REPL (Read–eval–print loop) session.",
rich_help_panel="Chat Options",
),
show_chat: str = typer.Option(
None,
help="Show all messages from provided chat id.",
callback=ChatHandler.show_messages_callback,
rich_help_panel="Chat Options",
),
list_chats: bool = typer.Option(
False,
help="List all existing chat ids.",
callback=ChatHandler.list_ids,
rich_help_panel="Chat Options",
),
role: str = typer.Option(
None,
help="System role for GPT model.",
rich_help_panel="Role Options",
),
create_role: str = typer.Option(
None,
help="Create role.",
callback=SystemRole.create,
rich_help_panel="Role Options",
),
show_role: str = typer.Option(
None,
help="Show role.",
callback=SystemRole.show,
rich_help_panel="Role Options",
),
list_roles: bool = typer.Option(
False,
help="List roles.",
callback=SystemRole.list,
rich_help_panel="Role Options",
),
install_integration: bool = typer.Option(
False,
help="Install shell integration (ZSH and Bash only)",
callback=install_shell_integration,
hidden=True, # Hiding since should be used only once.
),
) -> None:
stdin_passed = not sys.stdin.isatty()
if stdin_passed:
input_lines = sys.stdin.readlines()
prompt = "".join(input_lines) + "\n\n" + (prompt or "")
# Switch to stdin for interactive input
if os.name == "posix":
sys.stdin = open("/dev/tty", "r")
elif os.name == "nt":
sys.stdin = open("CON", "r")
if not prompt and not editor and not repl:
raise MissingParameter(param_hint="PROMPT", param_type="string")
if sum((shell, describe_shell, code)) > 1:
raise BadArgumentUsage(
"Only one of --shell, --describe-shell, and --code options can be used at a time."
)
if chat and repl:
raise BadArgumentUsage("--chat and --repl options cannot be used together.")
if editor and stdin_passed:
raise BadArgumentUsage("--editor option cannot be used with stdin input.")
if editor:
prompt = get_edited_prompt()
role_class = (
DefaultRoles.check_get(shell, describe_shell, code)
if not role
else SystemRole.get(role)
)
if repl:
# Will be in infinite loop here until user exits with Ctrl+C.
ReplHandler(repl, role_class).handle(
prompt,
model=model,
temperature=temperature,
top_probability=top_probability,
chat_id=repl,
caching=cache,
)
if chat:
full_completion = ChatHandler(chat, role_class).handle(
prompt,
model=model,
temperature=temperature,
top_probability=top_probability,
chat_id=chat,
caching=cache,
)
else:
full_completion = DefaultHandler(role_class).handle(
prompt,
model=model,
temperature=temperature,
top_probability=top_probability,
caching=cache,
)
while shell:
option = typer.prompt(
text="[E]xecute, [D]escribe, [A]bort",
type=Choice(("e", "d", "a", "y"), case_sensitive=False),
default="e" if cfg.get("DEFAULT_EXECUTE_SHELL_CMD") == "true" else "a",
show_choices=False,
show_default=False,
)
if option in ("e", "y"):
# "y" option is for keeping compatibility with old version.
run_command(full_completion)
elif option == "d":
DefaultHandler(DefaultRoles.DESCRIBE_SHELL.get_role()).handle(
full_completion,
model=model,
temperature=temperature,
top_probability=top_probability,
caching=cache,
)
continue
break
def entry_point() -> None:
# Python package entry point defined in setup.py
typer.run(main)
if __name__ == "__main__":
entry_point()