VirtualDeveloper.psm1
|
<#
.SYNOPSIS Core logic for the Virtual Developer Agent. .DESCRIPTION Contains pure functions for filtering comments, detecting state, and building API payloads. This module is self-contained with all dependencies bundled in the Private folder. Copyright (c) Microsoft Corporation. Licensed under the MIT License. #> function Select-UserComment { <# .SYNOPSIS Filters out comments made by the agent itself. #> param( [Parameter(Mandatory=$false)] [array] $Comments, [Parameter(Mandatory=$true)] [string] $AgentIdentity ) if (-not $Comments) { return @() } return $Comments | Where-Object { $_.CreatedBy.UniqueName -ne $AgentIdentity } } function Test-IsFrozen { <# .SYNOPSIS Detects if the conversation is frozen/ready for breakdown. #> param( [Parameter(Mandatory=$false)] [array] $Comments ) if (-not $Comments) { return $false } foreach ($c in $Comments) { if ($c.Text -match '#frozen') { return $true } } return $false } function New-WorkItemPatchParam { <# .SYNOPSIS Constructs the JSON Patch payload for ADO updates. #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification='Pure function creating an object')] param( [Parameter(Mandatory)] [int] $Id, [Parameter(Mandatory)] [hashtable] $Updates, [Parameter(Mandatory)] [string] $ETag ) $patchOps = @() foreach ($key in $Updates.Keys) { $patchOps += @{ op = "add" path = "/fields/$key" value = $Updates[$key] } } return @{ Uri = "https://dev.azure.com/{org}/{project}/_apis/wit/workitems/$Id`?api-version=7.0" Method = "Patch" Headers = @{ "If-Match" = $ETag "Content-Type" = "application/json-patch+json" } Body = ($patchOps | ConvertTo-Json -Depth 10) } } function Invoke-VirtualDeveloper { <# .SYNOPSIS Runs the Virtual Developer Agent against an Azure DevOps Work Item. .DESCRIPTION Analyzes the work item, invokes AI reasoning, and updates the work item with comments or description expansions. .PARAMETER WorkItemId The Azure DevOps Work Item ID to process. .PARAMETER AgentIdentity The display name of the agent (used to filter out its own comments). .PARAMETER MockAgent If specified, uses canned responses instead of calling Copilot. .EXAMPLE Invoke-VirtualDeveloper -WorkItemId 12345 .EXAMPLE Invoke-VirtualDeveloper -WorkItemId 12345 -MockAgent #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [int]$WorkItemId, [Parameter(Mandatory=$false)] [string]$AgentIdentity = "Virtual Developer", [Parameter(Mandatory=$false)] [switch]$MockAgent ) # Use the bundled script from the module's Private folder $scriptPath = Join-Path $PSScriptRoot "Private\start-virtualdeveloper-session.ps1" if (-not (Test-Path $scriptPath)) { throw "Could not find start-virtualdeveloper-session.ps1 in module. Module may be corrupted." } # Execute the script in a fresh PowerShell process to avoid scope conflicts $argList = @("-File", $scriptPath, "-WorkItemId", $WorkItemId, "-AgentIdentity", $AgentIdentity) if ($MockAgent) { $argList += "-MockAgent" } & pwsh @argList } Export-ModuleMember -Function Select-UserComment, Test-IsFrozen, New-WorkItemPatchParam, Invoke-VirtualDeveloper |