aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbin/gpt/gpt120
1 files changed, 84 insertions, 36 deletions
diff --git a/bin/gpt/gpt b/bin/gpt/gpt
index cd312d6..4d0f651 100755
--- a/bin/gpt/gpt
+++ b/bin/gpt/gpt
@@ -3,11 +3,13 @@
3# TODO 3# TODO
4# - Use suggested block to wrap data: 4# - Use suggested block to wrap data:
5# https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api 5# https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api
6# - Add signal trap for API parameters (like stop) 6# - Print token usage when exit
7
8# User can dynamically change these options for API call
9configurable_options=( behavior temperature max_tokens )
7 10
8# If script is interupt by SIGINT, simply print leave message 11# If script is interupt by SIGINT, simply print leave message
9trap 'echo -e "\nChat Finished, cached file: $cache"; exit 0' INT 12trap _print_leave_message INT
10trap '_configure_completion' TSTP
11 13
12# Function for printing helper message 14# Function for printing helper message
13_print_helper_message() { 15_print_helper_message() {
@@ -40,22 +42,72 @@ Options:
40 -s|--skip Skip message, STDIN would be treated as your message 42 -s|--skip Skip message, STDIN would be treated as your message
41 43
42 * The other arguments would be treated as message content. 44 * The other arguments would be treated as message content.
43 If no message is specified, user should type it by hands. 45 If no message is specified, user should input content by hands.
44 If STDIN is given, it would be append to the end of message. 46 If STDIN is given, it would be append to the end of message.
45 47
48Special prompt:
49 Options If input starts with '.', then a prompt of options shows up.
50 User can modify option value for API calls.
51
46Reference: https://platform.openai.com/docs/api-reference/completions 52Reference: https://platform.openai.com/docs/api-reference/completions
47EOF 53EOF
48} 54}
49 55
50_configure_completion() { 56_print_leave_message(){
51 field="$( 57 echo -e "\nChat Finished, cached file: $cache"
52 dialog --form "Configure Completion" 10 50 3 \ 58 exit 0
53 --stdout \ 59}
54 'model:' 1 1 "$(eval 'echo $model')" 1 15 25 0 \ 60
55 'temperature:' 2 1 "$(eval 'echo $temperature')" 2 15 25 0 \ 61# A prompt for option configuration
56 'max_tokens:' 3 1 "$(eval 'echo $max_tokens')" 3 15 25 0 62_configure_options() {
57 )" 63 # Apply original trap action, and exit this prompt
58 64 trap 'trap _print_leave_message SIGINT; echo; return' INT
65 # Hint message
66 echo 'List of options: (Use Ctrl-C to exit)'
67
68 # Print all available options
69 index=0
70 for option in "${configurable_options[@]}"; do
71 echo -e "$index." "$option:\t" "$(eval "echo \$$option")"
72 (( index+=1 ))
73 done
74
75 # Prompt for user input
76 while true; do
77 echo
78 read -e -r -p "Modify which option? (0~$((index-1))) " selection
79 local field=${configurable_options[$selection]}
80 eval "read -e -r -p '$field: ' $field"
81 done
82}
83
84# Get latest content for completion
85_get_content() {
86
87 # Read data from STDIN
88 [ ! -t 0 ] && data="$(cat)"
89
90 if [ ! "$SKIP_INPUT" = true ] ; then
91 # Read content it from terminal
92 while true; do
93 read -e -r -p "Let's Chat: " content </dev/tty
94 [[ "$content" =~ ^\. ]] && echo && _configure_options && echo -e '\n------\n' && continue
95 [ -n "$content" ] && break
96 done
97 elif [[ "$count" -eq 0 && -z "$data" ]]; then
98 echo -e "No data from STDIN\n"
99 exit 1;
100 fi
101
102 # If it is the first round, append STDIN (If it exists) at the end
103 if [[ ! "$SKIP_INPUT" = true && -n "$data" ]] ; then
104 content="$(printf "%s\\n\\n%s" "$content" "$data")"
105 echo -e "\n$data"
106 # Or only use STDIN as content
107 elif [ -n "$data" ]; then
108 content="$data"
109 echo "$content"
110 fi
59} 111}
60 112
61# Check OPENAI API KEY"Department:" 3 1 "" 3 15 25 0 113# Check OPENAI API KEY"Department:" 3 1 "" 3 15 25 0
@@ -82,15 +134,20 @@ while [ "$#" -gt 0 ]; do
82 temperature="$2" 134 temperature="$2"
83 shift 2 135 shift 2
84 ;; 136 ;;
85 -m|--max_tokens) 137 -M|--max_tokens)
86 max_tokens="$2" 138 max_tokens="$2"
87 shift 2 139 shift 2
88 ;; 140 ;;
141 -s|--skip)
142 SKIP_INPUT=true
143 shift 1
144 ;;
89 -h|--help) 145 -h|--help)
90 _print_helper_message 146 _print_helper_message
91 exit 0 147 exit 0
92 ;; 148 ;;
93 *) 149 *)
150 SKIP_INPUT=true
94 content="$1" 151 content="$1"
95 shift 1 152 shift 1
96 ;; 153 ;;
@@ -105,30 +162,21 @@ temperature=${temperature:-0.7}
105max_tokens=${max_tokens:-2048} 162max_tokens=${max_tokens:-2048}
106 163
107# Prepare for chat session 164# Prepare for chat session
108cache=`mktemp` && touch $cache # && trap "rm $cache" EXIT 165cache=$(mktemp) && touch "$cache"
166#trap "rm $cache" EXIT
109session=() 167session=()
110count=0 168count=0
111 169
112# Use while to keep chat session 170# Use while to keep chat session
113while true; do 171while true; do
114 # Read prompt from terminal 172 _get_content
115 # If content is not specified by argumment, read it from terminal 173
116 [[ -z "$content" || $count >=1 ]] && read -e -r -p "Let's Chat: " content </dev/tty 174 # User must input by hands in the following rounds
117 # If no user input, simple print helper message and exit with code 1 175 SKIP_INPUT=false
118 [ -z "$content" ] && { echo -e "No message is given\n"; _print_helper_message; exit 1; }
119 # Read data from STDIN
120 [ ! -t 0 ] && data="$(cat)"
121 # Append data to the end of content
122 # And print it out
123 if [ -n "$data" ]; then
124 content="$(printf "%s\\n\\n%s" "$content" "$data")"
125 echo
126 echo "$data"
127 fi
128 176
129 # Put user message into session 177 # Put user message into session
130 user_message="$(cat <<EOF 178 user_message="$(cat <<EOF
131{"role": "user", "content": $(<<<"$content" jq -sR .)} 179{"role": "user", "content": $(printf '%s' "$content" | jq -sR .)}
132EOF 180EOF
133 )" 181 )"
134 session+=("$user_message") 182 session+=("$user_message")
@@ -139,8 +187,8 @@ EOF
139{ 187{
140 "model": "$model", 188 "model": "$model",
141 "messages": [ 189 "messages": [
142 {"role": "system", "content": $(echo $behavior | jq -sR .)}, 190 {"role": "system", "content": $(echo "$behavior" | jq -sR .)},
143 `IFS=',\n'; echo "${session[*]}"` 191 $(IFS=','; echo "${session[*]}")
144 ], 192 ],
145 "temperature": $temperature, 193 "temperature": $temperature,
146 "max_tokens": $max_tokens 194 "max_tokens": $max_tokens
@@ -148,7 +196,7 @@ EOF
148EOF 196EOF
149 )" 197 )"
150 # Append request body into cache 198 # Append request body into cache
151 echo "$body" >>$cache 199 echo "$body" >>"$cache"
152 200
153 # Add an empty line between prompt and response 201 # Add an empty line between prompt and response
154 echo -e '\n------\n' 202 echo -e '\n------\n'
@@ -156,15 +204,15 @@ EOF
156 # API call 204 # API call
157 # Save original response into cache file 205 # Save original response into cache file
158 # And only print content of message 206 # And only print content of message
159 response="` 207 response="$(
160 curl https://api.openai.com/$ROUTE \ 208 curl https://api.openai.com/$ROUTE \
161 --silent \ 209 --silent \
162 -H "Content-Type: application/json" \ 210 -H "Content-Type: application/json" \
163 -H "Authorization: Bearer $OPENAI_API_KEY" \ 211 -H "Authorization: Bearer $OPENAI_API_KEY" \
164 -d "$body" | \ 212 -d "$body" | \
165 jq . | tee -a $cache | \ 213 jq . | tee -a "$cache" | \
166 jq -r .choices[0].message.content 214 jq -r .choices[0].message.content
167 `" 215 )"
168 echo -e "${response}\n\n------\n" 216 echo -e "${response}\n\n------\n"
169 217
170 # Append newest message into session 218 # Append newest message into session