@sqlrooms/ai-core 0.27.0-rc.5 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AnalysisAnswer.d.ts.map +1 -1
- package/dist/components/AnalysisAnswer.js +13 -9
- package/dist/components/AnalysisAnswer.js.map +1 -1
- package/dist/components/AnalysisResult.d.ts.map +1 -1
- package/dist/components/AnalysisResult.js +1 -1
- package/dist/components/AnalysisResult.js.map +1 -1
- package/dist/components/MessageContainer.d.ts +2 -0
- package/dist/components/MessageContainer.d.ts.map +1 -1
- package/dist/components/MessageContainer.js +3 -3
- package/dist/components/MessageContainer.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAiB,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAKpD,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAChD,CAAC;AAgHF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDAoFzB,CAAC"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
2
|
+
import { cn, CopyButton } from '@sqlrooms/ui';
|
|
3
|
+
import { truncate } from '@sqlrooms/utils';
|
|
4
|
+
import { BrainIcon } from 'lucide-react';
|
|
5
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
3
6
|
import Markdown from 'react-markdown';
|
|
4
|
-
import remarkGfm from 'remark-gfm';
|
|
5
7
|
import rehypeRaw from 'rehype-raw';
|
|
6
|
-
import
|
|
8
|
+
import remarkGfm from 'remark-gfm';
|
|
7
9
|
import { MessageContainer } from './MessageContainer';
|
|
8
|
-
import { BrainIcon } from 'lucide-react';
|
|
9
|
-
import { cn } from '@sqlrooms/ui';
|
|
10
10
|
// Constants moved outside component to prevent recreation
|
|
11
11
|
const THINK_WORD_LIMIT = 10;
|
|
12
12
|
const COMPLETE_THINK_REGEX = /<think>([\s\S]*?)<\/think>/g;
|
|
13
13
|
const INCOMPLETE_THINK_REGEX = /<think>([\s\S]*)$/;
|
|
14
|
+
const sanitizeThinkTags = (value) => value.replace(COMPLETE_THINK_REGEX, '').replace(INCOMPLETE_THINK_REGEX, '');
|
|
14
15
|
/**
|
|
15
16
|
* Processes content and extracts think content in one pass
|
|
16
17
|
*/
|
|
@@ -64,6 +65,8 @@ ThinkBlock.displayName = 'ThinkBlock';
|
|
|
64
65
|
export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
|
|
65
66
|
const { content, isAnswer, customMarkdownComponents } = props;
|
|
66
67
|
const [expandedThink, setExpandedThink] = useState(new Set());
|
|
68
|
+
const copyableText = useMemo(() => sanitizeThinkTags(content), [content]);
|
|
69
|
+
const hasTextContent = copyableText.trim().length > 0;
|
|
67
70
|
const toggleThinkExpansion = useCallback((content) => {
|
|
68
71
|
setExpandedThink((prev) => {
|
|
69
72
|
const newExpanded = new Set(prev);
|
|
@@ -78,6 +81,7 @@ export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
|
|
|
78
81
|
}, []);
|
|
79
82
|
// Memoize content processing to avoid recalculation on every render
|
|
80
83
|
const { processedContent, thinkContents } = useMemo(() => processContent(content), [content]);
|
|
84
|
+
const footerActions = hasTextContent ? (_jsx(CopyButton, { text: copyableText, tooltipLabel: isAnswer ? 'Copy response' : 'Copy message' })) : null;
|
|
81
85
|
// Memoize the think-block component to prevent unnecessary re-renders
|
|
82
86
|
const thinkBlockComponent = useCallback((thinkBlock) => {
|
|
83
87
|
try {
|
|
@@ -95,9 +99,9 @@ export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
|
|
|
95
99
|
return null;
|
|
96
100
|
}
|
|
97
101
|
}, [thinkContents, expandedThink, toggleThinkExpansion]);
|
|
98
|
-
return (_jsx(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
return (_jsx(MessageContainer, { isSuccess: true, type: isAnswer ? 'answer' : 'thinking', content: { content, isAnswer }, footerActions: footerActions, children: _jsx("div", { className: "prose dark:prose-invert max-w-none text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeRaw], components: {
|
|
103
|
+
'think-block': thinkBlockComponent,
|
|
104
|
+
...customMarkdownComponents,
|
|
105
|
+
}, children: processedContent }) }) }));
|
|
102
106
|
});
|
|
103
107
|
//# sourceMappingURL=AnalysisAnswer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useState, useCallback, useMemo} from 'react';\nimport Markdown, {Components} from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\nimport {truncate} from '@sqlrooms/utils';\nimport {MessageContainer} from './MessageContainer';\nimport {BrainIcon} from 'lucide-react';\nimport {cn} from '@sqlrooms/ui';\n\ntype AnalysisAnswerProps = {\n content: string;\n isAnswer: boolean;\n customMarkdownComponents?: Partial<Components>;\n};\n\ntype ThinkContent = {\n content: string;\n isComplete: boolean;\n index: number;\n};\n\n// Constants moved outside component to prevent recreation\nconst THINK_WORD_LIMIT = 10;\nconst COMPLETE_THINK_REGEX = /<think>([\\s\\S]*?)<\\/think>/g;\nconst INCOMPLETE_THINK_REGEX = /<think>([\\s\\S]*)$/;\n\n/**\n * Processes content and extracts think content in one pass\n */\nconst processContent = (\n originalContent: string,\n): {\n processedContent: string;\n thinkContents: ThinkContent[];\n} => {\n const thinkContents: ThinkContent[] = [];\n let processedContent = originalContent;\n let index = 0;\n\n // Replace complete think tags\n processedContent = processedContent.replace(\n COMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: true,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n // Replace incomplete think tags (no closing tag)\n processedContent = processedContent.replace(\n INCOMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: false,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n return {processedContent, thinkContents};\n};\n\n/**\n * ThinkBlock component for rendering individual think blocks\n */\nconst ThinkBlock = React.memo<{\n className?: string;\n thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion, className}) => {\n const {content, isComplete, index} = thinkContent;\n\n const displayText =\n isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;\n const needsTruncation =\n isComplete && content.split(' ').length > THINK_WORD_LIMIT;\n\n return (\n <span\n key={`think-${index}`}\n className={cn(\n 'inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400',\n isExpanded && 'bg-gray-50 dark:bg-gray-800/50',\n className,\n )}\n >\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <BrainIcon\n className=\"mb-1 inline-block opacity-60 grayscale\"\n size={12}\n />{' '}\n {displayText}\n </span>\n </span>{' '}\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300\"\n >\n {isExpanded ? 'Show less' : 'Show more thinking'}\n </button>\n )}\n </span>\n );\n});\n\nThinkBlock.displayName = 'ThinkBlock';\n\n/**\n * Renders an analysis answer with markdown content of the final streaming response.\n * Supports streaming think content that may arrive in chunks (e.g., \"<think>Hello\" before \"</think>\").\n *\n * @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.\n * @returns {JSX.Element} The rendered answer tool call\n */\nexport const AnalysisAnswer = React.memo(function AnalysisAnswer(\n props: AnalysisAnswerProps,\n) {\n const {content, isAnswer, customMarkdownComponents} = props;\n const [expandedThink, setExpandedThink] = useState<Set<string>>(new Set());\n\n const toggleThinkExpansion = useCallback((content: string) => {\n setExpandedThink((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(content)) {\n newExpanded.delete(content);\n } else {\n newExpanded.add(content);\n }\n return newExpanded;\n });\n }, []);\n\n // Memoize content processing to avoid recalculation on every render\n const {processedContent, thinkContents} = useMemo(\n () => processContent(content),\n [content],\n );\n\n // Memoize the think-block component to prevent unnecessary re-renders\n const thinkBlockComponent = useCallback(\n (thinkBlock: any) => {\n try {\n const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);\n const thinkContent = thinkContents[index];\n\n if (!thinkContent) {\n console.warn(`Think content not found for index: ${index}`);\n return null;\n }\n\n const isExpanded = expandedThink.has(thinkContent.content);\n\n return (\n <ThinkBlock\n thinkContent={thinkContent}\n isExpanded={isExpanded}\n onToggleExpansion={toggleThinkExpansion}\n />\n );\n } catch (error) {\n console.error('Error rendering think block:', error);\n return null;\n }\n },\n [thinkContents, expandedThink, toggleThinkExpansion],\n );\n\n return (\n <div className=\"flex flex-col gap-5\">\n <MessageContainer\n isSuccess={true}\n type={isAnswer ? 'answer' : 'thinking'}\n content={{content, isAnswer}}\n >\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={\n {\n 'think-block': thinkBlockComponent,\n ...customMarkdownComponents,\n } as Partial<Components>\n }\n >\n {processedContent}\n </Markdown>\n </div>\n </MessageContainer>\n </div>\n );\n});\n"]}
|
|
1
|
+
{"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {cn, CopyButton} from '@sqlrooms/ui';\nimport {truncate} from '@sqlrooms/utils';\nimport {BrainIcon} from 'lucide-react';\nimport React, {useCallback, useMemo, useState} from 'react';\nimport Markdown, {Components} from 'react-markdown';\nimport rehypeRaw from 'rehype-raw';\nimport remarkGfm from 'remark-gfm';\nimport {MessageContainer} from './MessageContainer';\n\ntype AnalysisAnswerProps = {\n content: string;\n isAnswer: boolean;\n customMarkdownComponents?: Partial<Components>;\n};\n\ntype ThinkContent = {\n content: string;\n isComplete: boolean;\n index: number;\n};\n\n// Constants moved outside component to prevent recreation\nconst THINK_WORD_LIMIT = 10;\nconst COMPLETE_THINK_REGEX = /<think>([\\s\\S]*?)<\\/think>/g;\nconst INCOMPLETE_THINK_REGEX = /<think>([\\s\\S]*)$/;\n\nconst sanitizeThinkTags = (value: string): string =>\n value.replace(COMPLETE_THINK_REGEX, '').replace(INCOMPLETE_THINK_REGEX, '');\n\n/**\n * Processes content and extracts think content in one pass\n */\nconst processContent = (\n originalContent: string,\n): {\n processedContent: string;\n thinkContents: ThinkContent[];\n} => {\n const thinkContents: ThinkContent[] = [];\n let processedContent = originalContent;\n let index = 0;\n\n // Replace complete think tags\n processedContent = processedContent.replace(\n COMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: true,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n // Replace incomplete think tags (no closing tag)\n processedContent = processedContent.replace(\n INCOMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: false,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n return {processedContent, thinkContents};\n};\n\n/**\n * ThinkBlock component for rendering individual think blocks\n */\nconst ThinkBlock = React.memo<{\n className?: string;\n thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion, className}) => {\n const {content, isComplete, index} = thinkContent;\n\n const displayText =\n isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;\n const needsTruncation =\n isComplete && content.split(' ').length > THINK_WORD_LIMIT;\n\n return (\n <span\n key={`think-${index}`}\n className={cn(\n 'inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400',\n isExpanded && 'bg-gray-50 dark:bg-gray-800/50',\n className,\n )}\n >\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <BrainIcon\n className=\"mb-1 inline-block opacity-60 grayscale\"\n size={12}\n />{' '}\n {displayText}\n </span>\n </span>{' '}\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300\"\n >\n {isExpanded ? 'Show less' : 'Show more thinking'}\n </button>\n )}\n </span>\n );\n});\n\nThinkBlock.displayName = 'ThinkBlock';\n\n/**\n * Renders an analysis answer with markdown content of the final streaming response.\n * Supports streaming think content that may arrive in chunks (e.g., \"<think>Hello\" before \"</think>\").\n *\n * @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.\n * @returns {JSX.Element} The rendered answer tool call\n */\nexport const AnalysisAnswer = React.memo(function AnalysisAnswer(\n props: AnalysisAnswerProps,\n) {\n const {content, isAnswer, customMarkdownComponents} = props;\n const [expandedThink, setExpandedThink] = useState<Set<string>>(new Set());\n const copyableText = useMemo(() => sanitizeThinkTags(content), [content]);\n const hasTextContent = copyableText.trim().length > 0;\n\n const toggleThinkExpansion = useCallback((content: string) => {\n setExpandedThink((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(content)) {\n newExpanded.delete(content);\n } else {\n newExpanded.add(content);\n }\n return newExpanded;\n });\n }, []);\n\n // Memoize content processing to avoid recalculation on every render\n const {processedContent, thinkContents} = useMemo(\n () => processContent(content),\n [content],\n );\n const footerActions = hasTextContent ? (\n <CopyButton\n text={copyableText}\n tooltipLabel={isAnswer ? 'Copy response' : 'Copy message'}\n />\n ) : null;\n\n // Memoize the think-block component to prevent unnecessary re-renders\n const thinkBlockComponent = useCallback(\n (thinkBlock: any) => {\n try {\n const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);\n const thinkContent = thinkContents[index];\n\n if (!thinkContent) {\n console.warn(`Think content not found for index: ${index}`);\n return null;\n }\n\n const isExpanded = expandedThink.has(thinkContent.content);\n\n return (\n <ThinkBlock\n thinkContent={thinkContent}\n isExpanded={isExpanded}\n onToggleExpansion={toggleThinkExpansion}\n />\n );\n } catch (error) {\n console.error('Error rendering think block:', error);\n return null;\n }\n },\n [thinkContents, expandedThink, toggleThinkExpansion],\n );\n\n return (\n <MessageContainer\n isSuccess={true}\n type={isAnswer ? 'answer' : 'thinking'}\n content={{content, isAnswer}}\n footerActions={footerActions}\n >\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={\n {\n 'think-block': thinkBlockComponent,\n ...customMarkdownComponents,\n } as Partial<Components>\n }\n >\n {processedContent}\n </Markdown>\n </div>\n </MessageContainer>\n );\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResult.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAKzD,OAAO,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAI1C,OAAO,EAAe,KAAK,0BAA0B,EAAC,MAAM,gBAAgB,CAAC;AAI7E;;;;;;GAMG;AACH,KAAK,mBAAmB,GAAG;IACzB,cAAc,EAAE,oBAAoB,CAAC;IACrC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qBAAqB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC;CACzE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"AnalysisResult.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAKzD,OAAO,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAI1C,OAAO,EAAe,KAAK,0BAA0B,EAAC,MAAM,gBAAgB,CAAC;AAI7E;;;;;;GAMG;AACH,KAAK,mBAAmB,GAAG;IACzB,cAAc,EAAE,oBAAoB,CAAC;IACrC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qBAAqB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC;CACzE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA8FxD,CAAC"}
|
|
@@ -45,7 +45,7 @@ export const AnalysisResult = ({ analysisResult, enableReasoningBox = false, cus
|
|
|
45
45
|
}, []);
|
|
46
46
|
// Group consecutive tool parts together for rendering in ReasoningBox (only if enabled)
|
|
47
47
|
const groupedParts = useToolGrouping(uiMessageParts, divWidth, userTools, toolAdditionalData);
|
|
48
|
-
return (_jsxs("div", { className: "group flex w-full flex-col gap-2 pb-2 text-sm", children: [_jsx("div", { className: "mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100", children: _jsxs("div", { className: "bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm", children: [_jsx(SquareTerminalIcon, { className: "h-4 w-4" }), _jsx("div", { className: "flex-1", children: analysisResult.prompt }), _jsx("div", { className: "flex gap-2 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx(CopyButton, { text: analysisResult.prompt,
|
|
48
|
+
return (_jsxs("div", { className: "group flex w-full flex-col gap-2 pb-2 text-sm", children: [_jsx("div", { className: "mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100", children: _jsxs("div", { className: "group/prompt bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm", children: [_jsx(SquareTerminalIcon, { className: "h-4 w-4" }), _jsx("div", { className: "flex-1", children: analysisResult.prompt }), _jsx("div", { className: "flex gap-2 opacity-0 transition-opacity group-focus-within/prompt:opacity-100 group-hover/prompt:opacity-100", children: _jsx(CopyButton, { text: analysisResult.prompt, tooltipLabel: "Copy message" }) })] }) }), _jsxs("div", { ref: divRef, className: "flex w-full flex-col gap-4", children: [enableReasoningBox ? (_jsx(GroupedMessageParts, { groupedParts: groupedParts, totalPartsCount: uiMessageParts.length, toolAdditionalData: toolAdditionalData, customMarkdownComponents: customMarkdownComponents })) : (_jsx(MessagePartsList, { parts: uiMessageParts, toolAdditionalData: toolAdditionalData, customMarkdownComponents: customMarkdownComponents })), analysisResult.errorMessage &&
|
|
49
49
|
(ErrorMessageComponent ? (_jsx(ErrorMessageComponent, { errorMessage: analysisResult.errorMessage.error })) : (_jsx(ErrorMessage, { errorMessage: analysisResult.errorMessage.error })))] })] }));
|
|
50
50
|
};
|
|
51
51
|
//# sourceMappingURL=AnalysisResult.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResult.js","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC,OAAO,EAAC,kBAAkB,EAAC,MAAM,cAAc,CAAC;AAChD,OAAO,EAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAElD,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAC,wBAAwB,EAAC,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAC,YAAY,EAAkC,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAiBpD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkC,CAAC,EAC5D,cAAc,EACd,kBAAkB,GAAG,KAAK,EAC1B,wBAAwB,EACxB,mBAAmB,EAAE,SAAS,EAC9B,qBAAqB,GACtB,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,cAAc,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,EAAE,EAAE,UAAqC,CACvE,CAAC;IACF,MAAM,kBAAkB,GAAG,cAAc,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,EAAE,EAAE,kBAAkB,IAAI,EAAE,CAC1D,CAAC;IACF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAE5C,MAAM,cAAc,GAAG,wBAAwB,CAC7C,UAAU,EACV,cAAc,CAAC,EAAE,CAClB,CAAC;IAEF,yCAAyC;IACzC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,gCAAgC;QAChC,WAAW,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE;YACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,uEAAuE;gBACvE,MAAM,KAAK,GACT,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC;gBAClE,WAAW,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEhC,OAAO,GAAG,EAAE;YACV,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,wFAAwF;IACxF,MAAM,YAAY,GAAG,eAAe,CAClC,cAAc,EACd,QAAQ,EACR,SAAS,EACT,kBAAkB,CACnB,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,+CAA+C,aAC5D,cAAK,SAAS,EAAC,0EAA0E,YACvF,eAAK,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"AnalysisResult.js","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"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","sourcesContent":["import {AnalysisResultSchema} from '@sqlrooms/ai-config';\nimport {CopyButton} from '@sqlrooms/ui';\nimport type {UIMessage} from 'ai';\nimport {SquareTerminalIcon} from 'lucide-react';\nimport {useEffect, useRef, useState} from 'react';\nimport {Components} from 'react-markdown';\nimport {useStoreWithAi} from '../AiSlice';\nimport {useAssistantMessageParts} from '../hooks/useAssistantMessageParts';\nimport {useToolGrouping} from '../hooks/useToolGrouping';\nimport {ErrorMessage, type ErrorMessageComponentProps} from './ErrorMessage';\nimport {GroupedMessageParts} from './GroupedMessageParts';\nimport {MessagePartsList} from './MessagePartsList';\n\n/**\n * Props for the AnalysisResult component\n * @property {AnalysisResultSchema} result - The result of the analysis containing prompt, tool calls, and analysis data\n * @property {boolean} enableReasoningBox - Whether to group consecutive tool parts into a collapsible ReasoningBox\n * @property {Partial<Components>} customMarkdownComponents - Optional custom components for markdown rendering\n * @property {string[]} userTools - Array of tool names that should not be grouped and must be rendered separately\n */\ntype AnalysisResultProps = {\n analysisResult: AnalysisResultSchema;\n enableReasoningBox?: boolean;\n customMarkdownComponents?: Partial<Components>;\n excludeFromGrouping?: string[];\n ErrorMessageComponent?: React.ComponentType<ErrorMessageComponentProps>;\n};\n\n/**\n * Component that displays the results of an AI analysis.\n * Shows the original prompt, intermediate tool calls, final analysis text,\n * and any tool results.\n *\n * @component\n * @param props - Component props\n * @param props.result - The analysis result data to display\n * @returns A React component displaying the analysis results\n */\nexport const AnalysisResult: React.FC<AnalysisResultProps> = ({\n analysisResult,\n enableReasoningBox = false,\n customMarkdownComponents,\n excludeFromGrouping: userTools,\n ErrorMessageComponent,\n}) => {\n const uiMessages = useStoreWithAi(\n (s) => s.ai.getCurrentSession()?.uiMessages as UIMessage[] | undefined,\n );\n const toolAdditionalData = useStoreWithAi(\n (s) => s.ai.getCurrentSession()?.toolAdditionalData || {},\n );\n const [divWidth, setDivWidth] = useState<number>(0);\n const divRef = useRef<HTMLDivElement>(null);\n\n const uiMessageParts = useAssistantMessageParts(\n uiMessages,\n analysisResult.id,\n );\n\n // Measure div width using ResizeObserver\n useEffect(() => {\n const element = divRef.current;\n if (!element) return;\n\n // Set initial width immediately\n setDivWidth(element.getBoundingClientRect().width);\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n // Use borderBoxSize if available (modern API), fallback to contentRect\n const width =\n entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n setDivWidth(width);\n }\n });\n\n resizeObserver.observe(element);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, []);\n\n // Group consecutive tool parts together for rendering in ReasoningBox (only if enabled)\n const groupedParts = useToolGrouping(\n uiMessageParts,\n divWidth,\n userTools,\n toolAdditionalData,\n );\n\n return (\n <div className=\"group flex w-full flex-col gap-2 pb-2 text-sm\">\n <div className=\"mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100\">\n <div className=\"group/prompt bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm\">\n <SquareTerminalIcon className=\"h-4 w-4\" />\n {/** render prompt */}\n <div className=\"flex-1\">{analysisResult.prompt}</div>\n <div className=\"flex gap-2 opacity-0 transition-opacity group-focus-within/prompt:opacity-100 group-hover/prompt:opacity-100\">\n <CopyButton\n text={analysisResult.prompt}\n tooltipLabel=\"Copy message\"\n />\n </div>\n </div>\n </div>\n <div ref={divRef} className=\"flex w-full flex-col gap-4\">\n {enableReasoningBox ? (\n <GroupedMessageParts\n groupedParts={groupedParts}\n totalPartsCount={uiMessageParts.length}\n toolAdditionalData={toolAdditionalData}\n customMarkdownComponents={customMarkdownComponents}\n />\n ) : (\n <MessagePartsList\n parts={uiMessageParts}\n toolAdditionalData={toolAdditionalData}\n customMarkdownComponents={customMarkdownComponents}\n />\n )}\n {analysisResult.errorMessage &&\n (ErrorMessageComponent ? (\n <ErrorMessageComponent\n errorMessage={analysisResult.errorMessage.error}\n />\n ) : (\n <ErrorMessage errorMessage={analysisResult.errorMessage.error} />\n ))}\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageContainer.d.ts","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MessageContainer.d.ts","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":"AAGA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAkD5D,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Badge, cn
|
|
2
|
+
import { Badge, cn } from '@sqlrooms/ui';
|
|
3
3
|
import { XCircleIcon } from 'lucide-react';
|
|
4
4
|
export const MessageContainer = ({ className, type,
|
|
5
5
|
// borderColor,
|
|
6
|
-
content, children, }) => {
|
|
7
|
-
return (_jsxs("div", { className: cn('group relative px-5 py-2 text-xs', className, type === 'error' && 'border-destructive rounded-md border py-4'), children: [type === 'error' && (_jsxs(Badge, { variant: "secondary", className: cn('absolute top-[-12px]
|
|
6
|
+
content, children, footerActions, footerActionsClassName, }) => {
|
|
7
|
+
return (_jsxs("div", { className: cn('group relative px-5 py-2 text-xs', className, type === 'error' && 'border-destructive rounded-md border py-4'), children: [type === 'error' && (_jsxs(Badge, { variant: "secondary", className: cn('absolute left-2 top-[-12px] flex items-center gap-1 border text-xs', 'border-destructive bg-background'), children: [_jsx(XCircleIcon, { className: "h-3 w-3 text-red-500" }), type ? type.replace(/^\w/, (c) => c.toUpperCase()) : ''] })), _jsx("div", { className: "flex flex-col gap-5", children: children }), footerActions && (_jsx("div", { className: cn('mt-2 flex items-center justify-end gap-1 pt-1 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100', footerActionsClassName), children: footerActions }))] }));
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=MessageContainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageContainer.js","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"MessageContainer.js","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,KAAK,EAAE,EAAE,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAazC,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,EACT,IAAI;AACJ,eAAe;AACf,OAAO,EACP,QAAQ,EACR,aAAa,EACb,sBAAsB,GACvB,EAAE,EAAE;IACH,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,kCAAkC,EAClC,SAAS,EACT,IAAI,KAAK,OAAO,IAAI,2CAA2C,CAGhE,aAEA,IAAI,KAAK,OAAO,IAAI,CACnB,MAAC,KAAK,IACJ,OAAO,EAAC,WAAW,EACnB,SAAS,EAAE,EAAE,CACX,oEAAoE,EACpE,kCAAkC,CAEnC,aAKD,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAE/C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAClD,CACT,EAED,cAAK,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAO,EACpD,aAAa,IAAI,CAChB,cACE,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,sBAAsB,CACvB,YAEA,aAAa,GACV,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Badge, cn} from '@sqlrooms/ui';\nimport {XCircleIcon} from 'lucide-react';\n\ntype MessageContainerProps = {\n className?: string;\n isSuccess: boolean;\n // borderColor: string;\n type: string;\n content: object;\n children: React.ReactNode;\n footerActions?: React.ReactNode;\n footerActionsClassName?: string;\n};\n\nexport const MessageContainer: React.FC<MessageContainerProps> = ({\n className,\n type,\n // borderColor,\n content,\n children,\n footerActions,\n footerActionsClassName,\n}) => {\n return (\n <div\n className={cn(\n 'group relative px-5 py-2 text-xs',\n className,\n type === 'error' && 'border-destructive rounded-md border py-4',\n // borderColor,\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {type === 'error' && (\n <Badge\n variant=\"secondary\"\n className={cn(\n 'absolute left-2 top-[-12px] flex items-center gap-1 border text-xs',\n 'border-destructive bg-background',\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {/* {isSuccess ? ( */}\n {/* <CheckCircle2Icon className=\"h-3 w-3 text-green-500\" /> */}\n {/* ) : ( */}\n <XCircleIcon className=\"h-3 w-3 text-red-500\" />\n {/* )} */}\n {type ? type.replace(/^\\w/, (c) => c.toUpperCase()) : ''}\n </Badge>\n )}\n\n <div className=\"flex flex-col gap-5\">{children}</div>\n {footerActions && (\n <div\n className={cn(\n 'mt-2 flex items-center justify-end gap-1 pt-1 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100',\n footerActionsClassName,\n )}\n >\n {footerActions}\n </div>\n )}\n </div>\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/ai-core",
|
|
3
|
-
"version": "0.27.0
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"@ai-sdk/react": "^2.0.44",
|
|
24
24
|
"@openassistant/utils": "1.0.0-alpha.0",
|
|
25
25
|
"@paralleldrive/cuid2": "^3.0.0",
|
|
26
|
-
"@sqlrooms/ai-config": "0.27.0
|
|
27
|
-
"@sqlrooms/monaco-editor": "0.27.0
|
|
28
|
-
"@sqlrooms/room-store": "0.27.0
|
|
29
|
-
"@sqlrooms/ui": "0.27.0
|
|
30
|
-
"@sqlrooms/utils": "0.27.0
|
|
26
|
+
"@sqlrooms/ai-config": "0.27.0",
|
|
27
|
+
"@sqlrooms/monaco-editor": "0.27.0",
|
|
28
|
+
"@sqlrooms/room-store": "0.27.0",
|
|
29
|
+
"@sqlrooms/ui": "0.27.0",
|
|
30
|
+
"@sqlrooms/utils": "0.27.0",
|
|
31
31
|
"ai": "^5.0.44",
|
|
32
32
|
"immer": "^11.0.1",
|
|
33
33
|
"lucide-react": "^0.556.0",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit",
|
|
48
48
|
"typedoc": "typedoc"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "f215995ab4adeac4c58171739261a15cbba9e82b"
|
|
51
51
|
}
|