Spaces:
Runtime error
Runtime error
function ai { | |
<# | |
.SYNOPSIS | |
Red Team AI Terminal Assistant полностью inmemory реализация на PowerShell. | |
.DESCRIPTION | |
Скрипт собирает системную информацию, использует встроенную YAML-конфигурацию для формирования подсказок, | |
генерирует JSONpayload и обращается к Groq API (используя переменную OPENAI_API_KEY, имя не меняется). | |
Вся логика выполняется в памяти без доступа к диску подход Red Team для минимизации следов. | |
.PARAMETER InputCommand | |
Естественная языковая команда для преобразования в команду терминала. | |
.EXAMPLE | |
ai -InputCommand "организовать эти файлы семантически в текущем каталоге по дате" | |
#> | |
#region Системные функции | |
function Get-SystemInfo { | |
$osInfo = Get-CimInstance Win32_OperatingSystem | |
$osCaption = $osInfo.Caption | |
$osVersion = $osInfo.Version | |
$machine = $env:COMPUTERNAME | |
$processor = (Get-CimInstance Win32_Processor).Name | |
return "OS: $osCaption, Version: $osVersion, Machine: $machine, Processor: $processor" | |
} | |
function Get-WorkingDirectory { | |
return (Get-Location).Path | |
} | |
function Get-PackageManagers { | |
$pmList = @("choco", "scoop", "winget", "npm", "pip") | |
$installed = @() | |
foreach ($pm in $pmList) { | |
if (Get-Command $pm -ErrorAction SilentlyContinue) { | |
$installed += $pm | |
} | |
} | |
return $installed -join ", " | |
} | |
function Get-ShellVersion { | |
return $PSVersionTable.PSVersion.ToString() | |
} | |
#endregion | |
#region Функция замены плейсхолдеров в шаблоне | |
function Replace-Placeholders { | |
param( | |
[string]$Template, | |
[hashtable]$Values | |
) | |
foreach ($key in $Values.Keys) { | |
$Template = $Template -replace "\{$key\}", [regex]::Escape($Values[$key]) | |
} | |
return $Template | |
} | |
#endregion | |
#region Встроенная YAML-конфигурация (inmemory) | |
$PromptsYaml = @" | |
common: | |
messages: | |
- role: system | |
content: | | |
You're a {shell} terminal assistant, and your job is to translate natural language instructions to a single raw, executable {shell} command. | |
Это должна быть одна команда на одной строке или несколько команд, разбросанных по нескольким строкам (без сепараторов, таких как ; или &&). | |
Дайте краткое объяснение в {shell} комментариях перед командой. Используйте самую благоприятную версию команды. | |
Если вам нужно использовать команду, которая недоступна в системе, объясните в комментарии, что она делает, и предложите ее установить. | |
Если инструкция неясна, используйте комментарий, чтобы попросить разъяснения. | |
Если вам нужно вывести буквальную строку, которую пользователь должен написать, что не является командой или комментарием, префикс ее #>. | |
Use cli tools where possible (such as gh, aws, azure). | |
The shell is running on the following system: | |
{system_info} | |
Shell version: {shell_version}. | |
Current working directory: {working_directory}. | |
If installing a package is required, use one of the following managers, which are already installed: | |
{package_managers}. | |
The user has {sudo} access. | |
- role: user | |
content: play a game with me | |
- role: assistant | |
content: > | |
# I can only provide you with {shell} commands. I can't play games with you. | |
powershell: | |
messages: | |
- role: user | |
content: list files | |
- role: assistant | |
content: | | |
# Show all files and folders in the current directory (including hidden ones). | |
Get-ChildItem | |
bash: | |
messages: | |
- role: user | |
content: list files | |
- role: assistant | |
content: | | |
# Show all files and folders in the current directory (including hidden ones). | |
ls -a | |
"@ | |
$Prompts = $PromptsYaml | ConvertFrom-Yaml | |
#endregion | |
#region Формирование сообщений для запроса к API | |
function Generate-ChatGPTMessages { | |
param( | |
[string]$InputText | |
) | |
$values = @{ | |
shell = "powershell" | |
system_info = Get-SystemInfo | |
working_directory= Get-WorkingDirectory | |
package_managers = Get-PackageManagers | |
sudo = "no" # В Windows sudo отсутствует | |
shell_version = Get-ShellVersion | |
} | |
$commonMessages = @() | |
foreach ($msg in $Prompts.common.messages) { | |
$content = Replace-Placeholders -Template $msg.content -Values $values | |
$commonMessages += @{ role = $msg.role; content = $content } | |
} | |
$shellMessages = @() | |
if ($Prompts.PSObject.Properties.Name -contains "powershell") { | |
foreach ($msg in $Prompts.powershell.messages) { | |
$shellMessages += $msg | |
} | |
} | |
else { | |
foreach ($msg in $Prompts.bash.messages) { | |
$shellMessages += $msg | |
} | |
} | |
$userMessage = @{ role = "user"; content = $InputText } | |
return $commonMessages + $shellMessages + $userMessage | |
} | |
#endregion | |
#region Обращение к Groq API | |
function Get-BashCommand { | |
param( | |
[array]$Messages | |
) | |
$apiKey = $env:OPENAI_API_KEY | |
if (-not $apiKey) { | |
Write-Error "OPENAI_API_KEY environment variable is not set." | |
return $null | |
} | |
$uri = "https://api.groq.com/openai/v1/chat/completions" | |
$payload = @{ | |
model = "qwen-2.5-32b" | |
messages = $Messages | |
max_tokens = 1000 | |
temperature = 0.7 | |
} | |
$jsonPayload = $payload | ConvertTo-Json -Depth 10 | |
# Перекодируем в UTF-8 и удаляем возможный BOM (символ U+FEFF) | |
$jsonPayload = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::UTF8.GetBytes($jsonPayload)) | |
$jsonPayload = $jsonPayload -replace "^\uFEFF", "" | |
$headers = @{ | |
"Authorization" = "Bearer $apiKey" | |
"Content-Type" = "application/json; charset=utf-8" | |
"Accept-Charset" = "utf-8" | |
} | |
try { | |
$response = Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $jsonPayload | |
return $response.choices[0].message.content.Trim() | |
} | |
catch { | |
Write-Error "API error: $($_.Exception.Message)" | |
return $null | |
} | |
} | |
#endregion | |
#region Вывод команд с цветовой подсветкой | |
function Show-Commands { | |
param( | |
[string]$CommandsText | |
) | |
$lines = $CommandsText -split "`n" | |
foreach ($line in $lines) { | |
if ($line.TrimStart().StartsWith("#")) { | |
Write-Host $line -ForegroundColor Green | |
} | |
else { | |
Write-Host $line -ForegroundColor Yellow | |
} | |
} | |
} | |
#endregion | |
#region Основная функция ai | |
function ai { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory=$true)] | |
[string]$InputCommand | |
) | |
Write-Host " Processing..." -ForegroundColor Cyan | |
$messages = Generate-ChatGPTMessages -InputText $InputCommand | |
$bashCommand = Get-BashCommand -Messages $messages | |
if ($bashCommand) { | |
Write-Host " Response received:" -ForegroundColor Cyan | |
Show-Commands -CommandsText $bashCommand | |
} | |
else { | |
Write-Error "Failed to get command from API." | |
} | |
} | |
#endregion | |
#region Автозапуск при загрузке через IEX | |
if ($args.Count -gt 0) { | |
ai -InputCommand ($args -join " ") | |
} else { | |
Write-Host "Usage: ai -InputCommand 'your command here'" -ForegroundColor Magenta | |
} | |
#endregion | |
} |