@nethru/kit 1.1.5 → 1.1.7

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.
@@ -1,20 +1,22 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import { Stack } from "@mui/material";
3
3
  import { useChatContext } from './contexts/ChatContext';
4
4
  import ChatMessages from './ChatMessages';
5
5
  import ChatInput from './ChatInput';
6
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  function AiChat({
8
+ mainPageRef,
8
9
  sx
9
10
  }) {
10
11
  const {
11
12
  messages,
12
- inputValue,
13
- setInputValue,
14
13
  isLoading,
15
14
  chatContainerRef,
16
- sendMessage
15
+ mainPageRef: _mainPageRef
17
16
  } = useChatContext();
17
+ useEffect(() => {
18
+ _mainPageRef.current = mainPageRef.current;
19
+ }, [mainPageRef.current]);
18
20
  return /*#__PURE__*/_jsxs(Stack, {
19
21
  sx: {
20
22
  ...styles.container,
@@ -24,12 +26,7 @@ function AiChat({
24
26
  messages: messages,
25
27
  isLoading: isLoading,
26
28
  chatContainerRef: chatContainerRef
27
- }), /*#__PURE__*/_jsx(ChatInput, {
28
- inputValue: inputValue,
29
- setInputValue: setInputValue,
30
- onSend: sendMessage,
31
- isLoading: isLoading
32
- })]
29
+ }), /*#__PURE__*/_jsx(ChatInput, {})]
33
30
  });
34
31
  }
35
32
  export default AiChat;
@@ -1,25 +1,33 @@
1
- import React from 'react';
1
+ import React, { useRef, useEffect, useState } from 'react';
2
2
  import { Box, FormControl, IconButton, Stack, TextField } from '@mui/material';
3
3
  import { Send as SendIcon } from '@mui/icons-material';
4
+ import { useChatContext } from "./contexts/ChatContext";
4
5
  import ModelSelect from "./ModelSelect";
5
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
- const ChatInput = ({
7
- inputValue,
8
- setInputValue,
9
- onSend,
10
- isLoading
11
- }) => {
7
+ const ChatInput = () => {
8
+ const inputRef = useRef(null);
9
+ const [selectOpen, setSelectOpen] = useState(false);
10
+ const {
11
+ inputValue,
12
+ setInputValue,
13
+ isLoading,
14
+ sendMessage
15
+ } = useChatContext();
12
16
  const handleKeyPress = e => {
13
17
  if (e.key === 'Enter' && !e.shiftKey) {
14
18
  e.preventDefault();
15
- onSend();
19
+ sendMessage();
16
20
  }
17
21
  };
22
+ useEffect(() => {
23
+ if (!isLoading && !selectOpen && inputRef.current) inputRef.current.focus();
24
+ }, [isLoading, selectOpen]);
18
25
  return /*#__PURE__*/_jsx(Box, {
19
26
  sx: styles.container,
20
27
  children: /*#__PURE__*/_jsxs(Stack, {
21
28
  sx: styles.textArea,
22
29
  children: [/*#__PURE__*/_jsx(TextField, {
30
+ inputRef: inputRef,
23
31
  fullWidth: true,
24
32
  multiline: true,
25
33
  placeholder: "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694...",
@@ -41,9 +49,13 @@ const ChatInput = ({
41
49
  alignItems: "center",
42
50
  children: [/*#__PURE__*/_jsx(FormControl, {
43
51
  variant: "standard",
44
- children: /*#__PURE__*/_jsx(ModelSelect, {})
52
+ children: /*#__PURE__*/_jsx(ModelSelect, {
53
+ open: selectOpen,
54
+ onOpen: () => setSelectOpen(true),
55
+ onClose: () => setSelectOpen(false)
56
+ })
45
57
  }), /*#__PURE__*/_jsx(IconButton, {
46
- onClick: onSend,
58
+ onClick: sendMessage,
47
59
  disabled: isLoading || !inputValue.trim(),
48
60
  sx: styles.iconButton,
49
61
  children: /*#__PURE__*/_jsx(SendIcon, {
@@ -10,7 +10,7 @@ const ChatMessages = ({
10
10
  useEffect(() => {
11
11
  if (messages.length === 0) return;
12
12
  const message = messages[messages.length - 1];
13
- if (message.role === 'assistant') console.log(message);
13
+ //if(message.role === 'assistant') console.log(message);
14
14
  }, [messages.length]);
15
15
  return /*#__PURE__*/_jsxs("div", {
16
16
  style: styles.container,
@@ -2,7 +2,9 @@ import React from "react";
2
2
  import { Box, Divider, MenuItem, Select } from "@mui/material";
3
3
  import { useChatContext } from "./contexts/ChatContext";
4
4
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
5
- export default function ModelSelect() {
5
+ export default function ModelSelect({
6
+ ...props
7
+ }) {
6
8
  const {
7
9
  model,
8
10
  setModel,
@@ -25,6 +27,7 @@ export default function ModelSelect() {
25
27
  disableUnderline: true,
26
28
  sx: styles.select,
27
29
  renderValue: value => findModel(providers, value)?.name,
30
+ ...props,
28
31
  children: makeOptions(providers)
29
32
  })
30
33
  });
@@ -15,6 +15,7 @@ export function ChatProvider({
15
15
  const [model, setModel] = useState('gpt-4.1-mini');
16
16
  const [tools, setTools] = useState([]);
17
17
  const chatContainerRef = useRef(null);
18
+ const mainPageRef = useRef(null);
18
19
  useEffect(() => {
19
20
  loadModels();
20
21
  // loadTools();
@@ -80,8 +81,9 @@ export function ChatProvider({
80
81
  model: model
81
82
  })
82
83
  });
83
- const data = await response.json();
84
+ let data = await response.json();
84
85
  setConversationId(data.conversationId);
86
+ if (isPageAnalysisIntent(data)) data = await sendPageAnalysisRequest(data);
85
87
  setMessages(prev => [...prev, {
86
88
  role: data.role,
87
89
  kinds: data.kinds,
@@ -100,6 +102,40 @@ export function ChatProvider({
100
102
  setIsLoading(false);
101
103
  }
102
104
  };
105
+ const isPageAnalysisIntent = data => {
106
+ return data.content.filter(c => c.type === 'tool').some(c => c.name === 'detect-page-analysis-intent' && c.result === 'true');
107
+ };
108
+ const sendPageAnalysisRequest = async data => {
109
+ if (!mainPageRef.current) return data;
110
+ const {
111
+ apiUrl
112
+ } = getConfig();
113
+ const html = mainPageRef.current?.innerHTML;
114
+ try {
115
+ const response = await fetch(`${apiUrl}/api/pages/analyze`, {
116
+ method: 'POST',
117
+ headers: {
118
+ 'Content-Type': 'application/json'
119
+ },
120
+ body: JSON.stringify({
121
+ htmlContent: html,
122
+ pageUrl: window.location.href,
123
+ provider: provider,
124
+ model: model
125
+ })
126
+ });
127
+ const json = await response.json();
128
+ if (json.summary) {
129
+ data.content = [{
130
+ type: 'text',
131
+ value: json.summary
132
+ }];
133
+ }
134
+ } catch (error) {
135
+ console.error('Error:', error);
136
+ }
137
+ return data;
138
+ };
103
139
  const clearChat = () => {
104
140
  setMessages([]);
105
141
  setConversationId(null);
@@ -117,6 +153,7 @@ export function ChatProvider({
117
153
  setModel,
118
154
  tools,
119
155
  chatContainerRef,
156
+ mainPageRef,
120
157
  sendMessage,
121
158
  clearChat,
122
159
  conversationId
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nethru/kit",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "A React component library by Nethru",
5
5
  "main": "dist/index.js",
6
6
  "homepage": ".",