Skip to content

Instantly share code, notes, and snippets.

@ftk
Last active June 24, 2026 12:52
Show Gist options
  • Select an option

  • Save ftk/c2ea3d25530d035da4ecc5bbf9a5bf32 to your computer and use it in GitHub Desktop.

Select an option

Save ftk/c2ea3d25530d035da4ecc5bbf9a5bf32 to your computer and use it in GitHub Desktop.
Simple script to call OpenAI compatible endpoint with specified messages
#!/bin/bash
## Calls OpenAI v1 chat compatible endpoint with specified messages. Each passed argument is 1 message.
## Environment variables to set: OPENAI_API_KEY, optionally: OPENAI_API_BASE, OPENAI_MODEL, PROMPT, CURL_OPT
##
## Usage: ./llm.sh [-v] [-c] [-s "system prompt"] "message 1"...
## Example: ./llm.sh "count the number of lines in:" "$(cat file.txt)"
## --verbose|-v: debug the LLM call, prints input and output
## --continue|-c: continue conversation from /tmp/llm.prompt.json and /tmp/llm.response.json
set -euo pipefail
[[ $# -ge 1 && $1 == --help ]] && exec sed -n 's/^## //p' -- "$0"
[[ $# -ge 1 && ( $1 == --verbose || $1 == -v ) ]] && set -x && CURL_OPT="--trace-ascii /dev/stderr" && shift 1
[[ $# -ge 1 && ( $1 == --continue || $1 == -c ) ]] && CONTINUE=1 && shift 1
[[ -v OPENAI_API_KEY ]] || . .env
# check for system prompt
if [[ $# -ge 2 && ( $1 == -s || $1 == --system) ]]
then
PROMPT="$2"
shift 2
fi
if [[ -v PROMPT ]]
then
jq -n --arg model "${OPENAI_MODEL-gpt-5}" --arg system "$PROMPT" '{"model": $model, messages: [{role:"system", content: $system}, ($ARGS.positional.[] | {role:"user", content: .}) ]}' --args -- "$@"
elif [[ -v CONTINUE && -e /tmp/llm.prompt.json && -e /tmp/llm.response.json ]]
then
jq -n --slurpfile p /tmp/llm.prompt.json --slurpfile r /tmp/llm.response.json '$p[0] | .messages += ([{role:"assistant", content: ($r[0].choices[0].message.content // $r[0].error.message // $r[0].detail // "")}] + ($ARGS.positional | map({role:"user", content:.})))' --args -- "$@"
else
jq -n --arg model "${OPENAI_MODEL-gpt-5}" '{model: $model, messages: [$ARGS.positional.[]| {role:"user", content: .} ]}' --args -- "$@"
fi | \
tee /tmp/llm.prompt.json.part | \
curl --compressed --no-progress-meter -X POST --fail-with-body ${CURL_OPT-} --retry 3 \
"${OPENAI_BASE_URL-https://openai.com/v1}/chat/completions" \
-H @<(echo "Authorization: Bearer $OPENAI_API_KEY") \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d @- | \
tee /tmp/llm.response.json.part | \
jq -r '.choices[0].message.content // .error.message // .detail // .'
mv /tmp/llm.prompt.json{.part,}
mv /tmp/llm.response.json{.part,}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment