← back to Norma
components/email-analyzer/fetchProsCons.ts
97 lines
import type { ProsConsData } from './ProsConsPanel';
/**
* Fetches a pros/cons/suggestions comparison between two email versions
* via the rewrite API endpoint. Used by both the inline comparison panel
* and the compare modal.
*/
export async function fetchProsCons(
originalEmail: string,
newVersion: string,
previousVersion: string,
options?: {
/** Label for the "new" version in the prompt (e.g. "version B") */
newLabel?: string;
/** Label for the "previous" version in the prompt (e.g. "version A") */
previousLabel?: string;
},
): Promise<ProsConsData | null> {
if (!previousVersion || !newVersion) return null;
const newLabel = options?.newLabel ?? 'NEW version';
const previousLabel = options?.previousLabel ?? 'PREVIOUS version';
const instruction = `Compare this ${newLabel} to the ${previousLabel} below. List:
- 2-4 specific pros (improvements over ${previousLabel.toLowerCase()})
- 1-3 cons (things lost or weakened)
- 2-4 suggestions (specific actionable improvements to make this version even stronger)
Be concise -- one sentence each.
${previousLabel.toUpperCase()}:
---
${previousVersion.substring(0, 2000)}
---
Return ONLY a JSON object: {"pros":["..."],"cons":["..."],"suggestions":["..."]}
Do NOT include any other text, markdown fences, or explanation.`;
const res = await fetch('/api/email-analyzer/rewrite', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
originalEmail,
currentVersion: newVersion,
instruction,
chatHistory: [],
}),
});
if (!res.ok) return null;
const data = await res.json();
const raw = (data.rewrittenEmail || '')
.replace(/```json?\s*/gi, '')
.replace(/```/g, '')
.trim();
return parseProsConsJson(raw);
}
/**
* Attempts to parse a pros/cons JSON object from raw text.
* Handles both clean JSON and JSON embedded in other text.
*/
function parseProsConsJson(raw: string): ProsConsData | null {
// First attempt: direct parse
try {
const parsed = JSON.parse(raw);
if (parsed.pros && parsed.cons) {
return {
pros: parsed.pros,
cons: parsed.cons,
suggestions: parsed.suggestions || [],
};
}
} catch {
// Fall through to regex extraction
}
// Second attempt: extract JSON object from surrounding text
const jsonMatch = raw.match(/\{[\s\S]*"pros"[\s\S]*"cons"[\s\S]*\}/);
if (jsonMatch) {
try {
const parsed = JSON.parse(jsonMatch[0]);
return {
pros: parsed.pros || [],
cons: parsed.cons || [],
suggestions: parsed.suggestions || [],
};
} catch {
return null;
}
}
return null;
}