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();
}