@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/dist/index.mjs CHANGED
@@ -1,16 +1,545 @@
1
- import { ref as M } from "vue";
2
- class N {
3
- constructor(s) {
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
- timeout: 3e4,
6
- ...s
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(s) {
13
- const e = Date.now();
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
- ...s,
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 r = await n.text();
30
- throw new Error(`TFM API error: ${n.status} - ${r}`);
558
+ const o = await n.text();
559
+ throw new Error(`TFM API error: ${n.status} - ${o}`);
31
560
  }
32
- const t = await n.json(), i = Date.now() - e;
561
+ const s = await n.json(), a = Date.now() - t;
33
562
  return {
34
563
  success: !0,
35
- result: t.result || t,
564
+ result: s.result || s,
36
565
  metadata: {
37
- processingTime: i,
566
+ processingTime: a,
38
567
  model: this.config.model || "unknown",
39
- version: t.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() - e,
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(s) {
57
- const e = {
58
- operation: s.type,
59
- data: s.data,
60
- schema: s.schema,
61
- parameters: s.options
62
- }, n = await this.callTFM(e);
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(s.type, n.result, n.metadata);
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(s, e, n) {
71
- const t = {
72
- type: s,
599
+ parseAnalysisResult(e, t, n) {
600
+ const s = {
601
+ type: e,
73
602
  timestamp: /* @__PURE__ */ new Date(),
74
- summary: e.summary || "",
75
- insights: e.insights || [],
76
- recommendations: e.recommendations,
77
- confidence: e.confidence || 0.8,
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 (s) {
609
+ switch (e) {
81
610
  case "descriptive_stats":
82
611
  return {
83
- ...t,
84
- descriptiveStats: e.stats || e.descriptiveStats
612
+ ...s,
613
+ descriptiveStats: t.stats || t.descriptiveStats
85
614
  };
86
615
  case "anomaly_detection":
87
616
  return {
88
- ...t,
89
- anomalies: e.anomalies || []
617
+ ...s,
618
+ anomalies: t.anomalies || []
90
619
  };
91
620
  case "segmentation":
92
621
  case "clustering":
93
622
  return {
94
- ...t,
95
- clusters: e.clusters || []
623
+ ...s,
624
+ clusters: t.clusters || []
96
625
  };
97
626
  case "prediction":
98
627
  return {
99
- ...t,
100
- predictions: e.predictions || e
628
+ ...s,
629
+ predictions: t.predictions || t
101
630
  };
102
631
  case "correlation":
103
632
  return {
104
- ...t,
105
- correlations: e.correlations || e
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 t;
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(s) {
115
- this.config = { ...this.config, ...s };
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: s, ...e } = this.config;
122
- return e;
693
+ const { apiKey: e, ...t } = this.config;
694
+ return t;
123
695
  }
124
- }
125
- function T(c, s) {
126
- if (c.length === 0)
127
- return { columns: [], rowCount: 0, name: s };
128
- const e = c[0];
129
- return {
130
- columns: Object.keys(e).map((t) => {
131
- const i = $(c, t);
132
- return {
133
- name: t,
134
- type: i,
135
- nullable: c.some((r) => r[t] == null)
136
- };
137
- }),
138
- rowCount: c.length,
139
- name: s
140
- };
141
- }
142
- function $(c, s) {
143
- const e = c.map((t) => t[s]).filter((t) => t != null);
144
- if (e.length === 0) return "string";
145
- if (e.every((t) => typeof t == "number" || !isNaN(Number(t))))
146
- return "number";
147
- if (e.every((t) => typeof t == "boolean" || t === "true" || t === "false"))
148
- return "boolean";
149
- if (e.every((t) => !isNaN(Date.parse(t))))
150
- return "date";
151
- const n = new Set(e);
152
- return n.size < e.length * 0.5 && n.size < 20 ? "categorical" : "string";
153
- }
154
- function A(c, s, e) {
155
- const n = c.map((l) => l[s]).filter((l) => l != null), t = n.length, i = c.length - t, r = {
156
- column: s,
157
- count: t,
158
- nullCount: i
159
- };
160
- if (e === "number") {
161
- const l = n.map(Number).filter((o) => !isNaN(o));
162
- if (l.length > 0) {
163
- const o = [...l].sort((u, d) => u - d), p = l.reduce((u, d) => u + d, 0);
164
- r.mean = p / l.length, r.median = o[Math.floor(o.length / 2)], r.min = o[0], r.max = o[o.length - 1];
165
- const h = l.reduce((u, d) => u + Math.pow(d - r.mean, 2), 0) / l.length;
166
- r.std = Math.sqrt(h), r.percentiles = {
167
- 25: o[Math.floor(o.length * 0.25)],
168
- 50: r.median,
169
- 75: o[Math.floor(o.length * 0.75)],
170
- 90: o[Math.floor(o.length * 0.9)]
171
- };
172
- }
173
- } else {
174
- const l = new Set(n);
175
- r.uniqueValues = l.size;
176
- const o = {};
177
- n.forEach((h) => {
178
- const u = String(h);
179
- o[u] = (o[u] || 0) + 1;
180
- });
181
- const p = Math.max(...Object.values(o));
182
- r.mode = Object.keys(o).find((h) => o[h] === p);
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 E(c) {
207
- const s = new N(c.config), e = M(!1), n = M(null), t = M(null), i = c.data || M([]), r = c.schema || M(null), l = c.useLocalFallback !== !1;
208
- async function o(a, f) {
209
- e.value = !0, n.value = null;
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 y = {
212
- type: a,
213
- data: i.value,
214
- schema: r.value || void 0,
215
- options: f
216
- }, w = await s.analyze(y);
217
- return t.value = w, w;
218
- } catch (y) {
219
- if (n.value = y instanceof Error ? y : new Error("Analysis failed"), l)
220
- return p(a, f);
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
- e.value = !1;
785
+ t.value = !1;
224
786
  }
225
787
  }
226
- function p(a, f) {
227
- const y = r.value || T(i.value);
228
- switch (a) {
788
+ function y(u, w) {
789
+ const b = o.value || N(a.value);
790
+ switch (u) {
229
791
  case "descriptive_stats": {
230
- const w = y.columns.map(
231
- (b) => A(i.value, b.name, b.type)
792
+ const k = b.columns.map(
793
+ (x) => B(a.value, x.name, x.type)
232
794
  );
233
795
  return {
234
- type: a,
796
+ type: u,
235
797
  timestamp: /* @__PURE__ */ new Date(),
236
- descriptiveStats: w,
237
- summary: `Calculated statistics for ${w.length} columns`,
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 w = y.columns.filter((C) => C.type === "number").map((C) => C.name), b = F(
244
- i.value,
245
- w,
246
- f == null ? void 0 : f.sensitivity
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: a,
811
+ type: u,
250
812
  timestamp: /* @__PURE__ */ new Date(),
251
- anomalies: b,
252
- summary: `Found ${b.length} anomalies`,
253
- insights: b.slice(0, 3).map((C) => C.reasons[0]),
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: ${a}`);
820
+ throw new Error(`Local analysis not supported for type: ${u}`);
259
821
  }
260
822
  }
261
- async function h() {
262
- return (await o("descriptive_stats")).descriptiveStats || [];
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(a, f) {
265
- return (await o("anomaly_detection", { sensitivity: f, features: a })).anomalies || [];
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 d(a, f = 3) {
268
- return o("clustering", { features: a, numClusters: f });
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
- async function m(a, f) {
271
- return o("prediction", { targetColumn: a, ...f });
881
+ function K() {
882
+ r.value = [], i.value = [], l.value = null;
272
883
  }
273
- function g(a) {
274
- s.updateConfig(a);
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 v(a, f = !0) {
277
- i.value = a, f && (r.value = T(a));
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 S() {
280
- e.value = !1, n.value = null, t.value = null;
892
+ function W(u) {
893
+ e.initializeQA(u);
281
894
  }
282
895
  return {
283
- client: s,
284
- loading: e,
896
+ client: e,
897
+ loading: t,
285
898
  error: n,
286
- lastResult: t,
287
- data: i,
288
- schema: r,
289
- analyze: o,
290
- getDescriptiveStats: h,
291
- detectAnomalies: u,
292
- performClustering: d,
293
- predict: m,
294
- updateConfig: g,
295
- setData: v,
296
- reset: S
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
- N as TabularIntelligence,
301
- A as calculateStats,
302
- F as detectAnomalies,
303
- $ as inferColumnType,
304
- T as inferSchema,
305
- E as useTabularIntelligence
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