Private/Get-DocumentPovClassification.ps1
|
# Copyright (c) 2026 Jeffrey Snover. All rights reserved. # Licensed under the MIT License. See LICENSE file in the project root. # CHESS pre-classification: lightweight LLM call to identify which POVs a document touches. # Dot-sourced by AITriad.psm1 — do NOT export. function Get-DocumentPovClassification { <# .SYNOPSIS Lightweight CHESS pre-classification: identifies which POV camps a document touches. .DESCRIPTION Makes a fast, cheap AI call (~500 tokens in, ~100 out) to classify which POV camps a document is relevant to. Used to narrow the search space for Get-RelevantTaxonomyNodes — instead of searching all 518 nodes, search only the branches that matter. Returns an array of POV strings: @('accelerationist', 'safetyist', etc.) Always includes 'situations' as a catch-all safety margin per Risk Assessor. .PARAMETER QueryText Document excerpt for classification (title + first 500 words). .PARAMETER Model AI model. Default: gemini-3.1-flash-lite-preview (fast, cheap). .PARAMETER ApiKey API key. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$QueryText, [string]$Model = 'gemini-3.1-flash-lite-preview', [string]$ApiKey = '' ) Set-StrictMode -Version Latest if ([string]::IsNullOrWhiteSpace($ApiKey)) { $ApiKey = Resolve-AIApiKey -ExplicitKey '' -Backend 'gemini' } if (-not $ApiKey) { Write-Verbose 'CHESS: No API key — returning all POVs' return @('accelerationist', 'safetyist', 'skeptic', 'situations') } $Prompt = @" Classify which AI policy perspectives this document excerpt is relevant to. Return ONLY a JSON array of applicable perspectives from this list: ["accelerationist", "safetyist", "skeptic"] Rules: - Include a perspective if the document discusses, supports, critiques, or is relevant to that camp - Most documents touch 2-3 perspectives - If uncertain about a perspective, INCLUDE it (false positives are better than misses) - Return at minimum 1 perspective Document excerpt: $($QueryText.Substring(0, [Math]::Min(2000, $QueryText.Length))) "@ try { $Result = Invoke-AIApi -Prompt $Prompt -Model $Model -ApiKey $ApiKey ` -Temperature 0.1 -MaxTokens 100 -JsonMode -TimeoutSec 15 if ($Result -and $Result.Text) { $CleanText = $Result.Text -replace '(?s)^```json\s*', '' -replace '(?s)\s*```$', '' $Povs = $CleanText.Trim() | ConvertFrom-Json $ValidPovs = @($Povs | Where-Object { $_ -in @('accelerationist', 'safetyist', 'skeptic') }) if ($ValidPovs.Count -gt 0) { # Always include situations as catch-all safety margin $AllPovs = @($ValidPovs) + @('situations') Write-Verbose "CHESS classified: $($ValidPovs -join ', ')" return $AllPovs } } } catch { Write-Verbose "CHESS classification failed: $($_.Exception.Message) — using all POVs" } # Fallback: all POVs return @('accelerationist', 'safetyist', 'skeptic', 'situations') } |