@sqlrooms/ai-settings 0.27.0-rc.5 → 0.28.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.
|
@@ -74,6 +74,6 @@ export const AiModelParameters = ({ showViewInstructions = false, }) => {
|
|
|
74
74
|
const handleViewFullInstructions = () => {
|
|
75
75
|
onOpen();
|
|
76
76
|
};
|
|
77
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-md flex items-center gap-2 pb-6 font-medium", children: [_jsx(Sliders, { className: "h-4 w-4" }), "Model Parameters"] }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(Wrench, { className: "h-4 w-4" }), "Max Tool Steps"] }), _jsx("div", { className: "flex items-center gap-2", children: _jsx(Input, { type: "number", min: "1", max: "20", step: "1", value: maxSteps, onChange: (e) => handleMaxStepsChange(parseInt(e.target.value) || 1), className: "flex-1" }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(FileText, { className: "h-4 w-4" }), "Additional Instructions"] }), _jsx(Textarea, { value: additionalInstruction, onChange: (e) => handleAdditionalInstructionChange(e.target.value), placeholder: "Enter custom system instructions for the AI model...", className: "min-h-[80px] resize-y", autoResize: false }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: handleUploadButtonClick, className: "flex items-center gap-2", children: [_jsx(Upload, { className: "h-4 w-4" }), "Upload File"] }), showViewInstructions && (_jsxs(Button, { variant: "outline", size: "sm", onClick: handleViewFullInstructions, className: "flex items-center gap-2", children: [_jsx(Eye, { className: "h-4 w-4" }), "View Instructions"] }))] }), _jsx(Input, { ref: fileInputRef, type: "file", accept: ".txt,.md,.json,.text,text/plain,text/markdown,application/json", onChange: handleFileUpload, style: { display: 'none' } })] })] }), _jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: _jsxs(DialogContent, { className: "flex h-[80vh] max-w-4xl flex-col", children: [_jsxs(DialogHeader, { className: "
|
|
77
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-md flex items-center gap-2 pb-6 font-medium", children: [_jsx(Sliders, { className: "h-4 w-4" }), "Model Parameters"] }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(Wrench, { className: "h-4 w-4" }), "Max Tool Steps"] }), _jsx("div", { className: "flex items-center gap-2", children: _jsx(Input, { type: "number", min: "1", max: "20", step: "1", value: maxSteps, onChange: (e) => handleMaxStepsChange(parseInt(e.target.value) || 1), className: "flex-1" }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsx(FileText, { className: "h-4 w-4" }), "Additional Instructions"] }), _jsx(Textarea, { value: additionalInstruction, onChange: (e) => handleAdditionalInstructionChange(e.target.value), placeholder: "Enter custom system instructions for the AI model...", className: "min-h-[80px] resize-y", autoResize: false }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: handleUploadButtonClick, className: "flex items-center gap-2", children: [_jsx(Upload, { className: "h-4 w-4" }), "Upload File"] }), showViewInstructions && (_jsxs(Button, { variant: "outline", size: "sm", onClick: handleViewFullInstructions, className: "flex items-center gap-2", children: [_jsx(Eye, { className: "h-4 w-4" }), "View Instructions"] }))] }), _jsx(Input, { ref: fileInputRef, type: "file", accept: ".txt,.md,.json,.text,text/plain,text/markdown,application/json", onChange: handleFileUpload, style: { display: 'none' } })] })] }), _jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: _jsxs(DialogContent, { className: "flex h-[80vh] max-w-4xl flex-col", children: [_jsxs(DialogHeader, { className: "shrink-0", children: [_jsx(DialogTitle, { children: "Full System Instructions" }), _jsx(DialogDescription, { children: "Complete system instructions that will be sent to the AI model, including default instructions and your additional custom instructions." })] }), _jsx("div", { className: "mt-4 min-h-0 flex-1 overflow-hidden", children: _jsx("div", { className: "bg-muted/50 h-full overflow-auto rounded-lg p-4", children: _jsx("pre", { className: "overflow-wrap-anywhere w-full max-w-full font-mono text-sm leading-relaxed wrap-break-word", children: getFullInstructions() }) }) })] }) })] }));
|
|
78
78
|
};
|
|
79
79
|
//# sourceMappingURL=AiModelParameters.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiModelParameters.js","sourceRoot":"","sources":["../../src/components/AiModelParameters.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useRef} from 'react';\nimport {Sliders, Wrench, FileText, Upload, Eye} from 'lucide-react';\nimport {\n Textarea,\n Input,\n Button,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n useDisclosure,\n useToast,\n} from '@sqlrooms/ui';\nimport {useStoreWithAiSettings} from '../AiSettingsSlice';\n\nexport interface AiModelParametersProps {\n showViewInstructions?: boolean;\n}\n\nexport const AiModelParameters: FC<AiModelParametersProps> = ({\n showViewInstructions = false,\n}) => {\n const maxSteps = useStoreWithAiSettings(\n (s) => s.aiSettings.config.modelParameters.maxSteps,\n );\n const setMaxStepsAiChatUi = useStoreWithAiSettings(\n (s) => s.aiSettings.setMaxSteps,\n );\n\n const additionalInstruction = useStoreWithAiSettings(\n (s) => s.aiSettings.config.modelParameters.additionalInstruction,\n );\n const setAdditionalInstruction = useStoreWithAiSettings(\n (s) => s.aiSettings.setAdditionalInstruction,\n );\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const {toast} = useToast();\n\n const {isOpen, onOpen, onClose} = useDisclosure();\n\n const handleMaxStepsChange = (value: number) => {\n setMaxStepsAiChatUi(value);\n };\n\n const handleAdditionalInstructionChange = (value: string) => {\n setAdditionalInstruction(value);\n };\n\n const getFullInstructions = useStoreWithAiSettings(\n (s) => s.ai.getFullInstructions,\n );\n\n const handleFileUpload = async (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => {\n const file = event.target.files?.[0];\n if (!file) return;\n\n // Validate file type\n const allowedTypes = ['text/plain', 'text/markdown', 'application/json'];\n const allowedExtensions = ['.txt', '.md', '.json', '.text'];\n const fileExtension = file.name\n .toLowerCase()\n .slice(file.name.lastIndexOf('.'));\n\n if (\n !allowedTypes.includes(file.type) &&\n !allowedExtensions.includes(fileExtension)\n ) {\n toast({\n title: 'Invalid file type',\n description: 'Please select a text file (.txt, .md, .json)',\n variant: 'destructive',\n });\n return;\n }\n\n // Validate file size (max 1MB)\n const maxSize = 1024 * 1024; // 1MB\n if (file.size > maxSize) {\n toast({\n title: 'File too large',\n description: 'File size must be less than 1MB',\n variant: 'destructive',\n });\n return;\n }\n\n try {\n const text = await file.text();\n setAdditionalInstruction(text);\n toast({\n title: 'File uploaded successfully',\n description:\n 'System instructions have been updated from the uploaded file.',\n });\n } catch (error) {\n console.error('Error reading file:', error);\n toast({\n title: 'Error reading file',\n description: 'Please try again.',\n variant: 'destructive',\n });\n }\n\n // Reset the input so the same file can be selected again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleUploadButtonClick = () => {\n fileInputRef.current?.click();\n };\n\n const handleViewFullInstructions = () => {\n onOpen();\n };\n\n return (\n <div className=\"space-y-2\">\n <label className=\"text-md flex items-center gap-2 pb-6 font-medium\">\n <Sliders className=\"h-4 w-4\" />\n Model Parameters\n </label>\n <div className=\"grid grid-cols-1 gap-4\">\n {/* Max Steps */}\n <div className=\"space-y-2\">\n <label className=\"flex items-center gap-2 text-sm font-medium\">\n <Wrench className=\"h-4 w-4\" />\n Max Tool Steps\n </label>\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"number\"\n min=\"1\"\n max=\"20\"\n step=\"1\"\n value={maxSteps}\n onChange={(e) =>\n handleMaxStepsChange(parseInt(e.target.value) || 1)\n }\n className=\"flex-1\"\n />\n </div>\n </div>\n\n {/* Additional Instruction */}\n <div className=\"space-y-2\">\n <label className=\"flex items-center gap-2 text-sm font-medium\">\n <FileText className=\"h-4 w-4\" />\n Additional Instructions\n </label>\n <Textarea\n value={additionalInstruction}\n onChange={(e) => handleAdditionalInstructionChange(e.target.value)}\n placeholder=\"Enter custom system instructions for the AI model...\"\n className=\"min-h-[80px] resize-y\"\n autoResize={false}\n />\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleUploadButtonClick}\n className=\"flex items-center gap-2\"\n >\n <Upload className=\"h-4 w-4\" />\n Upload File\n </Button>\n {showViewInstructions && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleViewFullInstructions}\n className=\"flex items-center gap-2\"\n >\n <Eye className=\"h-4 w-4\" />\n View Instructions\n </Button>\n )}\n </div>\n <Input\n ref={fileInputRef}\n type=\"file\"\n accept=\".txt,.md,.json,.text,text/plain,text/markdown,application/json\"\n onChange={handleFileUpload}\n style={{display: 'none'}}\n />\n </div>\n </div>\n\n {/* Full Instructions Modal */}\n <Dialog open={isOpen} onOpenChange={onClose}>\n <DialogContent className=\"flex h-[80vh] max-w-4xl flex-col\">\n <DialogHeader className=\"flex-shrink-0\">\n <DialogTitle>Full System Instructions</DialogTitle>\n <DialogDescription>\n Complete system instructions that will be sent to the AI model,\n including default instructions and your additional custom\n instructions.\n </DialogDescription>\n </DialogHeader>\n <div className=\"mt-4 min-h-0 flex-1 overflow-hidden\">\n <div className=\"bg-muted/50 h-full overflow-auto rounded-lg p-4\">\n <pre className=\"overflow-wrap-anywhere w-full max-w-full break-words font-mono text-sm leading-relaxed\">\n {getFullInstructions()}\n </pre>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"AiModelParameters.js","sourceRoot":"","sources":["../../src/components/AiModelParameters.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useRef} from 'react';\nimport {Sliders, Wrench, FileText, Upload, Eye} from 'lucide-react';\nimport {\n Textarea,\n Input,\n Button,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n useDisclosure,\n useToast,\n} from '@sqlrooms/ui';\nimport {useStoreWithAiSettings} from '../AiSettingsSlice';\n\nexport interface AiModelParametersProps {\n showViewInstructions?: boolean;\n}\n\nexport const AiModelParameters: FC<AiModelParametersProps> = ({\n showViewInstructions = false,\n}) => {\n const maxSteps = useStoreWithAiSettings(\n (s) => s.aiSettings.config.modelParameters.maxSteps,\n );\n const setMaxStepsAiChatUi = useStoreWithAiSettings(\n (s) => s.aiSettings.setMaxSteps,\n );\n\n const additionalInstruction = useStoreWithAiSettings(\n (s) => s.aiSettings.config.modelParameters.additionalInstruction,\n );\n const setAdditionalInstruction = useStoreWithAiSettings(\n (s) => s.aiSettings.setAdditionalInstruction,\n );\n\n const fileInputRef = useRef<HTMLInputElement>(null);\n const {toast} = useToast();\n\n const {isOpen, onOpen, onClose} = useDisclosure();\n\n const handleMaxStepsChange = (value: number) => {\n setMaxStepsAiChatUi(value);\n };\n\n const handleAdditionalInstructionChange = (value: string) => {\n setAdditionalInstruction(value);\n };\n\n const getFullInstructions = useStoreWithAiSettings(\n (s) => s.ai.getFullInstructions,\n );\n\n const handleFileUpload = async (\n event: React.ChangeEvent<HTMLInputElement>,\n ) => {\n const file = event.target.files?.[0];\n if (!file) return;\n\n // Validate file type\n const allowedTypes = ['text/plain', 'text/markdown', 'application/json'];\n const allowedExtensions = ['.txt', '.md', '.json', '.text'];\n const fileExtension = file.name\n .toLowerCase()\n .slice(file.name.lastIndexOf('.'));\n\n if (\n !allowedTypes.includes(file.type) &&\n !allowedExtensions.includes(fileExtension)\n ) {\n toast({\n title: 'Invalid file type',\n description: 'Please select a text file (.txt, .md, .json)',\n variant: 'destructive',\n });\n return;\n }\n\n // Validate file size (max 1MB)\n const maxSize = 1024 * 1024; // 1MB\n if (file.size > maxSize) {\n toast({\n title: 'File too large',\n description: 'File size must be less than 1MB',\n variant: 'destructive',\n });\n return;\n }\n\n try {\n const text = await file.text();\n setAdditionalInstruction(text);\n toast({\n title: 'File uploaded successfully',\n description:\n 'System instructions have been updated from the uploaded file.',\n });\n } catch (error) {\n console.error('Error reading file:', error);\n toast({\n title: 'Error reading file',\n description: 'Please try again.',\n variant: 'destructive',\n });\n }\n\n // Reset the input so the same file can be selected again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleUploadButtonClick = () => {\n fileInputRef.current?.click();\n };\n\n const handleViewFullInstructions = () => {\n onOpen();\n };\n\n return (\n <div className=\"space-y-2\">\n <label className=\"text-md flex items-center gap-2 pb-6 font-medium\">\n <Sliders className=\"h-4 w-4\" />\n Model Parameters\n </label>\n <div className=\"grid grid-cols-1 gap-4\">\n {/* Max Steps */}\n <div className=\"space-y-2\">\n <label className=\"flex items-center gap-2 text-sm font-medium\">\n <Wrench className=\"h-4 w-4\" />\n Max Tool Steps\n </label>\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"number\"\n min=\"1\"\n max=\"20\"\n step=\"1\"\n value={maxSteps}\n onChange={(e) =>\n handleMaxStepsChange(parseInt(e.target.value) || 1)\n }\n className=\"flex-1\"\n />\n </div>\n </div>\n\n {/* Additional Instruction */}\n <div className=\"space-y-2\">\n <label className=\"flex items-center gap-2 text-sm font-medium\">\n <FileText className=\"h-4 w-4\" />\n Additional Instructions\n </label>\n <Textarea\n value={additionalInstruction}\n onChange={(e) => handleAdditionalInstructionChange(e.target.value)}\n placeholder=\"Enter custom system instructions for the AI model...\"\n className=\"min-h-[80px] resize-y\"\n autoResize={false}\n />\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleUploadButtonClick}\n className=\"flex items-center gap-2\"\n >\n <Upload className=\"h-4 w-4\" />\n Upload File\n </Button>\n {showViewInstructions && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleViewFullInstructions}\n className=\"flex items-center gap-2\"\n >\n <Eye className=\"h-4 w-4\" />\n View Instructions\n </Button>\n )}\n </div>\n <Input\n ref={fileInputRef}\n type=\"file\"\n accept=\".txt,.md,.json,.text,text/plain,text/markdown,application/json\"\n onChange={handleFileUpload}\n style={{display: 'none'}}\n />\n </div>\n </div>\n\n {/* Full Instructions Modal */}\n <Dialog open={isOpen} onOpenChange={onClose}>\n <DialogContent className=\"flex h-[80vh] max-w-4xl flex-col\">\n <DialogHeader className=\"shrink-0\">\n <DialogTitle>Full System Instructions</DialogTitle>\n <DialogDescription>\n Complete system instructions that will be sent to the AI model,\n including default instructions and your additional custom\n instructions.\n </DialogDescription>\n </DialogHeader>\n <div className=\"mt-4 min-h-0 flex-1 overflow-hidden\">\n <div className=\"bg-muted/50 h-full overflow-auto rounded-lg p-4\">\n <pre className=\"overflow-wrap-anywhere w-full max-w-full font-mono text-sm leading-relaxed wrap-break-word\">\n {getFullInstructions()}\n </pre>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </div>\n );\n};\n"]}
|
|
@@ -82,7 +82,7 @@ export const AiProvidersSettings = () => {
|
|
|
82
82
|
};
|
|
83
83
|
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "text-md flex items-center gap-2 pb-6 font-medium", children: [_jsx(Cone, { className: "h-4 w-4" }), "Providers"] }), _jsx("div", { className: "space-y-1", children: Object.entries(modelProviders).map(([providerKey, provider]) => {
|
|
84
84
|
const isExpanded = expandedProviders.has(providerKey);
|
|
85
|
-
return (_jsxs("div", { className: "space-y-0 rounded-lg p-0", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { className: "w-20
|
|
86
|
-
}) }), _jsx("div", { className: "flex w-full p-2", children: _jsxs(Button, { onClick: onOpen, variant: "secondary", size: "sm", children: [_jsx(CirclePlus, { className: "h-3 w-3" }), "Add"] }) }), _jsxs(Dialog, { open: isOpen, onOpenChange: (open) => (open ? onOpen() : onClose()), children: [_jsx(DialogTrigger, { asChild: true }), _jsxs(DialogContent, { className: "border-0 p-5", children: [_jsxs(DialogHeader, { className: "mb-1", children: [_jsxs(DialogTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Cone, { className: "h-4 w-4" }), " Add New Provider"] }), _jsx(DialogDescription, { className: "text-xs", children: "Configure a new model provider with API credentials." })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { htmlFor: "new-provider-key", className: "w-20 text-sm", children: "Key" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Cone, { className: "absolute
|
|
85
|
+
return (_jsxs("div", { className: "space-y-0 rounded-lg p-0", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { className: "w-20 shrink-0 text-sm", children: providerKey.charAt(0).toUpperCase() + providerKey.slice(1) }), _jsx(Input, { id: `${providerKey}-apiKey`, type: "password", value: provider.apiKey, onChange: (e) => handleUpdateProvider(providerKey, 'apiKey', e.target.value), placeholder: "Enter API key", className: "flex-1" }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => handleDeleteProvider(providerKey), className: "h-6 h-8 w-6 w-8 p-0 text-gray-500 hover:bg-gray-100 hover:text-gray-700", children: _jsx(Trash2, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => toggleProviderExpanded(providerKey), className: "h-8 w-8 shrink-0", children: _jsx(Settings, { className: "h-4 w-4" }) })] }), isExpanded && (_jsxs("div", { className: "flex items-center gap-3 pt-1", children: [_jsx("div", { className: "w-20 shrink-0" }), ' ', _jsxs("div", { className: "flex flex-1 items-center gap-3", children: [_jsx(Label, { htmlFor: `${providerKey}-baseUrl`, className: "text-muted-foreground shrink-0 text-xs", children: "baseUrl:" }), _jsx(Input, { id: `${providerKey}-baseUrl`, type: "url", value: provider.baseUrl, onChange: (e) => handleUpdateProvider(providerKey, 'baseUrl', e.target.value), placeholder: "Enter base URL", className: "flex-1" })] }), _jsx("div", { className: "w-16 shrink-0" }), ' '] }))] }, providerKey));
|
|
86
|
+
}) }), _jsx("div", { className: "flex w-full p-2", children: _jsxs(Button, { onClick: onOpen, variant: "secondary", size: "sm", children: [_jsx(CirclePlus, { className: "h-3 w-3" }), "Add"] }) }), _jsxs(Dialog, { open: isOpen, onOpenChange: (open) => (open ? onOpen() : onClose()), children: [_jsx(DialogTrigger, { asChild: true }), _jsxs(DialogContent, { className: "border-0 p-5", children: [_jsxs(DialogHeader, { className: "mb-1", children: [_jsxs(DialogTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(Cone, { className: "h-4 w-4" }), " Add New Provider"] }), _jsx(DialogDescription, { className: "text-xs", children: "Configure a new model provider with API credentials." })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { htmlFor: "new-provider-key", className: "w-20 text-sm", children: "Key" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Cone, { className: "absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { id: "new-provider-key", value: newProviderKey, onChange: (e) => setNewProviderKey(e.target.value), placeholder: "e.g., anthropic", className: "pl-8" })] })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { htmlFor: "new-provider-api-key", className: "w-20 text-sm", children: "API Key" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Key, { className: "absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { id: "new-provider-api-key", type: "password", value: newProviderApiKey, onChange: (e) => setNewProviderApiKey(e.target.value), placeholder: "Enter API key", className: "pl-8" })] })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Label, { htmlFor: "new-provider-url", className: "w-20 text-sm", children: "baseUrl" }), _jsxs("div", { className: "relative flex-1", children: [_jsx(Server, { className: "absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { id: "new-provider-url", type: "url", value: newProviderBaseUrl, onChange: (e) => setNewProviderBaseUrl(e.target.value), placeholder: "Enter base URL", className: "pl-8" })] })] }), _jsx("div", { className: "flex justify-end pt-1", children: _jsxs(Button, { size: "sm", onClick: handleAddProvider, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Add Provider"] }) })] })] })] }), _jsx(Dialog, { open: isDeleteOpen, onOpenChange: (open) => (open ? onDeleteOpen() : onDeleteClose()), children: _jsxs(DialogContent, { className: "border-0 p-5", children: [_jsxs(DialogHeader, { className: "mb-1", children: [_jsxs(DialogTitle, { className: "text-destructive flex items-center gap-2 text-base", children: [_jsx(Trash2, { className: "h-4 w-4" }), " Delete Provider"] }), _jsx(DialogDescription, { className: "text-xs", children: "This action cannot be undone. This will permanently delete the provider and all its associated models." })] }), _jsxs("div", { className: "py-2", children: [_jsxs("p", { className: "text-sm", children: ["Are you sure you want to delete the provider", ' ', _jsxs("strong", { children: ["\u201C", providerToDelete?.key, "\u201D"] }), "?"] }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: "All models associated with this provider will also be removed." })] }), _jsxs(DialogFooter, { className: "gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: onDeleteClose, children: "Cancel" }), _jsxs(Button, { variant: "destructive", size: "sm", onClick: confirmDeleteProvider, children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), "Delete Provider"] })] })] }) })] }));
|
|
87
87
|
};
|
|
88
88
|
//# sourceMappingURL=AiProvidersSettings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiProvidersSettings.js","sourceRoot":"","sources":["../../src/components/AiProvidersSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {FC, useState} from 'react';\nimport {\n Button,\n Input,\n Label,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogTrigger,\n DialogFooter,\n useDisclosure,\n useToast,\n} from '@sqlrooms/ui';\nimport {\n Cone,\n Settings,\n Plus,\n Server,\n Key,\n Trash2,\n CirclePlus,\n} from 'lucide-react';\nimport {useStoreWithAiSettings} from '../AiSettingsSlice';\n\nexport const AiProvidersSettings: FC = () => {\n const {toast} = useToast();\n const updateProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.updateProvider,\n );\n const addProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.addProvider,\n );\n const removeProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.removeProvider,\n );\n const providers = useStoreWithAiSettings(\n (state) => state.aiSettings.config.providers,\n );\n const modelProviders = React.useMemo(() => {\n const result: Record<string, {apiKey: string; baseUrl: string}> = {};\n Object.entries(providers).forEach(([key, provider]) => {\n result[key] = {\n apiKey: provider.apiKey,\n baseUrl: provider.baseUrl,\n };\n });\n return result;\n }, [providers]);\n\n const [expandedProviders, setExpandedProviders] = useState<Set<string>>(\n new Set(),\n );\n\n // Dialog state for adding a new provider\n const {isOpen, onOpen, onClose} = useDisclosure();\n const [newProviderKey, setNewProviderKey] = useState('');\n const [newProviderApiKey, setNewProviderApiKey] = useState('');\n const [newProviderBaseUrl, setNewProviderBaseUrl] = useState('');\n\n // Dialog state for delete confirmation\n const {\n isOpen: isDeleteOpen,\n onOpen: onDeleteOpen,\n onClose: onDeleteClose,\n } = useDisclosure();\n const [providerToDelete, setProviderToDelete] = useState<{\n key: string;\n } | null>(null);\n\n const handleAddProvider = () => {\n if (newProviderKey) {\n // Check if provider already exists\n if (providers[newProviderKey]) {\n toast({\n title: 'Provider already exists',\n description: `A provider with the key \"${newProviderKey}\" already exists. Please choose a different key.`,\n variant: 'destructive',\n });\n return;\n }\n\n addProvider(newProviderKey, newProviderBaseUrl, newProviderApiKey);\n setNewProviderKey('');\n setNewProviderApiKey('');\n setNewProviderBaseUrl('');\n onClose();\n\n toast({\n title: 'Provider added successfully',\n description: `Provider \"${newProviderKey}\" has been added.`,\n });\n }\n };\n\n const handleUpdateProvider = (\n providerKey: string,\n field: 'apiKey' | 'baseUrl',\n value: string,\n ) => {\n updateProvider(providerKey, {[field]: value});\n };\n\n const handleDeleteProvider = (providerKey: string) => {\n setProviderToDelete({key: providerKey});\n onDeleteOpen();\n };\n\n const confirmDeleteProvider = () => {\n if (providerToDelete) {\n removeProvider(providerToDelete.key);\n onDeleteClose();\n setProviderToDelete(null);\n\n toast({\n title: 'Provider deleted successfully',\n description: `Provider \"${providerToDelete.key}\" and its associated models have been removed.`,\n });\n }\n };\n\n const toggleProviderExpanded = (providerKey: string) => {\n setExpandedProviders((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(providerKey)) {\n newSet.delete(providerKey);\n } else {\n newSet.add(providerKey);\n }\n return newSet;\n });\n };\n\n return (\n <div className=\"space-y-2\">\n <label className=\"text-md flex items-center gap-2 pb-6 font-medium\">\n <Cone className=\"h-4 w-4\" />\n Providers\n </label>\n\n {/* Existing Providers */}\n <div className=\"space-y-1\">\n {Object.entries(modelProviders).map(([providerKey, provider]) => {\n const isExpanded = expandedProviders.has(providerKey);\n\n return (\n <div key={providerKey} className=\"space-y-0 rounded-lg p-0\">\n {/* First row: Provider name, API key input, delete button, and cogwheel button */}\n <div className=\"flex items-center gap-3\">\n <Label className=\"w-20 flex-shrink-0 text-sm\">\n {providerKey.charAt(0).toUpperCase() + providerKey.slice(1)}\n </Label>\n <Input\n id={`${providerKey}-apiKey`}\n type=\"password\"\n value={provider.apiKey}\n onChange={(e) =>\n handleUpdateProvider(providerKey, 'apiKey', e.target.value)\n }\n placeholder=\"Enter API key\"\n className=\"flex-1\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteProvider(providerKey)}\n className=\"h-6 h-8 w-6 w-8 p-0 text-gray-500 hover:bg-gray-100 hover:text-gray-700\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => toggleProviderExpanded(providerKey)}\n className=\"h-8 w-8 flex-shrink-0\"\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Second row: baseUrl input (toggleable) */}\n {isExpanded && (\n <div className=\"flex items-center gap-3 pt-1\">\n <div className=\"w-20 flex-shrink-0\" />{' '}\n {/* Spacer to align with provider name above */}\n <div className=\"flex flex-1 items-center gap-3\">\n <Label\n htmlFor={`${providerKey}-baseUrl`}\n className=\"text-muted-foreground flex-shrink-0 text-xs\"\n >\n baseUrl:\n </Label>\n <Input\n id={`${providerKey}-baseUrl`}\n type=\"url\"\n value={provider.baseUrl}\n onChange={(e) =>\n handleUpdateProvider(\n providerKey,\n 'baseUrl',\n e.target.value,\n )\n }\n placeholder=\"Enter base URL\"\n className=\"flex-1\"\n />\n </div>\n <div className=\"w-16 flex-shrink-0\" />{' '}\n {/* Spacer to align with delete and cogwheel buttons above */}\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Add New Provider */}\n <div className=\"flex w-full p-2\">\n <Button onClick={onOpen} variant=\"secondary\" size=\"sm\">\n <CirclePlus className=\"h-3 w-3\" />\n Add\n </Button>\n </div>\n\n {/* Add New Provider Dialog */}\n <Dialog\n open={isOpen}\n onOpenChange={(open) => (open ? onOpen() : onClose())}\n >\n <DialogTrigger asChild>\n {/* handled via onOpen button above */}\n </DialogTrigger>\n <DialogContent className=\"border-0 p-5\">\n <DialogHeader className=\"mb-1\">\n <DialogTitle className=\"flex items-center gap-2 text-base\">\n <Cone className=\"h-4 w-4\" /> Add New Provider\n </DialogTitle>\n <DialogDescription className=\"text-xs\">\n Configure a new model provider with API credentials.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-key\" className=\"w-20 text-sm\">\n Key\n </Label>\n <div className=\"relative flex-1\">\n <Cone className=\"absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-key\"\n value={newProviderKey}\n onChange={(e) => setNewProviderKey(e.target.value)}\n placeholder=\"e.g., anthropic\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-api-key\" className=\"w-20 text-sm\">\n API Key\n </Label>\n <div className=\"relative flex-1\">\n <Key className=\"absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-api-key\"\n type=\"password\"\n value={newProviderApiKey}\n onChange={(e) => setNewProviderApiKey(e.target.value)}\n placeholder=\"Enter API key\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-url\" className=\"w-20 text-sm\">\n baseUrl\n </Label>\n <div className=\"relative flex-1\">\n <Server className=\"absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-url\"\n type=\"url\"\n value={newProviderBaseUrl}\n onChange={(e) => setNewProviderBaseUrl(e.target.value)}\n placeholder=\"Enter base URL\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" onClick={handleAddProvider}>\n <Plus className=\"mr-2 h-4 w-4\" /> Add Provider\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n\n {/* Delete Confirmation Dialog */}\n <Dialog\n open={isDeleteOpen}\n onOpenChange={(open) => (open ? onDeleteOpen() : onDeleteClose())}\n >\n <DialogContent className=\"border-0 p-5\">\n <DialogHeader className=\"mb-1\">\n <DialogTitle className=\"text-destructive flex items-center gap-2 text-base\">\n <Trash2 className=\"h-4 w-4\" /> Delete Provider\n </DialogTitle>\n <DialogDescription className=\"text-xs\">\n This action cannot be undone. This will permanently delete the\n provider and all its associated models.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"py-2\">\n <p className=\"text-sm\">\n Are you sure you want to delete the provider{' '}\n <strong>“{providerToDelete?.key}”</strong>?\n </p>\n <p className=\"text-muted-foreground mt-1 text-xs\">\n All models associated with this provider will also be removed.\n </p>\n </div>\n\n <DialogFooter className=\"gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={onDeleteClose}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={confirmDeleteProvider}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete Provider\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"AiProvidersSettings.js","sourceRoot":"","sources":["../../src/components/AiProvidersSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {FC, useState} from 'react';\nimport {\n Button,\n Input,\n Label,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogTrigger,\n DialogFooter,\n useDisclosure,\n useToast,\n} from '@sqlrooms/ui';\nimport {\n Cone,\n Settings,\n Plus,\n Server,\n Key,\n Trash2,\n CirclePlus,\n} from 'lucide-react';\nimport {useStoreWithAiSettings} from '../AiSettingsSlice';\n\nexport const AiProvidersSettings: FC = () => {\n const {toast} = useToast();\n const updateProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.updateProvider,\n );\n const addProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.addProvider,\n );\n const removeProvider = useStoreWithAiSettings(\n (state) => state.aiSettings.removeProvider,\n );\n const providers = useStoreWithAiSettings(\n (state) => state.aiSettings.config.providers,\n );\n const modelProviders = React.useMemo(() => {\n const result: Record<string, {apiKey: string; baseUrl: string}> = {};\n Object.entries(providers).forEach(([key, provider]) => {\n result[key] = {\n apiKey: provider.apiKey,\n baseUrl: provider.baseUrl,\n };\n });\n return result;\n }, [providers]);\n\n const [expandedProviders, setExpandedProviders] = useState<Set<string>>(\n new Set(),\n );\n\n // Dialog state for adding a new provider\n const {isOpen, onOpen, onClose} = useDisclosure();\n const [newProviderKey, setNewProviderKey] = useState('');\n const [newProviderApiKey, setNewProviderApiKey] = useState('');\n const [newProviderBaseUrl, setNewProviderBaseUrl] = useState('');\n\n // Dialog state for delete confirmation\n const {\n isOpen: isDeleteOpen,\n onOpen: onDeleteOpen,\n onClose: onDeleteClose,\n } = useDisclosure();\n const [providerToDelete, setProviderToDelete] = useState<{\n key: string;\n } | null>(null);\n\n const handleAddProvider = () => {\n if (newProviderKey) {\n // Check if provider already exists\n if (providers[newProviderKey]) {\n toast({\n title: 'Provider already exists',\n description: `A provider with the key \"${newProviderKey}\" already exists. Please choose a different key.`,\n variant: 'destructive',\n });\n return;\n }\n\n addProvider(newProviderKey, newProviderBaseUrl, newProviderApiKey);\n setNewProviderKey('');\n setNewProviderApiKey('');\n setNewProviderBaseUrl('');\n onClose();\n\n toast({\n title: 'Provider added successfully',\n description: `Provider \"${newProviderKey}\" has been added.`,\n });\n }\n };\n\n const handleUpdateProvider = (\n providerKey: string,\n field: 'apiKey' | 'baseUrl',\n value: string,\n ) => {\n updateProvider(providerKey, {[field]: value});\n };\n\n const handleDeleteProvider = (providerKey: string) => {\n setProviderToDelete({key: providerKey});\n onDeleteOpen();\n };\n\n const confirmDeleteProvider = () => {\n if (providerToDelete) {\n removeProvider(providerToDelete.key);\n onDeleteClose();\n setProviderToDelete(null);\n\n toast({\n title: 'Provider deleted successfully',\n description: `Provider \"${providerToDelete.key}\" and its associated models have been removed.`,\n });\n }\n };\n\n const toggleProviderExpanded = (providerKey: string) => {\n setExpandedProviders((prev) => {\n const newSet = new Set(prev);\n if (newSet.has(providerKey)) {\n newSet.delete(providerKey);\n } else {\n newSet.add(providerKey);\n }\n return newSet;\n });\n };\n\n return (\n <div className=\"space-y-2\">\n <label className=\"text-md flex items-center gap-2 pb-6 font-medium\">\n <Cone className=\"h-4 w-4\" />\n Providers\n </label>\n\n {/* Existing Providers */}\n <div className=\"space-y-1\">\n {Object.entries(modelProviders).map(([providerKey, provider]) => {\n const isExpanded = expandedProviders.has(providerKey);\n\n return (\n <div key={providerKey} className=\"space-y-0 rounded-lg p-0\">\n {/* First row: Provider name, API key input, delete button, and cogwheel button */}\n <div className=\"flex items-center gap-3\">\n <Label className=\"w-20 shrink-0 text-sm\">\n {providerKey.charAt(0).toUpperCase() + providerKey.slice(1)}\n </Label>\n <Input\n id={`${providerKey}-apiKey`}\n type=\"password\"\n value={provider.apiKey}\n onChange={(e) =>\n handleUpdateProvider(providerKey, 'apiKey', e.target.value)\n }\n placeholder=\"Enter API key\"\n className=\"flex-1\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteProvider(providerKey)}\n className=\"h-6 h-8 w-6 w-8 p-0 text-gray-500 hover:bg-gray-100 hover:text-gray-700\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => toggleProviderExpanded(providerKey)}\n className=\"h-8 w-8 shrink-0\"\n >\n <Settings className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Second row: baseUrl input (toggleable) */}\n {isExpanded && (\n <div className=\"flex items-center gap-3 pt-1\">\n <div className=\"w-20 shrink-0\" />{' '}\n {/* Spacer to align with provider name above */}\n <div className=\"flex flex-1 items-center gap-3\">\n <Label\n htmlFor={`${providerKey}-baseUrl`}\n className=\"text-muted-foreground shrink-0 text-xs\"\n >\n baseUrl:\n </Label>\n <Input\n id={`${providerKey}-baseUrl`}\n type=\"url\"\n value={provider.baseUrl}\n onChange={(e) =>\n handleUpdateProvider(\n providerKey,\n 'baseUrl',\n e.target.value,\n )\n }\n placeholder=\"Enter base URL\"\n className=\"flex-1\"\n />\n </div>\n <div className=\"w-16 shrink-0\" />{' '}\n {/* Spacer to align with delete and cogwheel buttons above */}\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Add New Provider */}\n <div className=\"flex w-full p-2\">\n <Button onClick={onOpen} variant=\"secondary\" size=\"sm\">\n <CirclePlus className=\"h-3 w-3\" />\n Add\n </Button>\n </div>\n\n {/* Add New Provider Dialog */}\n <Dialog\n open={isOpen}\n onOpenChange={(open) => (open ? onOpen() : onClose())}\n >\n <DialogTrigger asChild>\n {/* handled via onOpen button above */}\n </DialogTrigger>\n <DialogContent className=\"border-0 p-5\">\n <DialogHeader className=\"mb-1\">\n <DialogTitle className=\"flex items-center gap-2 text-base\">\n <Cone className=\"h-4 w-4\" /> Add New Provider\n </DialogTitle>\n <DialogDescription className=\"text-xs\">\n Configure a new model provider with API credentials.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-key\" className=\"w-20 text-sm\">\n Key\n </Label>\n <div className=\"relative flex-1\">\n <Cone className=\"absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-key\"\n value={newProviderKey}\n onChange={(e) => setNewProviderKey(e.target.value)}\n placeholder=\"e.g., anthropic\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-api-key\" className=\"w-20 text-sm\">\n API Key\n </Label>\n <div className=\"relative flex-1\">\n <Key className=\"absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-api-key\"\n type=\"password\"\n value={newProviderApiKey}\n onChange={(e) => setNewProviderApiKey(e.target.value)}\n placeholder=\"Enter API key\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Label htmlFor=\"new-provider-url\" className=\"w-20 text-sm\">\n baseUrl\n </Label>\n <div className=\"relative flex-1\">\n <Server className=\"absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2\" />\n <Input\n id=\"new-provider-url\"\n type=\"url\"\n value={newProviderBaseUrl}\n onChange={(e) => setNewProviderBaseUrl(e.target.value)}\n placeholder=\"Enter base URL\"\n className=\"pl-8\"\n />\n </div>\n </div>\n\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" onClick={handleAddProvider}>\n <Plus className=\"mr-2 h-4 w-4\" /> Add Provider\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n\n {/* Delete Confirmation Dialog */}\n <Dialog\n open={isDeleteOpen}\n onOpenChange={(open) => (open ? onDeleteOpen() : onDeleteClose())}\n >\n <DialogContent className=\"border-0 p-5\">\n <DialogHeader className=\"mb-1\">\n <DialogTitle className=\"text-destructive flex items-center gap-2 text-base\">\n <Trash2 className=\"h-4 w-4\" /> Delete Provider\n </DialogTitle>\n <DialogDescription className=\"text-xs\">\n This action cannot be undone. This will permanently delete the\n provider and all its associated models.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"py-2\">\n <p className=\"text-sm\">\n Are you sure you want to delete the provider{' '}\n <strong>“{providerToDelete?.key}”</strong>?\n </p>\n <p className=\"text-muted-foreground mt-1 text-xs\">\n All models associated with this provider will also be removed.\n </p>\n </div>\n\n <DialogFooter className=\"gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={onDeleteClose}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={confirmDeleteProvider}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n Delete Provider\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/ai-settings",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0-rc.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@sqlrooms/ai-config": "0.
|
|
23
|
-
"@sqlrooms/ai-core": "0.
|
|
24
|
-
"@sqlrooms/recharts": "0.
|
|
25
|
-
"@sqlrooms/room-store": "0.
|
|
26
|
-
"@sqlrooms/ui": "0.
|
|
22
|
+
"@sqlrooms/ai-config": "0.28.0-rc.0",
|
|
23
|
+
"@sqlrooms/ai-core": "0.28.0-rc.0",
|
|
24
|
+
"@sqlrooms/recharts": "0.28.0-rc.0",
|
|
25
|
+
"@sqlrooms/room-store": "0.28.0-rc.0",
|
|
26
|
+
"@sqlrooms/ui": "0.28.0-rc.0",
|
|
27
27
|
"immer": "^11.0.1",
|
|
28
28
|
"lucide-react": "^0.556.0",
|
|
29
29
|
"recharts": "^2.12.7"
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit",
|
|
40
40
|
"typedoc": "typedoc"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "87a478edbff690e04c38cc717db8e11e844565c8"
|
|
43
43
|
}
|