Skip to content

Commit

Permalink
feat: Update the provider configuration workflow in ai-gateway (higre…
Browse files Browse the repository at this point in the history
…ss-group#113)

and support more LLM providers
  • Loading branch information
CH3CHO authored Dec 18, 2024
1 parent bb38a22 commit f8cf408
Show file tree
Hide file tree
Showing 2 changed files with 391 additions and 56 deletions.
250 changes: 238 additions & 12 deletions all-in-one/get-ai-gateway.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ fi

DEFAULT_CONTAINER_NAME=higress
DEFAULT_IMAGE_REPO=higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/all-in-one
# DFEAULT_IMAGE_TAG=latest
DFEAULT_IMAGE_TAG=20241029
DFEAULT_IMAGE_TAG=latest
DEFAULT_GATEWAY_HTTP_PORT=8080
DEFAULT_GATEWAY_HTTPS_PORT=8443
DEFAULT_CONSOLE_PORT=8001
Expand All @@ -34,7 +33,8 @@ CONFIG_FILENAME="default.cfg"

COMMAND_START="start"
COMMAND_STOP="stop"
KNOWN_COMMANDS=($COMMAND_START, $COMMAND_STOP)
COMMAND_DELETE="delete"
KNOWN_COMMANDS=($COMMAND_START, $COMMAND_STOP, $COMMAND_DELETE)

cd "$(dirname -- "$0")"
ROOT="$(pwd -P)/higress"
Expand Down Expand Up @@ -132,6 +132,8 @@ resetEnv() {
GATEWAY_HTTP_PORT="$DEFAULT_GATEWAY_HTTP_PORT"
GATEWAY_HTTPS_PORT="$DEFAULT_GATEWAY_HTTPS_PORT"
CONSOLE_PORT="$DEFAULT_CONSOLE_PORT"

LLM_ENVS=()
}

runConfigWizard() {
Expand All @@ -140,13 +142,119 @@ runConfigWizard() {

echo

read -r -p "→ Enter API Key for OpenAI: " OPENAI_API_KEY
read -r -p "→ Enter API Key for Aliyun Dashscope: " DASHSCOPE_API_KEY
read -r -p "→ Enter API Key for Moonshot: " MOONSHOT_API_KEY
local providers=(
"OpenAI|OPENAI"
"Aliyun Dashscope|DASHSCOPE"
"Moonshot|MOONSHOT"
"Azure OpenAI|AZURE|configureAzureProvider"
"360 Zhinao|AI360"
"Github Models|GITHUB"
"Groq|GROQ"
"Baichuan AI|BAICHUAN"
"01.AI|YI"
"DeepSeek|DEEPSEEK"
"Zhipu AI|ZHIPUAI"
"Ollama|OLLAMA|configureOllamaProvider"
"Claude|CLAUDE|configureClaudeProvider"
"Baidu AI Cloud|BAIDU"
# "Tencent Hunyuan|HUNYUAN"
"Stepfun|STEPFUN"
"Minimax|MINIMAX|configureMinimaxProvider"
# "Cloudflare Workers AI|CLOUDFLARE"
# "iFlyTek Spark|SPARK"
"Google Gemini|GEMINI"
# "DeepL|DEEPL"
"Mistral AI|MISTRAL"
"Cohere|COHERE"
"Doubao|DOUBAO"
"Coze|COZE"
)

local selectedIndex=''
while :; do
declare -i i=0
for provider in "${providers[@]}"; do
IFS='|' read -ra segments <<<"$provider"
local providerName=${segments[0]}
local apiKeyVarName="${segments[1]}_API_KEY"
local apiKeyConfiguredMarkName="${segments[1]}_CONFIGURED"
local mark=""
if [ -n "${!apiKeyVarName}" -o -n "${!apiKeyConfiguredMarkName}" ]; then
mark="[Configured] "
fi
i+=1
echo "${i}. ${mark}${providerName}"
done
read -r -p "Please choose an LLM service provider to configure (1~$i, 0 to break): " selectedIndex

case $selectedIndex in
'' | *[!0-9]*) ;;
*)
selectedIndex=$((selectedIndex))
if [ $selectedIndex -eq 0 ]; then
break
elif [ $selectedIndex -gt $i ]; then
echo "Incorrect option number."
else
local provider=${providers[$selectedIndex - 1]}
IFS='|' read -ra segments <<<"$provider"
local providerName=${segments[0]}
local apiKeyVarName="${segments[1]}_API_KEY"
local customConfigFunction="${segments[2]}"

if [ -n "$customConfigFunction" ]; then
$customConfigFunction
else
local token=""
read -r -p "→ Enter API Key for ${providerName}: " token
IFS= read -r -d '' "${apiKeyVarName}" <<<"$token"
LLM_ENVS+=("${apiKeyVarName}")
fi
fi
;;
esac
done

echo
}

configureAzureProvider() {
for (( ; ; )); do
read -r -p "→ Enter Azure OpenAI service URL (Sample: https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/chat/completions?api-version=2024-06-01): " AZURE_SERVICE_URL
if [[ "$AZURE_SERVICE_URL" == "https://"* ]]; then
break
fi
echo 'URL must start with "https://"'
done
read -r -p "→ Enter API Key for Azure OpenAI: " AZURE_API_KEY
LLM_ENVS+=("AZURE_SERVICE_URL" "AZURE_API_KEY")
}

configureOllamaProvider() {
read -r -p "→ Enter Ollama server host: " OLLAMA_SERVER_HOST
readPortWithDefault "→ Enter Ollama server port (Default: 11434): " 11434
OLLAMA_SERVER_PORT="$input"
if [ -n "$OLLAMA_SERVER_HOST" ]; then
# Mark as configured
OLLAMA_CONFIGURED="placeholder"
fi
LLM_ENVS+=("OLLAMA_SERVER_HOST" "OLLAMA_SERVER_PORT")
}

configureClaudeProvider() {
read -r -p "→ Enter API Key for Claude: " CLAUDE_API_KEY
local DEFAULT_CLAUDE_VERSION="2023-06-01"
readWithDefault "→ Enter API version for Claude (Default: $DEFAULT_CLAUDE_VERSION): " $DEFAULT_CLAUDE_VERSION
CLAUDE_VERSION="$input"
LLM_ENVS+=("CLAUDE_API_KEY" "CLAUDE_VERSION")
}

configureMinimaxProvider() {
read -r -p "→ Enter API Key for Minimax: " MINIMAX_API_KEY
read -r -p "→ Enter group ID for Minimax (only required when using ChatCompletion Pro): " MINIMAX_GROUP_ID
LLM_ENVS+=("MINIMAX_API_KEY" "MINIMAX_GROUP_ID")
}

configureStorage() {
if [ -d "$DATA_FOLDER" ]; then
return 0
Expand All @@ -158,16 +266,69 @@ configureStorage() {
fi
}

readNonEmpty() {
# $1 prompt
while true; do
read -r -p "$1" input
if [ -n "$input" ]; then
break
fi
done
}

readWithDefault() {
# $1 prompt
# $2 default
read -r -p "$1" input
if [ -z "$input" ]; then
input="$2"
fi
}

readPortWithDefault() {
# $1 prompt
# $2 default
for (( ; ; )); do
read -r -p "$1" input
if [ -z "$input" ]; then
input="$2"
break
fi
validatePort "$input" "Invalid port number." 0
if [ $? -eq 0 ]; then
break
fi
done
}

validatePort() {
# $1 port
# $2 error message
# $3 exit when error if set to 1
if [[ $1 =~ ^[0-9]+$ ]] && [ $1 -gt 0 ] && [ $1 -lt 65536 ]; then
return 0
fi
echo "$2"
if [ $3 -eq 1 ]; then
exit -1
else
return -1
fi
}

writeConfiguration() {
local LLM_CONFIGS=""
for env in "${LLM_ENVS[@]}"; do
LLM_CONFIGS="$LLM_CONFIGS
${env}=${!env}"
done
cat <<EOF >$DATA_FOLDER/$CONFIG_FILENAME
MODE=full
CONFIG_TEMPLATE=ai-gateway
DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY}
MOONSHOT_API_KEY=${MOONSHOT_API_KEY}
OPENAI_API_KEY=${OPENAI_API_KEY}
GATEWAY_HTTP_PORT=${GATEWAY_HTTP_PORT}
GATEWAY_HTTPS_PORT=${GATEWAY_HTTPS_PORT}
CONSOLE_PORT=${CONSOLE_PORT}
${LLM_CONFIGS}
EOF
}

Expand All @@ -188,7 +349,7 @@ outputWelcomeMessage() {
\|__|\|__|\|__|\|_______|\|__|\|__|\|_______|\_________\\_________\
\|_________\|_________|
'
echo "Higress AI Gateway is started successfully."
echo "Higress AI Gateway is now running."

echo
echo "======================================================="
Expand All @@ -197,12 +358,13 @@ outputWelcomeMessage() {
echo
echo "Higress AI Gateway Data Plane endpoints:"
echo " HTTP = http://localhost:$GATEWAY_HTTP_PORT"
echo " HTTPS = https://localhost:$GATEWAY_HTTPS_PORT}"
echo " HTTPS = https://localhost:$GATEWAY_HTTPS_PORT"
echo
echo "Higress AI Gateway chat completion endpoint:"
echo " http://localhost:$GATEWAY_HTTP_PORT/v1/chat/completions"
echo
echo "You can try it with cURL directly:"
echo
echo " curl 'http://localhost:$GATEWAY_HTTP_PORT/v1/chat/completions' \\"
echo " -H 'Content-Type: application/json' \\"
echo " -d '{"
Expand Down Expand Up @@ -232,17 +394,38 @@ outputWelcomeMessage() {
echo "Happy Higressing!"
}

tryAwake() {
containerExists=$(docker ps -a --filter "name=^/${CONTAINER_NAME}$" --format "{{.Names}}")

if [ -z "$containerExists" ]; then
return
fi

containerRunning=$(docker ps --filter "name=^/${CONTAINER_NAME}$" --filter "status=running" --format "{{.Names}}")

if [ -z "$containerRunning" ]; then
docker start "$CONTAINER_NAME"
if [ $? -ne 0 ]; then
exit -1
fi
fi

outputWelcomeMessage
exit 0
}

start() {
echo "Starting Higress AI Gateway..."
echo

NORMALIZED_DATA_FOLDER_PATH="$(normalizePath "${DATA_FOLDER}")"
NORMALIZED_CONFIG_FILE_PATH="$(normalizePath "${DATA_FOLDER}/${CONFIG_FILENAME}")"

$DOCKER_COMMAND run --name higress -d --rm \
$DOCKER_COMMAND run --name "${CONTAINER_NAME}" -d \
-p 127.0.0.1:$GATEWAY_HTTP_PORT:8080 \
-p 127.0.0.1:$GATEWAY_HTTPS_PORT:8443 \
-p 127.0.0.1:$CONSOLE_PORT:8001 \
--restart=always \
--env-file "$NORMALIZED_CONFIG_FILE_PATH" \
--mount "type=bind,source=$NORMALIZED_DATA_FOLDER_PATH,target=/data" "$IMAGE_REPO:$IMAGE_TAG" >/dev/null

Expand All @@ -252,6 +435,20 @@ start() {
}

stop() {
containerExists=$(docker ps -a --filter "name=^/${CONTAINER_NAME}$" --format "{{.Names}}")

if [ -z "$containerExists" ]; then
echo "Higress AI Gateway not found."
exit -1
fi

containerRunning=$(docker ps --filter "name=^/${CONTAINER_NAME}$" --filter "status=running" --format "{{.Names}}")

if [ -z "$containerRunning" ]; then
echo "Higress AI Gateway isn't running."
exit 0
fi

echo "Stopping Higress AI Gateway..."
echo

Expand All @@ -262,11 +459,37 @@ stop() {
fi
}

delete() {
containerExists=$(docker ps -a --filter "name=^/${CONTAINER_NAME}$" --format "{{.Names}}")

if [ -z "$containerExists" ]; then
echo "Higress AI Gateway not found."
exit 0
fi

containerRunning=$(docker ps --filter "name=^/${CONTAINER_NAME}$" --filter "status=running" --format "{{.Names}}")

if [ -n "$containerRunning" ]; then
echo "Higress AI Gateway is still running. Please stop it first."
exit -1
fi

echo "Deleting Higress AI Gateway container..."
echo

$DOCKER_COMMAND rm $CONTAINER_NAME >/dev/null

if [ $? -eq 0 ]; then
echo "Thanks for using Higress AI Gateway."
fi
}

initArch
initOS
parseArgs "$@"
case $COMMAND in
"$COMMAND_START")
tryAwake
if [ ! -f "$CONFIGURED_MARK" ]; then
configure
touch "$CONFIGURED_MARK"
Expand All @@ -276,4 +499,7 @@ case $COMMAND in
"$COMMAND_STOP")
stop
;;
"$COMMAND_DELETE")
delete
;;
esac
Loading

0 comments on commit f8cf408

Please sign in to comment.