1
0
Files
solar.creative-crafter.de/install-cloud.ps1
2026-05-31 12:42:38 +02:00

652 lines
21 KiB
PowerShell

# =========================
# 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_online/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 gemma3:27b-cloud
ollama pull qwen3-coder-next:cloud
$fileName = "Modelfile"
$content = @(
"FROM gemma3:27b-cloud"
@"
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: "<message the user wants to send>"; Name: "<recipient name>"; Platform: "<discord|whatsapp|instagram>"
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 "<clear description of the code the user wants>"
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: "<event name>"; date-start: "<start date>"; time-start: "<start time>"; date-end: "<end date>"; time-end: "<end time>"
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 "<application or website the user wants to 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-gemma3:27b-cloud --file Modelfile
$fileName = "Modelfile2"
$content = @(
"FROM gemma3:27b-cloud"
@"
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-gemma3:27b-cloud2 --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
}
}