@aivue/tabular-intelligence 1.0.0 → 1.2.0
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/README.md +147 -0
- package/dist/composables/useTabularIntelligence.d.ts +13 -1
- package/dist/composables/useTabularIntelligence.d.ts.map +1 -1
- package/dist/core/TabularIntelligence.d.ts +61 -2
- package/dist/core/TabularIntelligence.d.ts.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1008 -191
- package/dist/index.mjs.map +1 -1
- package/dist/tabular-intelligence.css +1 -0
- package/dist/types/index.d.ts +109 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/apiClient.d.ts +27 -0
- package/dist/utils/apiClient.d.ts.map +1 -0
- package/dist/utils/postmanParser.d.ts +97 -0
- package/dist/utils/postmanParser.d.ts.map +1 -0
- package/dist/utils/qaEngine.d.ts +61 -0
- package/dist/utils/qaEngine.d.ts.map +1 -0
- package/dist/utils/tableExtractor.d.ts +14 -0
- package/dist/utils/tableExtractor.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,545 @@
|
|
|
1
|
-
import { ref as
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { ref as E, defineComponent as z, createElementBlock as h, openBlock as f, createElementVNode as m, createCommentVNode as S, withDirectives as Z, withKeys as V, withModifiers as R, vModelText as ee, toDisplayString as A, normalizeClass as te, createTextVNode as ne, Fragment as O, renderList as Q, computed as se } from "vue";
|
|
2
|
+
function N(c, e) {
|
|
3
|
+
if (c.length === 0)
|
|
4
|
+
return { columns: [], rowCount: 0, name: e };
|
|
5
|
+
const t = c[0];
|
|
6
|
+
return {
|
|
7
|
+
columns: Object.keys(t).map((s) => {
|
|
8
|
+
const a = L(c, s);
|
|
9
|
+
return {
|
|
10
|
+
name: s,
|
|
11
|
+
type: a,
|
|
12
|
+
nullable: c.some((o) => o[s] == null)
|
|
13
|
+
};
|
|
14
|
+
}),
|
|
15
|
+
rowCount: c.length,
|
|
16
|
+
name: e
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function L(c, e) {
|
|
20
|
+
const t = c.map((s) => s[e]).filter((s) => s != null);
|
|
21
|
+
if (t.length === 0) return "string";
|
|
22
|
+
if (t.every((s) => typeof s == "number" || !isNaN(Number(s))))
|
|
23
|
+
return "number";
|
|
24
|
+
if (t.every((s) => typeof s == "boolean" || s === "true" || s === "false"))
|
|
25
|
+
return "boolean";
|
|
26
|
+
if (t.every((s) => !isNaN(Date.parse(s))))
|
|
27
|
+
return "date";
|
|
28
|
+
const n = new Set(t);
|
|
29
|
+
return n.size < t.length * 0.5 && n.size < 20 ? "categorical" : "string";
|
|
30
|
+
}
|
|
31
|
+
function B(c, e, t) {
|
|
32
|
+
const n = c.map((r) => r[e]).filter((r) => r != null), s = n.length, a = c.length - s, o = {
|
|
33
|
+
column: e,
|
|
34
|
+
count: s,
|
|
35
|
+
nullCount: a
|
|
36
|
+
};
|
|
37
|
+
if (t === "number") {
|
|
38
|
+
const r = n.map(Number).filter((i) => !isNaN(i));
|
|
39
|
+
if (r.length > 0) {
|
|
40
|
+
const i = [...r].sort((p, d) => p - d), l = r.reduce((p, d) => p + d, 0);
|
|
41
|
+
o.mean = l / r.length, o.median = i[Math.floor(i.length / 2)], o.min = i[0], o.max = i[i.length - 1];
|
|
42
|
+
const g = r.reduce((p, d) => p + Math.pow(d - o.mean, 2), 0) / r.length;
|
|
43
|
+
o.std = Math.sqrt(g), o.percentiles = {
|
|
44
|
+
25: i[Math.floor(i.length * 0.25)],
|
|
45
|
+
50: o.median,
|
|
46
|
+
75: i[Math.floor(i.length * 0.75)],
|
|
47
|
+
90: i[Math.floor(i.length * 0.9)]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
const r = new Set(n);
|
|
52
|
+
o.uniqueValues = r.size;
|
|
53
|
+
const i = {};
|
|
54
|
+
n.forEach((g) => {
|
|
55
|
+
const p = String(g);
|
|
56
|
+
i[p] = (i[p] || 0) + 1;
|
|
57
|
+
});
|
|
58
|
+
const l = Math.max(...Object.values(i));
|
|
59
|
+
o.mode = Object.keys(i).find((g) => i[g] === l);
|
|
60
|
+
}
|
|
61
|
+
return o;
|
|
62
|
+
}
|
|
63
|
+
function ae(c, e, t = 0.5) {
|
|
64
|
+
const n = [], s = 1.5 + (1 - t) * 1.5;
|
|
65
|
+
return e.forEach((a) => {
|
|
66
|
+
const o = c.map((y, v) => ({ value: Number(y[a]), idx: v })).filter((y) => !isNaN(y.value));
|
|
67
|
+
if (o.length === 0) return;
|
|
68
|
+
const r = [...o].sort((y, v) => y.value - v.value), i = r[Math.floor(r.length * 0.25)].value, l = r[Math.floor(r.length * 0.75)].value, g = l - i, p = i - s * g, d = l + s * g;
|
|
69
|
+
o.forEach(({ value: y, idx: v }) => {
|
|
70
|
+
if (y < p || y > d) {
|
|
71
|
+
const $ = n.find((D) => D.rowIndex === v), C = y < p ? `${a}: ${y.toFixed(2)} < ${p.toFixed(2)}` : `${a}: ${y.toFixed(2)} > ${d.toFixed(2)}`;
|
|
72
|
+
$ ? ($.reasons.push(C), $.affectedColumns.push(a), $.score = Math.min(1, $.score + 0.2)) : n.push({
|
|
73
|
+
rowIndex: v,
|
|
74
|
+
row: c[v],
|
|
75
|
+
score: 0.7,
|
|
76
|
+
reasons: [C],
|
|
77
|
+
affectedColumns: [a]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}), n.sort((a, o) => o.score - a.score);
|
|
82
|
+
}
|
|
83
|
+
class H {
|
|
84
|
+
constructor(e) {
|
|
4
85
|
this.config = {
|
|
5
|
-
|
|
6
|
-
|
|
86
|
+
maxTokens: 1e3,
|
|
87
|
+
temperature: 0.3,
|
|
88
|
+
...e
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Answer a question about the table data
|
|
93
|
+
*/
|
|
94
|
+
async answerQuestion(e) {
|
|
95
|
+
const t = Date.now();
|
|
96
|
+
try {
|
|
97
|
+
const { question: n, schema: s, data: a = [], sampleSize: o = 100, includeAggregates: r = !0 } = e, i = a.length > o ? this.sampleData(a, o) : a, l = r ? this.calculateAggregates(a, s) : void 0, g = this.buildPrompt(n, s, i, l, a.length), p = await this.callLLM(g);
|
|
98
|
+
return {
|
|
99
|
+
answer: this.parseResponse(p, n, a.length > o),
|
|
100
|
+
processingTime: Date.now() - t
|
|
101
|
+
};
|
|
102
|
+
} catch (n) {
|
|
103
|
+
return console.error("Q&A error:", n), {
|
|
104
|
+
answer: {
|
|
105
|
+
questionId: this.generateId(),
|
|
106
|
+
text: "I encountered an error while processing your question. Please try again.",
|
|
107
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
108
|
+
confidence: 0,
|
|
109
|
+
cannotAnswer: !0,
|
|
110
|
+
reason: n instanceof Error ? n.message : "Unknown error"
|
|
111
|
+
},
|
|
112
|
+
processingTime: Date.now() - t
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Sample data for large datasets
|
|
118
|
+
*/
|
|
119
|
+
sampleData(e, t) {
|
|
120
|
+
if (e.length <= t)
|
|
121
|
+
return e;
|
|
122
|
+
const n = Math.floor(e.length / t), s = [];
|
|
123
|
+
for (let a = 0; a < e.length && s.length < t; a += n)
|
|
124
|
+
s.push(e[a]);
|
|
125
|
+
return s;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Calculate aggregates for numeric columns
|
|
129
|
+
*/
|
|
130
|
+
calculateAggregates(e, t) {
|
|
131
|
+
const n = {};
|
|
132
|
+
for (const s of t.columns)
|
|
133
|
+
if (s.type === "number" && e.length > 0)
|
|
134
|
+
try {
|
|
135
|
+
const a = B(e, s.name, "number");
|
|
136
|
+
n[s.name] = {
|
|
137
|
+
mean: a.mean,
|
|
138
|
+
median: a.median,
|
|
139
|
+
min: a.min,
|
|
140
|
+
max: a.max,
|
|
141
|
+
count: a.count
|
|
142
|
+
};
|
|
143
|
+
} catch {
|
|
144
|
+
}
|
|
145
|
+
else if (s.type === "categorical" || s.type === "string") {
|
|
146
|
+
const a = e.map((r) => r[s.name]).filter((r) => r != null), o = new Set(a);
|
|
147
|
+
n[s.name] = {
|
|
148
|
+
uniqueCount: o.size,
|
|
149
|
+
totalCount: a.length,
|
|
150
|
+
topValues: this.getTopValues(a, 5)
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return n;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get top N most frequent values
|
|
157
|
+
*/
|
|
158
|
+
getTopValues(e, t) {
|
|
159
|
+
const n = /* @__PURE__ */ new Map();
|
|
160
|
+
for (const s of e)
|
|
161
|
+
n.set(s, (n.get(s) || 0) + 1);
|
|
162
|
+
return Array.from(n.entries()).map(([s, a]) => ({ value: s, count: a })).sort((s, a) => a.count - s.count).slice(0, t);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Build prompt for LLM
|
|
166
|
+
*/
|
|
167
|
+
buildPrompt(e, t, n, s, a) {
|
|
168
|
+
const o = a && a > n.length;
|
|
169
|
+
let r = `You are a data analyst assistant. Answer the following question about a table dataset.
|
|
170
|
+
|
|
171
|
+
`;
|
|
172
|
+
r += `**Table Schema:**
|
|
173
|
+
`, r += `Table: ${t.name}
|
|
174
|
+
`, r += `Columns:
|
|
175
|
+
`;
|
|
176
|
+
for (const i of t.columns)
|
|
177
|
+
r += `- ${i.name} (${i.type})
|
|
178
|
+
`;
|
|
179
|
+
return r += `
|
|
180
|
+
`, s && Object.keys(s).length > 0 && (r += `**Summary Statistics:**
|
|
181
|
+
`, r += JSON.stringify(s, null, 2), r += `
|
|
182
|
+
|
|
183
|
+
`), r += `**Sample Data** (${n.length} rows${o ? ` out of ${a} total` : ""}):
|
|
184
|
+
`, r += JSON.stringify(n.slice(0, 10), null, 2), r += `
|
|
185
|
+
|
|
186
|
+
`, r += `**Question:** ${e}
|
|
187
|
+
|
|
188
|
+
`, r += `**Instructions:**
|
|
189
|
+
`, r += `1. Answer ONLY based on the data provided above.
|
|
190
|
+
`, r += `2. If the question cannot be answered from the available data, clearly state "I cannot answer this question from the available data" and explain why.
|
|
191
|
+
`, r += `3. Provide a clear, concise answer.
|
|
192
|
+
`, r += `4. Include specific numbers or examples from the data when relevant.
|
|
193
|
+
`, r += `5. If the answer is based on sampled data, mention that it's an approximation.
|
|
194
|
+
`, r += `6. Format your response as JSON with the following structure:
|
|
195
|
+
`, r += `{
|
|
196
|
+
`, r += ` "answer": "Your answer text here",
|
|
197
|
+
`, r += ` "confidence": 0.0-1.0,
|
|
198
|
+
`, r += ` "cannotAnswer": false,
|
|
199
|
+
`, r += ` "isApproximate": ${o},
|
|
200
|
+
`, r += ` "supportingData": { "key": "value" } // optional
|
|
201
|
+
`, r += `}
|
|
202
|
+
`, r;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Call LLM API
|
|
206
|
+
*/
|
|
207
|
+
async callLLM(e) {
|
|
208
|
+
const { provider: t, apiKey: n, baseUrl: s, model: a, maxTokens: o, temperature: r } = this.config;
|
|
209
|
+
if (t === "openai")
|
|
210
|
+
return this.callOpenAI(e, n, a || "gpt-4-turbo-preview", o, r);
|
|
211
|
+
if (t === "anthropic")
|
|
212
|
+
return this.callAnthropic(e, n, a || "claude-3-5-sonnet-20241022", o, r);
|
|
213
|
+
if (t === "custom" && s)
|
|
214
|
+
return this.callCustomAPI(e, s, n);
|
|
215
|
+
throw new Error(`Unsupported provider: ${t}`);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Call OpenAI API
|
|
219
|
+
*/
|
|
220
|
+
async callOpenAI(e, t, n, s, a) {
|
|
221
|
+
var i, l;
|
|
222
|
+
const o = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
223
|
+
method: "POST",
|
|
224
|
+
headers: {
|
|
225
|
+
"Content-Type": "application/json",
|
|
226
|
+
Authorization: `Bearer ${t}`
|
|
227
|
+
},
|
|
228
|
+
body: JSON.stringify({
|
|
229
|
+
model: n,
|
|
230
|
+
messages: [{ role: "user", content: e }],
|
|
231
|
+
max_tokens: s,
|
|
232
|
+
temperature: a,
|
|
233
|
+
response_format: { type: "json_object" }
|
|
234
|
+
})
|
|
235
|
+
});
|
|
236
|
+
if (!o.ok)
|
|
237
|
+
throw new Error(`OpenAI API error: ${o.statusText}`);
|
|
238
|
+
return ((l = (i = (await o.json()).choices[0]) == null ? void 0 : i.message) == null ? void 0 : l.content) || "";
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Call Anthropic API
|
|
242
|
+
*/
|
|
243
|
+
async callAnthropic(e, t, n, s, a) {
|
|
244
|
+
var i;
|
|
245
|
+
const o = await fetch("https://api.anthropic.com/v1/messages", {
|
|
246
|
+
method: "POST",
|
|
247
|
+
headers: {
|
|
248
|
+
"Content-Type": "application/json",
|
|
249
|
+
"x-api-key": t,
|
|
250
|
+
"anthropic-version": "2023-06-01"
|
|
251
|
+
},
|
|
252
|
+
body: JSON.stringify({
|
|
253
|
+
model: n,
|
|
254
|
+
max_tokens: s,
|
|
255
|
+
temperature: a,
|
|
256
|
+
messages: [{ role: "user", content: e }]
|
|
257
|
+
})
|
|
258
|
+
});
|
|
259
|
+
if (!o.ok)
|
|
260
|
+
throw new Error(`Anthropic API error: ${o.statusText}`);
|
|
261
|
+
return ((i = (await o.json()).content[0]) == null ? void 0 : i.text) || "";
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Call custom API
|
|
265
|
+
*/
|
|
266
|
+
async callCustomAPI(e, t, n) {
|
|
267
|
+
const s = {
|
|
268
|
+
"Content-Type": "application/json"
|
|
269
|
+
};
|
|
270
|
+
n && (s.Authorization = `Bearer ${n}`);
|
|
271
|
+
const a = await fetch(t, {
|
|
272
|
+
method: "POST",
|
|
273
|
+
headers: s,
|
|
274
|
+
body: JSON.stringify({ prompt: e })
|
|
275
|
+
});
|
|
276
|
+
if (!a.ok)
|
|
277
|
+
throw new Error(`Custom API error: ${a.statusText}`);
|
|
278
|
+
const o = await a.json();
|
|
279
|
+
return o.response || o.answer || JSON.stringify(o);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Parse LLM response
|
|
283
|
+
*/
|
|
284
|
+
parseResponse(e, t, n) {
|
|
285
|
+
try {
|
|
286
|
+
const s = JSON.parse(e);
|
|
287
|
+
return {
|
|
288
|
+
questionId: this.generateId(),
|
|
289
|
+
text: s.answer || s.text || e,
|
|
290
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
291
|
+
confidence: s.confidence || 0.8,
|
|
292
|
+
cannotAnswer: s.cannotAnswer || !1,
|
|
293
|
+
isApproximate: s.isApproximate !== void 0 ? s.isApproximate : n,
|
|
294
|
+
supportingData: s.supportingData,
|
|
295
|
+
reason: s.reason
|
|
296
|
+
};
|
|
297
|
+
} catch {
|
|
298
|
+
return {
|
|
299
|
+
questionId: this.generateId(),
|
|
300
|
+
text: e,
|
|
301
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
302
|
+
confidence: 0.7,
|
|
303
|
+
isApproximate: n
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Generate unique ID
|
|
309
|
+
*/
|
|
310
|
+
generateId() {
|
|
311
|
+
return `qa_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function re(c = {}) {
|
|
315
|
+
const {
|
|
316
|
+
selector: e = "table",
|
|
317
|
+
includeHeaders: t = !0,
|
|
318
|
+
maxRows: n,
|
|
319
|
+
inferTypes: s = !0,
|
|
320
|
+
skipEmptyRows: a = !0
|
|
321
|
+
} = c, o = document.querySelector(e);
|
|
322
|
+
if (!o || o.tagName !== "TABLE")
|
|
323
|
+
return console.warn(`No table found with selector: ${e}`), null;
|
|
324
|
+
const i = Array.from(o.rows);
|
|
325
|
+
if (i.length === 0)
|
|
326
|
+
return null;
|
|
327
|
+
let l = [], g = 0;
|
|
328
|
+
if (t && i[0]) {
|
|
329
|
+
const v = i[0];
|
|
330
|
+
l = Array.from(v.cells).map(($, C) => {
|
|
331
|
+
var _;
|
|
332
|
+
return ((_ = $.textContent) == null ? void 0 : _.trim()) || "" || `Column${C + 1}`;
|
|
333
|
+
}), g = 1;
|
|
334
|
+
} else {
|
|
335
|
+
const v = i[0];
|
|
336
|
+
l = Array.from(v.cells).map(($, C) => `Column${C + 1}`);
|
|
337
|
+
}
|
|
338
|
+
const p = [], d = n ? i.slice(g, g + n) : i.slice(g);
|
|
339
|
+
for (const v of d) {
|
|
340
|
+
const $ = Array.from(v.cells);
|
|
341
|
+
if (a && $.every((D) => {
|
|
342
|
+
var _;
|
|
343
|
+
return !((_ = D.textContent) != null && _.trim());
|
|
344
|
+
}))
|
|
345
|
+
continue;
|
|
346
|
+
const C = {};
|
|
347
|
+
$.forEach((D, _) => {
|
|
348
|
+
var M;
|
|
349
|
+
const j = l[_] || `Column${_ + 1}`;
|
|
350
|
+
let T = ((M = D.textContent) == null ? void 0 : M.trim()) || "";
|
|
351
|
+
if (s && T) {
|
|
352
|
+
const P = parseFloat(T);
|
|
353
|
+
!isNaN(P) && T === P.toString() && (T = P);
|
|
354
|
+
}
|
|
355
|
+
C[j] = T;
|
|
356
|
+
}), p.push(C);
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
schema: s && p.length > 0 ? N(p, "Extracted Table") : ie(l, p.length),
|
|
360
|
+
data: p,
|
|
361
|
+
source: "dom",
|
|
362
|
+
metadata: {
|
|
363
|
+
selector: e,
|
|
364
|
+
rowCount: p.length,
|
|
365
|
+
columnCount: l.length,
|
|
366
|
+
extractedAt: /* @__PURE__ */ new Date()
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function oe(c, e, t = {}) {
|
|
371
|
+
const { maxRows: n, inferTypes: s = !0 } = t, a = n ? c.slice(0, n) : c;
|
|
372
|
+
let o;
|
|
373
|
+
return e && e.length > 0 ? o = {
|
|
374
|
+
name: "Vue Data Grid",
|
|
375
|
+
columns: e.map((r) => ({
|
|
376
|
+
name: r.field,
|
|
377
|
+
type: s && a.length > 0 ? L(a, r.field) : "string",
|
|
378
|
+
nullable: !0
|
|
379
|
+
})),
|
|
380
|
+
rowCount: a.length
|
|
381
|
+
} : a.length > 0 ? o = N(a, "Vue Data Grid") : o = { name: "Vue Data Grid", columns: [], rowCount: 0 }, {
|
|
382
|
+
schema: o,
|
|
383
|
+
data: a,
|
|
384
|
+
source: "vue",
|
|
385
|
+
metadata: {
|
|
386
|
+
rowCount: a.length,
|
|
387
|
+
columnCount: o.columns.length,
|
|
388
|
+
extractedAt: /* @__PURE__ */ new Date()
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function ie(c, e = 0) {
|
|
393
|
+
return {
|
|
394
|
+
name: "Extracted Table",
|
|
395
|
+
columns: c.map((t) => ({
|
|
396
|
+
name: t,
|
|
397
|
+
type: "string",
|
|
398
|
+
nullable: !0
|
|
399
|
+
})),
|
|
400
|
+
rowCount: e
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function ce(c) {
|
|
404
|
+
const e = {};
|
|
405
|
+
c.variable && c.variable.forEach((a) => {
|
|
406
|
+
e[a.key] = a.value;
|
|
407
|
+
});
|
|
408
|
+
const t = c.auth ? J(c.auth) : void 0, n = [];
|
|
409
|
+
function s(a, o = "") {
|
|
410
|
+
a.forEach((r) => {
|
|
411
|
+
r.item ? s(r.item, o ? `${o}/${r.name}` : r.name) : r.request && n.push(le(r, t));
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
return s(c.item), {
|
|
415
|
+
name: c.info.name,
|
|
416
|
+
description: c.info.description,
|
|
417
|
+
endpoints: n,
|
|
418
|
+
variables: e,
|
|
419
|
+
auth: t
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function le(c, e) {
|
|
423
|
+
const t = c.request, n = {};
|
|
424
|
+
t.header && t.header.forEach((o) => {
|
|
425
|
+
n[o.key] = o.value;
|
|
426
|
+
});
|
|
427
|
+
const s = {};
|
|
428
|
+
t.url.query && t.url.query.forEach((o) => {
|
|
429
|
+
s[o.key] = o.value;
|
|
430
|
+
});
|
|
431
|
+
const a = t.auth ? J(t.auth) : e;
|
|
432
|
+
return {
|
|
433
|
+
name: c.name,
|
|
434
|
+
method: t.method,
|
|
435
|
+
url: t.url.raw,
|
|
436
|
+
description: t.description,
|
|
437
|
+
headers: n,
|
|
438
|
+
queryParams: s,
|
|
439
|
+
auth: a
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function J(c) {
|
|
443
|
+
const e = {};
|
|
444
|
+
return c.apikey ? c.apikey.forEach((t) => {
|
|
445
|
+
e[t.key] = t.value;
|
|
446
|
+
}) : c.bearer ? c.bearer.forEach((t) => {
|
|
447
|
+
e[t.key] = t.value;
|
|
448
|
+
}) : c.basic && c.basic.forEach((t) => {
|
|
449
|
+
e[t.key] = t.value;
|
|
450
|
+
}), {
|
|
451
|
+
type: c.type,
|
|
452
|
+
credentials: e
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function I(c, e) {
|
|
456
|
+
let t = c;
|
|
457
|
+
return Object.keys(e).forEach((n) => {
|
|
458
|
+
const s = new RegExp(`{{${n}}}`, "g");
|
|
459
|
+
t = t.replace(s, e[n]);
|
|
460
|
+
}), t;
|
|
461
|
+
}
|
|
462
|
+
async function U(c) {
|
|
463
|
+
const { endpoint: e, variables: t = {}, additionalHeaders: n = {}, additionalParams: s = {} } = c;
|
|
464
|
+
try {
|
|
465
|
+
let a = I(e.url, t);
|
|
466
|
+
const o = { ...e.queryParams, ...s }, r = Object.keys(o).map((d) => `${encodeURIComponent(d)}=${encodeURIComponent(I(o[d], t))}`).join("&");
|
|
467
|
+
r && (a = a.includes("?") ? `${a}&${r}` : `${a}?${r}`);
|
|
468
|
+
const i = {
|
|
469
|
+
"Content-Type": "application/json",
|
|
470
|
+
...e.headers,
|
|
471
|
+
...n
|
|
7
472
|
};
|
|
473
|
+
if (Object.keys(i).forEach((d) => {
|
|
474
|
+
i[d] = I(i[d], t);
|
|
475
|
+
}), e.auth) {
|
|
476
|
+
if (e.auth.type === "apikey") {
|
|
477
|
+
const d = e.auth.credentials.key || "access_key", y = I(e.auth.credentials.value || "", t);
|
|
478
|
+
e.auth.credentials.in === "header" && (i[d] = y);
|
|
479
|
+
} else if (e.auth.type === "bearer") {
|
|
480
|
+
const d = I(e.auth.credentials.token || "", t);
|
|
481
|
+
i.Authorization = `Bearer ${d}`;
|
|
482
|
+
} else if (e.auth.type === "basic") {
|
|
483
|
+
const d = I(e.auth.credentials.username || "", t), y = I(e.auth.credentials.password || "", t), v = btoa(`${d}:${y}`);
|
|
484
|
+
i.Authorization = `Basic ${v}`;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const l = await fetch(a, {
|
|
488
|
+
method: e.method,
|
|
489
|
+
headers: i
|
|
490
|
+
}), g = {};
|
|
491
|
+
return l.headers.forEach((d, y) => {
|
|
492
|
+
g[y] = d;
|
|
493
|
+
}), l.ok ? {
|
|
494
|
+
success: !0,
|
|
495
|
+
data: await l.json(),
|
|
496
|
+
statusCode: l.status,
|
|
497
|
+
headers: g
|
|
498
|
+
} : {
|
|
499
|
+
success: !1,
|
|
500
|
+
error: `HTTP ${l.status}: ${l.statusText}`,
|
|
501
|
+
statusCode: l.status,
|
|
502
|
+
headers: g
|
|
503
|
+
};
|
|
504
|
+
} catch (a) {
|
|
505
|
+
return {
|
|
506
|
+
success: !1,
|
|
507
|
+
error: a.message || "Unknown error occurred"
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
async function Ge(c, e = {}) {
|
|
512
|
+
const t = [];
|
|
513
|
+
for (const n of c) {
|
|
514
|
+
const s = await U({ endpoint: n, variables: e });
|
|
515
|
+
t.push(s);
|
|
516
|
+
}
|
|
517
|
+
return t;
|
|
518
|
+
}
|
|
519
|
+
function ue(c) {
|
|
520
|
+
if (!c.success || !c.data)
|
|
521
|
+
return [];
|
|
522
|
+
const e = c.data;
|
|
523
|
+
return Array.isArray(e) ? e : e.data && Array.isArray(e.data) ? e.data : e.results && Array.isArray(e.results) ? e.results : e.items && Array.isArray(e.items) ? e.items : typeof e == "object" ? [e] : [];
|
|
524
|
+
}
|
|
525
|
+
class de {
|
|
526
|
+
constructor(e, t) {
|
|
527
|
+
this.config = {
|
|
528
|
+
timeout: 3e4,
|
|
529
|
+
...e
|
|
530
|
+
}, t && (this.qaEngine = new H(t));
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Initialize or update Q&A engine
|
|
534
|
+
*/
|
|
535
|
+
initializeQA(e) {
|
|
536
|
+
this.qaEngine = new H(e);
|
|
8
537
|
}
|
|
9
538
|
/**
|
|
10
539
|
* Generic API call to TFM endpoint
|
|
11
540
|
*/
|
|
12
|
-
async callTFM(
|
|
13
|
-
const
|
|
541
|
+
async callTFM(e) {
|
|
542
|
+
const t = Date.now();
|
|
14
543
|
try {
|
|
15
544
|
const n = await fetch(this.config.baseUrl, {
|
|
16
545
|
method: "POST",
|
|
@@ -20,23 +549,23 @@ class N {
|
|
|
20
549
|
...this.config.headers
|
|
21
550
|
},
|
|
22
551
|
body: JSON.stringify({
|
|
23
|
-
...
|
|
552
|
+
...e,
|
|
24
553
|
model: this.config.model
|
|
25
554
|
}),
|
|
26
555
|
signal: AbortSignal.timeout(this.config.timeout || 3e4)
|
|
27
556
|
});
|
|
28
557
|
if (!n.ok) {
|
|
29
|
-
const
|
|
30
|
-
throw new Error(`TFM API error: ${n.status} - ${
|
|
558
|
+
const o = await n.text();
|
|
559
|
+
throw new Error(`TFM API error: ${n.status} - ${o}`);
|
|
31
560
|
}
|
|
32
|
-
const
|
|
561
|
+
const s = await n.json(), a = Date.now() - t;
|
|
33
562
|
return {
|
|
34
563
|
success: !0,
|
|
35
|
-
result:
|
|
564
|
+
result: s.result || s,
|
|
36
565
|
metadata: {
|
|
37
|
-
processingTime:
|
|
566
|
+
processingTime: a,
|
|
38
567
|
model: this.config.model || "unknown",
|
|
39
|
-
version:
|
|
568
|
+
version: s.version
|
|
40
569
|
}
|
|
41
570
|
};
|
|
42
571
|
} catch (n) {
|
|
@@ -44,7 +573,7 @@ class N {
|
|
|
44
573
|
success: !1,
|
|
45
574
|
error: n instanceof Error ? n.message : "Unknown error",
|
|
46
575
|
metadata: {
|
|
47
|
-
processingTime: Date.now() -
|
|
576
|
+
processingTime: Date.now() - t,
|
|
48
577
|
model: this.config.model || "unknown"
|
|
49
578
|
}
|
|
50
579
|
};
|
|
@@ -53,255 +582,543 @@ class N {
|
|
|
53
582
|
/**
|
|
54
583
|
* Perform analysis on tabular data
|
|
55
584
|
*/
|
|
56
|
-
async analyze(
|
|
57
|
-
const
|
|
58
|
-
operation:
|
|
59
|
-
data:
|
|
60
|
-
schema:
|
|
61
|
-
parameters:
|
|
62
|
-
}, n = await this.callTFM(
|
|
585
|
+
async analyze(e) {
|
|
586
|
+
const t = {
|
|
587
|
+
operation: e.type,
|
|
588
|
+
data: e.data,
|
|
589
|
+
schema: e.schema,
|
|
590
|
+
parameters: e.options
|
|
591
|
+
}, n = await this.callTFM(t);
|
|
63
592
|
if (!n.success)
|
|
64
593
|
throw new Error(n.error || "Analysis failed");
|
|
65
|
-
return this.parseAnalysisResult(
|
|
594
|
+
return this.parseAnalysisResult(e.type, n.result, n.metadata);
|
|
66
595
|
}
|
|
67
596
|
/**
|
|
68
597
|
* Parse TFM response into structured AnalysisResult
|
|
69
598
|
*/
|
|
70
|
-
parseAnalysisResult(
|
|
71
|
-
const
|
|
72
|
-
type:
|
|
599
|
+
parseAnalysisResult(e, t, n) {
|
|
600
|
+
const s = {
|
|
601
|
+
type: e,
|
|
73
602
|
timestamp: /* @__PURE__ */ new Date(),
|
|
74
|
-
summary:
|
|
75
|
-
insights:
|
|
76
|
-
recommendations:
|
|
77
|
-
confidence:
|
|
603
|
+
summary: t.summary || "",
|
|
604
|
+
insights: t.insights || [],
|
|
605
|
+
recommendations: t.recommendations,
|
|
606
|
+
confidence: t.confidence || 0.8,
|
|
78
607
|
processingTime: n == null ? void 0 : n.processingTime
|
|
79
608
|
};
|
|
80
|
-
switch (
|
|
609
|
+
switch (e) {
|
|
81
610
|
case "descriptive_stats":
|
|
82
611
|
return {
|
|
83
|
-
...
|
|
84
|
-
descriptiveStats:
|
|
612
|
+
...s,
|
|
613
|
+
descriptiveStats: t.stats || t.descriptiveStats
|
|
85
614
|
};
|
|
86
615
|
case "anomaly_detection":
|
|
87
616
|
return {
|
|
88
|
-
...
|
|
89
|
-
anomalies:
|
|
617
|
+
...s,
|
|
618
|
+
anomalies: t.anomalies || []
|
|
90
619
|
};
|
|
91
620
|
case "segmentation":
|
|
92
621
|
case "clustering":
|
|
93
622
|
return {
|
|
94
|
-
...
|
|
95
|
-
clusters:
|
|
623
|
+
...s,
|
|
624
|
+
clusters: t.clusters || []
|
|
96
625
|
};
|
|
97
626
|
case "prediction":
|
|
98
627
|
return {
|
|
99
|
-
...
|
|
100
|
-
predictions:
|
|
628
|
+
...s,
|
|
629
|
+
predictions: t.predictions || t
|
|
101
630
|
};
|
|
102
631
|
case "correlation":
|
|
103
632
|
return {
|
|
104
|
-
...
|
|
105
|
-
correlations:
|
|
633
|
+
...s,
|
|
634
|
+
correlations: t.correlations || t
|
|
635
|
+
};
|
|
636
|
+
case "summary":
|
|
637
|
+
return {
|
|
638
|
+
...s,
|
|
639
|
+
aiSummary: t.summary || t
|
|
640
|
+
};
|
|
641
|
+
case "qa":
|
|
642
|
+
return {
|
|
643
|
+
...s,
|
|
644
|
+
qaAnswer: t.answer || t
|
|
106
645
|
};
|
|
107
646
|
default:
|
|
108
|
-
return
|
|
647
|
+
return s;
|
|
109
648
|
}
|
|
110
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* Ask a question about the data (Q&A)
|
|
652
|
+
*/
|
|
653
|
+
async askQuestion(e) {
|
|
654
|
+
if (!this.qaEngine)
|
|
655
|
+
throw new Error("Q&A engine not initialized. Call initializeQA() first.");
|
|
656
|
+
return this.qaEngine.answerQuestion(e);
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Generate AI summary of table data
|
|
660
|
+
*/
|
|
661
|
+
async generateSummary(e, t) {
|
|
662
|
+
const n = {
|
|
663
|
+
type: "summary",
|
|
664
|
+
data: e,
|
|
665
|
+
schema: t
|
|
666
|
+
}, s = await this.analyze(n);
|
|
667
|
+
if (!s.aiSummary)
|
|
668
|
+
throw new Error("Failed to generate summary");
|
|
669
|
+
return s.aiSummary;
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Extract table from DOM
|
|
673
|
+
*/
|
|
674
|
+
extractFromDOM(e) {
|
|
675
|
+
return re(e);
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Normalize Vue data grid data
|
|
679
|
+
*/
|
|
680
|
+
normalizeVueData(e, t, n) {
|
|
681
|
+
return oe(e, t, n);
|
|
682
|
+
}
|
|
111
683
|
/**
|
|
112
684
|
* Update configuration
|
|
113
685
|
*/
|
|
114
|
-
updateConfig(
|
|
115
|
-
this.config = { ...this.config, ...
|
|
686
|
+
updateConfig(e) {
|
|
687
|
+
this.config = { ...this.config, ...e };
|
|
116
688
|
}
|
|
117
689
|
/**
|
|
118
690
|
* Get current configuration (without sensitive data)
|
|
119
691
|
*/
|
|
120
692
|
getConfig() {
|
|
121
|
-
const { apiKey:
|
|
122
|
-
return
|
|
693
|
+
const { apiKey: e, ...t } = this.config;
|
|
694
|
+
return t;
|
|
123
695
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
696
|
+
// ============================================================================
|
|
697
|
+
// API Integration Methods
|
|
698
|
+
// ============================================================================
|
|
699
|
+
/**
|
|
700
|
+
* Load Postman collection
|
|
701
|
+
*/
|
|
702
|
+
loadPostmanCollection(e) {
|
|
703
|
+
return this.parsedCollection = ce(e), this.parsedCollection;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Get loaded collection
|
|
707
|
+
*/
|
|
708
|
+
getCollection() {
|
|
709
|
+
return this.parsedCollection;
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Get endpoints from loaded collection
|
|
713
|
+
*/
|
|
714
|
+
getEndpoints() {
|
|
715
|
+
var e;
|
|
716
|
+
return ((e = this.parsedCollection) == null ? void 0 : e.endpoints) || [];
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Execute API request and get data
|
|
720
|
+
*/
|
|
721
|
+
async fetchDataFromAPI(e, t) {
|
|
722
|
+
if (!this.parsedCollection)
|
|
723
|
+
throw new Error("No Postman collection loaded. Call loadPostmanCollection() first.");
|
|
724
|
+
const n = this.parsedCollection.endpoints.find((i) => i.name === e);
|
|
725
|
+
if (!n)
|
|
726
|
+
throw new Error(`Endpoint "${e}" not found in collection.`);
|
|
727
|
+
const s = {
|
|
728
|
+
...this.parsedCollection.variables,
|
|
729
|
+
...t
|
|
730
|
+
}, a = await U({ endpoint: n, variables: s });
|
|
731
|
+
if (!a.success)
|
|
732
|
+
throw new Error(`API request failed: ${a.error}`);
|
|
733
|
+
const o = ue(a), r = N(o);
|
|
734
|
+
return { data: o, schema: r };
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Query API data with natural language
|
|
738
|
+
*/
|
|
739
|
+
async queryAPI(e) {
|
|
740
|
+
if (!this.qaEngine)
|
|
741
|
+
throw new Error("Q&A engine not initialized. Provide qaConfig in constructor or call initializeQA().");
|
|
742
|
+
const t = Date.now(), { data: n, schema: s } = await this.fetchDataFromAPI(
|
|
743
|
+
e.dataSource.endpoint || "",
|
|
744
|
+
e.variables
|
|
745
|
+
), a = {
|
|
746
|
+
question: e.question,
|
|
747
|
+
schema: s,
|
|
748
|
+
data: n
|
|
749
|
+
}, o = await this.qaEngine.answerQuestion(a), r = Date.now() - t;
|
|
750
|
+
return {
|
|
751
|
+
answer: o.answer,
|
|
752
|
+
apiResponse: n,
|
|
753
|
+
endpoint: e.dataSource.endpoint,
|
|
754
|
+
executionTime: r
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* List available endpoints from loaded collection
|
|
759
|
+
*/
|
|
760
|
+
listEndpoints() {
|
|
761
|
+
return this.parsedCollection ? this.parsedCollection.endpoints.map((e) => ({
|
|
762
|
+
name: e.name,
|
|
763
|
+
method: e.method,
|
|
764
|
+
description: e.description
|
|
765
|
+
})) : [];
|
|
183
766
|
}
|
|
184
|
-
return r;
|
|
185
|
-
}
|
|
186
|
-
function F(c, s, e = 0.5) {
|
|
187
|
-
const n = [], t = 1.5 + (1 - e) * 1.5;
|
|
188
|
-
return s.forEach((i) => {
|
|
189
|
-
const r = c.map((m, g) => ({ value: Number(m[i]), idx: g })).filter((m) => !isNaN(m.value));
|
|
190
|
-
if (r.length === 0) return;
|
|
191
|
-
const l = [...r].sort((m, g) => m.value - g.value), o = l[Math.floor(l.length * 0.25)].value, p = l[Math.floor(l.length * 0.75)].value, h = p - o, u = o - t * h, d = p + t * h;
|
|
192
|
-
r.forEach(({ value: m, idx: g }) => {
|
|
193
|
-
if (m < u || m > d) {
|
|
194
|
-
const v = n.find((a) => a.rowIndex === g), S = m < u ? `${i}: ${m.toFixed(2)} < ${u.toFixed(2)}` : `${i}: ${m.toFixed(2)} > ${d.toFixed(2)}`;
|
|
195
|
-
v ? (v.reasons.push(S), v.affectedColumns.push(i), v.score = Math.min(1, v.score + 0.2)) : n.push({
|
|
196
|
-
rowIndex: g,
|
|
197
|
-
row: c[g],
|
|
198
|
-
score: 0.7,
|
|
199
|
-
reasons: [S],
|
|
200
|
-
affectedColumns: [i]
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}), n.sort((i, r) => r.score - i.score);
|
|
205
767
|
}
|
|
206
|
-
function
|
|
207
|
-
const
|
|
208
|
-
async function
|
|
209
|
-
|
|
768
|
+
function Ye(c) {
|
|
769
|
+
const e = new de(c.config, c.qaConfig), t = E(!1), n = E(null), s = E(null), a = c.data || E([]), o = c.schema || E(null), r = E([]), i = E([]), l = E(null), g = c.maxQuestionHistory || 50, p = c.useLocalFallback !== !1;
|
|
770
|
+
async function d(u, w) {
|
|
771
|
+
t.value = !0, n.value = null;
|
|
210
772
|
try {
|
|
211
|
-
const
|
|
212
|
-
type:
|
|
213
|
-
data:
|
|
214
|
-
schema:
|
|
215
|
-
options:
|
|
216
|
-
},
|
|
217
|
-
return
|
|
218
|
-
} catch (
|
|
219
|
-
if (n.value =
|
|
220
|
-
return
|
|
773
|
+
const b = {
|
|
774
|
+
type: u,
|
|
775
|
+
data: a.value,
|
|
776
|
+
schema: o.value || void 0,
|
|
777
|
+
options: w
|
|
778
|
+
}, k = await e.analyze(b);
|
|
779
|
+
return s.value = k, k;
|
|
780
|
+
} catch (b) {
|
|
781
|
+
if (n.value = b instanceof Error ? b : new Error("Analysis failed"), p)
|
|
782
|
+
return y(u, w);
|
|
221
783
|
throw n.value;
|
|
222
784
|
} finally {
|
|
223
|
-
|
|
785
|
+
t.value = !1;
|
|
224
786
|
}
|
|
225
787
|
}
|
|
226
|
-
function
|
|
227
|
-
const
|
|
228
|
-
switch (
|
|
788
|
+
function y(u, w) {
|
|
789
|
+
const b = o.value || N(a.value);
|
|
790
|
+
switch (u) {
|
|
229
791
|
case "descriptive_stats": {
|
|
230
|
-
const
|
|
231
|
-
(
|
|
792
|
+
const k = b.columns.map(
|
|
793
|
+
(x) => B(a.value, x.name, x.type)
|
|
232
794
|
);
|
|
233
795
|
return {
|
|
234
|
-
type:
|
|
796
|
+
type: u,
|
|
235
797
|
timestamp: /* @__PURE__ */ new Date(),
|
|
236
|
-
descriptiveStats:
|
|
237
|
-
summary: `Calculated statistics for ${
|
|
798
|
+
descriptiveStats: k,
|
|
799
|
+
summary: `Calculated statistics for ${k.length} columns`,
|
|
238
800
|
insights: [],
|
|
239
801
|
confidence: 0.9
|
|
240
802
|
};
|
|
241
803
|
}
|
|
242
804
|
case "anomaly_detection": {
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
805
|
+
const k = b.columns.filter((q) => q.type === "number").map((q) => q.name), x = ae(
|
|
806
|
+
a.value,
|
|
807
|
+
k,
|
|
808
|
+
w == null ? void 0 : w.sensitivity
|
|
247
809
|
);
|
|
248
810
|
return {
|
|
249
|
-
type:
|
|
811
|
+
type: u,
|
|
250
812
|
timestamp: /* @__PURE__ */ new Date(),
|
|
251
|
-
anomalies:
|
|
252
|
-
summary: `Found ${
|
|
253
|
-
insights:
|
|
813
|
+
anomalies: x,
|
|
814
|
+
summary: `Found ${x.length} anomalies`,
|
|
815
|
+
insights: x.slice(0, 3).map((q) => q.reasons[0]),
|
|
254
816
|
confidence: 0.8
|
|
255
817
|
};
|
|
256
818
|
}
|
|
257
819
|
default:
|
|
258
|
-
throw new Error(`Local analysis not supported for type: ${
|
|
820
|
+
throw new Error(`Local analysis not supported for type: ${u}`);
|
|
259
821
|
}
|
|
260
822
|
}
|
|
261
|
-
async function
|
|
262
|
-
return (await
|
|
823
|
+
async function v() {
|
|
824
|
+
return (await d("descriptive_stats")).descriptiveStats || [];
|
|
825
|
+
}
|
|
826
|
+
async function $(u, w) {
|
|
827
|
+
return (await d("anomaly_detection", { sensitivity: w, features: u })).anomalies || [];
|
|
828
|
+
}
|
|
829
|
+
async function C(u, w = 3) {
|
|
830
|
+
return d("clustering", { features: u, numClusters: w });
|
|
263
831
|
}
|
|
264
|
-
async function u
|
|
265
|
-
return (
|
|
832
|
+
async function D(u, w) {
|
|
833
|
+
return d("prediction", { targetColumn: u, ...w });
|
|
834
|
+
}
|
|
835
|
+
function _(u) {
|
|
836
|
+
e.updateConfig(u);
|
|
837
|
+
}
|
|
838
|
+
function j(u, w = !0) {
|
|
839
|
+
a.value = u, w && (o.value = N(u));
|
|
840
|
+
}
|
|
841
|
+
function T() {
|
|
842
|
+
t.value = !1, n.value = null, s.value = null, r.value = [], i.value = [], l.value = null;
|
|
843
|
+
}
|
|
844
|
+
async function M(u, w) {
|
|
845
|
+
t.value = !0, n.value = null;
|
|
846
|
+
try {
|
|
847
|
+
const b = o.value || N(a.value), k = {
|
|
848
|
+
question: u,
|
|
849
|
+
schema: b,
|
|
850
|
+
data: a.value,
|
|
851
|
+
sampleSize: 100,
|
|
852
|
+
includeAggregates: !0,
|
|
853
|
+
...w
|
|
854
|
+
}, q = (await e.askQuestion(k)).answer, X = {
|
|
855
|
+
id: q.questionId,
|
|
856
|
+
text: u,
|
|
857
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
858
|
+
context: {
|
|
859
|
+
tableSchema: b,
|
|
860
|
+
rowCount: a.value.length
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
return r.value.push(X), i.value.push(q), l.value = q, r.value.length > g && (r.value.shift(), i.value.shift()), q;
|
|
864
|
+
} catch (b) {
|
|
865
|
+
throw n.value = b instanceof Error ? b : new Error("Q&A failed"), n.value;
|
|
866
|
+
} finally {
|
|
867
|
+
t.value = !1;
|
|
868
|
+
}
|
|
266
869
|
}
|
|
267
|
-
async function
|
|
268
|
-
|
|
870
|
+
async function P() {
|
|
871
|
+
t.value = !0, n.value = null;
|
|
872
|
+
try {
|
|
873
|
+
const u = o.value || N(a.value);
|
|
874
|
+
return await e.generateSummary(a.value, u);
|
|
875
|
+
} catch (u) {
|
|
876
|
+
throw n.value = u instanceof Error ? u : new Error("Summary generation failed"), n.value;
|
|
877
|
+
} finally {
|
|
878
|
+
t.value = !1;
|
|
879
|
+
}
|
|
269
880
|
}
|
|
270
|
-
|
|
271
|
-
|
|
881
|
+
function K() {
|
|
882
|
+
r.value = [], i.value = [], l.value = null;
|
|
272
883
|
}
|
|
273
|
-
function
|
|
274
|
-
|
|
884
|
+
function G(u) {
|
|
885
|
+
const w = e.extractFromDOM(u);
|
|
886
|
+
return w && (a.value = w.data, o.value = w.schema), w;
|
|
275
887
|
}
|
|
276
|
-
function
|
|
277
|
-
|
|
888
|
+
function Y(u, w, b) {
|
|
889
|
+
const k = e.normalizeVueData(u, w, b);
|
|
890
|
+
a.value = k.data, o.value = k.schema;
|
|
278
891
|
}
|
|
279
|
-
function
|
|
280
|
-
e.
|
|
892
|
+
function W(u) {
|
|
893
|
+
e.initializeQA(u);
|
|
281
894
|
}
|
|
282
895
|
return {
|
|
283
|
-
client:
|
|
284
|
-
loading:
|
|
896
|
+
client: e,
|
|
897
|
+
loading: t,
|
|
285
898
|
error: n,
|
|
286
|
-
lastResult:
|
|
287
|
-
data:
|
|
288
|
-
schema:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
899
|
+
lastResult: s,
|
|
900
|
+
data: a,
|
|
901
|
+
schema: o,
|
|
902
|
+
questionHistory: r,
|
|
903
|
+
answerHistory: i,
|
|
904
|
+
lastAnswer: l,
|
|
905
|
+
analyze: d,
|
|
906
|
+
getDescriptiveStats: v,
|
|
907
|
+
detectAnomalies: $,
|
|
908
|
+
performClustering: C,
|
|
909
|
+
predict: D,
|
|
910
|
+
askQuestion: M,
|
|
911
|
+
generateSummary: P,
|
|
912
|
+
clearHistory: K,
|
|
913
|
+
extractFromDOM: G,
|
|
914
|
+
loadFromVueGrid: Y,
|
|
915
|
+
updateConfig: _,
|
|
916
|
+
initializeQA: W,
|
|
917
|
+
setData: j,
|
|
918
|
+
reset: T
|
|
297
919
|
};
|
|
298
920
|
}
|
|
921
|
+
const me = { class: "ti-question-input" }, pe = { class: "ti-input-wrapper" }, he = ["placeholder", "disabled", "onKeydown"], fe = ["disabled"], ge = { key: 0 }, we = {
|
|
922
|
+
key: 1,
|
|
923
|
+
class: "ti-loading"
|
|
924
|
+
}, ye = {
|
|
925
|
+
key: 0,
|
|
926
|
+
class: "ti-hint"
|
|
927
|
+
}, ve = /* @__PURE__ */ z({
|
|
928
|
+
__name: "QuestionInput",
|
|
929
|
+
props: {
|
|
930
|
+
placeholder: { default: "Ask a question about this data..." },
|
|
931
|
+
submitLabel: { default: "Ask" },
|
|
932
|
+
loadingLabel: { default: "Processing..." },
|
|
933
|
+
hint: { default: "Press Enter to submit, Shift+Enter for new line" },
|
|
934
|
+
showHint: { type: Boolean, default: !0 },
|
|
935
|
+
disabled: { type: Boolean, default: !1 },
|
|
936
|
+
loading: { type: Boolean, default: !1 }
|
|
937
|
+
},
|
|
938
|
+
emits: ["submit"],
|
|
939
|
+
setup(c, { emit: e }) {
|
|
940
|
+
const t = c, n = e, s = E("");
|
|
941
|
+
function a() {
|
|
942
|
+
s.value.trim() && !t.disabled && !t.loading && (n("submit", s.value.trim()), s.value = "");
|
|
943
|
+
}
|
|
944
|
+
function o(r) {
|
|
945
|
+
}
|
|
946
|
+
return (r, i) => (f(), h("div", me, [
|
|
947
|
+
m("div", pe, [
|
|
948
|
+
Z(m("textarea", {
|
|
949
|
+
"onUpdate:modelValue": i[0] || (i[0] = (l) => s.value = l),
|
|
950
|
+
placeholder: r.placeholder,
|
|
951
|
+
disabled: r.disabled,
|
|
952
|
+
class: "ti-textarea",
|
|
953
|
+
rows: "2",
|
|
954
|
+
onKeydown: [
|
|
955
|
+
V(R(a, ["exact", "prevent"]), ["enter"]),
|
|
956
|
+
V(R(o, ["shift"]), ["enter"])
|
|
957
|
+
]
|
|
958
|
+
}, null, 40, he), [
|
|
959
|
+
[ee, s.value]
|
|
960
|
+
]),
|
|
961
|
+
m("button", {
|
|
962
|
+
disabled: r.disabled || !s.value.trim(),
|
|
963
|
+
class: "ti-submit-btn",
|
|
964
|
+
onClick: a
|
|
965
|
+
}, [
|
|
966
|
+
r.loading ? (f(), h("span", we, A(r.loadingLabel), 1)) : (f(), h("span", ge, A(r.submitLabel), 1))
|
|
967
|
+
], 8, fe)
|
|
968
|
+
]),
|
|
969
|
+
r.showHint ? (f(), h("div", ye, A(r.hint), 1)) : S("", !0)
|
|
970
|
+
]));
|
|
971
|
+
}
|
|
972
|
+
}), F = (c, e) => {
|
|
973
|
+
const t = c.__vccOpts || c;
|
|
974
|
+
for (const [n, s] of e)
|
|
975
|
+
t[n] = s;
|
|
976
|
+
return t;
|
|
977
|
+
}, We = /* @__PURE__ */ F(ve, [["__scopeId", "data-v-90db5921"]]), be = { class: "ti-answer-header" }, Ae = { class: "ti-answer-icon" }, $e = { key: 0 }, ke = { key: 1 }, Ce = { class: "ti-answer-meta" }, _e = { class: "ti-confidence" }, qe = { class: "ti-timestamp" }, Ee = { class: "ti-answer-text" }, Se = {
|
|
978
|
+
key: 0,
|
|
979
|
+
class: "ti-approximate-notice"
|
|
980
|
+
}, De = {
|
|
981
|
+
key: 1,
|
|
982
|
+
class: "ti-reason"
|
|
983
|
+
}, Te = {
|
|
984
|
+
key: 2,
|
|
985
|
+
class: "ti-supporting-data"
|
|
986
|
+
}, xe = {
|
|
987
|
+
key: 0,
|
|
988
|
+
class: "ti-supporting-content"
|
|
989
|
+
}, Ie = {
|
|
990
|
+
key: 0,
|
|
991
|
+
class: "ti-aggregates"
|
|
992
|
+
}, Ne = {
|
|
993
|
+
key: 1,
|
|
994
|
+
class: "ti-rows"
|
|
995
|
+
}, Pe = { class: "ti-table-wrapper" }, Me = { class: "ti-table" }, Oe = /* @__PURE__ */ z({
|
|
996
|
+
__name: "AnswerDisplay",
|
|
997
|
+
props: {
|
|
998
|
+
answer: {}
|
|
999
|
+
},
|
|
1000
|
+
setup(c) {
|
|
1001
|
+
const e = E(!1);
|
|
1002
|
+
function t(n) {
|
|
1003
|
+
return new Date(n).toLocaleTimeString();
|
|
1004
|
+
}
|
|
1005
|
+
return (n, s) => (f(), h("div", {
|
|
1006
|
+
class: te(["ti-answer-display", { "ti-cannot-answer": n.answer.cannotAnswer }])
|
|
1007
|
+
}, [
|
|
1008
|
+
m("div", be, [
|
|
1009
|
+
m("div", Ae, [
|
|
1010
|
+
n.answer.cannotAnswer ? (f(), h("span", ke, "⚠️")) : (f(), h("span", $e, "💡"))
|
|
1011
|
+
]),
|
|
1012
|
+
m("div", Ce, [
|
|
1013
|
+
m("div", _e, " Confidence: " + A(Math.round(n.answer.confidence * 100)) + "% ", 1),
|
|
1014
|
+
m("div", qe, A(t(n.answer.timestamp)), 1)
|
|
1015
|
+
])
|
|
1016
|
+
]),
|
|
1017
|
+
m("div", Ee, A(n.answer.text), 1),
|
|
1018
|
+
n.answer.isApproximate ? (f(), h("div", Se, " ℹ️ This answer is based on sampled data and may be approximate. ")) : S("", !0),
|
|
1019
|
+
n.answer.reason && n.answer.cannotAnswer ? (f(), h("div", De, [
|
|
1020
|
+
s[1] || (s[1] = m("strong", null, "Reason:", -1)),
|
|
1021
|
+
ne(" " + A(n.answer.reason), 1)
|
|
1022
|
+
])) : S("", !0),
|
|
1023
|
+
n.answer.supportingData ? (f(), h("div", Te, [
|
|
1024
|
+
m("button", {
|
|
1025
|
+
class: "ti-toggle-btn",
|
|
1026
|
+
onClick: s[0] || (s[0] = (a) => e.value = !e.value)
|
|
1027
|
+
}, A(e.value ? "▼" : "▶") + " Supporting Data ", 1),
|
|
1028
|
+
e.value ? (f(), h("div", xe, [
|
|
1029
|
+
n.answer.supportingData.aggregates ? (f(), h("div", Ie, [
|
|
1030
|
+
s[2] || (s[2] = m("h4", null, "Aggregates:", -1)),
|
|
1031
|
+
m("pre", null, A(JSON.stringify(n.answer.supportingData.aggregates, null, 2)), 1)
|
|
1032
|
+
])) : S("", !0),
|
|
1033
|
+
n.answer.supportingData.rows && n.answer.supportingData.rows.length > 0 ? (f(), h("div", Ne, [
|
|
1034
|
+
m("h4", null, "Sample Rows (" + A(n.answer.supportingData.rows.length) + "):", 1),
|
|
1035
|
+
m("div", Pe, [
|
|
1036
|
+
m("table", Me, [
|
|
1037
|
+
m("thead", null, [
|
|
1038
|
+
m("tr", null, [
|
|
1039
|
+
(f(!0), h(O, null, Q(Object.keys(n.answer.supportingData.rows[0]), (a, o) => (f(), h("th", { key: o }, A(a), 1))), 128))
|
|
1040
|
+
])
|
|
1041
|
+
]),
|
|
1042
|
+
m("tbody", null, [
|
|
1043
|
+
(f(!0), h(O, null, Q(n.answer.supportingData.rows.slice(0, 5), (a, o) => (f(), h("tr", { key: o }, [
|
|
1044
|
+
(f(!0), h(O, null, Q(Object.keys(a), (r, i) => (f(), h("td", { key: i }, A(a[r]), 1))), 128))
|
|
1045
|
+
]))), 128))
|
|
1046
|
+
])
|
|
1047
|
+
])
|
|
1048
|
+
])
|
|
1049
|
+
])) : S("", !0)
|
|
1050
|
+
])) : S("", !0)
|
|
1051
|
+
])) : S("", !0)
|
|
1052
|
+
], 2));
|
|
1053
|
+
}
|
|
1054
|
+
}), Xe = /* @__PURE__ */ F(Oe, [["__scopeId", "data-v-d1aaae1d"]]), Qe = { class: "ti-question-history" }, je = { class: "ti-history-header" }, ze = {
|
|
1055
|
+
key: 0,
|
|
1056
|
+
class: "ti-empty-state"
|
|
1057
|
+
}, Fe = {
|
|
1058
|
+
key: 1,
|
|
1059
|
+
class: "ti-history-list"
|
|
1060
|
+
}, Ve = ["onClick"], Re = { class: "ti-question-header" }, He = { class: "ti-question-number" }, Le = { class: "ti-question-time" }, Be = { class: "ti-question-text" }, Je = {
|
|
1061
|
+
key: 0,
|
|
1062
|
+
class: "ti-question-context"
|
|
1063
|
+
}, Ue = /* @__PURE__ */ z({
|
|
1064
|
+
__name: "QuestionHistory",
|
|
1065
|
+
props: {
|
|
1066
|
+
questions: {}
|
|
1067
|
+
},
|
|
1068
|
+
emits: ["clear", "select"],
|
|
1069
|
+
setup(c, { emit: e }) {
|
|
1070
|
+
const t = c, n = se(() => [...t.questions].reverse());
|
|
1071
|
+
function s(a) {
|
|
1072
|
+
const o = new Date(a), i = (/* @__PURE__ */ new Date()).getTime() - o.getTime(), l = Math.floor(i / 6e4), g = Math.floor(i / 36e5), p = Math.floor(i / 864e5);
|
|
1073
|
+
return l < 1 ? "Just now" : l < 60 ? `${l}m ago` : g < 24 ? `${g}h ago` : `${p}d ago`;
|
|
1074
|
+
}
|
|
1075
|
+
return (a, o) => (f(), h("div", Qe, [
|
|
1076
|
+
m("div", je, [
|
|
1077
|
+
o[1] || (o[1] = m("h3", null, "Question History", -1)),
|
|
1078
|
+
a.questions.length > 0 ? (f(), h("button", {
|
|
1079
|
+
key: 0,
|
|
1080
|
+
class: "ti-clear-btn",
|
|
1081
|
+
onClick: o[0] || (o[0] = (r) => a.$emit("clear"))
|
|
1082
|
+
}, " Clear History ")) : S("", !0)
|
|
1083
|
+
]),
|
|
1084
|
+
a.questions.length === 0 ? (f(), h("div", ze, o[2] || (o[2] = [
|
|
1085
|
+
m("div", { class: "ti-empty-icon" }, "💬", -1),
|
|
1086
|
+
m("p", null, "No questions asked yet", -1),
|
|
1087
|
+
m("p", { class: "ti-empty-hint" }, "Ask a question about your data to get started", -1)
|
|
1088
|
+
]))) : (f(), h("div", Fe, [
|
|
1089
|
+
(f(!0), h(O, null, Q(n.value, (r, i) => (f(), h("div", {
|
|
1090
|
+
key: r.id,
|
|
1091
|
+
class: "ti-history-item",
|
|
1092
|
+
onClick: (l) => a.$emit("select", r)
|
|
1093
|
+
}, [
|
|
1094
|
+
m("div", Re, [
|
|
1095
|
+
m("span", He, "#" + A(a.questions.length - i), 1),
|
|
1096
|
+
m("span", Le, A(s(r.timestamp)), 1)
|
|
1097
|
+
]),
|
|
1098
|
+
m("div", Be, A(r.text), 1),
|
|
1099
|
+
r.context ? (f(), h("div", Je, A(r.context.rowCount) + " rows ", 1)) : S("", !0)
|
|
1100
|
+
], 8, Ve))), 128))
|
|
1101
|
+
]))
|
|
1102
|
+
]));
|
|
1103
|
+
}
|
|
1104
|
+
}), Ze = /* @__PURE__ */ F(Ue, [["__scopeId", "data-v-c66393d9"]]);
|
|
299
1105
|
export {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
1106
|
+
Xe as AnswerDisplay,
|
|
1107
|
+
H as QAEngine,
|
|
1108
|
+
Ze as QuestionHistory,
|
|
1109
|
+
We as QuestionInput,
|
|
1110
|
+
de as TabularIntelligence,
|
|
1111
|
+
B as calculateStats,
|
|
1112
|
+
ue as convertToTabular,
|
|
1113
|
+
ae as detectAnomalies,
|
|
1114
|
+
U as executeAPIRequest,
|
|
1115
|
+
Ge as executeMultipleRequests,
|
|
1116
|
+
re as extractFromDOM,
|
|
1117
|
+
L as inferColumnType,
|
|
1118
|
+
N as inferSchema,
|
|
1119
|
+
oe as normalizeVueData,
|
|
1120
|
+
ce as parsePostmanCollection,
|
|
1121
|
+
I as replaceVariables,
|
|
1122
|
+
Ye as useTabularIntelligence
|
|
306
1123
|
};
|
|
307
1124
|
//# sourceMappingURL=index.mjs.map
|