-
Notifications
You must be signed in to change notification settings - Fork 1
/
ask.sh
executable file
·169 lines (144 loc) · 4.28 KB
/
ask.sh
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
#!/bin/bash
set -o pipefail
api_key=${SHELL_ASK_API_KEY:-""}
api_model=${SHELL_ASK_API_MODEL:-"gpt-3.5-turbo"}
api_endpoint=${SHELL_ASK_API_ENDPOINT:-"https://api.openai.com/v1/chat/completions"}
answer_language=${SHELL_ASK_ANSWER_LANGUAGE:-"english"}
config_dir=${SHELL_ASK_CONFIG_DIR:-"$HOME/.config/ask.sh"}
config_file=${SHELL_ASK_CONFIG_FILE:-"$config_dir/config.json"}
send_request() {
local content="$1"
local body=$(jq -n --arg content "$content" --arg model "$api_model" '{
model: "\($model)",
messages: [{"role": "user", "content": "\($content)"}],
temperature: 0.3
}')
local response=$(curl -s $api_endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $api_key" \
-d "$body")
local error=$(echo $response | jq -r '.error.message')
if [ "$error" != "null" ]; then
echo $error
else
local result=$(echo $response | jq -r '.choices[0].message.content')
if declare -f after_ask > /dev/null; then
after_ask "$result"
else
echo $result
fi
fi
}
ask() {
local input=""
local content=""
local prompt="$1"
local content=""
if [ -p /dev/stdin ]; then
input=$(cat -)
fi
if [ ! -z "$input" ]; then
content="According to the following shell output, using $answer_language to answer the question below: $prompt, here is the shell output: $input"
else
local shell_name=$(basename $SHELL)
local os_name=$(uname)
content="Return commands suitable for copy/pasting into $shell_name on $os_name. Do NOT include commentary NOR Markdown triple-backtick code blocks as your whole response will be copied into my terminal automatically.\n\nThe script should do this: $prompt"
fi
send_request "$content"
}
ask_with_plugin() {
local input=""
local plugin=$1
local prompt=$2
if [ -p /dev/stdin ]; then
input=$(cat -)
fi
if [ -f "$plugin" ]; then
source $plugin
local content=$(gen_content $prompt "$input")
send_request "$content"
else
echo "Plugin not found: $plugin"
fi
}
load_config() {
if [ -f "$config_file" ]; then
api_key=$(jq -r '.api_key' $config_file)
api_model=$(jq -r '.api_model' $config_file)
api_endpoint=$(jq -r '.api_endpoint' $config_file)
answer_language=$(jq -r '.answer_language' $config_file)
fi
}
get_config() {
local key=$1
if [ -f "$config_file" ]; then
jq -r --arg key "$key" '.[$key]' $config_file
else
case $key in
api_key)
echo $api_key
;;
api_model)
echo $api_model
;;
api_endpoint)
echo $api_endpoint
;;
answer_language)
echo $answer_language
;;
*)
echo "Key not found: $key"
;;
esac
fi
}
set_config() {
if [ ! -d "$config_dir" ]; then
mkdir -p $config_dir
fi
if [ ! -f "$config_file" ]; then
jq -n --arg api_key "$api_key" --arg api_model "$api_model" --arg api_endpoint "$api_endpoint" --arg answer_language "$answer_language" '{
api_key: $api_key,
api_model: $api_model,
api_endpoint: $api_endpoint,
answer_language: $answer_language
}' > $config_file
fi
local key=$1
local value=$2
jq -r --arg key "$key" --arg value "$value" '.[$key] = $value' $config_file > tmp.$$.json && mv tmp.$$.json $config_file
}
install_plugin() {
local url=$1
local name=$(basename $url)
if [ ! -d "$config_dir/plugins" ]; then
mkdir -p $config_dir/plugins
fi
curl -s $url > $config_dir/plugins/$name
}
case $1 in
set-config)
set_config $2 $3
;;
get-config)
get_config $2
;;
install-plugin)
install_plugin $2
;;
-p|--plugin)
load_config
plugin=$config_dir/plugins/$2.sh
prompt=${@:3}
if [ -f "$plugin" ]; then
ask_with_plugin $plugin "$prompt"
else
echo "Plugin not found: $plugin"
fi
;;
*)
load_config
ask "$*"
;;
esac