data-navigator 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1460,22 +1460,31 @@ var getAllRuleNames = (structure) => {
1460
1460
  return [];
1461
1461
  return Object.keys(structure.navigationRules);
1462
1462
  };
1463
- var levenshtein = (a, b) => {
1463
+ var damerauLevenshtein = (a, b) => {
1464
1464
  const m = a.length;
1465
1465
  const n = b.length;
1466
- const dp = Array(n + 1);
1466
+ const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
1467
+ for (let i = 0; i <= m; i++)
1468
+ dp[i][0] = i;
1467
1469
  for (let j = 0; j <= n; j++)
1468
- dp[j] = j;
1470
+ dp[0][j] = j;
1469
1471
  for (let i = 1; i <= m; i++) {
1470
- let prev = dp[0];
1471
- dp[0] = i;
1472
1472
  for (let j = 1; j <= n; j++) {
1473
- const temp = dp[j];
1474
- dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);
1475
- prev = temp;
1473
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
1474
+ dp[i][j] = Math.min(
1475
+ dp[i - 1][j] + 1,
1476
+ // deletion
1477
+ dp[i][j - 1] + 1,
1478
+ // insertion
1479
+ dp[i - 1][j - 1] + cost
1480
+ // substitution
1481
+ );
1482
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
1483
+ dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + cost);
1484
+ }
1476
1485
  }
1477
1486
  }
1478
- return dp[n];
1487
+ return dp[m][n];
1479
1488
  };
1480
1489
  var maxTypoDistance = (len) => len <= 4 ? 1 : 2;
1481
1490
  var fuzzyMatch = (input, candidates, labels = {}) => {
@@ -1509,7 +1518,7 @@ var fuzzyMatch = (input, candidates, labels = {}) => {
1509
1518
  const typoMatches = [];
1510
1519
  for (let i = 0; i < candidates.length; i++) {
1511
1520
  const c = candidates[i];
1512
- const nameDist = levenshtein(lower, c.toLowerCase());
1521
+ const nameDist = damerauLevenshtein(lower, c.toLowerCase());
1513
1522
  if (nameDist <= threshold) {
1514
1523
  typoMatches.push({ candidate: c, dist: nameDist });
1515
1524
  continue;
@@ -1517,8 +1526,8 @@ var fuzzyMatch = (input, candidates, labels = {}) => {
1517
1526
  if (labels[c]) {
1518
1527
  const words = labels[c].toLowerCase().split(/\s+/);
1519
1528
  for (let w = 0; w < words.length; w++) {
1520
- if (levenshtein(lower, words[w]) <= threshold) {
1521
- typoMatches.push({ candidate: c, dist: levenshtein(lower, words[w]) });
1529
+ if (damerauLevenshtein(lower, words[w]) <= threshold) {
1530
+ typoMatches.push({ candidate: c, dist: damerauLevenshtein(lower, words[w]) });
1522
1531
  break;
1523
1532
  }
1524
1533
  }
package/dist/index.js CHANGED
@@ -1438,22 +1438,31 @@ var getAllRuleNames = (structure) => {
1438
1438
  return [];
1439
1439
  return Object.keys(structure.navigationRules);
1440
1440
  };
1441
- var levenshtein = (a, b) => {
1441
+ var damerauLevenshtein = (a, b) => {
1442
1442
  const m = a.length;
1443
1443
  const n = b.length;
1444
- const dp = Array(n + 1);
1444
+ const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
1445
+ for (let i = 0; i <= m; i++)
1446
+ dp[i][0] = i;
1445
1447
  for (let j = 0; j <= n; j++)
1446
- dp[j] = j;
1448
+ dp[0][j] = j;
1447
1449
  for (let i = 1; i <= m; i++) {
1448
- let prev = dp[0];
1449
- dp[0] = i;
1450
1450
  for (let j = 1; j <= n; j++) {
1451
- const temp = dp[j];
1452
- dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);
1453
- prev = temp;
1451
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
1452
+ dp[i][j] = Math.min(
1453
+ dp[i - 1][j] + 1,
1454
+ // deletion
1455
+ dp[i][j - 1] + 1,
1456
+ // insertion
1457
+ dp[i - 1][j - 1] + cost
1458
+ // substitution
1459
+ );
1460
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
1461
+ dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + cost);
1462
+ }
1454
1463
  }
1455
1464
  }
1456
- return dp[n];
1465
+ return dp[m][n];
1457
1466
  };
1458
1467
  var maxTypoDistance = (len) => len <= 4 ? 1 : 2;
1459
1468
  var fuzzyMatch = (input, candidates, labels = {}) => {
@@ -1487,7 +1496,7 @@ var fuzzyMatch = (input, candidates, labels = {}) => {
1487
1496
  const typoMatches = [];
1488
1497
  for (let i = 0; i < candidates.length; i++) {
1489
1498
  const c = candidates[i];
1490
- const nameDist = levenshtein(lower, c.toLowerCase());
1499
+ const nameDist = damerauLevenshtein(lower, c.toLowerCase());
1491
1500
  if (nameDist <= threshold) {
1492
1501
  typoMatches.push({ candidate: c, dist: nameDist });
1493
1502
  continue;
@@ -1495,8 +1504,8 @@ var fuzzyMatch = (input, candidates, labels = {}) => {
1495
1504
  if (labels[c]) {
1496
1505
  const words = labels[c].toLowerCase().split(/\s+/);
1497
1506
  for (let w = 0; w < words.length; w++) {
1498
- if (levenshtein(lower, words[w]) <= threshold) {
1499
- typoMatches.push({ candidate: c, dist: levenshtein(lower, words[w]) });
1507
+ if (damerauLevenshtein(lower, words[w]) <= threshold) {
1508
+ typoMatches.push({ candidate: c, dist: damerauLevenshtein(lower, words[w]) });
1500
1509
  break;
1501
1510
  }
1502
1511
  }
@@ -1,21 +1,21 @@
1
- var F=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var ue=(e,t)=>{for(var a in t)F(e,a,{get:t[a],enumerable:!0})},me=(e,t,a,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of le(t))!de.call(e,n)&&n!==a&&F(e,n,{get:()=>t[n],enumerable:!(l=ce(t,n))||l.enumerable});return e};var pe=e=>me(F({},"__esModule",{value:!0}),e);var K=(e,t,a)=>new Promise((l,n)=>{var r=i=>{try{s(a.next(i))}catch(u){n(u)}},o=i=>{try{s(a.throw(i))}catch(u){n(u)}},s=i=>i.done?l(i.value):Promise.resolve(i.value).then(r,o);s((a=a.apply(e,t)).next())});var we={};ue(we,{default:()=>be});module.exports=pe(we);var Y={ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",ArrowDown:"down",Period:"forward",Comma:"backward",Escape:"parent",Enter:"child"};var q={left:{key:"ArrowLeft",direction:"source"},right:{key:"ArrowRight",direction:"target"},up:{key:"ArrowUp",direction:"source"},down:{key:"ArrowDown",direction:"target"},child:{key:"Enter",direction:"target"},parent:{key:"Backspace",direction:"source"},backward:{key:"Comma",direction:"source"},forward:{key:"Period",direction:"target"},previous:{key:"Semicolon",direction:"source"},next:{key:"Quote",direction:"target"},exit:{key:"Escape",direction:"target"},help:{key:"KeyY",direction:"target"},undo:{key:"KeyZ",direction:"target"}};var ee=e=>{let t={},a=Y,l=q;return t.moveTo=n=>{let r=e.structure.nodes[n];if(r)return r},t.move=(n,r)=>{if(n){let o=e.structure.nodes[n];if(o.edges){let s=null,i=0,u=l[r];if(!u)return;let f=(y,c)=>{if(y!==r)return null;let d={target:typeof c.target=="string"?c.target:c.target(o,n),source:typeof c.source=="string"?c.source:c.source(o,n)};return d[u.direction]!==n?d[u.direction]:null};for(i=0;i<o.edges.length;i++){let y=e.structure.edges[o.edges[i]];if(y.navigationRules.forEach(c=>{s||(s=f(c,y))}),s)break}return s?t.moveTo(s):void 0}}},t.enter=()=>{if(e.entryPoint)return t.moveTo(e.entryPoint);console.error("No entry point was specified in InputOptions, returning undefined")},t.exit=()=>{if(e.exitPoint)return e.exitPoint;console.error("No exit point was specified in InputOptions, returning undefined")},t.keydownValidator=n=>{let r=a[n.code];if(r)return r},t.focus=n=>{let r=document.getElementById(n);r&&r.focus()},t.setNavigationKeyBindings=n=>{n?(a={},l=n,Object.keys(n).forEach(r=>{let o=n[r];a[o.key]=r})):(a=Y,l=q)},t.setNavigationKeyBindings(e.navigationRules),t};var he=e=>{var t,a,l,n,r;if((t=e.semantics)!=null&&t.label){let o=typeof e.semantics.label=="function"?e.semantics.label():e.semantics.label;if(o)return o}if(!e.derivedNode)return e.data?Object.keys(e.data).map(o=>`${o}: ${e.data[o]}`).join(". ")+". Data point.":e.id;if((a=e.data)!=null&&a.dimensionKey){let o=0,s=Object.keys(e.data.divisions||{});s.forEach(u=>{o+=Object.keys(e.data.divisions[u].values||{}).length});let i=`${e.derivedNode}.`;return i+=s.length&&o?` ${s.length} division${s.length>1?"s":""}, ${o} datapoint${o>1?"s":""}.`:" No child data points.",i+=` ${e.data.type} dimension.`,i}return`${e.derivedNode}: ${(l=e.data)==null?void 0:l[e.derivedNode]}. ${Object.keys(((n=e.data)==null?void 0:n.values)||{}).length} child data point${Object.keys(((r=e.data)==null?void 0:r.values)||{}).length>1?"s":""}. Division.`},ge=(e,t,a)=>{let l=new Set,n=a.navigationRules||{};return t.edges&&t.edges.forEach(r=>{let o=a.edges[r];o&&o.navigationRules.forEach(s=>{let i=n[s];if(!i)return;let u=i.direction==="target"?o.target:o.source,f=typeof u=="function"?u(t,e):u;f&&f!==e&&l.add(s)})}),Array.from(l)},te=e=>e.navigationRules?Object.keys(e.navigationRules):[],J=(e,t)=>{let a=e.length,l=t.length,n=Array(l+1);for(let r=0;r<=l;r++)n[r]=r;for(let r=1;r<=a;r++){let o=n[0];n[0]=r;for(let s=1;s<=l;s++){let i=n[s];n[s]=e[r-1]===t[s-1]?o:1+Math.min(o,n[s],n[s-1]),o=i}}return n[l]},fe=e=>e<=4?1:2,ye=(e,t,a={})=>{let l=e.toLowerCase().trim(),n=t.find(c=>c.toLowerCase()===l);if(n)return{match:n,ambiguous:[]};let r=t.find(c=>a[c]&&a[c].toLowerCase()===l);if(r)return{match:r,ambiguous:[]};let o=t.filter(c=>c.toLowerCase().startsWith(l));if(o.length===1)return{match:o[0],ambiguous:[]};let s=t.filter(c=>{if(!a[c])return!1;let d=a[c].toLowerCase();return d.startsWith(l)?!0:d.split(/\s+/).some(T=>T.startsWith(l))}),i=new Set([...o,...s]),u=Array.from(i);if(u.length===1)return{match:u[0],ambiguous:[]};if(u.length>1)return{match:null,ambiguous:u};let f=fe(l.length),y=[];for(let c=0;c<t.length;c++){let d=t[c],T=J(l,d.toLowerCase());if(T<=f){y.push({candidate:d,dist:T});continue}if(a[d]){let C=a[d].toLowerCase().split(/\s+/);for(let w=0;w<C.length;w++)if(J(l,C[w])<=f){y.push({candidate:d,dist:J(l,C[w])});break}}}return y.length===1?{match:y[0].candidate,ambiguous:[]}:y.length>1?(y.sort((c,d)=>c.dist-d.dist),y[0].dist<y[1].dist?{match:y[0].candidate,ambiguous:[]}:{match:null,ambiguous:y.map(c=>c.candidate)}):{match:null,ambiguous:[]}},G=(e,t)=>t[e]?`${t[e]} (${e})`:e,ve=(e,t,a,l=10)=>{let n=e.toLowerCase(),r=[],o=Object.keys(t.nodes);for(let s=0;s<o.length&&r.length<l;s++){let i=o[s],u=t.nodes[i],f=!1;if(u.data&&!f){let y=Object.keys(u.data);for(let c=0;c<y.length&&!f;c++){let d=u.data[y[c]];d!=null&&typeof d!="object"&&String(d).toLowerCase().includes(n)&&(f=!0)}}!f&&u.derivedNode&&u.derivedNode.toLowerCase().includes(n)&&(f=!0),!f&&i.toLowerCase().includes(n)&&(f=!0),f&&r.push({nodeId:i,description:a(u)})}return r},be=e=>{var _;let{structure:t,container:a,entryPoint:l,describeNode:n=he,commandLabels:r={},onNavigate:o,onExit:s,llm:i,data:u}=e,f=typeof a=="string"?document.getElementById(a):a;if(!f)throw new Error(`textChat: container "${a}" not found`);let y=l||(t.dimensions?(_=t.dimensions[Object.keys(t.dimensions)[0]])==null?void 0:_.nodeId:Object.keys(t.nodes)[0]),c=ee({structure:t,navigationRules:t.navigationRules||{},entryPoint:y}),d=null,T=Math.random().toString(36).slice(2,8),C=[],w=-1,R=null,$=[],ne=()=>{let m=`You are a data assistant helping a user explore a dataset through a text-based navigation interface.
1
+ var F=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var ue=(e,t)=>{for(var a in t)F(e,a,{get:t[a],enumerable:!0})},me=(e,t,a,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of le(t))!de.call(e,r)&&r!==a&&F(e,r,{get:()=>t[r],enumerable:!(s=ce(t,r))||s.enumerable});return e};var he=e=>me(F({},"__esModule",{value:!0}),e);var K=(e,t,a)=>new Promise((s,r)=>{var n=c=>{try{m(a.next(c))}catch(d){r(d)}},o=c=>{try{m(a.throw(c))}catch(d){r(d)}},m=c=>c.done?s(c.value):Promise.resolve(c.value).then(n,o);m((a=a.apply(e,t)).next())});var we={};ue(we,{default:()=>be});module.exports=he(we);var Y={ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",ArrowDown:"down",Period:"forward",Comma:"backward",Escape:"parent",Enter:"child"};var q={left:{key:"ArrowLeft",direction:"source"},right:{key:"ArrowRight",direction:"target"},up:{key:"ArrowUp",direction:"source"},down:{key:"ArrowDown",direction:"target"},child:{key:"Enter",direction:"target"},parent:{key:"Backspace",direction:"source"},backward:{key:"Comma",direction:"source"},forward:{key:"Period",direction:"target"},previous:{key:"Semicolon",direction:"source"},next:{key:"Quote",direction:"target"},exit:{key:"Escape",direction:"target"},help:{key:"KeyY",direction:"target"},undo:{key:"KeyZ",direction:"target"}};var ee=e=>{let t={},a=Y,s=q;return t.moveTo=r=>{let n=e.structure.nodes[r];if(n)return n},t.move=(r,n)=>{if(r){let o=e.structure.nodes[r];if(o.edges){let m=null,c=0,d=s[n];if(!d)return;let f=(y,i)=>{if(y!==n)return null;let l={target:typeof i.target=="string"?i.target:i.target(o,r),source:typeof i.source=="string"?i.source:i.source(o,r)};return l[d.direction]!==r?l[d.direction]:null};for(c=0;c<o.edges.length;c++){let y=e.structure.edges[o.edges[c]];if(y.navigationRules.forEach(i=>{m||(m=f(i,y))}),m)break}return m?t.moveTo(m):void 0}}},t.enter=()=>{if(e.entryPoint)return t.moveTo(e.entryPoint);console.error("No entry point was specified in InputOptions, returning undefined")},t.exit=()=>{if(e.exitPoint)return e.exitPoint;console.error("No exit point was specified in InputOptions, returning undefined")},t.keydownValidator=r=>{let n=a[r.code];if(n)return n},t.focus=r=>{let n=document.getElementById(r);n&&n.focus()},t.setNavigationKeyBindings=r=>{r?(a={},s=r,Object.keys(r).forEach(n=>{let o=r[n];a[o.key]=n})):(a=Y,s=q)},t.setNavigationKeyBindings(e.navigationRules),t};var pe=e=>{var t,a,s,r,n;if((t=e.semantics)!=null&&t.label){let o=typeof e.semantics.label=="function"?e.semantics.label():e.semantics.label;if(o)return o}if(!e.derivedNode)return e.data?Object.keys(e.data).map(o=>`${o}: ${e.data[o]}`).join(". ")+". Data point.":e.id;if((a=e.data)!=null&&a.dimensionKey){let o=0,m=Object.keys(e.data.divisions||{});m.forEach(d=>{o+=Object.keys(e.data.divisions[d].values||{}).length});let c=`${e.derivedNode}.`;return c+=m.length&&o?` ${m.length} division${m.length>1?"s":""}, ${o} datapoint${o>1?"s":""}.`:" No child data points.",c+=` ${e.data.type} dimension.`,c}return`${e.derivedNode}: ${(s=e.data)==null?void 0:s[e.derivedNode]}. ${Object.keys(((r=e.data)==null?void 0:r.values)||{}).length} child data point${Object.keys(((n=e.data)==null?void 0:n.values)||{}).length>1?"s":""}. Division.`},ge=(e,t,a)=>{let s=new Set,r=a.navigationRules||{};return t.edges&&t.edges.forEach(n=>{let o=a.edges[n];o&&o.navigationRules.forEach(m=>{let c=r[m];if(!c)return;let d=c.direction==="target"?o.target:o.source,f=typeof d=="function"?d(t,e):d;f&&f!==e&&s.add(m)})}),Array.from(s)},te=e=>e.navigationRules?Object.keys(e.navigationRules):[],J=(e,t)=>{let a=e.length,s=t.length,r=Array.from({length:a+1},()=>Array(s+1).fill(0));for(let n=0;n<=a;n++)r[n][0]=n;for(let n=0;n<=s;n++)r[0][n]=n;for(let n=1;n<=a;n++)for(let o=1;o<=s;o++){let m=e[n-1]===t[o-1]?0:1;r[n][o]=Math.min(r[n-1][o]+1,r[n][o-1]+1,r[n-1][o-1]+m),n>1&&o>1&&e[n-1]===t[o-2]&&e[n-2]===t[o-1]&&(r[n][o]=Math.min(r[n][o],r[n-2][o-2]+m))}return r[a][s]},fe=e=>e<=4?1:2,ye=(e,t,a={})=>{let s=e.toLowerCase().trim(),r=t.find(i=>i.toLowerCase()===s);if(r)return{match:r,ambiguous:[]};let n=t.find(i=>a[i]&&a[i].toLowerCase()===s);if(n)return{match:n,ambiguous:[]};let o=t.filter(i=>i.toLowerCase().startsWith(s));if(o.length===1)return{match:o[0],ambiguous:[]};let m=t.filter(i=>{if(!a[i])return!1;let l=a[i].toLowerCase();return l.startsWith(s)?!0:l.split(/\s+/).some(T=>T.startsWith(s))}),c=new Set([...o,...m]),d=Array.from(c);if(d.length===1)return{match:d[0],ambiguous:[]};if(d.length>1)return{match:null,ambiguous:d};let f=fe(s.length),y=[];for(let i=0;i<t.length;i++){let l=t[i],T=J(s,l.toLowerCase());if(T<=f){y.push({candidate:l,dist:T});continue}if(a[l]){let C=a[l].toLowerCase().split(/\s+/);for(let w=0;w<C.length;w++)if(J(s,C[w])<=f){y.push({candidate:l,dist:J(s,C[w])});break}}}return y.length===1?{match:y[0].candidate,ambiguous:[]}:y.length>1?(y.sort((i,l)=>i.dist-l.dist),y[0].dist<y[1].dist?{match:y[0].candidate,ambiguous:[]}:{match:null,ambiguous:y.map(i=>i.candidate)}):{match:null,ambiguous:[]}},G=(e,t)=>t[e]?`${t[e]} (${e})`:e,ve=(e,t,a,s=10)=>{let r=e.toLowerCase(),n=[],o=Object.keys(t.nodes);for(let m=0;m<o.length&&n.length<s;m++){let c=o[m],d=t.nodes[c],f=!1;if(d.data&&!f){let y=Object.keys(d.data);for(let i=0;i<y.length&&!f;i++){let l=d.data[y[i]];l!=null&&typeof l!="object"&&String(l).toLowerCase().includes(r)&&(f=!0)}}!f&&d.derivedNode&&d.derivedNode.toLowerCase().includes(r)&&(f=!0),!f&&c.toLowerCase().includes(r)&&(f=!0),f&&n.push({nodeId:c,description:a(d)})}return n},be=e=>{var _;let{structure:t,container:a,entryPoint:s,describeNode:r=pe,commandLabels:n={},onNavigate:o,onExit:m,llm:c,data:d}=e,f=typeof a=="string"?document.getElementById(a):a;if(!f)throw new Error(`textChat: container "${a}" not found`);let y=s||(t.dimensions?(_=t.dimensions[Object.keys(t.dimensions)[0]])==null?void 0:_.nodeId:Object.keys(t.nodes)[0]),i=ee({structure:t,navigationRules:t.navigationRules||{},entryPoint:y}),l=null,T=Math.random().toString(36).slice(2,8),C=[],w=-1,R=null,$=[],ne=()=>{let u=`You are a data assistant helping a user explore a dataset through a text-based navigation interface.
2
2
 
3
- `;if(u&&u.length>0){let p=Object.keys(u[0]),h=u.slice(0,3).map(N=>JSON.stringify(N)).join(`
4
- `);m+=`DATASET SUMMARY:
5
- - Columns: ${p.join(", ")}
6
- - Rows: ${u.length}
3
+ `;if(d&&d.length>0){let h=Object.keys(d[0]),p=d.slice(0,3).map(N=>JSON.stringify(N)).join(`
4
+ `);u+=`DATASET SUMMARY:
5
+ - Columns: ${h.join(", ")}
6
+ - Rows: ${d.length}
7
7
  - Sample (first 3):
8
- ${h}
8
+ ${p}
9
9
 
10
- `,m+=`FULL DATASET (JSON):
11
- `+JSON.stringify(u)+`
10
+ `,u+=`FULL DATASET (JSON):
11
+ `+JSON.stringify(d)+`
12
12
 
13
- `}if(d){let p=t.nodes[d];m+=`CURRENT POSITION: ${p?n(p):d}
13
+ `}if(l){let h=t.nodes[l];u+=`CURRENT POSITION: ${h?r(h):l}
14
14
 
15
- `}else m+=`CURRENT POSITION: Not yet navigated into the structure.
15
+ `}else u+=`CURRENT POSITION: Not yet navigated into the structure.
16
16
 
17
- `;return m+=`PRIORITY: Always prefer answers that can be verified against the dataset. For any statistical or quantitative claim (averages, comparisons, trends, extremes), briefly describe the method you used. Avoid open-ended or contextual claims that go beyond what the data can support \u2014 if the user asks something that cannot be checked against the dataset, say so and suggest they verify externally.
17
+ `;return u+=`PRIORITY: Always prefer answers that can be verified against the dataset. For any statistical or quantitative claim (averages, comparisons, trends, extremes), briefly describe the method you used. Avoid open-ended or contextual claims that go beyond what the data can support \u2014 if the user asks something that cannot be checked against the dataset, say so and suggest they verify externally.
18
18
 
19
- `,m+=`VERIFICATION: When the user asks you to verify a claim, write a short Python script (using the dataset as a JSON array) that computes the answer, and show the expected output. If the claim is too open-ended to verify with code, explain why and recommend external verification.
19
+ `,u+=`VERIFICATION: When the user asks you to verify a claim, write a short Python script (using the dataset as a JSON array) that computes the answer, and show the expected output. If the claim is too open-ended to verify with code, explain why and recommend external verification.
20
20
 
21
- `,m+='IMPORTANT: Your responses may contain errors. The user has been told they can ask you to "verify" any answer, and you will attempt to provide a Python script to check it.',m},L=document.createElement("div");L.className="dn-text-chat";let b=document.createElement("div");b.className="dn-text-chat-log",b.setAttribute("role","log"),b.setAttribute("aria-live","polite"),L.appendChild(b);let B=document.createElement("div");B.className="dn-text-chat-controls";let U=document.createElement("label"),I=document.createElement("input");I.type="checkbox",I.checked=!0,I.addEventListener("change",()=>{b.setAttribute("aria-live",I.checked?"polite":"off")}),U.appendChild(I),U.appendChild(document.createTextNode(" Automatically announce to screen readers")),B.appendChild(U),L.appendChild(B);let O=document.createElement("form");O.className="dn-text-chat-form";let j=document.createElement("label");j.setAttribute("for",`dn-text-chat-input-${T}`),j.className="dn-text-chat-sr-only",j.textContent="Navigation command";let k=document.createElement("input");k.type="text",k.id=`dn-text-chat-input-${T}`,k.autocomplete="off",k.setAttribute("placeholder","Type a command...");let H=document.createElement("button");H.type="submit",H.textContent="Send",O.appendChild(j),O.appendChild(k),O.appendChild(H),L.appendChild(O),f.appendChild(L);let z="";k.addEventListener("keydown",m=>{if(m.key==="ArrowUp"){if(m.preventDefault(),C.length===0)return;w===-1?(z=k.value,w=C.length-1):w>0&&w--,k.value=C[w]}else if(m.key==="ArrowDown"){if(m.preventDefault(),w===-1)return;w<C.length-1?(w++,k.value=C[w]):(w=-1,k.value=z)}});let W=(m,p)=>{let h=document.createElement("div");h.className=`dn-text-chat-message ${p}`,h.textContent=m,b.appendChild(h),b.scrollTop=b.scrollHeight},S=m=>W(m,"dn-text-chat-system"),re=m=>W(`> ${m}`,"dn-text-chat-input-echo"),v=m=>W(m,"dn-text-chat-response"),oe=(m,p)=>{let h=document.createElement("div");h.className="dn-text-chat-message dn-text-chat-response";let N=document.createElement("span");N.textContent=m,h.appendChild(N);let E=document.createElement("ol");E.className="dn-text-chat-choices",p.forEach(P=>{let A=document.createElement("li");A.textContent=P,E.appendChild(A)}),h.appendChild(E),b.appendChild(h),b.scrollTop=b.scrollHeight},V=m=>K(void 0,null,function*(){let p={role:"system",content:ne()};$.push({role:"user",content:m});let h=document.createElement("div");h.className="dn-text-chat-message dn-text-chat-llm-thinking",h.textContent="Thinking...",b.appendChild(h),b.scrollTop=b.scrollHeight;try{let N=yield i([p,...$]);return b.removeChild(h),N===null?($.pop(),null):($.push({role:"assistant",content:N}),v(N),N)}catch(N){return b.removeChild(h),$.pop(),v(`Error: ${N.message||"Could not get a response."}`),""}});i?(S('Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.'),S('Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.')):S('Text navigation ready. Type "enter" to begin or "help" for available commands.');let Q=["enter","help","more","more help","clear"],Z=m=>{let p=c.moveTo(m);p?(d=p.id,o&&o(p),v(`Moved to: ${n(p)}`)):v("Could not move to that node.")},X=m=>K(void 0,null,function*(){let p=m.trim();if(!p)return;re(p);let h=p.toLowerCase();if(R){let g=parseInt(p,10);if(!isNaN(g)&&g>=1&&g<=R.length){let x=R[g-1];R=null,Z(x.nodeId);return}R=null}if(h==="clear"){b.innerHTML="",S('Chat cleared. Type "help" for available commands.');return}if(h==="enter"){if(d){v('Already in the structure. Type "help" to see available commands.');return}let g=c.enter();if(!g){v("Could not enter the structure. No entry point found.");return}d=g.id,o&&o(g),v(`Entered: ${n(g)}`);return}if(h==="help"){let g=i?" You can also type any question about the data.":"";if(!d)v('Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.'+g);else{let x=t.nodes[d],ie=ge(d,x,t).map(se=>G(se,r));v(`Available: ${ie.join(", ")}, move to <search>.`+g)}return}if(h.startsWith("move to ")){let g=p.slice(8).trim();if(!g){v("Usage: move to <search term>");return}let x=ve(g,t,n);x.length===0?v(`No nodes found matching "${g}".`):x.length===1?Z(x[0].nodeId):(R=x,oe(`Found ${x.length} matches. Type a number to move there:`,x.map(D=>D.description)));return}if(h==="more"||h==="more help"){let x=te(t).map(D=>G(D,r));v(`All navigation rules: ${x.join(", ")}.`);return}if(!d){if(i&&(yield V(p))!==null)return;v('Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.'+(i?" Enter an API key above to ask questions about the data.":""));return}let N=te(t),{match:E,ambiguous:P}=ye(h,[...N,...Q],r);if(E&&Q.includes(E)){yield X(E);return}if(!E&&P.length>0){let g=P.map(x=>G(x,r));v(`Did you mean: ${g.join(", ")}?`);return}if(!E){if(i&&(yield V(p))!==null)return;let g=i?" Enter an API key above to ask questions about the data.":"";v(`Unknown command "${p}". Type "help" for available commands.`+g);return}let A=E,ae=r[A]||A;if(A==="exit"){d=null,s&&s(),v('Exited the structure. Type "enter" to re-enter.');return}let M=c.move(d,A);M?(d=M.id,o&&o(M),v(`${ae}: ${n(M)}`)):v(`Cannot move "${A}" from here.`)});return O.addEventListener("submit",m=>K(void 0,null,function*(){m.preventDefault();let p=k.value.trim();p&&(C.push(p),w=-1),yield X(k.value),k.value="",k.focus()})),{destroy(){f.removeChild(L)},getCurrentNode(){return d&&t.nodes[d]||null}}};
21
+ `,u+='IMPORTANT: Your responses may contain errors. The user has been told they can ask you to "verify" any answer, and you will attempt to provide a Python script to check it.',u},L=document.createElement("div");L.className="dn-text-chat";let b=document.createElement("div");b.className="dn-text-chat-log",b.setAttribute("role","log"),b.setAttribute("aria-live","polite"),L.appendChild(b);let B=document.createElement("div");B.className="dn-text-chat-controls";let U=document.createElement("label"),I=document.createElement("input");I.type="checkbox",I.checked=!0,I.addEventListener("change",()=>{b.setAttribute("aria-live",I.checked?"polite":"off")}),U.appendChild(I),U.appendChild(document.createTextNode(" Automatically announce to screen readers")),B.appendChild(U),L.appendChild(B);let O=document.createElement("form");O.className="dn-text-chat-form";let j=document.createElement("label");j.setAttribute("for",`dn-text-chat-input-${T}`),j.className="dn-text-chat-sr-only",j.textContent="Navigation command";let k=document.createElement("input");k.type="text",k.id=`dn-text-chat-input-${T}`,k.autocomplete="off",k.setAttribute("placeholder","Type a command...");let H=document.createElement("button");H.type="submit",H.textContent="Send",O.appendChild(j),O.appendChild(k),O.appendChild(H),L.appendChild(O),f.appendChild(L);let z="";k.addEventListener("keydown",u=>{if(u.key==="ArrowUp"){if(u.preventDefault(),C.length===0)return;w===-1?(z=k.value,w=C.length-1):w>0&&w--,k.value=C[w]}else if(u.key==="ArrowDown"){if(u.preventDefault(),w===-1)return;w<C.length-1?(w++,k.value=C[w]):(w=-1,k.value=z)}});let W=(u,h)=>{let p=document.createElement("div");p.className=`dn-text-chat-message ${h}`,p.textContent=u,b.appendChild(p),b.scrollTop=b.scrollHeight},S=u=>W(u,"dn-text-chat-system"),re=u=>W(`> ${u}`,"dn-text-chat-input-echo"),v=u=>W(u,"dn-text-chat-response"),oe=(u,h)=>{let p=document.createElement("div");p.className="dn-text-chat-message dn-text-chat-response";let N=document.createElement("span");N.textContent=u,p.appendChild(N);let E=document.createElement("ol");E.className="dn-text-chat-choices",h.forEach(P=>{let A=document.createElement("li");A.textContent=P,E.appendChild(A)}),p.appendChild(E),b.appendChild(p),b.scrollTop=b.scrollHeight},V=u=>K(void 0,null,function*(){let h={role:"system",content:ne()};$.push({role:"user",content:u});let p=document.createElement("div");p.className="dn-text-chat-message dn-text-chat-llm-thinking",p.textContent="Thinking...",b.appendChild(p),b.scrollTop=b.scrollHeight;try{let N=yield c([h,...$]);return b.removeChild(p),N===null?($.pop(),null):($.push({role:"assistant",content:N}),v(N),N)}catch(N){return b.removeChild(p),$.pop(),v(`Error: ${N.message||"Could not get a response."}`),""}});c?(S('Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.'),S('Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.')):S('Text navigation ready. Type "enter" to begin or "help" for available commands.');let Q=["enter","help","more","more help","clear"],Z=u=>{let h=i.moveTo(u);h?(l=h.id,o&&o(h),v(`Moved to: ${r(h)}`)):v("Could not move to that node.")},X=u=>K(void 0,null,function*(){let h=u.trim();if(!h)return;re(h);let p=h.toLowerCase();if(R){let g=parseInt(h,10);if(!isNaN(g)&&g>=1&&g<=R.length){let x=R[g-1];R=null,Z(x.nodeId);return}R=null}if(p==="clear"){b.innerHTML="",S('Chat cleared. Type "help" for available commands.');return}if(p==="enter"){if(l){v('Already in the structure. Type "help" to see available commands.');return}let g=i.enter();if(!g){v("Could not enter the structure. No entry point found.");return}l=g.id,o&&o(g),v(`Entered: ${r(g)}`);return}if(p==="help"){let g=c?" You can also type any question about the data.":"";if(!l)v('Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.'+g);else{let x=t.nodes[l],ie=ge(l,x,t).map(se=>G(se,n));v(`Available: ${ie.join(", ")}, move to <search>.`+g)}return}if(p.startsWith("move to ")){let g=h.slice(8).trim();if(!g){v("Usage: move to <search term>");return}let x=ve(g,t,r);x.length===0?v(`No nodes found matching "${g}".`):x.length===1?Z(x[0].nodeId):(R=x,oe(`Found ${x.length} matches. Type a number to move there:`,x.map(D=>D.description)));return}if(p==="more"||p==="more help"){let x=te(t).map(D=>G(D,n));v(`All navigation rules: ${x.join(", ")}.`);return}if(!l){if(c&&(yield V(h))!==null)return;v('Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.'+(c?" Enter an API key above to ask questions about the data.":""));return}let N=te(t),{match:E,ambiguous:P}=ye(p,[...N,...Q],n);if(E&&Q.includes(E)){yield X(E);return}if(!E&&P.length>0){let g=P.map(x=>G(x,n));v(`Did you mean: ${g.join(", ")}?`);return}if(!E){if(c&&(yield V(h))!==null)return;let g=c?" Enter an API key above to ask questions about the data.":"";v(`Unknown command "${h}". Type "help" for available commands.`+g);return}let A=E,ae=n[A]||A;if(A==="exit"){l=null,m&&m(),v('Exited the structure. Type "enter" to re-enter.');return}let M=i.move(l,A);M?(l=M.id,o&&o(M),v(`${ae}: ${r(M)}`)):v(`Cannot move "${A}" from here.`)});return O.addEventListener("submit",u=>K(void 0,null,function*(){u.preventDefault();let h=k.value.trim();h&&(C.push(h),w=-1),yield X(k.value),k.value="",k.focus()})),{destroy(){f.removeChild(L)},getCurrentNode(){return l&&t.nodes[l]||null}}};
package/dist/text-chat.js CHANGED
@@ -1,21 +1,21 @@
1
- import{a as X}from"./chunk-FP25I6TN.js";import"./chunk-MPFBSVCV.js";import{c as H}from"./chunk-RGY6OTGO.js";var at=t=>{var e,g,l,i,a;if((e=t.semantics)!=null&&e.label){let n=typeof t.semantics.label=="function"?t.semantics.label():t.semantics.label;if(n)return n}if(!t.derivedNode)return t.data?Object.keys(t.data).map(n=>`${n}: ${t.data[n]}`).join(". ")+". Data point.":t.id;if((g=t.data)!=null&&g.dimensionKey){let n=0,d=Object.keys(t.data.divisions||{});d.forEach(u=>{n+=Object.keys(t.data.divisions[u].values||{}).length});let h=`${t.derivedNode}.`;return h+=d.length&&n?` ${d.length} division${d.length>1?"s":""}, ${n} datapoint${n>1?"s":""}.`:" No child data points.",h+=` ${t.data.type} dimension.`,h}return`${t.derivedNode}: ${(l=t.data)==null?void 0:l[t.derivedNode]}. ${Object.keys(((i=t.data)==null?void 0:i.values)||{}).length} child data point${Object.keys(((a=t.data)==null?void 0:a.values)||{}).length>1?"s":""}. Division.`},rt=(t,e,g)=>{let l=new Set,i=g.navigationRules||{};return e.edges&&e.edges.forEach(a=>{let n=g.edges[a];n&&n.navigationRules.forEach(d=>{let h=i[d];if(!h)return;let u=h.direction==="target"?n.target:n.source,f=typeof u=="function"?u(e,t):u;f&&f!==t&&l.add(d)})}),Array.from(l)},Z=t=>t.navigationRules?Object.keys(t.navigationRules):[],Y=(t,e)=>{let g=t.length,l=e.length,i=Array(l+1);for(let a=0;a<=l;a++)i[a]=a;for(let a=1;a<=g;a++){let n=i[0];i[0]=a;for(let d=1;d<=l;d++){let h=i[d];i[d]=t[a-1]===e[d-1]?n:1+Math.min(n,i[d],i[d-1]),n=h}}return i[l]},it=t=>t<=4?1:2,ct=(t,e,g={})=>{let l=t.toLowerCase().trim(),i=e.find(c=>c.toLowerCase()===l);if(i)return{match:i,ambiguous:[]};let a=e.find(c=>g[c]&&g[c].toLowerCase()===l);if(a)return{match:a,ambiguous:[]};let n=e.filter(c=>c.toLowerCase().startsWith(l));if(n.length===1)return{match:n[0],ambiguous:[]};let d=e.filter(c=>{if(!g[c])return!1;let s=g[c].toLowerCase();return s.startsWith(l)?!0:s.split(/\s+/).some($=>$.startsWith(l))}),h=new Set([...n,...d]),u=Array.from(h);if(u.length===1)return{match:u[0],ambiguous:[]};if(u.length>1)return{match:null,ambiguous:u};let f=it(l.length),x=[];for(let c=0;c<e.length;c++){let s=e[c],$=Y(l,s.toLowerCase());if($<=f){x.push({candidate:s,dist:$});continue}if(g[s]){let E=g[s].toLowerCase().split(/\s+/);for(let b=0;b<E.length;b++)if(Y(l,E[b])<=f){x.push({candidate:s,dist:Y(l,E[b])});break}}}return x.length===1?{match:x[0].candidate,ambiguous:[]}:x.length>1?(x.sort((c,s)=>c.dist-s.dist),x[0].dist<x[1].dist?{match:x[0].candidate,ambiguous:[]}:{match:null,ambiguous:x.map(c=>c.candidate)}):{match:null,ambiguous:[]}},J=(t,e)=>e[t]?`${e[t]} (${t})`:t,lt=(t,e,g,l=10)=>{let i=t.toLowerCase(),a=[],n=Object.keys(e.nodes);for(let d=0;d<n.length&&a.length<l;d++){let h=n[d],u=e.nodes[h],f=!1;if(u.data&&!f){let x=Object.keys(u.data);for(let c=0;c<x.length&&!f;c++){let s=u.data[x[c]];s!=null&&typeof s!="object"&&String(s).toLowerCase().includes(i)&&(f=!0)}}!f&&u.derivedNode&&u.derivedNode.toLowerCase().includes(i)&&(f=!0),!f&&h.toLowerCase().includes(i)&&(f=!0),f&&a.push({nodeId:h,description:g(u)})}return a},ut=t=>{var Q;let{structure:e,container:g,entryPoint:l,describeNode:i=at,commandLabels:a={},onNavigate:n,onExit:d,llm:h,data:u}=t,f=typeof g=="string"?document.getElementById(g):g;if(!f)throw new Error(`textChat: container "${g}" not found`);let x=l||(e.dimensions?(Q=e.dimensions[Object.keys(e.dimensions)[0]])==null?void 0:Q.nodeId:Object.keys(e.nodes)[0]),c=X({structure:e,navigationRules:e.navigationRules||{},entryPoint:x}),s=null,$=Math.random().toString(36).slice(2,8),E=[],b=-1,A=null,R=[],_=()=>{let o=`You are a data assistant helping a user explore a dataset through a text-based navigation interface.
1
+ import{a as X}from"./chunk-FP25I6TN.js";import"./chunk-MPFBSVCV.js";import{c as H}from"./chunk-RGY6OTGO.js";var at=t=>{var o,l,d,r,n;if((o=t.semantics)!=null&&o.label){let e=typeof t.semantics.label=="function"?t.semantics.label():t.semantics.label;if(e)return e}if(!t.derivedNode)return t.data?Object.keys(t.data).map(e=>`${e}: ${t.data[e]}`).join(". ")+". Data point.":t.id;if((l=t.data)!=null&&l.dimensionKey){let e=0,g=Object.keys(t.data.divisions||{});g.forEach(u=>{e+=Object.keys(t.data.divisions[u].values||{}).length});let p=`${t.derivedNode}.`;return p+=g.length&&e?` ${g.length} division${g.length>1?"s":""}, ${e} datapoint${e>1?"s":""}.`:" No child data points.",p+=` ${t.data.type} dimension.`,p}return`${t.derivedNode}: ${(d=t.data)==null?void 0:d[t.derivedNode]}. ${Object.keys(((r=t.data)==null?void 0:r.values)||{}).length} child data point${Object.keys(((n=t.data)==null?void 0:n.values)||{}).length>1?"s":""}. Division.`},rt=(t,o,l)=>{let d=new Set,r=l.navigationRules||{};return o.edges&&o.edges.forEach(n=>{let e=l.edges[n];e&&e.navigationRules.forEach(g=>{let p=r[g];if(!p)return;let u=p.direction==="target"?e.target:e.source,f=typeof u=="function"?u(o,t):u;f&&f!==t&&d.add(g)})}),Array.from(d)},Z=t=>t.navigationRules?Object.keys(t.navigationRules):[],Y=(t,o)=>{let l=t.length,d=o.length,r=Array.from({length:l+1},()=>Array(d+1).fill(0));for(let n=0;n<=l;n++)r[n][0]=n;for(let n=0;n<=d;n++)r[0][n]=n;for(let n=1;n<=l;n++)for(let e=1;e<=d;e++){let g=t[n-1]===o[e-1]?0:1;r[n][e]=Math.min(r[n-1][e]+1,r[n][e-1]+1,r[n-1][e-1]+g),n>1&&e>1&&t[n-1]===o[e-2]&&t[n-2]===o[e-1]&&(r[n][e]=Math.min(r[n][e],r[n-2][e-2]+g))}return r[l][d]},it=t=>t<=4?1:2,ct=(t,o,l={})=>{let d=t.toLowerCase().trim(),r=o.find(c=>c.toLowerCase()===d);if(r)return{match:r,ambiguous:[]};let n=o.find(c=>l[c]&&l[c].toLowerCase()===d);if(n)return{match:n,ambiguous:[]};let e=o.filter(c=>c.toLowerCase().startsWith(d));if(e.length===1)return{match:e[0],ambiguous:[]};let g=o.filter(c=>{if(!l[c])return!1;let a=l[c].toLowerCase();return a.startsWith(d)?!0:a.split(/\s+/).some($=>$.startsWith(d))}),p=new Set([...e,...g]),u=Array.from(p);if(u.length===1)return{match:u[0],ambiguous:[]};if(u.length>1)return{match:null,ambiguous:u};let f=it(d.length),x=[];for(let c=0;c<o.length;c++){let a=o[c],$=Y(d,a.toLowerCase());if($<=f){x.push({candidate:a,dist:$});continue}if(l[a]){let E=l[a].toLowerCase().split(/\s+/);for(let b=0;b<E.length;b++)if(Y(d,E[b])<=f){x.push({candidate:a,dist:Y(d,E[b])});break}}}return x.length===1?{match:x[0].candidate,ambiguous:[]}:x.length>1?(x.sort((c,a)=>c.dist-a.dist),x[0].dist<x[1].dist?{match:x[0].candidate,ambiguous:[]}:{match:null,ambiguous:x.map(c=>c.candidate)}):{match:null,ambiguous:[]}},J=(t,o)=>o[t]?`${o[t]} (${t})`:t,lt=(t,o,l,d=10)=>{let r=t.toLowerCase(),n=[],e=Object.keys(o.nodes);for(let g=0;g<e.length&&n.length<d;g++){let p=e[g],u=o.nodes[p],f=!1;if(u.data&&!f){let x=Object.keys(u.data);for(let c=0;c<x.length&&!f;c++){let a=u.data[x[c]];a!=null&&typeof a!="object"&&String(a).toLowerCase().includes(r)&&(f=!0)}}!f&&u.derivedNode&&u.derivedNode.toLowerCase().includes(r)&&(f=!0),!f&&p.toLowerCase().includes(r)&&(f=!0),f&&n.push({nodeId:p,description:l(u)})}return n},ut=t=>{var Q;let{structure:o,container:l,entryPoint:d,describeNode:r=at,commandLabels:n={},onNavigate:e,onExit:g,llm:p,data:u}=t,f=typeof l=="string"?document.getElementById(l):l;if(!f)throw new Error(`textChat: container "${l}" not found`);let x=d||(o.dimensions?(Q=o.dimensions[Object.keys(o.dimensions)[0]])==null?void 0:Q.nodeId:Object.keys(o.nodes)[0]),c=X({structure:o,navigationRules:o.navigationRules||{},entryPoint:x}),a=null,$=Math.random().toString(36).slice(2,8),E=[],b=-1,A=null,R=[],_=()=>{let s=`You are a data assistant helping a user explore a dataset through a text-based navigation interface.
2
2
 
3
- `;if(u&&u.length>0){let r=Object.keys(u[0]),m=u.slice(0,3).map(N=>JSON.stringify(N)).join(`
4
- `);o+=`DATASET SUMMARY:
5
- - Columns: ${r.join(", ")}
3
+ `;if(u&&u.length>0){let i=Object.keys(u[0]),m=u.slice(0,3).map(N=>JSON.stringify(N)).join(`
4
+ `);s+=`DATASET SUMMARY:
5
+ - Columns: ${i.join(", ")}
6
6
  - Rows: ${u.length}
7
7
  - Sample (first 3):
8
8
  ${m}
9
9
 
10
- `,o+=`FULL DATASET (JSON):
10
+ `,s+=`FULL DATASET (JSON):
11
11
  `+JSON.stringify(u)+`
12
12
 
13
- `}if(s){let r=e.nodes[s];o+=`CURRENT POSITION: ${r?i(r):s}
13
+ `}if(a){let i=o.nodes[a];s+=`CURRENT POSITION: ${i?r(i):a}
14
14
 
15
- `}else o+=`CURRENT POSITION: Not yet navigated into the structure.
15
+ `}else s+=`CURRENT POSITION: Not yet navigated into the structure.
16
16
 
17
- `;return o+=`PRIORITY: Always prefer answers that can be verified against the dataset. For any statistical or quantitative claim (averages, comparisons, trends, extremes), briefly describe the method you used. Avoid open-ended or contextual claims that go beyond what the data can support \u2014 if the user asks something that cannot be checked against the dataset, say so and suggest they verify externally.
17
+ `;return s+=`PRIORITY: Always prefer answers that can be verified against the dataset. For any statistical or quantitative claim (averages, comparisons, trends, extremes), briefly describe the method you used. Avoid open-ended or contextual claims that go beyond what the data can support \u2014 if the user asks something that cannot be checked against the dataset, say so and suggest they verify externally.
18
18
 
19
- `,o+=`VERIFICATION: When the user asks you to verify a claim, write a short Python script (using the dataset as a JSON array) that computes the answer, and show the expected output. If the claim is too open-ended to verify with code, explain why and recommend external verification.
19
+ `,s+=`VERIFICATION: When the user asks you to verify a claim, write a short Python script (using the dataset as a JSON array) that computes the answer, and show the expected output. If the claim is too open-ended to verify with code, explain why and recommend external verification.
20
20
 
21
- `,o+='IMPORTANT: Your responses may contain errors. The user has been told they can ask you to "verify" any answer, and you will attempt to provide a Python script to check it.',o},L=document.createElement("div");L.className="dn-text-chat";let v=document.createElement("div");v.className="dn-text-chat-log",v.setAttribute("role","log"),v.setAttribute("aria-live","polite"),L.appendChild(v);let U=document.createElement("div");U.className="dn-text-chat-controls";let q=document.createElement("label"),O=document.createElement("input");O.type="checkbox",O.checked=!0,O.addEventListener("change",()=>{v.setAttribute("aria-live",O.checked?"polite":"off")}),q.appendChild(O),q.appendChild(document.createTextNode(" Automatically announce to screen readers")),U.appendChild(q),L.appendChild(U);let I=document.createElement("form");I.className="dn-text-chat-form";let j=document.createElement("label");j.setAttribute("for",`dn-text-chat-input-${$}`),j.className="dn-text-chat-sr-only",j.textContent="Navigation command";let w=document.createElement("input");w.type="text",w.id=`dn-text-chat-input-${$}`,w.autocomplete="off",w.setAttribute("placeholder","Type a command...");let F=document.createElement("button");F.type="submit",F.textContent="Send",I.appendChild(j),I.appendChild(w),I.appendChild(F),L.appendChild(I),f.appendChild(L);let K="";w.addEventListener("keydown",o=>{if(o.key==="ArrowUp"){if(o.preventDefault(),E.length===0)return;b===-1?(K=w.value,b=E.length-1):b>0&&b--,w.value=E[b]}else if(o.key==="ArrowDown"){if(o.preventDefault(),b===-1)return;b<E.length-1?(b++,w.value=E[b]):(b=-1,w.value=K)}});let W=(o,r)=>{let m=document.createElement("div");m.className=`dn-text-chat-message ${r}`,m.textContent=o,v.appendChild(m),v.scrollTop=v.scrollHeight},M=o=>W(o,"dn-text-chat-system"),tt=o=>W(`> ${o}`,"dn-text-chat-input-echo"),y=o=>W(o,"dn-text-chat-response"),et=(o,r)=>{let m=document.createElement("div");m.className="dn-text-chat-message dn-text-chat-response";let N=document.createElement("span");N.textContent=o,m.appendChild(N);let T=document.createElement("ol");T.className="dn-text-chat-choices",r.forEach(S=>{let k=document.createElement("li");k.textContent=S,T.appendChild(k)}),m.appendChild(T),v.appendChild(m),v.scrollTop=v.scrollHeight},z=o=>H(void 0,null,function*(){let r={role:"system",content:_()};R.push({role:"user",content:o});let m=document.createElement("div");m.className="dn-text-chat-message dn-text-chat-llm-thinking",m.textContent="Thinking...",v.appendChild(m),v.scrollTop=v.scrollHeight;try{let N=yield h([r,...R]);return v.removeChild(m),N===null?(R.pop(),null):(R.push({role:"assistant",content:N}),y(N),N)}catch(N){return v.removeChild(m),R.pop(),y(`Error: ${N.message||"Could not get a response."}`),""}});h?(M('Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.'),M('Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.')):M('Text navigation ready. Type "enter" to begin or "help" for available commands.');let B=["enter","help","more","more help","clear"],V=o=>{let r=c.moveTo(o);r?(s=r.id,n&&n(r),y(`Moved to: ${i(r)}`)):y("Could not move to that node.")},G=o=>H(void 0,null,function*(){let r=o.trim();if(!r)return;tt(r);let m=r.toLowerCase();if(A){let p=parseInt(r,10);if(!isNaN(p)&&p>=1&&p<=A.length){let C=A[p-1];A=null,V(C.nodeId);return}A=null}if(m==="clear"){v.innerHTML="",M('Chat cleared. Type "help" for available commands.');return}if(m==="enter"){if(s){y('Already in the structure. Type "help" to see available commands.');return}let p=c.enter();if(!p){y("Could not enter the structure. No entry point found.");return}s=p.id,n&&n(p),y(`Entered: ${i(p)}`);return}if(m==="help"){let p=h?" You can also type any question about the data.":"";if(!s)y('Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.'+p);else{let C=e.nodes[s],ot=rt(s,C,e).map(st=>J(st,a));y(`Available: ${ot.join(", ")}, move to <search>.`+p)}return}if(m.startsWith("move to ")){let p=r.slice(8).trim();if(!p){y("Usage: move to <search term>");return}let C=lt(p,e,i);C.length===0?y(`No nodes found matching "${p}".`):C.length===1?V(C[0].nodeId):(A=C,et(`Found ${C.length} matches. Type a number to move there:`,C.map(D=>D.description)));return}if(m==="more"||m==="more help"){let C=Z(e).map(D=>J(D,a));y(`All navigation rules: ${C.join(", ")}.`);return}if(!s){if(h&&(yield z(r))!==null)return;y('Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.'+(h?" Enter an API key above to ask questions about the data.":""));return}let N=Z(e),{match:T,ambiguous:S}=ct(m,[...N,...B],a);if(T&&B.includes(T)){yield G(T);return}if(!T&&S.length>0){let p=S.map(C=>J(C,a));y(`Did you mean: ${p.join(", ")}?`);return}if(!T){if(h&&(yield z(r))!==null)return;let p=h?" Enter an API key above to ask questions about the data.":"";y(`Unknown command "${r}". Type "help" for available commands.`+p);return}let k=T,nt=a[k]||k;if(k==="exit"){s=null,d&&d(),y('Exited the structure. Type "enter" to re-enter.');return}let P=c.move(s,k);P?(s=P.id,n&&n(P),y(`${nt}: ${i(P)}`)):y(`Cannot move "${k}" from here.`)});return I.addEventListener("submit",o=>H(void 0,null,function*(){o.preventDefault();let r=w.value.trim();r&&(E.push(r),b=-1),yield G(w.value),w.value="",w.focus()})),{destroy(){f.removeChild(L)},getCurrentNode(){return s&&e.nodes[s]||null}}};export{ut as default};
21
+ `,s+='IMPORTANT: Your responses may contain errors. The user has been told they can ask you to "verify" any answer, and you will attempt to provide a Python script to check it.',s},L=document.createElement("div");L.className="dn-text-chat";let v=document.createElement("div");v.className="dn-text-chat-log",v.setAttribute("role","log"),v.setAttribute("aria-live","polite"),L.appendChild(v);let U=document.createElement("div");U.className="dn-text-chat-controls";let q=document.createElement("label"),O=document.createElement("input");O.type="checkbox",O.checked=!0,O.addEventListener("change",()=>{v.setAttribute("aria-live",O.checked?"polite":"off")}),q.appendChild(O),q.appendChild(document.createTextNode(" Automatically announce to screen readers")),U.appendChild(q),L.appendChild(U);let I=document.createElement("form");I.className="dn-text-chat-form";let j=document.createElement("label");j.setAttribute("for",`dn-text-chat-input-${$}`),j.className="dn-text-chat-sr-only",j.textContent="Navigation command";let w=document.createElement("input");w.type="text",w.id=`dn-text-chat-input-${$}`,w.autocomplete="off",w.setAttribute("placeholder","Type a command...");let F=document.createElement("button");F.type="submit",F.textContent="Send",I.appendChild(j),I.appendChild(w),I.appendChild(F),L.appendChild(I),f.appendChild(L);let K="";w.addEventListener("keydown",s=>{if(s.key==="ArrowUp"){if(s.preventDefault(),E.length===0)return;b===-1?(K=w.value,b=E.length-1):b>0&&b--,w.value=E[b]}else if(s.key==="ArrowDown"){if(s.preventDefault(),b===-1)return;b<E.length-1?(b++,w.value=E[b]):(b=-1,w.value=K)}});let W=(s,i)=>{let m=document.createElement("div");m.className=`dn-text-chat-message ${i}`,m.textContent=s,v.appendChild(m),v.scrollTop=v.scrollHeight},M=s=>W(s,"dn-text-chat-system"),tt=s=>W(`> ${s}`,"dn-text-chat-input-echo"),y=s=>W(s,"dn-text-chat-response"),et=(s,i)=>{let m=document.createElement("div");m.className="dn-text-chat-message dn-text-chat-response";let N=document.createElement("span");N.textContent=s,m.appendChild(N);let T=document.createElement("ol");T.className="dn-text-chat-choices",i.forEach(S=>{let k=document.createElement("li");k.textContent=S,T.appendChild(k)}),m.appendChild(T),v.appendChild(m),v.scrollTop=v.scrollHeight},z=s=>H(void 0,null,function*(){let i={role:"system",content:_()};R.push({role:"user",content:s});let m=document.createElement("div");m.className="dn-text-chat-message dn-text-chat-llm-thinking",m.textContent="Thinking...",v.appendChild(m),v.scrollTop=v.scrollHeight;try{let N=yield p([i,...R]);return v.removeChild(m),N===null?(R.pop(),null):(R.push({role:"assistant",content:N}),y(N),N)}catch(N){return v.removeChild(m),R.pop(),y(`Error: ${N.message||"Could not get a response."}`),""}});p?(M('Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.'),M('Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.')):M('Text navigation ready. Type "enter" to begin or "help" for available commands.');let B=["enter","help","more","more help","clear"],V=s=>{let i=c.moveTo(s);i?(a=i.id,e&&e(i),y(`Moved to: ${r(i)}`)):y("Could not move to that node.")},G=s=>H(void 0,null,function*(){let i=s.trim();if(!i)return;tt(i);let m=i.toLowerCase();if(A){let h=parseInt(i,10);if(!isNaN(h)&&h>=1&&h<=A.length){let C=A[h-1];A=null,V(C.nodeId);return}A=null}if(m==="clear"){v.innerHTML="",M('Chat cleared. Type "help" for available commands.');return}if(m==="enter"){if(a){y('Already in the structure. Type "help" to see available commands.');return}let h=c.enter();if(!h){y("Could not enter the structure. No entry point found.");return}a=h.id,e&&e(h),y(`Entered: ${r(h)}`);return}if(m==="help"){let h=p?" You can also type any question about the data.":"";if(!a)y('Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.'+h);else{let C=o.nodes[a],ot=rt(a,C,o).map(st=>J(st,n));y(`Available: ${ot.join(", ")}, move to <search>.`+h)}return}if(m.startsWith("move to ")){let h=i.slice(8).trim();if(!h){y("Usage: move to <search term>");return}let C=lt(h,o,r);C.length===0?y(`No nodes found matching "${h}".`):C.length===1?V(C[0].nodeId):(A=C,et(`Found ${C.length} matches. Type a number to move there:`,C.map(D=>D.description)));return}if(m==="more"||m==="more help"){let C=Z(o).map(D=>J(D,n));y(`All navigation rules: ${C.join(", ")}.`);return}if(!a){if(p&&(yield z(i))!==null)return;y('Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.'+(p?" Enter an API key above to ask questions about the data.":""));return}let N=Z(o),{match:T,ambiguous:S}=ct(m,[...N,...B],n);if(T&&B.includes(T)){yield G(T);return}if(!T&&S.length>0){let h=S.map(C=>J(C,n));y(`Did you mean: ${h.join(", ")}?`);return}if(!T){if(p&&(yield z(i))!==null)return;let h=p?" Enter an API key above to ask questions about the data.":"";y(`Unknown command "${i}". Type "help" for available commands.`+h);return}let k=T,nt=n[k]||k;if(k==="exit"){a=null,g&&g(),y('Exited the structure. Type "enter" to re-enter.');return}let P=c.move(a,k);P?(a=P.id,e&&e(P),y(`${nt}: ${r(P)}`)):y(`Cannot move "${k}" from here.`)});return I.addEventListener("submit",s=>H(void 0,null,function*(){s.preventDefault();let i=w.value.trim();i&&(E.push(i),b=-1),yield G(w.value),w.value="",w.focus()})),{destroy(){f.removeChild(L)},getCurrentNode(){return a&&o.nodes[a]||null}}};export{ut as default};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "data-navigator",
3
3
  "author": "Frank Elavsky",
4
- "version": "2.3.0",
4
+ "version": "2.3.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",