# ========================= # MENU CONFIGURATION # ========================= $options = @("Yes", "No") $selectedIndex = 0 $solarPath = "C:\solar" $header = @" ____ ___ _ _ ____ / ___| / _ \ | | / \ | _ \ \___ \ | | | | | | / _ \ | |_) | ___) | _ | |_| | _ | |___ _ / ___ \ _ | _ < _ |____/ (_) \___/ (_) |_____| (_) /_/ \_\ (_) |_| \_\ (_) "@ $subtitle = "Systematic Online or Local Analysis Robot" function Show-Menu { Clear-Host Write-Host $header -ForegroundColor Cyan Write-Host $subtitle -ForegroundColor Yellow Write-Host $tospp -ForegroundColor Gray Write-Host "`nUse arrow keys to select an option and press Enter:`n" $esc = [char]27 $link = "https://solar.creative-crafter.de/terms_of_services_and_privacy_policy/" $text = "Terms of Service and Privacy Policy" Write-Host "Before continuing, please review the $esc[36m$esc]8;;$link$esc\$text$esc]8;;$esc\$esc[0m." for ($i = 0; $i -lt $options.Length; $i++) { if ($i -eq $selectedIndex) { Write-Host "-> $($options[$i])" -ForegroundColor Green } else { Write-Host " $($options[$i])" } } } do { Show-Menu $key = [System.Console]::ReadKey($true) switch ($key.Key) { "UpArrow" { $selectedIndex-- if ($selectedIndex -lt 0) { $selectedIndex = $options.Length - 1 } } "DownArrow" { $selectedIndex++ if ($selectedIndex -ge $options.Length) { $selectedIndex = 0 } } } } until ($key.Key -eq "Enter") # ========================= # YES LOGIC # ========================= switch ($options[$selectedIndex]) { "Yes" { # Create solarPath folder if it doesn't exist if (-Not (Test-Path -Path $solarPath)) { New-Item -Path $solarPath -ItemType Directory | Out-Null Write-Host "Folder created at $solarPath" } else { Write-Host "Folder already exists at $solarPath" } Write-Host "Starting installation and environment setup..." -ForegroundColor Green Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/main.py" -OutFile "C:\solar\main.py" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/solar_local/skills.py" -OutFile "C:\solar\skills.py" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/requirements.txt" -OutFile "C:\solar\requirements.txt" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/accept.png" -OutFile "C:\solar\accept.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/decline.png" -OutFile "C:\solar\decline.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/beep.wav" -OutFile "C:\solar\beep.wav" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/discord_search.png" -OutFile "C:\solar\discord_search.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/insta1.png" -OutFile "C:\solar\insta1.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/insta2.png" -OutFile "C:\solar\insta2.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/insta3.png" -OutFile "C:\solar\insta3.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/search.png" -OutFile "C:\solar\search.png" Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Creative-Crafter/SOLAR/main/whatsapp.png" -OutFile "C:\solar\whatsapp.png" Invoke-WebRequest -Uri "https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip" -OutFile "C:\solar\vosk-model-small-en-us-0.15.zip" Expand-Archive -Path "C:\solar\vosk-model-small-en-us-0.15.zip" -DestinationPath "C:\solar\vosk-model-small-en-us-0.15_for_deleting" -Force Copy-Item -Path "C:\solar\vosk-model-small-en-us-0.15_for_deleting\vosk-model-small-en-us-0.15" -Destination "C:\solar\vosk-model-small-en-us-0.15" -Recurse -Force Remove-Item -Path "C:\solar\vosk-model-small-en-us-0.15_for_deleting" -Recurse -Force Remove-Item -Path "C:\solar\vosk-model-small-en-us-0.15.zip" -Recurse -Force Invoke-WebRequest -Uri "https://solar.creative-crafter.de/install-local.ps1" -OutFile "C:\solar\install-local.ps1" # Change directory to solarPath Set-Location -Path $solarPath # Create subfolders $subfolders = @("scripts", "data", "logs") foreach ($folder in $subfolders) { $fullPath = Join-Path $solarPath $folder if (-Not (Test-Path -Path $fullPath)) { New-Item -Path $fullPath -ItemType Directory | Out-Null Write-Host "Created subfolder: $fullPath" } } # ========================= # PYTHON INSTALL CONFIG # ========================= # ========================= # PYTHON CONFIG # ========================= $requiredVersion = "3.11.0" $installDir = "C:\Python311" $installerPath = "$env:TEMP\python-3.11.0-amd64.exe" $pythonUrl = "https://www.python.org/ftp/python/3.11.0/python-3.11.0-amd64.exe" $pythonExe = Join-Path $installDir "python.exe" # ========================= # PROJECT CONFIG # ========================= $venvName = ".venv" $projectPath = Get-Location $venvPath = Join-Path $projectPath $venvName $requirementsFile = Join-Path $projectPath "requirements.txt" # ========================= # CHECK PYTHON 3.11 INSTALL # ========================= function Test-Python311 { # check installed directory if (Test-Path $pythonExe) { $version = & $pythonExe --version 2>&1 if ($version -match $requiredVersion) { return $true } } # check via python launcher (works even if other versions exist) $pyLauncher = Get-Command py -ErrorAction SilentlyContinue if ($pyLauncher) { try { $version = py -3.11 --version 2>&1 if ($version -match "3\.11") { return $true } } catch {} } return $false } # ========================= # INSTALL PYTHON IF MISSING # ========================= if (Test-Python311) { Write-Output "Python $requiredVersion already installed." } else { Write-Output "Downloading Python $requiredVersion..." Invoke-WebRequest -Uri $pythonUrl -OutFile $installerPath Write-Output "Installing Python $requiredVersion to $installDir ..." Start-Process ` -FilePath $installerPath ` -ArgumentList "/quiet InstallAllUsers=1 PrependPath=0 TargetDir=$installDir Include_launcher=1" ` -Wait if (!(Test-Path $pythonExe)) { Write-Output "Python installation failed." exit 1 } $installedVersion = & $pythonExe --version Write-Output "Installed: $installedVersion" } # ========================= # CREATE VENV WITH PYTHON 3.11 # ========================= if (!(Test-Path $venvPath)) { Write-Output "Creating virtual environment using Python 3.11..." if (Test-Path $pythonExe) { & $pythonExe -m venv $venvPath } else { py -3.11 -m venv $venvPath } } else { Write-Output ".venv already exists." } # ========================= # ACTIVATE VENV # ========================= $activateScript = Join-Path $venvPath "Scripts\Activate.ps1" if (Test-Path $activateScript) { Write-Output "Activating .venv ..." & $activateScript } else { Write-Output "Activation script not found." exit 1 } # ========================= # INSTALL REQUIREMENTS # ========================= if (Test-Path $requirementsFile) { Write-Output "Installing dependencies..." & "$venvPath\Scripts\python.exe" -m pip install --upgrade pip & "$venvPath\Scripts\python.exe" -m pip install -r $requirementsFile } # ========================= # UPGRADE PIP AND INSTALL PACKAGES # ========================= Write-Output "Upgrading pip..." python -m pip install --upgrade pip foreach ($pkg in $packages) { Write-Output "Installing $pkg..." python -m pip install --upgrade $pkg } # ========================= # INSTALL REQUIREMENTS.TXT IF EXISTS # ========================= # ========================= # OLLAMA INSTALL CONFIG # ========================= $ollamaCommand = "ollama" function Test-OllamaInstalled { $cmd = Get-Command $ollamaCommand -ErrorAction SilentlyContinue return $cmd -ne $null } if (Test-OllamaInstalled) { Write-Output "Ollama is already installed." } else { Write-Output "Ollama is not installed. Installing now..." Invoke-RestMethod -Uri "https://ollama.com/install.ps1" | Invoke-Expression if (Test-OllamaInstalled) { Write-Output "Ollama installed successfully!" } else { Write-Output "Ollama installation failed. Please check for errors." } } # ========================= # CREATE MODELFILENAME FOR OLLAMA # ========================= $name = Read-Host "Please enter how you want to call S.O.L.A.R." do { $user_gender = Read-Host "Please enter if you want to be called Ma'am or Sir by the Assistant. (m for Ma'am and s for Sir)" # Convert input to lowercase to make it case-insensitive $user_gender = $user_gender.ToLower() if (($user_gender -ne "s") -and ($user_gender -ne "m")) { Write-Output "Invalid input, please try again." } } while (($user_gender -ne "s") -and ($user_gender -ne "m")) Write-Output "Thank you! Your preference has been noted." if ($user_gender -eq "s") { $user_gender = "Sir" } else { $user_gender = "Ma'am" } # ========================= # CREATE MODELFILENAME FOR OLLAMA # ========================= Write-Output "Now downloading The models. This may take a while." ollama pull llama3.2-vision:11b ollama pull Malicus7862/deepseekcoder-6.7b-jarvis-gguf:latest $fileName = "Modelfile" $content = @( "FROM llama3.2-vision:11b" @" SYSTEM """ You are $name, a concise, capable AI assistant for the user. Core behavior: - Be clear, intelligent, and direct. - Keep replies short unless the user asks for detail. - Address the user as "$user_gender" in normal conversational replies. - Use a confident, professional tone with subtle dry humor when it fits. - Give practical answers and anticipate the next useful step. - Do not add information the user did not ask for. - If a request is unsafe, illegal, or harmful, refuse briefly and offer a safer alternative. Command routing: - If the user's request matches one of the supported actions below, output only the command in the exact format shown. - Extract the required fields from natural language, even when the words are in a different order. - Do not explain the command. - Do not add greetings, commentary, Markdown, or extra text around a command. - Never write phrases like "Here is the command", "I can do that", or "Sir" before a command. - When outputting a command, the first character of your response must be "/". - If required information is missing, ask one short question that names the missing information. - If the user asks something that is not a supported action, answer normally using the core behavior rules. Supported command outputs: 1. Send a message Use this format: /send Message: ""; Name: ""; Platform: "" Rules: - Preserve the user's message meaning. - The recipient name is usually after words like "to", "for", or "contact". - The message is usually after words like "saying", "that says", "message", "text", or "tell them". - The platform is usually after words like "on", "using", or "via". - Treat names like "Bob", "Mom", "Sarah Miller", or "John from work" as valid recipient names. - Do not ask for a name if the user already gave a recipient. - Use only these platforms: discord, whatsapp, instagram. - If the user names another platform, reply: Sir, I can only send messages on Discord, WhatsApp, or Instagram. - If the message, recipient, or platform is missing, ask for the missing detail. Examples: - User: send a message on whatsapp to bob saying Hi, how are you Output: /send Message: "Hi, how are you"; Name: "bob"; Platform: "whatsapp" - User: tell Sarah on Discord I will be late Output: /send Message: "I will be late"; Name: "Sarah"; Platform: "discord" - User: send Hi Output: Sir, who should I send it to, and on which platform? 2. Get the current time Use this format: /time Rules: - Use /time when the user asks what time it is, asks for the current time, or asks a similar time question. - Also use /time for relative time questions, such as "what time is it in two hours", "what time will it be in 30 minutes", or "what time was it three hours ago". - Do not answer the time yourself. - Do not guess, calculate, or invent the current time. - The Python app will receive /time, fetch the real current time, and answer the user's original time question. - Output only /time. Examples: - User: what time is it Output: /time - User: tell me the current time Output: /time - User: what time is it in two hours Output: /time - User: what time will it be in 30 minutes Output: /time 3. Get the current date or day Use this format: /date Rules: - Use /date when the user asks what date or day it is, asks for today's date, or asks a similar date question. - Also use /date for relative date or day questions, such as "what day is it in 50 days", "what date will it be next week", "what day was it 10 days ago", or "what date is tomorrow". - Do not answer the date yourself. - Do not guess, calculate, or invent the current date. - The Python app will receive /date, fetch the real current date, and answer the user's original date question. - Output only /date. Examples: - User: what date is it Output: /date - User: what is today's date Output: /date - User: what day is it in 50 days Output: /date - User: what date will it be next week Output: /date - User: what date is tomorrow Output: /date 4. Write or generate code Use this format: /code "" Rules: - Rewrite vague wording into a clear, complete coding request. - Preserve the user's intent, language, framework, and constraints when provided. - Do not write the code inside this command. - Do not wrap the command in backticks, code fences, or Markdown. - The text inside quotes must be a request description, not the finished code. - For code requests, output only the /code command and nothing else. Examples: - User: program me a python script that outputs hello world Output: /code "write a Python script that prints Hello World" - User: make me a calculator in JavaScript Output: /code "write a JavaScript calculator" 5. Create a calendar event Use this format: /event name: ""; date-start: ""; time-start: ""; date-end: ""; time-end: "" Rules: - If the event lasts multiple days, set date-end to the final date. - If the event is on one day, set date-end to the same value as date-start. - If the user gives no end time, calculate time-end as exactly one hour after time-start. - Never set time-end equal to time-start unless the user explicitly says the event ends at the same time. - Convert dates to ISO format: YYYY-MM-DD. - Convert times to 24-hour format: HH:MM. - If the event name, start date, or start time is missing, ask for the missing detail. Examples: - User: create a event for 25 of august 2027 named meeting with mom at 5 pm Output: /event name: "meeting with mom"; date-start: "2027-08-25"; time-start: "17:00"; date-end: "2027-08-25"; time-end: "18:00" - User: create an event on June 1 2027 at 9 named dentist Output: /event name: "dentist"; date-start: "2027-06-01"; time-start: "09:00"; date-end: "2027-06-01"; time-end: "10:00" - User: create an event called conference from June 3 2027 at 10 am to June 5 2027 at 4 pm Output: /event name: "conference"; date-start: "2027-06-03"; time-start: "10:00"; date-end: "2027-06-05"; time-end: "16:00" 6. Open an application or website Use this format: /open "" Rules: - Always put the application or website inside double quotes. - Do not output /open without quotes. Examples: - User: open chrome Output: /open "chrome" - User: open youtube.com Output: /open "youtube.com" """ "@ ) Set-Content -Path $fileName -Value $content Write-Output "Creating Ollama model..." ollama create Creative-Crafter/SOLAR-llama3.2-vision:11b --file Modelfile $fileName = "Modelfile2" $content = @( "FROM llama3.2-vision:11b" @" SYSTEM """ You are $name, a concise, capable AI assistant for the user. Core behavior: - Be clear, intelligent, and direct. - Keep replies short unless the user asks for detail. - Address the user as "$user_gender" in normal conversational replies. - Use a confident, professional tone with subtle dry humor when it fits. - Give practical answers and anticipate the next useful step. - Do not add information the user did not ask for. - If a request is unsafe, illegal, or harmful, refuse briefly and offer a safer alternative. Additional information about time and dates: Months: January = 31 days February = 28 days (29 days in leap years) March = 31 days April = 30 days May = 31 days June = 30 days July = 31 days August = 31 days September = 30 days October = 31 days November = 30 days December = 31 days Years: Normal year = 365 days Leap year = 366 days Leap years usually occur every 4 years Years divisible by 100 are not leap years unless they are also divisible by 400 Last leap year: 2024 Next leap year: 2028 Time units: 1 week = 7 days 1 day = 24 hours 1 hour = 60 minutes 1 minute = 60 seconds 1 second = 1000 milliseconds days of the week: 1 monday 2 tuesday 3 wednesday 4 thursday 5 friday 6 Saturday 7 Sunday You will get a question, inforamtions to that and you have to answer the question It will look something like this: The question: What time time is it in two hours. The information you have to that: the current time: 10:15 give me the answer to that make a full sentece but do not add additional information or your solution process """ "@ ) Set-Content -Path $fileName -Value $content Write-Output "Creating Ollama model..." ollama create Creative-Crafter/SOLAR-llama3.2-vision:11b2 --file Modelfile2 Write-Output "" Write-Output "All setup complete! Your environment, Ollama, and model are ready." do { $solar_gender = Read-Host "Please enter if you want the Assistant to be male or female. (m for male and f for female)" $solar_gender = $solar_gender.ToLower() if (($solar_gender -ne "m") -and ($solar_gender -ne "f")) { Write-Output "Invalid input, please try again." } } while (($solar_gender -ne "m") -and ($solar_gender -ne "f")) if ($solar_gender -eq "f") { $solar_gender = "af_sarah" } else { $solar_gender = "am_liam" } $user_name = Read-Host "Please enter your name." # Manually create YAML string $yaml_string = @" - name: $name gender: $solar_gender user_name: $user_name "@ # Write to file Set-Content -Path "config.yaml" -Value $yaml_string $commands = @" @echo off if "%1"=="launch" ( cd /d "C:\solar" call .venv\Scripts\activate.bat echo Starting Python file... python "%~dp0main.py" goto :eof ) if "%1"=="-config" ( cd /d "C:\solar" echo Starting configuration PowerShell... powershell -ExecutionPolicy Bypass -File "%~dp0install-local.ps1" goto :eof ) if "%1"=="-h" ( echo. echo Solar CLI Commands: echo. echo solar launch - Starts the Assistent echo solar -config - Starts the setup echo solar -h - Shows this help echo. goto :eof ) echo Unknown command. echo Type: solar -h for help "@ Set-Content -Path "solar.bat" -Value $commands # PATH auslesen und in Liste aufteilen $oldPath = [Environment]::GetEnvironmentVariable("Path", "User") $newPath = "$oldPath;C:\solar" [Environment]::SetEnvironmentVariable("Path", $newPath, "User") } "No" { Write-Host "OK, too bad" -ForegroundColor Red } }