@smarter.sh/ui-chat 0.7.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/README.md CHANGED
@@ -1,178 +1,287 @@
1
- [![NPM](https://a11ybadges.com/badge?logo=npm)](https://www.npmjs.com/package/@smarter.sh/ui-chat)
2
- [![GitHub](https://a11ybadges.com/badge?logo=github)](https://github.com/smarter-sh/smarter-chat/)
3
- [![Test Status](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml)
4
- [![Coverage](https://img.shields.io/codecov/c/github/smarter-sh/smarter-chat/main?label=coverage&logo=codecov)](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
10
-
11
- Smarter Chat is the React chat component of the [Smarter](https://smarter.sh) LLMClient prompt engineering
12
- workbench. Beside the chat, its Console displays the LLMClient's configuration, and the chat session's api calls,
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.
1
+ # @smarter.sh/ui-chat
23
2
 
24
- It is also published to npm as [@smarter.sh/ui-chat](https://www.npmjs.com/package/@smarter.sh/ui-chat), so that
25
- any web page can use a Smarter LLMClient as its chat backend: a Wordpress or Squarespace site, a Salesforce portal,
26
- a Shopify storefront, a Sharepoint add-in, or your own web application.
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.
27
5
 
28
- ![Basic Usage](./doc/img/readme-usage4.png)
6
+ [![npm version](https://img.shields.io/npm/v/@smarter.sh/ui-chat?logo=npm)](https://www.npmjs.com/package/@smarter.sh/ui-chat)
7
+ [![npm downloads](https://img.shields.io/npm/dm/@smarter.sh/ui-chat)](https://www.npmjs.com/package/@smarter.sh/ui-chat)
8
+ [![Test Status](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/smarter-sh/smarter-chat/actions/workflows/test.yml)
9
+ [![Coverage](https://img.shields.io/codecov/c/github/smarter-sh/smarter-chat/main?label=coverage&logo=codecov)](https://codecov.io/gh/smarter-sh/smarter-chat)
10
+ [![TypeScript](https://img.shields.io/badge/types-included-blue?logo=typescript&logoColor=white)](#typescript)
11
+ [![React 19](https://img.shields.io/badge/react-19-61dafb?logo=react&logoColor=white)](https://react.dev)
12
+ [![License: AGPL-3.0-or-later](https://img.shields.io/npm/l/@smarter.sh/ui-chat)](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE)
13
+
14
+ ![Smarter Chat](https://cdn.smarter.sh/images/smarter-chat-ui-example.png)
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
29
61
 
30
- See the [Smarter Chat documentation](https://docs.smarter.sh/en/latest/smarter-framework/developer-reference/react-integration/smarter-chat.html).
62
+ ```console
63
+ npm install @smarter.sh/ui-chat
64
+ ```
31
65
 
32
- ## Usage
66
+ ```console
67
+ yarn add @smarter.sh/ui-chat
68
+ ```
33
69
 
34
70
  ```console
35
- npm install @smarter.sh/ui-chat
71
+ pnpm add @smarter.sh/ui-chat
36
72
  ```
37
73
 
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.
76
+
77
+ ## Quick start
78
+
38
79
  ```tsx
39
80
  import { createRoot } from "react-dom/client";
40
81
  import { SmarterChat } from "@smarter.sh/ui-chat";
41
82
  import "@smarter.sh/ui-chat/dist/ui-chat.css";
42
- // the stylesheet and fonts of math in the responses. katex is installed with @smarter.sh/ui-chat.
43
- import "katex/dist/katex.min.css";
83
+ import "katex/dist/katex.min.css"; // math in responses. katex is installed with the package.
44
84
 
45
85
  createRoot(document.getElementById("chat")!).render(
46
- <SmarterChat
47
- apiUrl="https://stackademy.3141-5926-5359.api.example.com/"
48
- cookieDomain="example.com"
49
- showConsole={false}
50
- />,
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>,
51
93
  );
52
94
  ```
53
95
 
54
- React 19 is a peer dependency.
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.
96
+ The chat fills the height of its parent element, so give the parent a height.
95
97
 
96
- ## Development
98
+ ## Requirements on the Smarter side
97
99
 
98
- This repository is self-contained: clone it, and its Makefile does the rest. The Smarter backend is optional.
100
+ The component talks directly to the Smarter platform from your visitors' browsers, so three things must be true:
99
101
 
100
- ```console
101
- git clone https://github.com/smarter-sh/smarter-chat.git
102
- cd smarter-chat
103
- make init # npm install
104
- make serve # Storybook, at http://localhost:6006
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:
107
+
108
+ ```yaml
109
+ spec:
110
+ config:
111
+ allowedOrigins:
112
+ - https://www.example.com
113
+ - http://localhost:5173
114
+ ```
115
+
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
+ }
105
167
  ```
106
168
 
107
- `make serve` browses the components in Storybook, whose stories mock the Smarter api with
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.
169
+ ### Next.js
111
170
 
112
- | Command | What it does |
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. |
171
+ The component uses browser apis (cookies, `localStorage`, `EventSource`), so render it on the client only:
172
+
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";
122
178
 
123
- ### Inside the Smarter repository
179
+ const SmarterChat = dynamic(() => import("@smarter.sh/ui-chat").then((m) => m.SmarterChat), { ssr: false });
180
+
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
+ }
192
+ ```
124
193
 
125
- Smarter's web console hosts Smarter Chat as one of the React apps in its npm workspace. `make react-install`, in the
126
- [Smarter repository](https://github.com/smarter-sh/smarter), clones this repository into
127
- `smarter/react/packages/smarter-chat`:
194
+ ### A prompt engineering workbench
128
195
 
129
- ```console
130
- git clone https://github.com/smarter-sh/smarter.git
131
- cd smarter
132
- make react-install # clones smarter-chat's main branch
133
- make react-install SMARTER_CHAT_BRANCH=alpha # or another branch
196
+ The full workbench, as in the Smarter web console: the Console, the mode toggle, and your server logs.
197
+
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
+ />
134
206
  ```
135
207
 
136
- The same `make` commands work there, in `smarter/react/packages/smarter-chat`, which is this repository's own git
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.
208
+ ## Styling
140
209
 
141
- ### Commits, versions and releases
210
+ Import the stylesheet once, anywhere in your app:
142
211
 
143
- Run `make pre-commit-init` once per clone (the Smarter repository's `make react-install` does it when its virtual
144
- environment is active). It installs two git hooks: pre-commit, which runs codespell, Prettier and
145
- ESLint, and the standard pre-commit-hooks checks, and commit-msg, which runs commitlint.
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
+ ```
146
216
 
147
- Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/), as Smarter's do, because
148
- [semantic-release](https://semantic-release.gitbook.io/) versions this package from them. On each push to `alpha`
149
- (prereleases, e.g. `1.0.0-alpha.1`) and to `main`, `.github/workflows/pushMain.yml` determines the next version, writes
150
- it to `package.json`, adds the release notes to `CHANGELOG.md`, tags the commit and creates a GitHub release. A release
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`.
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.
153
221
 
154
- semantic-release does not publish to npm. After a release on `main`, publish it with `make release`.
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.
155
225
 
156
- ### Source
226
+ ## TypeScript
157
227
 
158
- | Path | Contents |
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. |
228
+ Type declarations are included. Besides the components, the package exports:
165
229
 
166
- ## License
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. |
242
+
243
+ ## How it works
244
+
245
+ The component makes two kinds of POST requests to Smarter, with the browser's cookies:
167
246
 
168
- Smarter Chat is licensed under the GNU Affero General Public License v3.0 or later
169
- ([AGPL-3.0-or-later](./LICENSE)), as Smarter is.
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.
170
252
 
171
- ## Contributing
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.
255
+
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).
258
+
259
+ ## Browser support
260
+
261
+ Current versions of Chrome, Edge, Firefox and Safari. The component uses `fetch` response streams, `EventSource`,
262
+ `localStorage` and the `inert` attribute.
263
+
264
+ ## Development
265
+
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
+ ```
273
+
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.
279
+
280
+ ## License
172
281
 
173
- We welcome contributions! There are a variety of ways for you to get involved, regardless of your background. In
174
- addition to Pull requests, this project would benefit from contributors focused on documentation and how-to video
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.
282
+ [AGPL-3.0-or-later](https://github.com/smarter-sh/smarter-chat/blob/main/LICENSE), as Smarter is. Copyright © Lawrence
283
+ McDaniel.
177
284
 
178
- You can also contact [Lawrence McDaniel](https://lawrencemcdaniel.com/contact) directly.
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).