-feat 修复json格式问题

This commit is contained in:
2026-01-28 21:48:50 +08:00
parent e163fadd01
commit 303b4ed001
2 changed files with 161 additions and 160 deletions

View File

@@ -289,45 +289,47 @@ Output Requirements:
// Here we choose to throw so fallback static text appears.
throw error;
}
// Cache storage for daily insight
let dailyInsightCache: {
data: { spending: string; budget: string };
timestamp: number;
contentHash: string;
} | null = null;
}
export interface DailyInsightContext {
todaySpend: number;
yesterdaySpend: number;
monthlyBudget: number;
monthlySpent: number;
monthProgress: number; // 0-1
topCategory?: { name: string; amount: number };
maxTransaction?: { note: string; amount: number };
lastWeekSpend?: number;
streakDays?: number;
// Cache storage for daily insight
let dailyInsightCache: {
data: { spending: string; budget: string };
timestamp: number;
contentHash: string;
} | null = null;
export interface DailyInsightContext {
todaySpend: number;
yesterdaySpend: number;
monthlyBudget: number;
monthlySpent: number;
monthProgress: number; // 0-1
topCategory?: { name: string; amount: number };
maxTransaction?: { note: string; amount: number };
lastWeekSpend?: number;
streakDays?: number;
}
/**
* Get AI-powered daily insight
*/
export async function getDailyInsight(context: DailyInsightContext): Promise<{ spending: string; budget: string }> {
// Hash needs to include new fields
const currentHash = JSON.stringify(context);
const NOW = Date.now();
const CACHE_TTL = 30 * 60 * 1000; // 30 Minutes
// 1. Check Cache
if (dailyInsightCache &&
(NOW - dailyInsightCache.timestamp < CACHE_TTL) &&
dailyInsightCache.contentHash === currentHash) {
return dailyInsightCache.data;
}
/**
* Get AI-powered daily insight
*/
export async function getDailyInsight(context: DailyInsightContext): Promise<{ spending: string; budget: string }> {
// Hash needs to include new fields
const currentHash = JSON.stringify(context);
const NOW = Date.now();
const CACHE_TTL = 30 * 60 * 1000; // 30 Minutes
const weekday = new Date().toLocaleDateString('zh-CN', { weekday: 'long' });
const weekDiff = context.lastWeekSpend !== undefined ? (context.todaySpend - context.lastWeekSpend) : 0;
// 1. Check Cache
if (dailyInsightCache &&
(NOW - dailyInsightCache.timestamp < CACHE_TTL) &&
dailyInsightCache.contentHash === currentHash) {
return dailyInsightCache.data;
}
const weekday = new Date().toLocaleDateString('zh-CN', { weekday: 'long' });
const weekDiff = context.lastWeekSpend !== undefined ? (context.todaySpend - context.lastWeekSpend) : 0;
const prompt = `System: 你是 Novault 首席财务AI也是用户的贴身管家。你的点评需要非常有温度、有依据。
const prompt = `System: 你是 Novault 首席财务AI也是用户的贴身管家。你的点评需要非常有温度、有依据。
Context:
- 今天是: ${weekday}
- 连续记账: ${context.streakDays || 0}
@@ -351,63 +353,64 @@ Task:
- 结合月度进度,给出具体行动指南。
`;
try {
const response = await sendChatMessage(prompt);
try {
const response = await sendChatMessage(prompt);
if (response.message) {
let content = response.message.trim();
if (response.message) {
let content = response.message.trim();
// Extract JSON object using regex to handle potential markdown or extra text
const jsonMatch = content.match(/\{[\s\S]*\}/);
if (jsonMatch) {
content = jsonMatch[0];
} else {
// Fallback cleanup if regex fails but it might still be JSON-ish
content = content.replace(/^```json\s*/, '').replace(/\s*```$/, '');
}
let parsed;
try {
parsed = JSON.parse(content);
} catch (e) {
console.warn('AI returned invalid JSON, falling back to raw text split or default', content);
// Fallback: simple split if possible or default
parsed = {
spending: content.slice(0, 50) + '...',
budget: 'AI 分析数据格式异常,请稍后再试。'
};
}
const result = {
spending: parsed.spending || '暂无点评',
budget: parsed.budget || '暂无建议'
};
// Update Cache
dailyInsightCache = {
data: result,
timestamp: NOW,
contentHash: currentHash
};
return result;
// Extract JSON object using regex to handle potential markdown or extra text
const jsonMatch = content.match(/\{[\s\S]*\}/);
if (jsonMatch) {
content = jsonMatch[0];
} else {
// Fallback cleanup if regex fails but it might still be JSON-ish
content = content.replace(/^```json\s*/, '').replace(/\s*```$/, '');
}
throw new Error('No insight received');
} catch (error) {
console.error('Failed to get AI insight:', error);
throw error;
}
}
export default {
getSessionId,
clearSession,
sendChatMessage,
transcribeAudio,
confirmTransaction,
cancelSession,
processVoiceInput,
isConfirmationCardComplete,
formatConfirmationCard,
getFinancialAdvice,
};
let parsed;
try {
parsed = JSON.parse(content);
} catch (e) {
console.warn('AI returned invalid JSON, falling back to raw text split or default', content);
// Fallback: simple split if possible or default
parsed = {
spending: content.slice(0, 50) + '...',
budget: 'AI 分析数据格式异常,请稍后再试。'
};
}
const result = {
spending: parsed.spending || '暂无点评',
budget: parsed.budget || '暂无建议'
};
// Update Cache
dailyInsightCache = {
data: result,
timestamp: NOW,
contentHash: currentHash
};
return result;
}
throw new Error('No insight received');
} catch (error) {
console.error('Failed to get AI insight:', error);
throw error;
}
}
export default {
getSessionId,
clearSession,
sendChatMessage,
transcribeAudio,
confirmTransaction,
cancelSession,
processVoiceInput,
isConfirmationCardComplete,
formatConfirmationCard,
getFinancialAdvice,
getDailyInsight,
};