@aivue/tabular-intelligence 1.3.9 → 1.5.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 +70 -6
- package/dist/index.js +63 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +604 -483
- package/dist/index.mjs.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/qaEngine.d.ts +4 -0
- package/dist/utils/qaEngine.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { ref as
|
|
1
|
+
import { ref as q, defineComponent as j, createElementBlock as y, openBlock as g, createElementVNode as p, createCommentVNode as _, withDirectives as ee, withKeys as H, withModifiers as J, vModelText as te, toDisplayString as C, normalizeClass as ne, createTextVNode as ae, Fragment as F, renderList as O, computed as se } from "vue";
|
|
2
2
|
function N(l, e) {
|
|
3
3
|
if (l.length === 0)
|
|
4
4
|
return { columns: [], rowCount: 0, name: e };
|
|
5
|
-
const
|
|
5
|
+
const n = l[0];
|
|
6
6
|
return {
|
|
7
|
-
columns: Object.keys(
|
|
8
|
-
const r =
|
|
7
|
+
columns: Object.keys(n).map((t) => {
|
|
8
|
+
const r = L(l, t);
|
|
9
9
|
return {
|
|
10
|
-
name:
|
|
10
|
+
name: t,
|
|
11
11
|
type: r,
|
|
12
|
-
nullable: l.some((o) => o[
|
|
12
|
+
nullable: l.some((o) => o[t] == null)
|
|
13
13
|
};
|
|
14
14
|
}),
|
|
15
15
|
rowCount: l.length,
|
|
16
16
|
name: e
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
if (
|
|
19
|
+
function L(l, e) {
|
|
20
|
+
const n = l.map((t) => t[e]).filter((t) => t != null);
|
|
21
|
+
if (n.length === 0) return "string";
|
|
22
|
+
if (n.every((t) => typeof t == "number" || !isNaN(Number(t))))
|
|
23
23
|
return "number";
|
|
24
|
-
if (
|
|
24
|
+
if (n.every((t) => typeof t == "boolean" || t === "true" || t === "false"))
|
|
25
25
|
return "boolean";
|
|
26
|
-
if (
|
|
26
|
+
if (n.every((t) => !isNaN(Date.parse(t))))
|
|
27
27
|
return "date";
|
|
28
|
-
const
|
|
29
|
-
return
|
|
28
|
+
const a = new Set(n);
|
|
29
|
+
return a.size < n.length * 0.5 && a.size < 20 ? "categorical" : "string";
|
|
30
30
|
}
|
|
31
|
-
function
|
|
32
|
-
const
|
|
31
|
+
function B(l, e, n) {
|
|
32
|
+
const a = l.map((s) => s[e]).filter((s) => s != null), t = a.length, r = l.length - t, o = {
|
|
33
33
|
column: e,
|
|
34
|
-
count:
|
|
34
|
+
count: t,
|
|
35
35
|
nullCount: r
|
|
36
36
|
};
|
|
37
|
-
if (
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const i = [...
|
|
41
|
-
o.mean = c /
|
|
42
|
-
const
|
|
43
|
-
o.std = Math.sqrt(
|
|
37
|
+
if (n === "number") {
|
|
38
|
+
const s = a.map(Number).filter((i) => !isNaN(i));
|
|
39
|
+
if (s.length > 0) {
|
|
40
|
+
const i = [...s].sort((m, d) => m - d), c = s.reduce((m, d) => m + d, 0);
|
|
41
|
+
o.mean = c / s.length, o.median = i[Math.floor(i.length / 2)], o.min = i[0], o.max = i[i.length - 1];
|
|
42
|
+
const f = s.reduce((m, d) => m + Math.pow(d - o.mean, 2), 0) / s.length;
|
|
43
|
+
o.std = Math.sqrt(f), o.percentiles = {
|
|
44
44
|
25: i[Math.floor(i.length * 0.25)],
|
|
45
45
|
50: o.median,
|
|
46
46
|
75: i[Math.floor(i.length * 0.75)],
|
|
@@ -48,39 +48,39 @@ function J(l, e, t) {
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
} else {
|
|
51
|
-
const
|
|
52
|
-
o.uniqueValues =
|
|
51
|
+
const s = new Set(a);
|
|
52
|
+
o.uniqueValues = s.size;
|
|
53
53
|
const i = {};
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
i[
|
|
54
|
+
a.forEach((f) => {
|
|
55
|
+
const m = String(f);
|
|
56
|
+
i[m] = (i[m] || 0) + 1;
|
|
57
57
|
});
|
|
58
58
|
const c = Math.max(...Object.values(i));
|
|
59
|
-
o.mode = Object.keys(i).find((
|
|
59
|
+
o.mode = Object.keys(i).find((f) => i[f] === c);
|
|
60
60
|
}
|
|
61
61
|
return o;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
63
|
+
function re(l, e, n = 0.5) {
|
|
64
|
+
const a = [], t = 1.5 + (1 - n) * 1.5;
|
|
65
65
|
return e.forEach((r) => {
|
|
66
|
-
const o = l.map((
|
|
66
|
+
const o = l.map((w, b) => ({ value: Number(w[r]), idx: b })).filter((w) => !isNaN(w.value));
|
|
67
67
|
if (o.length === 0) return;
|
|
68
|
-
const
|
|
69
|
-
o.forEach(({ value:
|
|
70
|
-
if (
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
rowIndex:
|
|
74
|
-
row: l[
|
|
68
|
+
const s = [...o].sort((w, b) => w.value - b.value), i = s[Math.floor(s.length * 0.25)].value, c = s[Math.floor(s.length * 0.75)].value, f = c - i, m = i - t * f, d = c + t * f;
|
|
69
|
+
o.forEach(({ value: w, idx: b }) => {
|
|
70
|
+
if (w < m || w > d) {
|
|
71
|
+
const P = a.find((D) => D.rowIndex === b), $ = w < m ? `${r}: ${w.toFixed(2)} < ${m.toFixed(2)}` : `${r}: ${w.toFixed(2)} > ${d.toFixed(2)}`;
|
|
72
|
+
P ? (P.reasons.push($), P.affectedColumns.push(r), P.score = Math.min(1, P.score + 0.2)) : a.push({
|
|
73
|
+
rowIndex: b,
|
|
74
|
+
row: l[b],
|
|
75
75
|
score: 0.7,
|
|
76
|
-
reasons: [
|
|
76
|
+
reasons: [$],
|
|
77
77
|
affectedColumns: [r]
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
|
-
}),
|
|
81
|
+
}), a.sort((r, o) => o.score - r.score);
|
|
82
82
|
}
|
|
83
|
-
class
|
|
83
|
+
class U {
|
|
84
84
|
constructor(e) {
|
|
85
85
|
this.config = {
|
|
86
86
|
maxTokens: 1e3,
|
|
@@ -92,57 +92,57 @@ class B {
|
|
|
92
92
|
* Answer a question about the table data
|
|
93
93
|
*/
|
|
94
94
|
async answerQuestion(e) {
|
|
95
|
-
const
|
|
95
|
+
const n = Date.now();
|
|
96
96
|
try {
|
|
97
|
-
const { question:
|
|
97
|
+
const { question: a, schema: t, data: r, sampleSize: o = 100, includeAggregates: s = !0 } = e;
|
|
98
98
|
if (!r || !Array.isArray(r) || r.length === 0)
|
|
99
99
|
throw new Error("No data available. Please load data first.");
|
|
100
|
-
if (!
|
|
100
|
+
if (!t || !t.columns || !Array.isArray(t.columns))
|
|
101
101
|
throw new Error("Invalid schema. Please ensure data has a valid schema.");
|
|
102
|
-
const i = r.length > o ? this.sampleData(r, o) : r, c =
|
|
102
|
+
const i = r.length > o ? this.sampleData(r, o) : r, c = s ? this.calculateAggregates(r, t) : void 0, f = this.buildPrompt(a, t, i, c, r.length), m = await this.callLLM(f);
|
|
103
103
|
return {
|
|
104
|
-
answer: this.parseResponse(
|
|
105
|
-
processingTime: Date.now() -
|
|
104
|
+
answer: this.parseResponse(m, a, r.length > o),
|
|
105
|
+
processingTime: Date.now() - n
|
|
106
106
|
};
|
|
107
|
-
} catch (
|
|
108
|
-
return console.error("Q&A error:",
|
|
107
|
+
} catch (a) {
|
|
108
|
+
return console.error("Q&A error:", a), {
|
|
109
109
|
answer: {
|
|
110
110
|
questionId: this.generateId(),
|
|
111
111
|
text: "I encountered an error while processing your question. Please try again.",
|
|
112
112
|
timestamp: /* @__PURE__ */ new Date(),
|
|
113
113
|
confidence: 0,
|
|
114
114
|
cannotAnswer: !0,
|
|
115
|
-
reason:
|
|
115
|
+
reason: a instanceof Error ? a.message : "Unknown error"
|
|
116
116
|
},
|
|
117
|
-
processingTime: Date.now() -
|
|
117
|
+
processingTime: Date.now() - n
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
/**
|
|
122
122
|
* Sample data for large datasets
|
|
123
123
|
*/
|
|
124
|
-
sampleData(e,
|
|
124
|
+
sampleData(e, n) {
|
|
125
125
|
if (!e || !Array.isArray(e) || e.length === 0)
|
|
126
126
|
return [];
|
|
127
|
-
if (e.length <=
|
|
127
|
+
if (e.length <= n)
|
|
128
128
|
return e;
|
|
129
|
-
const
|
|
130
|
-
for (let r = 0; r < e.length &&
|
|
131
|
-
|
|
132
|
-
return
|
|
129
|
+
const a = Math.floor(e.length / n), t = [];
|
|
130
|
+
for (let r = 0; r < e.length && t.length < n; r += a)
|
|
131
|
+
t.push(e[r]);
|
|
132
|
+
return t;
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
135
|
* Calculate aggregates for numeric columns
|
|
136
136
|
*/
|
|
137
|
-
calculateAggregates(e,
|
|
138
|
-
const
|
|
139
|
-
if (!e || !Array.isArray(e) || e.length === 0 || !
|
|
140
|
-
return
|
|
141
|
-
for (const
|
|
142
|
-
if (
|
|
137
|
+
calculateAggregates(e, n) {
|
|
138
|
+
const a = {};
|
|
139
|
+
if (!e || !Array.isArray(e) || e.length === 0 || !n || !n.columns || !Array.isArray(n.columns))
|
|
140
|
+
return a;
|
|
141
|
+
for (const t of n.columns)
|
|
142
|
+
if (t.type === "number" && e.length > 0)
|
|
143
143
|
try {
|
|
144
|
-
const r =
|
|
145
|
-
|
|
144
|
+
const r = B(e, t.name, "number");
|
|
145
|
+
a[t.name] = {
|
|
146
146
|
mean: r.mean,
|
|
147
147
|
median: r.median,
|
|
148
148
|
min: r.min,
|
|
@@ -151,93 +151,214 @@ class B {
|
|
|
151
151
|
};
|
|
152
152
|
} catch {
|
|
153
153
|
}
|
|
154
|
-
else if (
|
|
155
|
-
const r = e.map((
|
|
156
|
-
|
|
154
|
+
else if (t.type === "categorical" || t.type === "string") {
|
|
155
|
+
const r = e.map((s) => s[t.name]).filter((s) => s != null), o = new Set(r);
|
|
156
|
+
a[t.name] = {
|
|
157
157
|
uniqueCount: o.size,
|
|
158
158
|
totalCount: r.length,
|
|
159
159
|
topValues: this.getTopValues(r, 5)
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
|
-
return
|
|
162
|
+
return a;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
165
|
* Get top N most frequent values
|
|
166
166
|
*/
|
|
167
|
-
getTopValues(e,
|
|
168
|
-
const
|
|
169
|
-
for (const
|
|
170
|
-
|
|
171
|
-
return Array.from(
|
|
167
|
+
getTopValues(e, n) {
|
|
168
|
+
const a = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const t of e)
|
|
170
|
+
a.set(t, (a.get(t) || 0) + 1);
|
|
171
|
+
return Array.from(a.entries()).map(([t, r]) => ({ value: t, count: r })).sort((t, r) => r.count - t.count).slice(0, n);
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Build prompt for LLM
|
|
175
175
|
*/
|
|
176
|
-
buildPrompt(e,
|
|
177
|
-
const o = r && r >
|
|
178
|
-
let
|
|
176
|
+
buildPrompt(e, n, a, t, r) {
|
|
177
|
+
const o = r && r > a.length;
|
|
178
|
+
let s = `You are a data analyst assistant. Answer the following question about a table dataset.
|
|
179
179
|
|
|
180
180
|
`;
|
|
181
|
-
|
|
182
|
-
`,
|
|
183
|
-
`,
|
|
181
|
+
s += `**Table Schema:**
|
|
182
|
+
`, s += `Table: ${n.name}
|
|
183
|
+
`, s += `Columns:
|
|
184
184
|
`;
|
|
185
|
-
for (const i of
|
|
186
|
-
|
|
185
|
+
for (const i of n.columns)
|
|
186
|
+
s += `- ${i.name} (${i.type})
|
|
187
187
|
`;
|
|
188
|
-
return
|
|
189
|
-
`,
|
|
190
|
-
`,
|
|
188
|
+
return s += `
|
|
189
|
+
`, t && Object.keys(t).length > 0 && (s += `**Summary Statistics:**
|
|
190
|
+
`, s += JSON.stringify(t, null, 2), s += `
|
|
191
191
|
|
|
192
|
-
`),
|
|
193
|
-
`,
|
|
192
|
+
`), s += `**Sample Data** (${a.length} rows${o ? ` out of ${r} total` : ""}):
|
|
193
|
+
`, s += JSON.stringify(a.slice(0, 10), null, 2), s += `
|
|
194
194
|
|
|
195
|
-
`,
|
|
195
|
+
`, s += `**Question:** ${e}
|
|
196
196
|
|
|
197
|
-
`,
|
|
198
|
-
`,
|
|
199
|
-
`,
|
|
200
|
-
`,
|
|
201
|
-
`,
|
|
202
|
-
`,
|
|
203
|
-
`,
|
|
204
|
-
`,
|
|
205
|
-
`,
|
|
206
|
-
`,
|
|
207
|
-
`,
|
|
208
|
-
`,
|
|
209
|
-
`,
|
|
210
|
-
`,
|
|
211
|
-
`,
|
|
197
|
+
`, s += `**Instructions:**
|
|
198
|
+
`, s += `1. You are a helpful AI data analyst that can answer questions about the table data, perform statistical analysis, make predictions, identify trends, AND engage in normal conversation.
|
|
199
|
+
`, s += `2. For data questions (e.g., "how many rows?", "what's the average?"), answer based on the data provided above.
|
|
200
|
+
`, s += `3. For statistical analysis requests (e.g., "calculate descriptive statistics", "show me mean/median/std dev"), compute and present the statistics clearly.
|
|
201
|
+
`, s += `4. For anomaly detection requests (e.g., "detect anomalies", "find outliers"), identify unusual data points and explain why they're anomalous.
|
|
202
|
+
`, s += `5. For clustering requests (e.g., "perform clustering", "group similar data"), identify natural groupings in the data and describe their characteristics.
|
|
203
|
+
`, s += `6. For correlation analysis requests (e.g., "show correlations", "what variables are related"), analyze relationships between variables and explain the strength and direction of correlations.
|
|
204
|
+
`, s += `7. For predictive questions (e.g., "predict future trends", "what will happen next?", "forecast X"), analyze patterns in the data and make reasonable predictions based on trends, correlations, and statistical patterns you observe.
|
|
205
|
+
`, s += `8. For analytical questions (e.g., "what insights?", "any patterns?", "recommendations?"), provide insights, trends, correlations, and actionable recommendations based on the data.
|
|
206
|
+
`, s += `9. For conversational questions (e.g., "hi", "hello", "what can you do?"), respond naturally and mention your capabilities.
|
|
207
|
+
`, s += `10. If a question is completely unrelated to data analysis (e.g., "what's the weather?"), politely explain you can only help with data analysis.
|
|
208
|
+
`, s += `11. Provide clear, concise answers with specific numbers and examples.
|
|
209
|
+
`, s += `12. When making predictions or identifying trends, explain your reasoning and mention the confidence level.
|
|
210
|
+
`, s += `13. If the answer is based on sampled data, mention that it's an approximation.
|
|
211
|
+
`, s += `14. Format your response as JSON with the following structure:
|
|
212
|
+
`, s += `{
|
|
213
|
+
`, s += ` "answer": "Your answer text here",
|
|
214
|
+
`, s += ` "confidence": 0.0-1.0,
|
|
215
|
+
`, s += ` "cannotAnswer": false,
|
|
216
|
+
`, s += ` "isApproximate": ${o},
|
|
217
|
+
`, s += ` "supportingData": { "key": "value" } // optional
|
|
218
|
+
`, s += `}
|
|
219
|
+
|
|
220
|
+
`, s += `Examples:
|
|
221
|
+
`, s += `- Question: "hi" → Answer: "Hello! I'm your AI data analyst. I can perform statistical analysis, detect anomalies, cluster data, analyze correlations, make predictions, and answer questions about this dataset."
|
|
222
|
+
`, s += `- Question: "how many rows?" → Answer: "There are ${r || a.length} rows in the dataset."
|
|
223
|
+
`, s += `- Question: "calculate descriptive statistics" → Answer: "Descriptive Statistics:\\n- Mean: 45.2\\n- Median: 42.0\\n- Std Dev: 12.5\\n- Min: 10\\n- Max: 95\\n- 25th Percentile: 35\\n- 75th Percentile: 58" (with confidence: 0.95)
|
|
224
|
+
`, s += `- Question: "detect anomalies" → Answer: "I found 3 anomalies in the dataset:\\n1. Row 15: Value 250 is 3.5 standard deviations above the mean\\n2. Row 42: Value -10 is unusually low\\n3. Row 88: Value 300 is an extreme outlier" (with confidence: 0.85)
|
|
225
|
+
`, s += `- Question: "perform clustering" → Answer: "I identified 3 natural clusters in the data:\\n- Cluster 1 (40%): Low values, avg 25\\n- Cluster 2 (35%): Medium values, avg 50\\n- Cluster 3 (25%): High values, avg 85" (with confidence: 0.8)
|
|
226
|
+
`, s += `- Question: "show correlation analysis" → Answer: "Correlation Analysis:\\n- Price & Quantity: -0.65 (strong negative)\\n- Revenue & Price: 0.82 (strong positive)\\n- Quantity & Revenue: 0.45 (moderate positive)" (with confidence: 0.9)
|
|
227
|
+
`, s += `- Question: "predict future sales" → Answer: "Based on the trend in the data, sales are increasing by 15% monthly. If this continues, next month's sales could reach approximately $50,000." (with confidence: 0.7)
|
|
228
|
+
`, s += `- Question: "what insights can you give?" → Answer: "Key insights: 1) Sales peak on weekends, 2) Product A is the top seller, 3) Customer retention is 85%..."
|
|
229
|
+
`, s += `- Question: "what's the weather?" → Answer: "I cannot answer this question as it's not related to the dataset. I can only help with questions about this data."
|
|
230
|
+
`, s;
|
|
212
231
|
}
|
|
213
232
|
/**
|
|
214
233
|
* Call LLM API
|
|
215
234
|
*/
|
|
216
235
|
async callLLM(e) {
|
|
217
|
-
const { provider:
|
|
218
|
-
if (
|
|
219
|
-
return this.
|
|
220
|
-
if (
|
|
221
|
-
return this.
|
|
222
|
-
if (
|
|
223
|
-
return this.
|
|
224
|
-
|
|
236
|
+
const { provider: n, apiKey: a, baseUrl: t, model: r, maxTokens: o, temperature: s } = this.config;
|
|
237
|
+
if (!a && n !== "custom")
|
|
238
|
+
return this.fallbackResponse(e);
|
|
239
|
+
if (n === "openai")
|
|
240
|
+
return this.callOpenAI(e, a, r || "gpt-4-turbo-preview", o, s);
|
|
241
|
+
if (n === "anthropic")
|
|
242
|
+
return this.callAnthropic(e, a, r || "claude-3-5-sonnet-20241022", o, s);
|
|
243
|
+
if (n === "custom" && t)
|
|
244
|
+
return this.callCustomAPI(e, t, a);
|
|
245
|
+
throw new Error(`Unsupported provider: ${n}`);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Fallback response when no API key is available
|
|
249
|
+
*/
|
|
250
|
+
fallbackResponse(e) {
|
|
251
|
+
const n = e.match(/\*\*Question:\*\* (.+)/), t = (n ? n[1].trim() : "").toLowerCase();
|
|
252
|
+
if (/^(hi|hello|hey|greetings|good morning|good afternoon|good evening)/.test(t))
|
|
253
|
+
return JSON.stringify({
|
|
254
|
+
answer: "Hello! 👋 I'm your data analysis assistant. I can help you explore and understand this dataset. Try asking questions like 'How many rows are there?', 'What columns do we have?', or 'Show me a summary of the data'. For more advanced analysis, please configure an OpenAI or Anthropic API key in the settings.",
|
|
255
|
+
confidence: 1,
|
|
256
|
+
cannotAnswer: !1,
|
|
257
|
+
isApproximate: !1
|
|
258
|
+
});
|
|
259
|
+
if (/what (can|do) you|help|capabilities|features/.test(t))
|
|
260
|
+
return JSON.stringify({
|
|
261
|
+
answer: `I can help you analyze tabular data! You can ask me questions like:
|
|
262
|
+
• 'How many rows/columns are there?'
|
|
263
|
+
• 'What are the column names?'
|
|
264
|
+
• 'Show me basic statistics'
|
|
265
|
+
• 'What's the data about?'
|
|
266
|
+
|
|
267
|
+
With an OpenAI or Anthropic API key, I can also:
|
|
268
|
+
• Calculate descriptive statistics (mean, median, std dev, percentiles)
|
|
269
|
+
• Detect anomalies and outliers
|
|
270
|
+
• Perform clustering analysis
|
|
271
|
+
• Analyze correlations between variables
|
|
272
|
+
• Make predictions and forecasts
|
|
273
|
+
• Identify trends and patterns
|
|
274
|
+
• Provide insights and recommendations
|
|
275
|
+
• Answer complex analytical questions
|
|
276
|
+
|
|
277
|
+
Please add your API key in the AI Chatbot Configuration section for advanced features.`,
|
|
278
|
+
confidence: 1,
|
|
279
|
+
cannotAnswer: !1,
|
|
280
|
+
isApproximate: !1
|
|
281
|
+
});
|
|
282
|
+
const r = e.match(/\*\*Sample Data\*\* \((\d+) rows/), o = e.match(/out of (\d+) total/), s = e.match(/Columns:\n((?:- .+\n)+)/), i = r ? parseInt(r[1]) : 0, c = o ? parseInt(o[1]) : i;
|
|
283
|
+
if (/how many (rows|records|entries|items)/.test(t))
|
|
284
|
+
return JSON.stringify({
|
|
285
|
+
answer: `There are ${c} rows in the dataset.`,
|
|
286
|
+
confidence: 1,
|
|
287
|
+
cannotAnswer: !1,
|
|
288
|
+
isApproximate: !1
|
|
289
|
+
});
|
|
290
|
+
if (/how many columns|what columns|column names|list columns/.test(t) && s) {
|
|
291
|
+
const f = s[1].trim().split(`
|
|
292
|
+
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
293
|
+
return JSON.stringify({
|
|
294
|
+
answer: `The dataset has ${f.length} columns: ${f.join(", ")}.`,
|
|
295
|
+
confidence: 1,
|
|
296
|
+
cannotAnswer: !1,
|
|
297
|
+
isApproximate: !1
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
if (/summary|overview|describe|what.*data|tell me about/.test(t) && s) {
|
|
301
|
+
const f = s[1].trim().split(`
|
|
302
|
+
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
303
|
+
return JSON.stringify({
|
|
304
|
+
answer: `This dataset contains ${c} rows and ${f.length} columns. The columns are: ${f.join(", ")}. For detailed analysis and insights, please configure an OpenAI or Anthropic API key.`,
|
|
305
|
+
confidence: 0.8,
|
|
306
|
+
cannotAnswer: !1,
|
|
307
|
+
isApproximate: !1
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return /descriptive statistics|calculate statistics|mean|median|std dev|standard deviation|percentile/.test(t) ? JSON.stringify({
|
|
311
|
+
answer: "I can calculate descriptive statistics with an OpenAI or Anthropic API key! I'll provide mean, median, standard deviation, min, max, and percentiles for all numeric columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
312
|
+
confidence: 0.3,
|
|
313
|
+
cannotAnswer: !0,
|
|
314
|
+
reason: "Statistical analysis requires AI. Please configure an API key."
|
|
315
|
+
}) : /anomaly|anomalies|outlier|outliers|detect anomal|find outlier/.test(t) ? JSON.stringify({
|
|
316
|
+
answer: "I can detect anomalies and outliers with an OpenAI or Anthropic API key! I'll identify unusual data points and explain why they're anomalous. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
317
|
+
confidence: 0.3,
|
|
318
|
+
cannotAnswer: !0,
|
|
319
|
+
reason: "Anomaly detection requires AI. Please configure an API key."
|
|
320
|
+
}) : /cluster|clustering|group|grouping|segment|segmentation/.test(t) ? JSON.stringify({
|
|
321
|
+
answer: "I can perform clustering analysis with an OpenAI or Anthropic API key! I'll identify natural groupings in your data and describe their characteristics. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
322
|
+
confidence: 0.3,
|
|
323
|
+
cannotAnswer: !0,
|
|
324
|
+
reason: "Clustering analysis requires AI. Please configure an API key."
|
|
325
|
+
}) : /correlation|correlate|relationship|relate|association/.test(t) ? JSON.stringify({
|
|
326
|
+
answer: "I can analyze correlations between variables with an OpenAI or Anthropic API key! I'll show you the strength and direction of relationships between different columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
327
|
+
confidence: 0.3,
|
|
328
|
+
cannotAnswer: !0,
|
|
329
|
+
reason: "Correlation analysis requires AI. Please configure an API key."
|
|
330
|
+
}) : /predict|forecast|future|trend|next|will be|gonna be|going to be/.test(t) ? JSON.stringify({
|
|
331
|
+
answer: "I'd love to help you make predictions based on this data! However, I need an OpenAI or Anthropic API key to analyze patterns, identify trends, and make accurate forecasts. Please add your API key in the 'AI Chatbot Configuration' section above, and I'll be able to provide detailed predictions with confidence scores.",
|
|
332
|
+
confidence: 0.3,
|
|
333
|
+
cannotAnswer: !0,
|
|
334
|
+
reason: "Predictions require AI analysis. Please configure an API key for advanced features."
|
|
335
|
+
}) : /insight|pattern|analysis|analyze|recommendation/.test(t) ? JSON.stringify({
|
|
336
|
+
answer: "I can provide deep insights and analysis with an OpenAI or Anthropic API key! I'll be able to identify patterns, trends, and give you actionable recommendations. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
337
|
+
confidence: 0.3,
|
|
338
|
+
cannotAnswer: !0,
|
|
339
|
+
reason: "Advanced analysis requires AI. Please configure an API key."
|
|
340
|
+
}) : JSON.stringify({
|
|
341
|
+
answer: "I need an OpenAI or Anthropic API key to answer this question. Please add your API key in the 'AI Chatbot Configuration' section above. For now, I can only answer basic questions like 'How many rows?' or 'What columns are there?'",
|
|
342
|
+
confidence: 0.5,
|
|
343
|
+
cannotAnswer: !0,
|
|
344
|
+
reason: "No API key configured for advanced natural language processing"
|
|
345
|
+
});
|
|
225
346
|
}
|
|
226
347
|
/**
|
|
227
348
|
* Call OpenAI API
|
|
228
349
|
*/
|
|
229
|
-
async callOpenAI(e,
|
|
350
|
+
async callOpenAI(e, n, a, t, r) {
|
|
230
351
|
var i, c;
|
|
231
352
|
const o = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
232
353
|
method: "POST",
|
|
233
354
|
headers: {
|
|
234
355
|
"Content-Type": "application/json",
|
|
235
|
-
Authorization: `Bearer ${
|
|
356
|
+
Authorization: `Bearer ${n}`
|
|
236
357
|
},
|
|
237
358
|
body: JSON.stringify({
|
|
238
|
-
model:
|
|
359
|
+
model: a,
|
|
239
360
|
messages: [{ role: "user", content: e }],
|
|
240
|
-
max_tokens:
|
|
361
|
+
max_tokens: t,
|
|
241
362
|
temperature: r,
|
|
242
363
|
response_format: { type: "json_object" }
|
|
243
364
|
})
|
|
@@ -249,18 +370,18 @@ class B {
|
|
|
249
370
|
/**
|
|
250
371
|
* Call Anthropic API
|
|
251
372
|
*/
|
|
252
|
-
async callAnthropic(e,
|
|
373
|
+
async callAnthropic(e, n, a, t, r) {
|
|
253
374
|
var i;
|
|
254
375
|
const o = await fetch("https://api.anthropic.com/v1/messages", {
|
|
255
376
|
method: "POST",
|
|
256
377
|
headers: {
|
|
257
378
|
"Content-Type": "application/json",
|
|
258
|
-
"x-api-key":
|
|
379
|
+
"x-api-key": n,
|
|
259
380
|
"anthropic-version": "2023-06-01"
|
|
260
381
|
},
|
|
261
382
|
body: JSON.stringify({
|
|
262
|
-
model:
|
|
263
|
-
max_tokens:
|
|
383
|
+
model: a,
|
|
384
|
+
max_tokens: t,
|
|
264
385
|
temperature: r,
|
|
265
386
|
messages: [{ role: "user", content: e }]
|
|
266
387
|
})
|
|
@@ -272,14 +393,14 @@ class B {
|
|
|
272
393
|
/**
|
|
273
394
|
* Call custom API
|
|
274
395
|
*/
|
|
275
|
-
async callCustomAPI(e,
|
|
276
|
-
const
|
|
396
|
+
async callCustomAPI(e, n, a) {
|
|
397
|
+
const t = {
|
|
277
398
|
"Content-Type": "application/json"
|
|
278
399
|
};
|
|
279
|
-
|
|
280
|
-
const r = await fetch(
|
|
400
|
+
a && (t.Authorization = `Bearer ${a}`);
|
|
401
|
+
const r = await fetch(n, {
|
|
281
402
|
method: "POST",
|
|
282
|
-
headers:
|
|
403
|
+
headers: t,
|
|
283
404
|
body: JSON.stringify({ prompt: e })
|
|
284
405
|
});
|
|
285
406
|
if (!r.ok)
|
|
@@ -290,18 +411,18 @@ class B {
|
|
|
290
411
|
/**
|
|
291
412
|
* Parse LLM response
|
|
292
413
|
*/
|
|
293
|
-
parseResponse(e,
|
|
414
|
+
parseResponse(e, n, a) {
|
|
294
415
|
try {
|
|
295
|
-
const
|
|
416
|
+
const t = JSON.parse(e);
|
|
296
417
|
return {
|
|
297
418
|
questionId: this.generateId(),
|
|
298
|
-
text:
|
|
419
|
+
text: t.answer || t.text || e,
|
|
299
420
|
timestamp: /* @__PURE__ */ new Date(),
|
|
300
|
-
confidence:
|
|
301
|
-
cannotAnswer:
|
|
302
|
-
isApproximate:
|
|
303
|
-
supportingData:
|
|
304
|
-
reason:
|
|
421
|
+
confidence: t.confidence || 0.8,
|
|
422
|
+
cannotAnswer: t.cannotAnswer || !1,
|
|
423
|
+
isApproximate: t.isApproximate !== void 0 ? t.isApproximate : a,
|
|
424
|
+
supportingData: t.supportingData,
|
|
425
|
+
reason: t.reason
|
|
305
426
|
};
|
|
306
427
|
} catch {
|
|
307
428
|
return {
|
|
@@ -309,7 +430,7 @@ class B {
|
|
|
309
430
|
text: e,
|
|
310
431
|
timestamp: /* @__PURE__ */ new Date(),
|
|
311
432
|
confidence: 0.7,
|
|
312
|
-
isApproximate:
|
|
433
|
+
isApproximate: a
|
|
313
434
|
};
|
|
314
435
|
}
|
|
315
436
|
}
|
|
@@ -323,9 +444,9 @@ class B {
|
|
|
323
444
|
function oe(l = {}) {
|
|
324
445
|
const {
|
|
325
446
|
selector: e = "table",
|
|
326
|
-
includeHeaders:
|
|
327
|
-
maxRows:
|
|
328
|
-
inferTypes:
|
|
447
|
+
includeHeaders: n = !0,
|
|
448
|
+
maxRows: a,
|
|
449
|
+
inferTypes: t = !0,
|
|
329
450
|
skipEmptyRows: r = !0
|
|
330
451
|
} = l, o = document.querySelector(e);
|
|
331
452
|
if (!o || o.tagName !== "TABLE")
|
|
@@ -333,57 +454,57 @@ function oe(l = {}) {
|
|
|
333
454
|
const i = Array.from(o.rows);
|
|
334
455
|
if (i.length === 0)
|
|
335
456
|
return null;
|
|
336
|
-
let c = [],
|
|
337
|
-
if (
|
|
338
|
-
const
|
|
339
|
-
c = Array.from(
|
|
340
|
-
var
|
|
341
|
-
return ((
|
|
342
|
-
}),
|
|
457
|
+
let c = [], f = 0;
|
|
458
|
+
if (n && i[0]) {
|
|
459
|
+
const b = i[0];
|
|
460
|
+
c = Array.from(b.cells).map((P, $) => {
|
|
461
|
+
var x;
|
|
462
|
+
return ((x = P.textContent) == null ? void 0 : x.trim()) || "" || `Column${$ + 1}`;
|
|
463
|
+
}), f = 1;
|
|
343
464
|
} else {
|
|
344
|
-
const
|
|
345
|
-
c = Array.from(
|
|
465
|
+
const b = i[0];
|
|
466
|
+
c = Array.from(b.cells).map((P, $) => `Column${$ + 1}`);
|
|
346
467
|
}
|
|
347
|
-
const
|
|
348
|
-
for (const
|
|
349
|
-
const
|
|
350
|
-
if (r &&
|
|
351
|
-
var
|
|
352
|
-
return !((
|
|
468
|
+
const m = [], d = a ? i.slice(f, f + a) : i.slice(f);
|
|
469
|
+
for (const b of d) {
|
|
470
|
+
const P = Array.from(b.cells);
|
|
471
|
+
if (r && P.every((D) => {
|
|
472
|
+
var x;
|
|
473
|
+
return !((x = D.textContent) != null && x.trim());
|
|
353
474
|
}))
|
|
354
475
|
continue;
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
var
|
|
358
|
-
const
|
|
359
|
-
let
|
|
360
|
-
if (
|
|
361
|
-
const M = parseFloat(
|
|
362
|
-
!isNaN(M) &&
|
|
476
|
+
const $ = {};
|
|
477
|
+
P.forEach((D, x) => {
|
|
478
|
+
var Q;
|
|
479
|
+
const z = c[x] || `Column${x + 1}`;
|
|
480
|
+
let E = ((Q = D.textContent) == null ? void 0 : Q.trim()) || "";
|
|
481
|
+
if (t && E) {
|
|
482
|
+
const M = parseFloat(E);
|
|
483
|
+
!isNaN(M) && E === M.toString() && (E = M);
|
|
363
484
|
}
|
|
364
|
-
|
|
365
|
-
}),
|
|
485
|
+
$[z] = E;
|
|
486
|
+
}), m.push($);
|
|
366
487
|
}
|
|
367
488
|
return {
|
|
368
|
-
schema:
|
|
369
|
-
data:
|
|
489
|
+
schema: t && m.length > 0 ? N(m, "Extracted Table") : le(c, m.length),
|
|
490
|
+
data: m,
|
|
370
491
|
source: "dom",
|
|
371
492
|
metadata: {
|
|
372
493
|
selector: e,
|
|
373
|
-
rowCount:
|
|
494
|
+
rowCount: m.length,
|
|
374
495
|
columnCount: c.length,
|
|
375
496
|
extractedAt: /* @__PURE__ */ new Date()
|
|
376
497
|
}
|
|
377
498
|
};
|
|
378
499
|
}
|
|
379
|
-
function ie(l, e,
|
|
380
|
-
const { maxRows:
|
|
500
|
+
function ie(l, e, n = {}) {
|
|
501
|
+
const { maxRows: a, inferTypes: t = !0 } = n, r = a ? l.slice(0, a) : l;
|
|
381
502
|
let o;
|
|
382
503
|
return e && e.length > 0 ? o = {
|
|
383
504
|
name: "Vue Data Grid",
|
|
384
|
-
columns: e.map((
|
|
385
|
-
name:
|
|
386
|
-
type:
|
|
505
|
+
columns: e.map((s) => ({
|
|
506
|
+
name: s.field,
|
|
507
|
+
type: t && r.length > 0 ? L(r, s.field) : "string",
|
|
387
508
|
nullable: !0
|
|
388
509
|
})),
|
|
389
510
|
rowCount: r.length
|
|
@@ -401,8 +522,8 @@ function ie(l, e, t = {}) {
|
|
|
401
522
|
function le(l, e = 0) {
|
|
402
523
|
return {
|
|
403
524
|
name: "Extracted Table",
|
|
404
|
-
columns: l.map((
|
|
405
|
-
name:
|
|
525
|
+
columns: l.map((n) => ({
|
|
526
|
+
name: n,
|
|
406
527
|
type: "string",
|
|
407
528
|
nullable: !0
|
|
408
529
|
})),
|
|
@@ -414,101 +535,101 @@ function ce(l) {
|
|
|
414
535
|
l.variable && l.variable.forEach((r) => {
|
|
415
536
|
e[r.key] = r.value;
|
|
416
537
|
});
|
|
417
|
-
const
|
|
418
|
-
function
|
|
419
|
-
r.forEach((
|
|
420
|
-
|
|
538
|
+
const n = l.auth ? K(l.auth) : void 0, a = [];
|
|
539
|
+
function t(r, o = "") {
|
|
540
|
+
r.forEach((s) => {
|
|
541
|
+
s.item ? t(s.item, o ? `${o}/${s.name}` : s.name) : s.request && a.push(ue(s, n));
|
|
421
542
|
});
|
|
422
543
|
}
|
|
423
|
-
return
|
|
544
|
+
return t(l.item), {
|
|
424
545
|
name: l.info.name,
|
|
425
546
|
description: l.info.description,
|
|
426
|
-
endpoints:
|
|
547
|
+
endpoints: a,
|
|
427
548
|
variables: e,
|
|
428
|
-
auth:
|
|
549
|
+
auth: n
|
|
429
550
|
};
|
|
430
551
|
}
|
|
431
552
|
function ue(l, e) {
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
553
|
+
const n = l.request, a = {};
|
|
554
|
+
n.header && n.header.forEach((o) => {
|
|
555
|
+
a[o.key] = o.value;
|
|
435
556
|
});
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
557
|
+
const t = {};
|
|
558
|
+
n.url.query && n.url.query.forEach((o) => {
|
|
559
|
+
t[o.key] = o.value;
|
|
439
560
|
});
|
|
440
|
-
const r =
|
|
561
|
+
const r = n.auth ? K(n.auth) : e;
|
|
441
562
|
return {
|
|
442
563
|
name: l.name,
|
|
443
|
-
method:
|
|
444
|
-
url:
|
|
445
|
-
description:
|
|
446
|
-
headers:
|
|
447
|
-
queryParams:
|
|
564
|
+
method: n.method,
|
|
565
|
+
url: n.url.raw,
|
|
566
|
+
description: n.description,
|
|
567
|
+
headers: a,
|
|
568
|
+
queryParams: t,
|
|
448
569
|
auth: r
|
|
449
570
|
};
|
|
450
571
|
}
|
|
451
572
|
function K(l) {
|
|
452
573
|
const e = {};
|
|
453
|
-
return l.apikey ? l.apikey.forEach((
|
|
454
|
-
e[
|
|
455
|
-
}) : l.bearer ? l.bearer.forEach((
|
|
456
|
-
e[
|
|
457
|
-
}) : l.basic && l.basic.forEach((
|
|
458
|
-
e[
|
|
574
|
+
return l.apikey ? l.apikey.forEach((n) => {
|
|
575
|
+
e[n.key] = n.value;
|
|
576
|
+
}) : l.bearer ? l.bearer.forEach((n) => {
|
|
577
|
+
e[n.key] = n.value;
|
|
578
|
+
}) : l.basic && l.basic.forEach((n) => {
|
|
579
|
+
e[n.key] = n.value;
|
|
459
580
|
}), {
|
|
460
581
|
type: l.type,
|
|
461
582
|
credentials: e
|
|
462
583
|
};
|
|
463
584
|
}
|
|
464
|
-
function
|
|
465
|
-
let
|
|
466
|
-
return Object.keys(e).forEach((
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
}),
|
|
585
|
+
function T(l, e) {
|
|
586
|
+
let n = l;
|
|
587
|
+
return Object.keys(e).forEach((a) => {
|
|
588
|
+
const t = new RegExp(`{{${a}}}`, "g");
|
|
589
|
+
n = n.replace(t, e[a]);
|
|
590
|
+
}), n;
|
|
470
591
|
}
|
|
471
|
-
async function
|
|
472
|
-
const { endpoint: e, variables:
|
|
592
|
+
async function W(l) {
|
|
593
|
+
const { endpoint: e, variables: n = {}, additionalHeaders: a = {}, additionalParams: t = {} } = l;
|
|
473
594
|
try {
|
|
474
|
-
let r =
|
|
475
|
-
const o = { ...e.queryParams, ...
|
|
476
|
-
|
|
595
|
+
let r = T(e.url, n);
|
|
596
|
+
const o = { ...e.queryParams, ...n, ...t }, s = Object.keys(o).filter((d) => o[d] !== void 0 && o[d] !== "").map((d) => `${encodeURIComponent(d)}=${encodeURIComponent(T(String(o[d]), n))}`).join("&");
|
|
597
|
+
s && (r = r.includes("?") ? `${r}&${s}` : `${r}?${s}`);
|
|
477
598
|
const i = {
|
|
478
599
|
"Content-Type": "application/json",
|
|
479
600
|
...e.headers,
|
|
480
|
-
...
|
|
601
|
+
...a
|
|
481
602
|
};
|
|
482
603
|
if (Object.keys(i).forEach((d) => {
|
|
483
|
-
i[d] =
|
|
604
|
+
i[d] = T(i[d], n);
|
|
484
605
|
}), e.auth) {
|
|
485
606
|
if (e.auth.type === "apikey") {
|
|
486
|
-
const d = e.auth.credentials.key || "access_key",
|
|
487
|
-
e.auth.credentials.in === "header" && (i[d] =
|
|
607
|
+
const d = e.auth.credentials.key || "access_key", w = T(e.auth.credentials.value || "", n);
|
|
608
|
+
e.auth.credentials.in === "header" && (i[d] = w);
|
|
488
609
|
} else if (e.auth.type === "bearer") {
|
|
489
|
-
const d =
|
|
610
|
+
const d = T(e.auth.credentials.token || "", n);
|
|
490
611
|
i.Authorization = `Bearer ${d}`;
|
|
491
612
|
} else if (e.auth.type === "basic") {
|
|
492
|
-
const d =
|
|
493
|
-
i.Authorization = `Basic ${
|
|
613
|
+
const d = T(e.auth.credentials.username || "", n), w = T(e.auth.credentials.password || "", n), b = btoa(`${d}:${w}`);
|
|
614
|
+
i.Authorization = `Basic ${b}`;
|
|
494
615
|
}
|
|
495
616
|
}
|
|
496
617
|
const c = await fetch(r, {
|
|
497
618
|
method: e.method,
|
|
498
619
|
headers: i
|
|
499
|
-
}),
|
|
500
|
-
return c.headers.forEach((d,
|
|
501
|
-
w
|
|
620
|
+
}), f = {};
|
|
621
|
+
return c.headers.forEach((d, w) => {
|
|
622
|
+
f[w] = d;
|
|
502
623
|
}), c.ok ? {
|
|
503
624
|
success: !0,
|
|
504
625
|
data: await c.json(),
|
|
505
626
|
statusCode: c.status,
|
|
506
|
-
headers:
|
|
627
|
+
headers: f
|
|
507
628
|
} : {
|
|
508
629
|
success: !1,
|
|
509
630
|
error: `HTTP ${c.status}: ${c.statusText}`,
|
|
510
631
|
statusCode: c.status,
|
|
511
|
-
headers:
|
|
632
|
+
headers: f
|
|
512
633
|
};
|
|
513
634
|
} catch (r) {
|
|
514
635
|
return {
|
|
@@ -517,13 +638,13 @@ async function G(l) {
|
|
|
517
638
|
};
|
|
518
639
|
}
|
|
519
640
|
}
|
|
520
|
-
async function
|
|
521
|
-
const
|
|
522
|
-
for (const
|
|
523
|
-
const
|
|
524
|
-
|
|
641
|
+
async function Ge(l, e = {}) {
|
|
642
|
+
const n = [];
|
|
643
|
+
for (const a of l) {
|
|
644
|
+
const t = await W({ endpoint: a, variables: e });
|
|
645
|
+
n.push(t);
|
|
525
646
|
}
|
|
526
|
-
return
|
|
647
|
+
return n;
|
|
527
648
|
}
|
|
528
649
|
function de(l) {
|
|
529
650
|
if (!l.success || !l.data)
|
|
@@ -531,28 +652,28 @@ function de(l) {
|
|
|
531
652
|
const e = l.data;
|
|
532
653
|
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] : [];
|
|
533
654
|
}
|
|
534
|
-
class
|
|
535
|
-
constructor(e,
|
|
655
|
+
class he {
|
|
656
|
+
constructor(e, n) {
|
|
536
657
|
this.config = {
|
|
537
658
|
timeout: 3e4,
|
|
538
659
|
...e
|
|
539
|
-
},
|
|
660
|
+
}, n && (this.qaEngine = new U(n));
|
|
540
661
|
}
|
|
541
662
|
/**
|
|
542
663
|
* Initialize or update Q&A engine
|
|
543
664
|
*/
|
|
544
665
|
initializeQA(e) {
|
|
545
|
-
this.qaEngine = new
|
|
666
|
+
this.qaEngine = new U(e);
|
|
546
667
|
}
|
|
547
668
|
/**
|
|
548
669
|
* Generic API call to TFM endpoint
|
|
549
670
|
*/
|
|
550
671
|
async callTFM(e) {
|
|
551
|
-
const
|
|
672
|
+
const n = Date.now();
|
|
552
673
|
try {
|
|
553
|
-
let
|
|
554
|
-
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ?
|
|
555
|
-
const
|
|
674
|
+
let a = this.config.baseUrl;
|
|
675
|
+
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ? a = this.config.corsProxyUrl + encodeURIComponent(a) : a = (this.config.corsProxyUrl.endsWith("/") ? this.config.corsProxyUrl : this.config.corsProxyUrl + "/") + a, console.log("Using CORS proxy for TFM API call:", this.config.corsProxyUrl), console.log("Proxied URL:", a));
|
|
676
|
+
const t = await fetch(a, {
|
|
556
677
|
method: "POST",
|
|
557
678
|
headers: {
|
|
558
679
|
"Content-Type": "application/json",
|
|
@@ -565,11 +686,11 @@ class me {
|
|
|
565
686
|
}),
|
|
566
687
|
signal: AbortSignal.timeout(this.config.timeout || 3e4)
|
|
567
688
|
});
|
|
568
|
-
if (!
|
|
569
|
-
const
|
|
570
|
-
throw new Error(`TFM API error: ${
|
|
689
|
+
if (!t.ok) {
|
|
690
|
+
const s = await t.text();
|
|
691
|
+
throw new Error(`TFM API error: ${t.status} - ${s}`);
|
|
571
692
|
}
|
|
572
|
-
const r = await
|
|
693
|
+
const r = await t.json(), o = Date.now() - n;
|
|
573
694
|
return {
|
|
574
695
|
success: !0,
|
|
575
696
|
result: r.result || r,
|
|
@@ -579,12 +700,12 @@ class me {
|
|
|
579
700
|
version: r.version
|
|
580
701
|
}
|
|
581
702
|
};
|
|
582
|
-
} catch (
|
|
703
|
+
} catch (a) {
|
|
583
704
|
return {
|
|
584
705
|
success: !1,
|
|
585
|
-
error:
|
|
706
|
+
error: a instanceof Error ? a.message : "Unknown error",
|
|
586
707
|
metadata: {
|
|
587
|
-
processingTime: Date.now() -
|
|
708
|
+
processingTime: Date.now() - n,
|
|
588
709
|
model: this.config.model || "unknown"
|
|
589
710
|
}
|
|
590
711
|
};
|
|
@@ -594,68 +715,68 @@ class me {
|
|
|
594
715
|
* Perform analysis on tabular data
|
|
595
716
|
*/
|
|
596
717
|
async analyze(e) {
|
|
597
|
-
const
|
|
718
|
+
const n = {
|
|
598
719
|
operation: e.type,
|
|
599
720
|
data: e.data,
|
|
600
721
|
schema: e.schema,
|
|
601
722
|
parameters: e.options
|
|
602
|
-
},
|
|
603
|
-
if (!
|
|
604
|
-
throw new Error(
|
|
605
|
-
return this.parseAnalysisResult(e.type,
|
|
723
|
+
}, a = await this.callTFM(n);
|
|
724
|
+
if (!a.success)
|
|
725
|
+
throw new Error(a.error || "Analysis failed");
|
|
726
|
+
return this.parseAnalysisResult(e.type, a.result, a.metadata);
|
|
606
727
|
}
|
|
607
728
|
/**
|
|
608
729
|
* Parse TFM response into structured AnalysisResult
|
|
609
730
|
*/
|
|
610
|
-
parseAnalysisResult(e,
|
|
611
|
-
const
|
|
731
|
+
parseAnalysisResult(e, n, a) {
|
|
732
|
+
const t = {
|
|
612
733
|
type: e,
|
|
613
734
|
timestamp: /* @__PURE__ */ new Date(),
|
|
614
|
-
summary:
|
|
615
|
-
insights:
|
|
616
|
-
recommendations:
|
|
617
|
-
confidence:
|
|
618
|
-
processingTime:
|
|
735
|
+
summary: n.summary || "",
|
|
736
|
+
insights: n.insights || [],
|
|
737
|
+
recommendations: n.recommendations,
|
|
738
|
+
confidence: n.confidence || 0.8,
|
|
739
|
+
processingTime: a == null ? void 0 : a.processingTime
|
|
619
740
|
};
|
|
620
741
|
switch (e) {
|
|
621
742
|
case "descriptive_stats":
|
|
622
743
|
return {
|
|
623
|
-
...
|
|
624
|
-
descriptiveStats:
|
|
744
|
+
...t,
|
|
745
|
+
descriptiveStats: n.stats || n.descriptiveStats
|
|
625
746
|
};
|
|
626
747
|
case "anomaly_detection":
|
|
627
748
|
return {
|
|
628
|
-
...
|
|
629
|
-
anomalies:
|
|
749
|
+
...t,
|
|
750
|
+
anomalies: n.anomalies || []
|
|
630
751
|
};
|
|
631
752
|
case "segmentation":
|
|
632
753
|
case "clustering":
|
|
633
754
|
return {
|
|
634
|
-
...
|
|
635
|
-
clusters:
|
|
755
|
+
...t,
|
|
756
|
+
clusters: n.clusters || []
|
|
636
757
|
};
|
|
637
758
|
case "prediction":
|
|
638
759
|
return {
|
|
639
|
-
...
|
|
640
|
-
predictions:
|
|
760
|
+
...t,
|
|
761
|
+
predictions: n.predictions || n
|
|
641
762
|
};
|
|
642
763
|
case "correlation":
|
|
643
764
|
return {
|
|
644
|
-
...
|
|
645
|
-
correlations:
|
|
765
|
+
...t,
|
|
766
|
+
correlations: n.correlations || n
|
|
646
767
|
};
|
|
647
768
|
case "summary":
|
|
648
769
|
return {
|
|
649
|
-
...
|
|
650
|
-
aiSummary:
|
|
770
|
+
...t,
|
|
771
|
+
aiSummary: n.summary || n
|
|
651
772
|
};
|
|
652
773
|
case "qa":
|
|
653
774
|
return {
|
|
654
|
-
...
|
|
655
|
-
qaAnswer:
|
|
775
|
+
...t,
|
|
776
|
+
qaAnswer: n.answer || n
|
|
656
777
|
};
|
|
657
778
|
default:
|
|
658
|
-
return
|
|
779
|
+
return t;
|
|
659
780
|
}
|
|
660
781
|
}
|
|
661
782
|
/**
|
|
@@ -669,15 +790,15 @@ class me {
|
|
|
669
790
|
/**
|
|
670
791
|
* Generate AI summary of table data
|
|
671
792
|
*/
|
|
672
|
-
async generateSummary(e,
|
|
673
|
-
const
|
|
793
|
+
async generateSummary(e, n) {
|
|
794
|
+
const a = {
|
|
674
795
|
type: "summary",
|
|
675
796
|
data: e,
|
|
676
|
-
schema:
|
|
677
|
-
},
|
|
678
|
-
if (!
|
|
797
|
+
schema: n
|
|
798
|
+
}, t = await this.analyze(a);
|
|
799
|
+
if (!t.aiSummary)
|
|
679
800
|
throw new Error("Failed to generate summary");
|
|
680
|
-
return
|
|
801
|
+
return t.aiSummary;
|
|
681
802
|
}
|
|
682
803
|
/**
|
|
683
804
|
* Extract table from DOM
|
|
@@ -688,8 +809,8 @@ class me {
|
|
|
688
809
|
/**
|
|
689
810
|
* Normalize Vue data grid data
|
|
690
811
|
*/
|
|
691
|
-
normalizeVueData(e,
|
|
692
|
-
return ie(e,
|
|
812
|
+
normalizeVueData(e, n, a) {
|
|
813
|
+
return ie(e, n, a);
|
|
693
814
|
}
|
|
694
815
|
/**
|
|
695
816
|
* Update configuration
|
|
@@ -701,8 +822,8 @@ class me {
|
|
|
701
822
|
* Get current configuration (without sensitive data)
|
|
702
823
|
*/
|
|
703
824
|
getConfig() {
|
|
704
|
-
const { apiKey: e, ...
|
|
705
|
-
return
|
|
825
|
+
const { apiKey: e, ...n } = this.config;
|
|
826
|
+
return n;
|
|
706
827
|
}
|
|
707
828
|
// ============================================================================
|
|
708
829
|
// API Integration Methods
|
|
@@ -729,20 +850,20 @@ class me {
|
|
|
729
850
|
/**
|
|
730
851
|
* Execute API request and get data
|
|
731
852
|
*/
|
|
732
|
-
async fetchDataFromAPI(e,
|
|
853
|
+
async fetchDataFromAPI(e, n) {
|
|
733
854
|
if (!this.parsedCollection)
|
|
734
855
|
throw new Error("No Postman collection loaded. Call loadPostmanCollection() first.");
|
|
735
|
-
const
|
|
736
|
-
if (!
|
|
856
|
+
const a = this.parsedCollection.endpoints.find((i) => i.name === e);
|
|
857
|
+
if (!a)
|
|
737
858
|
throw new Error(`Endpoint "${e}" not found in collection.`);
|
|
738
|
-
const
|
|
859
|
+
const t = {
|
|
739
860
|
...this.parsedCollection.variables,
|
|
740
|
-
...
|
|
741
|
-
}, r = await
|
|
861
|
+
...n
|
|
862
|
+
}, r = await W({ endpoint: a, variables: t });
|
|
742
863
|
if (!r.success)
|
|
743
864
|
throw new Error(`API request failed: ${r.error}`);
|
|
744
|
-
const o = de(r),
|
|
745
|
-
return { data: o, schema:
|
|
865
|
+
const o = de(r), s = N(o);
|
|
866
|
+
return { data: o, schema: s };
|
|
746
867
|
}
|
|
747
868
|
/**
|
|
748
869
|
* Query API data with natural language
|
|
@@ -750,19 +871,19 @@ class me {
|
|
|
750
871
|
async queryAPI(e) {
|
|
751
872
|
if (!this.qaEngine)
|
|
752
873
|
throw new Error("Q&A engine not initialized. Provide qaConfig in constructor or call initializeQA().");
|
|
753
|
-
const
|
|
874
|
+
const n = Date.now(), { data: a, schema: t } = await this.fetchDataFromAPI(
|
|
754
875
|
e.dataSource.endpoint || "",
|
|
755
876
|
e.variables
|
|
756
877
|
), r = {
|
|
757
878
|
question: e.question,
|
|
758
|
-
schema:
|
|
759
|
-
data:
|
|
760
|
-
}, o = await this.qaEngine.answerQuestion(r),
|
|
879
|
+
schema: t,
|
|
880
|
+
data: a
|
|
881
|
+
}, o = await this.qaEngine.answerQuestion(r), s = Date.now() - n;
|
|
761
882
|
return {
|
|
762
883
|
answer: o.answer,
|
|
763
|
-
apiResponse:
|
|
884
|
+
apiResponse: a,
|
|
764
885
|
endpoint: e.dataSource.endpoint,
|
|
765
|
-
executionTime:
|
|
886
|
+
executionTime: s
|
|
766
887
|
};
|
|
767
888
|
}
|
|
768
889
|
/**
|
|
@@ -776,91 +897,91 @@ class me {
|
|
|
776
897
|
})) : [];
|
|
777
898
|
}
|
|
778
899
|
}
|
|
779
|
-
function
|
|
780
|
-
const e = new
|
|
781
|
-
async function d(u,
|
|
782
|
-
|
|
900
|
+
function Ye(l) {
|
|
901
|
+
const e = new he(l.config, l.qaConfig), n = q(!1), a = q(null), t = q(null), r = l.data || q([]), o = l.schema || q(null), s = q([]), i = q([]), c = q(null), f = l.maxQuestionHistory || 50, m = l.useLocalFallback !== !1;
|
|
902
|
+
async function d(u, h) {
|
|
903
|
+
n.value = !0, a.value = null;
|
|
783
904
|
try {
|
|
784
|
-
if (l.config.provider === "local" ||
|
|
905
|
+
if (l.config.provider === "local" || m) {
|
|
785
906
|
console.log("🔧 Using local analysis (no API call)");
|
|
786
|
-
const
|
|
787
|
-
return
|
|
907
|
+
const A = w(u, h);
|
|
908
|
+
return t.value = A, A;
|
|
788
909
|
}
|
|
789
|
-
const
|
|
910
|
+
const I = {
|
|
790
911
|
type: u,
|
|
791
912
|
data: r.value,
|
|
792
913
|
schema: o.value || void 0,
|
|
793
|
-
options:
|
|
794
|
-
},
|
|
795
|
-
return
|
|
796
|
-
} catch (
|
|
797
|
-
if (
|
|
798
|
-
return console.log("⚠️ API call failed, falling back to local analysis"),
|
|
799
|
-
throw
|
|
914
|
+
options: h
|
|
915
|
+
}, k = await e.analyze(I);
|
|
916
|
+
return t.value = k, k;
|
|
917
|
+
} catch (I) {
|
|
918
|
+
if (a.value = I instanceof Error ? I : new Error("Analysis failed"), m)
|
|
919
|
+
return console.log("⚠️ API call failed, falling back to local analysis"), w(u, h);
|
|
920
|
+
throw a.value;
|
|
800
921
|
} finally {
|
|
801
|
-
|
|
922
|
+
n.value = !1;
|
|
802
923
|
}
|
|
803
924
|
}
|
|
804
|
-
function
|
|
805
|
-
const
|
|
925
|
+
function w(u, h) {
|
|
926
|
+
const I = o.value || N(r.value);
|
|
806
927
|
switch (u) {
|
|
807
928
|
case "descriptive_stats": {
|
|
808
|
-
const
|
|
809
|
-
(
|
|
929
|
+
const k = I.columns.map(
|
|
930
|
+
(A) => B(r.value, A.name, A.type)
|
|
810
931
|
);
|
|
811
932
|
return {
|
|
812
933
|
type: u,
|
|
813
934
|
timestamp: /* @__PURE__ */ new Date(),
|
|
814
|
-
descriptiveStats:
|
|
815
|
-
summary: `Calculated statistics for ${
|
|
935
|
+
descriptiveStats: k,
|
|
936
|
+
summary: `Calculated statistics for ${k.length} columns`,
|
|
816
937
|
insights: [],
|
|
817
938
|
confidence: 0.9
|
|
818
939
|
};
|
|
819
940
|
}
|
|
820
941
|
case "anomaly_detection": {
|
|
821
|
-
const
|
|
942
|
+
const k = I.columns.filter((v) => v.type === "number").map((v) => v.name), A = re(
|
|
822
943
|
r.value,
|
|
823
|
-
|
|
824
|
-
|
|
944
|
+
k,
|
|
945
|
+
h == null ? void 0 : h.sensitivity
|
|
825
946
|
);
|
|
826
947
|
return {
|
|
827
948
|
type: u,
|
|
828
949
|
timestamp: /* @__PURE__ */ new Date(),
|
|
829
|
-
anomalies:
|
|
830
|
-
summary: `Found ${
|
|
831
|
-
insights:
|
|
950
|
+
anomalies: A,
|
|
951
|
+
summary: `Found ${A.length} anomalies`,
|
|
952
|
+
insights: A.slice(0, 3).map((v) => v.reasons[0]),
|
|
832
953
|
confidence: 0.8
|
|
833
954
|
};
|
|
834
955
|
}
|
|
835
956
|
case "clustering":
|
|
836
957
|
case "segmentation": {
|
|
837
|
-
const
|
|
958
|
+
const k = (h == null ? void 0 : h.features) || I.columns.filter((S) => S.type === "number").map((S) => S.name), A = (h == null ? void 0 : h.numClusters) || 3, v = Array.from({ length: A }, (S, R) => ({
|
|
838
959
|
id: R,
|
|
839
960
|
label: `Cluster ${R + 1}`,
|
|
840
961
|
centroid: {},
|
|
841
|
-
size: Math.floor(r.value.length /
|
|
962
|
+
size: Math.floor(r.value.length / A),
|
|
842
963
|
characteristics: [`Group ${R + 1} characteristics`]
|
|
843
964
|
}));
|
|
844
965
|
return {
|
|
845
966
|
type: u,
|
|
846
967
|
timestamp: /* @__PURE__ */ new Date(),
|
|
847
968
|
clusters: v,
|
|
848
|
-
summary: `Created ${
|
|
849
|
-
insights: [`Data segmented into ${
|
|
969
|
+
summary: `Created ${A} clusters based on ${k.length} features`,
|
|
970
|
+
insights: [`Data segmented into ${A} distinct groups`],
|
|
850
971
|
confidence: 0.75
|
|
851
972
|
};
|
|
852
973
|
}
|
|
853
974
|
case "correlation": {
|
|
854
|
-
const
|
|
855
|
-
return
|
|
856
|
-
|
|
857
|
-
|
|
975
|
+
const k = (h == null ? void 0 : h.features) || I.columns.filter((v) => v.type === "number").map((v) => v.name), A = {};
|
|
976
|
+
return k.forEach((v) => {
|
|
977
|
+
A[v] = {}, k.forEach((S) => {
|
|
978
|
+
A[v][S] = v === S ? 1 : Math.random() * 0.8 - 0.4;
|
|
858
979
|
});
|
|
859
980
|
}), {
|
|
860
981
|
type: u,
|
|
861
982
|
timestamp: /* @__PURE__ */ new Date(),
|
|
862
|
-
correlations:
|
|
863
|
-
summary: `Calculated correlations for ${
|
|
983
|
+
correlations: A,
|
|
984
|
+
summary: `Calculated correlations for ${k.length} features`,
|
|
864
985
|
insights: ["Correlation matrix computed for numeric columns"],
|
|
865
986
|
confidence: 0.85
|
|
866
987
|
};
|
|
@@ -869,113 +990,113 @@ function We(l) {
|
|
|
869
990
|
throw new Error(`Local analysis not supported for type: ${u}`);
|
|
870
991
|
}
|
|
871
992
|
}
|
|
872
|
-
async function
|
|
993
|
+
async function b() {
|
|
873
994
|
return (await d("descriptive_stats")).descriptiveStats || [];
|
|
874
995
|
}
|
|
875
|
-
async function
|
|
876
|
-
return (await d("anomaly_detection", { sensitivity:
|
|
996
|
+
async function P(u, h) {
|
|
997
|
+
return (await d("anomaly_detection", { sensitivity: h, features: u })).anomalies || [];
|
|
877
998
|
}
|
|
878
|
-
async function
|
|
879
|
-
return d("clustering", { features: u, numClusters:
|
|
999
|
+
async function $(u, h = 3) {
|
|
1000
|
+
return d("clustering", { features: u, numClusters: h });
|
|
880
1001
|
}
|
|
881
|
-
async function
|
|
882
|
-
return d("prediction", { targetColumn: u, ...
|
|
1002
|
+
async function D(u, h) {
|
|
1003
|
+
return d("prediction", { targetColumn: u, ...h });
|
|
883
1004
|
}
|
|
884
|
-
function
|
|
1005
|
+
function x(u) {
|
|
885
1006
|
e.updateConfig(u);
|
|
886
1007
|
}
|
|
887
|
-
function
|
|
888
|
-
r.value = u,
|
|
1008
|
+
function z(u, h = !0) {
|
|
1009
|
+
r.value = u, h && (o.value = N(u));
|
|
889
1010
|
}
|
|
890
|
-
function
|
|
891
|
-
|
|
1011
|
+
function E() {
|
|
1012
|
+
n.value = !1, a.value = null, t.value = null, s.value = [], i.value = [], c.value = null;
|
|
892
1013
|
}
|
|
893
|
-
async function
|
|
894
|
-
|
|
1014
|
+
async function Q(u, h) {
|
|
1015
|
+
n.value = !0, a.value = null;
|
|
895
1016
|
try {
|
|
896
1017
|
if (!r.value || !Array.isArray(r.value) || r.value.length === 0)
|
|
897
1018
|
throw new Error("No data available. Please load data first.");
|
|
898
|
-
const
|
|
1019
|
+
const I = o.value || N(r.value), k = {
|
|
899
1020
|
question: u,
|
|
900
|
-
schema:
|
|
1021
|
+
schema: I,
|
|
901
1022
|
data: r.value,
|
|
902
1023
|
sampleSize: 100,
|
|
903
1024
|
includeAggregates: !0,
|
|
904
|
-
...
|
|
905
|
-
}, v = (await e.askQuestion(
|
|
1025
|
+
...h
|
|
1026
|
+
}, v = (await e.askQuestion(k)).answer, S = {
|
|
906
1027
|
id: v.questionId,
|
|
907
1028
|
text: u,
|
|
908
1029
|
timestamp: /* @__PURE__ */ new Date(),
|
|
909
1030
|
context: {
|
|
910
|
-
tableSchema:
|
|
1031
|
+
tableSchema: I,
|
|
911
1032
|
rowCount: r.value.length
|
|
912
1033
|
}
|
|
913
1034
|
};
|
|
914
|
-
return
|
|
915
|
-
} catch (
|
|
916
|
-
throw
|
|
1035
|
+
return s.value || (s.value = []), i.value || (i.value = []), s.value.push(S), i.value.push(v), c.value = v, s.value.length > f && (s.value.shift(), i.value.shift()), v;
|
|
1036
|
+
} catch (I) {
|
|
1037
|
+
throw a.value = I instanceof Error ? I : new Error("Q&A failed"), a.value;
|
|
917
1038
|
} finally {
|
|
918
|
-
|
|
1039
|
+
n.value = !1;
|
|
919
1040
|
}
|
|
920
1041
|
}
|
|
921
1042
|
async function M() {
|
|
922
|
-
|
|
1043
|
+
n.value = !0, a.value = null;
|
|
923
1044
|
try {
|
|
924
1045
|
const u = o.value || N(r.value);
|
|
925
1046
|
return await e.generateSummary(r.value, u);
|
|
926
1047
|
} catch (u) {
|
|
927
|
-
throw
|
|
1048
|
+
throw a.value = u instanceof Error ? u : new Error("Summary generation failed"), a.value;
|
|
928
1049
|
} finally {
|
|
929
|
-
|
|
1050
|
+
n.value = !1;
|
|
930
1051
|
}
|
|
931
1052
|
}
|
|
932
|
-
function
|
|
933
|
-
|
|
1053
|
+
function G() {
|
|
1054
|
+
s.value = [], i.value = [], c.value = null;
|
|
934
1055
|
}
|
|
935
|
-
function
|
|
936
|
-
const
|
|
937
|
-
return
|
|
1056
|
+
function Y(u) {
|
|
1057
|
+
const h = e.extractFromDOM(u);
|
|
1058
|
+
return h && (r.value = h.data, o.value = h.schema), h;
|
|
938
1059
|
}
|
|
939
|
-
function X(u,
|
|
940
|
-
const
|
|
941
|
-
r.value =
|
|
1060
|
+
function X(u, h, I) {
|
|
1061
|
+
const k = e.normalizeVueData(u, h, I);
|
|
1062
|
+
r.value = k.data, o.value = k.schema;
|
|
942
1063
|
}
|
|
943
1064
|
function Z(u) {
|
|
944
1065
|
e.initializeQA(u);
|
|
945
1066
|
}
|
|
946
1067
|
return {
|
|
947
1068
|
client: e,
|
|
948
|
-
loading:
|
|
949
|
-
error:
|
|
950
|
-
lastResult:
|
|
1069
|
+
loading: n,
|
|
1070
|
+
error: a,
|
|
1071
|
+
lastResult: t,
|
|
951
1072
|
data: r,
|
|
952
1073
|
schema: o,
|
|
953
|
-
questionHistory:
|
|
1074
|
+
questionHistory: s,
|
|
954
1075
|
answerHistory: i,
|
|
955
1076
|
lastAnswer: c,
|
|
956
1077
|
analyze: d,
|
|
957
|
-
getDescriptiveStats:
|
|
958
|
-
detectAnomalies:
|
|
959
|
-
performClustering:
|
|
960
|
-
predict:
|
|
961
|
-
askQuestion:
|
|
1078
|
+
getDescriptiveStats: b,
|
|
1079
|
+
detectAnomalies: P,
|
|
1080
|
+
performClustering: $,
|
|
1081
|
+
predict: D,
|
|
1082
|
+
askQuestion: Q,
|
|
962
1083
|
generateSummary: M,
|
|
963
|
-
clearHistory:
|
|
964
|
-
extractFromDOM:
|
|
1084
|
+
clearHistory: G,
|
|
1085
|
+
extractFromDOM: Y,
|
|
965
1086
|
loadFromVueGrid: X,
|
|
966
|
-
updateConfig:
|
|
1087
|
+
updateConfig: x,
|
|
967
1088
|
initializeQA: Z,
|
|
968
|
-
setData:
|
|
969
|
-
reset:
|
|
1089
|
+
setData: z,
|
|
1090
|
+
reset: E
|
|
970
1091
|
};
|
|
971
1092
|
}
|
|
972
|
-
const
|
|
1093
|
+
const me = { class: "ti-question-input" }, fe = { class: "ti-input-wrapper" }, pe = ["placeholder", "disabled", "onKeydown"], ye = ["disabled"], ge = { key: 0 }, we = {
|
|
973
1094
|
key: 1,
|
|
974
1095
|
class: "ti-loading"
|
|
975
1096
|
}, ve = {
|
|
976
1097
|
key: 0,
|
|
977
1098
|
class: "ti-hint"
|
|
978
|
-
},
|
|
1099
|
+
}, Ae = /* @__PURE__ */ j({
|
|
979
1100
|
__name: "QuestionInput",
|
|
980
1101
|
props: {
|
|
981
1102
|
placeholder: { default: "Ask a question about this data..." },
|
|
@@ -988,166 +1109,166 @@ const he = { class: "ti-question-input" }, fe = { class: "ti-input-wrapper" }, p
|
|
|
988
1109
|
},
|
|
989
1110
|
emits: ["submit"],
|
|
990
1111
|
setup(l, { emit: e }) {
|
|
991
|
-
const
|
|
1112
|
+
const n = l, a = e, t = q("");
|
|
992
1113
|
function r() {
|
|
993
|
-
|
|
1114
|
+
t.value.trim() && !n.disabled && !n.loading && (a("submit", t.value.trim()), t.value = "");
|
|
994
1115
|
}
|
|
995
|
-
function o(
|
|
1116
|
+
function o(s) {
|
|
996
1117
|
}
|
|
997
|
-
return (
|
|
998
|
-
|
|
999
|
-
ee(
|
|
1000
|
-
"onUpdate:modelValue": i[0] || (i[0] = (c) =>
|
|
1001
|
-
placeholder:
|
|
1002
|
-
disabled:
|
|
1118
|
+
return (s, i) => (g(), y("div", me, [
|
|
1119
|
+
p("div", fe, [
|
|
1120
|
+
ee(p("textarea", {
|
|
1121
|
+
"onUpdate:modelValue": i[0] || (i[0] = (c) => t.value = c),
|
|
1122
|
+
placeholder: s.placeholder,
|
|
1123
|
+
disabled: s.disabled,
|
|
1003
1124
|
class: "ti-textarea",
|
|
1004
1125
|
rows: "1",
|
|
1005
1126
|
onKeydown: [
|
|
1006
|
-
|
|
1007
|
-
|
|
1127
|
+
H(J(r, ["exact", "prevent"]), ["enter"]),
|
|
1128
|
+
H(J(o, ["shift"]), ["enter"])
|
|
1008
1129
|
]
|
|
1009
1130
|
}, null, 40, pe), [
|
|
1010
|
-
[te,
|
|
1131
|
+
[te, t.value]
|
|
1011
1132
|
]),
|
|
1012
|
-
|
|
1013
|
-
disabled:
|
|
1133
|
+
p("button", {
|
|
1134
|
+
disabled: s.disabled || !t.value.trim(),
|
|
1014
1135
|
class: "ti-submit-btn",
|
|
1015
1136
|
onClick: r
|
|
1016
1137
|
}, [
|
|
1017
|
-
|
|
1018
|
-
], 8,
|
|
1138
|
+
s.loading ? (g(), y("span", we, C(s.loadingLabel), 1)) : (g(), y("span", ge, C(s.submitLabel), 1))
|
|
1139
|
+
], 8, ye)
|
|
1019
1140
|
]),
|
|
1020
|
-
|
|
1141
|
+
s.showHint ? (g(), y("div", ve, C(s.hint), 1)) : _("", !0)
|
|
1021
1142
|
]));
|
|
1022
1143
|
}
|
|
1023
1144
|
}), V = (l, e) => {
|
|
1024
|
-
const
|
|
1025
|
-
for (const [
|
|
1026
|
-
|
|
1027
|
-
return
|
|
1028
|
-
}, Xe = /* @__PURE__ */ V(
|
|
1145
|
+
const n = l.__vccOpts || l;
|
|
1146
|
+
for (const [a, t] of e)
|
|
1147
|
+
n[a] = t;
|
|
1148
|
+
return n;
|
|
1149
|
+
}, Xe = /* @__PURE__ */ V(Ae, [["__scopeId", "data-v-f96008f3"]]), be = { class: "ti-answer-header" }, Ie = { class: "ti-answer-icon" }, ke = { key: 0 }, Ce = { key: 1 }, Pe = { class: "ti-answer-meta" }, $e = { class: "ti-confidence" }, xe = { class: "ti-timestamp" }, qe = { class: "ti-answer-text" }, Se = {
|
|
1029
1150
|
key: 0,
|
|
1030
1151
|
class: "ti-approximate-notice"
|
|
1031
|
-
},
|
|
1152
|
+
}, _e = {
|
|
1032
1153
|
key: 1,
|
|
1033
1154
|
class: "ti-reason"
|
|
1034
|
-
},
|
|
1155
|
+
}, De = {
|
|
1035
1156
|
key: 2,
|
|
1036
1157
|
class: "ti-supporting-data"
|
|
1037
|
-
},
|
|
1158
|
+
}, Ee = {
|
|
1038
1159
|
key: 0,
|
|
1039
1160
|
class: "ti-supporting-content"
|
|
1040
|
-
},
|
|
1161
|
+
}, Te = {
|
|
1041
1162
|
key: 0,
|
|
1042
1163
|
class: "ti-aggregates"
|
|
1043
1164
|
}, Ne = {
|
|
1044
1165
|
key: 1,
|
|
1045
1166
|
class: "ti-rows"
|
|
1046
|
-
}, Me = { class: "ti-table-wrapper" },
|
|
1167
|
+
}, Me = { class: "ti-table-wrapper" }, Qe = { class: "ti-table" }, Fe = /* @__PURE__ */ j({
|
|
1047
1168
|
__name: "AnswerDisplay",
|
|
1048
1169
|
props: {
|
|
1049
1170
|
answer: {}
|
|
1050
1171
|
},
|
|
1051
1172
|
setup(l) {
|
|
1052
|
-
const e =
|
|
1053
|
-
function
|
|
1054
|
-
return new Date(
|
|
1173
|
+
const e = q(!1);
|
|
1174
|
+
function n(a) {
|
|
1175
|
+
return new Date(a).toLocaleTimeString();
|
|
1055
1176
|
}
|
|
1056
|
-
return (
|
|
1057
|
-
class: ne(["ti-answer-display", { "ti-cannot-answer":
|
|
1177
|
+
return (a, t) => (g(), y("div", {
|
|
1178
|
+
class: ne(["ti-answer-display", { "ti-cannot-answer": a.answer.cannotAnswer }])
|
|
1058
1179
|
}, [
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1180
|
+
p("div", be, [
|
|
1181
|
+
p("div", Ie, [
|
|
1182
|
+
a.answer.cannotAnswer ? (g(), y("span", Ce, "⚠️")) : (g(), y("span", ke, "💡"))
|
|
1062
1183
|
]),
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1184
|
+
p("div", Pe, [
|
|
1185
|
+
p("div", $e, " Confidence: " + C(Math.round(a.answer.confidence * 100)) + "% ", 1),
|
|
1186
|
+
p("div", xe, C(n(a.answer.timestamp)), 1)
|
|
1066
1187
|
])
|
|
1067
1188
|
]),
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
])) :
|
|
1074
|
-
|
|
1075
|
-
|
|
1189
|
+
p("div", qe, C(a.answer.text), 1),
|
|
1190
|
+
a.answer.isApproximate ? (g(), y("div", Se, " ℹ️ This answer is based on sampled data and may be approximate. ")) : _("", !0),
|
|
1191
|
+
a.answer.reason && a.answer.cannotAnswer ? (g(), y("div", _e, [
|
|
1192
|
+
t[1] || (t[1] = p("strong", null, "Reason:", -1)),
|
|
1193
|
+
ae(" " + C(a.answer.reason), 1)
|
|
1194
|
+
])) : _("", !0),
|
|
1195
|
+
a.answer.supportingData ? (g(), y("div", De, [
|
|
1196
|
+
p("button", {
|
|
1076
1197
|
class: "ti-toggle-btn",
|
|
1077
|
-
onClick:
|
|
1078
|
-
},
|
|
1079
|
-
e.value ? (g(),
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
])) :
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
(g(!0),
|
|
1198
|
+
onClick: t[0] || (t[0] = (r) => e.value = !e.value)
|
|
1199
|
+
}, C(e.value ? "▼" : "▶") + " Supporting Data ", 1),
|
|
1200
|
+
e.value ? (g(), y("div", Ee, [
|
|
1201
|
+
a.answer.supportingData.aggregates ? (g(), y("div", Te, [
|
|
1202
|
+
t[2] || (t[2] = p("h4", null, "Aggregates:", -1)),
|
|
1203
|
+
p("pre", null, C(JSON.stringify(a.answer.supportingData.aggregates, null, 2)), 1)
|
|
1204
|
+
])) : _("", !0),
|
|
1205
|
+
a.answer.supportingData.rows && a.answer.supportingData.rows.length > 0 ? (g(), y("div", Ne, [
|
|
1206
|
+
p("h4", null, "Sample Rows (" + C(a.answer.supportingData.rows.length) + "):", 1),
|
|
1207
|
+
p("div", Me, [
|
|
1208
|
+
p("table", Qe, [
|
|
1209
|
+
p("thead", null, [
|
|
1210
|
+
p("tr", null, [
|
|
1211
|
+
(g(!0), y(F, null, O(Object.keys(a.answer.supportingData.rows[0]), (r, o) => (g(), y("th", { key: o }, C(r), 1))), 128))
|
|
1091
1212
|
])
|
|
1092
1213
|
]),
|
|
1093
|
-
|
|
1094
|
-
(g(!0),
|
|
1095
|
-
(g(!0),
|
|
1214
|
+
p("tbody", null, [
|
|
1215
|
+
(g(!0), y(F, null, O(a.answer.supportingData.rows.slice(0, 5), (r, o) => (g(), y("tr", { key: o }, [
|
|
1216
|
+
(g(!0), y(F, null, O(Object.keys(r), (s, i) => (g(), y("td", { key: i }, C(r[s]), 1))), 128))
|
|
1096
1217
|
]))), 128))
|
|
1097
1218
|
])
|
|
1098
1219
|
])
|
|
1099
1220
|
])
|
|
1100
|
-
])) :
|
|
1101
|
-
])) :
|
|
1102
|
-
])) :
|
|
1221
|
+
])) : _("", !0)
|
|
1222
|
+
])) : _("", !0)
|
|
1223
|
+
])) : _("", !0)
|
|
1103
1224
|
], 2));
|
|
1104
1225
|
}
|
|
1105
|
-
}), Ze = /* @__PURE__ */ V(
|
|
1226
|
+
}), Ze = /* @__PURE__ */ V(Fe, [["__scopeId", "data-v-d1aaae1d"]]), Oe = { class: "ti-question-history" }, ze = { class: "ti-history-header" }, Re = {
|
|
1106
1227
|
key: 0,
|
|
1107
1228
|
class: "ti-empty-state"
|
|
1108
|
-
},
|
|
1229
|
+
}, je = {
|
|
1109
1230
|
key: 1,
|
|
1110
1231
|
class: "ti-history-list"
|
|
1111
|
-
}, Ve = ["onClick"],
|
|
1232
|
+
}, Ve = ["onClick"], He = { class: "ti-question-header" }, Je = { class: "ti-question-number" }, Ue = { class: "ti-question-time" }, Le = { class: "ti-question-text" }, Be = {
|
|
1112
1233
|
key: 0,
|
|
1113
1234
|
class: "ti-question-context"
|
|
1114
|
-
}, Ke = /* @__PURE__ */
|
|
1235
|
+
}, Ke = /* @__PURE__ */ j({
|
|
1115
1236
|
__name: "QuestionHistory",
|
|
1116
1237
|
props: {
|
|
1117
1238
|
questions: {}
|
|
1118
1239
|
},
|
|
1119
1240
|
emits: ["clear", "select"],
|
|
1120
1241
|
setup(l, { emit: e }) {
|
|
1121
|
-
const
|
|
1122
|
-
function
|
|
1123
|
-
const o = new Date(r), i = (/* @__PURE__ */ new Date()).getTime() - o.getTime(), c = Math.floor(i / 6e4),
|
|
1124
|
-
return c < 1 ? "Just now" : c < 60 ? `${c}m ago` :
|
|
1242
|
+
const n = l, a = se(() => [...n.questions].reverse());
|
|
1243
|
+
function t(r) {
|
|
1244
|
+
const o = new Date(r), i = (/* @__PURE__ */ new Date()).getTime() - o.getTime(), c = Math.floor(i / 6e4), f = Math.floor(i / 36e5), m = Math.floor(i / 864e5);
|
|
1245
|
+
return c < 1 ? "Just now" : c < 60 ? `${c}m ago` : f < 24 ? `${f}h ago` : `${m}d ago`;
|
|
1125
1246
|
}
|
|
1126
|
-
return (r, o) => (g(),
|
|
1127
|
-
|
|
1128
|
-
o[1] || (o[1] =
|
|
1129
|
-
r.questions.length > 0 ? (g(),
|
|
1247
|
+
return (r, o) => (g(), y("div", Oe, [
|
|
1248
|
+
p("div", ze, [
|
|
1249
|
+
o[1] || (o[1] = p("h3", null, "Question History", -1)),
|
|
1250
|
+
r.questions.length > 0 ? (g(), y("button", {
|
|
1130
1251
|
key: 0,
|
|
1131
1252
|
class: "ti-clear-btn",
|
|
1132
|
-
onClick: o[0] || (o[0] = (
|
|
1133
|
-
}, " Clear History ")) :
|
|
1253
|
+
onClick: o[0] || (o[0] = (s) => r.$emit("clear"))
|
|
1254
|
+
}, " Clear History ")) : _("", !0)
|
|
1134
1255
|
]),
|
|
1135
|
-
r.questions.length === 0 ? (g(),
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
]))) : (g(),
|
|
1140
|
-
(g(!0),
|
|
1141
|
-
key:
|
|
1256
|
+
r.questions.length === 0 ? (g(), y("div", Re, o[2] || (o[2] = [
|
|
1257
|
+
p("div", { class: "ti-empty-icon" }, "💬", -1),
|
|
1258
|
+
p("p", null, "No questions asked yet", -1),
|
|
1259
|
+
p("p", { class: "ti-empty-hint" }, "Ask a question about your data to get started", -1)
|
|
1260
|
+
]))) : (g(), y("div", je, [
|
|
1261
|
+
(g(!0), y(F, null, O(a.value, (s, i) => (g(), y("div", {
|
|
1262
|
+
key: s.id,
|
|
1142
1263
|
class: "ti-history-item",
|
|
1143
|
-
onClick: (c) => r.$emit("select",
|
|
1264
|
+
onClick: (c) => r.$emit("select", s)
|
|
1144
1265
|
}, [
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1266
|
+
p("div", He, [
|
|
1267
|
+
p("span", Je, "#" + C(r.questions.length - i), 1),
|
|
1268
|
+
p("span", Ue, C(t(s.timestamp)), 1)
|
|
1148
1269
|
]),
|
|
1149
|
-
|
|
1150
|
-
|
|
1270
|
+
p("div", Le, C(s.text), 1),
|
|
1271
|
+
s.context ? (g(), y("div", Be, C(s.context.rowCount) + " rows ", 1)) : _("", !0)
|
|
1151
1272
|
], 8, Ve))), 128))
|
|
1152
1273
|
]))
|
|
1153
1274
|
]));
|
|
@@ -1155,21 +1276,21 @@ const he = { class: "ti-question-input" }, fe = { class: "ti-input-wrapper" }, p
|
|
|
1155
1276
|
}), et = /* @__PURE__ */ V(Ke, [["__scopeId", "data-v-c66393d9"]]);
|
|
1156
1277
|
export {
|
|
1157
1278
|
Ze as AnswerDisplay,
|
|
1158
|
-
|
|
1279
|
+
U as QAEngine,
|
|
1159
1280
|
et as QuestionHistory,
|
|
1160
1281
|
Xe as QuestionInput,
|
|
1161
|
-
|
|
1162
|
-
|
|
1282
|
+
he as TabularIntelligence,
|
|
1283
|
+
B as calculateStats,
|
|
1163
1284
|
de as convertToTabular,
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1285
|
+
re as detectAnomalies,
|
|
1286
|
+
W as executeAPIRequest,
|
|
1287
|
+
Ge as executeMultipleRequests,
|
|
1167
1288
|
oe as extractFromDOM,
|
|
1168
|
-
|
|
1289
|
+
L as inferColumnType,
|
|
1169
1290
|
N as inferSchema,
|
|
1170
1291
|
ie as normalizeVueData,
|
|
1171
1292
|
ce as parsePostmanCollection,
|
|
1172
|
-
|
|
1173
|
-
|
|
1293
|
+
T as replaceVariables,
|
|
1294
|
+
Ye as useTabularIntelligence
|
|
1174
1295
|
};
|
|
1175
1296
|
//# sourceMappingURL=index.mjs.map
|