File size: 2,819 Bytes
08b0543 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | const API_BASE = process.env.REACT_APP_API_URL !== undefined ? process.env.REACT_APP_API_URL : 'http://localhost:8001';
export async function fetchModels() {
const resp = await fetch(`${API_BASE}/api/models`, { cache: 'no-store' });
if (!resp.ok) throw new Error(`Failed to fetch models: ${resp.status}`);
return resp.json();
}
export async function runComparisonStream(query, neonSelections, comparisonModelIds, sessionId, onGroupStart, onResponse, onDone, personaTarget = 'neon-only') {
const resp = await fetch(`${API_BASE}/api/compare/stream`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query,
neon_selections: neonSelections,
comparison_model_ids: comparisonModelIds,
session_id: sessionId,
persona_target: personaTarget,
}),
});
if (!resp.ok) {
const err = await resp.json().catch(() => ({ detail: resp.statusText }));
throw new Error(err.detail || 'Comparison failed');
}
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split('\n\n');
buffer = parts.pop();
for (const part of parts) {
const lines = part.trim().split('\n');
let eventType = 'message';
let data = '';
for (const line of lines) {
if (line.startsWith('event: ')) eventType = line.slice(7).trim();
else if (line.startsWith('data: ')) data = line.slice(6);
}
if (!data) continue;
try {
const parsed = JSON.parse(data);
if (eventType === 'group_start') onGroupStart(parsed);
else if (eventType === 'response') onResponse(parsed);
else if (eventType === 'done') onDone();
} catch (e) {
console.warn('SSE parse error', e, data);
}
}
}
}
export async function uploadCsvComparison(file, neonSelections, comparisonModelIds, personaTarget = 'neon-only') {
const form = new FormData();
form.append('file', file);
form.append('neon_selections', JSON.stringify(neonSelections));
form.append('comparison_model_ids', JSON.stringify(comparisonModelIds));
form.append('persona_target', personaTarget);
const resp = await fetch(`${API_BASE}/api/compare/csv`, {
method: 'POST',
body: form,
});
if (!resp.ok) {
const err = await resp.json().catch(() => ({ detail: resp.statusText }));
throw new Error(err.detail || 'CSV comparison failed');
}
return resp.blob();
}
export async function downloadHistory(sessionId) {
const resp = await fetch(`${API_BASE}/api/history/${sessionId}/csv`);
if (!resp.ok) throw new Error('No history available');
return resp.blob();
}
|