@nethru/kit 1.1.15 → 1.1.18
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/chat/AiChat.js +7 -5
- package/dist/components/chat/ChatMessage.js +51 -12
- package/dist/components/chat/ChatMessages.js +9 -3
- package/dist/components/chat/contexts/ChatContext.js +26 -16
- package/dist/components/chat/input/ModelSelect.js +18 -9
- package/package.json +1 -1
- package/dist/js/promptIntent.js +0 -0
|
@@ -5,19 +5,21 @@ import ChatMessages from './ChatMessages';
|
|
|
5
5
|
import ChatInput from './input/ChatInput';
|
|
6
6
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
7
|
function AiChat({
|
|
8
|
-
|
|
8
|
+
pageRef,
|
|
9
|
+
pagePath,
|
|
9
10
|
sx
|
|
10
11
|
}) {
|
|
11
12
|
const {
|
|
12
13
|
messages,
|
|
13
14
|
isLoading,
|
|
14
15
|
chatContainerRef,
|
|
15
|
-
|
|
16
|
+
pageRef: _pageRef,
|
|
17
|
+
setPagePath
|
|
16
18
|
} = useChatContext();
|
|
17
19
|
useEffect(() => {
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
}, [
|
|
20
|
+
if (pageRef) _pageRef.current = pageRef.current;
|
|
21
|
+
setPagePath(pagePath);
|
|
22
|
+
}, [pageRef?.current, pagePath]);
|
|
21
23
|
return /*#__PURE__*/_jsxs(Stack, {
|
|
22
24
|
sx: {
|
|
23
25
|
...styles.container,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import { Box, keyframes } from '@mui/material';
|
|
2
|
+
import { Box, IconButton, keyframes, Stack, Tooltip } from '@mui/material';
|
|
3
3
|
import MarkdownContent from "./content/MarkdownContent";
|
|
4
4
|
import ToolContent from "./content/ToolContent";
|
|
5
5
|
import { ToolContextProvider } from "./contexts/ToolContext";
|
|
6
|
+
import ReplayRoundedIcon from "@mui/icons-material/ReplayRounded";
|
|
6
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
8
|
const slideIn = keyframes`
|
|
8
9
|
from {
|
|
@@ -15,20 +16,43 @@ const slideIn = keyframes`
|
|
|
15
16
|
}
|
|
16
17
|
`;
|
|
17
18
|
const ChatMessage = ({
|
|
18
|
-
message
|
|
19
|
+
message,
|
|
20
|
+
retryable,
|
|
21
|
+
onRetry
|
|
19
22
|
}) => {
|
|
20
23
|
const textContent = useMemo(() => message.content.filter(c => c.type === 'text'), [message]);
|
|
21
|
-
return /*#__PURE__*/_jsxs(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
return /*#__PURE__*/_jsxs(Stack, {
|
|
25
|
+
gap: 0.5,
|
|
26
|
+
sx: {
|
|
27
|
+
...styles.options.base,
|
|
28
|
+
...(retryable && styles.options.hover)
|
|
29
|
+
},
|
|
30
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
31
|
+
sx: message.role === 'user' ? styles.messageUser : styles.messageAssistant,
|
|
32
|
+
children: [/*#__PURE__*/_jsx(ToolContextProvider, {
|
|
33
|
+
message: message,
|
|
34
|
+
children: /*#__PURE__*/_jsx(ToolContent, {})
|
|
35
|
+
}), textContent.map((item, index) => /*#__PURE__*/_jsx(Box, {
|
|
36
|
+
sx: styles.contentItem,
|
|
37
|
+
children: /*#__PURE__*/_jsx(MarkdownContent, {
|
|
38
|
+
content: item.value
|
|
39
|
+
})
|
|
40
|
+
}, index))]
|
|
41
|
+
}), /*#__PURE__*/_jsx(Stack, {
|
|
42
|
+
className: "chat-options",
|
|
43
|
+
direction: "row",
|
|
44
|
+
justifyContent: "flex-end",
|
|
45
|
+
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
46
|
+
title: "\uC7AC\uC2DC\uB3C4",
|
|
47
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
48
|
+
onClick: onRetry,
|
|
49
|
+
size: "small",
|
|
50
|
+
children: /*#__PURE__*/_jsx(ReplayRoundedIcon, {
|
|
51
|
+
fontSize: "small"
|
|
52
|
+
})
|
|
53
|
+
})
|
|
30
54
|
})
|
|
31
|
-
}
|
|
55
|
+
})]
|
|
32
56
|
});
|
|
33
57
|
};
|
|
34
58
|
export default ChatMessage;
|
|
@@ -72,5 +96,20 @@ const styles = {
|
|
|
72
96
|
'&:last-child': {
|
|
73
97
|
marginBottom: 0
|
|
74
98
|
}
|
|
99
|
+
},
|
|
100
|
+
options: {
|
|
101
|
+
base: {
|
|
102
|
+
'& .chat-options': {
|
|
103
|
+
opacity: 0,
|
|
104
|
+
pointerEvents: 'none',
|
|
105
|
+
transition: 'opacity 0.15s ease'
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
hover: {
|
|
109
|
+
'&:hover .chat-options': {
|
|
110
|
+
opacity: 1,
|
|
111
|
+
pointerEvents: 'auto'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
75
114
|
}
|
|
76
115
|
};
|
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
2
|
import ChatMessage from './ChatMessage';
|
|
3
3
|
import LoadingIndicator from './LoadingIndicator';
|
|
4
|
+
import { useChatContext } from "./contexts/ChatContext";
|
|
4
5
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
6
|
const ChatMessages = ({
|
|
6
7
|
messages,
|
|
7
8
|
isLoading,
|
|
8
9
|
chatContainerRef
|
|
9
10
|
}) => {
|
|
11
|
+
const {
|
|
12
|
+
retrySend
|
|
13
|
+
} = useChatContext();
|
|
10
14
|
useEffect(() => {
|
|
11
15
|
if (messages.length === 0) return;
|
|
12
16
|
const message = messages[messages.length - 1];
|
|
13
17
|
//if(message.role === 'assistant') console.log(message);
|
|
14
18
|
}, [messages.length]);
|
|
19
|
+
const lastUserIdx = useMemo(() => messages.findLastIndex(m => m.role === 'user'), [messages.length]);
|
|
15
20
|
return /*#__PURE__*/_jsxs("div", {
|
|
16
21
|
style: styles.container,
|
|
17
22
|
ref: chatContainerRef,
|
|
18
23
|
children: [messages.map((message, index) => /*#__PURE__*/_jsx(ChatMessage, {
|
|
19
|
-
message: message
|
|
24
|
+
message: message,
|
|
25
|
+
retryable: !isLoading && index === lastUserIdx,
|
|
26
|
+
onRetry: _ => retrySend(message.content[0].value)
|
|
20
27
|
}, index)), isLoading && /*#__PURE__*/_jsx(LoadingIndicator, {})]
|
|
21
28
|
});
|
|
22
29
|
};
|
|
@@ -28,7 +35,6 @@ const styles = {
|
|
|
28
35
|
padding: '10px',
|
|
29
36
|
display: 'flex',
|
|
30
37
|
flexDirection: 'column',
|
|
31
|
-
gap: '1rem',
|
|
32
38
|
background: '#fcfcfd'
|
|
33
39
|
}
|
|
34
40
|
};
|
|
@@ -20,8 +20,9 @@ export function ChatProvider({
|
|
|
20
20
|
const [option, setOption] = useState();
|
|
21
21
|
const options = useMemo(() => defaultOptions);
|
|
22
22
|
const [tools, setTools] = useState([]);
|
|
23
|
+
const [pagePath, setPagePath] = useState();
|
|
23
24
|
const chatContainerRef = useRef(null);
|
|
24
|
-
const
|
|
25
|
+
const pageRef = useRef(null);
|
|
25
26
|
useEffect(() => {
|
|
26
27
|
loadModels();
|
|
27
28
|
// loadTools();
|
|
@@ -78,11 +79,11 @@ export function ChatProvider({
|
|
|
78
79
|
return await response.json();
|
|
79
80
|
}
|
|
80
81
|
async function analyzePage(message) {
|
|
81
|
-
if (!
|
|
82
|
+
if (!pageRef.current) throw new Error('No main page');
|
|
82
83
|
const {
|
|
83
84
|
apiUrl
|
|
84
85
|
} = getConfig();
|
|
85
|
-
const html =
|
|
86
|
+
const html = pageRef.current?.innerHTML;
|
|
86
87
|
const response = await fetch(`${apiUrl}/api/pages/analyze`, {
|
|
87
88
|
method: 'POST',
|
|
88
89
|
headers: {
|
|
@@ -92,7 +93,7 @@ export function ChatProvider({
|
|
|
92
93
|
conversationId: conversationId,
|
|
93
94
|
message: message,
|
|
94
95
|
htmlContent: html,
|
|
95
|
-
|
|
96
|
+
pagePath: pagePath,
|
|
96
97
|
provider: provider,
|
|
97
98
|
model: model,
|
|
98
99
|
forceRefresh: true
|
|
@@ -100,18 +101,20 @@ export function ChatProvider({
|
|
|
100
101
|
});
|
|
101
102
|
return await response.json();
|
|
102
103
|
}
|
|
103
|
-
const sendMessage = async () => {
|
|
104
|
-
const message = inputValue.trim();
|
|
104
|
+
const sendMessage = async (messageToSend = null) => {
|
|
105
|
+
const message = messageToSend ?? inputValue.trim();
|
|
105
106
|
if (!message) return;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
if (!messageToSend) {
|
|
108
|
+
const userMessage = {
|
|
109
|
+
role: 'user',
|
|
110
|
+
content: [{
|
|
111
|
+
type: 'text',
|
|
112
|
+
value: message
|
|
113
|
+
}]
|
|
114
|
+
};
|
|
115
|
+
setMessages(prev => [...prev, userMessage]);
|
|
116
|
+
setInputValue('');
|
|
117
|
+
}
|
|
115
118
|
setIsLoading(true);
|
|
116
119
|
try {
|
|
117
120
|
let data = option === 'ANALYZE' ? await analyzePage(message) : await answer(message);
|
|
@@ -139,6 +142,10 @@ export function ChatProvider({
|
|
|
139
142
|
setConversationId(null);
|
|
140
143
|
setInputValue('');
|
|
141
144
|
};
|
|
145
|
+
const retrySend = async retryMessage => {
|
|
146
|
+
setMessages(prev => prev.at(-1)?.role === 'assistant' ? prev.slice(0, -1) : prev);
|
|
147
|
+
await sendMessage(retryMessage);
|
|
148
|
+
};
|
|
142
149
|
const value = {
|
|
143
150
|
messages,
|
|
144
151
|
inputValue,
|
|
@@ -153,9 +160,12 @@ export function ChatProvider({
|
|
|
153
160
|
option,
|
|
154
161
|
setOption,
|
|
155
162
|
tools,
|
|
163
|
+
pagePath,
|
|
164
|
+
setPagePath,
|
|
156
165
|
chatContainerRef,
|
|
157
|
-
|
|
166
|
+
pageRef,
|
|
158
167
|
sendMessage,
|
|
168
|
+
retrySend,
|
|
159
169
|
clearChat,
|
|
160
170
|
conversationId
|
|
161
171
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Divider, MenuItem, Select } from "@mui/material";
|
|
3
3
|
import { useChatContext } from "../contexts/ChatContext";
|
|
4
|
+
import typography from "@nethru/ui/base/styles/typography";
|
|
4
5
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
6
|
export default function ModelSelect({
|
|
6
7
|
...props
|
|
@@ -26,7 +27,10 @@ export default function ModelSelect({
|
|
|
26
27
|
onChange: onChange,
|
|
27
28
|
disableUnderline: true,
|
|
28
29
|
sx: styles.select,
|
|
29
|
-
renderValue: value =>
|
|
30
|
+
renderValue: value => /*#__PURE__*/_jsx(Box, {
|
|
31
|
+
sx: styles.value,
|
|
32
|
+
children: findModel(providers, value)?.name
|
|
33
|
+
}),
|
|
30
34
|
...props,
|
|
31
35
|
children: makeOptions(providers)
|
|
32
36
|
})
|
|
@@ -41,10 +45,10 @@ function makeOptions(providers) {
|
|
|
41
45
|
value: model.id,
|
|
42
46
|
children: /*#__PURE__*/_jsxs(Box, {
|
|
43
47
|
children: [/*#__PURE__*/_jsx(Box, {
|
|
44
|
-
sx: styles.name,
|
|
48
|
+
sx: styles.option.name,
|
|
45
49
|
children: model.name
|
|
46
50
|
}), /*#__PURE__*/_jsx(Box, {
|
|
47
|
-
sx: styles.desc,
|
|
51
|
+
sx: styles.option.desc,
|
|
48
52
|
children: model.description
|
|
49
53
|
})]
|
|
50
54
|
})
|
|
@@ -72,12 +76,17 @@ const styles = {
|
|
|
72
76
|
color: '#666',
|
|
73
77
|
fontSize: '11px'
|
|
74
78
|
},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
fontSize: '12px'
|
|
79
|
+
value: {
|
|
80
|
+
fontFamily: typography.fontFamily
|
|
78
81
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
option: {
|
|
83
|
+
name: {
|
|
84
|
+
fontWeight: 400,
|
|
85
|
+
fontSize: '12px'
|
|
86
|
+
},
|
|
87
|
+
desc: {
|
|
88
|
+
fontSize: '11px',
|
|
89
|
+
fontWeight: 200
|
|
90
|
+
}
|
|
82
91
|
}
|
|
83
92
|
};
|
package/package.json
CHANGED
package/dist/js/promptIntent.js
DELETED
|
File without changes
|