@nethru/kit 1.1.6 → 1.1.8
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
|
-
|
|
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,
|
|
@@ -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
|
|
13
|
+
//if(message.role === 'assistant') console.log(message);
|
|
14
14
|
}, [messages.length]);
|
|
15
15
|
return /*#__PURE__*/_jsxs("div", {
|
|
16
16
|
style: styles.container,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { getConfig } from "../../../js/config";
|
|
3
|
+
import { isPageAnalysisIntent } from "../../../js/promptIntent";
|
|
3
4
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
5
|
const ChatContext = /*#__PURE__*/createContext();
|
|
5
6
|
export function ChatProvider({
|
|
@@ -15,6 +16,7 @@ export function ChatProvider({
|
|
|
15
16
|
const [model, setModel] = useState('gpt-4.1-mini');
|
|
16
17
|
const [tools, setTools] = useState([]);
|
|
17
18
|
const chatContainerRef = useRef(null);
|
|
19
|
+
const mainPageRef = useRef(null);
|
|
18
20
|
useEffect(() => {
|
|
19
21
|
loadModels();
|
|
20
22
|
// loadTools();
|
|
@@ -51,10 +53,48 @@ export function ChatProvider({
|
|
|
51
53
|
console.error('Error loading tools:', error);
|
|
52
54
|
}
|
|
53
55
|
};
|
|
54
|
-
|
|
56
|
+
async function answer(message) {
|
|
57
|
+
const {
|
|
58
|
+
apiUrl
|
|
59
|
+
} = getConfig();
|
|
60
|
+
const response = await fetch(`${apiUrl}/api/chat`, {
|
|
61
|
+
method: 'POST',
|
|
62
|
+
headers: {
|
|
63
|
+
'Content-Type': 'application/json'
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
conversationId: conversationId,
|
|
67
|
+
message: message,
|
|
68
|
+
provider: provider,
|
|
69
|
+
model: model
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
return await response.json();
|
|
73
|
+
}
|
|
74
|
+
async function analyzePage(message) {
|
|
75
|
+
if (!mainPageRef.current) throw new Error('No main page');
|
|
55
76
|
const {
|
|
56
77
|
apiUrl
|
|
57
78
|
} = getConfig();
|
|
79
|
+
const html = mainPageRef.current?.innerHTML;
|
|
80
|
+
const response = await fetch(`${apiUrl}/api/pages/analyze`, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: {
|
|
83
|
+
'Content-Type': 'application/json'
|
|
84
|
+
},
|
|
85
|
+
body: JSON.stringify({
|
|
86
|
+
conversationId: conversationId,
|
|
87
|
+
message: message,
|
|
88
|
+
htmlContent: html,
|
|
89
|
+
pageUrl: window.location.href,
|
|
90
|
+
provider: provider,
|
|
91
|
+
model: model,
|
|
92
|
+
forceRefresh: true
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
return await response.json();
|
|
96
|
+
}
|
|
97
|
+
const sendMessage = async () => {
|
|
58
98
|
const message = inputValue.trim();
|
|
59
99
|
if (!message) return;
|
|
60
100
|
const userMessage = {
|
|
@@ -68,19 +108,7 @@ export function ChatProvider({
|
|
|
68
108
|
setInputValue('');
|
|
69
109
|
setIsLoading(true);
|
|
70
110
|
try {
|
|
71
|
-
|
|
72
|
-
method: 'POST',
|
|
73
|
-
headers: {
|
|
74
|
-
'Content-Type': 'application/json'
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify({
|
|
77
|
-
message: message,
|
|
78
|
-
conversationId: conversationId,
|
|
79
|
-
provider: provider,
|
|
80
|
-
model: model
|
|
81
|
-
})
|
|
82
|
-
});
|
|
83
|
-
const data = await response.json();
|
|
111
|
+
let data = isPageAnalysisIntent(message) ? await analyzePage(message) : await answer(message);
|
|
84
112
|
setConversationId(data.conversationId);
|
|
85
113
|
setMessages(prev => [...prev, {
|
|
86
114
|
role: data.role,
|
|
@@ -117,6 +145,7 @@ export function ChatProvider({
|
|
|
117
145
|
setModel,
|
|
118
146
|
tools,
|
|
119
147
|
chatContainerRef,
|
|
148
|
+
mainPageRef,
|
|
120
149
|
sendMessage,
|
|
121
150
|
clearChat,
|
|
122
151
|
conversationId
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function isPageAnalysisIntent(userPrompt) {
|
|
2
|
+
if (!userPrompt || userPrompt.trim() === "") return false;
|
|
3
|
+
const analysisKeywords = ["요약", "정리", "분석", "설명", "페이지", "화면", "글", "기사", "문서", "내용", "포스트", "블로그", "뭐야", "뭔가", "무엇", "어떤", "핵심", "주요", "포인트", "요점", "이", "현재", "지금", "여기", "summarize", "summary", "analyze", "analysis", "explain", "this page", "current page", "this article", "this post"];
|
|
4
|
+
const excludeKeywords = ["http://", "https://", "www.", "날씨", "weather", "뉴스", "news", "코드", "code", "프로그램", "program"];
|
|
5
|
+
const prompt = userPrompt.toLowerCase();
|
|
6
|
+
|
|
7
|
+
// 제외 키워드 포함 시, "이 페이지" 패턴만 예외 허용
|
|
8
|
+
if (excludeKeywords.some(k => prompt.includes(k))) {
|
|
9
|
+
if (!(prompt.includes("이") && prompt.includes("페이지"))) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const matchedKeywords = analysisKeywords.filter(k => prompt.includes(k));
|
|
14
|
+
|
|
15
|
+
// 최소 2개 이상의 키워드 매칭
|
|
16
|
+
if (matchedKeywords.length >= 2) return true;
|
|
17
|
+
|
|
18
|
+
// 단일 키워드지만 강한 패턴
|
|
19
|
+
const strongPatterns = ["요약해", "정리해", "분석해", "설명해", "요약 해", "정리 해", "분석 해", "설명 해", "페이지 요약", "페이지 정리", "페이지 분석", "summarize this", "analyze this", "explain this"];
|
|
20
|
+
if (strongPatterns.some(p => prompt.includes(p))) return true;
|
|
21
|
+
return false;
|
|
22
|
+
}
|