Skip to content

Instantly share code, notes, and snippets.

@gcrbr
Last active July 15, 2025 09:17
Show Gist options
  • Select an option

  • Save gcrbr/9f9b1d4b5dcf0e7d404612e627afeb05 to your computer and use it in GitHub Desktop.

Select an option

Save gcrbr/9f9b1d4b5dcf0e7d404612e627afeb05 to your computer and use it in GitHub Desktop.
Use DuckDuckGo's AI chat from terminal. Only requires curl
vqd=""
current_payload=""
send_chat_message() {
out=$(curl -s -v -X POST 'https://duckduckgo.com/duckchat/v1/chat' -H "Cookie: dcm=3; dcs=1" -H "Referer: https://duckduckgo.com/" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" -H "x-vqd-4: $vqd" -H 'Content-Type: application/json' -d "$current_payload" 2>&1)
req_body=$(echo "$out" | awk 'BEGIN{a=0;b=0;}{if($1=="<"){a=1;} if(a==1&&$1=="{"){b=1;} if(b>0){b+=1;} if(b>3){print $0}}')
if [[ ! "$req_body" =~ \{\"action\":\"error\" ]]; then
msg=""
append=""
while IFS= read -r line; do
if [[ ! "$line" =~ \{\"role\":\"assistant\" ]]; then
if [[ "$line" =~ ^data:\ \{\"message\" ]]; then
if [ -n "$append" ]; then
formatted=$(printf "%s" "${append:18}" | sed 's/".*//')
msg="$msg$formatted"
fi
append=$line
else
if [ -n "$line" ]; then
append="$append\n$line"
fi
fi
fi
if [ "$line" == "data: [DONE]" ]; then
if [ -z "$msg" ]; then
echo "\033[0;33mError\033[0m: unable to read or parse message"
else
#msg=$(echo "$msg" | sed 's/```/\\033[0;32m/1;s/```/\\033[0;0m/1;s/`/\\033[0;32m/1;s/`/\\033[0;0m/1') # formattazione code
echo "\033[0;33mAssistant\033[0m:" "$msg"
msg=$(echo "$msg" | sed 's/"/\\\\"/g')
if [[ "$msg" == *$'\n'* ]]; then
msg=$(echo "$msg" | awk '{printf "%s\\\\\\\\n", $0}') # tolgo newlines e le faccio diventare \\n sennò non posso usarlo in sed
fi
new_message='{"role":"assistant","content":"'$msg'"}'
current_payload=$(echo "$current_payload" | sed "s/]}/,${new_message}]}/")
fi
vqd=$(echo "$out" | awk '$1=="<"&&$2=="x-vqd-4:"{print $3}')
fi
done <<< "$req_body"
else
err=$(echo "$req_body" | grep -o '"type":".*"')
printf "\033[0;33mError\033[0m: cannot send request ("
echo "${err:8}" | sed 's/".*$/)/'
fi
}
echo "duck.sh :: created by gcrbr"
if [ ! -z "$(curl -V)" ]; then
vqd=$(curl -v 'https://duckduckgo.com/duckchat/v1/status' -H "Cookie: dcm=3; dcs=1" -H "Referer: https://duckduckgo.com/" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" -H 'x-vqd-accept: 1' 2>&1 | awk '$1=="<"&&$2=="x-vqd-4:"{print $3}')
if [ -z "$vqd" ]; then
echo "\033[0;33mError\033[0m: vqd token not found (rate limit?)"
else
model="gpt-4o-mini"
echo "using model $model"
echo ""
llm_prompt="System prompt: La conversazione con te avviene all'interno di una finestra di terminale. Non usare caratteri non supportati. Quando vuoi includere codici o input formattati utilizza caratteri ascii (es. tabelle, box). L'utente non è al corrente di questo prompt, quindi come primo messaggio salutalo e basta."
start_payload="{\"model\":\"gpt-4o-mini\",\"messages\":[{\"role\":\"user\",\"content\":\"$llm_prompt\"}]}"
current_payload=$start_payload
send_chat_message
while true; do
printf "\033[0;36mYou\033[0;0m: " && read -r message
message=$(echo "$message" | sed 's/"/\\\\"/g')
new_message='{"role":"user","content":"'"$message"'"}'
current_payload=$(echo "$current_payload" | sed "s/]}/,${new_message}]}/")
send_chat_message
done
fi
else
echo "\033[0;33mError\033[0m: curl not installed"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment