@smarter.sh/ui-chat 0.3.0 → 0.7.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.
- package/LICENSE +2 -2
- package/README.md +235 -173
- package/dist/smarter-chat-library.es.js +44331 -12089
- package/dist/smarter-chat-library.es.js.map +1 -1
- package/dist/smarter-chat-library.umd.js +340 -121
- 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/contract.gen.d.ts +1146 -0
- package/dist/types/src/index.d.ts +13 -0
- package/dist/types/src/lib/ansi.d.ts +33 -0
- package/dist/types/src/lib/api.d.ts +96 -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 +108 -0
- package/dist/ui-chat.css +2 -1
- package/package.json +90 -59
- 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 -431
- 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 -152
- 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
package/LICENSE
CHANGED
|
@@ -660,9 +660,9 @@ if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
|
660
660
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
|
661
661
|
<http://www.gnu.org/licenses/>.
|
|
662
662
|
|
|
663
|
-
|
|
663
|
+
Lawrence McDaniel wishes to state, in clarification of the above license terms, that
|
|
664
664
|
any public, independently available web service offered over the network and
|
|
665
|
-
communicating with
|
|
665
|
+
communicating with Lawrence McDaniel's copyrighted works by any form of inter-service
|
|
666
666
|
communication, including but not limited to Remote Procedure Call (RPC)
|
|
667
667
|
interfaces, is not a work based on our copyrighted work within the meaning
|
|
668
668
|
of the license. "Corresponding Source" of this work, or works based on this
|
package/README.md
CHANGED
|
@@ -1,225 +1,287 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
# @smarter.sh/ui-chat
|
|
2
|
+
|
|
3
|
+
> A drop-in React chat component for [Smarter](https://smarter.sh) LLMClients: streaming tool-call progress, GitHub
|
|
4
|
+
> flavored markdown, syntax-highlighted code, LaTeX math and Mermaid diagrams, out of the box.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@smarter.sh/ui-chat)
|
|
7
|
+
[](https://www.npmjs.com/package/@smarter.sh/ui-chat)
|
|
8
|
+
[](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml)
|
|
9
|
+
[](https://codecov.io/gh/smarter-sh/smarter-chat)
|
|
10
|
+
[](#typescript)
|
|
11
|
+
[](https://react.dev)
|
|
12
|
+
[](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE)
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
Smarter Chat is the chat UI of the Smarter web console's prompt engineering workbench, published as a React component
|
|
17
|
+
so that any web page can use a Smarter LLMClient as its chat backend: a marketing site, a customer portal, a storefront,
|
|
18
|
+
an intranet, or your own application.
|
|
19
|
+
|
|
20
|
+
**[Documentation](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat.html)** ·
|
|
21
|
+
**[Storybook](#development)** · **[Changelog](https://github.com/smarter-sh/smarter-chat/blob/main/CHANGELOG.md)** ·
|
|
22
|
+
**[Issues](https://github.com/smarter-sh/smarter-chat/issues)**
|
|
23
|
+
|
|
24
|
+
## Contents
|
|
25
|
+
|
|
26
|
+
- [Features](#features)
|
|
27
|
+
- [Installation](#installation)
|
|
28
|
+
- [Quick start](#quick-start)
|
|
29
|
+
- [Requirements on the Smarter side](#requirements-on-the-smarter-side)
|
|
30
|
+
- [Props](#props)
|
|
31
|
+
- [Examples](#examples)
|
|
32
|
+
- [Styling](#styling)
|
|
33
|
+
- [TypeScript](#typescript)
|
|
34
|
+
- [How it works](#how-it-works)
|
|
35
|
+
- [Browser support](#browser-support)
|
|
36
|
+
- [Development](#development)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **One component, one prop.** Give it the url of a deployed LLMClient, and it loads the LLMClient's name, welcome
|
|
42
|
+
message, example prompts and placeholder from Smarter.
|
|
43
|
+
- **Persistent chat sessions.** The conversation survives page reloads, and each LLMClient on a site keeps its own
|
|
44
|
+
session.
|
|
45
|
+
- **Live progress.** While a prompt runs, the chat shows each LLM request, tool, plugin and MCP server call, streamed
|
|
46
|
+
as Server-Sent Events.
|
|
47
|
+
- **Rich responses.** GitHub flavored markdown (tables, lists, block quotes, images, links), syntax-highlighted code
|
|
48
|
+
blocks with a copy button, LaTeX math typeset by [KaTeX](https://katex.org), and
|
|
49
|
+
[Mermaid](https://mermaid.js.org) diagrams.
|
|
50
|
+
- **Safe by default.** Raw html is displayed as text, links and images are restricted to `http(s)`, relative and raster
|
|
51
|
+
`data:` urls, and the rendered html and Mermaid's svg are sanitized with
|
|
52
|
+
[DOMPurify](https://github.com/cure53/DOMPurify).
|
|
53
|
+
- **Lightweight where it counts.** React is a peer dependency, Mermaid is loaded only when a message first has a
|
|
54
|
+
diagram, and KaTeX's fonts are downloaded only when an equation uses them.
|
|
55
|
+
- **Optional developer Console.** A resizable side panel with the LLMClient's configuration, the session's api calls,
|
|
56
|
+
tool calls and plugin usage, and a live server log stream, as in the Smarter workbench.
|
|
57
|
+
- **Accessible.** Labeled regions and controls, keyboard-resizable panels, and MathML for screen readers.
|
|
58
|
+
- **Typed.** Written in TypeScript, with type declarations for its props and for the Smarter api's data.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
18
61
|
|
|
19
62
|
```console
|
|
20
63
|
npm install @smarter.sh/ui-chat
|
|
21
64
|
```
|
|
22
65
|
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
import ReactDOM from "react-dom/client";
|
|
26
|
-
import { SmarterChat } from "@smarter.sh/ui-chat";
|
|
27
|
-
|
|
28
|
-
const rootElement = document.getElementById("smarter-sh-v1-ui-chat-root");
|
|
29
|
-
const root = ReactDOM.createRoot(rootElement);
|
|
30
|
-
const apiUrl = rootElement.getAttribute("smarter-chatbot-api-url") || "http://localhost:9357/api/v1/chatbots/1/";
|
|
31
|
-
const toggleMetadata = rootElement.getAttribute("smarter-toggle-metadata") === "true";
|
|
32
|
-
const csrfCookieName = rootElement.getAttribute("smarter-csrf-cookie-name") || "csrftoken";
|
|
33
|
-
const sessionCookieName = rootElement.getAttribute("smarter-session-cookie-name") || "session_key";
|
|
34
|
-
const cookieDomain = rootElement.getAttribute("smarter-cookie-domain") || "localhost";
|
|
35
|
-
const authSessionCookieName = rootElement.getAttribute("django-session-cookie-name") || "sessionid";
|
|
36
|
-
const csrftoken = rootElement.getAttribute("django-csrftoken");
|
|
37
|
-
const debugMode = rootElement.getAttribute("smarter-debug-mode") === "true";
|
|
38
|
-
const debugCookieName = "debug";
|
|
39
|
-
|
|
40
|
-
root.render(
|
|
41
|
-
<React.StrictMode>
|
|
42
|
-
<SmarterChat
|
|
43
|
-
apiUrl={apiUrl}
|
|
44
|
-
apiKey={apiKey}
|
|
45
|
-
toggleMetadata={toggleMetadata}
|
|
46
|
-
csrfCookieName={csrfCookieName}
|
|
47
|
-
csrftoken={csrftoken}
|
|
48
|
-
debugCookieName={debugCookieName}
|
|
49
|
-
debugCookieExpiration={debugCookieExpiration}
|
|
50
|
-
debugMode={debugMode}
|
|
51
|
-
sessionCookieName={sessionCookieName}
|
|
52
|
-
sessionCookieExpiration={sessionCookieExpiration}
|
|
53
|
-
authSessionCookieName={authSessionCookieName}
|
|
54
|
-
showConsole={true}
|
|
55
|
-
cookieDomain={cookieDomain}
|
|
56
|
-
/>
|
|
57
|
-
</React.StrictMode>,
|
|
58
|
-
);
|
|
66
|
+
```console
|
|
67
|
+
yarn add @smarter.sh/ui-chat
|
|
59
68
|
```
|
|
60
69
|
|
|
61
|
-
### Build from source
|
|
62
|
-
|
|
63
|
-
To build and deploy for use in the Smarter Web Console Prompt Engineer Workbench, do the following.
|
|
64
|
-
This assumes that you have already built your AWS cloud infrastructure using [github.com/smarter-sh/smarter-infrastructure](https://github.com/smarter-sh/smarter-infrastructure) and that a CDN exists at cdn.platform.example.com.
|
|
65
|
-
|
|
66
70
|
```console
|
|
67
|
-
|
|
68
|
-
export PLATFORM_SUBDOMAIN=platform
|
|
69
|
-
npm install
|
|
70
|
-
make build
|
|
71
|
-
make release
|
|
71
|
+
pnpm add @smarter.sh/ui-chat
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
`react` and `react-dom` 19 are peer dependencies. The package is published as ES and UMD bundles, and is meant to be
|
|
75
|
+
used with a bundler such as Vite, webpack, Rollup or Next.js.
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
## Quick start
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
```tsx
|
|
80
|
+
import { createRoot } from "react-dom/client";
|
|
81
|
+
import { SmarterChat } from "@smarter.sh/ui-chat";
|
|
82
|
+
import "@smarter.sh/ui-chat/dist/ui-chat.css";
|
|
83
|
+
import "katex/dist/katex.min.css"; // math in responses. katex is installed with the package.
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
<div
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
createRoot(document.getElementById("chat")!).render(
|
|
86
|
+
<div style={{ height: 600 }}>
|
|
87
|
+
<SmarterChat
|
|
88
|
+
apiUrl="https://stackademy.3141-5926-5359.api.example.com/"
|
|
89
|
+
apiKey={import.meta.env.VITE_SMARTER_API_KEY} // only if the LLMClient has an api key
|
|
90
|
+
showConsole={false}
|
|
91
|
+
/>
|
|
92
|
+
</div>,
|
|
93
|
+
);
|
|
92
94
|
```
|
|
93
95
|
|
|
94
|
-
|
|
96
|
+
The chat fills the height of its parent element, so give the parent a height.
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
## Requirements on the Smarter side
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
The component talks directly to the Smarter platform from your visitors' browsers, so three things must be true:
|
|
99
101
|
|
|
100
|
-
1.
|
|
102
|
+
1. **The LLMClient is deployed.** `apiUrl` is its url, for example
|
|
103
|
+
`https://<name>.<account-number>.api.<your-smarter-domain>/`, or its verified custom domain. The chat calls that
|
|
104
|
+
host only.
|
|
105
|
+
2. **Your page's origin is allowed.** Requests from your page are cross-origin, with credentials. List your origins in
|
|
106
|
+
the LLMClient's manifest, and apply it:
|
|
101
107
|
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
```yaml
|
|
109
|
+
spec:
|
|
110
|
+
config:
|
|
111
|
+
allowedOrigins:
|
|
112
|
+
- https://www.example.com
|
|
113
|
+
- http://localhost:5173
|
|
106
114
|
```
|
|
107
115
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
3. **The browser can authenticate, if the LLMClient requires it.** A deployed LLMClient without api keys is public:
|
|
117
|
+
pass no `apiKey`, and every prompt is charged to the LLMClient's owner. For one with an api key, pass a Smarter api
|
|
118
|
+
key as `apiKey`, which is sent as `Authorization: Token <apiKey>`. Anyone who can view your page can read it, so use
|
|
119
|
+
a key dedicated to the page.
|
|
120
|
+
|
|
121
|
+
The page receives the LLMClient's public configuration (its name, welcome message, example prompts, model and system
|
|
122
|
+
prompt), never, for example, its owner's profile or the session's diagnostic histories.
|
|
123
|
+
|
|
124
|
+
See [Embedding Smarter Chat](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/embedding.html) for
|
|
125
|
+
details, including troubleshooting.
|
|
126
|
+
|
|
127
|
+
## Props
|
|
128
|
+
|
|
129
|
+
Only `apiUrl` is required.
|
|
130
|
+
|
|
131
|
+
| Prop | Type | Default | Description |
|
|
132
|
+
| ------------------------- | ---------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| `apiUrl` | `string` | (required) | The LLMClient's api url. The chat appends `config/` to it for its configuration. |
|
|
134
|
+
| `apiKey` | `string \| null` | `null` | A Smarter api key, sent as `Authorization: Token <apiKey>`, for LLMClients that require authentication. |
|
|
135
|
+
| `showConsole` | `boolean` | `true` | Show the developer Console beside the chat. It needs a wide container; set it to `false` for end-user pages. |
|
|
136
|
+
| `toggleMetadata` | `boolean` | `false` | Show the Sandbox mode / Production mode button, which shows and hides the backend's own messages (system prompt, tool results, Smarter's), and start in sandbox mode. Without it, the chat is in production mode. |
|
|
137
|
+
| `streamProgress` | `boolean` | `true` | Display a running prompt's progress, which the prompt api streams as Server-Sent Events. |
|
|
138
|
+
| `debugMode` | `boolean` | `false` | Log to the browser console. |
|
|
139
|
+
| `cookieDomain` | `string` | `""` | The domain whose cookies the chat reads. Empty means the page's own domain. |
|
|
140
|
+
| `sessionCookieName` | `string` | `"session_key"` | The cookie in which the chat saves its session's key, for the page's path. |
|
|
141
|
+
| `sessionCookieExpiration` | `number` | one day | The session cookie's lifetime, in milliseconds. |
|
|
142
|
+
| `csrfCookieName` | `string` | `"csrftoken"` | The name of Django's CSRF cookie, whose value is sent as the `X-CSRFToken` header. |
|
|
143
|
+
| `csrftoken` | `string \| null` | `null` | The CSRF token, when the page cannot read the CSRF cookie. |
|
|
144
|
+
| `debugCookieName` | `string` | `"debug"` | The cookie in which the chat saves the LLMClient's debug mode. |
|
|
145
|
+
| `debugCookieExpiration` | `number` | one day | The debug cookie's lifetime, in milliseconds. |
|
|
146
|
+
| `smarterRequestId` | `string` | `""` | A unique id of the page request, sent as the `X-Smarter-RequestId` header, for tracing. |
|
|
147
|
+
| `logStreamUrl` | `string \| null` | `null` | The url of a server log stream (Server-Sent Events), for the Console's Server Logs tab. |
|
|
148
|
+
|
|
149
|
+
## Examples
|
|
150
|
+
|
|
151
|
+
### A chat widget in a corner of the page
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
function ChatWidget({ apiKey }: { apiKey: string }) {
|
|
155
|
+
const [open, setOpen] = useState(false);
|
|
156
|
+
return (
|
|
157
|
+
<>
|
|
158
|
+
<button onClick={() => setOpen(!open)}>Chat with us</button>
|
|
159
|
+
{open && (
|
|
160
|
+
<div style={{ position: "fixed", right: 24, bottom: 80, width: 400, height: 600 }}>
|
|
161
|
+
<SmarterChat apiUrl="https://support.3141-5926-5359.api.example.com/" apiKey={apiKey} showConsole={false} />
|
|
162
|
+
</div>
|
|
163
|
+
)}
|
|
164
|
+
</>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
113
167
|
```
|
|
114
168
|
|
|
115
|
-
|
|
169
|
+
### Next.js
|
|
116
170
|
|
|
117
|
-
|
|
118
|
-
yalc add @smarter.sh/ui-chat
|
|
119
|
-
npm install # verifies peer dependencies
|
|
120
|
-
```
|
|
171
|
+
The component uses browser apis (cookies, `localStorage`, `EventSource`), so render it on the client only:
|
|
121
172
|
|
|
122
|
-
|
|
173
|
+
```tsx
|
|
174
|
+
"use client";
|
|
175
|
+
import dynamic from "next/dynamic";
|
|
176
|
+
import "@smarter.sh/ui-chat/dist/ui-chat.css";
|
|
177
|
+
import "katex/dist/katex.min.css";
|
|
123
178
|
|
|
124
|
-
|
|
179
|
+
const SmarterChat = dynamic(() => import("@smarter.sh/ui-chat").then((m) => m.SmarterChat), { ssr: false });
|
|
125
180
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
181
|
+
export default function Chat() {
|
|
182
|
+
return (
|
|
183
|
+
<div style={{ height: "80vh" }}>
|
|
184
|
+
<SmarterChat
|
|
185
|
+
apiUrl="https://stackademy.3141-5926-5359.api.example.com/"
|
|
186
|
+
apiKey={process.env.NEXT_PUBLIC_SMARTER_API_KEY}
|
|
187
|
+
showConsole={false}
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
130
192
|
```
|
|
131
193
|
|
|
132
|
-
###
|
|
133
|
-
|
|
134
|
-
See [Getting Started with the Smarter Chatbot Api](./doc/CHATBOT_API.md)
|
|
135
|
-
This app interacts with two endpoints from the [smarter.sh/v1](https://platform.smarter.sh/docs/api/) chatbot api:
|
|
194
|
+
### A prompt engineering workbench
|
|
136
195
|
|
|
137
|
-
|
|
138
|
-
- POST `/chat/`: send a text completion prompt to the Smarter Api.
|
|
196
|
+
The full workbench, as in the Smarter web console: the Console, the mode toggle, and your server logs.
|
|
139
197
|
|
|
140
|
-
|
|
198
|
+
```tsx
|
|
199
|
+
<SmarterChat
|
|
200
|
+
apiUrl={apiUrl}
|
|
201
|
+
apiKey={apiKey}
|
|
202
|
+
toggleMetadata
|
|
203
|
+
showConsole
|
|
204
|
+
logStreamUrl="https://platform.example.com/dashboard/logs/api/stream/"
|
|
205
|
+
/>
|
|
206
|
+
```
|
|
141
207
|
|
|
142
|
-
|
|
143
|
-
- authenticated: `https://platform.smarter.sh/chatbots/<name>/`. This react component looks for and adds the Smarter platform sessionid cookie value to request headers, if it exists.
|
|
208
|
+
## Styling
|
|
144
209
|
|
|
145
|
-
|
|
210
|
+
Import the stylesheet once, anywhere in your app:
|
|
146
211
|
|
|
147
|
-
|
|
148
|
-
|
|
212
|
+
```ts
|
|
213
|
+
import "@smarter.sh/ui-chat/dist/ui-chat.css"; // or "@smarter.sh/ui-chat/style.css"
|
|
214
|
+
import "katex/dist/katex.min.css";
|
|
215
|
+
```
|
|
149
216
|
|
|
150
|
-
|
|
217
|
+
- **`ui-chat.css`** is the component's own css, including
|
|
218
|
+
[chatscope](https://github.com/chatscope/chat-ui-kit-react)'s chat styles, which it is built on.
|
|
219
|
+
- **`katex/dist/katex.min.css`** is the stylesheet of math in responses. It's left out of `ui-chat.css` so that pages
|
|
220
|
+
without math don't pay for KaTeX's fonts. Without it, math is displayed twice: as text, and as unstyled MathML.
|
|
151
221
|
|
|
152
|
-
|
|
153
|
-
-
|
|
222
|
+
The component's elements have stable class names, prefixed `smarter-chat-` (for example `.smarter-chat-message-list`,
|
|
223
|
+
`.smarter-chat-code`, `.smarter-chat-image`), under a root `.SmarterChat` element, so you can override their styles
|
|
224
|
+
from your own stylesheet.
|
|
154
225
|
|
|
155
|
-
|
|
226
|
+
## TypeScript
|
|
156
227
|
|
|
157
|
-
|
|
158
|
-
Example: [/chatbots/example/config/?session_key=YOUR-SESSION-KEY](http://localhost:8000/chatbots/example/config/)
|
|
228
|
+
Type declarations are included. Besides the components, the package exports:
|
|
159
229
|
|
|
160
|
-
|
|
230
|
+
| Export | What it is |
|
|
231
|
+
| ------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
|
|
232
|
+
| `SmarterChat` | The chat component. |
|
|
233
|
+
| `Console` | The developer Console, on its own. |
|
|
234
|
+
| `SmarterChatProps` | The chat's props. |
|
|
235
|
+
| `ChatConfig`, `LLMClientConfig`, `ChatHistory`, `ChatMetaData` | The LLMClient configuration that the Smarter config api returns. |
|
|
236
|
+
| `Contract` | Every type of the api contract, generated from its JSON Schema. |
|
|
237
|
+
| `normalizeConfig`, `CHAT_CONTRACT_V2_CAPABILITY` | Converts an older platform's configuration to the current one. |
|
|
238
|
+
| `ApiMessage`, `ChatMessage` | A message as the api sends it, and as the chat thread holds it. |
|
|
239
|
+
| `PromptProgressEvent` | A step of a running prompt, as the prompt api streams it. |
|
|
240
|
+
| `MessageDirectionEnum`, `SenderRoleEnum`, `ValidMessageRolesEnum`, `MenuItems` | Message directions and roles, and the Console's tabs. |
|
|
241
|
+
| `version` | The package's version. |
|
|
161
242
|
|
|
162
|
-
|
|
243
|
+
## How it works
|
|
163
244
|
|
|
164
|
-
|
|
165
|
-
example: `http://api.smarter.sh/v1/chatbots/smarter/example/`
|
|
245
|
+
The component makes two kinds of POST requests to Smarter, with the browser's cookies:
|
|
166
246
|
|
|
167
|
-
|
|
247
|
+
1. **`<apiUrl>config/`** returns the LLMClient's configuration and the chat session's history, which restores the
|
|
248
|
+
thread when the page reloads. A new session's key is saved in a cookie.
|
|
249
|
+
2. **The LLMClient's prompt api** (`llmclient.url_llmclient` in the configuration) receives the thread with each new
|
|
250
|
+
message, and returns the messages to add to it. With `streamProgress`, it answers with Server-Sent Events: progress
|
|
251
|
+
events while the prompt runs, then the result.
|
|
168
252
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"method": "POST",
|
|
172
|
-
"credentials": "include",
|
|
173
|
-
"mode": "cors",
|
|
174
|
-
"headers": {
|
|
175
|
-
"Accept": "application/json",
|
|
176
|
-
"Content-Type": "application/json",
|
|
177
|
-
"X-CSRFToken": "q9WXqqIhYJMI3ZSBIOE18JMORBMqAHri",
|
|
178
|
-
"Origin": "http://localhost:8000",
|
|
179
|
-
"Cookie": "session_key=a07593ecfaecd24008ca4251096732663ac0213b8cc6bdcce4f4c043276ab0b5; debug=true;"
|
|
180
|
-
},
|
|
181
|
-
"body": "{\"session_key\":\"a07593ecfaecd24008ca4251096732663ac0213b8cc6bdcce4f4c043276ab0b5\",\"messages\":[{\"role\":\"system\",\"content\":\"You are a helpful chatbot."},{\"role\":\"assistant\",\"content\":\"Welcome to the Smarter demo!\"}]}"
|
|
182
|
-
}
|
|
183
|
-
```
|
|
253
|
+
The api contract is versioned, and generated from the backend's Pydantic models: the component asks for the current
|
|
254
|
+
version, with `X-Smarter-Capabilities: chat-contract-v2`, and reads the previous one from older Smarter platforms.
|
|
184
255
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
```json
|
|
188
|
-
{
|
|
189
|
-
"data": {
|
|
190
|
-
"isBase64Encoded": false,
|
|
191
|
-
"statusCode": 200,
|
|
192
|
-
"headers": {
|
|
193
|
-
"Content-Type": "application/json"
|
|
194
|
-
},
|
|
195
|
-
"body": "{\"id\": \"chatcmpl-AoDpMvoAhf8iSJuEm6pMqkX62HK4G\", \"choices\": [{\"finish_reason\": \"stop\", \"index\": 0, \"logprobs\": null, \"message\": {\"content\": \"Hello! While I'm not your mom, I'm here to help you with any questions or tasks you have. What can I assist you with today?\", \"refusal\": null, \"role\": \"assistant\", \"audio\": null, \"function_call\": null, \"tool_calls\": null}}], \"created\": 1736532916, \"model\": \"gpt-4-turbo-2024-04-09\", \"object\": \"chat.completion\", \"service_tier\": \"default\", \"system_fingerprint\": \"fp_f17929ee92\", \"usage\": {\"completion_tokens\": 33, \"prompt_tokens\": 1122, \"total_tokens\": 1155, \"completion_tokens_details\": {\"accepted_prediction_tokens\": 0, \"audio_tokens\": 0, \"reasoning_tokens\": 0, \"rejected_prediction_tokens\": 0}, \"prompt_tokens_details\": {\"audio_tokens\": 0, \"cached_tokens\": 0}}, \"metadata\": {\"tool_calls\": null, \"model\": \"gpt-4-turbo\", \"temperature\": 0.5, \"max_tokens\": 256, \"input_text\": \"hi mom\"}}"
|
|
196
|
-
},
|
|
197
|
-
"api": "smarter.sh/v1",
|
|
198
|
-
"thing": "Chatbot",
|
|
199
|
-
"metadata": {
|
|
200
|
-
"command": "chat"
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
```
|
|
256
|
+
The complete contract, with every request, response, header, cookie and event, is in
|
|
257
|
+
[The Chat API Contract](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/api-contract.html).
|
|
204
258
|
|
|
205
|
-
##
|
|
259
|
+
## Browser support
|
|
206
260
|
|
|
207
|
-
|
|
261
|
+
Current versions of Chrome, Edge, Firefox and Safari. The component uses `fetch` response streams, `EventSource`,
|
|
262
|
+
`localStorage` and the `inert` attribute.
|
|
208
263
|
|
|
209
|
-
|
|
210
|
-
- `make init`: Setup your environment for first time use. sets up your Node environment for you. initializes pre-commit, which you need to run prior to creating pull requests.
|
|
211
|
-
- `make run`: Run the dev server locally
|
|
212
|
-
- `make build`: Build the react.js project. saves vite.js output to `./build` in the root of this project.
|
|
213
|
-
- `make release`: Deploy the react.js project. **REQUIRES awscli + keypair with sufficient permissions**. Publishes the contents of the `./build` folder to an AWS S3 bucket served by the host defined by the value of `CDN_HOST_BASE_URL` located in shared/constant.js. For example, the react app for the Smarter workbench is initialized and served from these endpoints: a. [index.html](https://cdn.platform.smarter.sh/ui-chat/index.html): the react app build artifacts, and b. [app-loader.js](https://cdn.platform.smarter.sh/ui-chat/app-loader.js): a script to insert the react app build artifacts into the DOM.
|
|
264
|
+
## Development
|
|
214
265
|
|
|
215
|
-
|
|
266
|
+
```console
|
|
267
|
+
git clone https://github.com/smarter-sh/smarter-chat.git
|
|
268
|
+
cd smarter-chat
|
|
269
|
+
make init # npm install
|
|
270
|
+
make serve # Storybook at http://localhost:6006, with the Smarter api mocked
|
|
271
|
+
make test # Vitest; every story is also rendered as a test
|
|
272
|
+
```
|
|
216
273
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
274
|
+
No Smarter backend is needed: the stories mock the api with [MSW](https://mswjs.io/). See
|
|
275
|
+
[CONTRIBUTING.md](https://github.com/smarter-sh/smarter-chat/blob/main/.github/CONTRIBUTING.md) for the rest of the
|
|
276
|
+
workflow (every `make` target, working inside the Smarter repository, commits and releases), and the
|
|
277
|
+
[developer guide](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/development.html) for the
|
|
278
|
+
architecture.
|
|
220
279
|
|
|
221
|
-
##
|
|
280
|
+
## License
|
|
222
281
|
|
|
223
|
-
|
|
282
|
+
[AGPL-3.0-or-later](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE), as Smarter is. Copyright © Lawrence
|
|
283
|
+
McDaniel.
|
|
224
284
|
|
|
225
|
-
|
|
285
|
+
Contributions are welcome: code, documentation, how-to videos, testing and community help. See
|
|
286
|
+
[CONTRIBUTING.md](https://github.com/smarter-sh/smarter-chat/blob/main/.github/CONTRIBUTING.md), or contact
|
|
287
|
+
[Lawrence McDaniel](https://lawrencemcdaniel.com/contact).
|