From 710ba21435e2177a43f5a8fe67b8c74701c21449 Mon Sep 17 00:00:00 2001 From: Knut Magnus Aasrud Date: Wed, 24 May 2023 14:42:58 +0200 Subject: [PATCH] cool warmup, now here is a POSIX ChatGPT client --- shatgpt | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ wsh | 96 -------------------------------------------------------- 2 files changed, 97 insertions(+), 96 deletions(-) create mode 100755 shatgpt delete mode 100755 wsh diff --git a/shatgpt b/shatgpt new file mode 100755 index 0000000..7aca31a --- /dev/null +++ b/shatgpt @@ -0,0 +1,97 @@ +#!/usr/bin/env dash + +has() { + # check if a command exists + # $1 - cmd to check + cmd=$(command -v "$1") 2>/dev/null || return 1 + [ -x "$cmd" ] || return 1 +} + +clear_line() { + # clear the current line and place cursor at the beginning + printf '\r\033[K' +} + +spinner() { + # display a spinner animation + # $1 - message to display + spinner_chars="⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏" + while : + do + for char in $spinner_chars + do + clear_line + printf '%s %s' "$char" "$1" + sleep 0.05 + done + done +} + +make_body() { + # make a body to send to the openai chat api + # $1 - prompt + printf '%s\n' "{\"model\": \"gpt-3.5-turbo\", \"stream\": true, \"messages\": [{\"role\": \"user\", \"content\": \"$1\"}]}" +} + +get_field() { + # get a field from a json string by grepping + # $1 - json string + # $2 - field to grep + printf '%s\n' "$1" | grep -o "\"$2\":\"[^\"]*" | sed "s/\"$2\":\"//" +} + +process_event() { + # process each streaming event + delta=$(get_field "$1" content) + if [ -n "$delta" ]; then + printf '%b' "$delta" + fi +} + +stream_events() { + # do http request from a url + # $1 - url + # $2 - data + spinner "Establishing connection..." & + spinner_pid=$! + + if has curl; then + curl "$1" -d "$2" -s -N -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" | while IFS= read -r event; do + if kill $spinner_pid 2>/dev/null; then + clear_line + fi + process_event "$event" + done + else + printf '%s\n' "Error: curl not found" + exit 1 + fi +} + +cleanup() { + # cleanup function to be called on script termination + # Add any cleanup tasks here + kill $spinner_pid 2>/dev/null + printf '\n' + exit 0 +} + +trap cleanup INT TERM + +main() { + + stream_events "https://api.openai.com/v1/chat/completions" "$(make_body "$*")" + + cleanup + + # content=$(get_field "$response" content) + # + # kill "$spinner_pid" >/dev/null 2>&1 + # clear_line + # + # printf '%s\n' "$response" + # printf '\n%s\n' "$response" | json '"choices"' 0 '"message"' '"content"' + # printf '\n%s\n' "$response" | json '"choices"' 0 '"message"' '"content"' | trim_quotes | fold -sw 80 +} + +main "$*" diff --git a/wsh b/wsh deleted file mode 100755 index fc2e1dd..0000000 --- a/wsh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env sh - -has() { - # check if a command exists - # $1 - cmd to check - cmd=$(command -v "$1") 2>/dev/null || return 1 - [ -x "$cmd" ] || return 1 -} - -trim() { - # trim whitespace from the beginning and end of a string - # reads from stdin - read trim - trim=${trim#${trim%%[![:space:]]*}} - trim=${trim%${trim##*[![:space:]]}} - trim=${trim%$'\n'} - printf '%s\n' "$trim" -} - -bolden() { - # make a string bold - # reads from stdin - read bold - printf '\033[1m%s\033[0m\n' "$bold" -} - -urlencode() { - # url encode a string - # $1 - string to encode - while IFS= read -r c; - do - case "$c" in - [a-zA-Z0-9.~_-]) - printf "$c" - continue - ;; - esac - printf '%s' "$c" | od -An -tx1 | xargs printf "%%%s" - done < /dev/null; then - printf '%s\n' "$(curl -s "$1")" - else - printf '%s\n' "Error: wget or curl not found" - exit 1 - fi - -} - -grep_field() { - # grep a field from a json string - # $1 - json string - # $2 - field to grep - printf '%s\n' "$1" | grep -o "\"$2\":\"[^\"]*" | sed "s/\"$2\":\"//" -} - -main() { - case "$1" in - -h|--help|"") - printf '%s\n' "Usage: $0 " - exit 0 - ;; - esac - - url=$(make_url "$*") - data=$(fetch_data $url) - title=$(grep_field "$data" title) - summary=$(grep_field "$data" extract) - - if [ -z "$summary" ]; then - printf '%s\n' "No results found for \"$@\"" - exit 1 - fi - - printf '\n' - printf '%s\n' "$title" | bolden - printf '%b\n' "$summary" | trim | fold -sw 80 - printf '\n' -} - -main "$*" -- 2.45.2