Public/Invoke-PCCompletion.ps1
|
function Invoke-PCCompletion { <# .SYNOPSIS Send a prompt to an AI provider and get a response. .DESCRIPTION Unified completion function supporting OpenAI, Gemini, and Anthropic. Auto-detects provider from model name or uses the only configured provider. .EXAMPLE Invoke-PCCompletion -UserPrompt "What is PowerShell?" .EXAMPLE Invoke-PCCompletion -Provider openai -Model gpt-4o -SystemPrompt "Be concise" -UserPrompt "Explain closures" #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$UserPrompt, [string]$SystemPrompt, [ValidateSet('openai', 'gemini', 'anthropic')] [string]$Provider, [string]$Model, [int]$MaxTokens = 4096, [ValidateRange(0.0, 2.0)] [double]$Temperature = 0.3, [switch]$JsonMode, [switch]$WebSearch, [int]$TimeoutSec = 120 ) # Resolve provider if (-not $Provider) { if ($Model -match '^gemini') { $Provider = 'gemini' } elseif ($Model -match '^claude') { $Provider = 'anthropic' } elseif ($Model -match '^(gpt|o[1-9])') { $Provider = 'openai' } else { # Auto-detect: use the only configured provider $available = @() foreach ($p in $script:Providers.Keys) { if (Resolve-PCApiKey -Provider $p) { $available += $p } } if ($available.Count -eq 1) { $Provider = $available[0] } elseif ($available.Count -eq 0) { throw "No AI provider API keys configured. Set a key via Set-PCSecret or environment variable (OPENAI_API_KEY, GEMINI_API_KEY, ANTHROPIC_API_KEY)." } else { throw "Multiple providers configured ($($available -join ', ')). Specify -Provider or -Model to select one." } } } # Resolve model if (-not $Model) { $Model = $script:Providers[$Provider].DefaultModel } # Resolve API key $apiKey = Resolve-PCApiKey -Provider $Provider if (-not $apiKey) { throw "No API key found for provider '$Provider'. Set it via Set-PCSecret -Name '$($script:Providers[$Provider].SecretName)' or environment variable." } # Build messages array $messages = @() if ($SystemPrompt) { $messages += @{ role = 'system'; content = $SystemPrompt } } $messages += @{ role = 'user'; content = $UserPrompt } # Dispatch to provider $splat = @{ ApiKey = $apiKey Model = $Model Messages = $messages MaxTokens = $MaxTokens Temperature = $Temperature JsonMode = $JsonMode TimeoutSec = $TimeoutSec } Write-Verbose "PCCompletion: Provider=$Provider Model=$Model MaxTokens=$MaxTokens" switch ($Provider) { 'openai' { $splat['WebSearch'] = $WebSearch Invoke-PCOpenAIRequest @splat } 'gemini' { Invoke-PCGeminiRequest @splat } 'anthropic' { Invoke-PCAnthropicRequest @splat } } } |