@smarter.sh/ui-chat 0.0.1

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.
@@ -0,0 +1,148 @@
1
+ .SmarterChat a {
2
+ text-decoration: inherit;
3
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
4
+ line-height: 1.5;
5
+ font-weight: 400;
6
+
7
+ font-synthesis: none;
8
+ text-rendering: optimizeLegibility;
9
+ -webkit-font-smoothing: antialiased;
10
+ -moz-osx-font-smoothing: grayscale;
11
+ -webkit-text-size-adjust: 100%;
12
+ }
13
+
14
+ .SmarterChat {
15
+ border: 1px solid rgba(255, 87, 51, 0.75);
16
+ height: 100%;
17
+ }
18
+
19
+ .app-title {
20
+ text-align: center;
21
+ background-color: rgba(255, 87, 51, 0.75);
22
+ width: 100%;
23
+ padding: 0;
24
+ margin: 0;
25
+ color: whitesmoke;
26
+ }
27
+
28
+ h5 {
29
+ color: whitesmoke;
30
+ margin-left: 10px;
31
+ margin-bottom: 0;
32
+ }
33
+ .app-logo {
34
+ width: 75px;
35
+ margin: 0 auto;
36
+ display: block;
37
+ }
38
+
39
+ .container {
40
+ display: flex;
41
+ }
42
+
43
+ .chat-app {
44
+ position: relative;
45
+ height: 100%;
46
+ width: 100%;
47
+ }
48
+
49
+ .cs-message-separator::before,
50
+ .cs-message-separator::after {
51
+ background-color: lightgray !important;
52
+ }
53
+
54
+ .cs-conversation-header {
55
+ text-align: center;
56
+ }
57
+
58
+ div.cs-message__html-content a {
59
+ text-decoration: underline !important;
60
+ color: #333333;
61
+ }
62
+ div.cs-message__html-content a:hover {
63
+ text-decoration: underline;
64
+ color: midnightblue;
65
+ }
66
+
67
+ section.smarter-message .cs-message__html-content {
68
+ color: brown !important;
69
+ background-color: blanchedalmond;
70
+ font-family: "Courier New", Courier, monospace;
71
+ font-weight: bold;
72
+ text-align: center;
73
+ }
74
+
75
+ section.smarter-message .cs-message__content {
76
+ color: brown !important;
77
+ background-color: blanchedalmond;
78
+ border: 1px solid brown;
79
+ margin-top: 10px;
80
+ margin-bottom: 10px;
81
+ border-radius: 10px;
82
+ }
83
+
84
+ section.system-message .cs-message__html-content {
85
+ color: beige !important;
86
+ background-color: rgb(39, 40, 34);
87
+ font-family: "Courier New", Courier, monospace;
88
+ font-weight: bold;
89
+ }
90
+
91
+ section.system-message .cs-message__content {
92
+ color: beige !important;
93
+ background-color: rgb(39, 40, 34);
94
+ border: 1px solid brown;
95
+ margin-top: 10px;
96
+ margin-bottom: 10px;
97
+ border-radius: 10px;
98
+ }
99
+
100
+ /*-------------- Responsive Styling -----------------------
101
+
102
+ xs = Extra small <576px. Max container width None (auto)
103
+ sm = Small ≥576px. Max container width 540px.
104
+ md = Medium ≥768px. Max container width 720px.
105
+ lg = Large ≥992px. Max container width 960px.
106
+ xl = Extra large ≥1200px. Max container width 1140px.
107
+
108
+ */
109
+
110
+ /********** Extra large devices only **********/
111
+ @media (min-width: 1200px) {
112
+ }
113
+
114
+ /********** Large devices only **********/
115
+ @media (min-width: 992px) and (max-width: 1199px) {
116
+ }
117
+
118
+ /********** Medium devices only **********/
119
+ @media (min-width: 768px) and (max-width: 991px) {
120
+ }
121
+
122
+ /********** Small devices only **********/
123
+ @media (min-width: 576) and (max-width: 767px) {
124
+ }
125
+
126
+ /********** Extra small devices only **********/
127
+ @media (min-width: 480px) and (max-width: 575px) {
128
+ }
129
+ /********** Super extra small devices Only :-) (e.g., iPhone 4) **********/
130
+ @media (max-width: 479px) {
131
+ }
132
+
133
+ /* ------------ MCDANIEL ------------------ */
134
+ @media (max-width: 991px) {
135
+ .hide-medium {
136
+ display: none;
137
+ width: 0 !important;
138
+ height: 0 !important;
139
+ }
140
+ }
141
+
142
+ @media (max-width: 767px) {
143
+ .hide-small {
144
+ display: none;
145
+ width: 0 !important;
146
+ height: 0 !important;
147
+ }
148
+ }
@@ -0,0 +1,158 @@
1
+ import { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./enums.js";
2
+
3
+ export function cookieMetaFactory(cookieName, cookieExpiration) {
4
+ /*
5
+ Create a cookie object.
6
+ */
7
+ return {
8
+ name: cookieName,
9
+ expiration: cookieExpiration,
10
+ };
11
+ }
12
+
13
+ export function chatRestoreFromBackend(chat_history, last_response) {
14
+ /*
15
+ Rebuild the message thread from the most recently persisted chat history.
16
+ */
17
+ try {
18
+ const messages = (chat_history ? chat_history : [])
19
+ .map((chat) => {
20
+ if (chat.role === SenderRoleEnum.USER) {
21
+ return messageFactory(chat, chat.content, MessageDirectionEnum.OUTGOING, chat.role);
22
+ } else if (chat.role === SenderRoleEnum.SYSTEM) {
23
+ return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
24
+ } else if (chat.role === SenderRoleEnum.ASSISTANT) {
25
+ return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
26
+ } else if (chat.role === SenderRoleEnum.SMARTER) {
27
+ return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
28
+ } else if (chat.role === SenderRoleEnum.TOOL) {
29
+ return messageFactory(chat, chat.content, MessageDirectionEnum.INCOMING, chat.role);
30
+ }
31
+ console.error(`chatRestoreFromBackend() Invalid role received: ${chat.role}`);
32
+ })
33
+ .filter((message) => message && typeof message === "object" && !Array.isArray(message));
34
+
35
+ if (last_response?.choices?.[0]?.message?.content) {
36
+ const last_message = last_response.choices[0].message;
37
+ const last_message_content = last_message.content;
38
+ messages.push(
39
+ messageFactory(last_message, last_message_content, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT),
40
+ );
41
+ }
42
+
43
+ return messages;
44
+ } catch (error) {
45
+ console.error(`chatRestoreFromBackend() Error occurred while restoring chat from backend: ${error}`);
46
+ return []; // return an empty array in case of error
47
+ }
48
+ }
49
+
50
+ const examplePrompts = (prompts) => {
51
+ /*
52
+ If we have no chat history, and the Application configuration includes
53
+ example prompts, we can display them to the user to help them get started.
54
+ */
55
+ if (prompts.length == 0) {
56
+ return "";
57
+ } else
58
+ return (
59
+ "Some example prompts to get you started:\r\n\r\n" +
60
+ prompts
61
+ .map((prompt) => {
62
+ return prompt + "\r\n";
63
+ })
64
+ .join("")
65
+ );
66
+ };
67
+
68
+ export function chatIntro(welcome_message, system_role, example_prompts) {
69
+ /*
70
+ Generate the initial message thread for the chat window. This includes the
71
+ welcome message, and any example prompts that are configured in the
72
+ Application settings.
73
+ */
74
+ let messages = [messageFactory({}, system_role, MessageDirectionEnum.INCOMING, SenderRoleEnum.SYSTEM)];
75
+ messages.push(messageFactory({}, welcome_message, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT));
76
+
77
+ const examples = examplePrompts(example_prompts);
78
+ if (examples) {
79
+ messages.push(messageFactory({}, examples, MessageDirectionEnum.INCOMING, SenderRoleEnum.ASSISTANT));
80
+ }
81
+
82
+ return messages;
83
+ }
84
+
85
+ export function convertMarkdownLinksToHTML(message) {
86
+ /*
87
+ Convert markdown links to HTML links.
88
+ */
89
+ if (typeof message !== "string") {
90
+ console.error(`convertMarkdownLinksToHTML() Expected a string but received ${typeof message}`);
91
+ console.error("convertMarkdownLinksToHTML() broke here", message);
92
+ return message; // or return a default value
93
+ }
94
+
95
+ const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
96
+ return message.replace(markdownLinkRegex, '<a href="$2">$1</a>');
97
+ }
98
+
99
+ export function messageFactory(originalMessage, content, direction, sender) {
100
+ /*
101
+ Create a new message object.
102
+ */
103
+ const display = typeof content === "string" && content !== null;
104
+ const converted_content = display ? convertMarkdownLinksToHTML(content) : content;
105
+ const retVal = {
106
+ message: converted_content,
107
+ direction: direction,
108
+ sender: sender,
109
+ sentTime: new Date().toLocaleString(),
110
+ display: display,
111
+ };
112
+ if (originalMessage) {
113
+ retVal.originalMessage = originalMessage;
114
+ } else {
115
+ retVal.originalMessage = retVal;
116
+ }
117
+ return retVal;
118
+ }
119
+
120
+ function requestMessageFactory(message) {
121
+ let retVal = message.originalMessage || {};
122
+ retVal.role = message.originalMessage && message.originalMessage.role ? message.originalMessage.role : message.sender;
123
+ retVal.content =
124
+ message.originalMessage && message.originalMessage.message ? message.originalMessage.message : message.message;
125
+ return retVal;
126
+ }
127
+
128
+ export function chatMessages2RequestMessages(messages) {
129
+ /*
130
+ Transform the chat message thread into a list of request messages for the
131
+ backend API.
132
+ */
133
+ return (
134
+ messages
135
+ // filter out smarter messages
136
+ .filter((message) => ValidMessageRolesEnum.includes(message.sender))
137
+ .map((message, index) => {
138
+ return requestMessageFactory(message);
139
+ })
140
+ );
141
+ }
142
+
143
+ export function chatInit(welcome_message, system_role, example_prompts, chat_id, chat_history, last_response) {
144
+ /*
145
+ Initialize the chat message thread. This function is called when the chat
146
+ window is first opened, or when the chat window is restored from the
147
+ backend.
148
+ */
149
+
150
+ let messages = [];
151
+ messages = chatRestoreFromBackend(chat_history, last_response);
152
+
153
+ if (messages.length === 0) {
154
+ messages = chatIntro(welcome_message, system_role, example_prompts);
155
+ }
156
+
157
+ return messages;
158
+ }
@@ -0,0 +1 @@
1
+ export { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./SmarterChat/enums";
@@ -0,0 +1,2 @@
1
+ export { default as SmarterChat } from "./SmarterChat";
2
+ export { default as ErrorModal } from "./ErrorModal";