@smarter.sh/ui-chat 0.7.1 → 0.9.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.
Files changed (146) hide show
  1. package/README.md +353 -106
  2. package/dist/embed/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  3. package/dist/embed/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  4. package/dist/embed/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  5. package/dist/embed/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  6. package/dist/embed/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  7. package/dist/embed/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  8. package/dist/embed/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  9. package/dist/embed/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  10. package/dist/embed/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  11. package/dist/embed/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  12. package/dist/embed/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  13. package/dist/embed/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  14. package/dist/embed/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  15. package/dist/embed/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  16. package/dist/embed/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  17. package/dist/embed/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  18. package/dist/embed/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  19. package/dist/embed/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  20. package/dist/embed/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  21. package/dist/embed/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  22. package/dist/embed/mermaid/abnfDiagram-VCTEODGH-1SbERmPs.js +89 -0
  23. package/dist/embed/mermaid/arc-VicTtbbz.js +82 -0
  24. package/dist/embed/mermaid/architecture-7GRP2DOG-D0nnNZ3B.js +2 -0
  25. package/dist/embed/mermaid/architectureDiagram-5GKGNRK7-CQABdiy9.js +4138 -0
  26. package/dist/embed/mermaid/array-CApNbSU9.js +6 -0
  27. package/dist/embed/mermaid/blockDiagram-I7D4REHJ-CtjOz0Jt.js +1911 -0
  28. package/dist/embed/mermaid/c4Diagram-7LVT6UL2-_qBudB6C.js +3010 -0
  29. package/dist/embed/mermaid/channel-BXMcYHk2.js +5 -0
  30. package/dist/embed/mermaid/chunk-2E4U76K2-CBll2dEU.js +346 -0
  31. package/dist/embed/mermaid/chunk-2Q5K7J3B-kzxEEeTu.js +15 -0
  32. package/dist/embed/mermaid/chunk-4HAMMTFA-Dhz0SVnN.js +4188 -0
  33. package/dist/embed/mermaid/chunk-5VM5RSS4-Cr17nBXp.js +5 -0
  34. package/dist/embed/mermaid/chunk-75Z2AOVW-BsWtLgfj.js +1330 -0
  35. package/dist/embed/mermaid/chunk-CLGD4ZFX-Bkjwlxy9.js +14 -0
  36. package/dist/embed/mermaid/chunk-DU6HZSFF-1zIarP1Q.js +3900 -0
  37. package/dist/embed/mermaid/chunk-F27PBJKO-CiOL12VY.js +61 -0
  38. package/dist/embed/mermaid/chunk-FOHPRMQF-DS9zEyR5.js +21447 -0
  39. package/dist/embed/mermaid/chunk-GMAD6QVW-Dc0gE_3Q.js +1804 -0
  40. package/dist/embed/mermaid/chunk-GVQU2GXP-CWFtOgtb.js +37 -0
  41. package/dist/embed/mermaid/chunk-IMKFNOWR-CLyTlLwx.js +2042 -0
  42. package/dist/embed/mermaid/chunk-JWPE2WC7-Ccb0QaC8.js +8 -0
  43. package/dist/embed/mermaid/chunk-L3NEJ4N5-DnkSrVO8.js +245 -0
  44. package/dist/embed/mermaid/chunk-LNGE3PJU-ByFTjlja.js +1517 -0
  45. package/dist/embed/mermaid/chunk-OSK3NFVY-B57tZZIG.js +672 -0
  46. package/dist/embed/mermaid/chunk-P2QGCYS3-BUVAOFF-.js +67 -0
  47. package/dist/embed/mermaid/chunk-POPQ4Y6H-BsUdeJ_J.js +26 -0
  48. package/dist/embed/mermaid/chunk-PWAF6VOD-Cb-w19aO.js +275 -0
  49. package/dist/embed/mermaid/chunk-SHT3W25Y-znBBpcIu.js +4183 -0
  50. package/dist/embed/mermaid/chunk-SVP7TREG-DrHUM-6R.js +490 -0
  51. package/dist/embed/mermaid/chunk-TICWLB2K-xlGqZZYJ.js +3357 -0
  52. package/dist/embed/mermaid/chunk-TLUHSLCS-COwDpXBa.js +59 -0
  53. package/dist/embed/mermaid/chunk-XXDRQBXY-pOp8MAr9.js +9 -0
  54. package/dist/embed/mermaid/chunk-Y2CYZVJY-i11wjrBe.js +12 -0
  55. package/dist/embed/mermaid/classDiagram-ZZMXUADV-C8BeuQnA.js +30 -0
  56. package/dist/embed/mermaid/classDiagram-v2-VYDZK3BY-B3jylZLr.js +30 -0
  57. package/dist/embed/mermaid/cose-bilkent-JH36ORCC-DFvJxZ7v.js +2240 -0
  58. package/dist/embed/mermaid/cynefin-OW5HDTMX-B6YJOAMM.js +2 -0
  59. package/dist/embed/mermaid/cynefinDiagram-5FMLGOSQ-CCm5IQBE.js +355 -0
  60. package/dist/embed/mermaid/cytoscape.esm-BstmGtAB.js +18047 -0
  61. package/dist/embed/mermaid/dagre-BwzzJJA_.js +1932 -0
  62. package/dist/embed/mermaid/dagre-GXQ25YYZ-B3d3iNF-.js +423 -0
  63. package/dist/embed/mermaid/defaultLocale-N-0uLSyg.js +198 -0
  64. package/dist/embed/mermaid/diagram-S7CK7UJ4-BeA5UJrt.js +293 -0
  65. package/dist/embed/mermaid/diagram-UQ7AKVKN-DK0uHb-2.js +214 -0
  66. package/dist/embed/mermaid/diagram-VSXAHHWV-D5JXip1B.js +432 -0
  67. package/dist/embed/mermaid/diagram-VX7I27RA-B1VysvG9.js +527 -0
  68. package/dist/embed/mermaid/diagram-Z3DM3KII-ZGUJaFq-.js +134 -0
  69. package/dist/embed/mermaid/dist-DRRwZ4Yi.js +59 -0
  70. package/dist/embed/mermaid/ebnfDiagram-PWID7BFC-BOahZhWx.js +100 -0
  71. package/dist/embed/mermaid/erDiagram-RLTQ6QDP-7cGpGRQo.js +1966 -0
  72. package/dist/embed/mermaid/eventmodeling-NTZA5JFV-C3kU50Cz.js +2 -0
  73. package/dist/embed/mermaid/flowDiagram-HODETNUW-D-eJN2AO.js +16 -0
  74. package/dist/embed/mermaid/ganttDiagram-EL5Y4UJY-s6Kx4KlU.js +3072 -0
  75. package/dist/embed/mermaid/gitGraph-4MIJSDKK-CqdlGRFk.js +2 -0
  76. package/dist/embed/mermaid/gitGraphDiagram-WWUBYQGX-Blwdy0b7.js +733 -0
  77. package/dist/embed/mermaid/graphlib-XW-Jr8pF.js +1267 -0
  78. package/dist/embed/mermaid/info-A6RAGUB7-2pwra5F3.js +2 -0
  79. package/dist/embed/mermaid/infoDiagram-27XIBGKW-CstzbQPb.js +20 -0
  80. package/dist/embed/mermaid/init-CsQUQz36.js +13 -0
  81. package/dist/embed/mermaid/ishikawaDiagram-5VMMS53U-C6y_w0kd.js +717 -0
  82. package/dist/embed/mermaid/journeyDiagram-3NMN7TZE-BHVux_z1.js +884 -0
  83. package/dist/embed/mermaid/kanban-definition-UXKFOSKX-Cgj-7IHi.js +976 -0
  84. package/dist/embed/mermaid/katex-DmPOayaq.js +21968 -0
  85. package/dist/embed/mermaid/line-brkWVSn0.js +34 -0
  86. package/dist/embed/mermaid/linear-CiZWLcTr.js +287 -0
  87. package/dist/embed/mermaid/mermaid-parser.core-BjLg_By9.js +632 -0
  88. package/dist/embed/mermaid/mermaid.js +1092 -0
  89. package/dist/embed/mermaid/mindmap-definition-YA3MSWOX-DRc-FzI_.js +1006 -0
  90. package/dist/embed/mermaid/ordinal-BubEveRk.js +65 -0
  91. package/dist/embed/mermaid/packet-AYTQ26CC-C3h9OoFk.js +2 -0
  92. package/dist/embed/mermaid/path-CnWkkRiY.js +84 -0
  93. package/dist/embed/mermaid/pegDiagram-XKGWAZYB-Cw-aYwaF.js +94 -0
  94. package/dist/embed/mermaid/pie-WAS4IAKB-CaECYpHT.js +2 -0
  95. package/dist/embed/mermaid/pieDiagram-E7YTZNPT-DoguGyzq.js +203 -0
  96. package/dist/embed/mermaid/quadrantDiagram-AXDQQJYC-Cu4dMFZL.js +2001 -0
  97. package/dist/embed/mermaid/radar-RG4KPBEZ-CoS7pnd_.js +2 -0
  98. package/dist/embed/mermaid/railroad-74A4TZTK-BjHa6MAk.js +2 -0
  99. package/dist/embed/mermaid/railroad-abnf-HS5TGJTU-Bm2YWqjG.js +2 -0
  100. package/dist/embed/mermaid/railroad-ebnf-LZEXJU2U-C7mPpgM3.js +2 -0
  101. package/dist/embed/mermaid/railroad-peg-WCYAUIDC-Cyp07M5x.js +2 -0
  102. package/dist/embed/mermaid/railroadDiagram-O6MQD6OU-DDX-9GRQ.js +76 -0
  103. package/dist/embed/mermaid/requirementDiagram-BXWQKSXE-z8PPo06M.js +2224 -0
  104. package/dist/embed/mermaid/rough.esm-DXYGHN3m.js +1361 -0
  105. package/dist/embed/mermaid/sankeyDiagram-P5KCCOFB-CeD0II3M.js +972 -0
  106. package/dist/embed/mermaid/sequenceDiagram-WJ2MYXX4-Cs-Wxyvw.js +4156 -0
  107. package/dist/embed/mermaid/sizeCapture-INFHLROL-DujrpAYz.js +46 -0
  108. package/dist/embed/mermaid/src-DbyMbLVK.js +2141 -0
  109. package/dist/embed/mermaid/stateDiagram-D77RDMKH-CqWtgHSc.js +220 -0
  110. package/dist/embed/mermaid/stateDiagram-v2-MP3YSRHH-CPideWIU.js +30 -0
  111. package/dist/embed/mermaid/swimlanes-42K2YHIH-MutR4uV4.js +4957 -0
  112. package/dist/embed/mermaid/swimlanesDiagram-VR7AAH4N-BC_o7pti.js +31 -0
  113. package/dist/embed/mermaid/timeline-definition-24CTP7MA-rZfNRFiT.js +1069 -0
  114. package/dist/embed/mermaid/treeView-Q6P3EWNA-C94eS7gV.js +2 -0
  115. package/dist/embed/mermaid/treemap-WGGIJYW6-DnrVJ1h3.js +2 -0
  116. package/dist/embed/mermaid/vennDiagram-4TSXK5OY-KwMHebDQ.js +1880 -0
  117. package/dist/embed/mermaid/wardley-WFR3VGLG-DRDACyIN.js +2 -0
  118. package/dist/embed/mermaid/wardleyDiagram-VM6X3IG4-C-Fm7GGB.js +645 -0
  119. package/dist/embed/mermaid/xychartDiagram-S5SC5T6Z-DZX43ay9.js +2210 -0
  120. package/dist/embed.js +903 -0
  121. package/dist/embed.js.map +1 -0
  122. package/dist/smarter-chat-library.es.js +3048 -2808
  123. package/dist/smarter-chat-library.es.js.map +1 -1
  124. package/dist/smarter-chat-library.umd.js +56 -56
  125. package/dist/smarter-chat-library.umd.js.map +1 -1
  126. package/dist/types/src/components/DocsDialog/Component.d.ts +8 -0
  127. package/dist/types/src/components/DocsDialog/data.d.ts +18 -0
  128. package/dist/types/src/components/DocsDialog/index.d.ts +2 -0
  129. package/dist/types/src/components/SmarterChat/Component.d.ts +7 -3
  130. package/dist/types/src/components/SmarterChat/icons.d.ts +2 -0
  131. package/dist/types/src/contract.gen.d.ts +56 -0
  132. package/dist/types/src/embed/EmbedApp.d.ts +10 -0
  133. package/dist/types/src/embed/assets.d.ts +7 -0
  134. package/dist/types/src/embed/autoMount.d.ts +18 -0
  135. package/dist/types/src/embed/css.d.ts +15 -0
  136. package/dist/types/src/embed/element.d.ts +19 -0
  137. package/dist/types/src/embed/index.d.ts +17 -0
  138. package/dist/types/src/embed/mermaid.d.ts +2 -0
  139. package/dist/types/src/embed/mermaidImport.d.ts +1 -0
  140. package/dist/types/src/embed/options.d.ts +69 -0
  141. package/dist/types/src/lib/cookie.d.ts +4 -3
  142. package/dist/types/src/lib/mermaidImport.d.ts +8 -0
  143. package/dist/types/src/lib/styles.d.ts +40 -0
  144. package/dist/types/src/types.d.ts +7 -0
  145. package/dist/ui-chat.css +1 -1
  146. package/package.json +10 -4
package/README.md CHANGED
@@ -1,61 +1,129 @@
1
1
  # @smarter.sh/ui-chat
2
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.
3
+ > The official chat UI for [Smarter](https://smarter.sh) LLMClients. Drop it into any website, whether React, Next.js,
4
+ > WordPress, Django, Flask, Node.js or plain HTML, and it gets its behavior and its look from the LLMClient's YAML
5
+ > manifest.
5
6
 
7
+ [![GitHub](https://img.shields.io/badge/github-smarter--sh%2Fsmarter--chat-181717?logo=github)](https://github.com/smarter-sh/smarter-chat)
6
8
  [![npm version](https://img.shields.io/npm/v/@smarter.sh/ui-chat?logo=npm)](https://www.npmjs.com/package/@smarter.sh/ui-chat)
7
9
  [![npm downloads](https://img.shields.io/npm/dm/@smarter.sh/ui-chat)](https://www.npmjs.com/package/@smarter.sh/ui-chat)
8
10
  [![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)
11
+ [![Docs](https://img.shields.io/badge/Read%20the%20Docs-smarter.sh-blue?logo=readthedocs)](https://docs.smarter.sh/smarter-framework/smarter-chat.html)
12
+ [![Coverage](https://img.shields.io/codecov/c/github/smarter-sh/smarter-chat/main?label=coverage&logo=codecov)](https://app.codecov.io/gh/smarter-sh/smarter-chat)
10
13
  [![TypeScript](https://img.shields.io/badge/types-included-blue?logo=typescript&logoColor=white)](#typescript)
11
14
  [![React 19](https://img.shields.io/badge/react-19-61dafb?logo=react&logoColor=white)](https://react.dev)
12
15
  [![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
16
 
14
17
  ![Smarter Chat](https://cdn.smarter.sh/images/smarter-chat-ui-example.png)
15
18
 
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
+ Smarter Chat is the chat window of the Smarter web console's prompt engineering workbench, published on npm so you can
20
+ put the same chat on your own website: a marketing site, a customer portal, a storefront, an intranet or an application.
21
+ You build and run the chatbot on Smarter, and this package displays it on your pages. The complete guide is at
22
+ [docs.smarter.sh](https://docs.smarter.sh/smarter-framework/smarter-chat.html).
19
23
 
20
- **[Documentation](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat.html)** ·
24
+ **[Documentation](https://docs.smarter.sh/smarter-framework/smarter-chat.html)** ·
21
25
  **[Storybook](#development)** · **[Changelog](https://github.com/smarter-sh/smarter-chat/blob/main/CHANGELOG.md)** ·
22
26
  **[Issues](https://github.com/smarter-sh/smarter-chat/issues)**
23
27
 
24
28
  ## Contents
25
29
 
30
+ - [How it works](#how-it-works)
26
31
  - [Features](#features)
27
32
  - [Installation](#installation)
28
- - [Quick start](#quick-start)
33
+ - [Quick start (React)](#quick-start-react)
34
+ - [Embedding in any website](#embedding-in-any-website)
29
35
  - [Requirements on the Smarter side](#requirements-on-the-smarter-side)
36
+ - [Behavior: `spec.config.prompt`](#behavior-specconfigprompt)
37
+ - [Styling: `spec.config.styles`](#styling-specconfigstyles)
30
38
  - [Props](#props)
31
- - [Examples](#examples)
32
- - [Styling](#styling)
39
+ - [More examples](#more-examples)
33
40
  - [TypeScript](#typescript)
34
- - [How it works](#how-it-works)
41
+ - [The api contract](#the-api-contract)
35
42
  - [Browser support](#browser-support)
36
43
  - [Development](#development)
37
44
  - [License](#license)
38
45
 
46
+ ## How it works
47
+
48
+ Smarter Chat isn't a general-purpose chat UI. It works only with a Smarter
49
+ [LLMClient](https://docs.smarter.sh/smarter-resources/smarter-llmclient.html), which is a chatbot that you declare in a
50
+ YAML manifest and apply to a Smarter platform with the `smarter` CLI or the REST API. The platform runs the
51
+ chatbot, and this component is its front end. It can't call OpenAI, Anthropic or any other LLM provider directly.
52
+
53
+ The `SmarterChat` component has a single required prop, `apiUrl`, which is the url of a deployed LLMClient. Everything
54
+ else comes from the LLMClient's manifest, so you change the chat by applying a new manifest, not by redeploying your
55
+ website:
56
+
57
+ | You want to change | Where it's set |
58
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
59
+ | What the chatbot says and does: its LLM, model, system prompt, name, welcome message and examples | The manifest's [`spec.config.prompt`](#behavior-specconfigprompt) |
60
+ | Its tools and safety: [Plugins](https://docs.smarter.sh/smarter-resources/smarter-plugin.html), Functions, [Guardrails](https://docs.smarter.sh/smarter-resources/smarter-guardrail.html) | The manifest's `spec.plugins`, `spec.functions` and `spec.guardrails` |
61
+ | How it looks: its logo, avatars, background image, font and colors | The manifest's [`spec.config.styles`](#styling-specconfigstyles) |
62
+ | Where it appears on your page and its size, plus any extra CSS | Your page: the component's [props](#props) and your [stylesheet](#your-own-css) |
63
+ | The data exchanged between browser and server | [The api contract](#the-api-contract), generated from Smarter's Pydantic models. You don't change it yourself |
64
+
65
+ ```yaml
66
+ apiVersion: smarter.sh/v1
67
+ kind: LLMClient
68
+ metadata:
69
+ name: support
70
+ description: Customer support for example.com
71
+ version: 1.0.0
72
+ spec:
73
+ config:
74
+ prompt: # behavior: what the chatbot is and does
75
+ deployed: true
76
+ provider: openai
77
+ defaultModel: gpt-4o-mini
78
+ defaultSystemRole: You are a friendly support agent for example.com. Answer briefly.
79
+ appName: Example Support
80
+ appAssistant: Sam
81
+ appWelcomeMessage: Hi, I'm Sam. How can I help?
82
+ appExamplePrompts:
83
+ - How do I reset my password?
84
+ - What is your return policy?
85
+ appPlaceholder: Ask me anything...
86
+ allowedOrigins:
87
+ - https://www.example.com
88
+ styles: # look: how the chat is displayed, on every page that embeds it
89
+ appLogoUrl: https://cdn.example.com/logo.png
90
+ googleFont: Nunito
91
+ conversationHeader: { backgroundColor: "#14213d", color: "#ffffff" }
92
+ outgoingMessage: { backgroundColor: "#fca311", color: "#14213d" }
93
+ plugins:
94
+ - order-status
95
+ ```
96
+
97
+ ```tsx
98
+ <SmarterChat apiUrl="https://support.3141-5926-5359.api.example.com/" showConsole={false} />
99
+ ```
100
+
39
101
  ## Features
40
102
 
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.
103
+ - **Configured by its manifest.** You give it the url of a deployed LLMClient, and it loads the LLMClient's name,
104
+ welcome message, example prompts, placeholder and styles from Smarter.
105
+ - **Embed it anywhere.** You can use it as a React component, or build it once into a small script that WordPress,
106
+ Django, Flask, Express or a plain HTML page includes.
107
+ - **Themeable without CSS.** The logo, avatars, background image, Google font, font size, corner radius and the colors
108
+ of every part of the chat are set in the manifest and validated by Smarter.
43
109
  - **Persistent chat sessions.** The conversation survives page reloads, and each LLMClient on a site keeps its own
44
110
  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
111
+ - **Live progress.** While a prompt runs, the chat shows each LLM request and each tool, Plugin and MCP server call,
112
+ streamed as Server-Sent Events.
113
+ - **Rich responses.** It renders GitHub flavored markdown (tables, lists, block quotes, images, links),
114
+ syntax-highlighted code blocks with a copy button, LaTeX math typeset by [KaTeX](https://katex.org), and
49
115
  [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
116
+ - **Safe by default.** Raw HTML is displayed as text. Links and images are restricted to `http(s)`, relative and
117
+ raster `data:` urls. The rendered HTML and Mermaid's SVG are sanitized with
52
118
  [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
119
+ - **Lightweight where it counts.** React is a peer dependency. Mermaid is loaded only when a message first has a
54
120
  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.
121
+ - **Optional developer Console.** As in the Smarter workbench, a resizable side panel can show the LLMClient's
122
+ configuration, the session's api calls, tool calls and Plugin usage, and a live server log stream.
123
+ - **Accessible.** It has labeled regions and controls, keyboard-resizable panels, and MathML for screen readers.
124
+ - **Typed.** It's written in TypeScript, and its types are generated from Smarter's api contract.
125
+
126
+ See [Features](https://docs.smarter.sh/smarter-framework/smarter-chat/features.html) for details.
59
127
 
60
128
  ## Installation
61
129
 
@@ -72,9 +140,10 @@ pnpm add @smarter.sh/ui-chat
72
140
  ```
73
141
 
74
142
  `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.
143
+ used with a bundler such as Vite, webpack, Rollup or Next.js. If your site isn't built with React, see
144
+ [Embedding in any website](#embedding-in-any-website).
76
145
 
77
- ## Quick start
146
+ ## Quick start (React)
78
147
 
79
148
  ```tsx
80
149
  import { createRoot } from "react-dom/client";
@@ -93,60 +162,242 @@ createRoot(document.getElementById("chat")!).render(
93
162
  );
94
163
  ```
95
164
 
96
- The chat fills the height of its parent element, so give the parent a height.
165
+ The chat fills the height of its parent element, so give the parent a height. Before it can connect, the LLMClient
166
+ must be deployed and must allow your page's origin. See
167
+ [Requirements on the Smarter side](#requirements-on-the-smarter-side).
168
+
169
+ ## Embedding in any website
170
+
171
+ If your site isn't built with React, such as a WordPress, Drupal, Shopify, Squarespace or SharePoint site, a
172
+ documentation site, or a server-rendered or plain HTML page, add the **embed script**. It's one prebuilt file,
173
+ `dist/embed.js`, that includes React and Smarter Chat, so your page needs nothing else, and it renders the chat in a
174
+ [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM), so your site's theme
175
+ can't break it, and it can't change your site.
176
+
177
+ ```html
178
+ <script
179
+ src="https://cdn.jsdelivr.net/npm/@smarter.sh/ui-chat@0/dist/embed.js"
180
+ data-chatbot="https://support.3141-5926-5359.api.example.com/"
181
+ async
182
+ ></script>
183
+ ```
184
+
185
+ That adds a chat button to the bottom right corner of every page that has the tag. The button opens the chat, which
186
+ loads only then, and the conversation follows the visitor from page to page. To put the chat in the page instead, use
187
+ the `<smarter-chat>` element, wherever the script is loaded:
188
+
189
+ ```html
190
+ <smarter-chat chatbot="https://support.3141-5926-5359.api.example.com/" height="600px"></smarter-chat>
191
+ ```
192
+
193
+ ### Options
194
+
195
+ The element's attributes, the script tag's `data-` attributes and the properties of `window.SmarterChatConfig` (in
196
+ camelCase, e.g. `apiKey`) are the same options. Only `chatbot` is required.
197
+
198
+ | Option | Default | Description |
199
+ | --------------------- | --------------------- | ------------------------------------------------------------------------------------- |
200
+ | `chatbot` | (required) | The deployed LLMClient's url. |
201
+ | `api-key` | | A Smarter api key, for LLMClients that require one. It's public in the page. |
202
+ | `mode` | `launcher` / `inline` | `launcher` (the script tag's default) or `inline` (the element's default). |
203
+ | `position` | `bottom-right` | The launcher's corner: `bottom-right` or `bottom-left`. |
204
+ | `open` | `false` | Start with the launcher open. |
205
+ | `label` | `Chat` | The launcher's accessible name. |
206
+ | `color` | `#ff5733` | The launcher button's color. |
207
+ | `width`, `height` | `400px`, `600px` | The launcher's panel, or the inline chat (`100%`, `600px`). Any css length. |
208
+ | `z-index` | `2147483000` | The launcher's stacking order. |
209
+ | `session-cookie-name` | one per chatbot host | The cookie that keeps the chat session. |
210
+ | `cookie-path` | `/` | The session cookie's path. `/` keeps one conversation across the whole site. |
211
+ | `stream-progress` | `true` | Show a running prompt's steps, e.g. its tool calls. |
212
+ | `debug` | `false` | Log to the browser console. |
213
+ | `target` | | Script tag and `SmarterChatConfig` only: a css selector to render the chat inline in. |
214
+
215
+ Where you can't set a script tag's attributes, as in Google Tag Manager, set `window.SmarterChatConfig` (an object, or
216
+ an array of them) before the script runs:
217
+
218
+ ```html
219
+ <script>
220
+ window.SmarterChatConfig = { chatbot: "https://support.3141-5926-5359.api.example.com/", position: "bottom-left" };
221
+ </script>
222
+ <script src="https://cdn.jsdelivr.net/npm/@smarter.sh/ui-chat@0/dist/embed.js" async></script>
223
+ ```
224
+
225
+ Your own buttons can open the launcher with `SmarterChat.open()`, `SmarterChat.close()` and `SmarterChat.toggle()`,
226
+ and the element dispatches a `smarter-chat-toggle` event, with `event.detail.open`, when it opens or closes. Style the
227
+ launcher from your css with `smarter-chat::part(launcher)`, `::part(panel)` and `::part(chat)`.
228
+
229
+ ### Hosting the script yourself
230
+
231
+ `embed.js` loads its other files from an `embed/` directory beside it: Mermaid, which is downloaded only when a
232
+ message has a diagram, and KaTeX's fonts, only when one has math. To serve it from your own site, copy `dist/embed.js`
233
+ and `dist/embed/` together, e.g. from `npm pack @smarter.sh/ui-chat`. Pin a version (`@0.9.0`) on a CDN url if you want
234
+ to review changes before your visitors see them; `@0` follows the latest 0.x release.
235
+
236
+ ### Platforms
237
+
238
+ Plugins that write the tag for you, with a settings screen:
239
+ [WordPress](https://github.com/smarter-sh/smarter-wordpress), [Drupal](https://github.com/smarter-sh/smarter-drupal),
240
+ [Shopify](https://github.com/smarter-sh/smarter-shopify),
241
+ [Google Tag Manager](https://github.com/smarter-sh/smarter-gtm-template), and Docusaurus, MkDocs, Sphinx and VitePress
242
+ ([smarter-docs-site-generators](https://github.com/smarter-sh/smarter-docs-site-generators)). Every other platform that
243
+ lets you add a script to its pages needs only the tag above. See
244
+ [Embedding Smarter Chat](https://docs.smarter.sh/smarter-framework/smarter-chat/embedding.html).
97
245
 
98
246
  ## Requirements on the Smarter side
99
247
 
100
- The component talks directly to the Smarter platform from your visitors' browsers, so three things must be true:
248
+ The component calls the Smarter platform directly from your visitors' browsers, so three things must be true:
101
249
 
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:
250
+ 1. **The LLMClient is deployed** (`spec.config.prompt.deployed: true`). `apiUrl` is its url, for example
251
+ `https://<name>.<account-number>.api.<your-smarter-domain>/`, or its verified
252
+ [custom domain](https://docs.smarter.sh/smarter-resources/smarter-custom-domain.html). The chat calls only
253
+ that host.
254
+ 2. **Your page's origin is allowed.** Requests from your page are cross-origin and include credentials, so list your
255
+ site's origins in the LLMClient's manifest and apply it:
107
256
 
108
257
  ```yaml
109
258
  spec:
110
259
  config:
111
- allowedOrigins:
112
- - https://www.example.com
113
- - http://localhost:5173
260
+ prompt:
261
+ allowedOrigins:
262
+ - https://www.example.com
263
+ - http://localhost:5173
114
264
  ```
115
265
 
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.
266
+ 3. **The browser can authenticate, if the LLMClient requires it.** A deployed LLMClient without api keys is public.
267
+ Pass no `apiKey`, and every prompt is charged to the LLMClient's owner. If the LLMClient has an api key, pass a
268
+ [Smarter api key](https://docs.smarter.sh/smarter-resources/smarter-authtoken.html) as `apiKey`, which is sent as `Authorization: Token <apiKey>`. Anyone who can view your page can
269
+ read it, so create a key just for that page.
270
+
271
+ The page receives only the LLMClient's public configuration (its name, welcome message, example prompts, model,
272
+ system prompt and styles). It never receives, for example, its owner's profile or the session's diagnostic history.
273
+
274
+ For details and troubleshooting, see
275
+ [Embedding Smarter Chat](https://docs.smarter.sh/smarter-framework/smarter-chat/embedding.html).
276
+
277
+ ## Behavior: `spec.config.prompt`
278
+
279
+ You configure the chatbot's behavior in its manifest, not in this package. The section is validated on the platform by
280
+ the Pydantic model
281
+ [`SAMLLMClientSpecConfigPrompt`](https://docs.smarter.sh/smarter-resources/llmclient/sam.html)
282
+ (`smarter.apps.llmclient.manifest.models.llmclient.spec`). The settings fall into three groups: what Smarter sends to the
283
+ LLM, what the chat displays, and who may use it.
284
+
285
+ | Setting | Effect in the chat |
286
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
287
+ | `provider`, `defaultModel` | The LLM that answers. They're also shown under the name in the header, as in "openai gpt-4o-mini with 2 additional plugins". |
288
+ | `defaultSystemRole` | The system prompt that starts every new session. It's visible in sandbox mode (`toggleMetadata`). |
289
+ | `defaultTemperature`, `defaultMaxTokens` | Sent to the LLM with each prompt. |
290
+ | `appName` | The title in the header, followed by the manifest's `metadata.version`. |
291
+ | `appAssistant` | The sender name on the assistant's messages. The default is "Assistant". |
292
+ | `appWelcomeMessage` | The first assistant message of a new session. |
293
+ | `appExamplePrompts` | A second assistant message that lists them: "Some example prompts to get you started". |
294
+ | `appPlaceholder` | The hint in the empty message box. |
295
+ | `appFileAttachment` | Shows the attach button in the message box. |
296
+ | `deployed`, `subdomain`, `customDomain` | Whether the LLMClient has a public url, and what that url is, which you pass as `apiUrl`. |
297
+ | `allowedOrigins` | The websites that may embed the chat. |
298
+
299
+ The chatbot's tools are set beside `config`: `spec.plugins`, `spec.functions` and `spec.guardrails` are run by the
300
+ platform. The chat displays their calls as progress while a prompt runs.
301
+
302
+ Apply a changed manifest with `smarter apply -f llmclient.yaml`. A new chat session picks up the change without any
303
+ change to your website.
304
+
305
+ ## Styling: `spec.config.styles`
306
+
307
+ ### The LLMClient's styles
308
+
309
+ The chat takes its look from the LLMClient's manifest, so most pages need no CSS of their own. `spec.config.styles` is
310
+ validated on the platform by the Pydantic model
311
+ [`SAMLLMClientSpecConfigStyles`](https://docs.smarter.sh/smarter-resources/llmclient/sam.html)
312
+ (`smarter.apps.llmclient.manifest.models.llmclient.styles`). Every setting is optional, and a setting that is left out
313
+ keeps the default. Colors, lengths and font names must be plain CSS values, and images must be `https` urls that
314
+ Smarter can fetch when the manifest is applied.
315
+
316
+ ```yaml
317
+ spec:
318
+ config:
319
+ styles:
320
+ # images
321
+ appLogoUrl: https://cdn.example.com/logo.png # in a circle at the left of the header
322
+ assistantAvatarUrl: https://cdn.example.com/assistant.png
323
+ userAvatarUrl: https://cdn.example.com/user.png
324
+ appBackgroundImageUrl: https://cdn.example.com/background.jpg
325
+ appBackgroundImageSize: cover # cover | contain | auto
326
+ # typography and shape
327
+ googleFont: Nunito # downloaded from fonts.google.com
328
+ fontFamily: '"Nunito", system-ui, sans-serif' # overrides googleFont's stack
329
+ fontSize: 16px
330
+ borderRadius: 0.7em
331
+ # colors, one section per part of the chat
332
+ mainContainer: { backgroundColor: "#ffffff", color: "#212121", borderColor: "#d1dbe3" }
333
+ conversationHeader: { backgroundColor: "#14213d", color: "#ffffff", infoColor: "#c0c4e0", borderColor: "#14213d" }
334
+ messageList: { backgroundColor: "rgba(255, 255, 255, 0.6)", color: "#212121" } # tints the background image
335
+ incomingMessage: { backgroundColor: "#e5e5e5", color: "#14213d", borderColor: "#d1dbe3", linkColor: "#0b57d0" }
336
+ outgoingMessage: { backgroundColor: "#fca311", color: "#14213d", linkColor: "#14213d" }
337
+ messageInput:
338
+ backgroundColor: "#ffffff"
339
+ editorBackgroundColor: "#f6fbff"
340
+ color: "#212121"
341
+ placeholderColor: "#9e9e9e"
342
+ borderColor: "#d1dbe3"
343
+ buttons: { color: "#fca311" }
344
+ typingIndicator: { color: "#fca311" }
345
+ ```
346
+
347
+ The sections correspond to the [chatscope](https://github.com/chatscope/chat-ui-kit-react) components that the chat is
348
+ built on: `MainContainer`, `ConversationHeader`, `MessageList`, `Message`, `MessageInput`, `Button` and
349
+ `TypingIndicator`. The same styles apply in the Smarter workbench and on every page that embeds the LLMClient.
350
+
351
+ The chat sets the styles as CSS custom properties on its root `.SmarterChat` element, such as
352
+ `--smarter-chat-header-bg` and `--smarter-chat-outgoing-bg`. Their fallbacks are chatscope's own colors. See
353
+ [Styling Your LLMClient's Chat](https://docs.smarter.sh/smarter-resources/llmclient/styles.html) for every
354
+ setting.
355
+
356
+ ### Your own CSS
357
+
358
+ Import the stylesheets once, anywhere in your app:
359
+
360
+ ```ts
361
+ import "@smarter.sh/ui-chat/dist/ui-chat.css"; // or "@smarter.sh/ui-chat/style.css"
362
+ import "katex/dist/katex.min.css";
363
+ ```
120
364
 
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.
365
+ - **`ui-chat.css`** is the component's own CSS, including chatscope's chat styles.
366
+ - **`katex/dist/katex.min.css`** styles math in responses. It's kept out of `ui-chat.css` so that pages without math
367
+ don't download KaTeX's fonts. Without it, each equation is displayed twice, once as text and once as unstyled
368
+ MathML.
123
369
 
124
- See [Embedding Smarter Chat](https://docs.smarter.sh/en/latest/smarter-framework/smarter-chat/embedding.html) for
125
- details, including troubleshooting.
370
+ The component's elements have stable class names prefixed `smarter-chat-` (for example `.smarter-chat-message-list`,
371
+ `.smarter-chat-code`, `.smarter-chat-image`), under a root `.SmarterChat` element. Your stylesheet can override them,
372
+ or set the `--smarter-chat-*` properties, for anything the manifest doesn't cover. If a setting is in the manifest,
373
+ prefer setting it there, so that it applies everywhere the LLMClient is embedded.
126
374
 
127
375
  ## Props
128
376
 
129
377
  Only `apiUrl` is required.
130
378
 
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
379
+ | Prop | Type | Default | Description |
380
+ | ------------------------- | ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
381
+ | `apiUrl` | `string` | (required) | The LLMClient's api url. The chat appends `config/` to it for its configuration. |
382
+ | `apiKey` | `string \| null` | `null` | A Smarter api key, sent as `Authorization: Token <apiKey>`, for LLMClients that require authentication. |
383
+ | `showConsole` | `boolean` | `true` | Show the developer Console beside the chat. It needs a wide container; set it to `false` for end-user pages. |
384
+ | `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. |
385
+ | `streamProgress` | `boolean` | `true` | Display a running prompt's progress, which the prompt api streams as Server-Sent Events. |
386
+ | `debugMode` | `boolean` | `false` | Log to the browser console. |
387
+ | `cookieDomain` | `string` | `""` | The domain whose cookies the chat reads. Empty means the page's own domain. |
388
+ | `sessionCookieName` | `string` | `"session_key"` | The cookie in which the chat saves its session's key, for the page's path. |
389
+ | `sessionCookieExpiration` | `number` | one day | The session cookie's lifetime, in milliseconds. |
390
+ | `csrfCookieName` | `string` | `"csrftoken"` | The name of Django's CSRF cookie, whose value is sent as the `X-CSRFToken` header. |
391
+ | `csrftoken` | `string \| null` | `null` | The CSRF token, when the page cannot read the CSRF cookie. |
392
+ | `debugCookieName` | `string` | `"debug"` | The cookie in which the chat saves the LLMClient's debug mode. |
393
+ | `debugCookieExpiration` | `number` | one day | The debug cookie's lifetime, in milliseconds. |
394
+ | `smarterRequestId` | `string` | `""` | A unique id of the page request, sent as the `X-Smarter-RequestId` header, for tracing. |
395
+ | `logStreamUrl` | `string \| null` | `null` | The url of a server log stream (Server-Sent Events), for the Console's Server Logs tab. |
396
+
397
+ The props control where and how the chat runs on your page. Its content and look come from the manifest, so there is
398
+ no prop for the welcome message, the colors or the model.
399
+
400
+ ## More examples
150
401
 
151
402
  ### A chat widget in a corner of the page
152
403
 
@@ -193,7 +444,7 @@ export default function Chat() {
193
444
 
194
445
  ### A prompt engineering workbench
195
446
 
196
- The full workbench, as in the Smarter web console: the Console, the mode toggle, and your server logs.
447
+ This is the full workbench, as in the Smarter web console, with the Console, the mode toggle and your server logs:
197
448
 
198
449
  ```tsx
199
450
  <SmarterChat
@@ -205,61 +456,56 @@ The full workbench, as in the Smarter web console: the Console, the mode toggle,
205
456
  />
206
457
  ```
207
458
 
208
- ## Styling
209
-
210
- Import the stylesheet once, anywhere in your app:
211
-
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
- ```
216
-
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.
221
-
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.
225
-
226
459
  ## TypeScript
227
460
 
228
461
  Type declarations are included. Besides the components, the package exports:
229
462
 
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
463
+ | Export | What it is |
464
+ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
465
+ | `SmarterChat` | The chat component. |
466
+ | `Console` | The developer Console, on its own. |
467
+ | `SmarterChatProps` | The chat's props. |
468
+ | `ChatConfig`, `LLMClientConfig`, `ChatHistory`, `ChatMetaData` | The LLMClient configuration that the Smarter config api returns. |
469
+ | `Contract` | Every type of the api contract, generated from its JSON Schema. |
470
+ | `normalizeConfig`, `CHAT_CONTRACT_V2_CAPABILITY` | Converts an older platform's configuration to the current version. |
471
+ | `ApiMessage`, `ChatMessage` | A message as the api sends it, and as the chat thread holds it. |
472
+ | `PromptProgressEvent` | A step of a running prompt, as the prompt api streams it. |
473
+ | `MessageDirectionEnum`, `SenderRoleEnum`, `ValidMessageRolesEnum`, `MenuItems` | Message directions and roles, and the Console's tabs. |
474
+ | `version` | The package's version. |
475
+
476
+ ## The api contract
477
+
478
+ The component and the Smarter platform share a single, versioned api contract. The contract is defined by Pydantic
479
+ models in the Smarter backend, in
480
+ [`smarter.apps.prompt.contract`](https://docs.smarter.sh/smarter-framework/smarter-chat/technical-reference/contract.html):
481
+
482
+ 1. The platform builds its responses from those models.
483
+ 2. `manage.py export_chat_contract_schema` exports the models as a JSON Schema, `chat-contract.schema.json`.
484
+ 3. This package keeps a copy of the schema in `contract/`, generates its TypeScript types from it (`src/contract.gen.ts`,
485
+ exported as `Contract`), and validates its test fixtures against it.
486
+
487
+ A change to the backend's models therefore reaches the component's types, and a test on each side fails if its copy of
488
+ the schema is out of date. This is why the component works only with a Smarter backend.
244
489
 
245
490
  The component makes two kinds of POST requests to Smarter, with the browser's cookies:
246
491
 
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.
492
+ 1. **`<apiUrl>config/`** returns the LLMClient's public configuration, including its `spec.config.prompt` settings and
493
+ its `styles`, plus the chat session's history, which restores the thread when the page reloads. A new session's key
494
+ is saved in a cookie.
249
495
  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
496
+ message, and returns the messages to add to it. With `streamProgress`, it responds with Server-Sent Events: progress
251
497
  events while the prompt runs, then the result.
252
498
 
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.
499
+ The component asks for version 2 of the contract with the `X-Smarter-Capabilities: chat-contract-v2` header. It also
500
+ reads version 1 from older Smarter platforms, and converts it with `normalizeConfig`.
255
501
 
256
502
  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).
503
+ [The Chat API Contract](https://docs.smarter.sh/smarter-framework/smarter-chat/api-contract.html).
258
504
 
259
505
  ## Browser support
260
506
 
261
- Current versions of Chrome, Edge, Firefox and Safari. The component uses `fetch` response streams, `EventSource`,
262
- `localStorage` and the `inert` attribute.
507
+ Smarter Chat supports current versions of Chrome, Edge, Firefox and Safari. It uses `fetch` response streams,
508
+ `EventSource`, `localStorage` and the `inert` attribute.
263
509
 
264
510
  ## Development
265
511
 
@@ -271,10 +517,11 @@ make serve # Storybook at http://localhost:6006, with the Smarter api mocked
271
517
  make test # Vitest; every story is also rendered as a test
272
518
  ```
273
519
 
274
- No Smarter backend is needed: the stories mock the api with [MSW](https://mswjs.io/). See
520
+ You don't need a Smarter backend: the stories mock the api with [MSW](https://mswjs.io/), using fixtures that are
521
+ validated against the contract's schema. See
275
522
  [CONTRIBUTING.md](https://github.com/smarter-sh/smarter-chat/blob/main/.github/CONTRIBUTING.md) for the rest of the
276
523
  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
524
+ [developer guide](https://docs.smarter.sh/smarter-framework/smarter-chat/development.html) for the
278
525
  architecture.
279
526
 
280
527
  ## License