@smarter.sh/ui-chat 0.2.14 → 0.7.0
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/LICENSE +2 -2
- package/README.md +130 -128
- package/dist/smarter-chat-library.es.js +44274 -10767
- package/dist/smarter-chat-library.es.js.map +1 -1
- package/dist/smarter-chat-library.umd.js +657 -362
- package/dist/smarter-chat-library.umd.js.map +1 -1
- package/dist/types/src/components/AppTitle/Component.d.ts +13 -0
- package/dist/types/src/components/AppTitle/index.d.ts +2 -0
- package/dist/types/src/components/Console/Component.d.ts +17 -0
- package/dist/types/src/components/Console/ServerLogs.d.ts +8 -0
- package/dist/types/src/components/Console/data.d.ts +7 -0
- package/dist/types/src/components/Console/enums.d.ts +9 -0
- package/dist/types/src/components/Console/index.d.ts +2 -0
- package/dist/types/src/components/ErrorBoundary/Component.d.ts +17 -0
- package/dist/types/src/components/ErrorBoundary/index.d.ts +2 -0
- package/dist/types/src/components/SmarterChat/Component.d.ts +26 -0
- package/dist/types/src/components/SmarterChat/icons.d.ts +17 -0
- package/dist/types/src/components/SmarterChat/index.d.ts +2 -0
- package/dist/types/src/const.d.ts +5 -0
- package/dist/types/src/index.d.ts +12 -0
- package/dist/types/src/lib/ansi.d.ts +33 -0
- package/dist/types/src/lib/api.d.ts +73 -0
- package/dist/types/src/lib/code.d.ts +32 -0
- package/dist/types/src/lib/cookie.d.ts +17 -0
- package/dist/types/src/lib/enums.d.ts +26 -0
- package/dist/types/src/lib/layout.d.ts +42 -0
- package/dist/types/src/lib/logStream.d.ts +30 -0
- package/dist/types/src/lib/math.d.ts +18 -0
- package/dist/types/src/lib/mermaid.d.ts +27 -0
- package/dist/types/src/lib/messages.d.ts +52 -0
- package/dist/types/src/types.d.ts +143 -0
- package/dist/ui-chat.css +2 -1
- package/package.json +89 -57
- package/src/components/Console/Component.css +0 -47
- package/src/components/Console/Component.jsx +0 -186
- package/src/components/Console/HeadStyles.jsx +0 -20
- package/src/components/Console/enums.js +0 -7
- package/src/components/Console/index.js +0 -2
- package/src/components/ErrorModal/ErrorModal.css +0 -35
- package/src/components/ErrorModal/ErrorModal.jsx +0 -56
- package/src/components/ErrorModal/index.js +0 -3
- package/src/components/SmarterChat/Component.jsx +0 -427
- package/src/components/SmarterChat/ErrorBoundary.jsx +0 -32
- package/src/components/SmarterChat/Layout.js +0 -47
- package/src/components/SmarterChat/api.js +0 -200
- package/src/components/SmarterChat/enums.js +0 -17
- package/src/components/SmarterChat/index.js +0 -3
- package/src/components/SmarterChat/styles.css +0 -149
- package/src/components/SmarterChat/utils.jsx +0 -148
- package/src/components/enums.js +0 -1
- package/src/components/index.js +0 -3
- package/src/components/shared/cookie.js +0 -51
- package/src/constants.js +0 -2
- package/src/index.js +0 -4
- package/src/types/index.js +0 -2
- package/src/types/propTypes.js +0 -154
- package/src/version.js +0 -2
- package/types/index.d.ts +0 -17
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/*-----------------------------------------------------------------------------
|
|
2
|
-
Description: This file contains the function that makes the API request to
|
|
3
|
-
the backend. It is called exclusively from chatApp/Component.jsx
|
|
4
|
-
|
|
5
|
-
Notes:
|
|
6
|
-
- The backend API is an AWS API Gateway endpoint that is configured to
|
|
7
|
-
call an AWS Lambda function. The Lambda function is written in Python
|
|
8
|
-
and calls the OpenAI API.
|
|
9
|
-
|
|
10
|
-
- The backend API is configured to require an API key. The API key is
|
|
11
|
-
passed in the header of the request. In real terms, the api key is
|
|
12
|
-
pointless because it is exposed in the client code. However, it is
|
|
13
|
-
required by the API Gateway configuration.
|
|
14
|
-
|
|
15
|
-
- The backend API is configured to allow CORS requests from the client.
|
|
16
|
-
This is necessary because the client and backend are served from
|
|
17
|
-
different domains.
|
|
18
|
-
|
|
19
|
-
Returns: the backend API is configured to return a JSON object that substantially
|
|
20
|
-
conforms to the following structure for all 200 responses:
|
|
21
|
-
v0.1.0 - v0.4.0: ./test/events/openai.response.v0.4.0.json
|
|
22
|
-
v0.5.0: ./test/events/langchain.response.v0.5.0.json
|
|
23
|
-
-----------------------------------------------------------------------------*/
|
|
24
|
-
|
|
25
|
-
import { getCookie, setCookie } from "../shared/cookie";
|
|
26
|
-
|
|
27
|
-
// Set to true to enable local development mode,
|
|
28
|
-
// which will simulate the server-side API calls.
|
|
29
|
-
const developerMode = false;
|
|
30
|
-
let debugMode = developerMode;
|
|
31
|
-
const userAgent = "SmarterChat/1.0";
|
|
32
|
-
const applicationJson = "application/json";
|
|
33
|
-
|
|
34
|
-
function promptRequestBodyFactory(messages, config) {
|
|
35
|
-
const body = {
|
|
36
|
-
session_key: config.session_key,
|
|
37
|
-
messages: messages,
|
|
38
|
-
};
|
|
39
|
-
return JSON.stringify(body);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function requestHeadersFactory(cookies) {
|
|
43
|
-
if (debugMode) {
|
|
44
|
-
console.log("requestHeadersFactory(): cookies", cookies);
|
|
45
|
-
}
|
|
46
|
-
function getRequestCookies(cookies) {
|
|
47
|
-
// Ensure that csrftoken is not included in the Cookie header.
|
|
48
|
-
const cookiesArray = document.cookie.split(";").filter((cookie) => {
|
|
49
|
-
const trimmedCookie = cookie.trim();
|
|
50
|
-
return !trimmedCookie.startsWith(`${cookies.csrfCookie.name}=`);
|
|
51
|
-
});
|
|
52
|
-
const selectedCookies = cookiesArray.join("; ");
|
|
53
|
-
|
|
54
|
-
// example return value: "_ga=GA1.1.1244182935.1742308279; _ga_SK81M5HQYS=GS1.1.1742316653.3.1.1742320251.0.0.0"
|
|
55
|
-
return selectedCookies;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const requestCookies = getRequestCookies(cookies);
|
|
59
|
-
const csrftoken = getCookie(cookies.csrfCookie, "");
|
|
60
|
-
const authToken = getCookie(cookies.authTokenCookie, "");
|
|
61
|
-
|
|
62
|
-
const requestHeaders = {
|
|
63
|
-
Accept: applicationJson,
|
|
64
|
-
"Content-Type": applicationJson,
|
|
65
|
-
"X-CSRFToken": csrftoken,
|
|
66
|
-
Origin: window.location.origin,
|
|
67
|
-
Cookie: requestCookies,
|
|
68
|
-
Authorization: `Bearer ${authToken}`,
|
|
69
|
-
"User-Agent": userAgent,
|
|
70
|
-
};
|
|
71
|
-
if (debugMode) {
|
|
72
|
-
console.log("requestHeadersFactory(): requestHeaders", requestHeaders);
|
|
73
|
-
}
|
|
74
|
-
return requestHeaders;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function requestInitFactory(headers, body) {
|
|
78
|
-
return {
|
|
79
|
-
method: "POST",
|
|
80
|
-
credentials: "include",
|
|
81
|
-
mode: "cors",
|
|
82
|
-
headers: headers,
|
|
83
|
-
body: body,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function urlFactory(apiUrl, endpoint, sessionKey) {
|
|
88
|
-
if (!apiUrl.endsWith("/")) {
|
|
89
|
-
apiUrl += "/";
|
|
90
|
-
}
|
|
91
|
-
endpoint = endpoint || "";
|
|
92
|
-
let apiConfigUrl = new URL(endpoint, apiUrl);
|
|
93
|
-
if (sessionKey) {
|
|
94
|
-
apiConfigUrl.searchParams.append("session_key", sessionKey);
|
|
95
|
-
}
|
|
96
|
-
const url = apiConfigUrl.toString();
|
|
97
|
-
return url;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async function getJsonResponse(url, init, cookies) {
|
|
101
|
-
try {
|
|
102
|
-
if (debugMode) {
|
|
103
|
-
console.log("getJsonResponse(): url: ", url, ", init: ", init, ", cookies: ", cookies);
|
|
104
|
-
}
|
|
105
|
-
const response = await fetch(url, init);
|
|
106
|
-
const contentType = response.headers.get("content-type");
|
|
107
|
-
if (contentType && contentType.includes(applicationJson)) {
|
|
108
|
-
const status = await response.status;
|
|
109
|
-
if (response.ok) {
|
|
110
|
-
const responseJson = await response.json(); // Convert the ReadableStream to a JSON object
|
|
111
|
-
const responseJsonData = await responseJson.data; // ditto
|
|
112
|
-
if (debugMode) {
|
|
113
|
-
console.log("getJsonResponse(): response: ", responseJson);
|
|
114
|
-
}
|
|
115
|
-
return responseJsonData;
|
|
116
|
-
} else {
|
|
117
|
-
/*
|
|
118
|
-
note:
|
|
119
|
-
- the responseBody object is not available when the status is 504, because
|
|
120
|
-
these responses are generated exclusively by API Gateway.
|
|
121
|
-
- the responseBody object is potentially not available when the status is 500
|
|
122
|
-
depending on whether the 500 response was generated by the Lambda or the API Gateway
|
|
123
|
-
- the responseBody object is intended to always be available when the status is 400.
|
|
124
|
-
However, there potentially COULD be a case where the response itself contains message text.
|
|
125
|
-
*/
|
|
126
|
-
console.error("getJsonResponse(): error: ", status, response.statusText);
|
|
127
|
-
return response;
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
const errorText = await response.text();
|
|
131
|
-
throw new Error(`getJsonResponse() Unexpected response format: ${errorText}`);
|
|
132
|
-
}
|
|
133
|
-
} catch (error) {
|
|
134
|
-
return error;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export async function fetchPrompt(config, messages, cookies) {
|
|
139
|
-
debugMode = config.debug_mode || developerMode;
|
|
140
|
-
|
|
141
|
-
if (debugMode) {
|
|
142
|
-
console.log("fetchPrompt(): config", config);
|
|
143
|
-
}
|
|
144
|
-
const apiUrl = config.chatbot.url_chatbot;
|
|
145
|
-
const sessionKey = getCookie(cookies.sessionCookie, "");
|
|
146
|
-
const url = urlFactory(apiUrl, null, sessionKey);
|
|
147
|
-
const headers = requestHeadersFactory(cookies);
|
|
148
|
-
const body = promptRequestBodyFactory(messages, config);
|
|
149
|
-
const init = requestInitFactory(headers, body);
|
|
150
|
-
const responseJson = await getJsonResponse(url, init, cookies);
|
|
151
|
-
if (responseJson && responseJson.body) {
|
|
152
|
-
if (debugMode) {
|
|
153
|
-
console.log("fetchPrompt(): parsing responseJson.body ");
|
|
154
|
-
}
|
|
155
|
-
const responseBody = await JSON.parse(responseJson.body);
|
|
156
|
-
return responseBody;
|
|
157
|
-
}
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
async function fetchLocalConfig(configFile) {
|
|
162
|
-
const response = await fetch("../data/" + configFile);
|
|
163
|
-
const sampleConfig = await response.json();
|
|
164
|
-
return sampleConfig.data;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export async function fetchConfig(apiUrl, cookies) {
|
|
168
|
-
/*
|
|
169
|
-
Fetch the chat configuration from the backend server. This is a POST request with the
|
|
170
|
-
session key as the payload. The server will return the configuration
|
|
171
|
-
as a JSON object.
|
|
172
|
-
|
|
173
|
-
See class ChatConfigView(View, AccountMixin) in
|
|
174
|
-
https://github.com/smarter-sh/smarter/blob/main/smarter/smarter/apps/chatapp/views.py
|
|
175
|
-
Things to note:
|
|
176
|
-
- The session key is used to identify the user, the chatbot,
|
|
177
|
-
and the chat history.
|
|
178
|
-
- The session key is stored in a cookie that is specific to the path. Thus,
|
|
179
|
-
each chatbot has its own session key.
|
|
180
|
-
- The CSRF token is stored in a cookie and is managed by Django.
|
|
181
|
-
- debugMode is a boolean that is also stored in a cookie, managed by Django
|
|
182
|
-
based on a Waffle switch 'reactapp_debug_mode'
|
|
183
|
-
*/
|
|
184
|
-
if (developerMode) {
|
|
185
|
-
return fetchLocalConfig("sample-config.json");
|
|
186
|
-
}
|
|
187
|
-
const sessionKey = getCookie(cookies.sessionCookie, "");
|
|
188
|
-
const headers = requestHeadersFactory(cookies);
|
|
189
|
-
const body = JSON.stringify({ session_key: sessionKey });
|
|
190
|
-
const init = requestInitFactory(headers, body);
|
|
191
|
-
const url = urlFactory(apiUrl, "config/", sessionKey);
|
|
192
|
-
const newConfig = await getJsonResponse(url, init, cookies);
|
|
193
|
-
if (newConfig) {
|
|
194
|
-
setCookie(cookies.sessionCookie, newConfig.session_key);
|
|
195
|
-
setCookie(cookies.debugCookie, newConfig.debug_mode);
|
|
196
|
-
debugMode = newConfig.debug_mode || developerMode;
|
|
197
|
-
return newConfig;
|
|
198
|
-
}
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const MessageDirectionEnum = {
|
|
2
|
-
INCOMING: "incoming",
|
|
3
|
-
OUTGOING: "outgoing",
|
|
4
|
-
};
|
|
5
|
-
export const SenderRoleEnum = {
|
|
6
|
-
SYSTEM: "system",
|
|
7
|
-
ASSISTANT: "assistant",
|
|
8
|
-
USER: "user",
|
|
9
|
-
TOOL: "tool",
|
|
10
|
-
SMARTER: "smarter",
|
|
11
|
-
};
|
|
12
|
-
export const ValidMessageRolesEnum = [
|
|
13
|
-
SenderRoleEnum.SYSTEM,
|
|
14
|
-
SenderRoleEnum.ASSISTANT,
|
|
15
|
-
SenderRoleEnum.USER,
|
|
16
|
-
SenderRoleEnum.TOOL,
|
|
17
|
-
];
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
.SmarterChat {
|
|
2
|
-
border: 1px solid rgba(255, 87, 51, 0.75);
|
|
3
|
-
height: 100%;
|
|
4
|
-
overflow-x: auto;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.SmarterChat a {
|
|
8
|
-
text-decoration: inherit;
|
|
9
|
-
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
10
|
-
line-height: 1.5;
|
|
11
|
-
font-weight: 400;
|
|
12
|
-
|
|
13
|
-
font-synthesis: none;
|
|
14
|
-
text-rendering: optimizeLegibility;
|
|
15
|
-
-webkit-font-smoothing: antialiased;
|
|
16
|
-
-moz-osx-font-smoothing: grayscale;
|
|
17
|
-
-webkit-text-size-adjust: 100%;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.app-title {
|
|
21
|
-
text-align: center;
|
|
22
|
-
background-color: rgba(255, 87, 51, 0.75);
|
|
23
|
-
width: 100%;
|
|
24
|
-
padding: 0;
|
|
25
|
-
margin: 0;
|
|
26
|
-
color: whitesmoke;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
h5 {
|
|
30
|
-
color: whitesmoke;
|
|
31
|
-
margin-left: 10px;
|
|
32
|
-
margin-bottom: 0;
|
|
33
|
-
}
|
|
34
|
-
.app-logo {
|
|
35
|
-
width: 75px;
|
|
36
|
-
margin: 0 auto;
|
|
37
|
-
display: block;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.container {
|
|
41
|
-
display: flex;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.chat-app {
|
|
45
|
-
position: relative;
|
|
46
|
-
height: 100%;
|
|
47
|
-
width: 100%;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.cs-message-separator::before,
|
|
51
|
-
.cs-message-separator::after {
|
|
52
|
-
background-color: lightgray !important;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.cs-conversation-header {
|
|
56
|
-
text-align: center;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
div.cs-message__html-content a {
|
|
60
|
-
text-decoration: underline !important;
|
|
61
|
-
filter: invert(1) contrast(2);
|
|
62
|
-
}
|
|
63
|
-
div.cs-message__html-content a:hover {
|
|
64
|
-
text-decoration: underline;
|
|
65
|
-
color: orange;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
section.smarter-message .cs-message__html-content {
|
|
69
|
-
color: brown !important;
|
|
70
|
-
background-color: blanchedalmond;
|
|
71
|
-
font-family: "Courier New", Courier, monospace;
|
|
72
|
-
font-weight: bold;
|
|
73
|
-
text-align: left;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
section.smarter-message .cs-message__content {
|
|
77
|
-
color: brown !important;
|
|
78
|
-
background-color: blanchedalmond;
|
|
79
|
-
border: 1px solid brown;
|
|
80
|
-
margin-top: 10px;
|
|
81
|
-
margin-bottom: 10px;
|
|
82
|
-
border-radius: 10px;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
section.system-message .cs-message__html-content {
|
|
86
|
-
color: beige !important;
|
|
87
|
-
background-color: rgb(39, 40, 34);
|
|
88
|
-
font-family: "Courier New", Courier, monospace;
|
|
89
|
-
font-weight: bold;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
section.system-message .cs-message__content {
|
|
93
|
-
color: beige !important;
|
|
94
|
-
background-color: rgb(39, 40, 34);
|
|
95
|
-
border: 1px solid brown;
|
|
96
|
-
margin-top: 10px;
|
|
97
|
-
margin-bottom: 10px;
|
|
98
|
-
border-radius: 10px;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/*-------------- Responsive Styling -----------------------
|
|
102
|
-
|
|
103
|
-
xs = Extra small <576px. Max container width None (auto)
|
|
104
|
-
sm = Small ≥576px. Max container width 540px.
|
|
105
|
-
md = Medium ≥768px. Max container width 720px.
|
|
106
|
-
lg = Large ≥992px. Max container width 960px.
|
|
107
|
-
xl = Extra large ≥1200px. Max container width 1140px.
|
|
108
|
-
|
|
109
|
-
*/
|
|
110
|
-
|
|
111
|
-
/********** Extra large devices only **********/
|
|
112
|
-
@media (min-width: 1200px) {
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/********** Large devices only **********/
|
|
116
|
-
@media (min-width: 992px) and (max-width: 1199px) {
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/********** Medium devices only **********/
|
|
120
|
-
@media (min-width: 768px) and (max-width: 991px) {
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/********** Small devices only **********/
|
|
124
|
-
@media (min-width: 576) and (max-width: 767px) {
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/********** Extra small devices only **********/
|
|
128
|
-
@media (min-width: 480px) and (max-width: 575px) {
|
|
129
|
-
}
|
|
130
|
-
/********** Super extra small devices Only :-) (e.g., iPhone 4) **********/
|
|
131
|
-
@media (max-width: 479px) {
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* ------------ MCDANIEL ------------------ */
|
|
135
|
-
@media (max-width: 991px) {
|
|
136
|
-
.hide-medium {
|
|
137
|
-
display: none;
|
|
138
|
-
width: 0 !important;
|
|
139
|
-
height: 0 !important;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
@media (max-width: 767px) {
|
|
144
|
-
.hide-small {
|
|
145
|
-
display: none;
|
|
146
|
-
width: 0 !important;
|
|
147
|
-
height: 0 !important;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./enums.js";
|
|
2
|
-
|
|
3
|
-
export function chatRestoreFromBackend(chat_history, last_response) {
|
|
4
|
-
/*
|
|
5
|
-
Rebuild the message thread from the most recently persisted chat history.
|
|
6
|
-
*/
|
|
7
|
-
try {
|
|
8
|
-
const messages = (chat_history ? chat_history : [])
|
|
9
|
-
.map((chat) => {
|
|
10
|
-
if (chat.role === SenderRoleEnum.USER) {
|
|
11
|
-
return messageFactory(chat, chat.content, MessageDirectionEnum.OUTGOING, chat.role);
|
|
12
|
-
} else if (chat.role === SenderRoleEnum.SYSTEM) {
|
|
13
|
-
return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
|
|
14
|
-
} else if (chat.role === SenderRoleEnum.ASSISTANT) {
|
|
15
|
-
return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
|
|
16
|
-
} else if (chat.role === SenderRoleEnum.SMARTER) {
|
|
17
|
-
return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
|
|
18
|
-
} else if (chat.role === SenderRoleEnum.TOOL) {
|
|
19
|
-
return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
|
|
20
|
-
}
|
|
21
|
-
console.error(`chatRestoreFromBackend() Invalid role received: ${chat.role}`);
|
|
22
|
-
})
|
|
23
|
-
.filter((message) => message && typeof message === "object" && !Array.isArray(message));
|
|
24
|
-
|
|
25
|
-
if (last_response?.choices?.[0]?.message?.content) {
|
|
26
|
-
const last_message = last_response.choices[0].message;
|
|
27
|
-
const last_message_content = last_message.content;
|
|
28
|
-
messages.push(
|
|
29
|
-
messageFactory(last_message, last_message_content, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT),
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return messages;
|
|
34
|
-
} catch (error) {
|
|
35
|
-
console.error(`chatRestoreFromBackend() Error occurred while restoring chat from backend: ${error}`);
|
|
36
|
-
return []; // return an empty array in case of error
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const examplePrompts = (prompts) => {
|
|
41
|
-
/*
|
|
42
|
-
If we have no chat history, and the Application configuration includes
|
|
43
|
-
example prompts, we can display them to the user to help them get started.
|
|
44
|
-
*/
|
|
45
|
-
if (prompts.length == 0) {
|
|
46
|
-
return "";
|
|
47
|
-
} else
|
|
48
|
-
return (
|
|
49
|
-
"Some example prompts to get you started:\r\n\r\n" +
|
|
50
|
-
prompts
|
|
51
|
-
.map((prompt) => {
|
|
52
|
-
return prompt + "\r\n";
|
|
53
|
-
})
|
|
54
|
-
.join("")
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export function chatIntro(welcome_message, system_role, example_prompts) {
|
|
59
|
-
/*
|
|
60
|
-
Generate the initial message thread for the chat window. This includes the
|
|
61
|
-
welcome message, and any example prompts that are configured in the
|
|
62
|
-
Application settings.
|
|
63
|
-
*/
|
|
64
|
-
let messages = [messageFactory({}, system_role, MessageDirectionEnum.INCOMING, SenderRoleEnum.SYSTEM)];
|
|
65
|
-
messages.push(messageFactory({}, welcome_message, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT));
|
|
66
|
-
|
|
67
|
-
const examples = examplePrompts(example_prompts);
|
|
68
|
-
if (examples) {
|
|
69
|
-
messages.push(messageFactory({}, examples, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return messages;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function convertMarkdownLinksToHTML(message) {
|
|
76
|
-
/*
|
|
77
|
-
Convert markdown links to HTML links.
|
|
78
|
-
*/
|
|
79
|
-
if (typeof message !== "string") {
|
|
80
|
-
console.error(`convertMarkdownLinksToHTML() Expected a string but received ${typeof message}`);
|
|
81
|
-
console.error("convertMarkdownLinksToHTML() broke here", message);
|
|
82
|
-
return message; // or return a default value
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
86
|
-
return message.replace(markdownLinkRegex, '<a href="$2">$1</a>');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function messageFactory(originalMessage, content, direction, sender) {
|
|
90
|
-
/*
|
|
91
|
-
Create a new message object.
|
|
92
|
-
*/
|
|
93
|
-
const display = typeof content === "string" && content !== null;
|
|
94
|
-
const converted_content = display ? convertMarkdownLinksToHTML(content) : content;
|
|
95
|
-
const retVal = {
|
|
96
|
-
message: converted_content,
|
|
97
|
-
direction: direction,
|
|
98
|
-
sender: sender,
|
|
99
|
-
sentTime: new Date().toLocaleString(),
|
|
100
|
-
display: display,
|
|
101
|
-
};
|
|
102
|
-
if (originalMessage) {
|
|
103
|
-
retVal.originalMessage = originalMessage;
|
|
104
|
-
} else {
|
|
105
|
-
retVal.originalMessage = retVal;
|
|
106
|
-
}
|
|
107
|
-
return retVal;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function requestMessageFactory(message) {
|
|
111
|
-
let retVal = message.originalMessage || {};
|
|
112
|
-
retVal.role = message.originalMessage && message.originalMessage.role ? message.originalMessage.role : message.sender;
|
|
113
|
-
retVal.content =
|
|
114
|
-
message.originalMessage && message.originalMessage.message ? message.originalMessage.message : message.message;
|
|
115
|
-
return retVal;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function chatMessages2RequestMessages(messages) {
|
|
119
|
-
/*
|
|
120
|
-
Transform the chat message thread into a list of request messages for the
|
|
121
|
-
backend API.
|
|
122
|
-
*/
|
|
123
|
-
return (
|
|
124
|
-
messages
|
|
125
|
-
// filter out smarter messages
|
|
126
|
-
.filter((message) => ValidMessageRolesEnum.includes(message.sender))
|
|
127
|
-
.map((message, index) => {
|
|
128
|
-
return requestMessageFactory(message);
|
|
129
|
-
})
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function chatInit(welcome_message, system_role, example_prompts, chat_id, chat_history, last_response) {
|
|
134
|
-
/*
|
|
135
|
-
Initialize the chat message thread. This function is called when the chat
|
|
136
|
-
window is first opened, or when the chat window is restored from the
|
|
137
|
-
backend.
|
|
138
|
-
*/
|
|
139
|
-
|
|
140
|
-
let messages = [];
|
|
141
|
-
messages = chatRestoreFromBackend(chat_history, last_response);
|
|
142
|
-
|
|
143
|
-
if (messages.length === 0) {
|
|
144
|
-
messages = chatIntro(welcome_message, system_role, example_prompts);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return messages;
|
|
148
|
-
}
|
package/src/components/enums.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./SmarterChat/enums";
|
package/src/components/index.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
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
|
-
}
|
|
40
|
-
|
|
41
|
-
export function cookieMetaFactory(cookieName, cookieExpiration, cookieDomain, cookieValue = null) {
|
|
42
|
-
/*
|
|
43
|
-
Create a cookie object.
|
|
44
|
-
*/
|
|
45
|
-
return {
|
|
46
|
-
name: cookieName,
|
|
47
|
-
expiration: cookieExpiration,
|
|
48
|
-
domain: cookieDomain,
|
|
49
|
-
value: cookieValue,
|
|
50
|
-
};
|
|
51
|
-
}
|
package/src/constants.js
DELETED
package/src/index.js
DELETED
package/src/types/index.js
DELETED