@sqlrooms/ai 0.7.0 → 0.8.1
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 +377 -25
- package/dist/AiSlice.d.ts +489 -307
- package/dist/AiSlice.d.ts.map +1 -1
- package/dist/AiSlice.js +267 -177
- package/dist/AiSlice.js.map +1 -1
- package/dist/analysis.d.ts +25 -19
- package/dist/analysis.d.ts.map +1 -1
- package/dist/analysis.js +86 -145
- package/dist/analysis.js.map +1 -1
- package/dist/components/AnalysisAnswer.d.ts +14 -0
- package/dist/components/AnalysisAnswer.d.ts.map +1 -0
- package/dist/components/AnalysisAnswer.js +14 -0
- package/dist/components/AnalysisAnswer.js.map +1 -0
- package/dist/{AnalysisResult.d.ts → components/AnalysisResult.d.ts} +2 -1
- package/dist/components/AnalysisResult.d.ts.map +1 -0
- package/dist/components/AnalysisResult.js +46 -0
- package/dist/components/AnalysisResult.js.map +1 -0
- package/dist/components/AnalysisResultsContainer.d.ts +5 -0
- package/dist/components/AnalysisResultsContainer.d.ts.map +1 -0
- package/dist/components/AnalysisResultsContainer.js +27 -0
- package/dist/components/AnalysisResultsContainer.js.map +1 -0
- package/dist/components/ErrorMessage.d.ts +4 -0
- package/dist/components/ErrorMessage.d.ts.map +1 -0
- package/dist/components/ErrorMessage.js +7 -0
- package/dist/components/ErrorMessage.js.map +1 -0
- package/dist/components/MessageContainer.d.ts +10 -0
- package/dist/components/MessageContainer.d.ts.map +1 -0
- package/dist/components/MessageContainer.js +17 -0
- package/dist/components/MessageContainer.js.map +1 -0
- package/dist/components/ModelSelector.d.ts +13 -0
- package/dist/components/ModelSelector.d.ts.map +1 -0
- package/dist/components/ModelSelector.js +29 -0
- package/dist/components/ModelSelector.js.map +1 -0
- package/dist/components/QueryControls.d.ts +8 -0
- package/dist/components/QueryControls.d.ts.map +1 -0
- package/dist/components/QueryControls.js +45 -0
- package/dist/components/QueryControls.js.map +1 -0
- package/dist/components/SessionControls.d.ts +17 -0
- package/dist/components/SessionControls.d.ts.map +1 -0
- package/dist/components/SessionControls.js +20 -0
- package/dist/components/SessionControls.js.map +1 -0
- package/dist/components/session/DeleteSessionButton.d.ts +19 -0
- package/dist/components/session/DeleteSessionButton.d.ts.map +1 -0
- package/dist/components/session/DeleteSessionButton.js +54 -0
- package/dist/components/session/DeleteSessionButton.js.map +1 -0
- package/dist/components/session/DeleteSessionDialog.d.ts +27 -0
- package/dist/components/session/DeleteSessionDialog.d.ts.map +1 -0
- package/dist/components/session/DeleteSessionDialog.js +19 -0
- package/dist/components/session/DeleteSessionDialog.js.map +1 -0
- package/dist/components/session/SessionActions.d.ts +18 -0
- package/dist/components/session/SessionActions.d.ts.map +1 -0
- package/dist/components/session/SessionActions.js +19 -0
- package/dist/components/session/SessionActions.js.map +1 -0
- package/dist/components/session/SessionDropdown.d.ts +18 -0
- package/dist/components/session/SessionDropdown.d.ts.map +1 -0
- package/dist/components/session/SessionDropdown.js +21 -0
- package/dist/components/session/SessionDropdown.js.map +1 -0
- package/dist/components/session/SessionTitle.d.ts +18 -0
- package/dist/components/session/SessionTitle.d.ts.map +1 -0
- package/dist/components/session/SessionTitle.js +22 -0
- package/dist/components/session/SessionTitle.js.map +1 -0
- package/dist/components/session/SessionType.d.ts +24 -0
- package/dist/components/session/SessionType.d.ts.map +1 -0
- package/dist/components/session/SessionType.js +2 -0
- package/dist/components/session/SessionType.js.map +1 -0
- package/dist/components/session/index.d.ts +7 -0
- package/dist/components/session/index.d.ts.map +1 -0
- package/dist/components/session/index.js +7 -0
- package/dist/components/session/index.js.map +1 -0
- package/dist/components/tools/QueryToolResult.d.ts +7 -0
- package/dist/components/tools/QueryToolResult.d.ts.map +1 -0
- package/dist/components/tools/QueryToolResult.js +9 -0
- package/dist/components/tools/QueryToolResult.js.map +1 -0
- package/dist/components/tools/ToolResult.d.ts +9 -0
- package/dist/components/tools/ToolResult.d.ts.map +1 -0
- package/dist/components/tools/ToolResult.js +32 -0
- package/dist/components/tools/ToolResult.js.map +1 -0
- package/dist/components/tools/ToolResultErrorBoundary.d.ts +19 -0
- package/dist/components/tools/ToolResultErrorBoundary.d.ts.map +1 -0
- package/dist/components/tools/ToolResultErrorBoundary.js +23 -0
- package/dist/components/tools/ToolResultErrorBoundary.js.map +1 -0
- package/dist/hooks/useScrollToBottom.d.ts +82 -0
- package/dist/hooks/useScrollToBottom.d.ts.map +1 -0
- package/dist/hooks/useScrollToBottom.js +140 -0
- package/dist/hooks/useScrollToBottom.js.map +1 -0
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +592 -201
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +36 -11
- package/dist/schemas.js.map +1 -1
- package/package.json +11 -10
- package/dist/AnalysisResult.d.ts.map +0 -1
- package/dist/AnalysisResult.js +0 -56
- package/dist/AnalysisResult.js.map +0 -1
- package/dist/AnalysisResultsContainer.d.ts +0 -2
- package/dist/AnalysisResultsContainer.d.ts.map +0 -1
- package/dist/AnalysisResultsContainer.js +0 -15
- package/dist/AnalysisResultsContainer.js.map +0 -1
- package/dist/QueryControls.d.ts +0 -6
- package/dist/QueryControls.d.ts.map +0 -1
- package/dist/QueryControls.js +0 -28
- package/dist/QueryControls.js.map +0 -1
- package/dist/QueryResult.d.ts +0 -9
- package/dist/QueryResult.d.ts.map +0 -1
- package/dist/QueryResult.js +0 -46
- package/dist/QueryResult.js.map +0 -1
- package/dist/ToolCall.d.ts +0 -66
- package/dist/ToolCall.d.ts.map +0 -1
- package/dist/ToolCall.js +0 -59
- package/dist/ToolCall.js.map +0 -1
- package/dist/ToolResult.d.ts +0 -10
- package/dist/ToolResult.d.ts.map +0 -1
- package/dist/ToolResult.js +0 -39
- package/dist/ToolResult.js.map +0 -1
- package/dist/hooks/use-scroll-to-bottom.d.ts +0 -7
- package/dist/hooks/use-scroll-to-bottom.d.ts.map +0 -1
- package/dist/hooks/use-scroll-to-bottom.js +0 -51
- package/dist/hooks/use-scroll-to-bottom.js.map +0 -1
package/dist/ToolResult.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ToolResult.js","sourceRoot":"","sources":["../src/ToolResult.tsx"],"names":[],"mappings":"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","sourcesContent":["import {ToolResultSchema} from './schemas';\nimport {\n Badge,\n Button,\n Popover,\n PopoverContent,\n PopoverTrigger,\n cn,\n} from '@sqlrooms/ui';\nimport {CheckCircle2Icon, CodeIcon, XCircleIcon} from 'lucide-react';\nimport {ReactNode} from 'react';\nimport {\n AnalysisAnswer,\n ChartToolCall,\n isAnalysisAnswer,\n isChartToolParameters,\n} from './ToolCall';\nimport {isQueryToolParameters, QueryToolCall} from './ToolCall';\nimport React from 'react';\nimport {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\n\ninterface ToolResultProps {\n toolResult: ToolResultSchema;\n customMessage?: ReactNode;\n}\n\nfunction getBorderColor(isSuccess: boolean, toolName: string) {\n if (!isSuccess) {\n return 'border-red-500';\n }\n switch (toolName) {\n case 'query':\n return 'border-green-500';\n case 'chart':\n return 'border-blue-500';\n case 'answer':\n return 'border-gray-500';\n default:\n return 'border-gray-500';\n }\n}\n\nexport const ToolResult: React.FC<ToolResultProps> = ({\n toolResult,\n customMessage,\n}) => {\n const {toolName, args, result} = toolResult;\n const isSuccess = result.success;\n\n return (\n <div\n className={cn(\n 'border-2 relative bg-gray-100 dark:bg-gray-900 px-5 py-6 rounded-md text-gray-700 dark:text-gray-300 text-xs',\n getBorderColor(isSuccess, toolName),\n )}\n >\n <Badge\n variant=\"secondary\"\n className={cn(\n 'text-xs absolute top-[-12px] left-2 dark:text-gray-100 text-gray-700 flex items-center gap-1 border',\n getBorderColor(isSuccess, toolName),\n )}\n >\n {isSuccess ? (\n <CheckCircle2Icon className=\"w-3 h-3 text-green-500\" />\n ) : (\n <XCircleIcon className=\"w-3 h-3 text-red-500\" />\n )}\n {toolName}\n </Badge>\n\n <div className=\"absolute top-2 right-2\">\n <Popover>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" size=\"icon\" className=\"w-6 h-6\">\n <CodeIcon className=\"w-4 h-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[400px] max-h-[300px] overflow-auto p-4\"\n side=\"right\"\n align=\"start\"\n >\n <JsonMonacoEditor\n value={JSON.stringify(toolResult, null, 2)}\n readOnly={true}\n className=\"h-[250px]\"\n options={{\n minimap: {enabled: false},\n scrollBeyondLastLine: false,\n automaticLayout: true,\n folding: true,\n lineNumbers: false,\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n\n <div className=\"flex flex-col gap-5\">\n {toolName === 'query' && isQueryToolParameters(args) ? (\n <QueryToolCall {...args} customMessage={customMessage} />\n ) : toolName === 'chart' && isChartToolParameters(args) ? (\n <ChartToolCall {...args} />\n ) : toolName === 'answer' && isAnalysisAnswer(result) ? (\n <AnalysisAnswer {...result} />\n ) : (\n Object.keys(args).length > 0 && (\n <JsonMonacoEditor\n value={JSON.stringify(args, null, 2)}\n readOnly={true}\n className=\"h-[150px]\"\n options={{\n minimap: {enabled: false},\n scrollBeyondLastLine: false,\n automaticLayout: true,\n folding: true,\n lineNumbers: false,\n }}\n />\n )\n )}\n {!result.success && (\n <div className=\"text-red-500 gap-2 flex flex-col\">\n <p className=\"text-sm font-bold\">Oops! Something went wrong...</p>\n <p className=\"text-xs\">{result.error}</p>\n </div>\n )}\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type RefObject } from 'react';
|
|
2
|
-
export declare function useScrollToBottom<T extends HTMLElement>(options?: MutationObserverInit): [RefObject<T>, RefObject<T>];
|
|
3
|
-
export declare function useScrollToBottomButton(containerRef: RefObject<HTMLElement>): {
|
|
4
|
-
showButton: boolean;
|
|
5
|
-
scrollToBottom: () => void;
|
|
6
|
-
};
|
|
7
|
-
//# sourceMappingURL=use-scroll-to-bottom.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-scroll-to-bottom.d.ts","sourceRoot":"","sources":["../../src/hooks/use-scroll-to-bottom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAW,MAAM,OAAO,CAAC;AAElE,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,EACrD,OAAO,GAAE,oBAKR,GACA,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAoB9B;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,SAAS,CAAC,WAAW,CAAC;;;EAiC3E"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
export function useScrollToBottom(options = {
|
|
3
|
-
childList: true,
|
|
4
|
-
subtree: true,
|
|
5
|
-
characterData: true,
|
|
6
|
-
// attributes: true,
|
|
7
|
-
}) {
|
|
8
|
-
const containerRef = useRef(null);
|
|
9
|
-
const endRef = useRef(null);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
const container = containerRef.current;
|
|
12
|
-
const end = endRef.current;
|
|
13
|
-
if (container && end) {
|
|
14
|
-
const observer = new MutationObserver(() => {
|
|
15
|
-
end.scrollIntoView({ behavior: 'instant', block: 'end' });
|
|
16
|
-
});
|
|
17
|
-
observer.observe(container, options);
|
|
18
|
-
return () => observer.disconnect();
|
|
19
|
-
}
|
|
20
|
-
}, [options]);
|
|
21
|
-
return [containerRef, endRef];
|
|
22
|
-
}
|
|
23
|
-
export function useScrollToBottomButton(containerRef) {
|
|
24
|
-
const [showButton, setShowButton] = useState(false);
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
const container = containerRef.current;
|
|
27
|
-
if (!container)
|
|
28
|
-
return;
|
|
29
|
-
const handleScroll = () => {
|
|
30
|
-
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
31
|
-
// Only show if we're scrolled up more than 200px from the bottom
|
|
32
|
-
const isNotAtBottom = scrollHeight - scrollTop - clientHeight > 200;
|
|
33
|
-
setShowButton(isNotAtBottom);
|
|
34
|
-
};
|
|
35
|
-
container.addEventListener('scroll', handleScroll);
|
|
36
|
-
// Initial check with a slight delay to ensure proper measurement
|
|
37
|
-
const timeoutId = setTimeout(handleScroll, 100);
|
|
38
|
-
return () => {
|
|
39
|
-
container.removeEventListener('scroll', handleScroll);
|
|
40
|
-
clearTimeout(timeoutId);
|
|
41
|
-
};
|
|
42
|
-
}, [containerRef]);
|
|
43
|
-
const scrollToBottom = () => {
|
|
44
|
-
containerRef.current?.scrollTo({
|
|
45
|
-
top: containerRef.current.scrollHeight,
|
|
46
|
-
behavior: 'smooth',
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
return { showButton, scrollToBottom };
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=use-scroll-to-bottom.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-scroll-to-bottom.js","sourceRoot":"","sources":["../../src/hooks/use-scroll-to-bottom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,MAAM,EAAkB,QAAQ,EAAC,MAAM,OAAO,CAAC;AAElE,MAAM,UAAU,iBAAiB,CAC/B,UAAgC;IAC9B,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,oBAAoB;CACrB;IAED,MAAM,YAAY,GAAG,MAAM,CAAI,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAI,IAAI,CAAC,CAAC;IAE/B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;QAE3B,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;gBACzC,GAAG,CAAC,cAAc,CAAC,EAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAErC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACrC,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,YAAoC;IAC1E,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,MAAM,EAAC,SAAS,EAAE,YAAY,EAAE,YAAY,EAAC,GAAG,SAAS,CAAC;YAC1D,iEAAiE;YACjE,MAAM,aAAa,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,GAAG,CAAC;YACpE,aAAa,CAAC,aAAa,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEnD,iEAAiE;QACjE,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEhD,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YACtD,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC7B,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,YAAY;YACtC,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,EAAC,UAAU,EAAE,cAAc,EAAC,CAAC;AACtC,CAAC","sourcesContent":["import {useEffect, useRef, type RefObject, useState} from 'react';\n\nexport function useScrollToBottom<T extends HTMLElement>(\n options: MutationObserverInit = {\n childList: true,\n subtree: true,\n characterData: true,\n // attributes: true,\n },\n): [RefObject<T>, RefObject<T>] {\n const containerRef = useRef<T>(null);\n const endRef = useRef<T>(null);\n\n useEffect(() => {\n const container = containerRef.current;\n const end = endRef.current;\n\n if (container && end) {\n const observer = new MutationObserver(() => {\n end.scrollIntoView({behavior: 'instant', block: 'end'});\n });\n\n observer.observe(container, options);\n\n return () => observer.disconnect();\n }\n }, [options]);\n\n return [containerRef, endRef];\n}\n\nexport function useScrollToBottomButton(containerRef: RefObject<HTMLElement>) {\n const [showButton, setShowButton] = useState(false);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n const {scrollTop, scrollHeight, clientHeight} = container;\n // Only show if we're scrolled up more than 200px from the bottom\n const isNotAtBottom = scrollHeight - scrollTop - clientHeight > 200;\n setShowButton(isNotAtBottom);\n };\n\n container.addEventListener('scroll', handleScroll);\n\n // Initial check with a slight delay to ensure proper measurement\n const timeoutId = setTimeout(handleScroll, 100);\n\n return () => {\n container.removeEventListener('scroll', handleScroll);\n clearTimeout(timeoutId);\n };\n }, [containerRef]);\n\n const scrollToBottom = () => {\n containerRef.current?.scrollTo({\n top: containerRef.current.scrollHeight,\n behavior: 'smooth',\n });\n };\n\n return {showButton, scrollToBottom};\n}\n"]}
|