File size: 2,026 Bytes
66eabcc | 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 | export function extractFinalJson(text) {
if (!text) return null;
if (text.includes("</think>")) text = text.split("</think>").at(-1);
text = text.replace(/```(?:json)?\s*/g, "");
const blocks = [];
for (let i = 0; i < text.length; i++) {
if (text[i] !== "{") continue;
let depth = 0;
for (let j = i; j < text.length; j++) {
if (text[j] === "{") depth++;
else if (text[j] === "}") {
depth--;
if (depth === 0) { blocks.push(text.slice(i, j + 1)); break; }
}
}
}
for (let b = blocks.length - 1; b >= 0; b--) {
try { return JSON.parse(blocks[b]); } catch { /* try next */ }
}
return null;
}
export function filterVerbatim(answer, text) {
const out = {};
for (const [k, v] of Object.entries(answer ?? {})) {
if (typeof v === "string" && v && text.includes(v)) out[k] = v;
}
return out;
}
export function buildPrompt(text, mention) {
return (
"Extract attributes of this data mention. Output ONLY a JSON object with " +
"keys producer, year, geography, acronym. Each value must be an exact " +
"substring of the text; omit keys that are absent.\n\n" +
`Mention: "${mention}"\n\nText: ${text}`
);
}
export function buildUsageImpactPrompt(mention, usage, context) {
return (
"Classify the usage and impact of this data mention. Output ONLY a JSON " +
"object with keys data_type, usage_action, impact_label, usage_summary. " +
"usage_summary is one sentence in your own words, derived from the labels; " +
"do not invent specifics not present in the text.\n\n" +
`Mention: "${mention}"\n\nUsage: "${usage}"\n\nText: ${context}`
);
}
export function sentenceContaining(text, mention) {
const idx = text.indexOf(mention);
if (idx < 0) return text;
const re = /[.!?](?=\s|$)/g;
let start = 0;
let end = text.length;
let m;
while ((m = re.exec(text)) !== null) {
if (m.index < idx) start = m.index + 1;
else { end = m.index + 1; break; }
}
return text.slice(start, end).trim();
}
|