diff --git a/setup.ps1 b/setup.ps1 index 45b354e1..5da9d233 100644 --- a/setup.ps1 +++ b/setup.ps1 @@ -286,6 +286,301 @@ function Prompt-OllamaOptions { $script:ollama_choice = Read-Host "Choose option (1-2, or b)" } +# ======================== +# Advanced Settings Functions +# ======================== + +# Vector Store configuration +function Configure-VectorStore { + Write-Host "" + Write-ColorText "Vector Store Configuration" -ForegroundColor "White" -Bold + Write-ColorText "Choose your vector store:" -ForegroundColor "White" + Write-ColorText "1) FAISS (default, local)" -ForegroundColor "Yellow" + Write-ColorText "2) Elasticsearch" -ForegroundColor "Yellow" + Write-ColorText "3) Qdrant" -ForegroundColor "Yellow" + Write-ColorText "4) Milvus" -ForegroundColor "Yellow" + Write-ColorText "5) LanceDB" -ForegroundColor "Yellow" + Write-ColorText "6) PGVector" -ForegroundColor "Yellow" + Write-ColorText "b) Back" -ForegroundColor "Yellow" + Write-Host "" + $vs_choice = Read-Host "Choose option (1-6, or b)" + + switch ($vs_choice) { + "1" { + "VECTOR_STORE=faiss" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Vector store set to FAISS." -ForegroundColor "Green" + } + "2" { + "VECTOR_STORE=elasticsearch" | Add-Content -Path $ENV_FILE -Encoding utf8 + $elastic_url = Read-Host "Enter Elasticsearch URL (e.g. http://localhost:9200)" + if ($elastic_url) { "ELASTIC_URL=$elastic_url" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $elastic_cloud_id = Read-Host "Enter Elasticsearch Cloud ID (leave empty if using URL)" + if ($elastic_cloud_id) { "ELASTIC_CLOUD_ID=$elastic_cloud_id" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $elastic_user = Read-Host "Enter Elasticsearch username (leave empty if none)" + if ($elastic_user) { "ELASTIC_USERNAME=$elastic_user" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $elastic_pass = Read-Host "Enter Elasticsearch password (leave empty if none)" + if ($elastic_pass) { "ELASTIC_PASSWORD=$elastic_pass" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $elastic_index = Read-Host "Enter Elasticsearch index name (default: docsgpt)" + if ([string]::IsNullOrEmpty($elastic_index)) { $elastic_index = "docsgpt" } + "ELASTIC_INDEX=$elastic_index" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Vector store set to Elasticsearch." -ForegroundColor "Green" + } + "3" { + "VECTOR_STORE=qdrant" | Add-Content -Path $ENV_FILE -Encoding utf8 + $qdrant_url = Read-Host "Enter Qdrant URL (e.g. http://localhost:6333)" + if ($qdrant_url) { "QDRANT_URL=$qdrant_url" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $qdrant_key = Read-Host "Enter Qdrant API key (leave empty if none)" + if ($qdrant_key) { "QDRANT_API_KEY=$qdrant_key" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $qdrant_collection = Read-Host "Enter Qdrant collection name (default: docsgpt)" + if ([string]::IsNullOrEmpty($qdrant_collection)) { $qdrant_collection = "docsgpt" } + "QDRANT_COLLECTION_NAME=$qdrant_collection" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Vector store set to Qdrant." -ForegroundColor "Green" + } + "4" { + "VECTOR_STORE=milvus" | Add-Content -Path $ENV_FILE -Encoding utf8 + $milvus_uri = Read-Host "Enter Milvus URI (default: ./milvus_local.db)" + if ([string]::IsNullOrEmpty($milvus_uri)) { $milvus_uri = "./milvus_local.db" } + "MILVUS_URI=$milvus_uri" | Add-Content -Path $ENV_FILE -Encoding utf8 + $milvus_token = Read-Host "Enter Milvus token (leave empty if none)" + if ($milvus_token) { "MILVUS_TOKEN=$milvus_token" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $milvus_collection = Read-Host "Enter Milvus collection name (default: docsgpt)" + if ([string]::IsNullOrEmpty($milvus_collection)) { $milvus_collection = "docsgpt" } + "MILVUS_COLLECTION_NAME=$milvus_collection" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Vector store set to Milvus." -ForegroundColor "Green" + } + "5" { + "VECTOR_STORE=lancedb" | Add-Content -Path $ENV_FILE -Encoding utf8 + $lancedb_path = Read-Host "Enter LanceDB path (default: ./data/lancedb)" + if ([string]::IsNullOrEmpty($lancedb_path)) { $lancedb_path = "./data/lancedb" } + "LANCEDB_PATH=$lancedb_path" | Add-Content -Path $ENV_FILE -Encoding utf8 + $lancedb_table = Read-Host "Enter LanceDB table name (default: docsgpts)" + if ([string]::IsNullOrEmpty($lancedb_table)) { $lancedb_table = "docsgpts" } + "LANCEDB_TABLE_NAME=$lancedb_table" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Vector store set to LanceDB." -ForegroundColor "Green" + } + "6" { + "VECTOR_STORE=pgvector" | Add-Content -Path $ENV_FILE -Encoding utf8 + $pgvector_conn = Read-Host "Enter PGVector connection string (e.g. postgresql://user:pass@host:5432/db)" + if ($pgvector_conn) { "PGVECTOR_CONNECTION_STRING=$pgvector_conn" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "Vector store set to PGVector." -ForegroundColor "Green" + } + {$_ -eq "b" -or $_ -eq "B"} { return } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } +} + +# Embeddings configuration +function Configure-Embeddings { + Write-Host "" + Write-ColorText "Embeddings Configuration" -ForegroundColor "White" -Bold + Write-ColorText "Choose your embeddings provider:" -ForegroundColor "White" + Write-ColorText "1) HuggingFace (default, local)" -ForegroundColor "Yellow" + Write-ColorText "2) OpenAI Embeddings" -ForegroundColor "Yellow" + Write-ColorText "3) Custom Remote Embeddings (OpenAI-compatible API)" -ForegroundColor "Yellow" + Write-ColorText "b) Back" -ForegroundColor "Yellow" + Write-Host "" + $emb_choice = Read-Host "Choose option (1-3, or b)" + + switch ($emb_choice) { + "1" { + "EMBEDDINGS_NAME=huggingface_sentence-transformers/all-mpnet-base-v2" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Embeddings set to HuggingFace (local)." -ForegroundColor "Green" + } + "2" { + "EMBEDDINGS_NAME=openai_text-embedding-ada-002" | Add-Content -Path $ENV_FILE -Encoding utf8 + $emb_key = Read-Host "Enter Embeddings API key (leave empty to reuse LLM API_KEY)" + if ($emb_key) { "EMBEDDINGS_KEY=$emb_key" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "Embeddings set to OpenAI." -ForegroundColor "Green" + } + "3" { + $emb_name = Read-Host "Enter embeddings model name" + if ($emb_name) { "EMBEDDINGS_NAME=$emb_name" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $emb_url = Read-Host "Enter remote embeddings API base URL" + if ($emb_url) { "EMBEDDINGS_BASE_URL=$emb_url" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $emb_key = Read-Host "Enter embeddings API key (leave empty if none)" + if ($emb_key) { "EMBEDDINGS_KEY=$emb_key" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "Custom remote embeddings configured." -ForegroundColor "Green" + } + {$_ -eq "b" -or $_ -eq "B"} { return } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } +} + +# Authentication configuration +function Configure-Auth { + Write-Host "" + Write-ColorText "Authentication Configuration" -ForegroundColor "White" -Bold + Write-ColorText "Choose authentication type:" -ForegroundColor "White" + Write-ColorText "1) None (default, no authentication)" -ForegroundColor "Yellow" + Write-ColorText "2) Simple JWT" -ForegroundColor "Yellow" + Write-ColorText "3) Session JWT" -ForegroundColor "Yellow" + Write-ColorText "b) Back" -ForegroundColor "Yellow" + Write-Host "" + $auth_choice = Read-Host "Choose option (1-3, or b)" + + switch ($auth_choice) { + "1" { + Write-ColorText "Authentication disabled (default)." -ForegroundColor "Green" + } + "2" { + "AUTH_TYPE=simple_jwt" | Add-Content -Path $ENV_FILE -Encoding utf8 + $jwt_key = Read-Host "Enter JWT secret key (leave empty to auto-generate)" + if ([string]::IsNullOrEmpty($jwt_key)) { + $bytes = New-Object byte[] 32 + [System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes) + $jwt_key = [System.BitConverter]::ToString($bytes).Replace("-", "").ToLower() + Write-ColorText "Auto-generated JWT secret key." -ForegroundColor "Yellow" + } + "JWT_SECRET_KEY=$jwt_key" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Authentication set to Simple JWT." -ForegroundColor "Green" + } + "3" { + "AUTH_TYPE=session_jwt" | Add-Content -Path $ENV_FILE -Encoding utf8 + $jwt_key = Read-Host "Enter JWT secret key (leave empty to auto-generate)" + if ([string]::IsNullOrEmpty($jwt_key)) { + $bytes = New-Object byte[] 32 + [System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes) + $jwt_key = [System.BitConverter]::ToString($bytes).Replace("-", "").ToLower() + Write-ColorText "Auto-generated JWT secret key." -ForegroundColor "Yellow" + } + "JWT_SECRET_KEY=$jwt_key" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Authentication set to Session JWT." -ForegroundColor "Green" + } + {$_ -eq "b" -or $_ -eq "B"} { return } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } +} + +# Integrations configuration +function Configure-Integrations { + Write-Host "" + Write-ColorText "Integrations Configuration" -ForegroundColor "White" -Bold + Write-ColorText "1) Google Drive" -ForegroundColor "Yellow" + Write-ColorText "2) GitHub" -ForegroundColor "Yellow" + Write-ColorText "b) Back" -ForegroundColor "Yellow" + Write-Host "" + $int_choice = Read-Host "Choose option (1-2, or b)" + + switch ($int_choice) { + "1" { + $google_id = Read-Host "Enter Google OAuth Client ID" + if ($google_id) { "GOOGLE_CLIENT_ID=$google_id" | Add-Content -Path $ENV_FILE -Encoding utf8 } + $google_secret = Read-Host "Enter Google OAuth Client Secret" + if ($google_secret) { "GOOGLE_CLIENT_SECRET=$google_secret" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "Google Drive integration configured." -ForegroundColor "Green" + } + "2" { + $github_token = Read-Host "Enter GitHub Personal Access Token (with repo read access)" + if ($github_token) { "GITHUB_ACCESS_TOKEN=$github_token" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "GitHub integration configured." -ForegroundColor "Green" + } + {$_ -eq "b" -or $_ -eq "B"} { return } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } +} + +# Document Processing configuration +function Configure-DocProcessing { + Write-Host "" + Write-ColorText "Document Processing Configuration" -ForegroundColor "White" -Bold + $pdf_image = Read-Host "Parse PDF pages as images for better table/chart extraction? (y/N)" + if ($pdf_image -eq "y" -or $pdf_image -eq "Y") { + "PARSE_PDF_AS_IMAGE=true" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "PDF-as-image parsing enabled." -ForegroundColor "Green" + } + + $ocr_enabled = Read-Host "Enable OCR for document processing (Docling)? (y/N)" + if ($ocr_enabled -eq "y" -or $ocr_enabled -eq "Y") { + "DOCLING_OCR_ENABLED=true" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "Docling OCR enabled." -ForegroundColor "Green" + } +} + +# Text-to-Speech configuration +function Configure-TTS { + Write-Host "" + Write-ColorText "Text-to-Speech Configuration" -ForegroundColor "White" -Bold + Write-ColorText "Choose TTS provider:" -ForegroundColor "White" + Write-ColorText "1) Google TTS (default, free)" -ForegroundColor "Yellow" + Write-ColorText "2) ElevenLabs" -ForegroundColor "Yellow" + Write-ColorText "b) Back" -ForegroundColor "Yellow" + Write-Host "" + $tts_choice = Read-Host "Choose option (1-2, or b)" + + switch ($tts_choice) { + "1" { + "TTS_PROVIDER=google_tts" | Add-Content -Path $ENV_FILE -Encoding utf8 + Write-ColorText "TTS set to Google TTS." -ForegroundColor "Green" + } + "2" { + "TTS_PROVIDER=elevenlabs" | Add-Content -Path $ENV_FILE -Encoding utf8 + $elevenlabs_key = Read-Host "Enter ElevenLabs API key" + if ($elevenlabs_key) { "ELEVENLABS_API_KEY=$elevenlabs_key" | Add-Content -Path $ENV_FILE -Encoding utf8 } + Write-ColorText "TTS set to ElevenLabs." -ForegroundColor "Green" + } + {$_ -eq "b" -or $_ -eq "B"} { return } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } +} + +# Main advanced settings menu +function Prompt-AdvancedSettings { + Write-Host "" + $configure_advanced = Read-Host "Would you like to configure advanced settings? (y/N)" + if ($configure_advanced -ne "y" -and $configure_advanced -ne "Y") { + return + } + + while ($true) { + Write-Host "" + Write-ColorText "Advanced Settings" -ForegroundColor "White" -Bold + Write-ColorText "1) Vector Store (default: faiss)" -ForegroundColor "Yellow" + Write-ColorText "2) Embeddings (default: HuggingFace local)" -ForegroundColor "Yellow" + Write-ColorText "3) Authentication (default: none)" -ForegroundColor "Yellow" + Write-ColorText "4) Integrations (Google Drive, GitHub)" -ForegroundColor "Yellow" + Write-ColorText "5) Document Processing (PDF as image, OCR)" -ForegroundColor "Yellow" + Write-ColorText "6) Text-to-Speech (default: Google TTS)" -ForegroundColor "Yellow" + Write-ColorText "s) Save and Continue with Docker setup" -ForegroundColor "Yellow" + Write-Host "" + $adv_choice = Read-Host "Choose option (1-6, or s)" + + switch ($adv_choice) { + "1" { Configure-VectorStore } + "2" { Configure-Embeddings } + "3" { Configure-Auth } + "4" { Configure-Integrations } + "5" { Configure-DocProcessing } + "6" { Configure-TTS } + {$_ -eq "s" -or $_ -eq "S"} { break } + default { + Write-Host "" + Write-ColorText "Invalid choice." -ForegroundColor "Red" + Start-Sleep -Seconds 1 + } + } + } +} + # 1) Use DocsGPT Public API Endpoint (simple and free) function Use-DocsPublicAPIEndpoint { Write-Host "" @@ -297,6 +592,8 @@ function Use-DocsPublicAPIEndpoint { Write-ColorText ".env file configured for DocsGPT Public API." -ForegroundColor "Green" + Prompt-AdvancedSettings + # Start Docker if needed $dockerRunning = Check-AndStartDocker if (-not $dockerRunning) { @@ -369,6 +666,7 @@ function Serve-LocalOllama { break } elseif ($confirm_gpu -eq "b" -or $confirm_gpu -eq "B") { + $script:ollama_choice = "b" Clear-Host return } @@ -406,6 +704,8 @@ function Serve-LocalOllama { Write-ColorText ".env file configured for Ollama ($($docker_compose_file_suffix.ToUpper()))." -ForegroundColor "Green" Write-ColorText "Note: MODEL_NAME is set to '$model_name'. You can change it later in the .env file." -ForegroundColor "Yellow" + Prompt-AdvancedSettings + # Start Docker if needed $dockerRunning = Check-AndStartDocker if (-not $dockerRunning) { @@ -569,6 +869,8 @@ function Connect-LocalInferenceEngine { Write-ColorText ".env file configured for $engine_name with OpenAI API format." -ForegroundColor "Green" Write-ColorText "Note: MODEL_NAME is set to '$model_name'. You can change it later in the .env file." -ForegroundColor "Yellow" + Prompt-AdvancedSettings + # Start Docker if needed $dockerRunning = Check-AndStartDocker if (-not $dockerRunning) { @@ -665,6 +967,12 @@ function Connect-CloudAPIProvider { $script:llm_name = "azure_openai" $script:model_name = "gpt-4o" Get-APIKey + Write-Host "" + Write-ColorText "Azure OpenAI requires additional configuration:" -ForegroundColor "White" -Bold + $script:azure_api_base = Read-Host "Enter Azure OpenAI API base URL (e.g. https://your-resource.openai.azure.com/)" + $script:azure_api_version = Read-Host "Enter Azure OpenAI API version (e.g. 2024-02-15-preview)" + $script:azure_deployment = Read-Host "Enter Azure deployment name for chat" + $script:azure_emb_deployment = Read-Host "Enter Azure deployment name for embeddings (leave empty to skip)" break } "7" { # Novita @@ -696,9 +1004,19 @@ function Connect-CloudAPIProvider { "LLM_PROVIDER=$llm_name" | Add-Content -Path $ENV_FILE -Encoding utf8 "LLM_NAME=$model_name" | Add-Content -Path $ENV_FILE -Encoding utf8 "VITE_API_STREAMING=true" | Add-Content -Path $ENV_FILE -Encoding utf8 - + + # Azure OpenAI additional settings + if ($llm_name -eq "azure_openai") { + if ($azure_api_base) { "OPENAI_API_BASE=$azure_api_base" | Add-Content -Path $ENV_FILE -Encoding utf8 } + if ($azure_api_version) { "OPENAI_API_VERSION=$azure_api_version" | Add-Content -Path $ENV_FILE -Encoding utf8 } + if ($azure_deployment) { "AZURE_DEPLOYMENT_NAME=$azure_deployment" | Add-Content -Path $ENV_FILE -Encoding utf8 } + if ($azure_emb_deployment) { "AZURE_EMBEDDINGS_DEPLOYMENT_NAME=$azure_emb_deployment" | Add-Content -Path $ENV_FILE -Encoding utf8 } + } + Write-ColorText ".env file configured for $provider_name." -ForegroundColor "Green" + Prompt-AdvancedSettings + # Start Docker if needed $dockerRunning = Check-AndStartDocker if (-not $dockerRunning) { @@ -709,15 +1027,15 @@ function Connect-CloudAPIProvider { try { Write-Host "" Write-ColorText "Starting Docker Compose..." -ForegroundColor "White" - + # Run Docker compose commands & docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" pull if ($LASTEXITCODE -ne 0) { throw "Docker compose pull failed with exit code $LASTEXITCODE" } - + & docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d - + Write-Host "" Write-ColorText "DocsGPT is now configured to use $provider_name on http://localhost:5173" -ForegroundColor "Green" Write-ColorText "You can stop the application by running: docker compose -f `"$COMPOSE_FILE`" down" -ForegroundColor "Yellow" @@ -734,6 +1052,23 @@ function Connect-CloudAPIProvider { # Main script execution Animate-Dino +# Check if .env file exists and is not empty +if ((Test-Path $ENV_FILE) -and ((Get-Item $ENV_FILE).Length -gt 0)) { + Write-Host "" + Write-ColorText "Warning: An existing .env file was found with the following settings:" -ForegroundColor "Yellow" -Bold + $envLines = Get-Content $ENV_FILE + $envLines | Select-Object -First 3 | ForEach-Object { Write-Host " $_" } + if ($envLines.Count -gt 3) { + Write-Host " ... and $($envLines.Count - 3) more lines" + } + Write-Host "" + $confirm_overwrite = Read-Host "Running setup will overwrite this file. Continue? (y/N)" + if ($confirm_overwrite -ne "y" -and $confirm_overwrite -ne "Y") { + Write-ColorText "Setup cancelled. Your .env file was not modified." -ForegroundColor "Green" + exit 0 + } +} + while ($true) { Clear-Host Prompt-MainMenu diff --git a/setup.sh b/setup.sh index 690400a7..807a1b37 100755 --- a/setup.sh +++ b/setup.sh @@ -9,9 +9,10 @@ NC='\033[0m' BOLD='\033[1m' # Base Compose file (relative to script location) -COMPOSE_FILE="$(dirname "$(readlink -f "$0")")/deployment/docker-compose-hub.yaml" -COMPOSE_FILE_LOCAL="$(dirname "$(readlink -f "$0")")/deployment/docker-compose.yaml" -ENV_FILE="$(dirname "$(readlink -f "$0")")/.env" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" +COMPOSE_FILE="${SCRIPT_DIR}/deployment/docker-compose-hub.yaml" +COMPOSE_FILE_LOCAL="${SCRIPT_DIR}/deployment/docker-compose.yaml" +ENV_FILE="${SCRIPT_DIR}/.env" # Animation function animate_dino() { @@ -155,7 +156,7 @@ prompt_cloud_api_provider_options() { echo -e "${YELLOW}7) Novita${NC}" echo -e "${YELLOW}b) Back to Main Menu${NC}" echo - read -p "$(echo -e "${DEFAULT_FG}Choose option (1-6, or b): ${NC}")" provider_choice + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-7, or b): ${NC}")" provider_choice } # Function to prompt for Ollama CPU/GPU options @@ -170,6 +171,264 @@ prompt_ollama_options() { read -p "$(echo -e "${DEFAULT_FG}Choose option (1-2, or b): ${NC}")" ollama_choice } +# ======================== +# Advanced Settings Functions +# ======================== + +# Vector Store configuration +configure_vector_store() { + echo -e "\n${DEFAULT_FG}${BOLD}Vector Store Configuration${NC}" + echo -e "${DEFAULT_FG}Choose your vector store:${NC}" + echo -e "${YELLOW}1) FAISS (default, local)${NC}" + echo -e "${YELLOW}2) Elasticsearch${NC}" + echo -e "${YELLOW}3) Qdrant${NC}" + echo -e "${YELLOW}4) Milvus${NC}" + echo -e "${YELLOW}5) LanceDB${NC}" + echo -e "${YELLOW}6) PGVector${NC}" + echo -e "${YELLOW}b) Back${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-6, or b): ${NC}")" vs_choice + + case "$vs_choice" in + 1) + echo "VECTOR_STORE=faiss" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to FAISS.${NC}" + ;; + 2) + echo "VECTOR_STORE=elasticsearch" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Elasticsearch URL (e.g. http://localhost:9200): ${NC}")" elastic_url + [ -n "$elastic_url" ] && echo "ELASTIC_URL=$elastic_url" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Elasticsearch Cloud ID (leave empty if using URL): ${NC}")" elastic_cloud_id + [ -n "$elastic_cloud_id" ] && echo "ELASTIC_CLOUD_ID=$elastic_cloud_id" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Elasticsearch username (leave empty if none): ${NC}")" elastic_user + [ -n "$elastic_user" ] && echo "ELASTIC_USERNAME=$elastic_user" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Elasticsearch password (leave empty if none): ${NC}")" elastic_pass + [ -n "$elastic_pass" ] && echo "ELASTIC_PASSWORD=$elastic_pass" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Elasticsearch index name (default: docsgpt): ${NC}")" elastic_index + echo "ELASTIC_INDEX=${elastic_index:-docsgpt}" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to Elasticsearch.${NC}" + ;; + 3) + echo "VECTOR_STORE=qdrant" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Qdrant URL (e.g. http://localhost:6333): ${NC}")" qdrant_url + [ -n "$qdrant_url" ] && echo "QDRANT_URL=$qdrant_url" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Qdrant API key (leave empty if none): ${NC}")" qdrant_key + [ -n "$qdrant_key" ] && echo "QDRANT_API_KEY=$qdrant_key" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Qdrant collection name (default: docsgpt): ${NC}")" qdrant_collection + echo "QDRANT_COLLECTION_NAME=${qdrant_collection:-docsgpt}" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to Qdrant.${NC}" + ;; + 4) + echo "VECTOR_STORE=milvus" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Milvus URI (default: ./milvus_local.db): ${NC}")" milvus_uri + echo "MILVUS_URI=${milvus_uri:-./milvus_local.db}" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Milvus token (leave empty if none): ${NC}")" milvus_token + [ -n "$milvus_token" ] && echo "MILVUS_TOKEN=$milvus_token" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Milvus collection name (default: docsgpt): ${NC}")" milvus_collection + echo "MILVUS_COLLECTION_NAME=${milvus_collection:-docsgpt}" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to Milvus.${NC}" + ;; + 5) + echo "VECTOR_STORE=lancedb" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter LanceDB path (default: ./data/lancedb): ${NC}")" lancedb_path + echo "LANCEDB_PATH=${lancedb_path:-./data/lancedb}" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter LanceDB table name (default: docsgpts): ${NC}")" lancedb_table + echo "LANCEDB_TABLE_NAME=${lancedb_table:-docsgpts}" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to LanceDB.${NC}" + ;; + 6) + echo "VECTOR_STORE=pgvector" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter PGVector connection string (e.g. postgresql://user:pass@host:5432/db): ${NC}")" pgvector_conn + [ -n "$pgvector_conn" ] && echo "PGVECTOR_CONNECTION_STRING=$pgvector_conn" >> "$ENV_FILE" + echo -e "${GREEN}Vector store set to PGVector.${NC}" + ;; + b|B) return ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac +} + +# Embeddings configuration +configure_embeddings() { + echo -e "\n${DEFAULT_FG}${BOLD}Embeddings Configuration${NC}" + echo -e "${DEFAULT_FG}Choose your embeddings provider:${NC}" + echo -e "${YELLOW}1) HuggingFace (default, local)${NC}" + echo -e "${YELLOW}2) OpenAI Embeddings${NC}" + echo -e "${YELLOW}3) Custom Remote Embeddings (OpenAI-compatible API)${NC}" + echo -e "${YELLOW}b) Back${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-3, or b): ${NC}")" emb_choice + + case "$emb_choice" in + 1) + echo "EMBEDDINGS_NAME=huggingface_sentence-transformers/all-mpnet-base-v2" >> "$ENV_FILE" + echo -e "${GREEN}Embeddings set to HuggingFace (local).${NC}" + ;; + 2) + echo "EMBEDDINGS_NAME=openai_text-embedding-ada-002" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Embeddings API key (leave empty to reuse LLM API_KEY): ${NC}")" emb_key + [ -n "$emb_key" ] && echo "EMBEDDINGS_KEY=$emb_key" >> "$ENV_FILE" + echo -e "${GREEN}Embeddings set to OpenAI.${NC}" + ;; + 3) + read -p "$(echo -e "${DEFAULT_FG}Enter embeddings model name: ${NC}")" emb_name + [ -n "$emb_name" ] && echo "EMBEDDINGS_NAME=$emb_name" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter remote embeddings API base URL: ${NC}")" emb_url + [ -n "$emb_url" ] && echo "EMBEDDINGS_BASE_URL=$emb_url" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter embeddings API key (leave empty if none): ${NC}")" emb_key + [ -n "$emb_key" ] && echo "EMBEDDINGS_KEY=$emb_key" >> "$ENV_FILE" + echo -e "${GREEN}Custom remote embeddings configured.${NC}" + ;; + b|B) return ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac +} + +# Authentication configuration +configure_auth() { + echo -e "\n${DEFAULT_FG}${BOLD}Authentication Configuration${NC}" + echo -e "${DEFAULT_FG}Choose authentication type:${NC}" + echo -e "${YELLOW}1) None (default, no authentication)${NC}" + echo -e "${YELLOW}2) Simple JWT${NC}" + echo -e "${YELLOW}3) Session JWT${NC}" + echo -e "${YELLOW}b) Back${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-3, or b): ${NC}")" auth_choice + + case "$auth_choice" in + 1) + echo -e "${GREEN}Authentication disabled (default).${NC}" + ;; + 2) + echo "AUTH_TYPE=simple_jwt" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter JWT secret key (leave empty to auto-generate): ${NC}")" jwt_key + if [ -n "$jwt_key" ]; then + echo "JWT_SECRET_KEY=$jwt_key" >> "$ENV_FILE" + else + generated_key=$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n') + echo "JWT_SECRET_KEY=$generated_key" >> "$ENV_FILE" + echo -e "${YELLOW}Auto-generated JWT secret key.${NC}" + fi + echo -e "${GREEN}Authentication set to Simple JWT.${NC}" + ;; + 3) + echo "AUTH_TYPE=session_jwt" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter JWT secret key (leave empty to auto-generate): ${NC}")" jwt_key + if [ -n "$jwt_key" ]; then + echo "JWT_SECRET_KEY=$jwt_key" >> "$ENV_FILE" + else + generated_key=$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n') + echo "JWT_SECRET_KEY=$generated_key" >> "$ENV_FILE" + echo -e "${YELLOW}Auto-generated JWT secret key.${NC}" + fi + echo -e "${GREEN}Authentication set to Session JWT.${NC}" + ;; + b|B) return ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac +} + +# Integrations configuration +configure_integrations() { + echo -e "\n${DEFAULT_FG}${BOLD}Integrations Configuration${NC}" + echo -e "${YELLOW}1) Google Drive${NC}" + echo -e "${YELLOW}2) GitHub${NC}" + echo -e "${YELLOW}b) Back${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-2, or b): ${NC}")" int_choice + + case "$int_choice" in + 1) + read -p "$(echo -e "${DEFAULT_FG}Enter Google OAuth Client ID: ${NC}")" google_id + [ -n "$google_id" ] && echo "GOOGLE_CLIENT_ID=$google_id" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter Google OAuth Client Secret: ${NC}")" google_secret + [ -n "$google_secret" ] && echo "GOOGLE_CLIENT_SECRET=$google_secret" >> "$ENV_FILE" + echo -e "${GREEN}Google Drive integration configured.${NC}" + ;; + 2) + read -p "$(echo -e "${DEFAULT_FG}Enter GitHub Personal Access Token (with repo read access): ${NC}")" github_token + [ -n "$github_token" ] && echo "GITHUB_ACCESS_TOKEN=$github_token" >> "$ENV_FILE" + echo -e "${GREEN}GitHub integration configured.${NC}" + ;; + b|B) return ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac +} + +# Document Processing configuration +configure_doc_processing() { + echo -e "\n${DEFAULT_FG}${BOLD}Document Processing Configuration${NC}" + read -p "$(echo -e "${DEFAULT_FG}Parse PDF pages as images for better table/chart extraction? (y/N): ${NC}")" pdf_image + if [[ "$pdf_image" =~ ^[yY]$ ]]; then + echo "PARSE_PDF_AS_IMAGE=true" >> "$ENV_FILE" + echo -e "${GREEN}PDF-as-image parsing enabled.${NC}" + fi + + read -p "$(echo -e "${DEFAULT_FG}Enable OCR for document processing (Docling)? (y/N): ${NC}")" ocr_enabled + if [[ "$ocr_enabled" =~ ^[yY]$ ]]; then + echo "DOCLING_OCR_ENABLED=true" >> "$ENV_FILE" + echo -e "${GREEN}Docling OCR enabled.${NC}" + fi +} + +# Text-to-Speech configuration +configure_tts() { + echo -e "\n${DEFAULT_FG}${BOLD}Text-to-Speech Configuration${NC}" + echo -e "${DEFAULT_FG}Choose TTS provider:${NC}" + echo -e "${YELLOW}1) Google TTS (default, free)${NC}" + echo -e "${YELLOW}2) ElevenLabs${NC}" + echo -e "${YELLOW}b) Back${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-2, or b): ${NC}")" tts_choice + + case "$tts_choice" in + 1) + echo "TTS_PROVIDER=google_tts" >> "$ENV_FILE" + echo -e "${GREEN}TTS set to Google TTS.${NC}" + ;; + 2) + echo "TTS_PROVIDER=elevenlabs" >> "$ENV_FILE" + read -p "$(echo -e "${DEFAULT_FG}Enter ElevenLabs API key: ${NC}")" elevenlabs_key + [ -n "$elevenlabs_key" ] && echo "ELEVENLABS_API_KEY=$elevenlabs_key" >> "$ENV_FILE" + echo -e "${GREEN}TTS set to ElevenLabs.${NC}" + ;; + b|B) return ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac +} + +# Main advanced settings menu +prompt_advanced_settings() { + echo + read -p "$(echo -e "${DEFAULT_FG}Would you like to configure advanced settings? (y/N): ${NC}")" configure_advanced + if [[ ! "$configure_advanced" =~ ^[yY]$ ]]; then + return + fi + + while true; do + echo -e "\n${DEFAULT_FG}${BOLD}Advanced Settings${NC}" + echo -e "${YELLOW}1) Vector Store ${NC}${DEFAULT_FG}(default: faiss)${NC}" + echo -e "${YELLOW}2) Embeddings ${NC}${DEFAULT_FG}(default: HuggingFace local)${NC}" + echo -e "${YELLOW}3) Authentication ${NC}${DEFAULT_FG}(default: none)${NC}" + echo -e "${YELLOW}4) Integrations ${NC}${DEFAULT_FG}(Google Drive, GitHub)${NC}" + echo -e "${YELLOW}5) Document Processing ${NC}${DEFAULT_FG}(PDF as image, OCR)${NC}" + echo -e "${YELLOW}6) Text-to-Speech ${NC}${DEFAULT_FG}(default: Google TTS)${NC}" + echo -e "${YELLOW}s) Save and Continue with Docker setup${NC}" + echo + read -p "$(echo -e "${DEFAULT_FG}Choose option (1-6, or s): ${NC}")" adv_choice + + case "$adv_choice" in + 1) configure_vector_store ;; + 2) configure_embeddings ;; + 3) configure_auth ;; + 4) configure_integrations ;; + 5) configure_doc_processing ;; + 6) configure_tts ;; + s|S) break ;; + *) echo -e "\n${RED}Invalid choice.${NC}" ; sleep 1 ;; + esac + done +} + # 1) Use DocsGPT Public API Endpoint (simple and free) use_docs_public_api_endpoint() { echo -e "\n${NC}Setting up DocsGPT Public API Endpoint...${NC}" @@ -177,6 +436,8 @@ use_docs_public_api_endpoint() { echo "VITE_API_STREAMING=true" >> "$ENV_FILE" echo -e "${GREEN}.env file configured for DocsGPT Public API.${NC}" + prompt_advanced_settings + check_and_start_docker echo -e "\n${NC}Starting Docker Compose...${NC}" @@ -229,11 +490,11 @@ serve_local_ollama() { docker_compose_file_suffix="gpu" get_model_name_ollama break ;; - b|B) clear; return ;; # Back to Main Menu + b|B) clear; return 1 ;; # Back to Main Menu *) echo -e "\n${RED}Invalid choice. Please choose y or b.${NC}" ; sleep 1 ;; esac ;; - b|B) clear; return ;; # Back to Main Menu + b|B) clear; return 1 ;; # Back to Main Menu *) echo -e "\n${RED}Invalid choice. Please choose 1-2, or b.${NC}" ; sleep 1 ;; esac done @@ -248,6 +509,7 @@ serve_local_ollama() { echo "EMBEDDINGS_NAME=huggingface_sentence-transformers/all-mpnet-base-v2" >> "$ENV_FILE" echo -e "${GREEN}.env file configured for Ollama ($(echo "$docker_compose_file_suffix" | tr '[:lower:]' '[:upper:]')${NC}${GREEN}).${NC}" + prompt_advanced_settings check_and_start_docker local compose_files=( @@ -346,7 +608,7 @@ connect_local_inference_engine() { openai_base_url="http://host.docker.internal:23333/v1" get_model_name break ;; - b|B) clear; return ;; # Back to Main Menu + b|B) clear; return 1 ;; # Back to Main Menu *) echo -e "\n${RED}Invalid choice. Please choose 1-8, or b.${NC}" ; sleep 1 ;; esac done @@ -361,6 +623,8 @@ connect_local_inference_engine() { echo -e "${GREEN}.env file configured for ${BOLD}${engine_name}${NC}${GREEN} with OpenAI API format.${NC}" echo -e "${YELLOW}Note: MODEL_NAME is set to '${BOLD}$model_name${NC}${YELLOW}'. You can change it later in the .env file.${NC}" + prompt_advanced_settings + check_and_start_docker echo -e "\n${NC}Starting Docker Compose...${NC}" @@ -431,6 +695,11 @@ connect_cloud_api_provider() { llm_provider="azure_openai" model_name="gpt-4o" get_api_key + echo -e "\n${DEFAULT_FG}${BOLD}Azure OpenAI requires additional configuration:${NC}" + read -p "$(echo -e "${DEFAULT_FG}Enter Azure OpenAI API base URL (e.g. https://your-resource.openai.azure.com/): ${NC}")" azure_api_base + read -p "$(echo -e "${DEFAULT_FG}Enter Azure OpenAI API version (e.g. 2024-02-15-preview): ${NC}")" azure_api_version + read -p "$(echo -e "${DEFAULT_FG}Enter Azure deployment name for chat: ${NC}")" azure_deployment + read -p "$(echo -e "${DEFAULT_FG}Enter Azure deployment name for embeddings (leave empty to skip): ${NC}")" azure_emb_deployment break ;; 7) # Novita provider_name="Novita" @@ -438,8 +707,8 @@ connect_cloud_api_provider() { model_name="deepseek/deepseek-r1" get_api_key break ;; - b|B) clear; return ;; # Clear screen and Back to Main Menu - *) echo -e "\n${RED}Invalid choice. Please choose 1-6, or b.${NC}" ; sleep 1 ;; + b|B) clear; return 1 ;; # Clear screen and Back to Main Menu + *) echo -e "\n${RED}Invalid choice. Please choose 1-7, or b.${NC}" ; sleep 1 ;; esac done @@ -448,8 +717,19 @@ connect_cloud_api_provider() { echo "LLM_PROVIDER=$llm_provider" >> "$ENV_FILE" echo "LLM_NAME=$model_name" >> "$ENV_FILE" echo "VITE_API_STREAMING=true" >> "$ENV_FILE" + + # Azure OpenAI additional settings + if [ "$llm_provider" = "azure_openai" ]; then + [ -n "$azure_api_base" ] && echo "OPENAI_API_BASE=$azure_api_base" >> "$ENV_FILE" + [ -n "$azure_api_version" ] && echo "OPENAI_API_VERSION=$azure_api_version" >> "$ENV_FILE" + [ -n "$azure_deployment" ] && echo "AZURE_DEPLOYMENT_NAME=$azure_deployment" >> "$ENV_FILE" + [ -n "$azure_emb_deployment" ] && echo "AZURE_EMBEDDINGS_DEPLOYMENT_NAME=$azure_emb_deployment" >> "$ENV_FILE" + fi + echo -e "${GREEN}.env file configured for ${BOLD}${provider_name}${NC}${GREEN}.${NC}" + prompt_advanced_settings + check_and_start_docker echo -e "\n${NC}Starting Docker Compose...${NC}" @@ -472,6 +752,21 @@ connect_cloud_api_provider() { # Main script execution animate_dino +# Check if .env file exists and is not empty +if [ -f "$ENV_FILE" ] && [ -s "$ENV_FILE" ]; then + echo -e "\n${YELLOW}${BOLD}Warning:${NC}${YELLOW} An existing .env file was found with the following settings:${NC}" + head -3 "$ENV_FILE" | while IFS= read -r line; do echo -e "${DEFAULT_FG} $line${NC}"; done + total_lines=$(wc -l < "$ENV_FILE") + if [ "$total_lines" -gt 3 ]; then + echo -e "${DEFAULT_FG} ... and $((total_lines - 3)) more lines${NC}" + fi + echo + read -p "$(echo -e "${YELLOW}Running setup will overwrite this file. Continue? (y/N): ${NC}")" confirm_overwrite + if [[ ! "$confirm_overwrite" =~ ^[yY]$ ]]; then + echo -e "${GREEN}Setup cancelled. Your .env file was not modified.${NC}" + exit 0 + fi +fi while true; do # Main menu loop clear # Clear screen before showing main menu again @@ -479,18 +774,15 @@ while true; do # Main menu loop case $main_choice in 1) # Use DocsGPT Public API Endpoint (Docker Hub images) - COMPOSE_FILE="$(dirname "$(readlink -f "$0")")/deployment/docker-compose-hub.yaml" + COMPOSE_FILE="${SCRIPT_DIR}/deployment/docker-compose-hub.yaml" use_docs_public_api_endpoint break ;; 2) # Serve Local (with Ollama) - serve_local_ollama - break ;; + serve_local_ollama && break ;; 3) # Connect Local Inference Engine - connect_local_inference_engine - break ;; + connect_local_inference_engine && break ;; 4) # Connect Cloud API Provider - connect_cloud_api_provider - break ;; + connect_cloud_api_provider && break ;; 5) # Advanced: Build images locally echo -e "\n${YELLOW}You have selected to build images locally. This is recommended for developers or if you want to test local changes.${NC}" COMPOSE_FILE="$COMPOSE_FILE_LOCAL"