UNPKG

jqwidgets-ng

Version:

[![Price](https://img.shields.io/badge/price-COMMERCIAL-0098f7.svg)](https://jqwidgets.com/license/)

10 lines (7 loc) 10.6 kB
/* jQWidgets v26.0.0 (2026-July) Copyright (c) 2011-2026 jQWidgets. License: https://jqwidgets.com/license/ */ /* eslint-disable */ (function(){if(typeof document==="undefined"){return}(function(a){a.jqx.ai=a.jqx.ai||{};a.jqx.ai.adapters={anthropic:{url:"https://api.anthropic.com/v1/messages",headers:function(b){return{"content-type":"application/json","x-api-key":b.apiKey,"anthropic-version":"2023-06-01","anthropic-dangerous-direct-browser-access":"true"}},payload:function(f,d,b){var e={model:f.model||"claude-opus-4-8",max_tokens:f.maxTokens||1024,messages:[{role:"user",content:b}]};if(d){e.system=d}return e},parse:function(d){if(d&&d.content&&d.content.length){var c="";for(var b=0;b<d.content.length;b++){if(d.content[b].type==="text"){c+=d.content[b].text}}return c}if(d&&d.error){throw new Error(d.error.message||"Anthropic API error")}return""}},openai:{url:"https://api.openai.com/v1/chat/completions",headers:function(b){return{"content-type":"application/json",Authorization:"Bearer "+b.apiKey}},payload:function(f,e,b){var d=[];if(e){d.push({role:"system",content:e})}d.push({role:"user",content:b});return{model:f.model||"gpt-4o",max_tokens:f.maxTokens||1024,messages:d}},parse:function(b){if(b&&b.choices&&b.choices.length&&b.choices[0].message){return b.choices[0].message.content||""}if(b&&b.error){throw new Error(b.error.message||"OpenAI API error")}return""}}};a.jqx.ai.adapters.custom=a.jqx.ai.adapters.anthropic;a.jqx.ai.complete=function(f,g){f=f||{};if(typeof f.sendRequest==="function"){try{var d=f.sendRequest({system:g.system,user:g.user,model:f.model,provider:f.provider},f.owner);return Promise.resolve(d).then(function(e){return(e==null)?"":(""+e)})}catch(h){return Promise.reject(h)}}if(!f.apiKey&&!f.proxyUrl){return Promise.reject(new Error("AI is not configured. Set aiKey for a local trial, or aiProxyUrl / aiSendRequest for production."))}var b=a.jqx.ai.adapters[(f.provider||"anthropic").toLowerCase()]||a.jqx.ai.adapters.anthropic;var c=f.proxyUrl||b.url;var i=b.headers(f);if(f.headers){i=a.extend({},i,f.headers)}return fetch(c,{method:"POST",headers:i,body:JSON.stringify(b.payload(f,g.system,g.user))}).then(function(e){if(!e.ok){return e.text().then(function(j){throw new Error("HTTP "+e.status+": "+j)})}return e.json()}).then(function(e){return b.parse(e)})};a.jqx.ai.extractJson=function(l){if(l==null){return null}var k=/```(?:json)?\s*([\s\S]*?)```/i.exec(l);var o=k?k[1]:(""+l);var c=o.search(/[\[{]/);if(c<0){return null}var g=o.charAt(c),n=g==="{"?"}":"]",f=0,m=false,j=false;for(var d=c;d<o.length;d++){var b=o.charAt(d);if(m){if(j){j=false}else{if(b==="\\"){j=true}else{if(b==='"'){m=false}}}}else{if(b==='"'){m=true}else{if(b===g){f++}else{if(b===n){f--;if(f===0){try{return JSON.parse(o.slice(c,d+1))}catch(h){return null}}}}}}}return null};a.extend(a.jqx._jqxGrid.prototype,{aiConfig:function(b){this._ai=a.extend(this._ai||{},b||{});return this._ai},_aiGetConfig:function(){var b=this;var d=a.extend({provider:b.aiProvider||"anthropic",apiKey:b.aiKey||"",model:b.aiModel||null,proxyUrl:b.aiProxyUrl||b.aiUrl||null,headers:b.aiHeaders||null,sendRequest:b.aiSendRequest||null,maxRows:b.aiMaxRows||40,maxTokens:1024},b._ai||{});d.owner=b;return d},_aiEmit:function(c,b){try{this.host.trigger(c,b)}catch(d){}},_aiError:function(b,c){this._aiEmit("gridaiError",{error:b,message:(b&&b.message)?b.message:(""+b)});if(typeof c==="function"){c(b)}},_aiColumns:function(){var d=[],c=this.columns?this.columns.records:[];for(var b=0;b<c.length;b++){if(c[b].datafield){d.push({text:c[b].text||c[b].datafield,datafield:c[b].datafield,type:this._aiColType(c[b].datafield)})}}return d},_aiColType:function(d){var c=this.source&&this.source._source&&this.source._source.datafields;if(c){for(var b=0;b<c.length;b++){if(c[b].name===d){return c[b].type||"string"}}}return"string"},_aiColumnsPrompt:function(){return this._aiColumns().map(function(b){return"- "+b.text+" => "+b.datafield+" : "+b.type}).join("\n")},_aiSampleRows:function(b){var f=this.getrows()||[],d=[],g=this._aiColumns();b=Math.min(b||40,f.length);for(var e=0;e<b;e++){var k=f[e],h={};for(var c=0;c<g.length;c++){h[g[c].datafield]=k[g[c].datafield]}d.push(h)}return d},_aiAggregates:function(){var f=this,h=this._aiColumns(),b={};for(var d=0;d<h.length;d++){if(h[d].type==="number"){try{var c=f.getcolumnaggregateddata(h[d].datafield,["min","max","sum","avg","count"]);if(c){b[h[d].datafield]=c}}catch(g){}}}return b},aiCommand:function(f,g){var e=this,b=e._aiGetConfig();var d='{\n "clear": boolean, // reset filters/sort/groups first\n "filters": [ { "field": <datafield>, "operator": <OP>, "value": <string|number|boolean>, "logic": "AND"|"OR" } ],\n "sort": { "field": <datafield>, "direction": "asc"|"desc" } | null,\n "group": [ <datafield> ]\n}';var c="You translate a user request about a data grid into grid actions.\nColumns (label => datafield : type):\n"+e._aiColumnsPrompt()+"\n\nSupported operators (OP): EQUAL, NOT_EQUAL, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL, CONTAINS, STARTS_WITH, ENDS_WITH.\nRespond ONLY with a JSON object of this shape (omit keys you do not need):\n"+d+"\nUse only the listed datafields.";return a.jqx.ai.complete(b,{system:c,user:""+f}).then(function(i){var j=a.jqx.ai.extractJson(i)||{};var k=e._aiApplyCommand(j);var h={spec:j,applied:k,query:f};e._aiEmit("gridaiResult",{type:"command",result:h});if(typeof g==="function"){g(null,h)}return h},function(h){e._aiError(h,g);throw h})},_aiApplyCommand:function(j){var k=this,b=[],o={},d={EQUAL:1,NOT_EQUAL:1,GREATER_THAN:1,LESS_THAN:1,GREATER_THAN_OR_EQUAL:1,LESS_THAN_OR_EQUAL:1,CONTAINS:1,STARTS_WITH:1,ENDS_WITH:1};var m=k._aiColumns();for(var s=0;s<m.length;s++){o[m[s].datafield]=m[s]}if(j.clear){if(k.clearfilters){k.clearfilters()}if(k.cleargroups){k.cleargroups()}b.push("cleared")}if(a.isArray(j.filters)&&j.filters.length&&typeof a.jqx.filter==="function"){var w={};for(var v=0;v<j.filters.length;v++){var r=j.filters[v];if(!r||!o[r.field]||!d[r.operator]){continue}(w[r.field]=w[r.field]||[]).push(r)}for(var c in w){if(!w.hasOwnProperty(c)){continue}var h=o[c];var e=h.type==="number"?"numericfilter":h.type==="date"?"datefilter":h.type==="bool"||h.type==="boolean"?"booleanfilter":"stringfilter";var n=new a.jqx.filter();for(var t=0;t<w[c].length;t++){var x=w[c][t];var q=k._aiCoerce(x.value,h.type);var l=n.createfilter(e,q,x.operator);n.addfilter(x.logic==="OR"?0:1,l);b.push(h.text+" "+x.operator+" "+x.value)}k.addfilter(c,n)}k.applyfilters()}if(j.sort&&o[j.sort.field]&&k.sortby){var p=j.sort.direction==="desc"?"desc":"asc";k.sortby(j.sort.field,p);b.push("sort by "+o[j.sort.field].text+" "+p)}if(a.isArray(j.group)&&k.addgroup&&k.groupable){for(var u=0;u<j.group.length;u++){if(o[j.group[u]]){k.addgroup(j.group[u]);b.push("group by "+o[j.group[u]].text)}}}return b},_aiCoerce:function(c,b){if(b==="number"){var d=parseFloat(c);return isNaN(d)?c:d}if(b==="bool"||b==="boolean"){return(c===true||c==="true"||c==="yes"||c===1||c==="1")}return c==null?"":(""+c)},aiAsk:function(f,g){var e=this,b=e._aiGetConfig();var c="Columns:\n"+e._aiColumnsPrompt()+"\n\nAggregates (numeric columns): "+JSON.stringify(e._aiAggregates())+"\n\nSample rows (JSON): "+JSON.stringify(e._aiSampleRows(b.maxRows));var d='You are a concise data analyst. Answer the user\'s question about the dataset below using only that data. Give a short, direct answer. If a chart would help, append a fenced code block:\n```chart {"type":"column|pie|line","categoryField":"<datafield>","valueField":"<datafield>","aggregate":"sum|avg|count|min|max"}```';return a.jqx.ai.complete(b,{system:d,user:f+"\n\n"+c}).then(function(j){var k=null;var i=/```chart\s*([\s\S]*?)```/i.exec(j);if(i){try{k=JSON.parse(i[1])}catch(n){}}var l=j.replace(/```chart[\s\S]*?```/i,"").trim();var h={answer:l,chart:k,query:f};e._aiEmit("gridaiResult",{type:"ask",result:h});if(typeof g==="function"){g(null,h)}return h},function(h){e._aiError(h,g);throw h})},aiSummarize:function(h,k){var g=this,c=g._aiGetConfig();if(typeof h==="function"){k=h;h=null}if(!h){var b=g.getselectedrowindexes?g.getselectedrowindexes():[];if(b&&b.length){h=[];for(var e=0;e<b.length;e++){var j=g.getrowdata?g.getrowdata(b[e]):null;if(j){h.push(j)}}}}if(!h||!h.length){h=g._aiSampleRows(c.maxRows)}var f="You summarize tabular data. In 2-4 sentences, describe the key patterns, ranges and anything notable in the rows below. Be specific with numbers.";return a.jqx.ai.complete(c,{system:f,user:"Columns:\n"+g._aiColumnsPrompt()+"\n\nRows (JSON):\n"+JSON.stringify(h)}).then(function(i){var d={summary:i.trim(),count:h.length};g._aiEmit("gridaiResult",{type:"summary",result:d});if(typeof k==="function"){k(null,d)}return d},function(d){g._aiError(d,k);throw d})},aiExplainRow:function(d,h){var f=this,b=f._aiGetConfig();var g=f.getrowdata?f.getrowdata(d):null;if(!g){return Promise.reject(new Error("Row "+d+" not found."))}var e="You explain a single record in the context of the whole dataset. In 1-3 sentences, note how it compares to typical values and anything unusual.";var c="Dataset aggregates: "+JSON.stringify(f._aiAggregates())+"\n\nThis row (JSON): "+JSON.stringify(g);return a.jqx.ai.complete(b,{system:e,user:c}).then(function(j){var i={row:d,explanation:j.trim()};f._aiEmit("gridaiResult",{type:"explain",result:i});if(typeof h==="function"){h(null,i)}return i},function(i){f._aiError(i,h);throw i})},aiClassifyColumn:function(n,l){var f=this,g=f._aiGetConfig();n=n||{};if(!n.datafield){return Promise.reject(new Error("aiClassifyColumn requires a target datafield."))}var m=f.getrows()||[];var k=n.sourceFields||f._aiColumns().map(function(i){return i.datafield});var h=[];for(var e=0;e<m.length;e++){var d={};for(var c=0;c<k.length;c++){d[k[c]]=m[e][k[c]]}h.push(d)}var b="You label each item in an array. "+(n.instruction||"Assign a short category to each item.")+(n.categories?" Use only these labels: "+n.categories.join(", ")+".":"")+"\nReturn ONLY a JSON array of strings - exactly one label per item, in the same order. No prose.";return a.jqx.ai.complete(g,{system:b,user:JSON.stringify(h)}).then(function(j){var r=a.jqx.ai.extractJson(j);if(!a.isArray(r)){throw new Error("AI did not return a label array.")}var o=0;for(var q=0;q<m.length&&q<r.length;q++){var p=f.getboundindex?f.getboundindex(m[q]):q;if(f.setcellvalue){f.setcellvalue(p,n.datafield,r[q]);o++}}var i={datafield:n.datafield,written:o};f._aiEmit("gridaiResult",{type:"classify",result:i});if(typeof l==="function"){l(null,i)}return i},function(i){f._aiError(i,l);throw i})}})})(jqxBaseFramework)})();