Public/Update-Documentation.ps1
|
function Update-Documentation { <# .SYNOPSIS Sends drift results to AI to generate a corrected version of the original document. .DESCRIPTION Reads the original document and verified facts with drift data, then uses an AI to rewrite the document with corrections. Optionally highlights changes with [UPDATED] and [UNVERIFIED] tags. .PARAMETER DocumentPath Path to the original document. .PARAMETER FactsPath Path to the verified facts.json database. .PARAMETER OutputPath Directory to save the corrected document. Default is .\Updated. .PARAMETER Format Output format. Default is Markdown. .PARAMETER Provider AI provider to use. .PARAMETER ApiKey API key for the provider. .PARAMETER Model AI model to use. .PARAMETER Endpoint Custom API endpoint URL. .PARAMETER HighlightChanges Mark corrections with [UPDATED] and [UNVERIFIED] tags. .EXAMPLE Update-Documentation -DocumentPath ".\docs\overview.md" -FactsPath .\facts.json -HighlightChanges #> [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [ValidateScript({ Test-Path $_ })] [string]$DocumentPath, [Parameter(Mandatory, Position = 1)] [ValidateScript({ Test-Path $_ })] [string]$FactsPath, [Parameter()] [string]$OutputPath = '.\Updated', [Parameter()] [ValidateSet('Markdown', 'HTML')] [string]$Format = 'Markdown', [Parameter()] [ValidateSet('Anthropic', 'OpenAI', 'Ollama', 'Custom')] [string]$Provider = 'Anthropic', [Parameter()] [string]$ApiKey, [Parameter()] [string]$Model, [Parameter()] [string]$Endpoint, [Parameter()] [switch]$HighlightChanges ) # Read original document Write-Verbose "Reading original document: $DocumentPath" $docItem = Get-Item $DocumentPath $originalText = '' switch ($docItem.Extension.ToLower()) { '.docx' { $originalText = Read-WordDocument -Path $docItem.FullName } '.xlsx' { $originalText = Read-ExcelDocument -Path $docItem.FullName } default { $originalText = Get-Content -Path $docItem.FullName -Raw -Encoding UTF8 } } if ([string]::IsNullOrWhiteSpace($originalText)) { Write-Error "Original document is empty or could not be read." return } # Read facts database Write-Verbose "Reading facts database: $FactsPath" try { $factsDatabase = Get-Content -Path $FactsPath -Raw -Encoding UTF8 | ConvertFrom-Json } catch { throw "Failed to load facts database: $($_.Exception.Message)" } # Filter to relevant facts (from this document and verified/drift facts) $relevantFacts = $factsDatabase.facts | Where-Object { $_.overall_status -in @('verified', 'drift', 'unreachable') } if (-not $relevantFacts -or @($relevantFacts).Count -eq 0) { Write-Warning "No verified or drifted facts found in database. Cannot generate updated document." return } $factsJson = $relevantFacts | ConvertTo-Json -Depth 10 # Load update prompt template $templatePath = Join-Path (Join-Path $script:ModuleRoot 'Templates') 'update-prompt.txt' if (-not $script:ModuleRoot) { $templatePath = Join-Path (Join-Path $PSScriptRoot '..') (Join-Path 'Templates' 'update-prompt.txt') } if (Test-Path $templatePath) { $promptTemplate = Get-Content -Path $templatePath -Raw -Encoding UTF8 } else { Write-Warning "Update prompt template not found. Using built-in template." $promptTemplate = @' You are an IT documentation writer. Below is an original IT document followed by verified facts about the current environment. Rewrite the document to be accurate based on the verified facts. Rules: 1. Keep the same structure and style as the original 2. Correct any information that has drifted from reality 3. If highlight_changes is true, mark corrections with [UPDATED: old value -> new value] 4. Add a "Last Verified" date at the top 5. Do not remove information that couldn't be verified -- mark it as [UNVERIFIED] 6. Add any discovered items not in the original under a "New Discoveries" section ORIGINAL DOCUMENT: {original_text} VERIFIED FACTS: {facts_json} HIGHLIGHT CHANGES: {highlight_changes} '@ } # Build the prompt $highlightValue = if ($HighlightChanges) { 'true' } else { 'false' } $userPrompt = $promptTemplate ` -replace '\{original_text\}', $originalText ` -replace '\{facts_json\}', $factsJson ` -replace '\{highlight_changes\}', $highlightValue # Call the AI Write-Verbose "Sending document and facts to AI for rewriting..." $aiParams = @{ Provider = $Provider UserPrompt = $userPrompt SystemPrompt = 'You are an IT documentation writer. Rewrite documentation to be accurate based on verified facts.' Temperature = 0.2 MaxTokens = 4096 } if ($ApiKey) { $aiParams['ApiKey'] = $ApiKey } if ($Model) { $aiParams['Model'] = $Model } if ($Endpoint) { $aiParams['Endpoint'] = $Endpoint } try { $updatedContent = Invoke-AICompletion @aiParams } catch { throw "AI document update failed: $($_.Exception.Message)" } # Clean up AI response (remove markdown code blocks if present) if ($updatedContent -match '```markdown\s*([\s\S]*?)\s*```') { $updatedContent = $Matches[1] } elseif ($updatedContent -match '```\s*([\s\S]*?)\s*```') { $updatedContent = $Matches[1] } $updatedContent = $updatedContent.Trim() # Ensure output directory exists if (-not (Test-Path $OutputPath)) { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } # Determine output filename $baseName = [System.IO.Path]::GetFileNameWithoutExtension($docItem.Name) $extension = switch ($Format) { 'Markdown' { '.md' } 'HTML' { '.html' } } $outputFileName = "${baseName}-updated${extension}" $outputFilePath = Join-Path $OutputPath $outputFileName # If HTML format, wrap in basic HTML if ($Format -eq 'HTML') { $updatedContent = @" <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>$baseName - Updated Documentation</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 900px; margin: 2rem auto; padding: 0 1rem; line-height: 1.7; color: #e6edf3; background: #0d1117; } h1, h2, h3 { color: #a371f7; } .updated { background: #0f2d1a; padding: 0.1rem 0.3rem; border-radius: 3px; color: #3fb950; } .unverified { background: #3d2e00; padding: 0.1rem 0.3rem; border-radius: 3px; color: #d29922; } pre { background: #161b22; padding: 1rem; border-radius: 6px; overflow-x: auto; } code { background: #161b22; padding: 0.15rem 0.3rem; border-radius: 3px; } </style> </head> <body> $updatedContent </body> </html> "@ } # Save the updated document $updatedContent | Out-File -FilePath $outputFilePath -Encoding UTF8 -Force Write-Verbose "Updated document saved to: $outputFilePath" # Return file info $result = [PSCustomObject]@{ OriginalDocument = $docItem.FullName UpdatedDocument = (Resolve-Path $outputFilePath).Path Format = $Format HighlightChanges = $HighlightChanges.IsPresent FactsUsed = @($relevantFacts).Count GeneratedAt = (Get-Date).ToString('o') } return $result } |