This commit is contained in:
dios.one
2026-04-21 18:00:30 +07:00
parent 2173a765c9
commit 23dc306f12
67 changed files with 10302 additions and 67 deletions
+64
View File
@@ -0,0 +1,64 @@
const FALLBACK = {
identity_title: 'A Better Version of Me',
identity_summary: 'You are starting a journey to transform yourself, step by step. Every small action counts.',
suggested_habits: [
'Do one small positive action today',
'Avoid one bad habit',
'Reflect for 2 minutes before sleep',
],
};
/**
* Safely parse AI JSON response.
* Handles markdown wrapping, broken JSON, and missing fields.
* Always returns a valid result — never throws.
*
* @param {string} raw - Raw text from AI response
* @returns {{ identity_title: string, identity_summary: string, suggested_habits: string[] }}
*/
export default function safeParseAI(raw) {
if (!raw || typeof raw !== 'string') return { ...FALLBACK };
try {
// Strip markdown code fences
let cleaned = raw.trim();
cleaned = cleaned.replace(/```json\s*/gi, '').replace(/```\s*/gi, '');
cleaned = cleaned.trim();
// Find first { and last } to extract JSON object
const start = cleaned.indexOf('{');
const end = cleaned.lastIndexOf('}');
if (start === -1 || end === -1) return { ...FALLBACK };
cleaned = cleaned.slice(start, end + 1);
const parsed = JSON.parse(cleaned);
// Validate required fields
const title = typeof parsed.identity_title === 'string' && parsed.identity_title.trim()
? parsed.identity_title.trim()
: FALLBACK.identity_title;
const summary = typeof parsed.identity_summary === 'string' && parsed.identity_summary.trim()
? parsed.identity_summary.trim()
: FALLBACK.identity_summary;
let habits = FALLBACK.suggested_habits;
if (Array.isArray(parsed.suggested_habits) && parsed.suggested_habits.length > 0) {
habits = parsed.suggested_habits
.filter((h) => typeof h === 'string' && h.trim())
.map((h) => h.trim());
}
if (habits.length === 0) habits = FALLBACK.suggested_habits;
return {
identity_title: title,
identity_summary: summary,
suggested_habits: habits,
};
} catch (_) {
return { ...FALLBACK };
}
}
export { FALLBACK };