Examples/Demos/28-what-a-run-cost/EstimateRunCost.ps1
|
# Estimate the cost of a run from Jev's reported token usage. # Defaults reflect TypeSafe's published Jev 1.13 pricing: $0.042 per million input tokens; output is free. param( [string] $Path = "$PSScriptRoot/requests.jsonl", [double] $InputPricePerMillionTokens = 0.042, [double] $OutputPricePerMillionTokens = 0.0 ) $ErrorActionPreference = 'Stop' if ($InputPricePerMillionTokens -lt 0 -or [double]::IsNaN($InputPricePerMillionTokens) -or [double]::IsInfinity($InputPricePerMillionTokens)) { throw 'Input price must be a finite, non-negative number.' } if ($OutputPricePerMillionTokens -lt 0 -or [double]::IsNaN($OutputPricePerMillionTokens) -or [double]::IsInfinity($OutputPricePerMillionTokens)) { throw 'Output price must be a finite, non-negative number.' } Import-Module "$PSScriptRoot/../../../Jev.psd1" $question = New-JevYesNoQuestion -Name specialist -Question 'Does this request need a specialist?' ` -TrueCriteria 'The request needs a specialist to work across systems.' ` -FalseCriteria 'A routine response or one-person account check is enough.' $rows = foreach ($line in Get-Content -LiteralPath $Path) { $request = $line | ConvertFrom-Json if ([string]::IsNullOrWhiteSpace([string] $request.id) -or [string]::IsNullOrWhiteSpace([string] $request.body)) { throw 'Every request needs a non-empty id and body.' } $decision = $request.body | Invoke-Jev -Question $question $inputProperty = if ($null -ne $decision.usage) { $decision.usage.PSObject.Properties['input_tokens'] } else { $null } $outputProperty = if ($null -ne $decision.usage) { $decision.usage.PSObject.Properties['output_tokens'] } else { $null } $hasUsage = $null -ne $inputProperty -and $null -ne $inputProperty.Value -and $null -ne $outputProperty -and $null -ne $outputProperty.Value if ($hasUsage) { $inputTokens = [long] $inputProperty.Value $outputTokens = [long] $outputProperty.Value $estimatedUsd = (($inputTokens * $InputPricePerMillionTokens) + ($outputTokens * $OutputPricePerMillionTokens)) / 1000000 } else { $inputTokens = $null $outputTokens = $null $estimatedUsd = $null } [pscustomobject]@{ Id = $request.id Specialist = [math]::Round([double] $decision.specialist, 2) InputTokens = $inputTokens OutputTokens = $outputTokens EstimatedUsd = if ($null -eq $estimatedUsd) { $null } else { [math]::Round($estimatedUsd, 8) } } } $rows = @($rows) $costedRows = @($rows | Where-Object { $null -ne $_.InputTokens -and $null -ne $_.OutputTokens }) $missingUsageIds = @($rows | Where-Object { $null -eq $_.InputTokens -or $null -eq $_.OutputTokens } | ForEach-Object Id) $totalInputTokens = [long] (($costedRows | Measure-Object -Property InputTokens -Sum).Sum) $totalOutputTokens = [long] (($costedRows | Measure-Object -Property OutputTokens -Sum).Sum) $totalEstimatedUsd = (($totalInputTokens * $InputPricePerMillionTokens) + ($totalOutputTokens * $OutputPricePerMillionTokens)) / 1000000 [pscustomobject]@{ Rows = $rows Summary = [pscustomobject]@{ Requests = $rows.Count RequestsWithUsage = $costedRows.Count MissingUsageIds = $missingUsageIds InputTokens = $totalInputTokens OutputTokens = $totalOutputTokens EstimatedUsd = [math]::Round($totalEstimatedUsd, 8) InputPricePerMillionTokens = $InputPricePerMillionTokens OutputPricePerMillionTokens = $OutputPricePerMillionTokens } } |