@sqlrooms/ai-core 0.26.0-rc.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.
Files changed (99) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +488 -0
  3. package/dist/AiSlice.d.ts +52 -0
  4. package/dist/AiSlice.d.ts.map +1 -0
  5. package/dist/AiSlice.js +367 -0
  6. package/dist/AiSlice.js.map +1 -0
  7. package/dist/analysis.d.ts +51 -0
  8. package/dist/analysis.d.ts.map +1 -0
  9. package/dist/analysis.js +43 -0
  10. package/dist/analysis.js.map +1 -0
  11. package/dist/components/AnalysisAnswer.d.ts +15 -0
  12. package/dist/components/AnalysisAnswer.d.ts.map +1 -0
  13. package/dist/components/AnalysisAnswer.js +102 -0
  14. package/dist/components/AnalysisAnswer.js.map +1 -0
  15. package/dist/components/AnalysisResult.d.ts +22 -0
  16. package/dist/components/AnalysisResult.d.ts.map +1 -0
  17. package/dist/components/AnalysisResult.js +39 -0
  18. package/dist/components/AnalysisResult.js.map +1 -0
  19. package/dist/components/AnalysisResultsContainer.d.ts +5 -0
  20. package/dist/components/AnalysisResultsContainer.d.ts.map +1 -0
  21. package/dist/components/AnalysisResultsContainer.js +26 -0
  22. package/dist/components/AnalysisResultsContainer.js.map +1 -0
  23. package/dist/components/ErrorMessage.d.ts +4 -0
  24. package/dist/components/ErrorMessage.d.ts.map +1 -0
  25. package/dist/components/ErrorMessage.js +8 -0
  26. package/dist/components/ErrorMessage.js.map +1 -0
  27. package/dist/components/MessageContainer.d.ts +10 -0
  28. package/dist/components/MessageContainer.d.ts.map +1 -0
  29. package/dist/components/MessageContainer.js +9 -0
  30. package/dist/components/MessageContainer.js.map +1 -0
  31. package/dist/components/ModelSelector.d.ts +13 -0
  32. package/dist/components/ModelSelector.d.ts.map +1 -0
  33. package/dist/components/ModelSelector.js +34 -0
  34. package/dist/components/ModelSelector.js.map +1 -0
  35. package/dist/components/QueryControls.d.ts +10 -0
  36. package/dist/components/QueryControls.d.ts.map +1 -0
  37. package/dist/components/QueryControls.js +52 -0
  38. package/dist/components/QueryControls.js.map +1 -0
  39. package/dist/components/SessionControls.d.ts +17 -0
  40. package/dist/components/SessionControls.d.ts.map +1 -0
  41. package/dist/components/SessionControls.js +20 -0
  42. package/dist/components/SessionControls.js.map +1 -0
  43. package/dist/components/session/DeleteSessionButton.d.ts +19 -0
  44. package/dist/components/session/DeleteSessionButton.d.ts.map +1 -0
  45. package/dist/components/session/DeleteSessionButton.js +54 -0
  46. package/dist/components/session/DeleteSessionButton.js.map +1 -0
  47. package/dist/components/session/DeleteSessionDialog.d.ts +27 -0
  48. package/dist/components/session/DeleteSessionDialog.d.ts.map +1 -0
  49. package/dist/components/session/DeleteSessionDialog.js +19 -0
  50. package/dist/components/session/DeleteSessionDialog.js.map +1 -0
  51. package/dist/components/session/SessionActions.d.ts +18 -0
  52. package/dist/components/session/SessionActions.d.ts.map +1 -0
  53. package/dist/components/session/SessionActions.js +19 -0
  54. package/dist/components/session/SessionActions.js.map +1 -0
  55. package/dist/components/session/SessionDropdown.d.ts +18 -0
  56. package/dist/components/session/SessionDropdown.d.ts.map +1 -0
  57. package/dist/components/session/SessionDropdown.js +21 -0
  58. package/dist/components/session/SessionDropdown.js.map +1 -0
  59. package/dist/components/session/SessionTitle.d.ts +18 -0
  60. package/dist/components/session/SessionTitle.d.ts.map +1 -0
  61. package/dist/components/session/SessionTitle.js +22 -0
  62. package/dist/components/session/SessionTitle.js.map +1 -0
  63. package/dist/components/session/SessionType.d.ts +24 -0
  64. package/dist/components/session/SessionType.d.ts.map +1 -0
  65. package/dist/components/session/SessionType.js +2 -0
  66. package/dist/components/session/SessionType.js.map +1 -0
  67. package/dist/components/session/index.d.ts +7 -0
  68. package/dist/components/session/index.d.ts.map +1 -0
  69. package/dist/components/session/index.js +7 -0
  70. package/dist/components/session/index.js.map +1 -0
  71. package/dist/components/tools/ToolErrorMessage.d.ts +39 -0
  72. package/dist/components/tools/ToolErrorMessage.d.ts.map +1 -0
  73. package/dist/components/tools/ToolErrorMessage.js +20 -0
  74. package/dist/components/tools/ToolErrorMessage.js.map +1 -0
  75. package/dist/components/tools/ToolResult.d.ts +11 -0
  76. package/dist/components/tools/ToolResult.d.ts.map +1 -0
  77. package/dist/components/tools/ToolResult.js +29 -0
  78. package/dist/components/tools/ToolResult.js.map +1 -0
  79. package/dist/components/tools/ToolResultErrorBoundary.d.ts +19 -0
  80. package/dist/components/tools/ToolResultErrorBoundary.d.ts.map +1 -0
  81. package/dist/components/tools/ToolResultErrorBoundary.js +24 -0
  82. package/dist/components/tools/ToolResultErrorBoundary.js.map +1 -0
  83. package/dist/hasAiSettingsConfig.d.ts +13 -0
  84. package/dist/hasAiSettingsConfig.d.ts.map +1 -0
  85. package/dist/hasAiSettingsConfig.js +16 -0
  86. package/dist/hasAiSettingsConfig.js.map +1 -0
  87. package/dist/hooks/useScrollToBottom.d.ts +82 -0
  88. package/dist/hooks/useScrollToBottom.d.ts.map +1 -0
  89. package/dist/hooks/useScrollToBottom.js +142 -0
  90. package/dist/hooks/useScrollToBottom.js.map +1 -0
  91. package/dist/index.d.ts +21 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +18 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/utils.d.ts +15 -0
  96. package/dist/utils.d.ts.map +1 -0
  97. package/dist/utils.js +31 -0
  98. package/dist/utils.js.map +1 -0
  99. package/package.json +51 -0
@@ -0,0 +1,82 @@
1
+ import { type RefObject } from 'react';
2
+ interface ScrollToBottomResult<T extends HTMLElement | null> {
3
+ showScrollButton: boolean;
4
+ scrollToBottom: () => void;
5
+ }
6
+ /**
7
+ * A React hook that provides automatic scrolling behavior for containers with dynamic content.
8
+ *
9
+ * This hook helps manage scroll behavior in containers where content is being added dynamically,
10
+ * such as chat interfaces or logs. It automatically scrolls to the bottom when new content is added
11
+ * if the user was already at the bottom, and provides a function to manually scroll to the bottom.
12
+ *
13
+ * @template T - The type of HTMLElement for the container and end references
14
+ *
15
+ * @param options - Configuration options
16
+ * @param options.dataToObserve - The data to observe for changes (messages, items, etc.)
17
+ * @param options.containerRef - Reference to the scrollable container element
18
+ * @param options.endRef - Reference to an element at the end of the content
19
+ * @param options.scrollOnInitialLoad - Whether to scroll to bottom on initial load (default: true)
20
+ *
21
+ * @returns An object containing:
22
+ * - showScrollButton: Boolean indicating if the "scroll to bottom" button should be shown
23
+ * - scrollToBottom: Function to programmatically scroll to the bottom
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * import { useRef } from 'react';
28
+ * import { useScrollToBottom } from './use-scroll-to-bottom';
29
+ *
30
+ * function ChatContainer({ messages }) {
31
+ * const containerRef = useRef<HTMLDivElement>(null);
32
+ * const endRef = useRef<HTMLDivElement>(null);
33
+ *
34
+ * const { showScrollButton, scrollToBottom } = useScrollToBottom({
35
+ * dataToObserve: messages,
36
+ * containerRef,
37
+ * endRef,
38
+ * scrollOnInitialLoad: false // Disable scrolling on initial load
39
+ * });
40
+ *
41
+ * return (
42
+ * <div className="relative h-[500px]">
43
+ * <div ref={containerRef} className="h-full overflow-y-auto p-4">
44
+ * {messages.map((message) => (
45
+ * <div key={message.id} className="mb-4">
46
+ * {message.text}
47
+ * </div>
48
+ * ))}
49
+ * <div ref={endRef} />
50
+ * </div>
51
+ *
52
+ * {showScrollButton && (
53
+ * <button
54
+ * onClick={scrollToBottom}
55
+ * className="absolute bottom-4 right-4 rounded-full bg-blue-500 p-2"
56
+ * >
57
+ * ↓
58
+ * </button>
59
+ * )}
60
+ * </div>
61
+ * );
62
+ * }
63
+ * ```
64
+ */
65
+ export declare function useScrollToBottom<T extends HTMLElement | null>({
66
+ /**
67
+ * The data to observe. Can be an array of items or a single item.
68
+ * When the data changes, the hook will scroll to the bottom of the container.
69
+ */
70
+ dataToObserve, containerRef, endRef,
71
+ /**
72
+ * Whether to scroll to bottom on initial load.
73
+ * @default false
74
+ */
75
+ scrollOnInitialLoad, }: {
76
+ dataToObserve: unknown;
77
+ containerRef: RefObject<T | null>;
78
+ endRef: RefObject<T | null>;
79
+ scrollOnInitialLoad?: boolean;
80
+ }): ScrollToBottomResult<T>;
81
+ export {};
82
+ //# sourceMappingURL=useScrollToBottom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScrollToBottom.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollToBottom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAwB,MAAM,OAAO,CAAC;AAE/E,UAAU,oBAAoB,CAAC,CAAC,SAAS,WAAW,GAAG,IAAI;IACzD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,GAAG,IAAI,EAAE;AAC9D;;;GAGG;AACH,aAAa,EACb,YAAY,EACZ,MAAM;AACN;;;GAGG;AACH,mBAA2B,GAC5B,EAAE;IACD,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAClC,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,oBAAoB,CAAC,CAAC,CAAC,CA+E1B"}
@@ -0,0 +1,142 @@
1
+ import { useEffect, useRef, useState, useCallback } from 'react';
2
+ /**
3
+ * Only show button and auto-scroll if we're scrolled up more
4
+ * than {AT_BOTTOM_TOLERANCE}px from the bottom.
5
+ */
6
+ const AT_BOTTOM_TOLERANCE = 100;
7
+ /**
8
+ * A React hook that provides automatic scrolling behavior for containers with dynamic content.
9
+ *
10
+ * This hook helps manage scroll behavior in containers where content is being added dynamically,
11
+ * such as chat interfaces or logs. It automatically scrolls to the bottom when new content is added
12
+ * if the user was already at the bottom, and provides a function to manually scroll to the bottom.
13
+ *
14
+ * @template T - The type of HTMLElement for the container and end references
15
+ *
16
+ * @param options - Configuration options
17
+ * @param options.dataToObserve - The data to observe for changes (messages, items, etc.)
18
+ * @param options.containerRef - Reference to the scrollable container element
19
+ * @param options.endRef - Reference to an element at the end of the content
20
+ * @param options.scrollOnInitialLoad - Whether to scroll to bottom on initial load (default: true)
21
+ *
22
+ * @returns An object containing:
23
+ * - showScrollButton: Boolean indicating if the "scroll to bottom" button should be shown
24
+ * - scrollToBottom: Function to programmatically scroll to the bottom
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { useRef } from 'react';
29
+ * import { useScrollToBottom } from './use-scroll-to-bottom';
30
+ *
31
+ * function ChatContainer({ messages }) {
32
+ * const containerRef = useRef<HTMLDivElement>(null);
33
+ * const endRef = useRef<HTMLDivElement>(null);
34
+ *
35
+ * const { showScrollButton, scrollToBottom } = useScrollToBottom({
36
+ * dataToObserve: messages,
37
+ * containerRef,
38
+ * endRef,
39
+ * scrollOnInitialLoad: false // Disable scrolling on initial load
40
+ * });
41
+ *
42
+ * return (
43
+ * <div className="relative h-[500px]">
44
+ * <div ref={containerRef} className="h-full overflow-y-auto p-4">
45
+ * {messages.map((message) => (
46
+ * <div key={message.id} className="mb-4">
47
+ * {message.text}
48
+ * </div>
49
+ * ))}
50
+ * <div ref={endRef} />
51
+ * </div>
52
+ *
53
+ * {showScrollButton && (
54
+ * <button
55
+ * onClick={scrollToBottom}
56
+ * className="absolute bottom-4 right-4 rounded-full bg-blue-500 p-2"
57
+ * >
58
+ * ↓
59
+ * </button>
60
+ * )}
61
+ * </div>
62
+ * );
63
+ * }
64
+ * ```
65
+ */
66
+ export function useScrollToBottom({
67
+ /**
68
+ * The data to observe. Can be an array of items or a single item.
69
+ * When the data changes, the hook will scroll to the bottom of the container.
70
+ */
71
+ dataToObserve, containerRef, endRef,
72
+ /**
73
+ * Whether to scroll to bottom on initial load.
74
+ * @default false
75
+ */
76
+ scrollOnInitialLoad = false, }) {
77
+ const [showScrollButton, setShowButton] = useState(false);
78
+ // Track if user was at bottom before content changes
79
+ const wasAtBottomRef = useRef(scrollOnInitialLoad);
80
+ // Track if this is the initial load
81
+ const isInitialLoadRef = useRef(true);
82
+ // Check if the container is scrolled to the bottom
83
+ const checkIfAtBottom = useCallback((container) => {
84
+ if (!container)
85
+ return false;
86
+ const { scrollTop, scrollHeight, clientHeight } = container;
87
+ return scrollHeight - scrollTop - clientHeight <= AT_BOTTOM_TOLERANCE;
88
+ }, []);
89
+ // Extracted reusable handleScroll function
90
+ const onScroll = useCallback(() => {
91
+ const container = containerRef.current;
92
+ if (!container)
93
+ return;
94
+ const isAtBottom = checkIfAtBottom(container);
95
+ // Update wasAtBottom state for next content change
96
+ wasAtBottomRef.current = isAtBottom;
97
+ // Show button only if not at bottom
98
+ setShowButton(!isAtBottom);
99
+ }, [checkIfAtBottom, containerRef]);
100
+ // Handle new content being added
101
+ useEffect(() => {
102
+ if (!dataToObserve)
103
+ return;
104
+ const container = containerRef.current;
105
+ const end = endRef.current;
106
+ if (container && end && wasAtBottomRef.current) {
107
+ // Only scroll if this is not the initial load or if scrollOnInitialLoad is true
108
+ if (!isInitialLoadRef.current || scrollOnInitialLoad) {
109
+ end.scrollIntoView({ behavior: 'instant', block: 'end' });
110
+ }
111
+ }
112
+ // Mark that initial load is complete
113
+ isInitialLoadRef.current = false;
114
+ // After content change, check scroll position again
115
+ onScroll();
116
+ }, [containerRef, dataToObserve, endRef, onScroll, scrollOnInitialLoad]);
117
+ useEffect(() => {
118
+ const container = containerRef.current;
119
+ if (!container)
120
+ return;
121
+ container.addEventListener('scroll', onScroll);
122
+ // Initial check with a slight delay to ensure proper measurement
123
+ const timeoutId = setTimeout(onScroll, 100);
124
+ return () => {
125
+ container.removeEventListener('scroll', onScroll);
126
+ clearTimeout(timeoutId);
127
+ };
128
+ }, [containerRef, onScroll]);
129
+ const scrollToBottom = () => {
130
+ if (containerRef.current) {
131
+ containerRef.current.scrollTo({
132
+ top: containerRef.current.scrollHeight,
133
+ behavior: 'smooth',
134
+ });
135
+ }
136
+ };
137
+ return {
138
+ showScrollButton,
139
+ scrollToBottom,
140
+ };
141
+ }
142
+ //# sourceMappingURL=useScrollToBottom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScrollToBottom.js","sourceRoot":"","sources":["../../src/hooks/useScrollToBottom.ts"],"names":[],"mappings":"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","sourcesContent":["import {useEffect, useRef, type RefObject, useState, useCallback} from 'react';\n\ninterface ScrollToBottomResult<T extends HTMLElement | null> {\n showScrollButton: boolean;\n scrollToBottom: () => void;\n}\n\n/**\n * Only show button and auto-scroll if we're scrolled up more\n * than {AT_BOTTOM_TOLERANCE}px from the bottom.\n */\nconst AT_BOTTOM_TOLERANCE = 100;\n\n/**\n * A React hook that provides automatic scrolling behavior for containers with dynamic content.\n *\n * This hook helps manage scroll behavior in containers where content is being added dynamically,\n * such as chat interfaces or logs. It automatically scrolls to the bottom when new content is added\n * if the user was already at the bottom, and provides a function to manually scroll to the bottom.\n *\n * @template T - The type of HTMLElement for the container and end references\n *\n * @param options - Configuration options\n * @param options.dataToObserve - The data to observe for changes (messages, items, etc.)\n * @param options.containerRef - Reference to the scrollable container element\n * @param options.endRef - Reference to an element at the end of the content\n * @param options.scrollOnInitialLoad - Whether to scroll to bottom on initial load (default: true)\n *\n * @returns An object containing:\n * - showScrollButton: Boolean indicating if the \"scroll to bottom\" button should be shown\n * - scrollToBottom: Function to programmatically scroll to the bottom\n *\n * @example\n * ```tsx\n * import { useRef } from 'react';\n * import { useScrollToBottom } from './use-scroll-to-bottom';\n *\n * function ChatContainer({ messages }) {\n * const containerRef = useRef<HTMLDivElement>(null);\n * const endRef = useRef<HTMLDivElement>(null);\n *\n * const { showScrollButton, scrollToBottom } = useScrollToBottom({\n * dataToObserve: messages,\n * containerRef,\n * endRef,\n * scrollOnInitialLoad: false // Disable scrolling on initial load\n * });\n *\n * return (\n * <div className=\"relative h-[500px]\">\n * <div ref={containerRef} className=\"h-full overflow-y-auto p-4\">\n * {messages.map((message) => (\n * <div key={message.id} className=\"mb-4\">\n * {message.text}\n * </div>\n * ))}\n * <div ref={endRef} />\n * </div>\n *\n * {showScrollButton && (\n * <button\n * onClick={scrollToBottom}\n * className=\"absolute bottom-4 right-4 rounded-full bg-blue-500 p-2\"\n * >\n * ↓\n * </button>\n * )}\n * </div>\n * );\n * }\n * ```\n */\nexport function useScrollToBottom<T extends HTMLElement | null>({\n /**\n * The data to observe. Can be an array of items or a single item.\n * When the data changes, the hook will scroll to the bottom of the container.\n */\n dataToObserve,\n containerRef,\n endRef,\n /**\n * Whether to scroll to bottom on initial load.\n * @default false\n */\n scrollOnInitialLoad = false,\n}: {\n dataToObserve: unknown;\n containerRef: RefObject<T | null>;\n endRef: RefObject<T | null>;\n scrollOnInitialLoad?: boolean;\n}): ScrollToBottomResult<T> {\n const [showScrollButton, setShowButton] = useState(false);\n\n // Track if user was at bottom before content changes\n const wasAtBottomRef = useRef(scrollOnInitialLoad);\n\n // Track if this is the initial load\n const isInitialLoadRef = useRef(true);\n\n // Check if the container is scrolled to the bottom\n const checkIfAtBottom = useCallback((container: T) => {\n if (!container) return false;\n const {scrollTop, scrollHeight, clientHeight} = container;\n return scrollHeight - scrollTop - clientHeight <= AT_BOTTOM_TOLERANCE;\n }, []);\n\n // Extracted reusable handleScroll function\n const onScroll = useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const isAtBottom = checkIfAtBottom(container);\n\n // Update wasAtBottom state for next content change\n wasAtBottomRef.current = isAtBottom;\n\n // Show button only if not at bottom\n setShowButton(!isAtBottom);\n }, [checkIfAtBottom, containerRef]);\n\n // Handle new content being added\n useEffect(() => {\n if (!dataToObserve) return;\n\n const container = containerRef.current;\n const end = endRef.current;\n\n if (container && end && wasAtBottomRef.current) {\n // Only scroll if this is not the initial load or if scrollOnInitialLoad is true\n if (!isInitialLoadRef.current || scrollOnInitialLoad) {\n end.scrollIntoView({behavior: 'instant', block: 'end'});\n }\n }\n\n // Mark that initial load is complete\n isInitialLoadRef.current = false;\n\n // After content change, check scroll position again\n onScroll();\n }, [containerRef, dataToObserve, endRef, onScroll, scrollOnInitialLoad]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n container.addEventListener('scroll', onScroll);\n\n // Initial check with a slight delay to ensure proper measurement\n const timeoutId = setTimeout(onScroll, 100);\n\n return () => {\n container.removeEventListener('scroll', onScroll);\n clearTimeout(timeoutId);\n };\n }, [containerRef, onScroll]);\n\n const scrollToBottom = () => {\n if (containerRef.current) {\n containerRef.current.scrollTo({\n top: containerRef.current.scrollHeight,\n behavior: 'smooth',\n });\n }\n };\n\n return {\n showScrollButton,\n scrollToBottom,\n };\n}\n"]}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * {@include ../README.md}
3
+ * @packageDocumentation
4
+ */
5
+ export { createAiSlice, useStoreWithAi } from './AiSlice';
6
+ export type { AiSliceState } from './AiSlice';
7
+ export { AnalysisResultsContainer } from './components/AnalysisResultsContainer';
8
+ export { AnalysisResult } from './components/AnalysisResult';
9
+ export { useScrollToBottom } from './hooks/useScrollToBottom';
10
+ export type { AiSliceTool } from './AiSlice';
11
+ export { ModelSelector } from './components/ModelSelector';
12
+ export { SessionControls } from './components/SessionControls';
13
+ export { QueryControls } from './components/QueryControls';
14
+ export { DeleteSessionDialog } from './components/session/DeleteSessionDialog';
15
+ export { SessionActions } from './components/session/SessionActions';
16
+ export { SessionDropdown } from './components/session/SessionDropdown';
17
+ export { SessionTitle } from './components/session/SessionTitle';
18
+ export type { SessionType } from './components/session/SessionType';
19
+ export { ToolErrorMessage } from './components/tools/ToolErrorMessage';
20
+ export { AiSliceConfig, createDefaultAiConfig } from '@sqlrooms/ai-config';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,WAAW,CAAC;AAExD,YAAY,EAAC,YAAY,EAAC,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AAC5D,YAAY,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,mBAAmB,EAAC,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAC,eAAe,EAAC,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAC/D,YAAY,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAC,aAAa,EAAE,qBAAqB,EAAC,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * {@include ../README.md}
3
+ * @packageDocumentation
4
+ */
5
+ export { createAiSlice, useStoreWithAi } from './AiSlice';
6
+ export { AnalysisResultsContainer } from './components/AnalysisResultsContainer';
7
+ export { AnalysisResult } from './components/AnalysisResult';
8
+ export { useScrollToBottom } from './hooks/useScrollToBottom';
9
+ export { ModelSelector } from './components/ModelSelector';
10
+ export { SessionControls } from './components/SessionControls';
11
+ export { QueryControls } from './components/QueryControls';
12
+ export { DeleteSessionDialog } from './components/session/DeleteSessionDialog';
13
+ export { SessionActions } from './components/session/SessionActions';
14
+ export { SessionDropdown } from './components/session/SessionDropdown';
15
+ export { SessionTitle } from './components/session/SessionTitle';
16
+ export { ToolErrorMessage } from './components/tools/ToolErrorMessage';
17
+ export { AiSliceConfig, createDefaultAiConfig } from '@sqlrooms/ai-config';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,WAAW,CAAC;AAGxD,OAAO,EAAC,wBAAwB,EAAC,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AAG5D,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAC,mBAAmB,EAAC,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAC,eAAe,EAAC,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAC;AAErE,OAAO,EAAC,aAAa,EAAE,qBAAqB,EAAC,MAAM,qBAAqB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {createAiSlice, useStoreWithAi} from './AiSlice';\n\nexport type {AiSliceState} from './AiSlice';\nexport {AnalysisResultsContainer} from './components/AnalysisResultsContainer';\nexport {AnalysisResult} from './components/AnalysisResult';\nexport {useScrollToBottom} from './hooks/useScrollToBottom';\nexport type {AiSliceTool} from './AiSlice';\n\nexport {ModelSelector} from './components/ModelSelector';\nexport {SessionControls} from './components/SessionControls';\nexport {QueryControls} from './components/QueryControls';\nexport {DeleteSessionDialog} from './components/session/DeleteSessionDialog';\nexport {SessionActions} from './components/session/SessionActions';\nexport {SessionDropdown} from './components/session/SessionDropdown';\nexport {SessionTitle} from './components/session/SessionTitle';\nexport type {SessionType} from './components/session/SessionType';\nexport {ToolErrorMessage} from './components/tools/ToolErrorMessage';\n\nexport {AiSliceConfig, createDefaultAiConfig} from '@sqlrooms/ai-config';\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Utility functions for AI Chat UI configuration
3
+ */
4
+ import { AiSettingsSliceConfig } from '@sqlrooms/ai-config';
5
+ /**
6
+ * Extract models from aiSettings in the format expected by ModelSelector
7
+ * @param config - The AI model configuration
8
+ * @returns Array of models with provider, label, and value properties
9
+ */
10
+ export declare function extractModelsFromSettings(config: AiSettingsSliceConfig): Array<{
11
+ provider: string;
12
+ label: string;
13
+ value: string;
14
+ }>;
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,KAAK,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CA4BD"}
package/dist/utils.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Utility functions for AI Chat UI configuration
3
+ */
4
+ /**
5
+ * Extract models from aiSettings in the format expected by ModelSelector
6
+ * @param config - The AI model configuration
7
+ * @returns Array of models with provider, label, and value properties
8
+ */
9
+ export function extractModelsFromSettings(config) {
10
+ const models = [];
11
+ // Extract models from providers
12
+ Object.entries(config.providers).forEach(([providerKey, provider]) => {
13
+ provider.models.forEach((model) => {
14
+ models.push({
15
+ provider: providerKey,
16
+ label: model.modelName,
17
+ value: model.modelName,
18
+ });
19
+ });
20
+ });
21
+ // Add custom models
22
+ config.customModels.forEach((customModel) => {
23
+ models.push({
24
+ provider: 'custom',
25
+ label: customModel.modelName,
26
+ value: customModel.modelName,
27
+ });
28
+ });
29
+ return models;
30
+ }
31
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAA6B;IAM7B,MAAM,MAAM,GAIP,EAAE,CAAC;IAER,gCAAgC;IAChC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QACnE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,KAAK,CAAC,SAAS;gBACtB,KAAK,EAAE,KAAK,CAAC,SAAS;aACvB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,oBAAoB;IACpB,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC;YACV,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,WAAW,CAAC,SAAS;YAC5B,KAAK,EAAE,WAAW,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Utility functions for AI Chat UI configuration\n */\n\nimport {AiSettingsSliceConfig} from '@sqlrooms/ai-config';\n\n/**\n * Extract models from aiSettings in the format expected by ModelSelector\n * @param config - The AI model configuration\n * @returns Array of models with provider, label, and value properties\n */\nexport function extractModelsFromSettings(\n config: AiSettingsSliceConfig,\n): Array<{\n provider: string;\n label: string;\n value: string;\n}> {\n const models: Array<{\n provider: string;\n label: string;\n value: string;\n }> = [];\n\n // Extract models from providers\n Object.entries(config.providers).forEach(([providerKey, provider]) => {\n provider.models.forEach((model) => {\n models.push({\n provider: providerKey,\n label: model.modelName,\n value: model.modelName,\n });\n });\n });\n\n // Add custom models\n config.customModels.forEach((customModel) => {\n models.push({\n provider: 'custom',\n label: customModel.modelName,\n value: customModel.modelName,\n });\n });\n\n return models;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@sqlrooms/ai-core",
3
+ "version": "0.26.0-rc.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "module": "dist/index.js",
7
+ "type": "module",
8
+ "author": "Ilya Boyandin <ilya@boyandin.me>",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/sqlrooms/sqlrooms.git"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "dependencies": {
21
+ "@ai-sdk/provider": "^1.1.3",
22
+ "@openassistant/core": "0.5.17",
23
+ "@openassistant/utils": "0.5.17",
24
+ "@paralleldrive/cuid2": "^2.2.2",
25
+ "@sqlrooms/ai-config": "0.26.0-rc.0",
26
+ "@sqlrooms/monaco-editor": "0.26.0-rc.0",
27
+ "@sqlrooms/room-config": "0.26.0-rc.0",
28
+ "@sqlrooms/room-store": "0.26.0-rc.0",
29
+ "@sqlrooms/ui": "0.26.0-rc.0",
30
+ "@sqlrooms/utils": "0.26.0-rc.0",
31
+ "ai": "^4.3.19",
32
+ "immer": "^10.1.1",
33
+ "lucide-react": "^0.475.0",
34
+ "react-markdown": "^10.1.0",
35
+ "rehype-raw": "^7.0.0",
36
+ "remark-gfm": "^4.0.0",
37
+ "zod": "^3.25.73"
38
+ },
39
+ "peerDependencies": {
40
+ "react": ">=18",
41
+ "react-dom": ">=18"
42
+ },
43
+ "scripts": {
44
+ "dev": "tsc -w",
45
+ "build": "tsc",
46
+ "lint": "eslint .",
47
+ "typecheck": "tsc --noEmit",
48
+ "typedoc": "typedoc"
49
+ },
50
+ "gitHead": "05d355acee6ea65b33b09c6e49d7746ffacb866e"
51
+ }