@informedai/react 0.4.27 → 0.4.29
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.d.mts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +212 -1
- package/dist/index.mjs +212 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -31,6 +31,7 @@ interface WidgetMessage {
|
|
|
31
31
|
runId: string;
|
|
32
32
|
query: string;
|
|
33
33
|
status: string;
|
|
34
|
+
queryType?: string;
|
|
34
35
|
};
|
|
35
36
|
triages?: string[];
|
|
36
37
|
};
|
|
@@ -136,6 +137,8 @@ interface InformedAssistantConfig {
|
|
|
136
137
|
* Return the current values of all fields as they appear in your UI.
|
|
137
138
|
*/
|
|
138
139
|
getCurrentFieldValues?: () => Record<string, unknown>;
|
|
140
|
+
/** Callback when an analytics run badge is clicked. If not provided, an inline panel is shown. */
|
|
141
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
139
142
|
/** Custom theme overrides */
|
|
140
143
|
theme?: Partial<WidgetTheme>;
|
|
141
144
|
/** Position of the widget (for floating mode) */
|
|
@@ -160,6 +163,24 @@ interface WidgetTheme {
|
|
|
160
163
|
/** Font family */
|
|
161
164
|
fontFamily: string;
|
|
162
165
|
}
|
|
166
|
+
interface SqlBreakdown {
|
|
167
|
+
baseDataset: string;
|
|
168
|
+
metrics: string[];
|
|
169
|
+
filters: string[];
|
|
170
|
+
grouping: string[];
|
|
171
|
+
sorting: string | null;
|
|
172
|
+
timeRange: string | null;
|
|
173
|
+
}
|
|
174
|
+
interface AnalyticsRunDetail {
|
|
175
|
+
id: string;
|
|
176
|
+
query: string;
|
|
177
|
+
status: string;
|
|
178
|
+
generatedSql: string | null;
|
|
179
|
+
structuredBreakdown: SqlBreakdown | null;
|
|
180
|
+
result: unknown[] | null;
|
|
181
|
+
createdAt: string;
|
|
182
|
+
parentRunId: string | null;
|
|
183
|
+
}
|
|
163
184
|
interface SSEEvent {
|
|
164
185
|
type: 'content' | 'done' | 'error' | 'session_update';
|
|
165
186
|
content?: string;
|
|
@@ -353,6 +374,8 @@ interface InformedAIContextValue {
|
|
|
353
374
|
startNewSession: () => Promise<void>;
|
|
354
375
|
endSession: () => Promise<void>;
|
|
355
376
|
clearError: () => void;
|
|
377
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
378
|
+
getAnalyticsRun: (sessionId: string, runId: string) => Promise<AnalyticsRunDetail>;
|
|
356
379
|
}
|
|
357
380
|
declare function useInformedAI(): InformedAIContextValue;
|
|
358
381
|
interface InformedAIProviderProps {
|
|
@@ -471,7 +494,11 @@ declare class InformedAIClient {
|
|
|
471
494
|
* Returns true if sendBeacon was used, false if fetch fallback was attempted.
|
|
472
495
|
*/
|
|
473
496
|
endSessionBeacon(sessionId: string): boolean;
|
|
497
|
+
/**
|
|
498
|
+
* Get details of a specific analytics run.
|
|
499
|
+
*/
|
|
500
|
+
getAnalyticsRun(sessionId: string, runId: string): Promise<AnalyticsRunDetail>;
|
|
474
501
|
private processSSEStream;
|
|
475
502
|
}
|
|
476
503
|
|
|
477
|
-
export { AdminChatbot, type AdminChatbotConfig, type AdminChatbotTheme, type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type QuickActionGroup, type SSEEvent, type Session, SmartQuestionnaire, type SmartQuestionnaireConfig, type SmartQuestionnaireTheme, type TaskConfig, type TaskState, type UseSessionReturn, WebsiteChatbot, type WebsiteChatbotConfig, type WebsiteChatbotTheme, type WidgetMessage, type WidgetReadyContext, type WidgetTheme, useInformedAI, useSession };
|
|
504
|
+
export { AdminChatbot, type AdminChatbotConfig, type AdminChatbotTheme, type AnalyticsRunDetail, type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type QuickActionGroup, type SSEEvent, type Session, SmartQuestionnaire, type SmartQuestionnaireConfig, type SmartQuestionnaireTheme, type SqlBreakdown, type TaskConfig, type TaskState, type UseSessionReturn, WebsiteChatbot, type WebsiteChatbotConfig, type WebsiteChatbotTheme, type WidgetMessage, type WidgetReadyContext, type WidgetTheme, useInformedAI, useSession };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ interface WidgetMessage {
|
|
|
31
31
|
runId: string;
|
|
32
32
|
query: string;
|
|
33
33
|
status: string;
|
|
34
|
+
queryType?: string;
|
|
34
35
|
};
|
|
35
36
|
triages?: string[];
|
|
36
37
|
};
|
|
@@ -136,6 +137,8 @@ interface InformedAssistantConfig {
|
|
|
136
137
|
* Return the current values of all fields as they appear in your UI.
|
|
137
138
|
*/
|
|
138
139
|
getCurrentFieldValues?: () => Record<string, unknown>;
|
|
140
|
+
/** Callback when an analytics run badge is clicked. If not provided, an inline panel is shown. */
|
|
141
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
139
142
|
/** Custom theme overrides */
|
|
140
143
|
theme?: Partial<WidgetTheme>;
|
|
141
144
|
/** Position of the widget (for floating mode) */
|
|
@@ -160,6 +163,24 @@ interface WidgetTheme {
|
|
|
160
163
|
/** Font family */
|
|
161
164
|
fontFamily: string;
|
|
162
165
|
}
|
|
166
|
+
interface SqlBreakdown {
|
|
167
|
+
baseDataset: string;
|
|
168
|
+
metrics: string[];
|
|
169
|
+
filters: string[];
|
|
170
|
+
grouping: string[];
|
|
171
|
+
sorting: string | null;
|
|
172
|
+
timeRange: string | null;
|
|
173
|
+
}
|
|
174
|
+
interface AnalyticsRunDetail {
|
|
175
|
+
id: string;
|
|
176
|
+
query: string;
|
|
177
|
+
status: string;
|
|
178
|
+
generatedSql: string | null;
|
|
179
|
+
structuredBreakdown: SqlBreakdown | null;
|
|
180
|
+
result: unknown[] | null;
|
|
181
|
+
createdAt: string;
|
|
182
|
+
parentRunId: string | null;
|
|
183
|
+
}
|
|
163
184
|
interface SSEEvent {
|
|
164
185
|
type: 'content' | 'done' | 'error' | 'session_update';
|
|
165
186
|
content?: string;
|
|
@@ -353,6 +374,8 @@ interface InformedAIContextValue {
|
|
|
353
374
|
startNewSession: () => Promise<void>;
|
|
354
375
|
endSession: () => Promise<void>;
|
|
355
376
|
clearError: () => void;
|
|
377
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
378
|
+
getAnalyticsRun: (sessionId: string, runId: string) => Promise<AnalyticsRunDetail>;
|
|
356
379
|
}
|
|
357
380
|
declare function useInformedAI(): InformedAIContextValue;
|
|
358
381
|
interface InformedAIProviderProps {
|
|
@@ -471,7 +494,11 @@ declare class InformedAIClient {
|
|
|
471
494
|
* Returns true if sendBeacon was used, false if fetch fallback was attempted.
|
|
472
495
|
*/
|
|
473
496
|
endSessionBeacon(sessionId: string): boolean;
|
|
497
|
+
/**
|
|
498
|
+
* Get details of a specific analytics run.
|
|
499
|
+
*/
|
|
500
|
+
getAnalyticsRun(sessionId: string, runId: string): Promise<AnalyticsRunDetail>;
|
|
474
501
|
private processSSEStream;
|
|
475
502
|
}
|
|
476
503
|
|
|
477
|
-
export { AdminChatbot, type AdminChatbotConfig, type AdminChatbotTheme, type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type QuickActionGroup, type SSEEvent, type Session, SmartQuestionnaire, type SmartQuestionnaireConfig, type SmartQuestionnaireTheme, type TaskConfig, type TaskState, type UseSessionReturn, WebsiteChatbot, type WebsiteChatbotConfig, type WebsiteChatbotTheme, type WidgetMessage, type WidgetReadyContext, type WidgetTheme, useInformedAI, useSession };
|
|
504
|
+
export { AdminChatbot, type AdminChatbotConfig, type AdminChatbotTheme, type AnalyticsRunDetail, type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type QuickActionGroup, type SSEEvent, type Session, SmartQuestionnaire, type SmartQuestionnaireConfig, type SmartQuestionnaireTheme, type SqlBreakdown, type TaskConfig, type TaskState, type UseSessionReturn, WebsiteChatbot, type WebsiteChatbotConfig, type WebsiteChatbotTheme, type WidgetMessage, type WidgetReadyContext, type WidgetTheme, useInformedAI, useSession };
|
package/dist/index.js
CHANGED
|
@@ -216,6 +216,15 @@ var InformedAIClient = class {
|
|
|
216
216
|
return false;
|
|
217
217
|
}
|
|
218
218
|
// ========================================================================
|
|
219
|
+
// Analytics
|
|
220
|
+
// ========================================================================
|
|
221
|
+
/**
|
|
222
|
+
* Get details of a specific analytics run.
|
|
223
|
+
*/
|
|
224
|
+
async getAnalyticsRun(sessionId, runId) {
|
|
225
|
+
return this.request(`/widget/sessions/${sessionId}/analytics-runs/${runId}`);
|
|
226
|
+
}
|
|
227
|
+
// ========================================================================
|
|
219
228
|
// SSE Stream Processing
|
|
220
229
|
// ========================================================================
|
|
221
230
|
async processSSEStream(response, onEvent) {
|
|
@@ -713,6 +722,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
713
722
|
const clearError = (0, import_react.useCallback)(() => {
|
|
714
723
|
setError(null);
|
|
715
724
|
}, []);
|
|
725
|
+
const getAnalyticsRun = (0, import_react.useCallback)(async (sessionId, runId) => {
|
|
726
|
+
if (!clientRef.current) throw new Error("Client not initialized");
|
|
727
|
+
return clientRef.current.getAnalyticsRun(sessionId, runId);
|
|
728
|
+
}, []);
|
|
716
729
|
const value = {
|
|
717
730
|
session,
|
|
718
731
|
document,
|
|
@@ -727,7 +740,9 @@ function InformedAIProvider({ config, children }) {
|
|
|
727
740
|
skipTask,
|
|
728
741
|
startNewSession,
|
|
729
742
|
endSession,
|
|
730
|
-
clearError
|
|
743
|
+
clearError,
|
|
744
|
+
onAnalyticsRunClick: config.onAnalyticsRunClick,
|
|
745
|
+
getAnalyticsRun
|
|
731
746
|
};
|
|
732
747
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InformedAIContext.Provider, { value, children });
|
|
733
748
|
}
|
|
@@ -1150,6 +1165,7 @@ function MessageBubble({ message, theme, onQuickAction, isLatest = false, quickA
|
|
|
1150
1165
|
const isUser = message.role === "user";
|
|
1151
1166
|
const hasQuickActions = isLatest && message.quickActions && message.quickActions.length > 0;
|
|
1152
1167
|
const hasKbSearch = message.kbSearch != null;
|
|
1168
|
+
const hasAnalyticsRun = message.agentContext?.analyticsRun != null;
|
|
1153
1169
|
if ((message.type === "quick_actions" || !message.content) && hasQuickActions) {
|
|
1154
1170
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1155
1171
|
GroupedQuickActions,
|
|
@@ -1188,6 +1204,15 @@ function MessageBubble({ message, theme, onQuickAction, isLatest = false, quickA
|
|
|
1188
1204
|
]
|
|
1189
1205
|
}
|
|
1190
1206
|
),
|
|
1207
|
+
hasAnalyticsRun && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1208
|
+
AnalyticsBadge,
|
|
1209
|
+
{
|
|
1210
|
+
runId: message.agentContext.analyticsRun.runId,
|
|
1211
|
+
query: message.agentContext.analyticsRun.query,
|
|
1212
|
+
status: message.agentContext.analyticsRun.status,
|
|
1213
|
+
queryType: message.agentContext.analyticsRun.queryType
|
|
1214
|
+
}
|
|
1215
|
+
),
|
|
1191
1216
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1192
1217
|
"div",
|
|
1193
1218
|
{
|
|
@@ -1323,6 +1348,185 @@ function GroupedQuickActions({ actions, groups, theme, onQuickAction }) {
|
|
|
1323
1348
|
] }, groupKey);
|
|
1324
1349
|
}) });
|
|
1325
1350
|
}
|
|
1351
|
+
function AnalyticsBadge({ runId, query, status, queryType }) {
|
|
1352
|
+
const { session, onAnalyticsRunClick, getAnalyticsRun } = useInformedAI();
|
|
1353
|
+
const [expanded, setExpanded] = (0, import_react2.useState)(false);
|
|
1354
|
+
const [runDetail, setRunDetail] = (0, import_react2.useState)(null);
|
|
1355
|
+
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
1356
|
+
const handleClick = () => {
|
|
1357
|
+
if (onAnalyticsRunClick && session) {
|
|
1358
|
+
onAnalyticsRunClick(runId, query, session.id);
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
setExpanded((prev) => !prev);
|
|
1362
|
+
};
|
|
1363
|
+
(0, import_react2.useEffect)(() => {
|
|
1364
|
+
if (expanded && !runDetail && !loading && session) {
|
|
1365
|
+
setLoading(true);
|
|
1366
|
+
getAnalyticsRun(session.id, runId).then(setRunDetail).catch((err) => console.warn("Failed to load analytics run:", err)).finally(() => setLoading(false));
|
|
1367
|
+
}
|
|
1368
|
+
}, [expanded, runDetail, loading, session, runId, getAnalyticsRun]);
|
|
1369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "4px" }, children: [
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1371
|
+
"button",
|
|
1372
|
+
{
|
|
1373
|
+
onClick: handleClick,
|
|
1374
|
+
style: {
|
|
1375
|
+
display: "inline-flex",
|
|
1376
|
+
alignItems: "center",
|
|
1377
|
+
gap: "6px",
|
|
1378
|
+
padding: "4px 10px",
|
|
1379
|
+
backgroundColor: status === "completed" ? "#ede9fe" : "#fef3c7",
|
|
1380
|
+
border: "none",
|
|
1381
|
+
borderRadius: "12px",
|
|
1382
|
+
fontSize: "11px",
|
|
1383
|
+
color: status === "completed" ? "#6d28d9" : "#92400e",
|
|
1384
|
+
cursor: "pointer",
|
|
1385
|
+
transition: "opacity 0.15s"
|
|
1386
|
+
},
|
|
1387
|
+
onMouseOver: (e) => {
|
|
1388
|
+
e.currentTarget.style.opacity = "0.8";
|
|
1389
|
+
},
|
|
1390
|
+
onMouseOut: (e) => {
|
|
1391
|
+
e.currentTarget.style.opacity = "1";
|
|
1392
|
+
},
|
|
1393
|
+
title: `Analytics query: ${query}`,
|
|
1394
|
+
children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartIcon, { size: 12 }),
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
|
|
1397
|
+
"Analytics query",
|
|
1398
|
+
queryType ? ` \xB7 ${queryType.charAt(0).toUpperCase() + queryType.slice(1)}` : ""
|
|
1399
|
+
] }),
|
|
1400
|
+
!onAnalyticsRunClick && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "9px", marginLeft: "2px" }, children: expanded ? "\u25B2" : "\u25BC" })
|
|
1401
|
+
]
|
|
1402
|
+
}
|
|
1403
|
+
),
|
|
1404
|
+
expanded && !onAnalyticsRunClick && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AnalyticsRunPanel, { detail: runDetail, loading })
|
|
1405
|
+
] });
|
|
1406
|
+
}
|
|
1407
|
+
function AnalyticsRunPanel({ detail, loading }) {
|
|
1408
|
+
const [sqlExpanded, setSqlExpanded] = (0, import_react2.useState)(false);
|
|
1409
|
+
if (loading) {
|
|
1410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { padding: "12px", fontSize: "12px", color: "#737373" }, children: "Loading analytics details..." });
|
|
1411
|
+
}
|
|
1412
|
+
if (!detail) return null;
|
|
1413
|
+
const breakdown = detail.structuredBreakdown;
|
|
1414
|
+
const rows = detail.result;
|
|
1415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1416
|
+
"div",
|
|
1417
|
+
{
|
|
1418
|
+
style: {
|
|
1419
|
+
marginTop: "6px",
|
|
1420
|
+
padding: "12px",
|
|
1421
|
+
backgroundColor: "#faf5ff",
|
|
1422
|
+
borderRadius: "8px",
|
|
1423
|
+
fontSize: "12px",
|
|
1424
|
+
lineHeight: 1.5,
|
|
1425
|
+
border: "1px solid #e9d5ff"
|
|
1426
|
+
},
|
|
1427
|
+
children: [
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: 600, color: "#6d28d9", marginBottom: "8px" }, children: detail.query }),
|
|
1429
|
+
breakdown && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "8px" }, children: [
|
|
1430
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Dataset", value: breakdown.baseDataset }),
|
|
1431
|
+
breakdown.metrics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Metrics", value: breakdown.metrics.join(", ") }),
|
|
1432
|
+
breakdown.filters.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Filters", value: breakdown.filters.join(", ") }),
|
|
1433
|
+
breakdown.grouping.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Grouped by", value: breakdown.grouping.join(", ") }),
|
|
1434
|
+
breakdown.sorting && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Sorted", value: breakdown.sorting }),
|
|
1435
|
+
breakdown.timeRange && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Time range", value: breakdown.timeRange })
|
|
1436
|
+
] }),
|
|
1437
|
+
detail.generatedSql && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1439
|
+
"button",
|
|
1440
|
+
{
|
|
1441
|
+
onClick: () => setSqlExpanded((prev) => !prev),
|
|
1442
|
+
style: {
|
|
1443
|
+
background: "none",
|
|
1444
|
+
border: "none",
|
|
1445
|
+
padding: 0,
|
|
1446
|
+
fontSize: "11px",
|
|
1447
|
+
color: "#7c3aed",
|
|
1448
|
+
cursor: "pointer",
|
|
1449
|
+
textDecoration: "underline"
|
|
1450
|
+
},
|
|
1451
|
+
children: sqlExpanded ? "Hide SQL" : "Show SQL"
|
|
1452
|
+
}
|
|
1453
|
+
),
|
|
1454
|
+
sqlExpanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1455
|
+
"pre",
|
|
1456
|
+
{
|
|
1457
|
+
style: {
|
|
1458
|
+
marginTop: "4px",
|
|
1459
|
+
padding: "8px",
|
|
1460
|
+
backgroundColor: "#1e1b4b",
|
|
1461
|
+
color: "#c4b5fd",
|
|
1462
|
+
borderRadius: "6px",
|
|
1463
|
+
fontSize: "10px",
|
|
1464
|
+
overflowX: "auto",
|
|
1465
|
+
whiteSpace: "pre-wrap",
|
|
1466
|
+
wordBreak: "break-all"
|
|
1467
|
+
},
|
|
1468
|
+
children: detail.generatedSql
|
|
1469
|
+
}
|
|
1470
|
+
)
|
|
1471
|
+
] }),
|
|
1472
|
+
rows && rows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "8px" }, children: [
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11px", color: "#737373", marginBottom: "4px" }, children: [
|
|
1474
|
+
"Results (",
|
|
1475
|
+
rows.length,
|
|
1476
|
+
" row",
|
|
1477
|
+
rows.length !== 1 ? "s" : "",
|
|
1478
|
+
")"
|
|
1479
|
+
] }),
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { overflowX: "auto" }, children: [
|
|
1481
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { style: { borderCollapse: "collapse", fontSize: "10px", width: "100%" }, children: [
|
|
1482
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: Object.keys(rows[0]).map((key) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1483
|
+
"th",
|
|
1484
|
+
{
|
|
1485
|
+
style: {
|
|
1486
|
+
padding: "4px 8px",
|
|
1487
|
+
backgroundColor: "#ede9fe",
|
|
1488
|
+
borderBottom: "1px solid #d8b4fe",
|
|
1489
|
+
textAlign: "left",
|
|
1490
|
+
fontWeight: 600,
|
|
1491
|
+
whiteSpace: "nowrap"
|
|
1492
|
+
},
|
|
1493
|
+
children: key
|
|
1494
|
+
},
|
|
1495
|
+
key
|
|
1496
|
+
)) }) }),
|
|
1497
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: rows.slice(0, 5).map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: Object.values(row).map((val, j) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1498
|
+
"td",
|
|
1499
|
+
{
|
|
1500
|
+
style: {
|
|
1501
|
+
padding: "3px 8px",
|
|
1502
|
+
borderBottom: "1px solid #f3e8ff",
|
|
1503
|
+
whiteSpace: "nowrap"
|
|
1504
|
+
},
|
|
1505
|
+
children: String(val ?? "")
|
|
1506
|
+
},
|
|
1507
|
+
j
|
|
1508
|
+
)) }, i)) })
|
|
1509
|
+
] }),
|
|
1510
|
+
rows.length > 5 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "10px", color: "#737373", marginTop: "4px" }, children: [
|
|
1511
|
+
"+ ",
|
|
1512
|
+
rows.length - 5,
|
|
1513
|
+
" more rows"
|
|
1514
|
+
] })
|
|
1515
|
+
] })
|
|
1516
|
+
] })
|
|
1517
|
+
]
|
|
1518
|
+
}
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
function BreakdownItem({ label, value }) {
|
|
1522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "6px" }, children: [
|
|
1523
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: "#737373", minWidth: "70px" }, children: [
|
|
1524
|
+
label,
|
|
1525
|
+
":"
|
|
1526
|
+
] }),
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#1c1917" }, children: value })
|
|
1528
|
+
] });
|
|
1529
|
+
}
|
|
1326
1530
|
function SparklesIcon({ color = "currentColor" }) {
|
|
1327
1531
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", children: [
|
|
1328
1532
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z" }),
|
|
@@ -1339,6 +1543,13 @@ function MinimizeIcon() {
|
|
|
1339
1543
|
function ChevronRightIcon({ size = 16, color = "currentColor" }) {
|
|
1340
1544
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 18l6-6-6-6" }) });
|
|
1341
1545
|
}
|
|
1546
|
+
function ChartIcon({ size = 16, color = "currentColor" }) {
|
|
1547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1548
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", y1: "20", x2: "18", y2: "10" }),
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", y1: "20", x2: "12", y2: "4" }),
|
|
1550
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", y1: "20", x2: "6", y2: "14" })
|
|
1551
|
+
] });
|
|
1552
|
+
}
|
|
1342
1553
|
function BookIcon({ size = 16, color = "currentColor" }) {
|
|
1343
1554
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1344
1555
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 19.5A2.5 2.5 0 016.5 17H20" }),
|
package/dist/index.mjs
CHANGED
|
@@ -183,6 +183,15 @@ var InformedAIClient = class {
|
|
|
183
183
|
return false;
|
|
184
184
|
}
|
|
185
185
|
// ========================================================================
|
|
186
|
+
// Analytics
|
|
187
|
+
// ========================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Get details of a specific analytics run.
|
|
190
|
+
*/
|
|
191
|
+
async getAnalyticsRun(sessionId, runId) {
|
|
192
|
+
return this.request(`/widget/sessions/${sessionId}/analytics-runs/${runId}`);
|
|
193
|
+
}
|
|
194
|
+
// ========================================================================
|
|
186
195
|
// SSE Stream Processing
|
|
187
196
|
// ========================================================================
|
|
188
197
|
async processSSEStream(response, onEvent) {
|
|
@@ -680,6 +689,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
680
689
|
const clearError = useCallback(() => {
|
|
681
690
|
setError(null);
|
|
682
691
|
}, []);
|
|
692
|
+
const getAnalyticsRun = useCallback(async (sessionId, runId) => {
|
|
693
|
+
if (!clientRef.current) throw new Error("Client not initialized");
|
|
694
|
+
return clientRef.current.getAnalyticsRun(sessionId, runId);
|
|
695
|
+
}, []);
|
|
683
696
|
const value = {
|
|
684
697
|
session,
|
|
685
698
|
document,
|
|
@@ -694,7 +707,9 @@ function InformedAIProvider({ config, children }) {
|
|
|
694
707
|
skipTask,
|
|
695
708
|
startNewSession,
|
|
696
709
|
endSession,
|
|
697
|
-
clearError
|
|
710
|
+
clearError,
|
|
711
|
+
onAnalyticsRunClick: config.onAnalyticsRunClick,
|
|
712
|
+
getAnalyticsRun
|
|
698
713
|
};
|
|
699
714
|
return /* @__PURE__ */ jsx(InformedAIContext.Provider, { value, children });
|
|
700
715
|
}
|
|
@@ -1117,6 +1132,7 @@ function MessageBubble({ message, theme, onQuickAction, isLatest = false, quickA
|
|
|
1117
1132
|
const isUser = message.role === "user";
|
|
1118
1133
|
const hasQuickActions = isLatest && message.quickActions && message.quickActions.length > 0;
|
|
1119
1134
|
const hasKbSearch = message.kbSearch != null;
|
|
1135
|
+
const hasAnalyticsRun = message.agentContext?.analyticsRun != null;
|
|
1120
1136
|
if ((message.type === "quick_actions" || !message.content) && hasQuickActions) {
|
|
1121
1137
|
return /* @__PURE__ */ jsx2(
|
|
1122
1138
|
GroupedQuickActions,
|
|
@@ -1155,6 +1171,15 @@ function MessageBubble({ message, theme, onQuickAction, isLatest = false, quickA
|
|
|
1155
1171
|
]
|
|
1156
1172
|
}
|
|
1157
1173
|
),
|
|
1174
|
+
hasAnalyticsRun && /* @__PURE__ */ jsx2(
|
|
1175
|
+
AnalyticsBadge,
|
|
1176
|
+
{
|
|
1177
|
+
runId: message.agentContext.analyticsRun.runId,
|
|
1178
|
+
query: message.agentContext.analyticsRun.query,
|
|
1179
|
+
status: message.agentContext.analyticsRun.status,
|
|
1180
|
+
queryType: message.agentContext.analyticsRun.queryType
|
|
1181
|
+
}
|
|
1182
|
+
),
|
|
1158
1183
|
/* @__PURE__ */ jsx2(
|
|
1159
1184
|
"div",
|
|
1160
1185
|
{
|
|
@@ -1290,6 +1315,185 @@ function GroupedQuickActions({ actions, groups, theme, onQuickAction }) {
|
|
|
1290
1315
|
] }, groupKey);
|
|
1291
1316
|
}) });
|
|
1292
1317
|
}
|
|
1318
|
+
function AnalyticsBadge({ runId, query, status, queryType }) {
|
|
1319
|
+
const { session, onAnalyticsRunClick, getAnalyticsRun } = useInformedAI();
|
|
1320
|
+
const [expanded, setExpanded] = useState2(false);
|
|
1321
|
+
const [runDetail, setRunDetail] = useState2(null);
|
|
1322
|
+
const [loading, setLoading] = useState2(false);
|
|
1323
|
+
const handleClick = () => {
|
|
1324
|
+
if (onAnalyticsRunClick && session) {
|
|
1325
|
+
onAnalyticsRunClick(runId, query, session.id);
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
setExpanded((prev) => !prev);
|
|
1329
|
+
};
|
|
1330
|
+
useEffect2(() => {
|
|
1331
|
+
if (expanded && !runDetail && !loading && session) {
|
|
1332
|
+
setLoading(true);
|
|
1333
|
+
getAnalyticsRun(session.id, runId).then(setRunDetail).catch((err) => console.warn("Failed to load analytics run:", err)).finally(() => setLoading(false));
|
|
1334
|
+
}
|
|
1335
|
+
}, [expanded, runDetail, loading, session, runId, getAnalyticsRun]);
|
|
1336
|
+
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: "4px" }, children: [
|
|
1337
|
+
/* @__PURE__ */ jsxs(
|
|
1338
|
+
"button",
|
|
1339
|
+
{
|
|
1340
|
+
onClick: handleClick,
|
|
1341
|
+
style: {
|
|
1342
|
+
display: "inline-flex",
|
|
1343
|
+
alignItems: "center",
|
|
1344
|
+
gap: "6px",
|
|
1345
|
+
padding: "4px 10px",
|
|
1346
|
+
backgroundColor: status === "completed" ? "#ede9fe" : "#fef3c7",
|
|
1347
|
+
border: "none",
|
|
1348
|
+
borderRadius: "12px",
|
|
1349
|
+
fontSize: "11px",
|
|
1350
|
+
color: status === "completed" ? "#6d28d9" : "#92400e",
|
|
1351
|
+
cursor: "pointer",
|
|
1352
|
+
transition: "opacity 0.15s"
|
|
1353
|
+
},
|
|
1354
|
+
onMouseOver: (e) => {
|
|
1355
|
+
e.currentTarget.style.opacity = "0.8";
|
|
1356
|
+
},
|
|
1357
|
+
onMouseOut: (e) => {
|
|
1358
|
+
e.currentTarget.style.opacity = "1";
|
|
1359
|
+
},
|
|
1360
|
+
title: `Analytics query: ${query}`,
|
|
1361
|
+
children: [
|
|
1362
|
+
/* @__PURE__ */ jsx2(ChartIcon, { size: 12 }),
|
|
1363
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1364
|
+
"Analytics query",
|
|
1365
|
+
queryType ? ` \xB7 ${queryType.charAt(0).toUpperCase() + queryType.slice(1)}` : ""
|
|
1366
|
+
] }),
|
|
1367
|
+
!onAnalyticsRunClick && /* @__PURE__ */ jsx2("span", { style: { fontSize: "9px", marginLeft: "2px" }, children: expanded ? "\u25B2" : "\u25BC" })
|
|
1368
|
+
]
|
|
1369
|
+
}
|
|
1370
|
+
),
|
|
1371
|
+
expanded && !onAnalyticsRunClick && /* @__PURE__ */ jsx2(AnalyticsRunPanel, { detail: runDetail, loading })
|
|
1372
|
+
] });
|
|
1373
|
+
}
|
|
1374
|
+
function AnalyticsRunPanel({ detail, loading }) {
|
|
1375
|
+
const [sqlExpanded, setSqlExpanded] = useState2(false);
|
|
1376
|
+
if (loading) {
|
|
1377
|
+
return /* @__PURE__ */ jsx2("div", { style: { padding: "12px", fontSize: "12px", color: "#737373" }, children: "Loading analytics details..." });
|
|
1378
|
+
}
|
|
1379
|
+
if (!detail) return null;
|
|
1380
|
+
const breakdown = detail.structuredBreakdown;
|
|
1381
|
+
const rows = detail.result;
|
|
1382
|
+
return /* @__PURE__ */ jsxs(
|
|
1383
|
+
"div",
|
|
1384
|
+
{
|
|
1385
|
+
style: {
|
|
1386
|
+
marginTop: "6px",
|
|
1387
|
+
padding: "12px",
|
|
1388
|
+
backgroundColor: "#faf5ff",
|
|
1389
|
+
borderRadius: "8px",
|
|
1390
|
+
fontSize: "12px",
|
|
1391
|
+
lineHeight: 1.5,
|
|
1392
|
+
border: "1px solid #e9d5ff"
|
|
1393
|
+
},
|
|
1394
|
+
children: [
|
|
1395
|
+
/* @__PURE__ */ jsx2("div", { style: { fontWeight: 600, color: "#6d28d9", marginBottom: "8px" }, children: detail.query }),
|
|
1396
|
+
breakdown && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "8px" }, children: [
|
|
1397
|
+
/* @__PURE__ */ jsx2(BreakdownItem, { label: "Dataset", value: breakdown.baseDataset }),
|
|
1398
|
+
breakdown.metrics.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Metrics", value: breakdown.metrics.join(", ") }),
|
|
1399
|
+
breakdown.filters.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Filters", value: breakdown.filters.join(", ") }),
|
|
1400
|
+
breakdown.grouping.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Grouped by", value: breakdown.grouping.join(", ") }),
|
|
1401
|
+
breakdown.sorting && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Sorted", value: breakdown.sorting }),
|
|
1402
|
+
breakdown.timeRange && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Time range", value: breakdown.timeRange })
|
|
1403
|
+
] }),
|
|
1404
|
+
detail.generatedSql && /* @__PURE__ */ jsxs("div", { children: [
|
|
1405
|
+
/* @__PURE__ */ jsx2(
|
|
1406
|
+
"button",
|
|
1407
|
+
{
|
|
1408
|
+
onClick: () => setSqlExpanded((prev) => !prev),
|
|
1409
|
+
style: {
|
|
1410
|
+
background: "none",
|
|
1411
|
+
border: "none",
|
|
1412
|
+
padding: 0,
|
|
1413
|
+
fontSize: "11px",
|
|
1414
|
+
color: "#7c3aed",
|
|
1415
|
+
cursor: "pointer",
|
|
1416
|
+
textDecoration: "underline"
|
|
1417
|
+
},
|
|
1418
|
+
children: sqlExpanded ? "Hide SQL" : "Show SQL"
|
|
1419
|
+
}
|
|
1420
|
+
),
|
|
1421
|
+
sqlExpanded && /* @__PURE__ */ jsx2(
|
|
1422
|
+
"pre",
|
|
1423
|
+
{
|
|
1424
|
+
style: {
|
|
1425
|
+
marginTop: "4px",
|
|
1426
|
+
padding: "8px",
|
|
1427
|
+
backgroundColor: "#1e1b4b",
|
|
1428
|
+
color: "#c4b5fd",
|
|
1429
|
+
borderRadius: "6px",
|
|
1430
|
+
fontSize: "10px",
|
|
1431
|
+
overflowX: "auto",
|
|
1432
|
+
whiteSpace: "pre-wrap",
|
|
1433
|
+
wordBreak: "break-all"
|
|
1434
|
+
},
|
|
1435
|
+
children: detail.generatedSql
|
|
1436
|
+
}
|
|
1437
|
+
)
|
|
1438
|
+
] }),
|
|
1439
|
+
rows && rows.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: "8px" }, children: [
|
|
1440
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", color: "#737373", marginBottom: "4px" }, children: [
|
|
1441
|
+
"Results (",
|
|
1442
|
+
rows.length,
|
|
1443
|
+
" row",
|
|
1444
|
+
rows.length !== 1 ? "s" : "",
|
|
1445
|
+
")"
|
|
1446
|
+
] }),
|
|
1447
|
+
/* @__PURE__ */ jsxs("div", { style: { overflowX: "auto" }, children: [
|
|
1448
|
+
/* @__PURE__ */ jsxs("table", { style: { borderCollapse: "collapse", fontSize: "10px", width: "100%" }, children: [
|
|
1449
|
+
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: Object.keys(rows[0]).map((key) => /* @__PURE__ */ jsx2(
|
|
1450
|
+
"th",
|
|
1451
|
+
{
|
|
1452
|
+
style: {
|
|
1453
|
+
padding: "4px 8px",
|
|
1454
|
+
backgroundColor: "#ede9fe",
|
|
1455
|
+
borderBottom: "1px solid #d8b4fe",
|
|
1456
|
+
textAlign: "left",
|
|
1457
|
+
fontWeight: 600,
|
|
1458
|
+
whiteSpace: "nowrap"
|
|
1459
|
+
},
|
|
1460
|
+
children: key
|
|
1461
|
+
},
|
|
1462
|
+
key
|
|
1463
|
+
)) }) }),
|
|
1464
|
+
/* @__PURE__ */ jsx2("tbody", { children: rows.slice(0, 5).map((row, i) => /* @__PURE__ */ jsx2("tr", { children: Object.values(row).map((val, j) => /* @__PURE__ */ jsx2(
|
|
1465
|
+
"td",
|
|
1466
|
+
{
|
|
1467
|
+
style: {
|
|
1468
|
+
padding: "3px 8px",
|
|
1469
|
+
borderBottom: "1px solid #f3e8ff",
|
|
1470
|
+
whiteSpace: "nowrap"
|
|
1471
|
+
},
|
|
1472
|
+
children: String(val ?? "")
|
|
1473
|
+
},
|
|
1474
|
+
j
|
|
1475
|
+
)) }, i)) })
|
|
1476
|
+
] }),
|
|
1477
|
+
rows.length > 5 && /* @__PURE__ */ jsxs("div", { style: { fontSize: "10px", color: "#737373", marginTop: "4px" }, children: [
|
|
1478
|
+
"+ ",
|
|
1479
|
+
rows.length - 5,
|
|
1480
|
+
" more rows"
|
|
1481
|
+
] })
|
|
1482
|
+
] })
|
|
1483
|
+
] })
|
|
1484
|
+
]
|
|
1485
|
+
}
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
function BreakdownItem({ label, value }) {
|
|
1489
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
|
|
1490
|
+
/* @__PURE__ */ jsxs("span", { style: { color: "#737373", minWidth: "70px" }, children: [
|
|
1491
|
+
label,
|
|
1492
|
+
":"
|
|
1493
|
+
] }),
|
|
1494
|
+
/* @__PURE__ */ jsx2("span", { style: { color: "#1c1917" }, children: value })
|
|
1495
|
+
] });
|
|
1496
|
+
}
|
|
1293
1497
|
function SparklesIcon({ color = "currentColor" }) {
|
|
1294
1498
|
return /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", children: [
|
|
1295
1499
|
/* @__PURE__ */ jsx2("path", { d: "M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z" }),
|
|
@@ -1306,6 +1510,13 @@ function MinimizeIcon() {
|
|
|
1306
1510
|
function ChevronRightIcon({ size = 16, color = "currentColor" }) {
|
|
1307
1511
|
return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx2("path", { d: "M9 18l6-6-6-6" }) });
|
|
1308
1512
|
}
|
|
1513
|
+
function ChartIcon({ size = 16, color = "currentColor" }) {
|
|
1514
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1515
|
+
/* @__PURE__ */ jsx2("line", { x1: "18", y1: "20", x2: "18", y2: "10" }),
|
|
1516
|
+
/* @__PURE__ */ jsx2("line", { x1: "12", y1: "20", x2: "12", y2: "4" }),
|
|
1517
|
+
/* @__PURE__ */ jsx2("line", { x1: "6", y1: "20", x2: "6", y2: "14" })
|
|
1518
|
+
] });
|
|
1519
|
+
}
|
|
1309
1520
|
function BookIcon({ size = 16, color = "currentColor" }) {
|
|
1310
1521
|
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1311
1522
|
/* @__PURE__ */ jsx2("path", { d: "M4 19.5A2.5 2.5 0 016.5 17H20" }),
|