1
0
Files
solar.creative-crafter.de/install-local.ps1
2026-05-30 20:25:47 +02:00

528 lines
17 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_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 deepseek-v2:16b
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: "<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. Tell the time
Use this format:
/time
3. Tell the date
Use this format:
/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-llama3.2-vision:11b --file Modelfile
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
}
}