// Shared upload handling: keep IDs intact and never silently replace a prompt. export function parseJsonlExamples(text) { const examples = []; const prompts = new Map(); const ids = new Set(); text.split(/\r?\n/).forEach((line, index) => { if (!line.trim()) return; const fail = message => { throw new Error(`Line ${index + 1}: ${message}`); }; let obj; try { obj = JSON.parse(line); } catch { fail('invalid JSON'); } if (!obj || typeof obj !== 'object' || Array.isArray(obj)) fail('expected a JSON object'); const llmon = obj.llmon_prompt_dirty || obj.llmon_prompt || obj.prompt; if (typeof llmon !== 'string' || !llmon.trim()) fail('missing "llmon_prompt_dirty" field'); const id = obj.id ?? examples.length; if (!(typeof id === 'string' && id.trim()) && !(Number.isSafeInteger(id) && id >= 0)) { fail('id must be a non-empty string or a non-negative integer'); } if (ids.has(String(id))) fail(`duplicate id "${id}"; use a unique id for each example`); ids.add(String(id)); examples.push({ id, instruction: String(obj.instruction || '').slice(0, 80), has_input: !!String(obj.input || '').trim(), num_distractors: Math.max(0, (llmon.match(/<\|open\|>instr<\|:\|>/g) || []).length - 1), }); prompts.set(id, llmon); }); if (!examples.length) throw new Error('Empty file'); return { examples, prompts }; } // Browser storage may be disabled in an embedded/private browsing session. export function readPalettePreference() { try { return localStorage.getItem('attn_cb_mode') === '1'; } catch { return false; } } export function savePalettePreference(enabled) { try { localStorage.setItem('attn_cb_mode', enabled ? '1' : '0'); } catch { /* Use this session's state. */ } }