diff --git a/PowerShell_AI_Agent/PowerShell_AI_Agent/README.md b/PowerShell_AI_Agent/PowerShell_AI_Agent/README.md new file mode 100644 index 0000000..08052b2 --- /dev/null +++ b/PowerShell_AI_Agent/PowerShell_AI_Agent/README.md @@ -0,0 +1,149 @@ +# PowerShell AI Agent + +A comprehensive, modular PowerShell-based AI agent with advanced capabilities including voice interaction, plugin system, and comprehensive logging. + +## Features + +- **Modular Architecture**: AI Engine, Voice Engine, Logging Engine, and Plugin Manager +- **Advanced AI Processing**: Intent recognition, system commands, and contextual responses +- **Voice Integration**: Speech recognition and text-to-speech capabilities +- **Plugin System**: Extensible architecture with custom plugin support +- **Comprehensive Logging**: Structured logging with multiple output formats +- **Memory Persistence**: Intelligent conversation memory with context awareness +- **System Integration**: Built-in system monitoring and management commands +- **Interactive CLI**: Rich command-line interface with color-coded output + +## Quick Start + +1. **Run the agent:** + ```powershell + .\Start-AIAgent.ps1 + ``` + +2. **Available commands:** + - `help` - Show available commands + - `exit` or `quit` - Exit the agent + - `memory` - Show memory statistics + - `config` - Show current configuration + - `clear` - Clear the screen + - `voice` - Toggle voice mode + - `logs` - Show recent log entries + - `test` - Test system capabilities + - `plugins` - Show loaded plugins + +## Configuration + +The agent uses `config/agent-config.json` for settings: + +- **AI**: Model settings (gpt-4, tokens, temperature) +- **Voice**: Speech recognition and synthesis settings +- **Memory**: Persistence and storage settings +- **Autopilot**: Autonomous operation settings + +## Project Structure + +``` +PowerShell_AI_Agent/ +├── Start-AIAgent.ps1 # Main entry point +├── config/ +│ └── agent-config.json # Configuration file +├── data/ +│ └── memory.json # Conversation memory +├── logs/ # Log files +├── modules/ # PowerShell modules +│ ├── AI-Engine.psm1 # AI processing engine +│ ├── Voice-Engine.psm1 # Voice recognition/synthesis +│ └── Logging-Engine.psm1 # Comprehensive logging +├── plugins/ # Extensions +│ ├── Plugin-Manager.psm1 # Plugin management system +│ └── System-Tools.ps1 # Example system tools plugin +├── scripts/ # Utility scripts +└── tests/ # Test files +│ └── Test-AIAgent.ps1 # Comprehensive test suite +``` + +## Parameters + +- `-Verbose`: Enable verbose error reporting +- `-NoVoice`: Disable voice features +- `-Debug`: Enable debug logging +- `-ConfigPath`: Specify custom config file path + +## Example Usage + +```powershell +# Basic run +.\Start-AIAgent.ps1 + +# With verbose logging +.\Start-AIAgent.ps1 -Verbose + +# With debug logging +.\Start-AIAgent.ps1 -Debug + +# Disable voice features +.\Start-AIAgent.ps1 -NoVoice + +# Custom config file +.\Start-AIAgent.ps1 -ConfigPath ".\custom-config.json" + +# Run test suite +.\tests\Test-AIAgent.ps1 + +# Run tests without voice +.\tests\Test-AIAgent.ps1 -SkipVoice +``` + +## Development + +### Creating Plugins + +Create new plugins in the `plugins/` directory: + +```powershell +@{ + Name = "My Plugin" + Version = "1.0" + Description = "Description of your plugin" + Commands = @( + @{ + Name = "MyCommand" + Description = "Description of the command" + Function = { + param([hashtable]$Parameters) + # Your command logic here + return "Command executed successfully" + } + } + ) +} +``` + +### Extending AI Engine + +Modify `modules/AI-Engine.psm1` to add new capabilities: +- Add new intent patterns in `Analyze-UserIntent` +- Create new system commands in `Execute-SystemCommand` +- Extend response patterns in `Generate-ContextualResponse` + +### Voice Integration + +The voice engine supports: +- Speech synthesis with configurable speed and voice +- Speech recognition with confidence thresholds +- Multiple voice selection +- Voice testing and diagnostics + +### Logging + +The logging system provides: +- Structured JSON logging +- Multiple log levels (Debug, Info, Warning, Error) +- Log rotation and archiving +- Export capabilities (CSV, JSON, HTML) + +## Requirements + +- PowerShell 5.1 or higher +- Windows 10/11 (for voice features) +- Internet connection (for AI service integration) \ No newline at end of file diff --git a/PowerShell_AI_Agent/PowerShell_AI_Agent/Start-AIAgent.ps1 b/PowerShell_AI_Agent/PowerShell_AI_Agent/Start-AIAgent.ps1 new file mode 100644 index 0000000..46d6ba6 --- /dev/null +++ b/PowerShell_AI_Agent/PowerShell_AI_Agent/Start-AIAgent.ps1 @@ -0,0 +1,355 @@ +# PowerShell AI Agent - Main Entry Point +# Version: 2.0 - Enhanced with modules + +param( + [switch]$Verbose, + [switch]$NoVoice, + [switch]$Debug, + [string]$ConfigPath = ".\config\agent-config.json" +) + +# Import required modules +$ErrorActionPreference = "Stop" + +# Import custom modules +$modulePath = ".\modules" +if (Test-Path $modulePath) { + Import-Module "$modulePath\AI-Engine.psm1" -Force + Import-Module "$modulePath\Voice-Engine.psm1" -Force + Import-Module "$modulePath\Logging-Engine.psm1" -Force +} + +# Import plugin manager +$pluginPath = ".\plugins" +if (Test-Path $pluginPath) { + Import-Module "$pluginPath\Plugin-Manager.psm1" -Force +} + +# Function to load configuration +function Load-Configuration { + param([string]$ConfigPath) + + try { + if (Test-Path $ConfigPath) { + $config = Get-Content $ConfigPath -Raw | ConvertFrom-Json + # Convert PSCustomObject to hashtable + $configHashtable = @{} + $config.PSObject.Properties | ForEach-Object { + $configHashtable[$_.Name] = $_.Value + } + Write-Host "Configuration loaded successfully" -ForegroundColor Green + return $configHashtable + } else { + throw "Configuration file not found: $ConfigPath" + } + } + catch { + Write-Error "Failed to load configuration: $_" + exit 1 + } +} + +# Function to initialize memory +function Initialize-Memory { + param($Config) + + $memoryPath = $Config.Memory.PersistencePath + if (Test-Path $memoryPath) { + try { + $memory = Get-Content $memoryPath -Raw | ConvertFrom-Json + Write-Host "Memory loaded from: $memoryPath" -ForegroundColor Green + return $memory + } + catch { + Write-Warning "Failed to load memory, creating new memory file" + } + } + + # Create new memory structure + $memory = @{ + entries = @() + lastUpdated = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + version = "1.0" + } + + # Ensure directory exists + $memoryDir = Split-Path $memoryPath -Parent + if (!(Test-Path $memoryDir)) { + New-Item -ItemType Directory -Path $memoryDir -Force | Out-Null + } + + $memory | ConvertTo-Json -Depth 10 | Set-Content $memoryPath + Write-Host "New memory file created: $memoryPath" -ForegroundColor Yellow + return $memory +} + +# Function to save memory +function Save-Memory { + param($Memory, $Config) + + $Memory.lastUpdated = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + $memoryPath = $Config.Memory.PersistencePath + $Memory | ConvertTo-Json -Depth 10 | Set-Content $memoryPath +} + +# Function to add memory entry +function Add-MemoryEntry { + param($Memory, $Input, $Response, $Timestamp = (Get-Date)) + + $entry = @{ + input = $Input + response = $Response + timestamp = $Timestamp.ToString("yyyy-MM-dd HH:mm:ss") + } + + $Memory.entries += $entry + + # Limit memory entries + if ($Memory.entries.Count -gt 1000) { + $Memory.entries = $Memory.entries | Select-Object -Last 1000 + } +} + +# Function to simulate AI response (placeholder for actual AI integration) +function Get-AIResponse { + param($Input, $Config, $Memory) + + # This is a placeholder - in a real implementation, you would integrate with an AI service + $responses = @( + "I understand you said: '$Input'. How can I help you further?", + "That's an interesting point about '$Input'. Let me think about that...", + "Based on your input '$Input', I'd recommend considering the following...", + "I've processed your request: '$Input'. Here's what I can do for you...", + "Thank you for sharing '$Input'. I'm here to assist you with any tasks." + ) + + $response = $responses | Get-Random + + # Add context from memory if available + if ($Memory.entries.Count -gt 0) { + $recentEntries = $Memory.entries | Select-Object -Last 3 + $context = "Based on our previous conversation, " + $response = $context + $response + } + + return $response +} + +# Function to handle voice input/output (placeholder) +function Handle-Voice { + param($Config, $Enabled = $true) + + if (-not $Enabled -or -not $Config.Voice.Enabled) { + return $false + } + + Write-Host "Voice features are configured but not implemented yet." -ForegroundColor Yellow + Write-Host "Voice settings: Language=$($Config.Voice.Language), Speed=$($Config.Voice.ResponseSpeed)" -ForegroundColor Cyan + return $false +} + +# Main agent loop +function Start-AgentLoop { + param($Config, $Memory, $AIEngine, $VoiceEngine, $LoggingEngine, $PluginManager) + + Write-Host "=== PowerShell AI Agent Started ===" -ForegroundColor Green + Write-Host "AI Model: $($Config.AI.Model)" -ForegroundColor Cyan + Write-Host "Max Tokens: $($Config.AI.MaxTokens)" -ForegroundColor Cyan + Write-Host "Temperature: $($Config.AI.Temperature)" -ForegroundColor Cyan + Write-Host "Memory Enabled: $($Config.Memory.Enabled)" -ForegroundColor Cyan + Write-Host "Autopilot Enabled: $($Config.Autopilot.Enabled)" -ForegroundColor Cyan + Write-Host "Voice Enabled: $($VoiceEngine.VoiceEnabled)" -ForegroundColor Cyan + Write-Host "" + Write-Host "Type 'exit' or 'quit' to stop the agent" -ForegroundColor Yellow + Write-Host "Type 'help' for available commands" -ForegroundColor Yellow + Write-Host "Type 'voice' to toggle voice mode" -ForegroundColor Yellow + Write-Host "" + + Write-InfoLog -Engine $LoggingEngine -Message "Agent loop started" + + # Initialize voice if enabled + if ($VoiceEngine.VoiceEnabled -and -not $NoVoice) { + Test-VoiceSystem -Engine $VoiceEngine + } + + do { + try { + Write-Host "AI Agent> " -NoNewline -ForegroundColor Green + $userInput = Read-Host + + if ([string]::IsNullOrWhiteSpace($userInput)) { + continue + } + + Write-DebugLog -Engine $LoggingEngine -Message "User input received" -Context @{ Input = $userInput } + + # Handle special commands + switch ($userInput.ToLower()) { + "exit" { + Write-InfoLog -Engine $LoggingEngine -Message "User requested exit" + Write-Host "Saving memory and shutting down..." -ForegroundColor Yellow + Save-Memory -Memory $Memory -Config $Config + Write-Host "Goodbye!" -ForegroundColor Green + return + } + "quit" { + Write-InfoLog -Engine $LoggingEngine -Message "User requested quit" + Write-Host "Saving memory and shutting down..." -ForegroundColor Yellow + Save-Memory -Memory $Memory -Config $Config + Write-Host "Goodbye!" -ForegroundColor Green + return + } + "help" { + Write-Host "Available commands:" -ForegroundColor Cyan + Write-Host " help - Show this help message" -ForegroundColor White + Write-Host " exit - Exit the agent" -ForegroundColor White + Write-Host " quit - Exit the agent" -ForegroundColor White + Write-Host " memory - Show memory statistics" -ForegroundColor White + Write-Host " config - Show current configuration" -ForegroundColor White + Write-Host " clear - Clear the screen" -ForegroundColor White + Write-Host " voice - Toggle voice mode" -ForegroundColor White + Write-Host " logs - Show recent log entries" -ForegroundColor White + Write-Host " test - Test system capabilities" -ForegroundColor White + Write-Host " plugins - Show loaded plugins" -ForegroundColor White + continue + } + "memory" { + Write-Host "Memory Statistics:" -ForegroundColor Cyan + Write-Host " Total Entries: $($Memory.entries.Count)" -ForegroundColor White + Write-Host " Last Updated: $($Memory.lastUpdated)" -ForegroundColor White + Write-Host " Version: $($Memory.version)" -ForegroundColor White + continue + } + "config" { + Write-Host "Current Configuration:" -ForegroundColor Cyan + $Config | ConvertTo-Json -Depth 3 | Write-Host -ForegroundColor White + continue + } + "clear" { + Clear-Host + continue + } + "voice" { + if ($VoiceEngine.VoiceEnabled) { + if ($VoiceEngine.IsListening) { + Stop-SpeechRecognition -Engine $VoiceEngine + } else { + Start-SpeechRecognition -Engine $VoiceEngine -OnSpeechRecognized { + param($text) + Write-Host "Voice: $text" -ForegroundColor Magenta + # Process voice input + $aiResponse = Get-AIResponse -Engine $AIEngine -Input $text -Memory $Memory + Write-Host "AI: $aiResponse" -ForegroundColor Blue + Speak-Text -Engine $VoiceEngine -Text $aiResponse + } + } + } else { + Write-Host "Voice features are disabled" -ForegroundColor Yellow + } + continue + } + "logs" { + $recentLogs = Get-LogEntries -Engine $LoggingEngine -Count 10 + Write-Host "Recent Log Entries:" -ForegroundColor Cyan + foreach ($log in $recentLogs) { + $color = switch ($log.Level) { + "Debug" { "Gray" } + "Info" { "White" } + "Warning" { "Yellow" } + "Error" { "Red" } + default { "White" } + } + Write-Host "[$($log.Timestamp)] [$($log.Level)] $($log.Message)" -ForegroundColor $color + } + continue + } + "test" { + Write-Host "Testing system capabilities..." -ForegroundColor Cyan + Test-VoiceSystem -Engine $VoiceEngine + Write-Host "AI Engine: OK" -ForegroundColor Green + Write-Host "Logging Engine: OK" -ForegroundColor Green + continue + } + "plugins" { + Show-PluginInfo -Manager $PluginManager + continue + } + } + + # Process user input with AI + $aiResponse = Get-AIResponse -Engine $AIEngine -Input $userInput -Memory $Memory + + # Display response + Write-Host "AI: $aiResponse" -ForegroundColor Blue + + # Speak response if voice is enabled + if ($VoiceEngine.VoiceEnabled -and $VoiceEngine.IsListening) { + Speak-Text -Engine $VoiceEngine -Text $aiResponse + } + + # Add to memory + if ($Config.Memory.Enabled) { + Add-MemoryEntry -Memory $Memory -Input $userInput -Response $aiResponse + } + + # Log the interaction + Write-InfoLog -Engine $LoggingEngine -Message "AI response generated" -Context @{ + Input = $userInput + Response = $aiResponse + MemoryEntries = $Memory.entries.Count + } + + # Save memory periodically + if ($Memory.entries.Count % 10 -eq 0) { + Save-Memory -Memory $Memory -Config $Config + Write-DebugLog -Engine $LoggingEngine -Message "Memory saved automatically" + } + + } + catch { + Write-ErrorLog -Engine $LoggingEngine -Message "Error in agent loop: $_" -Context @{ StackTrace = $_.ScriptStackTrace } + Write-Error "Error in agent loop: $_" + if ($Verbose) { + Write-Host "Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Red + } + } + } while ($true) +} + +# Main execution +try { + Write-Host "PowerShell AI Agent Starting..." -ForegroundColor Green + + # Load configuration + $config = Load-Configuration -ConfigPath $ConfigPath + + # Initialize engines + $aiEngine = Initialize-AIEngine -Config $config + $voiceEngine = Initialize-VoiceEngine -Config $config + $loggingEngine = Initialize-LoggingEngine -Config $config + $pluginManager = Initialize-PluginManager -Config $config + + # Set debug level if requested + if ($Debug) { + $loggingEngine.LogLevel = "Debug" + } + + Write-InfoLog -Engine $loggingEngine -Message "AI Agent starting with enhanced modules" + + # Load plugins + Load-AllPlugins -Manager $pluginManager + Write-InfoLog -Engine $loggingEngine -Message "Plugins loaded: $($pluginManager.LoadedPlugins.Count)" + + # Initialize memory + $memory = Initialize-Memory -Config $config + + # Start the agent loop + Start-AgentLoop -Config $config -Memory $memory -AIEngine $aiEngine -VoiceEngine $voiceEngine -LoggingEngine $loggingEngine -PluginManager $pluginManager +} +catch { + Write-Error "Failed to start AI Agent: $_" + if ($Verbose) { + Write-Host "Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Red + } + exit 1 +} \ No newline at end of file diff --git a/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/AI-Engine.psm1 b/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/AI-Engine.psm1 new file mode 100644 index 0000000..45ee703 --- /dev/null +++ b/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/AI-Engine.psm1 @@ -0,0 +1,243 @@ +# AI Engine Module for PowerShell AI Agent +# Provides AI response generation and integration capabilities + +function Initialize-AIEngine { + param( + [hashtable]$Config + ) + + $engine = @{ + Config = $Config + Context = @() + ResponsePatterns = @{ + Greeting = @("Hello!", "Hi there!", "Greetings!", "Welcome!") + Farewell = @("Goodbye!", "See you later!", "Take care!", "Until next time!") + Confused = @("I'm not sure I understand.", "Could you clarify that?", "I need more information.") + Helpful = @("I'd be happy to help!", "Let me assist you with that.", "I can help you with this.") + } + Skills = @{} + } + + # Register built-in skills + Register-AISkill -Engine $engine -Name "SystemInfo" -Function "Get-SystemInformation" + Register-AISkill -Engine $engine -Name "FileOperations" -Function "Handle-FileOperations" + Register-AISkill -Engine $engine -Name "ProcessManagement" -Function "Handle-ProcessOperations" + + return $engine +} + +function Register-AISkill { + param( + [hashtable]$Engine, + [string]$Name, + [string]$Function + ) + + $Engine.Skills[$Name] = $Function + Write-Verbose "Registered AI skill: $Name" +} + +function Get-AIResponse { + param( + [hashtable]$Engine, + [string]$Input, + [hashtable]$Memory + ) + + # Analyze input for intent + $intent = Analyze-UserIntent -Input $Input + + # Check for system commands + if ($intent.Type -eq "SystemCommand") { + return Execute-SystemCommand -Intent $intent -Engine $Engine + } + + # Check for skill-based requests + if ($intent.Type -eq "SkillRequest") { + return Execute-SkillRequest -Intent $intent -Engine $Engine + } + + # Generate contextual response + $response = Generate-ContextualResponse -Input $Input -Intent $intent -Memory $Memory -Engine $Engine + + # Add to context + $Engine.Context += @{ + Input = $Input + Response = $response + Intent = $intent + Timestamp = Get-Date + } + + # Limit context size + if ($Engine.Context.Count -gt 10) { + $Engine.Context = $Engine.Context | Select-Object -Last 10 + } + + return $response +} + +function Analyze-UserIntent { + param([string]$Input) + + $input = $Input.ToLower() + + # System commands + if ($input -match "^(get|show|list|display)\s+(system|computer|info|information)") { + return @{ Type = "SystemCommand"; Command = "SystemInfo"; Parameters = @{} } + } + + if ($input -match "^(get|show|list|display)\s+(process|processes)") { + return @{ Type = "SystemCommand"; Command = "ProcessList"; Parameters = @{} } + } + + if ($input -match "^(kill|stop|terminate)\s+(process|processes)") { + $processName = $input -replace "^(kill|stop|terminate)\s+(process|processes)\s+", "" + return @{ Type = "SystemCommand"; Command = "KillProcess"; Parameters = @{ ProcessName = $processName } } + } + + # File operations + if ($input -match "^(list|show|dir|directory)\s+(files|files in|contents of)") { + $path = $input -replace "^(list|show|dir|directory)\s+(files|files in|contents of)\s+", "" + return @{ Type = "SystemCommand"; Command = "ListFiles"; Parameters = @{ Path = $path } } + } + + # Greetings + if ($input -match "^(hello|hi|hey|greetings)") { + return @{ Type = "Greeting"; Command = "Greet"; Parameters = @{} } + } + + # Farewells + if ($input -match "^(goodbye|bye|see you|exit|quit)") { + return @{ Type = "Farewell"; Command = "Farewell"; Parameters = @{} } + } + + # Help requests + if ($input -match "^(help|what can you do|capabilities)") { + return @{ Type = "Help"; Command = "ShowHelp"; Parameters = @{} } + } + + # Default to conversation + return @{ Type = "Conversation"; Command = "Chat"; Parameters = @{} } +} + +function Execute-SystemCommand { + param( + [hashtable]$Intent, + [hashtable]$Engine + ) + + switch ($Intent.Command) { + "SystemInfo" { + $info = Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, TotalPhysicalMemory, CsProcessors + return "Here's your system information:`n$($info | Format-Table | Out-String)" + } + "ProcessList" { + $processes = Get-Process | Select-Object Name, Id, CPU, WorkingSet -First 10 + return "Top 10 processes by memory usage:`n$($processes | Format-Table | Out-String)" + } + "KillProcess" { + $processName = $Intent.Parameters.ProcessName + try { + $processes = Get-Process -Name $processName -ErrorAction Stop + $processes | Stop-Process -Force + return "Successfully terminated $($processes.Count) process(es) named '$processName'" + } + catch { + return "Error: Could not find or terminate process '$processName'" + } + } + "ListFiles" { + $path = $Intent.Parameters.Path + if ([string]::IsNullOrWhiteSpace($path)) { $path = "." } + + try { + $files = Get-ChildItem -Path $path | Select-Object Name, Length, LastWriteTime + return "Files in '$path':`n$($files | Format-Table | Out-String)" + } + catch { + return "Error: Could not list files in '$path'" + } + } + default { + return "I'm not sure how to handle that system command." + } + } +} + +function Execute-SkillRequest { + param( + [hashtable]$Intent, + [hashtable]$Engine + ) + + $skillName = $Intent.Command + if ($Engine.Skills.ContainsKey($skillName)) { + $functionName = $Engine.Skills[$skillName] + return & $functionName -Parameters $Intent.Parameters + } + + return "I don't have that skill available yet." +} + +function Generate-ContextualResponse { + param( + [string]$Input, + [hashtable]$Intent, + [hashtable]$Memory, + [hashtable]$Engine + ) + + switch ($Intent.Type) { + "Greeting" { + $greetings = $Engine.ResponsePatterns.Greeting + return $greetings | Get-Random + } + "Farewell" { + $farewells = $Engine.ResponsePatterns.Farewell + return $farewells | Get-Random + } + "Help" { + return @" +I can help you with various tasks: + +System Commands: +- Get system information +- List processes +- Kill processes +- List files in directories + +Conversation: +- Chat and respond to questions +- Remember our conversation history + +Try asking me to: +- "Show system information" +- "List processes" +- "What can you do?" +"@ + } + "Conversation" { + # Generate contextual response based on input and memory + $context = "" + if ($Memory.entries.Count -gt 0) { + $recentEntries = $Memory.entries | Select-Object -Last 3 + $context = "Based on our conversation, " + } + + $responses = @( + "I understand you're asking about '$Input'. Let me help you with that.", + "That's an interesting point about '$Input'. I'd be happy to assist.", + "Regarding '$Input', I can help you explore this further.", + "I've processed your input about '$Input'. How can I best assist you?" + ) + + return $context + ($responses | Get-Random) + } + default { + return "I'm processing your request: '$Input'. How can I help you further?" + } + } +} + +# Export functions +Export-ModuleMember -Function Initialize-AIEngine, Get-AIResponse, Register-AISkill \ No newline at end of file diff --git a/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/Logging-Engine.psm1 b/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/Logging-Engine.psm1 new file mode 100644 index 0000000..bf7bf0f --- /dev/null +++ b/PowerShell_AI_Agent/PowerShell_AI_Agent/modules/Logging-Engine.psm1 @@ -0,0 +1,259 @@ +# Logging Engine Module for PowerShell AI Agent +# Provides comprehensive logging capabilities + +function Initialize-LoggingEngine { + param( + [hashtable]$Config, + [string]$LogPath = ".\logs" + ) + + $engine = @{ + Config = $Config + LogPath = $LogPath + LogLevel = "Info" # Debug, Info, Warning, Error + MaxLogFiles = 10 + MaxLogSize = 10MB + } + + # Ensure log directory exists + if (!(Test-Path $LogPath)) { + New-Item -ItemType Directory -Path $LogPath -Force | Out-Null + } + + # Create log file name with timestamp + $timestamp = Get-Date -Format "yyyy-MM-dd" + $engine.LogFile = Join-Path $LogPath "ai-agent-$timestamp.log" + + Write-Verbose "Logging engine initialized. Log file: $($engine.LogFile)" + return $engine +} + +function Write-Log { + param( + [hashtable]$Engine, + [string]$Message, + [string]$Level = "Info", + [hashtable]$Context = @{} + ) + + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + $logEntry = @{ + Timestamp = $timestamp + Level = $Level + Message = $Message + Context = $Context + } + + # Convert to JSON for structured logging + $logLine = $logEntry | ConvertTo-Json -Compress + + try { + Add-Content -Path $Engine.LogFile -Value $logLine -ErrorAction Stop + + # Also write to console with color coding + $color = switch ($Level) { + "Debug" { "Gray" } + "Info" { "White" } + "Warning" { "Yellow" } + "Error" { "Red" } + default { "White" } + } + + Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $color + } + catch { + Write-Warning "Failed to write to log file: $_" + } +} + +function Write-DebugLog { + param( + [hashtable]$Engine, + [string]$Message, + [hashtable]$Context = @{} + ) + + if ($Engine.LogLevel -eq "Debug") { + Write-Log -Engine $Engine -Message $Message -Level "Debug" -Context $Context + } +} + +function Write-InfoLog { + param( + [hashtable]$Engine, + [string]$Message, + [hashtable]$Context = @{} + ) + + Write-Log -Engine $Engine -Message $Message -Level "Info" -Context $Context +} + +function Write-WarningLog { + param( + [hashtable]$Engine, + [string]$Message, + [hashtable]$Context = @{} + ) + + Write-Log -Engine $Engine -Message $Message -Level "Warning" -Context $Context +} + +function Write-ErrorLog { + param( + [hashtable]$Engine, + [string]$Message, + [hashtable]$Context = @{} + ) + + Write-Log -Engine $Engine -Message $Message -Level "Error" -Context $Context +} + +function Get-LogEntries { + param( + [hashtable]$Engine, + [int]$Count = 50, + [string]$Level = $null, + [string]$SearchTerm = $null + ) + + if (!(Test-Path $Engine.LogFile)) { + return @() + } + + try { + $entries = Get-Content $Engine.LogFile | ForEach-Object { + try { + $entry = $_ | ConvertFrom-Json + return $entry + } + catch { + # Skip invalid JSON entries + return $null + } + } | Where-Object { $null -ne $_ } + + # Filter by level if specified + if ($Level) { + $entries = $entries | Where-Object { $_.Level -eq $Level } + } + + # Filter by search term if specified + if ($SearchTerm) { + $entries = $entries | Where-Object { $_.Message -match $SearchTerm } + } + + # Return the most recent entries + return $entries | Select-Object -Last $Count + } + catch { + Write-Warning "Failed to read log entries: $_" + return @() + } +} + +function Clear-LogFiles { + param([hashtable]$Engine) + + try { + # Get all log files + $logFiles = Get-ChildItem -Path $Engine.LogPath -Filter "*.log" | Sort-Object LastWriteTime -Descending + + # Keep only the most recent files + if ($logFiles.Count -gt $Engine.MaxLogFiles) { + $filesToDelete = $logFiles | Select-Object -Skip $Engine.MaxLogFiles + $filesToDelete | Remove-Item -Force + + Write-InfoLog -Engine $Engine -Message "Cleaned up $($filesToDelete.Count) old log files" + } + + # Check log file size + $currentLog = Get-Item $Engine.LogFile -ErrorAction SilentlyContinue + if ($currentLog -and $currentLog.Length -gt $Engine.MaxLogSize) { + # Archive current log and start new one + $archiveName = $Engine.LogFile -replace "\.log$", "-$(Get-Date -Format 'HHmmss').log" + Move-Item $Engine.LogFile $archiveName + + Write-InfoLog -Engine $Engine -Message "Log file archived: $archiveName" + } + } + catch { + Write-Warning "Failed to clean up log files: $_" + } +} + +function Export-LogReport { + param( + [hashtable]$Engine, + [string]$OutputPath, + [string]$Format = "CSV" + ) + + try { + $entries = Get-LogEntries -Engine $Engine -Count 1000 + + switch ($Format.ToLower()) { + "CSV" { + $entries | Export-Csv -Path $OutputPath -NoTypeInformation + } + "JSON" { + $entries | ConvertTo-Json -Depth 3 | Set-Content $OutputPath + } + "HTML" { + $html = @" + + +
+Timestamp | +Level | +Message | +
---|---|---|
$($entry.Timestamp) | +$($entry.Level) | +$($entry.Message) | +