Public/Invoke-OpenAIDecision.ps1
|
<# .SYNOPSIS Evaluates one or more ordered questions against shared input. .DESCRIPTION Sends a request to POST /v1/decisions. Input can be text or user messages containing text and inline data-URL images. Non-string, non-array PowerShell objects are serialized as JSON text before sending. By default, named answers are also exposed through an answers map and as top-level properties. Use -Raw to return the unmodified API response. #> function Invoke-OpenAIDecision { [CmdletBinding(DefaultParameterSetName='QuestionObjects')] param( [Parameter(Mandatory,Position=0,ValueFromPipeline)][Alias('Input','State')][ValidateNotNull()][object]$InputObject, [Parameter(Mandatory,ParameterSetName='QuestionObjects')][ValidateNotNullOrEmpty()][object[]]$Question, [Parameter(Mandatory,ParameterSetName='WireQuestions')][ValidateNotNullOrEmpty()][object[]]$Questions, [Parameter()][ValidateNotNullOrEmpty()][string]$Model='gpt-6-luna', [Parameter()][ValidateNotNullOrEmpty()][uri]$Endpoint='https://api.openai.com/v1/decisions', [Parameter()][ValidateRange(1,600)][int]$TimeoutSec=30, [Parameter()][ValidateLength(1,128)][string]$SafetyIdentifier, [Parameter()][switch]$Raw ) process { if ([string]::IsNullOrWhiteSpace([string]$env:OPENAI_API_KEY)) { throw [System.InvalidOperationException]::new('OPENAI_API_KEY is not set. Set it in the environment before calling this command.') } if ($PSCmdlet.ParameterSetName -eq 'QuestionObjects') { $wireQuestions = @(ConvertTo-OpenAIDecisionQuestion -Question $Question) } else { $wireQuestions = @($Questions) } Assert-OpenAIDecisionQuestions -Questions $wireQuestions # The API accepts input text or an array of message objects. Demos and # callers may provide a record as shared evidence, so send that record # as JSON text rather than as an unsupported top-level JSON object. $wireInput = $InputObject if ($InputObject -isnot [string] -and $InputObject -isnot [array]) { $wireInput = ConvertTo-Json -InputObject $InputObject -Depth 100 -Compress } $payload = [ordered]@{ model=$Model; input=$wireInput; questions=$wireQuestions } if (-not [string]::IsNullOrWhiteSpace($SafetyIdentifier)) { $payload.safety_identifier=$SafetyIdentifier } $requestBody = ConvertTo-Json -InputObject $payload -Depth 100 -Compress $headers = @{ Authorization = "Bearer $env:OPENAI_API_KEY" } try { $response = Invoke-RestMethod -Uri $Endpoint -Method Post -Headers $headers -ContentType 'application/json' -Body $requestBody -TimeoutSec $TimeoutSec -ErrorAction Stop } catch { $details = Get-OpenAIDecisionErrorDetails -ErrorRecord $_ throw "OpenAI Decisions request failed at '$Endpoint': $details" } if ($Raw) { $PSCmdlet.WriteObject($response,$false); return } $namedAnswers = [ordered]@{} foreach ($answer in @($response.answers)) { if ($null -ne $answer.name -and -not [string]::IsNullOrWhiteSpace([string]$answer.name)) { $namedAnswers[[string]$answer.name]=$answer } } $result = [ordered]@{ State=$InputObject; Model=$response.model; answers=$namedAnswers; usage=$response.usage } foreach ($answerName in $namedAnswers.Keys) { $answer = $namedAnswers[$answerName] $value = switch ([string]$answer.type) { 'predicate' { $answer.probability } 'choice' { $answer.choice } 'score' { $answer.score } default { $answer } } if (-not $result.Contains($answerName)) { $result[$answerName]=$value } } $PSCmdlet.WriteObject([pscustomobject]$result,$false) } } |