@smarter.sh/ui-chat 0.7.0 → 0.8.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/README.md +274 -139
- package/dist/smarter-chat-library.es.js +2208 -1841
- package/dist/smarter-chat-library.es.js.map +1 -1
- package/dist/smarter-chat-library.umd.js +38 -38
- package/dist/smarter-chat-library.umd.js.map +1 -1
- package/dist/types/src/components/DocsDialog/Component.d.ts +8 -0
- package/dist/types/src/components/DocsDialog/data.d.ts +18 -0
- package/dist/types/src/components/DocsDialog/index.d.ts +2 -0
- package/dist/types/src/components/SmarterChat/Component.d.ts +6 -2
- package/dist/types/src/components/SmarterChat/icons.d.ts +2 -0
- package/dist/types/src/contract.gen.d.ts +1202 -0
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/lib/api.d.ts +29 -6
- package/dist/types/src/lib/messages.d.ts +1 -1
- package/dist/types/src/lib/styles.d.ts +40 -0
- package/dist/types/src/types.d.ts +28 -63
- package/dist/ui-chat.css +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,178 +1,313 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://github.com/smarter-sh/smarter-chat/)
|
|
3
|
-
[](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml)
|
|
4
|
-
[](https://codecov.io/gh/smarter-sh/smarter-chat)
|
|
5
|
-
<a href="https://smarter.sh">
|
|
6
|
-
<img src="https://img.shields.io/badge/Smarter.sh-orange?style=flat&logo=appveyor&logoColor=white" height="32">
|
|
7
|
-
</a>
|
|
8
|
-
|
|
9
|
-
# Smarter Chat
|
|
1
|
+
# @smarter.sh/ui-chat
|
|
10
2
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
tool calls and plugin usage, and optionally streams your server logs, in color, with long lines that scroll or wrap.
|
|
14
|
-
Drag the separator between the chat and the Console to resize them, or hide the Console, which slides out to the right.
|
|
15
|
-
The new chat button starts a new chat session, and clears the server logs. The Sandbox mode / Production mode button
|
|
16
|
-
shows and hides the backend's own messages in the chat thread. While a prompt runs, its progress (LLM requests, tool,
|
|
17
|
-
plugin and MCP server calls) is displayed in the thread, and a failed prompt is displayed with the LLM provider's error
|
|
18
|
-
message. Responses are rendered as GitHub flavored markdown (headings, emphasis, lists, tables, block quotes, code,
|
|
19
|
-
links and images), with raw html escaped, and images are scaled to fit their chat bubble. Math, written in LaTeX as
|
|
20
|
-
`\( ... \)` inline, or `\[ ... \]` or `$$ ... $$` displayed, is typeset by [KaTeX](https://katex.org). A `mermaid` code block is drawn as a
|
|
21
|
-
[Mermaid](https://mermaid.js.org) diagram, which is downloaded only when a message first has one, with a button that
|
|
22
|
-
shows its code.
|
|
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.
|
|
23
5
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
](https://github.com/smarter-sh/smarter-chat)
|
|
7
|
+
[](https://www.npmjs.com/package/@smarter.sh/ui-chat)
|
|
8
|
+
[](https://www.npmjs.com/package/@smarter.sh/ui-chat)
|
|
9
|
+
[](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml)
|
|
10
|
+
[](https://docs.smarter.sh/smarter-framework/smarter-chat.html)
|
|
11
|
+
[](https://app.codecov.io/gh/smarter-sh/smarter-chat)
|
|
12
|
+
[](#typescript)
|
|
13
|
+
[](https://react.dev)
|
|
14
|
+
[](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE)
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
Smarter Chat is the chat UI of the Smarter web console's prompt engineering workbench, published as a React component
|
|
19
|
+
so that any web page can use a Smarter LLMClient as its chat backend: a marketing site, a customer portal, a storefront,
|
|
20
|
+
an intranet, or your own application.
|
|
21
|
+
|
|
22
|
+
**[Documentation](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat.html)** ·
|
|
23
|
+
**[Storybook](#development)** · **[Changelog](https://github.com/smarter-sh/smarter-chat/blob/main/CHANGELOG.md)** ·
|
|
24
|
+
**[Issues](https://github.com/smarter-sh/smarter-chat/issues)**
|
|
25
|
+
|
|
26
|
+
## Contents
|
|
27
|
+
|
|
28
|
+
- [Features](#features)
|
|
29
|
+
- [Installation](#installation)
|
|
30
|
+
- [Quick start](#quick-start)
|
|
31
|
+
- [Requirements on the Smarter side](#requirements-on-the-smarter-side)
|
|
32
|
+
- [Props](#props)
|
|
33
|
+
- [Examples](#examples)
|
|
34
|
+
- [Styling](#styling)
|
|
35
|
+
- [TypeScript](#typescript)
|
|
36
|
+
- [How it works](#how-it-works)
|
|
37
|
+
- [Browser support](#browser-support)
|
|
38
|
+
- [Development](#development)
|
|
39
|
+
- [License](#license)
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- **One component, one prop.** Give it the url of a deployed LLMClient, and it loads the LLMClient's name, welcome
|
|
44
|
+
message, example prompts and placeholder from Smarter.
|
|
45
|
+
- **Persistent chat sessions.** The conversation survives page reloads, and each LLMClient on a site keeps its own
|
|
46
|
+
session.
|
|
47
|
+
- **Live progress.** While a prompt runs, the chat shows each LLM request, tool, plugin and MCP server call, streamed
|
|
48
|
+
as Server-Sent Events.
|
|
49
|
+
- **Rich responses.** GitHub flavored markdown (tables, lists, block quotes, images, links), syntax-highlighted code
|
|
50
|
+
blocks with a copy button, LaTeX math typeset by [KaTeX](https://katex.org), and
|
|
51
|
+
[Mermaid](https://mermaid.js.org) diagrams.
|
|
52
|
+
- **Safe by default.** Raw html is displayed as text, links and images are restricted to `http(s)`, relative and raster
|
|
53
|
+
`data:` urls, and the rendered html and Mermaid's svg are sanitized with
|
|
54
|
+
[DOMPurify](https://github.com/cure53/DOMPurify).
|
|
55
|
+
- **Lightweight where it counts.** React is a peer dependency, Mermaid is loaded only when a message first has a
|
|
56
|
+
diagram, and KaTeX's fonts are downloaded only when an equation uses them.
|
|
57
|
+
- **Optional developer Console.** A resizable side panel with the LLMClient's configuration, the session's api calls,
|
|
58
|
+
tool calls and plugin usage, and a live server log stream, as in the Smarter workbench.
|
|
59
|
+
- **Accessible.** Labeled regions and controls, keyboard-resizable panels, and MathML for screen readers.
|
|
60
|
+
- **Typed.** Written in TypeScript, with type declarations for its props and for the Smarter api's data.
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
29
63
|
|
|
30
|
-
|
|
64
|
+
```console
|
|
65
|
+
npm install @smarter.sh/ui-chat
|
|
66
|
+
```
|
|
31
67
|
|
|
32
|
-
|
|
68
|
+
```console
|
|
69
|
+
yarn add @smarter.sh/ui-chat
|
|
70
|
+
```
|
|
33
71
|
|
|
34
72
|
```console
|
|
35
|
-
|
|
73
|
+
pnpm add @smarter.sh/ui-chat
|
|
36
74
|
```
|
|
37
75
|
|
|
76
|
+
`react` and `react-dom` 19 are peer dependencies. The package is published as ES and UMD bundles, and is meant to be
|
|
77
|
+
used with a bundler such as Vite, webpack, Rollup or Next.js.
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
38
81
|
```tsx
|
|
39
82
|
import { createRoot } from "react-dom/client";
|
|
40
83
|
import { SmarterChat } from "@smarter.sh/ui-chat";
|
|
41
84
|
import "@smarter.sh/ui-chat/dist/ui-chat.css";
|
|
42
|
-
|
|
43
|
-
import "katex/dist/katex.min.css";
|
|
85
|
+
import "katex/dist/katex.min.css"; // math in responses. katex is installed with the package.
|
|
44
86
|
|
|
45
87
|
createRoot(document.getElementById("chat")!).render(
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
88
|
+
<div style={{ height: 600 }}>
|
|
89
|
+
<SmarterChat
|
|
90
|
+
apiUrl="https://stackademy.3141-5926-5359.api.example.com/"
|
|
91
|
+
apiKey={import.meta.env.VITE_SMARTER_API_KEY} // only if the LLMClient has an api key
|
|
92
|
+
showConsole={false}
|
|
93
|
+
/>
|
|
94
|
+
</div>,
|
|
51
95
|
);
|
|
52
96
|
```
|
|
53
97
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
### Props
|
|
57
|
-
|
|
58
|
-
| Prop | Default | Description |
|
|
59
|
-
| ------------------------- | --------------- | ------------------------------------------------------------------------------------------------------- |
|
|
60
|
-
| `apiUrl` | (required) | The url of the LLMClient's api. The chat appends `config/` for its configuration. |
|
|
61
|
-
| `apiKey` | `null` | A Smarter api key, sent as `Authorization: Token <apiKey>`, for LLMClients that require authentication. |
|
|
62
|
-
| `toggleMetadata` | `false` | Show the button that shows and hides the backend's messages (system prompt, tool results, Smarter's). |
|
|
63
|
-
| `showConsole` | `true` | Show the Console beside the chat. It needs a wide page. |
|
|
64
|
-
| `debugMode` | `false` | Log to the browser console. |
|
|
65
|
-
| `csrfCookieName` | `"csrftoken"` | The name of Django's CSRF cookie, whose value is sent as the `X-CSRFToken` header. |
|
|
66
|
-
| `csrftoken` | `null` | The CSRF token, when the page cannot read the CSRF cookie. |
|
|
67
|
-
| `sessionCookieName` | `"session_key"` | The cookie in which the chat saves its chat session's key, for the page's path. |
|
|
68
|
-
| `sessionCookieExpiration` | one day | The session cookie's lifetime, in milliseconds. |
|
|
69
|
-
| `debugCookieName` | `"debug"` | The cookie in which the chat saves the LLMClient's debug mode. |
|
|
70
|
-
| `debugCookieExpiration` | one day | The debug cookie's lifetime, in milliseconds. |
|
|
71
|
-
| `cookieDomain` | `""` | The domain whose cookies the chat reads. Empty means the page's own domain. |
|
|
72
|
-
| `smarterRequestId` | `""` | A unique id of the page request, sent as the `X-Smarter-RequestId` header. |
|
|
73
|
-
| `streamProgress` | `true` | Display a running prompt's progress, which the prompt api streams as Server-Sent Events. |
|
|
74
|
-
| `logStreamUrl` | `null` | The url of a server log stream (Server-Sent Events), for the Console's "Server Logs" tab. |
|
|
75
|
-
|
|
76
|
-
The package also exports the `Console` component, the `MessageDirectionEnum`, `SenderRoleEnum`,
|
|
77
|
-
`ValidMessageRolesEnum` and `MenuItems` enums, `version`, and TypeScript types for its props and for the
|
|
78
|
-
Smarter api's data (`SmarterChatProps`, `ChatConfig`, `ChatMessage`, `PromptProgressEvent`, ...).
|
|
79
|
-
|
|
80
|
-
### The Smarter api
|
|
81
|
-
|
|
82
|
-
Smarter Chat calls two apis, both with POST requests that send the browser's cookies:
|
|
83
|
-
|
|
84
|
-
- `<apiUrl>config/?session_key=<key>`: the LLMClient's configuration, including the chat session's history,
|
|
85
|
-
which restores the chat thread when the page reloads. A new chat session's key is saved in the session cookie.
|
|
86
|
-
- `chatbot.url_chatbot` in the configuration: the LLMClient's prompt api. It receives the chat thread with each
|
|
87
|
-
new message, `{"session_key": "...", "messages": [...]}`, and returns the completion as a JSON string, in
|
|
88
|
-
`data.body`, whose `smarter.messages` are added to the thread. A failed prompt returns the LLM provider's status,
|
|
89
|
-
and `{"error": {"status", "message"}, "response": <the completion>}` in its body. With `streamProgress`, the
|
|
90
|
-
request accepts `text/event-stream`, and the response is `progress` events while the prompt runs, then a `result`
|
|
91
|
-
event, `{"status": <http status>, "response": <the same JSON>}`. A server that doesn't stream answers with JSON.
|
|
92
|
-
|
|
93
|
-
Requests from your page to the Smarter api are cross-origin, so your page's origin must be allowed by the Smarter
|
|
94
|
-
platform's CORS configuration.
|
|
98
|
+
The chat fills the height of its parent element, so give the parent a height.
|
|
95
99
|
|
|
96
|
-
##
|
|
100
|
+
## Requirements on the Smarter side
|
|
97
101
|
|
|
98
|
-
|
|
102
|
+
The component talks directly to the Smarter platform from your visitors' browsers, so three things must be true:
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
1. **The LLMClient is deployed.** `apiUrl` is its url, for example
|
|
105
|
+
`https://<name>.<account-number>.api.<your-smarter-domain>/`, or its verified custom domain. The chat calls that
|
|
106
|
+
host only.
|
|
107
|
+
2. **Your page's origin is allowed.** Requests from your page are cross-origin, with credentials. List your origins in
|
|
108
|
+
the LLMClient's manifest, and apply it:
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
spec:
|
|
112
|
+
config:
|
|
113
|
+
prompt:
|
|
114
|
+
allowedOrigins:
|
|
115
|
+
- https://www.example.com
|
|
116
|
+
- http://localhost:5173
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
3. **The browser can authenticate, if the LLMClient requires it.** A deployed LLMClient without api keys is public:
|
|
120
|
+
pass no `apiKey`, and every prompt is charged to the LLMClient's owner. For one with an api key, pass a Smarter api
|
|
121
|
+
key as `apiKey`, which is sent as `Authorization: Token <apiKey>`. Anyone who can view your page can read it, so use
|
|
122
|
+
a key dedicated to the page.
|
|
123
|
+
|
|
124
|
+
The page receives the LLMClient's public configuration (its name, welcome message, example prompts, model and system
|
|
125
|
+
prompt), never, for example, its owner's profile or the session's diagnostic histories.
|
|
126
|
+
|
|
127
|
+
See [Embedding Smarter Chat](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/embedding.html) for
|
|
128
|
+
details, including troubleshooting.
|
|
129
|
+
|
|
130
|
+
## Props
|
|
131
|
+
|
|
132
|
+
Only `apiUrl` is required.
|
|
133
|
+
|
|
134
|
+
| Prop | Type | Default | Description |
|
|
135
|
+
| ------------------------- | ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `apiUrl` | `string` | (required) | The LLMClient's api url. The chat appends `config/` to it for its configuration. |
|
|
137
|
+
| `apiKey` | `string \| null` | `null` | A Smarter api key, sent as `Authorization: Token <apiKey>`, for LLMClients that require authentication. |
|
|
138
|
+
| `showConsole` | `boolean` | `true` | Show the developer Console beside the chat. It needs a wide container; set it to `false` for end-user pages. |
|
|
139
|
+
| `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. Sandbox mode also shows the Docs button, a dialog of technical references. Without it, the chat is in production mode. |
|
|
140
|
+
| `streamProgress` | `boolean` | `true` | Display a running prompt's progress, which the prompt api streams as Server-Sent Events. |
|
|
141
|
+
| `debugMode` | `boolean` | `false` | Log to the browser console. |
|
|
142
|
+
| `cookieDomain` | `string` | `""` | The domain whose cookies the chat reads. Empty means the page's own domain. |
|
|
143
|
+
| `sessionCookieName` | `string` | `"session_key"` | The cookie in which the chat saves its session's key, for the page's path. |
|
|
144
|
+
| `sessionCookieExpiration` | `number` | one day | The session cookie's lifetime, in milliseconds. |
|
|
145
|
+
| `csrfCookieName` | `string` | `"csrftoken"` | The name of Django's CSRF cookie, whose value is sent as the `X-CSRFToken` header. |
|
|
146
|
+
| `csrftoken` | `string \| null` | `null` | The CSRF token, when the page cannot read the CSRF cookie. |
|
|
147
|
+
| `debugCookieName` | `string` | `"debug"` | The cookie in which the chat saves the LLMClient's debug mode. |
|
|
148
|
+
| `debugCookieExpiration` | `number` | one day | The debug cookie's lifetime, in milliseconds. |
|
|
149
|
+
| `smarterRequestId` | `string` | `""` | A unique id of the page request, sent as the `X-Smarter-RequestId` header, for tracing. |
|
|
150
|
+
| `logStreamUrl` | `string \| null` | `null` | The url of a server log stream (Server-Sent Events), for the Console's Server Logs tab. |
|
|
151
|
+
|
|
152
|
+
## Examples
|
|
153
|
+
|
|
154
|
+
### A chat widget in a corner of the page
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
function ChatWidget({ apiKey }: { apiKey: string }) {
|
|
158
|
+
const [open, setOpen] = useState(false);
|
|
159
|
+
return (
|
|
160
|
+
<>
|
|
161
|
+
<button onClick={() => setOpen(!open)}>Chat with us</button>
|
|
162
|
+
{open && (
|
|
163
|
+
<div style={{ position: "fixed", right: 24, bottom: 80, width: 400, height: 600 }}>
|
|
164
|
+
<SmarterChat apiUrl="https://support.3141-5926-5359.api.example.com/" apiKey={apiKey} showConsole={false} />
|
|
165
|
+
</div>
|
|
166
|
+
)}
|
|
167
|
+
</>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
105
170
|
```
|
|
106
171
|
|
|
107
|
-
|
|
108
|
-
[MSW](https://mswjs.io/), so no backend is needed. When the Smarter dev server is running at http://localhost:9357, the
|
|
109
|
-
stories use the web console's own stylesheets; without it, they use Bootstrap, which the web console's theme is built
|
|
110
|
-
on.
|
|
172
|
+
### Next.js
|
|
111
173
|
|
|
112
|
-
|
|
113
|
-
| --------------- | ------------------------------------------------------------------------------------------------- |
|
|
114
|
-
| `make init` | Installs the dependencies. |
|
|
115
|
-
| `make serve` | Browses the components in Storybook, with the Smarter api mocked. |
|
|
116
|
-
| `make run` | Runs the app with Vite's dev server, proxying api requests to the Smarter dev server (port 9357). |
|
|
117
|
-
| `make build` | Builds the app, with a Vite manifest for Django, and the npm package into `dist/`. |
|
|
118
|
-
| `make test` | Runs the unit tests (Vitest and React Testing Library). Every story is also rendered as a test. |
|
|
119
|
-
| `make coverage` | Runs the unit tests with a coverage report in `coverage/`, which CI uploads to Codecov. |
|
|
120
|
-
| `make lint` | Lints with ESLint, type-checks with TypeScript, and checks formatting with Prettier. |
|
|
121
|
-
| `make release` | Runs the tests, then builds the npm package into `dist/` and publishes it to npm. |
|
|
174
|
+
The component uses browser apis (cookies, `localStorage`, `EventSource`), so render it on the client only:
|
|
122
175
|
|
|
123
|
-
|
|
176
|
+
```tsx
|
|
177
|
+
"use client";
|
|
178
|
+
import dynamic from "next/dynamic";
|
|
179
|
+
import "@smarter.sh/ui-chat/dist/ui-chat.css";
|
|
180
|
+
import "katex/dist/katex.min.css";
|
|
124
181
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
182
|
+
const SmarterChat = dynamic(() => import("@smarter.sh/ui-chat").then((m) => m.SmarterChat), { ssr: false });
|
|
183
|
+
|
|
184
|
+
export default function Chat() {
|
|
185
|
+
return (
|
|
186
|
+
<div style={{ height: "80vh" }}>
|
|
187
|
+
<SmarterChat
|
|
188
|
+
apiUrl="https://stackademy.3141-5926-5359.api.example.com/"
|
|
189
|
+
apiKey={process.env.NEXT_PUBLIC_SMARTER_API_KEY}
|
|
190
|
+
showConsole={false}
|
|
191
|
+
/>
|
|
192
|
+
</div>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
```
|
|
128
196
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
197
|
+
### A prompt engineering workbench
|
|
198
|
+
|
|
199
|
+
The full workbench, as in the Smarter web console: the Console, the mode toggle, and your server logs.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
<SmarterChat
|
|
203
|
+
apiUrl={apiUrl}
|
|
204
|
+
apiKey={apiKey}
|
|
205
|
+
toggleMetadata
|
|
206
|
+
showConsole
|
|
207
|
+
logStreamUrl="https://platform.example.com/dashboard/logs/api/stream/"
|
|
208
|
+
/>
|
|
134
209
|
```
|
|
135
210
|
|
|
136
|
-
|
|
137
|
-
working tree. Two differ: `make init` installs the whole workspace's dependencies, and `make build` builds the app into
|
|
138
|
-
the Smarter web console's static files, rather than into `build/`. The Smarter repository's `make react-test` and
|
|
139
|
-
`make react-lint`, and its GitHub Actions workflows, also test and lint Smarter Chat along with the other React apps.
|
|
211
|
+
## Styling
|
|
140
212
|
|
|
141
|
-
|
|
213
|
+
Import the stylesheet once, anywhere in your app:
|
|
142
214
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
215
|
+
```ts
|
|
216
|
+
import "@smarter.sh/ui-chat/dist/ui-chat.css"; // or "@smarter.sh/ui-chat/style.css"
|
|
217
|
+
import "katex/dist/katex.min.css";
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
- **`ui-chat.css`** is the component's own css, including
|
|
221
|
+
[chatscope](https://github.com/chatscope/chat-ui-kit-react)'s chat styles, which it is built on.
|
|
222
|
+
- **`katex/dist/katex.min.css`** is the stylesheet of math in responses. It's left out of `ui-chat.css` so that pages
|
|
223
|
+
without math don't pay for KaTeX's fonts. Without it, math is displayed twice: as text, and as unstyled MathML.
|
|
224
|
+
|
|
225
|
+
### The LLMClient's styles
|
|
226
|
+
|
|
227
|
+
The chat takes its look from the LLMClient's manifest, so most pages need no css of their own. Its
|
|
228
|
+
`spec.config.styles` sets the logo in the header, avatars beside the messages, a background image, a Google font, and
|
|
229
|
+
the colors of each part of the chat, which are chatscope's components:
|
|
230
|
+
|
|
231
|
+
```yaml
|
|
232
|
+
spec:
|
|
233
|
+
config:
|
|
234
|
+
styles:
|
|
235
|
+
appLogoUrl: https://cdn.example.com/logo.png
|
|
236
|
+
googleFont: Nunito
|
|
237
|
+
conversationHeader: { backgroundColor: "#14213d", color: "#ffffff" }
|
|
238
|
+
outgoingMessage: { backgroundColor: "#fca311", color: "#14213d" }
|
|
239
|
+
```
|
|
146
240
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
on `main` is then merged back into `alpha`. `feat` commits are minor releases, `fix` and `perf` commits are patches, and
|
|
152
|
-
a `BREAKING CHANGE:` footer is a major release. See `release.config.cjs`.
|
|
241
|
+
The chat sets them as css custom properties on its root `.SmarterChat` element, e.g. `--smarter-chat-header-bg` and
|
|
242
|
+
`--smarter-chat-outgoing-bg`, whose fallbacks are chatscope's own colors. Your stylesheet can set the same properties.
|
|
243
|
+
See [Styling Your LLMClient's Chat](https://docs.smarter.sh/en/latest/smarter-resources/llmclient/styles.html) for every
|
|
244
|
+
setting.
|
|
153
245
|
|
|
154
|
-
|
|
246
|
+
### Your own css
|
|
155
247
|
|
|
156
|
-
|
|
248
|
+
The component's elements have stable class names, prefixed `smarter-chat-` (for example `.smarter-chat-message-list`,
|
|
249
|
+
`.smarter-chat-code`, `.smarter-chat-image`), under a root `.SmarterChat` element, so you can override their styles
|
|
250
|
+
from your own stylesheet.
|
|
157
251
|
|
|
158
|
-
|
|
159
|
-
| ----------------------------- | ------------------------------------------------------------------------------------------ |
|
|
160
|
-
| `src/index.ts` | The npm package's public api. |
|
|
161
|
-
| `src/main.tsx`, `src/App.tsx` | The app that the Smarter web console renders, configured by its root element's attributes. |
|
|
162
|
-
| `src/components/` | `SmarterChat`, `Console`, `AppTitle` and `ErrorBoundary`, with their stories and tests. |
|
|
163
|
-
| `src/lib/` | The Smarter api calls, the chat thread's messages, and cookies. |
|
|
164
|
-
| `src/mocks/` | Example api data and MSW handlers, for the stories and tests. |
|
|
252
|
+
## TypeScript
|
|
165
253
|
|
|
166
|
-
|
|
254
|
+
Type declarations are included. Besides the components, the package exports:
|
|
255
|
+
|
|
256
|
+
| Export | What it is |
|
|
257
|
+
| ------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
|
|
258
|
+
| `SmarterChat` | The chat component. |
|
|
259
|
+
| `Console` | The developer Console, on its own. |
|
|
260
|
+
| `SmarterChatProps` | The chat's props. |
|
|
261
|
+
| `ChatConfig`, `LLMClientConfig`, `ChatHistory`, `ChatMetaData` | The LLMClient configuration that the Smarter config api returns. |
|
|
262
|
+
| `Contract` | Every type of the api contract, generated from its JSON Schema. |
|
|
263
|
+
| `normalizeConfig`, `CHAT_CONTRACT_V2_CAPABILITY` | Converts an older platform's configuration to the current one. |
|
|
264
|
+
| `ApiMessage`, `ChatMessage` | A message as the api sends it, and as the chat thread holds it. |
|
|
265
|
+
| `PromptProgressEvent` | A step of a running prompt, as the prompt api streams it. |
|
|
266
|
+
| `MessageDirectionEnum`, `SenderRoleEnum`, `ValidMessageRolesEnum`, `MenuItems` | Message directions and roles, and the Console's tabs. |
|
|
267
|
+
| `version` | The package's version. |
|
|
268
|
+
|
|
269
|
+
## How it works
|
|
270
|
+
|
|
271
|
+
The component makes two kinds of POST requests to Smarter, with the browser's cookies:
|
|
167
272
|
|
|
168
|
-
|
|
169
|
-
|
|
273
|
+
1. **`<apiUrl>config/`** returns the LLMClient's configuration and the chat session's history, which restores the
|
|
274
|
+
thread when the page reloads. A new session's key is saved in a cookie.
|
|
275
|
+
2. **The LLMClient's prompt api** (`llmclient.url_llmclient` in the configuration) receives the thread with each new
|
|
276
|
+
message, and returns the messages to add to it. With `streamProgress`, it answers with Server-Sent Events: progress
|
|
277
|
+
events while the prompt runs, then the result.
|
|
170
278
|
|
|
171
|
-
|
|
279
|
+
The api contract is versioned, and generated from the backend's Pydantic models: the component asks for the current
|
|
280
|
+
version, with `X-Smarter-Capabilities: chat-contract-v2`, and reads the previous one from older Smarter platforms.
|
|
281
|
+
|
|
282
|
+
The complete contract, with every request, response, header, cookie and event, is in
|
|
283
|
+
[The Chat API Contract](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/api-contract.html).
|
|
284
|
+
|
|
285
|
+
## Browser support
|
|
286
|
+
|
|
287
|
+
Current versions of Chrome, Edge, Firefox and Safari. The component uses `fetch` response streams, `EventSource`,
|
|
288
|
+
`localStorage` and the `inert` attribute.
|
|
289
|
+
|
|
290
|
+
## Development
|
|
291
|
+
|
|
292
|
+
```console
|
|
293
|
+
git clone https://github.com/smarter-sh/smarter-chat.git
|
|
294
|
+
cd smarter-chat
|
|
295
|
+
make init # npm install
|
|
296
|
+
make serve # Storybook at http://localhost:6006, with the Smarter api mocked
|
|
297
|
+
make test # Vitest; every story is also rendered as a test
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
No Smarter backend is needed: the stories mock the api with [MSW](https://mswjs.io/). See
|
|
301
|
+
[CONTRIBUTING.md](https://github.com/smarter-sh/smarter-chat/blob/main/.github/CONTRIBUTING.md) for the rest of the
|
|
302
|
+
workflow (every `make` target, working inside the Smarter repository, commits and releases), and the
|
|
303
|
+
[developer guide](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/development.html) for the
|
|
304
|
+
architecture.
|
|
305
|
+
|
|
306
|
+
## License
|
|
172
307
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
content creation, testing, community engagement, and stewards to help us to ensure that we comply with evolving
|
|
176
|
-
standards for the ethical use of AI.
|
|
308
|
+
[AGPL-3.0-or-later](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE), as Smarter is. Copyright © Lawrence
|
|
309
|
+
McDaniel.
|
|
177
310
|
|
|
178
|
-
|
|
311
|
+
Contributions are welcome: code, documentation, how-to videos, testing and community help. See
|
|
312
|
+
[CONTRIBUTING.md](https://github.com/smarter-sh/smarter-chat/blob/main/.github/CONTRIBUTING.md), or contact
|
|
313
|
+
[Lawrence McDaniel](https://lawrencemcdaniel.com/contact).
|