fix(frontend): ✨ update legal review page logic for structured suggestions
This commit is contained in:
parent
f86c84eb42
commit
dd024570f8
2 changed files with 68 additions and 8 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue