Private/Translation/Invoke-AnthropicTranslation.ps1
|
function Invoke-AnthropicTranslation { <# .SYNOPSIS Calls the Anthropic Messages API with retry and exponential backoff. .OUTPUTS PSCustomObject: Content, InputTokens, OutputTokens, FinishReason, Model, RetryCount #> [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [string] $SystemPrompt, [Parameter(Mandatory)] [string] $UserContent, [Parameter(Mandatory)] [TranslationProvider] $Provider, [Parameter(Mandatory)] [SecureString] $ApiKey, [int] $MaxRetries = 3, # When supplied, the call is attempted over the streaming path first so the # caller can report progress while the model is still writing; any streaming # failure falls back to the buffered request below. [scriptblock] $StreamCallback ) $plainKey = [System.Net.NetworkCredential]::new('', $ApiKey).Password $body = @{ model = $Provider.Model max_tokens = $Provider.MaxOutputTokens system = $SystemPrompt messages = @( @{ role = 'user'; content = $UserContent } ) temperature = [double]$Provider.Temperature } $headers = @{ 'x-api-key' = $plainKey 'anthropic-version' = '2023-06-01' } if ($StreamCallback) { $streamed = Invoke-TranslationStreamAttempt -Uri "$($Provider.BaseUrl)/messages" -Headers $headers -Body $body ` -Shape 'Anthropic' -ProviderLabel 'Anthropic' -Model $Provider.Model ` -StreamCallback $StreamCallback -JsonDepth 5 if ($streamed) { return $streamed } } $result = Invoke-TranslationApiRequest -Uri "$($Provider.BaseUrl)/messages" -Method Post ` -Body $body -Headers $headers -ProviderLabel 'Anthropic' -MaxRetries $MaxRetries -JsonDepth 5 if (-not $result.Success) { return [PSCustomObject]@{ Content = $result.ErrorMessage InputTokens = 0 OutputTokens = 0 FinishReason = 'error' Model = $Provider.Model RetryCount = $result.RetryCount } } $response = $result.Response # The content array can contain non-text blocks (e.g. 'thinking') - select the # first block that actually is text rather than assuming index 0. $textBlock = $null foreach ($block in $response.content) { if ($block.type -eq 'text') { $textBlock = $block break } } if (-not $textBlock) { return [PSCustomObject]@{ Content = 'Anthropic response contained no text content block.' InputTokens = $response.usage.input_tokens OutputTokens = $response.usage.output_tokens FinishReason = 'error' Model = $response.model RetryCount = $result.RetryCount } } return [PSCustomObject]@{ Content = $textBlock.text InputTokens = $response.usage.input_tokens OutputTokens = $response.usage.output_tokens FinishReason = $response.stop_reason Model = $response.model RetryCount = $result.RetryCount } } |