public/ConvertTo-FineTuning.ps1
function ConvertTo-FineTuning { <# .SYNOPSIS Converts help text of commands into fine-tuning data for a chatbot using an external service. .DESCRIPTION The ConvertTo-FineTuning function processes command help text to create fine-tuning data for a chatbot. It can take input directly from a pipeline of objects or specify a module to retrieve commands from. The function prepares the data by sending it to an external API and handles the responses to generate the fine-tuning data. .PARAMETER InputObject Objects containing commands to process. These can be piped into the function. .PARAMETER SystemRole A description of the chatbot's system role. If not provided, a default role based on the specified module will be used. .PARAMETER RoundOneInstructions The instructions for the first round of processing. If not provided, default instructions will be used. .PARAMETER RoundTwoInstructions The instructions for the second round of processing. If not provided, default instructions will be used. .PARAMETER Module The name of a module from which to retrieve commands. If specified, the module will be imported if not already present. .PARAMETER As This parameter is currently not used in the function. .EXAMPLE PS C:\> Get-Command -Module Microsoft.PowerShell.Management | ConvertTo-FineTuning Retrieves commands from the specified module and converts their help text into fine-tuning data. .EXAMPLE PS C:\> ConvertTo-FineTuning -Module Microsoft.PowerShell.Management Imports the specified module, retrieves its commands, and converts their help text into fine-tuning data. .EXAMPLE PS C:\> $commands = Get-Command -Module Microsoft.PowerShell.Management PS C:\> ConvertTo-FineTuning -InputObject $commands Uses a variable containing commands from the specified module and converts their help text into fine-tuning data. #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline)] [psobject[]]$InputObject, [string]$SystemRole, [string]$RoundOneInstructions, [string]$RoundTwoInstructions, [string]$Module, [string]$As ) process { if (-not $InputObject -and -not $Module) { Write-Error "You must provide either provide InputObject or Module" return } if ($Module) { Import-Module $Module -ErrorAction Stop $InputObject = Get-Command -Module $Module | Where-Object CommandType -ne Alias | Get-CleanHelp } if ($InputObject.ModuleName) { $Module = $InputObject.ModuleName } if (-not $SystemRole) { if ($Module) { $SystemRole = "You are a friendly support chatbot and PowerShell expert who helps people find the commands and write the code they need for the $Module module" } else { $SystemRole = "You are a friendly support chatbot and PowerShell expert who helps people find the commands and write the code they need" } } if (-not $RoundOneInstructions) { $RoundOneInstructions = (Get-Content -Path "$script:PSModuleRoot\instructions1.txt" -Raw).Replace('--replaceme--', $SystemRole) } if (-not $RoundTwoInstructions) { $RoundTwoInstructions = (Get-Content -Path "$script:PSModuleRoot\instructions2.txt" -Raw).Replace('--replaceme--', $SystemRole) } foreach ($object in $InputObject) { if ($object.Text) { $msg = $object.Text $cmdname = $object.Command } else { $msg = $object } $body = @{ max_tokens = 3000 messages = @( @{ "role" = "system" "content" = $RoundOneInstructions }, @{ "role" = "user" "content" = "$msg" } ) } | ConvertTo-Json -Compress -Depth 10 $splat = @{ Uri = $env:azureaiurl Method = "POST" Headers = @{ "Content-Type" = "application/json" "api-key" = $env:copAIkey } ErrorAction = 'Stop' } try { $results = Invoke-RestMethod @splat -Body $body } catch { Start-Sleep -Seconds 60 try { $results = Invoke-RestMethod @splat -Body $body } catch { Write-Warning "Failed to process the following: $Message" continue } } $inputTokens = $results.usage.prompt_tokens $outputTokens = $results.usage.completion_tokens Write-Verbose "Prompt tokens: $($results.usage.prompt_tokens)" Write-Verbose "Completion: $($results.usage.completion_tokens)" Write-Debug "First result: $($results.choices.message.content)" $body = @{ max_tokens = 3000 messages = @( @{ "role" = "system" "content" = $RoundTwoInstructions }, @{ "role" = "user" "content" = "$script:result1".Replace('```jsonl', '').Replace('```', '') } ) } | ConvertTo-Json -Compress -Depth 10 try { $results = Invoke-RestMethod @splat -Body $body } catch { Start-Sleep -Seconds 60 try { $results = Invoke-RestMethod @splat -Body $body } catch { Write-Warning "Failed to process the following: $Message" continue } } Write-Verbose "Prompt tokens: $($results.usage.prompt_tokens)" Write-Verbose "Completion: $($results.usage.completion_tokens)" $inputtokencost = "0.01" $outputtokencost = "0.03" $allinputtokencost = (($inputTokens + $results.usage.prompt_tokens) / 1000) * $inputtokencost $alloutputtokencost = (($outputTokens + $results.usage.completion_tokens) / 1000) * $outputtokencost Write-Verbose "Input token cost: $allinputtokencost" Write-Verbose "Output token cost: $alloutputtokencost" $script:result2 = $results.choices.message.content $script:result2 = Repair-Json -Json $script:result2 if ($As -eq "String") { $script:result2 } else { [PSCustomObject]@{ Command = $cmdname Text = $script:result2 } } Write-Debug "Second result: $script:result2" $commandcost = $allinputtokencost + $alloutputtokencost $script:totalcost = $script:totalcost + $commandcost Write-Verbose "Command token cost: $commandcost" Write-Verbose "Grand total token cost: $script:totalcost" } } } |