Skip to content

Commit 75403c7

Browse files
committed
feat: add evaluation persistence layer
Add EvaluationPersistence class for localStorage state management. Enables resume capability for long-running evaluations (5-15 min) after page reload. Includes staleness check (1 hour).
1 parent a93ed09 commit 75403c7

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import type { ModelInfo, PersonaInfo } from '../components/chat-header/types';
2+
import type { TestCase, SubmissionItem } from './evaluationViewTypes';
3+
4+
const STORAGE_KEY = 'braindrive_evaluation_in_progress';
5+
const MAX_AGE_MS = 60 * 60 * 1000; // 1 hour
6+
7+
export interface PersistedEvaluationState {
8+
runId: string;
9+
model: ModelInfo;
10+
persona: PersonaInfo | null;
11+
collectionId?: string;
12+
testCases: TestCase[];
13+
processedQuestionIds: string[];
14+
currentBatch: SubmissionItem[];
15+
timestamp: number;
16+
}
17+
18+
export class EvaluationPersistence {
19+
/**
20+
* Save evaluation state to localStorage
21+
*/
22+
static saveState(state: PersistedEvaluationState): void {
23+
try {
24+
const stateWithTimestamp = {
25+
...state,
26+
timestamp: Date.now(),
27+
};
28+
localStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
29+
} catch (error) {
30+
console.error('Failed to save evaluation state:', error);
31+
}
32+
}
33+
34+
/**
35+
* Load evaluation state from localStorage
36+
*/
37+
static loadState(): PersistedEvaluationState | null {
38+
try {
39+
const stored = localStorage.getItem(STORAGE_KEY);
40+
if (!stored) return null;
41+
42+
const state = JSON.parse(stored) as PersistedEvaluationState;
43+
44+
// Check if state is stale
45+
if (this.isStale(state)) {
46+
this.clearState();
47+
return null;
48+
}
49+
50+
return state;
51+
} catch (error) {
52+
console.error('Failed to load evaluation state:', error);
53+
return null;
54+
}
55+
}
56+
57+
/**
58+
* Clear evaluation state from localStorage
59+
*/
60+
static clearState(): void {
61+
try {
62+
localStorage.removeItem(STORAGE_KEY);
63+
} catch (error) {
64+
console.error('Failed to clear evaluation state:', error);
65+
}
66+
}
67+
68+
/**
69+
* Check if state is stale (older than 1 hour)
70+
*/
71+
static isStale(state: PersistedEvaluationState): boolean {
72+
const age = Date.now() - state.timestamp;
73+
return age > MAX_AGE_MS;
74+
}
75+
76+
/**
77+
* Check if there's an in-progress evaluation
78+
*/
79+
static hasInProgressEvaluation(): boolean {
80+
const state = this.loadState();
81+
return state !== null;
82+
}
83+
84+
/**
85+
* Get remaining questions count
86+
*/
87+
static getRemainingQuestionsCount(): number {
88+
const state = this.loadState();
89+
if (!state) return 0;
90+
91+
return state.testCases.length - state.processedQuestionIds.length;
92+
}
93+
}

0 commit comments

Comments
 (0)