Private/Translation/Invoke-GoogleTranslation.ps1
|
function Invoke-GoogleTranslation { <# .SYNOPSIS Calls the Google Gemini generateContent API with retry and exponential backoff. .OUTPUTS PSCustomObject: Content, InputTokens, OutputTokens, FinishReason, Model #> [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [string] $SystemPrompt, [Parameter(Mandatory)] [string] $UserContent, [Parameter(Mandatory)] [TranslationProvider] $Provider, [Parameter(Mandatory)] [SecureString] $ApiKey, [int] $MaxRetries = 3 ) $plainKey = [System.Net.NetworkCredential]::new('', $ApiKey).Password $body = @{ systemInstruction = @{ parts = @(@{ text = $SystemPrompt }) } contents = @( @{ role = 'user' parts = @(@{ text = $UserContent }) } ) generationConfig = @{ temperature = [double]$Provider.Temperature } } | ConvertTo-Json -Depth 8 $uri = '{0}/models/{1}:generateContent?key={2}' -f $Provider.BaseUrl, $Provider.Model, $plainKey $attempt = 0 while ($attempt -lt $MaxRetries) { try { $response = Invoke-RestMethod -Uri $uri -Method Post ` -ContentType 'application/json' -Body $body -ErrorAction Stop $text = $response.candidates[0].content.parts[0].text $inTok = $response.usageMetadata.promptTokenCount $outTok = $response.usageMetadata.candidatesTokenCount $finish = $response.candidates[0].finishReason return [PSCustomObject]@{ Content = $text InputTokens = $inTok OutputTokens = $outTok FinishReason = $finish.ToLower() Model = $Provider.Model } } catch { $attempt++ if ($attempt -ge $MaxRetries) { return [PSCustomObject]@{ Content = $_.Exception.Message InputTokens = 0 OutputTokens = 0 FinishReason = 'error' Model = $Provider.Model } } $delay = [Math]::Pow(2, $attempt) Write-Warning "Google API call failed (attempt $attempt/$MaxRetries). Retrying in ${delay}s..." Start-Sleep -Seconds $delay } } } |