@rolder/kit 3.0.0-alpha.21 → 3.0.0-alpha.24
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/ai/ui/{conversation → chat}/Empty.js +3 -3
- package/dist/ai/ui/chat/File.d.ts +3 -0
- package/dist/ai/ui/{conversation → chat}/File.js +8 -8
- package/dist/ai/ui/{conversation → chat}/Loader.js +3 -3
- package/dist/ai/ui/chat/Message.d.ts +3 -0
- package/dist/ai/ui/chat/Message.js +23 -0
- package/dist/ai/ui/chat/Messages.d.ts +2 -0
- package/dist/ai/ui/chat/Messages.js +11 -0
- package/dist/ai/ui/chat/Root.d.ts +11 -0
- package/dist/ai/ui/chat/Root.js +19 -0
- package/dist/ai/ui/{promptInput → chat/chatInput}/File.js +11 -9
- package/dist/ai/ui/chat/chatInput/Root.d.ts +9 -0
- package/dist/ai/ui/chat/chatInput/Root.js +25 -0
- package/dist/ai/ui/{promptInput → chat/chatInput}/Submit.js +6 -5
- package/dist/ai/ui/{promptInput → chat/chatInput}/Textarea.js +8 -8
- package/dist/ai/ui/{promptInput → chat/chatInput}/index.d.ts +2 -3
- package/dist/ai/ui/{promptInput → chat/chatInput}/index.js +2 -3
- package/dist/ai/ui/chat/chatInput/store.d.ts +15 -0
- package/dist/ai/ui/chat/chatInput/store.js +43 -0
- package/dist/ai/ui/chat/index.d.ts +18 -0
- package/dist/ai/ui/{conversation → chat}/index.js +5 -5
- package/dist/ai/ui/chat/store/index.d.ts +2 -0
- package/dist/ai/ui/chat/store/index.js +2 -0
- package/dist/ai/ui/chat/store/messages.d.ts +15 -0
- package/dist/ai/ui/chat/store/messages.js +75 -0
- package/dist/ai/ui/chat/store/states.d.ts +13 -0
- package/dist/ai/ui/chat/store/states.js +21 -0
- package/dist/ai/ui/index.d.ts +1 -2
- package/dist/ai/ui/index.js +1 -2
- package/dist/app/defaultTheme.d.ts +15 -15
- package/dist/styles.css +3 -3
- package/package.json +37 -35
- package/dist/ai/ui/conversation/ConversationContext.d.ts +0 -7
- package/dist/ai/ui/conversation/ConversationContext.js +0 -8
- package/dist/ai/ui/conversation/ConversationProvider.d.ts +0 -2
- package/dist/ai/ui/conversation/ConversationProvider.js +0 -14
- package/dist/ai/ui/conversation/File.d.ts +0 -4
- package/dist/ai/ui/conversation/Message.d.ts +0 -4
- package/dist/ai/ui/conversation/Message.js +0 -25
- package/dist/ai/ui/conversation/Root.d.ts +0 -2
- package/dist/ai/ui/conversation/Root.js +0 -26
- package/dist/ai/ui/conversation/index.d.ts +0 -13
- package/dist/ai/ui/conversation/types.d.ts +0 -7
- package/dist/ai/ui/conversation/types.js +0 -0
- package/dist/ai/ui/conversation/useChatMessage.d.ts +0 -2
- package/dist/ai/ui/conversation/useChatMessage.js +0 -12
- package/dist/ai/ui/promptInput/PromptInputContext.d.ts +0 -12
- package/dist/ai/ui/promptInput/PromptInputContext.js +0 -8
- package/dist/ai/ui/promptInput/PromptInputProvider.d.ts +0 -2
- package/dist/ai/ui/promptInput/PromptInputProvider.js +0 -50
- package/dist/ai/ui/promptInput/Root.d.ts +0 -3
- package/dist/ai/ui/promptInput/Root.js +0 -17
- package/dist/ai/ui/promptInput/types.d.ts +0 -11
- package/dist/ai/ui/promptInput/types.js +0 -0
- /package/dist/ai/ui/{conversation → chat}/Empty.d.ts +0 -0
- /package/dist/ai/ui/{conversation → chat}/FileIcon.d.ts +0 -0
- /package/dist/ai/ui/{conversation → chat}/FileIcon.js +0 -0
- /package/dist/ai/ui/{conversation → chat}/Loader.d.ts +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/File.d.ts +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/FileIcon.d.ts +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/FileIcon.js +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/Footer.d.ts +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/Footer.js +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/Submit.d.ts +0 -0
- /package/dist/ai/ui/{promptInput → chat/chatInput}/Textarea.d.ts +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Stack, Text } from "@mantine/core";
|
|
3
|
-
import {
|
|
3
|
+
import { useIsEmpty } from "./store/index.js";
|
|
4
4
|
const Empty = ()=>{
|
|
5
|
-
const
|
|
6
|
-
return
|
|
5
|
+
const isEmpty = useIsEmpty();
|
|
6
|
+
return isEmpty ? null : /*#__PURE__*/ jsxs(Stack, {
|
|
7
7
|
align: "center",
|
|
8
8
|
gap: 0,
|
|
9
9
|
children: [
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Image, Paper } from "@mantine/core";
|
|
3
3
|
import { FileIcon } from "./FileIcon.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
4
|
+
import { useChatMessagePart } from "./store/index.js";
|
|
5
|
+
const File = ({ messageId })=>{
|
|
6
|
+
const part = useChatMessagePart(messageId, 'file');
|
|
7
|
+
const textFileType = messageId.split('-')[1];
|
|
8
8
|
const FileComponent = ()=>{
|
|
9
9
|
switch(textFileType){
|
|
10
10
|
case 'excel':
|
|
@@ -20,17 +20,17 @@ const File = ({ message })=>{
|
|
|
20
20
|
mimeType: "powerpoint"
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
if (
|
|
23
|
+
if (part.mediaType.includes('image/')) return /*#__PURE__*/ jsx(Image, {
|
|
24
24
|
radius: "md",
|
|
25
25
|
h: 128,
|
|
26
|
-
src:
|
|
26
|
+
src: part.url,
|
|
27
27
|
alt: "Image Preview"
|
|
28
28
|
});
|
|
29
29
|
return /*#__PURE__*/ jsx(FileIcon, {
|
|
30
|
-
mimeType:
|
|
30
|
+
mimeType: part.mediaType
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
|
-
return textFileType ||
|
|
33
|
+
return textFileType || part ? /*#__PURE__*/ jsx(Paper, {
|
|
34
34
|
radius: "md",
|
|
35
35
|
px: "md",
|
|
36
36
|
py: "sm",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Loader } from "@mantine/core";
|
|
3
|
-
import {
|
|
3
|
+
import { useIsLoading } from "./store/index.js";
|
|
4
4
|
const Loader_Loader = (props)=>{
|
|
5
|
-
const
|
|
6
|
-
return
|
|
5
|
+
const isLoading = useIsLoading();
|
|
6
|
+
return isLoading ? /*#__PURE__*/ jsx(Loader, {
|
|
7
7
|
size: 28,
|
|
8
8
|
type: "dots",
|
|
9
9
|
...props
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Paper } from "@mantine/core";
|
|
3
|
+
import { Streamdown } from "streamdown";
|
|
4
|
+
import { useChatMessage, useChatMessagePart, useIsStreaming } from "./store/index.js";
|
|
5
|
+
const Message = ({ messageId })=>{
|
|
6
|
+
const message = useChatMessage(messageId);
|
|
7
|
+
const part = useChatMessagePart(messageId, 'text');
|
|
8
|
+
const isStreaming = useIsStreaming();
|
|
9
|
+
return /*#__PURE__*/ jsx(Paper, {
|
|
10
|
+
radius: "md",
|
|
11
|
+
px: "md",
|
|
12
|
+
py: "sm",
|
|
13
|
+
maw: "80%",
|
|
14
|
+
ml: 'user' === message.role ? 'auto' : void 0,
|
|
15
|
+
bg: 'user' === message.role ? 'var(--mantine-color-default-hover)' : 'var(--mantine-primary-color-light)',
|
|
16
|
+
fz: "sm",
|
|
17
|
+
children: /*#__PURE__*/ jsx(Streamdown, {
|
|
18
|
+
isAnimating: isStreaming && 'assistant' === message.role,
|
|
19
|
+
children: part?.text
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
export { Message };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Stack } from "@mantine/core";
|
|
3
|
+
import { useChatMessageIds } from "./store/index.js";
|
|
4
|
+
const Messages = ({ children, ...props })=>{
|
|
5
|
+
const messageIds = useChatMessageIds();
|
|
6
|
+
return messageIds.map((messageId)=>/*#__PURE__*/ jsx(Stack, {
|
|
7
|
+
...props,
|
|
8
|
+
children: children
|
|
9
|
+
}, messageId));
|
|
10
|
+
};
|
|
11
|
+
export { Messages };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PaperProps } from '@mantine/core';
|
|
2
|
+
import { type ScrollAreaProps } from '../../../ui';
|
|
3
|
+
export interface ConversationRootProps extends PaperProps {
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
scrollAreaProps?: ScrollAreaProps;
|
|
6
|
+
withScrollButton?: boolean;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
isStreaming: boolean;
|
|
9
|
+
isEmpty: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const Root: ({ children, scrollAreaProps, withScrollButton, ...props }: ConversationRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Paper } from "@mantine/core";
|
|
3
|
+
import { ScrollArea } from "../../../ui/index.js";
|
|
4
|
+
const Root = ({ children, scrollAreaProps, withScrollButton = true, ...props })=>/*#__PURE__*/ jsx(Paper, {
|
|
5
|
+
withBorder: true,
|
|
6
|
+
radius: "md",
|
|
7
|
+
...props,
|
|
8
|
+
children: /*#__PURE__*/ jsxs(ScrollArea, {
|
|
9
|
+
autoScroll: true,
|
|
10
|
+
scrollToBottomOnInit: true,
|
|
11
|
+
p: "md",
|
|
12
|
+
...scrollAreaProps,
|
|
13
|
+
children: [
|
|
14
|
+
children,
|
|
15
|
+
withScrollButton && /*#__PURE__*/ jsx(ScrollArea.ScrollButton, {})
|
|
16
|
+
]
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
export { Root };
|
|
@@ -3,27 +3,29 @@ import { ActionIcon, FileButton, Tooltip } from "@mantine/core";
|
|
|
3
3
|
import { IconPaperclip, IconTrash } from "@tabler/icons-react";
|
|
4
4
|
import { useRef } from "react";
|
|
5
5
|
import { FileIcon } from "./FileIcon.js";
|
|
6
|
-
import {
|
|
6
|
+
import { getAccept, setFile, useFile, useIsSubmitting, useIsUploading } from "./store.js";
|
|
7
7
|
const File = (props)=>{
|
|
8
8
|
const resetRef = useRef(null);
|
|
9
|
-
const
|
|
9
|
+
const isSubmiting = useIsSubmitting();
|
|
10
|
+
const isUploading = useIsUploading();
|
|
11
|
+
const file = useFile();
|
|
10
12
|
return /*#__PURE__*/ jsx(FileButton, {
|
|
11
13
|
resetRef: resetRef,
|
|
12
14
|
onChange: async (file)=>{
|
|
13
15
|
if (file) setFile(file);
|
|
14
16
|
},
|
|
15
|
-
accept:
|
|
16
|
-
disabled:
|
|
17
|
+
accept: getAccept(),
|
|
18
|
+
disabled: isSubmiting || isUploading,
|
|
17
19
|
...props,
|
|
18
20
|
children: (props)=>/*#__PURE__*/ jsxs(ActionIcon.Group, {
|
|
19
21
|
children: [
|
|
20
22
|
/*#__PURE__*/ jsx(ActionIcon, {
|
|
21
23
|
size: "lg",
|
|
22
24
|
variant: "default",
|
|
23
|
-
disabled:
|
|
24
|
-
loading:
|
|
25
|
+
disabled: isSubmiting,
|
|
26
|
+
loading: isUploading,
|
|
25
27
|
classNames: {
|
|
26
|
-
root: 'rolder-
|
|
28
|
+
root: 'rolder-chat-input-file-action-action'
|
|
27
29
|
},
|
|
28
30
|
...props,
|
|
29
31
|
children: /*#__PURE__*/ jsx(IconPaperclip, {
|
|
@@ -48,11 +50,11 @@ const File = (props)=>{
|
|
|
48
50
|
size: "lg",
|
|
49
51
|
variant: "default",
|
|
50
52
|
classNames: {
|
|
51
|
-
root: 'rolder-
|
|
53
|
+
root: 'rolder-chat-input-file-action-action'
|
|
52
54
|
},
|
|
53
55
|
onClick: ()=>{
|
|
54
56
|
resetRef.current?.();
|
|
55
|
-
setFile(
|
|
57
|
+
setFile(null);
|
|
56
58
|
},
|
|
57
59
|
children: /*#__PURE__*/ jsx(IconTrash, {
|
|
58
60
|
size: 24,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type PaperProps } from '@mantine/core';
|
|
2
|
+
import { type Accept } from './store';
|
|
3
|
+
export interface ChatInputRootProps extends PaperProps {
|
|
4
|
+
onSubmit: () => void;
|
|
5
|
+
isSubmitting: boolean;
|
|
6
|
+
isUploading: boolean;
|
|
7
|
+
accept?: Accept;
|
|
8
|
+
}
|
|
9
|
+
export declare const Root: ({ className, onSubmit, isSubmitting, isUploading, accept, ...props }: ChatInputRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Paper } from "@mantine/core";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { useEffect } from "react";
|
|
5
|
+
import { setAccept, setIsSubmitting, setIsUploading, setOnSubmit } from "./store.js";
|
|
6
|
+
const Root = ({ className, onSubmit, isSubmitting, isUploading, accept, ...props })=>{
|
|
7
|
+
useEffect(()=>{
|
|
8
|
+
setOnSubmit(onSubmit);
|
|
9
|
+
setIsSubmitting(isSubmitting);
|
|
10
|
+
setIsUploading(isUploading);
|
|
11
|
+
if (accept) setAccept(accept);
|
|
12
|
+
}, [
|
|
13
|
+
onSubmit,
|
|
14
|
+
isSubmitting,
|
|
15
|
+
isUploading,
|
|
16
|
+
accept
|
|
17
|
+
]);
|
|
18
|
+
return /*#__PURE__*/ jsx(Paper, {
|
|
19
|
+
radius: "md",
|
|
20
|
+
withBorder: true,
|
|
21
|
+
className: clsx('rolder-chat-input-root', className),
|
|
22
|
+
...props
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
export { Root };
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { ActionIcon } from "@mantine/core";
|
|
3
3
|
import { IconArrowBigUp } from "@tabler/icons-react";
|
|
4
|
-
import {
|
|
4
|
+
import { getOnSubmit, useIsSubmitting, useIsUploading } from "./store.js";
|
|
5
5
|
const Submit = ({ children, ...props })=>{
|
|
6
6
|
const Icon = /*#__PURE__*/ jsx(IconArrowBigUp, {
|
|
7
7
|
strokeWidth: 1.5
|
|
8
8
|
});
|
|
9
|
-
const
|
|
9
|
+
const isSubmiting = useIsSubmitting();
|
|
10
|
+
const isUploading = useIsUploading();
|
|
10
11
|
return /*#__PURE__*/ jsx(ActionIcon, {
|
|
11
12
|
"aria-label": "Submit",
|
|
12
13
|
variant: "light",
|
|
13
14
|
size: "lg",
|
|
14
|
-
onClick:
|
|
15
|
-
disabled:
|
|
16
|
-
loading:
|
|
15
|
+
onClick: getOnSubmit(),
|
|
16
|
+
disabled: isUploading,
|
|
17
|
+
loading: isSubmiting,
|
|
17
18
|
...props,
|
|
18
19
|
children: children ?? Icon
|
|
19
20
|
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Textarea } from "@mantine/core";
|
|
3
|
-
import {
|
|
4
|
-
import { usePromptInput } from "./PromptInputContext.js";
|
|
3
|
+
import { getIsComposing, getOnSubmit, setIsComposing, setText, useIsSubmitting, useIsUploading, useText } from "./store.js";
|
|
5
4
|
const Textarea_Textarea = (props)=>{
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
const text = useText();
|
|
6
|
+
const isSubmiting = useIsSubmitting();
|
|
7
|
+
const isUploading = useIsUploading();
|
|
8
8
|
const handleKeyDown = (e)=>{
|
|
9
9
|
if ('Enter' === e.key) {
|
|
10
|
-
if (
|
|
10
|
+
if (getIsComposing() || e.nativeEvent.isComposing) return;
|
|
11
11
|
if (e.shiftKey) return;
|
|
12
12
|
e.preventDefault();
|
|
13
|
-
|
|
13
|
+
getOnSubmit()();
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
16
|
return /*#__PURE__*/ jsx(Textarea, {
|
|
@@ -18,7 +18,7 @@ const Textarea_Textarea = (props)=>{
|
|
|
18
18
|
size: "md",
|
|
19
19
|
rows: 3,
|
|
20
20
|
classNames: {
|
|
21
|
-
input: 'rolder-
|
|
21
|
+
input: 'rolder-chat-input-textarea'
|
|
22
22
|
},
|
|
23
23
|
placeholder: "Напишите сообщение",
|
|
24
24
|
onCompositionEnd: ()=>setIsComposing(false),
|
|
@@ -26,7 +26,7 @@ const Textarea_Textarea = (props)=>{
|
|
|
26
26
|
onKeyDown: handleKeyDown,
|
|
27
27
|
value: text,
|
|
28
28
|
onChange: (e)=>setText(e.target.value),
|
|
29
|
-
disabled:
|
|
29
|
+
disabled: isSubmiting || isUploading,
|
|
30
30
|
...props
|
|
31
31
|
});
|
|
32
32
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
Root: ({ className, onSubmit, submiting, uploading, accept, ...props }: import("@mantine/core").PaperProps & import("./types").PromptInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
1
|
+
export declare const Input: {
|
|
2
|
+
Root: ({ className, onSubmit, isSubmitting, isUploading, accept, ...props }: import("./Root").ChatInputRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
3
|
Textarea: (props: import("@mantine/core").TextareaProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
4
|
Footer: (props: import("@mantine/core").GroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
5
|
Submit: ({ children, ...props }: import("@mantine/core").ActionIconProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,12 +3,11 @@ import { Footer } from "./Footer.js";
|
|
|
3
3
|
import { Root } from "./Root.js";
|
|
4
4
|
import { Submit } from "./Submit.js";
|
|
5
5
|
import { Textarea } from "./Textarea.js";
|
|
6
|
-
|
|
7
|
-
const PromptInput = {
|
|
6
|
+
const Input = {
|
|
8
7
|
Root: Root,
|
|
9
8
|
Textarea: Textarea,
|
|
10
9
|
Footer: Footer,
|
|
11
10
|
Submit: Submit,
|
|
12
11
|
File: File
|
|
13
12
|
};
|
|
14
|
-
export {
|
|
13
|
+
export { Input };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const setText: (text: string) => void;
|
|
2
|
+
export declare const useText: () => string;
|
|
3
|
+
export declare const getIsComposing: () => boolean;
|
|
4
|
+
export declare const setIsComposing: (isComposing: boolean) => void;
|
|
5
|
+
export declare const useIsSubmitting: () => boolean;
|
|
6
|
+
export declare const setIsSubmitting: (isSubmitting: boolean) => void;
|
|
7
|
+
export declare const useIsUploading: () => boolean;
|
|
8
|
+
export declare const setIsUploading: (isUploading: boolean) => void;
|
|
9
|
+
export declare const useFile: () => File | null;
|
|
10
|
+
export declare const setFile: (file: File | null) => void;
|
|
11
|
+
export declare const getOnSubmit: () => () => void;
|
|
12
|
+
export declare const setOnSubmit: (onSubmit: () => void) => void;
|
|
13
|
+
export type Accept = ('text' | 'image' | 'pdf' | 'word' | 'excel')[];
|
|
14
|
+
export declare const getAccept: () => string;
|
|
15
|
+
export declare const setAccept: (accept: Accept) => void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useStore } from "@nanostores/react";
|
|
2
|
+
import { atom } from "nanostores";
|
|
3
|
+
const $text = atom('');
|
|
4
|
+
const setText = (text)=>$text.set(text);
|
|
5
|
+
const useText = ()=>useStore($text);
|
|
6
|
+
const $isComposing = atom(false);
|
|
7
|
+
const getIsComposing = ()=>$isComposing.get();
|
|
8
|
+
const setIsComposing = (isComposing)=>$isComposing.set(isComposing);
|
|
9
|
+
const $isSubmitting = atom(false);
|
|
10
|
+
const useIsSubmitting = ()=>useStore($isSubmitting);
|
|
11
|
+
const setIsSubmitting = (isSubmitting)=>$isSubmitting.set(isSubmitting);
|
|
12
|
+
const $isUploading = atom(false);
|
|
13
|
+
const useIsUploading = ()=>useStore($isUploading);
|
|
14
|
+
const setIsUploading = (isUploading)=>$isUploading.set(isUploading);
|
|
15
|
+
const $file = atom(null);
|
|
16
|
+
const useFile = ()=>useStore($file);
|
|
17
|
+
const setFile = (file)=>$file.set(file);
|
|
18
|
+
const $onSubmit = atom(()=>()=>{});
|
|
19
|
+
const getOnSubmit = ()=>$onSubmit.get();
|
|
20
|
+
const setOnSubmit = (onSubmit)=>$onSubmit.set(onSubmit);
|
|
21
|
+
const $accept = atom([
|
|
22
|
+
'text',
|
|
23
|
+
'image',
|
|
24
|
+
'pdf'
|
|
25
|
+
]);
|
|
26
|
+
const getAccept = ()=>$accept.get().map((type)=>{
|
|
27
|
+
switch(type){
|
|
28
|
+
case 'text':
|
|
29
|
+
return 'text/plain';
|
|
30
|
+
case 'image':
|
|
31
|
+
return 'image/*';
|
|
32
|
+
case 'pdf':
|
|
33
|
+
return 'application/pdf';
|
|
34
|
+
case 'excel':
|
|
35
|
+
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
|
36
|
+
case 'word':
|
|
37
|
+
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
|
38
|
+
default:
|
|
39
|
+
return type;
|
|
40
|
+
}
|
|
41
|
+
}).join(',');
|
|
42
|
+
const setAccept = (accept)=>$accept.set(accept);
|
|
43
|
+
export { getAccept, getIsComposing, getOnSubmit, setAccept, setFile, setIsComposing, setIsSubmitting, setIsUploading, setOnSubmit, setText, useFile, useIsSubmitting, useIsUploading, useText };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const Chat: {
|
|
2
|
+
Root: ({ children, scrollAreaProps, withScrollButton, ...props }: import("./Root").ConversationRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
Message: ({ messageId }: {
|
|
4
|
+
messageId: string;
|
|
5
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
File: ({ messageId }: {
|
|
7
|
+
messageId: string;
|
|
8
|
+
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
Loader: (props: import("@mantine/core").LoaderProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
Empty: () => import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
Input: {
|
|
12
|
+
Root: ({ className, onSubmit, isSubmitting, isUploading, accept, ...props }: import("./chatInput/Root").ChatInputRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
Textarea: (props: import("@mantine/core").TextareaProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
Footer: (props: import("@mantine/core").GroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
Submit: ({ children, ...props }: import("@mantine/core").ActionIconProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
File: (props: Omit<import("@mantine/core").FileButtonProps, "onChange" | "children">) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
import { Input } from "./chatInput/index.js";
|
|
1
2
|
import { Empty } from "./Empty.js";
|
|
2
3
|
import { File } from "./File.js";
|
|
3
4
|
import { Loader } from "./Loader.js";
|
|
4
5
|
import { Message } from "./Message.js";
|
|
5
6
|
import { Root } from "./Root.js";
|
|
6
|
-
|
|
7
|
-
export * from "./useChatMessage.js";
|
|
8
|
-
const Conversation = {
|
|
7
|
+
const Chat = {
|
|
9
8
|
Root: Root,
|
|
10
9
|
Message: Message,
|
|
11
10
|
File: File,
|
|
12
11
|
Loader: Loader,
|
|
13
|
-
Empty: Empty
|
|
12
|
+
Empty: Empty,
|
|
13
|
+
Input: Input
|
|
14
14
|
};
|
|
15
|
-
export {
|
|
15
|
+
export { Chat };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type UseChatOptions } from '@ai-sdk/react';
|
|
2
|
+
import type { ChatInit, FileUIPart, UIDataTypes, UIMessage, UIMessagePart, UITools } from 'ai';
|
|
3
|
+
export declare const $chatMessageIds: import("nanostores").PreinitializedWritableAtom<string[]> & object;
|
|
4
|
+
export declare const $chatMessages: import("nanostores").PreinitializedMapStore<Record<string, UIMessage<unknown, UIDataTypes, UITools>>> & object;
|
|
5
|
+
export declare const getChatMessage: (messageId: string) => UIMessage<unknown, UIDataTypes, UITools>;
|
|
6
|
+
export declare const getChatMessages: <T extends UIMessage>() => T[];
|
|
7
|
+
export declare const setChatMessages: <T extends UIMessage>(messages: T[]) => void;
|
|
8
|
+
export declare const useChatMessageIds: <T extends UIMessage>(props?: UseChatOptions<T> & ChatInit<T>) => string[];
|
|
9
|
+
export declare const useChatMessage: <T extends UIMessage>(messageId: string) => T;
|
|
10
|
+
export declare const useChatMessagePart: <M extends UIMessage, T extends UIMessagePart<UIDataTypes, UITools>>(messageId: string, type?: T["type"]) => T;
|
|
11
|
+
export type SendMessage = ({ text, file }: {
|
|
12
|
+
text: string;
|
|
13
|
+
file?: FileUIPart;
|
|
14
|
+
}, data?: Record<string, unknown>) => Promise<void>;
|
|
15
|
+
export declare const sendMessage: SendMessage;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useChat } from "@ai-sdk/react";
|
|
2
|
+
import { notifications } from "@mantine/notifications";
|
|
3
|
+
import { useStore } from "@nanostores/react";
|
|
4
|
+
import { atom, map } from "nanostores";
|
|
5
|
+
import { useEffect } from "react";
|
|
6
|
+
import { setChatError, setChatStatus } from "./states.js";
|
|
7
|
+
const $chatMessageIds = atom([]);
|
|
8
|
+
const $chatMessages = map({});
|
|
9
|
+
const getChatMessage = (messageId)=>$chatMessages.get()[messageId];
|
|
10
|
+
const getChatMessages = ()=>$chatMessageIds.get().map((id)=>$chatMessages.get()[id]);
|
|
11
|
+
const setChatMessages = (messages)=>{
|
|
12
|
+
$chatMessageIds.set(messages.map((msg)=>msg.id));
|
|
13
|
+
const messagesMap = {};
|
|
14
|
+
for (const msg of messages)messagesMap[msg.id] = msg;
|
|
15
|
+
$chatMessages.set(messagesMap);
|
|
16
|
+
};
|
|
17
|
+
const useChatMessageIds = (props)=>{
|
|
18
|
+
const { messages, status, error, sendMessage } = useChat({
|
|
19
|
+
onError: (e)=>{
|
|
20
|
+
notifications.show({
|
|
21
|
+
title: 'Ошибка сервера ИИ',
|
|
22
|
+
message: e.message,
|
|
23
|
+
color: 'red',
|
|
24
|
+
autoClose: false
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
...props
|
|
28
|
+
});
|
|
29
|
+
useEffect(()=>{
|
|
30
|
+
setChatStatus(status);
|
|
31
|
+
}, [
|
|
32
|
+
status
|
|
33
|
+
]);
|
|
34
|
+
useEffect(()=>{
|
|
35
|
+
setChatError(error?.message);
|
|
36
|
+
}, [
|
|
37
|
+
error?.message
|
|
38
|
+
]);
|
|
39
|
+
useEffect(()=>{
|
|
40
|
+
setChatSendMessage(sendMessage);
|
|
41
|
+
}, [
|
|
42
|
+
sendMessage
|
|
43
|
+
]);
|
|
44
|
+
useEffect(()=>{
|
|
45
|
+
setChatMessages(messages);
|
|
46
|
+
}, [
|
|
47
|
+
messages
|
|
48
|
+
]);
|
|
49
|
+
return useStore($chatMessageIds);
|
|
50
|
+
};
|
|
51
|
+
const useChatMessage = (messageId)=>useStore($chatMessages, {
|
|
52
|
+
keys: [
|
|
53
|
+
messageId
|
|
54
|
+
]
|
|
55
|
+
})[messageId];
|
|
56
|
+
const useChatMessagePart = (messageId, type)=>{
|
|
57
|
+
const message = useChatMessage(messageId);
|
|
58
|
+
const part = message?.parts?.find((i)=>i.type === type);
|
|
59
|
+
return part;
|
|
60
|
+
};
|
|
61
|
+
const $chatSendMessage = atom();
|
|
62
|
+
const getChatSendMessage = ()=>$chatSendMessage.get();
|
|
63
|
+
const setChatSendMessage = (sendMessage)=>$chatSendMessage.set(sendMessage);
|
|
64
|
+
const messages_sendMessage = async ({ text, file }, data)=>{
|
|
65
|
+
const files = file ? [
|
|
66
|
+
file
|
|
67
|
+
] : [];
|
|
68
|
+
await getChatSendMessage()?.({
|
|
69
|
+
text,
|
|
70
|
+
files
|
|
71
|
+
}, {
|
|
72
|
+
body: data
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
export { $chatMessageIds, $chatMessages, getChatMessage, getChatMessages, messages_sendMessage as sendMessage, setChatMessages, useChatMessage, useChatMessageIds, useChatMessagePart };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ChatStatus } from 'ai';
|
|
2
|
+
export declare const getChatStatus: () => ChatStatus;
|
|
3
|
+
export declare const setChatStatus: (status: ChatStatus) => void;
|
|
4
|
+
export declare const useChatStatus: () => ChatStatus;
|
|
5
|
+
export declare const getIsLoading: () => boolean;
|
|
6
|
+
export declare const useIsLoading: () => boolean;
|
|
7
|
+
export declare const getIsStreaming: () => boolean;
|
|
8
|
+
export declare const useIsStreaming: () => boolean;
|
|
9
|
+
export declare const getIsEmpty: () => boolean;
|
|
10
|
+
export declare const useIsEmpty: () => boolean;
|
|
11
|
+
export declare const getChatError: () => string | undefined;
|
|
12
|
+
export declare const setChatError: (error: string | undefined) => void;
|
|
13
|
+
export declare const useChatError: () => string | undefined;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useStore } from "@nanostores/react";
|
|
2
|
+
import { atom, computed } from "nanostores";
|
|
3
|
+
import { $chatMessageIds } from "./messages.js";
|
|
4
|
+
const $chatStatus = atom('ready');
|
|
5
|
+
const getChatStatus = ()=>$chatStatus.get();
|
|
6
|
+
const setChatStatus = (status)=>$chatStatus.set(status);
|
|
7
|
+
const useChatStatus = ()=>useStore($chatStatus);
|
|
8
|
+
const $isLoading = computed($chatStatus, (status)=>'ready' !== status);
|
|
9
|
+
const getIsLoading = ()=>$isLoading.get();
|
|
10
|
+
const useIsLoading = ()=>useStore($isLoading);
|
|
11
|
+
const $isStreaming = computed($chatStatus, (status)=>'streaming' === status);
|
|
12
|
+
const getIsStreaming = ()=>$isStreaming.get();
|
|
13
|
+
const useIsStreaming = ()=>useStore($isStreaming);
|
|
14
|
+
const $isEmpty = computed($chatMessageIds, (messages)=>0 === messages.length);
|
|
15
|
+
const getIsEmpty = ()=>$isEmpty.get();
|
|
16
|
+
const useIsEmpty = ()=>useStore($isEmpty);
|
|
17
|
+
const $chatError = atom();
|
|
18
|
+
const getChatError = ()=>$chatError.get();
|
|
19
|
+
const setChatError = (error)=>$chatError.set(error);
|
|
20
|
+
const useChatError = ()=>useStore($chatError);
|
|
21
|
+
export { getChatError, getChatStatus, getIsEmpty, getIsLoading, getIsStreaming, setChatError, setChatStatus, useChatError, useChatStatus, useIsEmpty, useIsLoading, useIsStreaming };
|
package/dist/ai/ui/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './promptInput';
|
|
1
|
+
export * from './chat';
|
package/dist/ai/ui/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./promptInput/index.js";
|
|
1
|
+
export * from "./chat/index.js";
|
|
@@ -6,20 +6,20 @@ export declare const defaultTheme: {
|
|
|
6
6
|
black?: string | undefined;
|
|
7
7
|
colors?: {
|
|
8
8
|
[x: string & {}]: import("@mantine/core").MantineColorsTuple | undefined;
|
|
9
|
-
dark?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
10
|
-
gray?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
11
|
-
red?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
12
|
-
pink?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
13
|
-
grape?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
14
|
-
violet?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
15
|
-
indigo?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
16
9
|
blue?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
17
10
|
cyan?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
11
|
+
gray?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
18
12
|
green?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
13
|
+
indigo?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
19
14
|
lime?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
20
|
-
yellow?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
21
15
|
orange?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
16
|
+
pink?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
17
|
+
red?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
22
18
|
teal?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
19
|
+
violet?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
20
|
+
yellow?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
21
|
+
dark?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
22
|
+
grape?: import("@mantine/core").MantineColorsTuple | undefined;
|
|
23
23
|
} | undefined;
|
|
24
24
|
primaryShade?: import("@mantine/core").MantineColorShade | {
|
|
25
25
|
light?: import("@mantine/core").MantineColorShade | undefined;
|
|
@@ -34,7 +34,7 @@ export declare const defaultTheme: {
|
|
|
34
34
|
headings?: {
|
|
35
35
|
fontFamily?: string | undefined;
|
|
36
36
|
fontWeight?: string | undefined;
|
|
37
|
-
textWrap?: "
|
|
37
|
+
textWrap?: "nowrap" | "wrap" | "balance" | "stable" | "pretty" | undefined;
|
|
38
38
|
sizes?: {
|
|
39
39
|
h1?: {
|
|
40
40
|
fontSize?: string | undefined;
|
|
@@ -70,52 +70,52 @@ export declare const defaultTheme: {
|
|
|
70
70
|
} | undefined;
|
|
71
71
|
radius?: {
|
|
72
72
|
[x: string & {}]: string | undefined;
|
|
73
|
+
lg?: string | undefined;
|
|
73
74
|
xs?: string | undefined;
|
|
74
75
|
sm?: string | undefined;
|
|
75
76
|
md?: string | undefined;
|
|
76
|
-
lg?: string | undefined;
|
|
77
77
|
xl?: string | undefined;
|
|
78
78
|
} | undefined;
|
|
79
79
|
defaultRadius?: import("@mantine/core").MantineRadius | undefined;
|
|
80
80
|
spacing?: {
|
|
81
81
|
[x: number]: string | undefined;
|
|
82
82
|
[x: string & {}]: string | undefined;
|
|
83
|
+
lg?: string | undefined;
|
|
83
84
|
xs?: string | undefined;
|
|
84
85
|
sm?: string | undefined;
|
|
85
86
|
md?: string | undefined;
|
|
86
|
-
lg?: string | undefined;
|
|
87
87
|
xl?: string | undefined;
|
|
88
88
|
} | undefined;
|
|
89
89
|
fontSizes?: {
|
|
90
90
|
[x: string & {}]: string | undefined;
|
|
91
|
+
lg?: string | undefined;
|
|
91
92
|
xs?: string | undefined;
|
|
92
93
|
sm?: string | undefined;
|
|
93
94
|
md?: string | undefined;
|
|
94
|
-
lg?: string | undefined;
|
|
95
95
|
xl?: string | undefined;
|
|
96
96
|
} | undefined;
|
|
97
97
|
lineHeights?: {
|
|
98
98
|
[x: string & {}]: string | undefined;
|
|
99
|
+
lg?: string | undefined;
|
|
99
100
|
xs?: string | undefined;
|
|
100
101
|
sm?: string | undefined;
|
|
101
102
|
md?: string | undefined;
|
|
102
|
-
lg?: string | undefined;
|
|
103
103
|
xl?: string | undefined;
|
|
104
104
|
} | undefined;
|
|
105
105
|
breakpoints?: {
|
|
106
106
|
[x: string & {}]: string | undefined;
|
|
107
|
+
lg?: string | undefined;
|
|
107
108
|
xs?: string | undefined;
|
|
108
109
|
sm?: string | undefined;
|
|
109
110
|
md?: string | undefined;
|
|
110
|
-
lg?: string | undefined;
|
|
111
111
|
xl?: string | undefined;
|
|
112
112
|
} | undefined;
|
|
113
113
|
shadows?: {
|
|
114
114
|
[x: string & {}]: string | undefined;
|
|
115
|
+
lg?: string | undefined;
|
|
115
116
|
xs?: string | undefined;
|
|
116
117
|
sm?: string | undefined;
|
|
117
118
|
md?: string | undefined;
|
|
118
|
-
lg?: string | undefined;
|
|
119
119
|
xl?: string | undefined;
|
|
120
120
|
} | undefined;
|
|
121
121
|
respectReducedMotion?: boolean | undefined;
|
package/dist/styles.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.rolder-
|
|
1
|
+
.rolder-chat-input-root {
|
|
2
2
|
background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
|
|
3
3
|
|
|
4
4
|
&:focus-within {
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.rolder-
|
|
11
|
+
.rolder-chat-input-textarea {
|
|
12
12
|
border: 0;
|
|
13
13
|
border-radius: 8px;
|
|
14
14
|
overflow: hidden;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
.rolder-
|
|
17
|
+
.rolder-chat-input-file-action-action {
|
|
18
18
|
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
|
|
19
19
|
|
|
20
20
|
&[data-disabled] {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rolder/kit",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.24",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -16,50 +16,52 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "rslib build",
|
|
18
18
|
"dev": "rslib build --watch",
|
|
19
|
-
"check": "biome check --write &&
|
|
19
|
+
"check": "biome check --write && tsgo --noEmit"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@
|
|
23
|
-
"@rsbuild/plugin-react": "^1.4.2",
|
|
22
|
+
"@rsbuild/plugin-react": "^1.4.3",
|
|
24
23
|
"@rslib/core": "^0.19.2",
|
|
25
|
-
"@types/bun": "^1.3.
|
|
24
|
+
"@types/bun": "^1.3.6",
|
|
26
25
|
"@types/js-cookie": "^3.0.6",
|
|
27
26
|
"@types/omgopass": "^3.2.3",
|
|
28
27
|
"@types/react": "^19.2.8",
|
|
29
|
-
"
|
|
28
|
+
"@typescript/native-preview": "^7.0.0-dev.20260115.1",
|
|
30
29
|
"typescript": "^5.9.3"
|
|
31
30
|
},
|
|
32
31
|
"peerDependencies": {
|
|
33
|
-
"react": "^19.
|
|
34
|
-
"react-dom": "^19.
|
|
35
|
-
"clsx": "^2.
|
|
36
|
-
"@tiptap/
|
|
37
|
-
"@tiptap/extension-
|
|
38
|
-
"@tiptap/extension-
|
|
39
|
-
"@tiptap/extension-
|
|
40
|
-
"@tiptap/extension-task-
|
|
41
|
-
"@tiptap/extension-
|
|
42
|
-
"@tiptap/
|
|
43
|
-
"@
|
|
44
|
-
"@codemirror/
|
|
45
|
-
"@
|
|
46
|
-
"@uiw/
|
|
47
|
-
"@
|
|
48
|
-
"@mantine/
|
|
49
|
-
"@mantine/
|
|
50
|
-
"@mantine/
|
|
51
|
-
"@
|
|
52
|
-
"@tanstack/react-
|
|
53
|
-
"@tanstack/react-
|
|
54
|
-
"@tanstack/react-
|
|
55
|
-
"@tanstack/react-
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
32
|
+
"react": "^19.2.3",
|
|
33
|
+
"react-dom": "^19.2.3",
|
|
34
|
+
"clsx": "^2.1.1",
|
|
35
|
+
"@tiptap/react": "^3.15.3",
|
|
36
|
+
"@tiptap/extension-highlight": "^3.15.3",
|
|
37
|
+
"@tiptap/extension-placeholder": "^3.15.3",
|
|
38
|
+
"@tiptap/extension-table": "^3.15.3",
|
|
39
|
+
"@tiptap/extension-task-item": "^3.15.3",
|
|
40
|
+
"@tiptap/extension-task-list": "^3.15.3",
|
|
41
|
+
"@tiptap/extension-text-align": "^3.15.3",
|
|
42
|
+
"@tiptap/starter-kit": "^3.15.3",
|
|
43
|
+
"@codemirror/lang-json": "^6.0.2",
|
|
44
|
+
"@codemirror/lint": "^6.9.2",
|
|
45
|
+
"@uiw/codemirror-theme-vscode": "^4.25.4",
|
|
46
|
+
"@uiw/react-codemirror": "^4.25.4",
|
|
47
|
+
"@mantine/core": "^8.3.12",
|
|
48
|
+
"@mantine/hooks": "^8.3.12",
|
|
49
|
+
"@mantine/tiptap": "^8.3.12",
|
|
50
|
+
"@mantine/notifications": "^8.3.12",
|
|
51
|
+
"@tanstack/react-router": "^1.150.0",
|
|
52
|
+
"@tanstack/react-form": "^1.27.7",
|
|
53
|
+
"@tanstack/react-start": "^1.150.0",
|
|
54
|
+
"@tanstack/react-query": "^5.90.17",
|
|
55
|
+
"@tanstack/react-router-ssr-query": "^1.150.0",
|
|
56
|
+
"zod": "^4.3.5",
|
|
57
|
+
"js-cookie": "^3.0.5",
|
|
58
|
+
"nanostores": "^1.1.0",
|
|
59
|
+
"@nanostores/react": "^1.0.0",
|
|
59
60
|
"surrealdb": "^2.0.0-alpha.16",
|
|
60
|
-
"omgopass": "^3.
|
|
61
|
-
"ai": "^6.
|
|
62
|
-
"
|
|
61
|
+
"omgopass": "^3.2.1",
|
|
62
|
+
"ai": "^6.0.37",
|
|
63
|
+
"@ai-sdk/react": "^3.0.39",
|
|
64
|
+
"streamdown": "^2.0.1"
|
|
63
65
|
},
|
|
64
66
|
"trustedDependencies": [
|
|
65
67
|
"core-js",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react";
|
|
2
|
-
const ConversationContext = createContext(null);
|
|
3
|
-
const useConversation = ()=>{
|
|
4
|
-
const context = useContext(ConversationContext);
|
|
5
|
-
if (!context) throw new Error('useConversation must be used within a ConversationProvider');
|
|
6
|
-
return context;
|
|
7
|
-
};
|
|
8
|
-
export { ConversationContext, useConversation };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { ConversationContext } from "./ConversationContext.js";
|
|
3
|
-
const Provider = ({ children, loading, streaming, empty })=>{
|
|
4
|
-
const value = {
|
|
5
|
-
loading,
|
|
6
|
-
streaming,
|
|
7
|
-
empty
|
|
8
|
-
};
|
|
9
|
-
return /*#__PURE__*/ jsx(ConversationContext.Provider, {
|
|
10
|
-
value: value,
|
|
11
|
-
children: children
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
export { Provider };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Paper } from "@mantine/core";
|
|
3
|
-
import { Streamdown } from "streamdown";
|
|
4
|
-
import { useConversation } from "./ConversationContext.js";
|
|
5
|
-
import { useChatMessage } from "./useChatMessage.js";
|
|
6
|
-
const Message = ({ message })=>{
|
|
7
|
-
const textParts = message?.parts?.filter((i)=>'text' === i.type);
|
|
8
|
-
const lastTextPart = textParts?.[textParts.length - 1];
|
|
9
|
-
const chatMessage = useChatMessage(lastTextPart);
|
|
10
|
-
const { streaming } = useConversation();
|
|
11
|
-
return chatMessage && 'system' !== message.role ? /*#__PURE__*/ jsx(Paper, {
|
|
12
|
-
radius: "md",
|
|
13
|
-
px: "md",
|
|
14
|
-
py: "sm",
|
|
15
|
-
maw: "80%",
|
|
16
|
-
ml: 'user' === message.role ? 'auto' : void 0,
|
|
17
|
-
bg: 'user' === message.role ? 'var(--mantine-color-default-hover)' : 'var(--mantine-primary-color-light)',
|
|
18
|
-
fz: "sm",
|
|
19
|
-
children: /*#__PURE__*/ jsx(Streamdown, {
|
|
20
|
-
isAnimating: streaming && 'assistant' === message.role,
|
|
21
|
-
children: chatMessage
|
|
22
|
-
})
|
|
23
|
-
}) : null;
|
|
24
|
-
};
|
|
25
|
-
export { Message };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Paper, Stack } from "@mantine/core";
|
|
3
|
-
import { ScrollArea } from "../../../ui/index.js";
|
|
4
|
-
import { Provider } from "./ConversationProvider.js";
|
|
5
|
-
const Root = ({ children, loading, streaming, empty, ...props })=>/*#__PURE__*/ jsx(Provider, {
|
|
6
|
-
loading: loading,
|
|
7
|
-
streaming: streaming,
|
|
8
|
-
empty: empty,
|
|
9
|
-
children: /*#__PURE__*/ jsx(Paper, {
|
|
10
|
-
withBorder: true,
|
|
11
|
-
radius: "md",
|
|
12
|
-
...props,
|
|
13
|
-
children: /*#__PURE__*/ jsxs(ScrollArea, {
|
|
14
|
-
autoScroll: true,
|
|
15
|
-
scrollToBottomOnInit: true,
|
|
16
|
-
p: "md",
|
|
17
|
-
children: [
|
|
18
|
-
/*#__PURE__*/ jsx(Stack, {
|
|
19
|
-
children: children
|
|
20
|
-
}),
|
|
21
|
-
/*#__PURE__*/ jsx(ScrollArea.ScrollButton, {})
|
|
22
|
-
]
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
});
|
|
26
|
-
export { Root };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './useChatMessage';
|
|
3
|
-
export declare const Conversation: {
|
|
4
|
-
Root: ({ children, loading, streaming, empty, ...props }: import("./types").ConversationProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
Message: <T extends import("ai").UIMessage>({ message }: {
|
|
6
|
-
message: T;
|
|
7
|
-
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
-
File: <T extends import("ai").UIMessage>({ message }: {
|
|
9
|
-
message: T;
|
|
10
|
-
}) => import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
-
Loader: (props: import("@mantine/core").LoaderProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
12
|
-
Empty: () => import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
-
};
|
|
File without changes
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
import { parseAiMessagePart } from "../../utils/index.js";
|
|
3
|
-
const useChatMessage = (part)=>{
|
|
4
|
-
const [parsedText, setParsedText] = useState('');
|
|
5
|
-
useEffect(()=>{
|
|
6
|
-
parseAiMessagePart(part).then((i)=>setParsedText(i.text));
|
|
7
|
-
}, [
|
|
8
|
-
part
|
|
9
|
-
]);
|
|
10
|
-
return parsedText;
|
|
11
|
-
};
|
|
12
|
-
export { useChatMessage };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface PromptInputContext {
|
|
2
|
-
text: string;
|
|
3
|
-
setText: (text: string) => void;
|
|
4
|
-
file?: File;
|
|
5
|
-
setFile: (file?: File) => void;
|
|
6
|
-
onSubmit: () => void;
|
|
7
|
-
submiting: boolean;
|
|
8
|
-
uploading: boolean;
|
|
9
|
-
accept?: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const PromptInputContext: import("react").Context<PromptInputContext | null>;
|
|
12
|
-
export declare const usePromptInput: () => PromptInputContext;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react";
|
|
2
|
-
const PromptInputContext = createContext(null);
|
|
3
|
-
const usePromptInput = ()=>{
|
|
4
|
-
const context = useContext(PromptInputContext);
|
|
5
|
-
if (!context) throw new Error('usePromptInput must be used within a PromptInputProvider');
|
|
6
|
-
return context;
|
|
7
|
-
};
|
|
8
|
-
export { PromptInputContext, usePromptInput };
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { PromptInputContext } from "./PromptInputContext.js";
|
|
4
|
-
const Provider = ({ children, onSubmit, submiting, uploading, accept = [
|
|
5
|
-
'text',
|
|
6
|
-
'image',
|
|
7
|
-
'pdf'
|
|
8
|
-
] })=>{
|
|
9
|
-
const [text, setText] = useState('');
|
|
10
|
-
const [file, setFile] = useState();
|
|
11
|
-
const value = {
|
|
12
|
-
text,
|
|
13
|
-
setText,
|
|
14
|
-
file,
|
|
15
|
-
setFile,
|
|
16
|
-
onSubmit: ()=>{
|
|
17
|
-
if (text.trim()) {
|
|
18
|
-
onSubmit({
|
|
19
|
-
text: text.trim(),
|
|
20
|
-
file
|
|
21
|
-
});
|
|
22
|
-
setText('');
|
|
23
|
-
setFile(void 0);
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
submiting,
|
|
27
|
-
uploading,
|
|
28
|
-
accept: accept.map((type)=>{
|
|
29
|
-
switch(type){
|
|
30
|
-
case 'text':
|
|
31
|
-
return 'text/plain';
|
|
32
|
-
case 'image':
|
|
33
|
-
return 'image/*';
|
|
34
|
-
case 'pdf':
|
|
35
|
-
return 'application/pdf';
|
|
36
|
-
case 'excel':
|
|
37
|
-
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
|
38
|
-
case 'word':
|
|
39
|
-
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
|
40
|
-
default:
|
|
41
|
-
return type;
|
|
42
|
-
}
|
|
43
|
-
}).join(',')
|
|
44
|
-
};
|
|
45
|
-
return /*#__PURE__*/ jsx(PromptInputContext.Provider, {
|
|
46
|
-
value: value,
|
|
47
|
-
children: children
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
export { Provider };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Paper } from "@mantine/core";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
import { Provider } from "./PromptInputProvider.js";
|
|
5
|
-
const Root = ({ className, onSubmit, submiting, uploading, accept, ...props })=>/*#__PURE__*/ jsx(Provider, {
|
|
6
|
-
onSubmit: onSubmit,
|
|
7
|
-
submiting: submiting,
|
|
8
|
-
uploading: uploading,
|
|
9
|
-
accept: accept,
|
|
10
|
-
children: /*#__PURE__*/ jsx(Paper, {
|
|
11
|
-
radius: "md",
|
|
12
|
-
withBorder: true,
|
|
13
|
-
className: clsx('rolder-prompt-input-root', className),
|
|
14
|
-
...props
|
|
15
|
-
})
|
|
16
|
-
});
|
|
17
|
-
export { Root };
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type Accept = 'text' | 'image' | 'pdf' | 'excel' | 'word';
|
|
2
|
-
export interface PromptInputProps {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
onSubmit: ({ text, file }: {
|
|
5
|
-
text: string;
|
|
6
|
-
file?: File;
|
|
7
|
-
}) => void;
|
|
8
|
-
submiting: boolean;
|
|
9
|
-
uploading: boolean;
|
|
10
|
-
accept?: Accept[];
|
|
11
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|