@nethru/kit 1.1.7 → 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,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({
|
|
@@ -52,10 +53,48 @@ export function ChatProvider({
|
|
|
52
53
|
console.error('Error loading tools:', error);
|
|
53
54
|
}
|
|
54
55
|
};
|
|
55
|
-
|
|
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');
|
|
56
76
|
const {
|
|
57
77
|
apiUrl
|
|
58
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 () => {
|
|
59
98
|
const message = inputValue.trim();
|
|
60
99
|
if (!message) return;
|
|
61
100
|
const userMessage = {
|
|
@@ -69,21 +108,8 @@ export function ChatProvider({
|
|
|
69
108
|
setInputValue('');
|
|
70
109
|
setIsLoading(true);
|
|
71
110
|
try {
|
|
72
|
-
|
|
73
|
-
method: 'POST',
|
|
74
|
-
headers: {
|
|
75
|
-
'Content-Type': 'application/json'
|
|
76
|
-
},
|
|
77
|
-
body: JSON.stringify({
|
|
78
|
-
message: message,
|
|
79
|
-
conversationId: conversationId,
|
|
80
|
-
provider: provider,
|
|
81
|
-
model: model
|
|
82
|
-
})
|
|
83
|
-
});
|
|
84
|
-
let data = await response.json();
|
|
111
|
+
let data = isPageAnalysisIntent(message) ? await analyzePage(message) : await answer(message);
|
|
85
112
|
setConversationId(data.conversationId);
|
|
86
|
-
if (isPageAnalysisIntent(data)) data = await sendPageAnalysisRequest(data);
|
|
87
113
|
setMessages(prev => [...prev, {
|
|
88
114
|
role: data.role,
|
|
89
115
|
kinds: data.kinds,
|
|
@@ -102,40 +128,6 @@ export function ChatProvider({
|
|
|
102
128
|
setIsLoading(false);
|
|
103
129
|
}
|
|
104
130
|
};
|
|
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
|
-
};
|
|
139
131
|
const clearChat = () => {
|
|
140
132
|
setMessages([]);
|
|
141
133
|
setConversationId(null);
|
|
@@ -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
|
+
}
|