@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
- 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,
@@ -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,
@@ -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
- const sendMessage = async () => {
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
- const response = await fetch(`${apiUrl}/api/chat`, {
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nethru/kit",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "A React component library by Nethru",
5
5
  "main": "dist/index.js",
6
6
  "homepage": ".",