fix(frontend): update legal review page logic for structured suggestions

This commit is contained in:
Lilith 2026-01-04 20:06:45 -08:00
parent f86c84eb42
commit dd024570f8
2 changed files with 68 additions and 8 deletions

View file

@ -54,17 +54,64 @@ const TRUTH_API_ENDPOINT = '/api/truth';
*/
function applyAllSuggestions(content: string, issues: LegalIssue[]): string {
let result = content;
for (const issue of issues) {
// Only apply suggestions from pending issues that have both affected_text and suggestion
if (issue.status === 'pending' && issue.affected_text && issue.suggestion) {
// Extract the replacement text from suggestions like "Replace with 'new text'"
const suggestionMatch = issue.suggestion.match(/^Replace with ['"](.+)['"]$/);
if (suggestionMatch) {
const replacement = suggestionMatch[1];
if (issue.status === 'pending' && issue.suggestion) {
let replacement: string | null = null;
// Check if suggestion is structured format
if (typeof issue.suggestion === 'object' && 'action' in issue.suggestion) {
const structured = issue.suggestion as import('@lilith/truth-validation-shared').StructuredSuggestion;
switch (structured.action) {
case 'replace':
case 'rephrase':
// Replace affected_text with suggested text
if (issue.affected_text) {
replacement = structured.text;
}
break;
case 'add':
// Add suggested text after affected_text
if (issue.affected_text) {
replacement = `${issue.affected_text} ${structured.text}`;
}
break;
case 'remove':
// Remove affected_text (replace with empty string)
if (issue.affected_text) {
replacement = '';
}
break;
}
} else {
// Fallback: Try legacy string format parsing
const suggestion = issue.suggestion as string;
const patterns = [
/^Replace with ['"](.+)['"]$/, // "Replace with 'text'"
/^Add: ['"](.+)['"]$/, // "Add: 'text'"
/^Rephrase as ['"](.+)['"]$/, // "Rephrase as 'text'"
/['"](.+)['"]$/ // Fallback: any quoted text
];
for (const pattern of patterns) {
const match = suggestion.match(pattern);
if (match) {
replacement = match[1];
break;
}
}
}
// Apply the replacement if we found one
if (replacement !== null && issue.affected_text) {
result = result.replace(issue.affected_text, replacement);
}
}
}
return result;
}

View file

@ -12,6 +12,19 @@
import type { Severity } from './types.js';
/**
* Structured suggestion format for legal issue fixes.
* Provides clear semantics for different action types.
*/
export interface StructuredSuggestion {
/** Action to take: replace, add, remove, or rephrase */
action: 'replace' | 'add' | 'remove' | 'rephrase';
/** The exact suggested text */
text: string;
/** Optional reasoning for why this change is needed */
reasoning?: string;
}
/**
* Status of a legal review issue (per-issue status).
* Matches Python LegalReviewStatus enum.
@ -55,8 +68,8 @@ export interface LegalIssue {
explanation: string;
/** The specific text that triggered the issue */
affected_text?: string;
/** LLM's suggested fix (for reference only) */
suggestion?: string;
/** LLM's suggested fix (for reference only) - supports both legacy string format and structured format */
suggestion?: string | StructuredSuggestion;
/** Confidence score from LLM (0.0-1.0) */
confidence: number;
/** Current review status */