commit - /dev/null
commit + 8bbe6e741770283f282481556cd5055f661eb6ec
blob - /dev/null
blob + dff830ba63eed496359c9284340f67fda4398791 (mode 755)
--- /dev/null
+++ dda.sh
+#!/bin/sh
+
+# Sources:
+# - https://blek.codes/blog/duckduckgo-ai-chat/
+# - https://github.com/mumu-lhl/duckduckgo-ai-chat/blob/main/index.ts
+
+query () {
+
+ # Query model. 1st argument is the question, 2nd is the vqd, 3rd is the model
+ curl -H "x-vqd-4: $2" \
+ -H "Content-Type: application/json" \
+ -H "User-Agent: $USER_AGENT" \
+ -i \
+ -s \
+ -d "{\"messages\": [{\"content\": \" $1 \", \"role\": \"user\"}], \
+ \"model\": \"$3\"}" \
+ -X POST "$URL/chat" > $RAW_RESPONSE
+}
+
+process () {
+
+ # Process answer
+ echo "[" >> $PROCESSED_RESPONSE
+ cat $RAW_RESPONSE | grep data: | sed -e 's/data: //' \
+ -e '$d' >> $PROCESSED_RESPONSE
+ sed -i -e '$! s/}/},/' $PROCESSED_RESPONSE
+ echo "]" >> $PROCESSED_RESPONSE
+ jq '.[] | .message' $PROCESSED_RESPONSE | tr -d '\n' | tr -d '"'
+ echo "\n"
+}
+
+help () {
+
+ echo "USAGE:"
+ echo "dda -m MODEL -v VQD -V \"PROMPT\""
+ echo "Models:"
+ echo " - mixtral"
+ echo " - claude"
+ echo " - gpt"
+ echo " - llama"
+ echo "-V : verbose mode"
+}
+
+main () {
+
+ RAW_RESPONSE=$(mktemp -t tmp.XXXXXXXXXX)
+ PROCESSED_RESPONSE=$(mktemp -t tmp.XXXXXXXXXX)
+ URL="https://duckduckgo.com/duckchat/v1"
+ USERAGENT="Mozilla/5.0 (Linux; Android 13; M2101K6G) AppleWebKit/537.36 \
+(KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36"
+
+ # Get initial vqd (this is a sort of API KEY)
+ VQD=$(curl -s \
+ -i \
+ -A "$USER_AGENT" \
+ --get \
+ --header "x-vqd-accept: 1" \
+ "$URL/status" | awk -F ": " '/x-vqd-4/ {print $2}')
+
+ # Get the options
+ while getopts "hm:v:V" option; do
+ case $option in
+ h) # display Help
+ help
+ exit;;
+ m) # Enter a name
+ MODEL=$OPTARG;;
+ v) # Enter VQD to pursue conversation
+ #TODO: cannot pursue conversation when passing last VQD
+ VQD=$OPTARG;;
+ V) # Verbose
+ VERBOSE=1;;
+ *) # Invalid option
+ echo "Error: Invalid option"
+ exit 1;;
+ esac
+ done
+
+ case $MODEL in
+ mixtral)
+ MODEL_NAME="mistralai/Mixtral-8x7B-Instruct-v0.1";;
+ claude)
+ MODEL_NAME="claude-3-haiku-20240307";;
+ llama)
+ MODEL_NAME="meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo";;
+ gpt)
+ MODEL_NAME="gpt-4o-mini";;
+ *)
+ echo "Error: model unknown"
+ exit 1;;
+ esac
+
+ if [ $# -gt 0 ]
+ then
+ eval PROMPT=\$$#
+ else
+ PROMPT="NULL"
+ help
+ exit
+ fi
+
+ query "$PROMPT" "$VQD" "$MODEL_NAME"
+ VQD=$(cat $RAW_RESPONSE | awk -F ": " '/x-vqd-4/ {print $2}')
+
+ if [[ $VERBOSE -eq 1 ]]
+ then
+ echo "\nProcess data"
+ echo "------------"
+ echo ""
+ echo "Raw response file : $RAW_RESPONSE"
+ echo "Processed response file : $PROCESSED_RESPONSE"
+ echo "VQD : $VQD"
+ echo "Model : $MODEL_NAME"
+ echo "\nQ : $PROMPT"
+ echo "A : $(process)"
+ echo "\n---\n"
+ else
+ process | sed -e 's/\\n/\
+/g'
+ fi
+
+}
+
+main "$@"