@smarter.sh/ui-chat 0.2.7 → 0.2.9
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/README.md +24 -11
- package/dist/smarter-chat-library.es.js +3195 -3193
- package/dist/smarter-chat-library.es.js.map +1 -1
- package/dist/smarter-chat-library.umd.js +35 -35
- package/dist/smarter-chat-library.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Console/Component.jsx +1 -1
- package/src/components/SmarterChat/Component.jsx +16 -16
- package/src/components/SmarterChat/api.js +20 -57
- package/src/components/SmarterChat/utils.jsx +2 -1
- package/src/components/shared/cookie.js +39 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smarter.sh/ui-chat",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "chatbot React.js component for the https://smarter.sh no-code, plugin based AI platform",
|
|
5
5
|
"homepage": "https://smarter.sh",
|
|
6
6
|
"main": "dist/smarter-chat-library.umd.js",
|
|
@@ -35,12 +35,11 @@ import { Console } from "../Console/index.js";
|
|
|
35
35
|
import "./styles.css";
|
|
36
36
|
import { ContainerLayout, ContentLayout, WorkbenchLayout, ChatAppLayout, ConsoleLayout } from "./Layout.js";
|
|
37
37
|
import { MessageDirectionEnum, SenderRoleEnum } from "./enums.js";
|
|
38
|
-
import {
|
|
38
|
+
import { fetchConfig, fetchPrompt } from "./api.js";
|
|
39
|
+
import { setCookie } from "../shared/cookie.js"
|
|
39
40
|
import { cookieMetaFactory, messageFactory, chatMessages2RequestMessages, chatInit } from "./utils.jsx";
|
|
40
41
|
import { ErrorBoundary } from "./ErrorBoundary.jsx";
|
|
41
42
|
|
|
42
|
-
const DEBUG_MODE = false;
|
|
43
|
-
|
|
44
43
|
// The main chat component. This is the top-level component that
|
|
45
44
|
// is exported and used in the index.js file. It is responsible for
|
|
46
45
|
// managing the chat message thread, sending messages to the backend
|
|
@@ -50,6 +49,7 @@ function SmarterChat({
|
|
|
50
49
|
apiKey, // NOT USED. TO DELETE.
|
|
51
50
|
toggleMetadata, // show/hide toggle button to show/hide the chat thread metadata
|
|
52
51
|
csrfCookieName = "csrftoken", // the Django CSRF cookie.
|
|
52
|
+
csrftoken, // the Django CSRF token. Passed from the Django template in the Smarter web console workbench.
|
|
53
53
|
debugCookieName, // the Smarter chat debug cookie. Set here.
|
|
54
54
|
debugCookieExpiration, // the Smarter chat debug cookie. Set here.
|
|
55
55
|
sessionCookieName = "session_key", // the Smarter chat session cookie. Set here, where the user creates a new chat session.
|
|
@@ -74,7 +74,7 @@ function SmarterChat({
|
|
|
74
74
|
const [isValid, setIsValid] = useState(false);
|
|
75
75
|
const [isDeployed, setIsDeployed] = useState(false);
|
|
76
76
|
|
|
77
|
-
const [debugMode, setDebugMode] = useState(
|
|
77
|
+
const [debugMode, setDebugMode] = useState(false);
|
|
78
78
|
const [messages, setMessages] = useState([]);
|
|
79
79
|
|
|
80
80
|
// future use
|
|
@@ -89,10 +89,10 @@ function SmarterChat({
|
|
|
89
89
|
const fileInputRef = useRef(null);
|
|
90
90
|
|
|
91
91
|
// cookie management
|
|
92
|
-
const csrfCookie = cookieMetaFactory(csrfCookieName, null, cookieDomain); // we read this but never set it.
|
|
93
|
-
const authTokenCookie = cookieMetaFactory(authSessionCookieName, null, cookieDomain); // we read this but never set it.
|
|
94
|
-
const sessionCookie = cookieMetaFactory(sessionCookieName, sessionCookieExpiration, cookieDomain);
|
|
95
|
-
const debugCookie = cookieMetaFactory(debugCookieName, debugCookieExpiration, cookieDomain);
|
|
92
|
+
const csrfCookie = cookieMetaFactory(csrfCookieName, null, cookieDomain, csrftoken); // we read this but never set it.
|
|
93
|
+
const authTokenCookie = cookieMetaFactory(authSessionCookieName, null, cookieDomain, null); // we read this but never set it.
|
|
94
|
+
const sessionCookie = cookieMetaFactory(sessionCookieName, sessionCookieExpiration, cookieDomain, null);
|
|
95
|
+
const debugCookie = cookieMetaFactory(debugCookieName, debugCookieExpiration, cookieDomain, null);
|
|
96
96
|
const cookies = {
|
|
97
97
|
authTokenCookie: authTokenCookie, // the Django session cookie. Set when the user logs in to the Smarter web console app.
|
|
98
98
|
// typically this is not required for the chat app when running inside the
|
|
@@ -105,10 +105,11 @@ function SmarterChat({
|
|
|
105
105
|
|
|
106
106
|
const refetchConfig = async () => {
|
|
107
107
|
const newConfig = await fetchConfig(configApiUrl, cookies);
|
|
108
|
+
setDebugMode(newConfig?.debug_mode);
|
|
109
|
+
setCookie(cookies.debugCookie, debugMode);
|
|
108
110
|
|
|
109
|
-
if (
|
|
110
|
-
console.log("
|
|
111
|
-
console.log("fetchAndSetConfig() config:", newConfig);
|
|
111
|
+
if (debugMode) {
|
|
112
|
+
console.log("refetchConfig() config:", newConfig);
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
PropTypes.checkPropTypes(ConfigPropTypes, newConfig, "prop", "SmarterChat");
|
|
@@ -120,7 +121,9 @@ function SmarterChat({
|
|
|
120
121
|
try {
|
|
121
122
|
const newConfig = await refetchConfig();
|
|
122
123
|
|
|
123
|
-
|
|
124
|
+
if (debugMode) {
|
|
125
|
+
console.log("fetchAndSetConfig() config:", newConfig);
|
|
126
|
+
}
|
|
124
127
|
|
|
125
128
|
setPlaceholderText(newConfig.chatbot.app_placeholder);
|
|
126
129
|
setConfigApiUrl(newConfig.chatbot.url_chatbot);
|
|
@@ -153,7 +156,7 @@ function SmarterChat({
|
|
|
153
156
|
setIsReady(true);
|
|
154
157
|
setIsTyping(false);
|
|
155
158
|
|
|
156
|
-
if (
|
|
159
|
+
if (debugMode) {
|
|
157
160
|
console.log("fetchAndSetConfig() done!");
|
|
158
161
|
}
|
|
159
162
|
} catch (error) {
|
|
@@ -199,9 +202,6 @@ function SmarterChat({
|
|
|
199
202
|
}
|
|
200
203
|
if (["smarter", "system", "tool"].includes(message.sender)) {
|
|
201
204
|
// toggle backend messages
|
|
202
|
-
if (debugMode) {
|
|
203
|
-
//console.log("toggle message:", message);
|
|
204
|
-
}
|
|
205
205
|
return { ...message, display: newValue };
|
|
206
206
|
} else {
|
|
207
207
|
// always show user and assistant messages
|
|
@@ -22,62 +22,15 @@
|
|
|
22
22
|
v0.5.0: ./test/events/langchain.response.v0.5.0.json
|
|
23
23
|
-----------------------------------------------------------------------------*/
|
|
24
24
|
|
|
25
|
+
import { getCookie, setCookie } from "../shared/cookie";
|
|
26
|
+
|
|
25
27
|
// Set to true to enable local development mode,
|
|
26
28
|
// which will simulate the server-side API calls.
|
|
27
29
|
const developerMode = false;
|
|
30
|
+
const debugMode = getCookie(cookies.debugCookie) === "true" || developerMode;
|
|
28
31
|
const userAgent = "SmarterChat/1.0";
|
|
29
32
|
const applicationJson = "application/json";
|
|
30
33
|
|
|
31
|
-
function getCookie(cookie, defaultValue = null) {
|
|
32
|
-
console.log("getCookie(): cookie", cookie);
|
|
33
|
-
let cookieValue = null;
|
|
34
|
-
const expectedDomain = cookie.domain;
|
|
35
|
-
|
|
36
|
-
// Check if the cookie is set for the expected domain. example: alpha.platform.smarter.sh
|
|
37
|
-
if (window.location.hostname === expectedDomain && document.cookie && document.cookie !== "") {
|
|
38
|
-
const cookies = document.cookie.split(";");
|
|
39
|
-
for (let i = 0; i < cookies.length; i++) {
|
|
40
|
-
const thisCookie = cookies[i].trim();
|
|
41
|
-
if (thisCookie.substring(0, cookie.name.length + 1) === cookie.name + "=") {
|
|
42
|
-
cookieValue = decodeURIComponent(thisCookie.substring(cookie.name.length + 1));
|
|
43
|
-
console.log("getCookie(): ", cookie.domain, cookie.name, cookieValue);
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return cookieValue || defaultValue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function setCookie(cookie, value) {
|
|
53
|
-
const currentPath = window.location.pathname;
|
|
54
|
-
if (value) {
|
|
55
|
-
const expirationDate = new Date();
|
|
56
|
-
expirationDate.setTime(expirationDate.getTime() + cookie.expiration);
|
|
57
|
-
const expires = expirationDate.toUTCString();
|
|
58
|
-
const cookieData = `${cookie.name}=${value}; path=${currentPath}; SameSite=Lax; expires=${expires}`;
|
|
59
|
-
document.cookie = cookieData;
|
|
60
|
-
if (developerMode) {
|
|
61
|
-
console.log(
|
|
62
|
-
"setCookie(): ",
|
|
63
|
-
cookieData,
|
|
64
|
-
"now: ",
|
|
65
|
-
new Date().toUTCString(),
|
|
66
|
-
"expiration: ",
|
|
67
|
-
expirationDate.toUTCString(),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
} else {
|
|
71
|
-
// Unset the cookie by setting its expiration date to the past
|
|
72
|
-
const expirationDate = new Date(0);
|
|
73
|
-
const expires = expirationDate.toUTCString();
|
|
74
|
-
const cookieData = `${cookie.name}=; path=${currentPath}; SameSite=Lax; expires=${expires}`;
|
|
75
|
-
document.cookie = cookieData;
|
|
76
|
-
if (developerMode) {
|
|
77
|
-
console.log("setCookie(): Unsetting cookie", cookieData);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
34
|
|
|
82
35
|
function promptRequestBodyFactory(messages, config) {
|
|
83
36
|
const body = {
|
|
@@ -88,7 +41,9 @@ function promptRequestBodyFactory(messages, config) {
|
|
|
88
41
|
}
|
|
89
42
|
|
|
90
43
|
function requestHeadersFactory(cookies) {
|
|
91
|
-
|
|
44
|
+
if (debugMode) {
|
|
45
|
+
console.log("requestHeadersFactory(): cookies", cookies);
|
|
46
|
+
}
|
|
92
47
|
function getRequestCookies(cookies) {
|
|
93
48
|
// Ensure that csrftoken is not included in the Cookie header.
|
|
94
49
|
const cookiesArray = document.cookie.split(";").filter((cookie) => {
|
|
@@ -96,6 +51,8 @@ function requestHeadersFactory(cookies) {
|
|
|
96
51
|
return !trimmedCookie.startsWith(`${cookies.csrfCookie.name}=`);
|
|
97
52
|
});
|
|
98
53
|
const selectedCookies = cookiesArray.join("; ");
|
|
54
|
+
|
|
55
|
+
// example return value: "_ga=GA1.1.1244182935.1742308279; _ga_SK81M5HQYS=GS1.1.1742316653.3.1.1742320251.0.0.0"
|
|
99
56
|
return selectedCookies;
|
|
100
57
|
}
|
|
101
58
|
|
|
@@ -112,7 +69,9 @@ function requestHeadersFactory(cookies) {
|
|
|
112
69
|
Authorization: `Bearer ${authToken}`,
|
|
113
70
|
"User-Agent": userAgent,
|
|
114
71
|
};
|
|
115
|
-
|
|
72
|
+
if (debugMode) {
|
|
73
|
+
console.log("requestHeadersFactory(): requestHeaders", requestHeaders);
|
|
74
|
+
}
|
|
116
75
|
return requestHeaders;
|
|
117
76
|
}
|
|
118
77
|
|
|
@@ -140,9 +99,9 @@ function urlFactory(apiUrl, endpoint, sessionKey) {
|
|
|
140
99
|
}
|
|
141
100
|
|
|
142
101
|
async function getJsonResponse(url, init, cookies) {
|
|
143
|
-
|
|
102
|
+
|
|
144
103
|
try {
|
|
145
|
-
if (debugMode
|
|
104
|
+
if (debugMode) {
|
|
146
105
|
console.log("getJsonResponse(): url: ", url, ", init: ", init, ", cookies: ", cookies);
|
|
147
106
|
}
|
|
148
107
|
const response = await fetch(url, init);
|
|
@@ -152,7 +111,7 @@ async function getJsonResponse(url, init, cookies) {
|
|
|
152
111
|
if (response.ok) {
|
|
153
112
|
const responseJson = await response.json(); // Convert the ReadableStream to a JSON object
|
|
154
113
|
const responseJsonData = await responseJson.data; // ditto
|
|
155
|
-
if (debugMode
|
|
114
|
+
if (debugMode) {
|
|
156
115
|
console.log("getJsonResponse(): response: ", responseJson);
|
|
157
116
|
}
|
|
158
117
|
return responseJsonData;
|
|
@@ -179,7 +138,9 @@ async function getJsonResponse(url, init, cookies) {
|
|
|
179
138
|
}
|
|
180
139
|
|
|
181
140
|
export async function fetchPrompt(config, messages, cookies) {
|
|
182
|
-
|
|
141
|
+
if (debugMode) {
|
|
142
|
+
console.log("fetchPrompt(): config", config);
|
|
143
|
+
}
|
|
183
144
|
const apiUrl = config.chatbot.url_chatbot;
|
|
184
145
|
const sessionKey = getCookie(cookies.sessionCookie, "");
|
|
185
146
|
const url = urlFactory(apiUrl, null, sessionKey);
|
|
@@ -188,7 +149,9 @@ export async function fetchPrompt(config, messages, cookies) {
|
|
|
188
149
|
const init = requestInitFactory(headers, body);
|
|
189
150
|
const responseJson = await getJsonResponse(url, init, cookies);
|
|
190
151
|
if (responseJson && responseJson.body) {
|
|
191
|
-
|
|
152
|
+
if (debugMode) {
|
|
153
|
+
console.log("fetchPrompt(): parsing responseJson.body ");
|
|
154
|
+
}
|
|
192
155
|
const responseBody = await JSON.parse(responseJson.body);
|
|
193
156
|
return responseBody;
|
|
194
157
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./enums.js";
|
|
2
2
|
|
|
3
|
-
export function cookieMetaFactory(cookieName, cookieExpiration, cookieDomain) {
|
|
3
|
+
export function cookieMetaFactory(cookieName, cookieExpiration, cookieDomain, cookieValue = null) {
|
|
4
4
|
/*
|
|
5
5
|
Create a cookie object.
|
|
6
6
|
*/
|
|
@@ -8,6 +8,7 @@ export function cookieMetaFactory(cookieName, cookieExpiration, cookieDomain) {
|
|
|
8
8
|
name: cookieName,
|
|
9
9
|
expiration: cookieExpiration,
|
|
10
10
|
domain: cookieDomain,
|
|
11
|
+
value: cookieValue,
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*-----------------------------------------------------------------------------
|
|
2
|
+
Description: cookie management functions for the SmarterChat application.
|
|
3
|
+
-----------------------------------------------------------------------------*/
|
|
4
|
+
export function getCookie(cookie, defaultValue = null) {
|
|
5
|
+
if (cookie.value !== null) {
|
|
6
|
+
return cookie.value;
|
|
7
|
+
}
|
|
8
|
+
let cookieValue = null;
|
|
9
|
+
|
|
10
|
+
if (window.location.hostname.endsWith(cookie.domain) && document.cookie && document.cookie !== "") {
|
|
11
|
+
const cookies = document.cookie.split(";").map((cookie) => cookie.trim());
|
|
12
|
+
for (let i = 0; i < cookies.length; i++) {
|
|
13
|
+
const thisCookie = cookies[i];
|
|
14
|
+
if (thisCookie.startsWith(`${cookie.name}=`)) {
|
|
15
|
+
cookieValue = decodeURIComponent(thisCookie.substring(cookie.name.length + 1));
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return cookieValue || defaultValue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function setCookie(cookie, value) {
|
|
25
|
+
const currentPath = window.location.pathname;
|
|
26
|
+
if (value) {
|
|
27
|
+
const expirationDate = new Date();
|
|
28
|
+
expirationDate.setTime(expirationDate.getTime() + cookie.expiration);
|
|
29
|
+
const expires = expirationDate.toUTCString();
|
|
30
|
+
const cookieData = `${cookie.name}=${value}; path=${currentPath}; SameSite=Lax; expires=${expires}`;
|
|
31
|
+
document.cookie = cookieData;
|
|
32
|
+
} else {
|
|
33
|
+
// Unset the cookie by setting its expiration date to the past
|
|
34
|
+
const expirationDate = new Date(0);
|
|
35
|
+
const expires = expirationDate.toUTCString();
|
|
36
|
+
const cookieData = `${cookie.name}=; path=${currentPath}; SameSite=Lax; expires=${expires}`;
|
|
37
|
+
document.cookie = cookieData;
|
|
38
|
+
}
|
|
39
|
+
}
|