diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2023-03-23 16:15:33 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2023-03-23 23:52:55 +0800 |
commit | 6f1a9650fbce4fccba88402d9fea19a23c0ad1b2 (patch) | |
tree | 75b36f43fb53e8b6dedf44b9dbddfad97a7ee836 | |
parent | b0e36772acb8b5e4f722a63255f4414bcb1385ba (diff) |
Updateconfigure
-rwxr-xr-x | bin/gpt/gpt | 120 |
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 | ||
9 | configurable_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 |
9 | trap 'echo -e "\nChat Finished, cached file: $cache"; exit 0' INT | 12 | trap _print_leave_message INT |
10 | trap '_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 | ||
48 | Special prompt: | ||
49 | Options If input starts with '.', then a prompt of options shows up. | ||
50 | User can modify option value for API calls. | ||
51 | |||
46 | Reference: https://platform.openai.com/docs/api-reference/completions | 52 | Reference: https://platform.openai.com/docs/api-reference/completions |
47 | EOF | 53 | EOF |
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} | |||
105 | max_tokens=${max_tokens:-2048} | 162 | max_tokens=${max_tokens:-2048} |
106 | 163 | ||
107 | # Prepare for chat session | 164 | # Prepare for chat session |
108 | cache=`mktemp` && touch $cache # && trap "rm $cache" EXIT | 165 | cache=$(mktemp) && touch "$cache" |
166 | #trap "rm $cache" EXIT | ||
109 | session=() | 167 | session=() |
110 | count=0 | 168 | count=0 |
111 | 169 | ||
112 | # Use while to keep chat session | 170 | # Use while to keep chat session |
113 | while true; do | 171 | while 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 .)} |
132 | EOF | 180 | EOF |
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 | |||
148 | EOF | 196 | EOF |
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 |