@informedai/react 0.4.26 → 0.4.28
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 +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +208 -1
- package/dist/index.mjs +208 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -26,6 +26,14 @@ interface WidgetMessage {
|
|
|
26
26
|
timestamp: string;
|
|
27
27
|
taskContext?: string;
|
|
28
28
|
kbSearch?: KbSearchInfo;
|
|
29
|
+
agentContext?: {
|
|
30
|
+
analyticsRun?: {
|
|
31
|
+
runId: string;
|
|
32
|
+
query: string;
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
triages?: string[];
|
|
36
|
+
};
|
|
29
37
|
}
|
|
30
38
|
interface QuickAction {
|
|
31
39
|
id: string;
|
|
@@ -128,6 +136,8 @@ interface InformedAssistantConfig {
|
|
|
128
136
|
* Return the current values of all fields as they appear in your UI.
|
|
129
137
|
*/
|
|
130
138
|
getCurrentFieldValues?: () => Record<string, unknown>;
|
|
139
|
+
/** Callback when an analytics run badge is clicked. If not provided, an inline panel is shown. */
|
|
140
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
131
141
|
/** Custom theme overrides */
|
|
132
142
|
theme?: Partial<WidgetTheme>;
|
|
133
143
|
/** Position of the widget (for floating mode) */
|
|
@@ -152,6 +162,24 @@ interface WidgetTheme {
|
|
|
152
162
|
/** Font family */
|
|
153
163
|
fontFamily: string;
|
|
154
164
|
}
|
|
165
|
+
interface SqlBreakdown {
|
|
166
|
+
baseDataset: string;
|
|
167
|
+
metrics: string[];
|
|
168
|
+
filters: string[];
|
|
169
|
+
grouping: string[];
|
|
170
|
+
sorting: string | null;
|
|
171
|
+
timeRange: string | null;
|
|
172
|
+
}
|
|
173
|
+
interface AnalyticsRunDetail {
|
|
174
|
+
id: string;
|
|
175
|
+
query: string;
|
|
176
|
+
status: string;
|
|
177
|
+
generatedSql: string | null;
|
|
178
|
+
structuredBreakdown: SqlBreakdown | null;
|
|
179
|
+
result: unknown[] | null;
|
|
180
|
+
createdAt: string;
|
|
181
|
+
parentRunId: string | null;
|
|
182
|
+
}
|
|
155
183
|
interface SSEEvent {
|
|
156
184
|
type: 'content' | 'done' | 'error' | 'session_update';
|
|
157
185
|
content?: string;
|
|
@@ -345,6 +373,8 @@ interface InformedAIContextValue {
|
|
|
345
373
|
startNewSession: () => Promise<void>;
|
|
346
374
|
endSession: () => Promise<void>;
|
|
347
375
|
clearError: () => void;
|
|
376
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
377
|
+
getAnalyticsRun: (sessionId: string, runId: string) => Promise<AnalyticsRunDetail>;
|
|
348
378
|
}
|
|
349
379
|
declare function useInformedAI(): InformedAIContextValue;
|
|
350
380
|
interface InformedAIProviderProps {
|
|
@@ -463,7 +493,11 @@ declare class InformedAIClient {
|
|
|
463
493
|
* Returns true if sendBeacon was used, false if fetch fallback was attempted.
|
|
464
494
|
*/
|
|
465
495
|
endSessionBeacon(sessionId: string): boolean;
|
|
496
|
+
/**
|
|
497
|
+
* Get details of a specific analytics run.
|
|
498
|
+
*/
|
|
499
|
+
getAnalyticsRun(sessionId: string, runId: string): Promise<AnalyticsRunDetail>;
|
|
466
500
|
private processSSEStream;
|
|
467
501
|
}
|
|
468
502
|
|
|
469
|
-
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 };
|
|
503
|
+
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
|
@@ -26,6 +26,14 @@ interface WidgetMessage {
|
|
|
26
26
|
timestamp: string;
|
|
27
27
|
taskContext?: string;
|
|
28
28
|
kbSearch?: KbSearchInfo;
|
|
29
|
+
agentContext?: {
|
|
30
|
+
analyticsRun?: {
|
|
31
|
+
runId: string;
|
|
32
|
+
query: string;
|
|
33
|
+
status: string;
|
|
34
|
+
};
|
|
35
|
+
triages?: string[];
|
|
36
|
+
};
|
|
29
37
|
}
|
|
30
38
|
interface QuickAction {
|
|
31
39
|
id: string;
|
|
@@ -128,6 +136,8 @@ interface InformedAssistantConfig {
|
|
|
128
136
|
* Return the current values of all fields as they appear in your UI.
|
|
129
137
|
*/
|
|
130
138
|
getCurrentFieldValues?: () => Record<string, unknown>;
|
|
139
|
+
/** Callback when an analytics run badge is clicked. If not provided, an inline panel is shown. */
|
|
140
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
131
141
|
/** Custom theme overrides */
|
|
132
142
|
theme?: Partial<WidgetTheme>;
|
|
133
143
|
/** Position of the widget (for floating mode) */
|
|
@@ -152,6 +162,24 @@ interface WidgetTheme {
|
|
|
152
162
|
/** Font family */
|
|
153
163
|
fontFamily: string;
|
|
154
164
|
}
|
|
165
|
+
interface SqlBreakdown {
|
|
166
|
+
baseDataset: string;
|
|
167
|
+
metrics: string[];
|
|
168
|
+
filters: string[];
|
|
169
|
+
grouping: string[];
|
|
170
|
+
sorting: string | null;
|
|
171
|
+
timeRange: string | null;
|
|
172
|
+
}
|
|
173
|
+
interface AnalyticsRunDetail {
|
|
174
|
+
id: string;
|
|
175
|
+
query: string;
|
|
176
|
+
status: string;
|
|
177
|
+
generatedSql: string | null;
|
|
178
|
+
structuredBreakdown: SqlBreakdown | null;
|
|
179
|
+
result: unknown[] | null;
|
|
180
|
+
createdAt: string;
|
|
181
|
+
parentRunId: string | null;
|
|
182
|
+
}
|
|
155
183
|
interface SSEEvent {
|
|
156
184
|
type: 'content' | 'done' | 'error' | 'session_update';
|
|
157
185
|
content?: string;
|
|
@@ -345,6 +373,8 @@ interface InformedAIContextValue {
|
|
|
345
373
|
startNewSession: () => Promise<void>;
|
|
346
374
|
endSession: () => Promise<void>;
|
|
347
375
|
clearError: () => void;
|
|
376
|
+
onAnalyticsRunClick?: (runId: string, query: string, sessionId: string) => void;
|
|
377
|
+
getAnalyticsRun: (sessionId: string, runId: string) => Promise<AnalyticsRunDetail>;
|
|
348
378
|
}
|
|
349
379
|
declare function useInformedAI(): InformedAIContextValue;
|
|
350
380
|
interface InformedAIProviderProps {
|
|
@@ -463,7 +493,11 @@ declare class InformedAIClient {
|
|
|
463
493
|
* Returns true if sendBeacon was used, false if fetch fallback was attempted.
|
|
464
494
|
*/
|
|
465
495
|
endSessionBeacon(sessionId: string): boolean;
|
|
496
|
+
/**
|
|
497
|
+
* Get details of a specific analytics run.
|
|
498
|
+
*/
|
|
499
|
+
getAnalyticsRun(sessionId: string, runId: string): Promise<AnalyticsRunDetail>;
|
|
466
500
|
private processSSEStream;
|
|
467
501
|
}
|
|
468
502
|
|
|
469
|
-
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 };
|
|
503
|
+
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,14 @@ 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
|
+
}
|
|
1214
|
+
),
|
|
1191
1215
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1192
1216
|
"div",
|
|
1193
1217
|
{
|
|
@@ -1323,6 +1347,182 @@ function GroupedQuickActions({ actions, groups, theme, onQuickAction }) {
|
|
|
1323
1347
|
] }, groupKey);
|
|
1324
1348
|
}) });
|
|
1325
1349
|
}
|
|
1350
|
+
function AnalyticsBadge({ runId, query, status }) {
|
|
1351
|
+
const { session, onAnalyticsRunClick, getAnalyticsRun } = useInformedAI();
|
|
1352
|
+
const [expanded, setExpanded] = (0, import_react2.useState)(false);
|
|
1353
|
+
const [runDetail, setRunDetail] = (0, import_react2.useState)(null);
|
|
1354
|
+
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
1355
|
+
const handleClick = () => {
|
|
1356
|
+
if (onAnalyticsRunClick && session) {
|
|
1357
|
+
onAnalyticsRunClick(runId, query, session.id);
|
|
1358
|
+
return;
|
|
1359
|
+
}
|
|
1360
|
+
setExpanded((prev) => !prev);
|
|
1361
|
+
};
|
|
1362
|
+
(0, import_react2.useEffect)(() => {
|
|
1363
|
+
if (expanded && !runDetail && !loading && session) {
|
|
1364
|
+
setLoading(true);
|
|
1365
|
+
getAnalyticsRun(session.id, runId).then(setRunDetail).catch((err) => console.warn("Failed to load analytics run:", err)).finally(() => setLoading(false));
|
|
1366
|
+
}
|
|
1367
|
+
}, [expanded, runDetail, loading, session, runId, getAnalyticsRun]);
|
|
1368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "4px" }, children: [
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1370
|
+
"button",
|
|
1371
|
+
{
|
|
1372
|
+
onClick: handleClick,
|
|
1373
|
+
style: {
|
|
1374
|
+
display: "inline-flex",
|
|
1375
|
+
alignItems: "center",
|
|
1376
|
+
gap: "6px",
|
|
1377
|
+
padding: "4px 10px",
|
|
1378
|
+
backgroundColor: status === "completed" ? "#ede9fe" : "#fef3c7",
|
|
1379
|
+
border: "none",
|
|
1380
|
+
borderRadius: "12px",
|
|
1381
|
+
fontSize: "11px",
|
|
1382
|
+
color: status === "completed" ? "#6d28d9" : "#92400e",
|
|
1383
|
+
cursor: "pointer",
|
|
1384
|
+
transition: "opacity 0.15s"
|
|
1385
|
+
},
|
|
1386
|
+
onMouseOver: (e) => {
|
|
1387
|
+
e.currentTarget.style.opacity = "0.8";
|
|
1388
|
+
},
|
|
1389
|
+
onMouseOut: (e) => {
|
|
1390
|
+
e.currentTarget.style.opacity = "1";
|
|
1391
|
+
},
|
|
1392
|
+
title: `Analytics query: ${query}`,
|
|
1393
|
+
children: [
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChartIcon, { size: 12 }),
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Analytics query" }),
|
|
1396
|
+
!onAnalyticsRunClick && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "9px", marginLeft: "2px" }, children: expanded ? "\u25B2" : "\u25BC" })
|
|
1397
|
+
]
|
|
1398
|
+
}
|
|
1399
|
+
),
|
|
1400
|
+
expanded && !onAnalyticsRunClick && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AnalyticsRunPanel, { detail: runDetail, loading })
|
|
1401
|
+
] });
|
|
1402
|
+
}
|
|
1403
|
+
function AnalyticsRunPanel({ detail, loading }) {
|
|
1404
|
+
const [sqlExpanded, setSqlExpanded] = (0, import_react2.useState)(false);
|
|
1405
|
+
if (loading) {
|
|
1406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { padding: "12px", fontSize: "12px", color: "#737373" }, children: "Loading analytics details..." });
|
|
1407
|
+
}
|
|
1408
|
+
if (!detail) return null;
|
|
1409
|
+
const breakdown = detail.structuredBreakdown;
|
|
1410
|
+
const rows = detail.result;
|
|
1411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1412
|
+
"div",
|
|
1413
|
+
{
|
|
1414
|
+
style: {
|
|
1415
|
+
marginTop: "6px",
|
|
1416
|
+
padding: "12px",
|
|
1417
|
+
backgroundColor: "#faf5ff",
|
|
1418
|
+
borderRadius: "8px",
|
|
1419
|
+
fontSize: "12px",
|
|
1420
|
+
lineHeight: 1.5,
|
|
1421
|
+
border: "1px solid #e9d5ff"
|
|
1422
|
+
},
|
|
1423
|
+
children: [
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: 600, color: "#6d28d9", marginBottom: "8px" }, children: detail.query }),
|
|
1425
|
+
breakdown && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "8px" }, children: [
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Dataset", value: breakdown.baseDataset }),
|
|
1427
|
+
breakdown.metrics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Metrics", value: breakdown.metrics.join(", ") }),
|
|
1428
|
+
breakdown.filters.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Filters", value: breakdown.filters.join(", ") }),
|
|
1429
|
+
breakdown.grouping.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Grouped by", value: breakdown.grouping.join(", ") }),
|
|
1430
|
+
breakdown.sorting && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Sorted", value: breakdown.sorting }),
|
|
1431
|
+
breakdown.timeRange && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BreakdownItem, { label: "Time range", value: breakdown.timeRange })
|
|
1432
|
+
] }),
|
|
1433
|
+
detail.generatedSql && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
1434
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1435
|
+
"button",
|
|
1436
|
+
{
|
|
1437
|
+
onClick: () => setSqlExpanded((prev) => !prev),
|
|
1438
|
+
style: {
|
|
1439
|
+
background: "none",
|
|
1440
|
+
border: "none",
|
|
1441
|
+
padding: 0,
|
|
1442
|
+
fontSize: "11px",
|
|
1443
|
+
color: "#7c3aed",
|
|
1444
|
+
cursor: "pointer",
|
|
1445
|
+
textDecoration: "underline"
|
|
1446
|
+
},
|
|
1447
|
+
children: sqlExpanded ? "Hide SQL" : "Show SQL"
|
|
1448
|
+
}
|
|
1449
|
+
),
|
|
1450
|
+
sqlExpanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1451
|
+
"pre",
|
|
1452
|
+
{
|
|
1453
|
+
style: {
|
|
1454
|
+
marginTop: "4px",
|
|
1455
|
+
padding: "8px",
|
|
1456
|
+
backgroundColor: "#1e1b4b",
|
|
1457
|
+
color: "#c4b5fd",
|
|
1458
|
+
borderRadius: "6px",
|
|
1459
|
+
fontSize: "10px",
|
|
1460
|
+
overflowX: "auto",
|
|
1461
|
+
whiteSpace: "pre-wrap",
|
|
1462
|
+
wordBreak: "break-all"
|
|
1463
|
+
},
|
|
1464
|
+
children: detail.generatedSql
|
|
1465
|
+
}
|
|
1466
|
+
)
|
|
1467
|
+
] }),
|
|
1468
|
+
rows && rows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "8px" }, children: [
|
|
1469
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11px", color: "#737373", marginBottom: "4px" }, children: [
|
|
1470
|
+
"Results (",
|
|
1471
|
+
rows.length,
|
|
1472
|
+
" row",
|
|
1473
|
+
rows.length !== 1 ? "s" : "",
|
|
1474
|
+
")"
|
|
1475
|
+
] }),
|
|
1476
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { overflowX: "auto" }, children: [
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { style: { borderCollapse: "collapse", fontSize: "10px", width: "100%" }, children: [
|
|
1478
|
+
/* @__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)(
|
|
1479
|
+
"th",
|
|
1480
|
+
{
|
|
1481
|
+
style: {
|
|
1482
|
+
padding: "4px 8px",
|
|
1483
|
+
backgroundColor: "#ede9fe",
|
|
1484
|
+
borderBottom: "1px solid #d8b4fe",
|
|
1485
|
+
textAlign: "left",
|
|
1486
|
+
fontWeight: 600,
|
|
1487
|
+
whiteSpace: "nowrap"
|
|
1488
|
+
},
|
|
1489
|
+
children: key
|
|
1490
|
+
},
|
|
1491
|
+
key
|
|
1492
|
+
)) }) }),
|
|
1493
|
+
/* @__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)(
|
|
1494
|
+
"td",
|
|
1495
|
+
{
|
|
1496
|
+
style: {
|
|
1497
|
+
padding: "3px 8px",
|
|
1498
|
+
borderBottom: "1px solid #f3e8ff",
|
|
1499
|
+
whiteSpace: "nowrap"
|
|
1500
|
+
},
|
|
1501
|
+
children: String(val ?? "")
|
|
1502
|
+
},
|
|
1503
|
+
j
|
|
1504
|
+
)) }, i)) })
|
|
1505
|
+
] }),
|
|
1506
|
+
rows.length > 5 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "10px", color: "#737373", marginTop: "4px" }, children: [
|
|
1507
|
+
"+ ",
|
|
1508
|
+
rows.length - 5,
|
|
1509
|
+
" more rows"
|
|
1510
|
+
] })
|
|
1511
|
+
] })
|
|
1512
|
+
] })
|
|
1513
|
+
]
|
|
1514
|
+
}
|
|
1515
|
+
);
|
|
1516
|
+
}
|
|
1517
|
+
function BreakdownItem({ label, value }) {
|
|
1518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "6px" }, children: [
|
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: "#737373", minWidth: "70px" }, children: [
|
|
1520
|
+
label,
|
|
1521
|
+
":"
|
|
1522
|
+
] }),
|
|
1523
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#1c1917" }, children: value })
|
|
1524
|
+
] });
|
|
1525
|
+
}
|
|
1326
1526
|
function SparklesIcon({ color = "currentColor" }) {
|
|
1327
1527
|
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
1528
|
/* @__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 +1539,13 @@ function MinimizeIcon() {
|
|
|
1339
1539
|
function ChevronRightIcon({ size = 16, color = "currentColor" }) {
|
|
1340
1540
|
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
1541
|
}
|
|
1542
|
+
function ChartIcon({ size = 16, color = "currentColor" }) {
|
|
1543
|
+
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: [
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", y1: "20", x2: "18", y2: "10" }),
|
|
1545
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", y1: "20", x2: "12", y2: "4" }),
|
|
1546
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", y1: "20", x2: "6", y2: "14" })
|
|
1547
|
+
] });
|
|
1548
|
+
}
|
|
1342
1549
|
function BookIcon({ size = 16, color = "currentColor" }) {
|
|
1343
1550
|
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
1551
|
/* @__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,14 @@ 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
|
+
}
|
|
1181
|
+
),
|
|
1158
1182
|
/* @__PURE__ */ jsx2(
|
|
1159
1183
|
"div",
|
|
1160
1184
|
{
|
|
@@ -1290,6 +1314,182 @@ function GroupedQuickActions({ actions, groups, theme, onQuickAction }) {
|
|
|
1290
1314
|
] }, groupKey);
|
|
1291
1315
|
}) });
|
|
1292
1316
|
}
|
|
1317
|
+
function AnalyticsBadge({ runId, query, status }) {
|
|
1318
|
+
const { session, onAnalyticsRunClick, getAnalyticsRun } = useInformedAI();
|
|
1319
|
+
const [expanded, setExpanded] = useState2(false);
|
|
1320
|
+
const [runDetail, setRunDetail] = useState2(null);
|
|
1321
|
+
const [loading, setLoading] = useState2(false);
|
|
1322
|
+
const handleClick = () => {
|
|
1323
|
+
if (onAnalyticsRunClick && session) {
|
|
1324
|
+
onAnalyticsRunClick(runId, query, session.id);
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
setExpanded((prev) => !prev);
|
|
1328
|
+
};
|
|
1329
|
+
useEffect2(() => {
|
|
1330
|
+
if (expanded && !runDetail && !loading && session) {
|
|
1331
|
+
setLoading(true);
|
|
1332
|
+
getAnalyticsRun(session.id, runId).then(setRunDetail).catch((err) => console.warn("Failed to load analytics run:", err)).finally(() => setLoading(false));
|
|
1333
|
+
}
|
|
1334
|
+
}, [expanded, runDetail, loading, session, runId, getAnalyticsRun]);
|
|
1335
|
+
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: "4px" }, children: [
|
|
1336
|
+
/* @__PURE__ */ jsxs(
|
|
1337
|
+
"button",
|
|
1338
|
+
{
|
|
1339
|
+
onClick: handleClick,
|
|
1340
|
+
style: {
|
|
1341
|
+
display: "inline-flex",
|
|
1342
|
+
alignItems: "center",
|
|
1343
|
+
gap: "6px",
|
|
1344
|
+
padding: "4px 10px",
|
|
1345
|
+
backgroundColor: status === "completed" ? "#ede9fe" : "#fef3c7",
|
|
1346
|
+
border: "none",
|
|
1347
|
+
borderRadius: "12px",
|
|
1348
|
+
fontSize: "11px",
|
|
1349
|
+
color: status === "completed" ? "#6d28d9" : "#92400e",
|
|
1350
|
+
cursor: "pointer",
|
|
1351
|
+
transition: "opacity 0.15s"
|
|
1352
|
+
},
|
|
1353
|
+
onMouseOver: (e) => {
|
|
1354
|
+
e.currentTarget.style.opacity = "0.8";
|
|
1355
|
+
},
|
|
1356
|
+
onMouseOut: (e) => {
|
|
1357
|
+
e.currentTarget.style.opacity = "1";
|
|
1358
|
+
},
|
|
1359
|
+
title: `Analytics query: ${query}`,
|
|
1360
|
+
children: [
|
|
1361
|
+
/* @__PURE__ */ jsx2(ChartIcon, { size: 12 }),
|
|
1362
|
+
/* @__PURE__ */ jsx2("span", { children: "Analytics query" }),
|
|
1363
|
+
!onAnalyticsRunClick && /* @__PURE__ */ jsx2("span", { style: { fontSize: "9px", marginLeft: "2px" }, children: expanded ? "\u25B2" : "\u25BC" })
|
|
1364
|
+
]
|
|
1365
|
+
}
|
|
1366
|
+
),
|
|
1367
|
+
expanded && !onAnalyticsRunClick && /* @__PURE__ */ jsx2(AnalyticsRunPanel, { detail: runDetail, loading })
|
|
1368
|
+
] });
|
|
1369
|
+
}
|
|
1370
|
+
function AnalyticsRunPanel({ detail, loading }) {
|
|
1371
|
+
const [sqlExpanded, setSqlExpanded] = useState2(false);
|
|
1372
|
+
if (loading) {
|
|
1373
|
+
return /* @__PURE__ */ jsx2("div", { style: { padding: "12px", fontSize: "12px", color: "#737373" }, children: "Loading analytics details..." });
|
|
1374
|
+
}
|
|
1375
|
+
if (!detail) return null;
|
|
1376
|
+
const breakdown = detail.structuredBreakdown;
|
|
1377
|
+
const rows = detail.result;
|
|
1378
|
+
return /* @__PURE__ */ jsxs(
|
|
1379
|
+
"div",
|
|
1380
|
+
{
|
|
1381
|
+
style: {
|
|
1382
|
+
marginTop: "6px",
|
|
1383
|
+
padding: "12px",
|
|
1384
|
+
backgroundColor: "#faf5ff",
|
|
1385
|
+
borderRadius: "8px",
|
|
1386
|
+
fontSize: "12px",
|
|
1387
|
+
lineHeight: 1.5,
|
|
1388
|
+
border: "1px solid #e9d5ff"
|
|
1389
|
+
},
|
|
1390
|
+
children: [
|
|
1391
|
+
/* @__PURE__ */ jsx2("div", { style: { fontWeight: 600, color: "#6d28d9", marginBottom: "8px" }, children: detail.query }),
|
|
1392
|
+
breakdown && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "8px" }, children: [
|
|
1393
|
+
/* @__PURE__ */ jsx2(BreakdownItem, { label: "Dataset", value: breakdown.baseDataset }),
|
|
1394
|
+
breakdown.metrics.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Metrics", value: breakdown.metrics.join(", ") }),
|
|
1395
|
+
breakdown.filters.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Filters", value: breakdown.filters.join(", ") }),
|
|
1396
|
+
breakdown.grouping.length > 0 && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Grouped by", value: breakdown.grouping.join(", ") }),
|
|
1397
|
+
breakdown.sorting && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Sorted", value: breakdown.sorting }),
|
|
1398
|
+
breakdown.timeRange && /* @__PURE__ */ jsx2(BreakdownItem, { label: "Time range", value: breakdown.timeRange })
|
|
1399
|
+
] }),
|
|
1400
|
+
detail.generatedSql && /* @__PURE__ */ jsxs("div", { children: [
|
|
1401
|
+
/* @__PURE__ */ jsx2(
|
|
1402
|
+
"button",
|
|
1403
|
+
{
|
|
1404
|
+
onClick: () => setSqlExpanded((prev) => !prev),
|
|
1405
|
+
style: {
|
|
1406
|
+
background: "none",
|
|
1407
|
+
border: "none",
|
|
1408
|
+
padding: 0,
|
|
1409
|
+
fontSize: "11px",
|
|
1410
|
+
color: "#7c3aed",
|
|
1411
|
+
cursor: "pointer",
|
|
1412
|
+
textDecoration: "underline"
|
|
1413
|
+
},
|
|
1414
|
+
children: sqlExpanded ? "Hide SQL" : "Show SQL"
|
|
1415
|
+
}
|
|
1416
|
+
),
|
|
1417
|
+
sqlExpanded && /* @__PURE__ */ jsx2(
|
|
1418
|
+
"pre",
|
|
1419
|
+
{
|
|
1420
|
+
style: {
|
|
1421
|
+
marginTop: "4px",
|
|
1422
|
+
padding: "8px",
|
|
1423
|
+
backgroundColor: "#1e1b4b",
|
|
1424
|
+
color: "#c4b5fd",
|
|
1425
|
+
borderRadius: "6px",
|
|
1426
|
+
fontSize: "10px",
|
|
1427
|
+
overflowX: "auto",
|
|
1428
|
+
whiteSpace: "pre-wrap",
|
|
1429
|
+
wordBreak: "break-all"
|
|
1430
|
+
},
|
|
1431
|
+
children: detail.generatedSql
|
|
1432
|
+
}
|
|
1433
|
+
)
|
|
1434
|
+
] }),
|
|
1435
|
+
rows && rows.length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginTop: "8px" }, children: [
|
|
1436
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", color: "#737373", marginBottom: "4px" }, children: [
|
|
1437
|
+
"Results (",
|
|
1438
|
+
rows.length,
|
|
1439
|
+
" row",
|
|
1440
|
+
rows.length !== 1 ? "s" : "",
|
|
1441
|
+
")"
|
|
1442
|
+
] }),
|
|
1443
|
+
/* @__PURE__ */ jsxs("div", { style: { overflowX: "auto" }, children: [
|
|
1444
|
+
/* @__PURE__ */ jsxs("table", { style: { borderCollapse: "collapse", fontSize: "10px", width: "100%" }, children: [
|
|
1445
|
+
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: Object.keys(rows[0]).map((key) => /* @__PURE__ */ jsx2(
|
|
1446
|
+
"th",
|
|
1447
|
+
{
|
|
1448
|
+
style: {
|
|
1449
|
+
padding: "4px 8px",
|
|
1450
|
+
backgroundColor: "#ede9fe",
|
|
1451
|
+
borderBottom: "1px solid #d8b4fe",
|
|
1452
|
+
textAlign: "left",
|
|
1453
|
+
fontWeight: 600,
|
|
1454
|
+
whiteSpace: "nowrap"
|
|
1455
|
+
},
|
|
1456
|
+
children: key
|
|
1457
|
+
},
|
|
1458
|
+
key
|
|
1459
|
+
)) }) }),
|
|
1460
|
+
/* @__PURE__ */ jsx2("tbody", { children: rows.slice(0, 5).map((row, i) => /* @__PURE__ */ jsx2("tr", { children: Object.values(row).map((val, j) => /* @__PURE__ */ jsx2(
|
|
1461
|
+
"td",
|
|
1462
|
+
{
|
|
1463
|
+
style: {
|
|
1464
|
+
padding: "3px 8px",
|
|
1465
|
+
borderBottom: "1px solid #f3e8ff",
|
|
1466
|
+
whiteSpace: "nowrap"
|
|
1467
|
+
},
|
|
1468
|
+
children: String(val ?? "")
|
|
1469
|
+
},
|
|
1470
|
+
j
|
|
1471
|
+
)) }, i)) })
|
|
1472
|
+
] }),
|
|
1473
|
+
rows.length > 5 && /* @__PURE__ */ jsxs("div", { style: { fontSize: "10px", color: "#737373", marginTop: "4px" }, children: [
|
|
1474
|
+
"+ ",
|
|
1475
|
+
rows.length - 5,
|
|
1476
|
+
" more rows"
|
|
1477
|
+
] })
|
|
1478
|
+
] })
|
|
1479
|
+
] })
|
|
1480
|
+
]
|
|
1481
|
+
}
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
function BreakdownItem({ label, value }) {
|
|
1485
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
|
|
1486
|
+
/* @__PURE__ */ jsxs("span", { style: { color: "#737373", minWidth: "70px" }, children: [
|
|
1487
|
+
label,
|
|
1488
|
+
":"
|
|
1489
|
+
] }),
|
|
1490
|
+
/* @__PURE__ */ jsx2("span", { style: { color: "#1c1917" }, children: value })
|
|
1491
|
+
] });
|
|
1492
|
+
}
|
|
1293
1493
|
function SparklesIcon({ color = "currentColor" }) {
|
|
1294
1494
|
return /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", children: [
|
|
1295
1495
|
/* @__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 +1506,13 @@ function MinimizeIcon() {
|
|
|
1306
1506
|
function ChevronRightIcon({ size = 16, color = "currentColor" }) {
|
|
1307
1507
|
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
1508
|
}
|
|
1509
|
+
function ChartIcon({ size = 16, color = "currentColor" }) {
|
|
1510
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1511
|
+
/* @__PURE__ */ jsx2("line", { x1: "18", y1: "20", x2: "18", y2: "10" }),
|
|
1512
|
+
/* @__PURE__ */ jsx2("line", { x1: "12", y1: "20", x2: "12", y2: "4" }),
|
|
1513
|
+
/* @__PURE__ */ jsx2("line", { x1: "6", y1: "20", x2: "6", y2: "14" })
|
|
1514
|
+
] });
|
|
1515
|
+
}
|
|
1309
1516
|
function BookIcon({ size = 16, color = "currentColor" }) {
|
|
1310
1517
|
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
1518
|
/* @__PURE__ */ jsx2("path", { d: "M4 19.5A2.5 2.5 0 016.5 17H20" }),
|