omnix-chat 0.1.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 (176) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +21 -0
  3. package/README.md +360 -0
  4. package/dist/es-BoccmK_s.js +457 -0
  5. package/dist/es-BoccmK_s.js.map +1 -0
  6. package/dist/favicon.svg +1 -0
  7. package/dist/logo.svg +1 -0
  8. package/dist/omnix-chat.es.js +3197 -0
  9. package/dist/omnix-chat.es.js.map +1 -0
  10. package/dist/omnix-chat.umd.js +4 -0
  11. package/dist/omnix-chat.umd.js.map +1 -0
  12. package/dist/react.es.js +26062 -0
  13. package/dist/react.es.js.map +1 -0
  14. package/dist/react.umd.js +593 -0
  15. package/dist/react.umd.js.map +1 -0
  16. package/dist/src/chat/ChatRoot.d.ts +9 -0
  17. package/dist/src/chat/ChatRoot.d.ts.map +1 -0
  18. package/dist/src/chat/bridge/index.d.ts +2 -0
  19. package/dist/src/chat/bridge/index.d.ts.map +1 -0
  20. package/dist/src/chat/bridge/messageBridge.d.ts +8 -0
  21. package/dist/src/chat/bridge/messageBridge.d.ts.map +1 -0
  22. package/dist/src/chat/components/AIAssistantBubble.d.ts +13 -0
  23. package/dist/src/chat/components/AIAssistantBubble.d.ts.map +1 -0
  24. package/dist/src/chat/components/ErrorBoundary.d.ts +25 -0
  25. package/dist/src/chat/components/ErrorBoundary.d.ts.map +1 -0
  26. package/dist/src/chat/components/LauncherSlot.d.ts +8 -0
  27. package/dist/src/chat/components/LauncherSlot.d.ts.map +1 -0
  28. package/dist/src/chat/components/LoginForm.d.ts +7 -0
  29. package/dist/src/chat/components/LoginForm.d.ts.map +1 -0
  30. package/dist/src/chat/components/PanelHeaderTitle.d.ts +7 -0
  31. package/dist/src/chat/components/PanelHeaderTitle.d.ts.map +1 -0
  32. package/dist/src/chat/components/message/BlockExportActions.d.ts +7 -0
  33. package/dist/src/chat/components/message/BlockExportActions.d.ts.map +1 -0
  34. package/dist/src/chat/components/message/MessageBlockRenderer.d.ts +6 -0
  35. package/dist/src/chat/components/message/MessageBlockRenderer.d.ts.map +1 -0
  36. package/dist/src/chat/components/message/SafeMarkdownHtml.d.ts +11 -0
  37. package/dist/src/chat/components/message/SafeMarkdownHtml.d.ts.map +1 -0
  38. package/dist/src/chat/components/message/blockExport.d.ts +5 -0
  39. package/dist/src/chat/components/message/blockExport.d.ts.map +1 -0
  40. package/dist/src/chat/components/message/chartBlockUtils.d.ts +10 -0
  41. package/dist/src/chat/components/message/chartBlockUtils.d.ts.map +1 -0
  42. package/dist/src/chat/components/message/index.d.ts +4 -0
  43. package/dist/src/chat/components/message/index.d.ts.map +1 -0
  44. package/dist/src/chat/components/message/parseMessageBlocks.d.ts +15 -0
  45. package/dist/src/chat/components/message/parseMessageBlocks.d.ts.map +1 -0
  46. package/dist/src/chat/components/message/types.d.ts +89 -0
  47. package/dist/src/chat/components/message/types.d.ts.map +1 -0
  48. package/dist/src/chat/components/panel/AIAssistantPanel.d.ts +4 -0
  49. package/dist/src/chat/components/panel/AIAssistantPanel.d.ts.map +1 -0
  50. package/dist/src/chat/components/panel/AgentSkillBar.d.ts +17 -0
  51. package/dist/src/chat/components/panel/AgentSkillBar.d.ts.map +1 -0
  52. package/dist/src/chat/components/panel/BubbleAvatars.d.ts +7 -0
  53. package/dist/src/chat/components/panel/BubbleAvatars.d.ts.map +1 -0
  54. package/dist/src/chat/components/panel/ConversationSidebar.d.ts +23 -0
  55. package/dist/src/chat/components/panel/ConversationSidebar.d.ts.map +1 -0
  56. package/dist/src/chat/components/panel/DownFeedbackModal.d.ts +18 -0
  57. package/dist/src/chat/components/panel/DownFeedbackModal.d.ts.map +1 -0
  58. package/dist/src/chat/components/panel/MessageBody.d.ts +16 -0
  59. package/dist/src/chat/components/panel/MessageBody.d.ts.map +1 -0
  60. package/dist/src/chat/components/panel/MessageFeedbackFooter.d.ts +10 -0
  61. package/dist/src/chat/components/panel/MessageFeedbackFooter.d.ts.map +1 -0
  62. package/dist/src/chat/components/panel/MessageList.d.ts +13 -0
  63. package/dist/src/chat/components/panel/MessageList.d.ts.map +1 -0
  64. package/dist/src/chat/components/panel/PanelModals.d.ts +13 -0
  65. package/dist/src/chat/components/panel/PanelModals.d.ts.map +1 -0
  66. package/dist/src/chat/components/panel/PromptsSection.d.ts +11 -0
  67. package/dist/src/chat/components/panel/PromptsSection.d.ts.map +1 -0
  68. package/dist/src/chat/components/panel/constants.d.ts +83 -0
  69. package/dist/src/chat/components/panel/constants.d.ts.map +1 -0
  70. package/dist/src/chat/components/panel/index.d.ts +3 -0
  71. package/dist/src/chat/components/panel/index.d.ts.map +1 -0
  72. package/dist/src/chat/components/panel/types.d.ts +60 -0
  73. package/dist/src/chat/components/panel/types.d.ts.map +1 -0
  74. package/dist/src/chat/components/panel/useBubbleItems.d.ts +15 -0
  75. package/dist/src/chat/components/panel/useBubbleItems.d.ts.map +1 -0
  76. package/dist/src/chat/components/panel/useBubbleScroll.d.ts +21 -0
  77. package/dist/src/chat/components/panel/useBubbleScroll.d.ts.map +1 -0
  78. package/dist/src/chat/components/panel/useConversationSidebarScroll.d.ts +10 -0
  79. package/dist/src/chat/components/panel/useConversationSidebarScroll.d.ts.map +1 -0
  80. package/dist/src/chat/components/panel/utils.d.ts +25 -0
  81. package/dist/src/chat/components/panel/utils.d.ts.map +1 -0
  82. package/dist/src/chat/config/assistantPrompts.d.ts +9 -0
  83. package/dist/src/chat/config/assistantPrompts.d.ts.map +1 -0
  84. package/dist/src/chat/config/globalInteractionCopy.d.ts +19 -0
  85. package/dist/src/chat/config/globalInteractionCopy.d.ts.map +1 -0
  86. package/dist/src/chat/config/index.d.ts +2 -0
  87. package/dist/src/chat/config/index.d.ts.map +1 -0
  88. package/dist/src/chat/hooks/index.d.ts +4 -0
  89. package/dist/src/chat/hooks/index.d.ts.map +1 -0
  90. package/dist/src/chat/hooks/useClientState.d.ts +15 -0
  91. package/dist/src/chat/hooks/useClientState.d.ts.map +1 -0
  92. package/dist/src/chat/hooks/useDebouncedSessionPrepare.d.ts +9 -0
  93. package/dist/src/chat/hooks/useDebouncedSessionPrepare.d.ts.map +1 -0
  94. package/dist/src/chat/hooks/useLauncherPosition.d.ts +11 -0
  95. package/dist/src/chat/hooks/useLauncherPosition.d.ts.map +1 -0
  96. package/dist/src/chat/i18n.d.ts +11 -0
  97. package/dist/src/chat/i18n.d.ts.map +1 -0
  98. package/dist/src/chat/styles/host-styles.d.ts +10 -0
  99. package/dist/src/chat/styles/host-styles.d.ts.map +1 -0
  100. package/dist/src/chat/styles/inject.d.ts +4 -0
  101. package/dist/src/chat/styles/inject.d.ts.map +1 -0
  102. package/dist/src/chat/types.d.ts +56 -0
  103. package/dist/src/chat/types.d.ts.map +1 -0
  104. package/dist/src/chat/utils.d.ts +3 -0
  105. package/dist/src/chat/utils.d.ts.map +1 -0
  106. package/dist/src/core/api-envelope.d.ts +6 -0
  107. package/dist/src/core/api-envelope.d.ts.map +1 -0
  108. package/dist/src/core/auth-headers.d.ts +19 -0
  109. package/dist/src/core/auth-headers.d.ts.map +1 -0
  110. package/dist/src/core/auth-response.d.ts +9 -0
  111. package/dist/src/core/auth-response.d.ts.map +1 -0
  112. package/dist/src/core/auth-store.d.ts +23 -0
  113. package/dist/src/core/auth-store.d.ts.map +1 -0
  114. package/dist/src/core/auth-types.d.ts +26 -0
  115. package/dist/src/core/auth-types.d.ts.map +1 -0
  116. package/dist/src/core/auth.d.ts +25 -0
  117. package/dist/src/core/auth.d.ts.map +1 -0
  118. package/dist/src/core/chat-response.d.ts +66 -0
  119. package/dist/src/core/chat-response.d.ts.map +1 -0
  120. package/dist/src/core/chat-sse.d.ts +66 -0
  121. package/dist/src/core/chat-sse.d.ts.map +1 -0
  122. package/dist/src/core/errors.d.ts +16 -0
  123. package/dist/src/core/errors.d.ts.map +1 -0
  124. package/dist/src/core/events.d.ts +19 -0
  125. package/dist/src/core/events.d.ts.map +1 -0
  126. package/dist/src/core/feedback-utils.d.ts +9 -0
  127. package/dist/src/core/feedback-utils.d.ts.map +1 -0
  128. package/dist/src/core/http/client.d.ts +3 -0
  129. package/dist/src/core/http/client.d.ts.map +1 -0
  130. package/dist/src/core/http/errors.d.ts +6 -0
  131. package/dist/src/core/http/errors.d.ts.map +1 -0
  132. package/dist/src/core/http/index.d.ts +3 -0
  133. package/dist/src/core/http/index.d.ts.map +1 -0
  134. package/dist/src/core/http/sse.d.ts +5 -0
  135. package/dist/src/core/http/sse.d.ts.map +1 -0
  136. package/dist/src/core/http/types.d.ts +30 -0
  137. package/dist/src/core/http/types.d.ts.map +1 -0
  138. package/dist/src/core/instance.d.ts +135 -0
  139. package/dist/src/core/instance.d.ts.map +1 -0
  140. package/dist/src/core/message-blocks.d.ts +25 -0
  141. package/dist/src/core/message-blocks.d.ts.map +1 -0
  142. package/dist/src/core/resolve.d.ts +5 -0
  143. package/dist/src/core/resolve.d.ts.map +1 -0
  144. package/dist/src/core/services/agent.service.d.ts +18 -0
  145. package/dist/src/core/services/agent.service.d.ts.map +1 -0
  146. package/dist/src/core/services/auth.service.d.ts +14 -0
  147. package/dist/src/core/services/auth.service.d.ts.map +1 -0
  148. package/dist/src/core/services/chat.service.d.ts +28 -0
  149. package/dist/src/core/services/chat.service.d.ts.map +1 -0
  150. package/dist/src/core/services/feedback.service.d.ts +15 -0
  151. package/dist/src/core/services/feedback.service.d.ts.map +1 -0
  152. package/dist/src/core/services/index.d.ts +5 -0
  153. package/dist/src/core/services/index.d.ts.map +1 -0
  154. package/dist/src/index.d.ts +15 -0
  155. package/dist/src/index.d.ts.map +1 -0
  156. package/dist/src/react/AgentChat.d.ts +25 -0
  157. package/dist/src/react/AgentChat.d.ts.map +1 -0
  158. package/dist/src/react/AgentChatEmbedded.d.ts +12 -0
  159. package/dist/src/react/AgentChatEmbedded.d.ts.map +1 -0
  160. package/dist/src/react/AgentChatProvider.d.ts +15 -0
  161. package/dist/src/react/AgentChatProvider.d.ts.map +1 -0
  162. package/dist/src/react/context.d.ts +4 -0
  163. package/dist/src/react/context.d.ts.map +1 -0
  164. package/dist/src/react/index.d.ts +11 -0
  165. package/dist/src/react/index.d.ts.map +1 -0
  166. package/dist/src/react/useAgentChat.d.ts +36 -0
  167. package/dist/src/react/useAgentChat.d.ts.map +1 -0
  168. package/dist/src/types.d.ts +337 -0
  169. package/dist/src/types.d.ts.map +1 -0
  170. package/dist/src/utils/id.d.ts +7 -0
  171. package/dist/src/utils/id.d.ts.map +1 -0
  172. package/dist/src/utils/sdk-version.d.ts +9 -0
  173. package/dist/src/utils/sdk-version.d.ts.map +1 -0
  174. package/dist/xlsx-CXTDRHcz.js +12389 -0
  175. package/dist/xlsx-CXTDRHcz.js.map +1 -0
  176. package/package.json +115 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+
12
+ - npm package renamed from `agent-chat` to **`omnix-chat`**; build artifacts are
13
+ now `dist/omnix-chat.es.js` and `dist/omnix-chat.umd.js`.
14
+
15
+ ## [0.1.0] - Initial public beta
16
+
17
+ ### Added
18
+
19
+ - Imperative SDK entry: `AgentChat` singleton + `createAgentChat()` factory
20
+ (`init`, `destroy`, `open`, `close`, `toggle`, `isOpen`, `identify`,
21
+ `sendMessage`, `prefetch`, `getState`, `on`, `off`).
22
+ - React adapter exposed as the `omnix-chat/react` sub-path:
23
+ - `<AgentChat />`, `<AgentChatProvider>`, `AgentChatEmbedded`, `useAgentChat()`.
24
+ - DSN parsing (`normalizeDsn`) with `INVALID_DSN` errors for malformed input.
25
+ - Session list, message history, SSE streaming, agent/skill picker, message
26
+ feedback (like/dislike), table Excel export, chart PNG export.
27
+ - Shadow DOM widget with antd + `@ant-design/x`; `theme: 'light' | 'dark' | 'auto'`.
28
+ - Vite library build producing ESM + UMD for `omnix-chat` and `omnix-chat/react`,
29
+ plus `vite-plugin-dts`-generated `.d.ts`.
30
+ - UMD attaches `window.AgentChat`.
31
+ - Playground at `demo/`; CDN and React examples under `examples/`.
32
+
33
+ [Unreleased]: https://github.com/your-org/omnix-chat/compare/v0.1.0...HEAD
34
+ [0.1.0]: https://github.com/your-org/omnix-chat/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 omnix-chat contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # omnix-chat
2
+
3
+ Embeddable Agent chat SDK for the browser. Configure with a **DSN**, drop a
4
+ chat widget into any web page, and let your end users talk to your agent
5
+ backend.
6
+
7
+ - 🪶 **Tiny core** — the SDK weighs only a few KB once `react`, `antd`, and
8
+ `@ant-design/x` are externalized.
9
+ - 🔌 **Two integrations** — vanilla JS (`AgentChat.init({...})`) and React
10
+ (`<AgentChat />` from `omnix-chat/react`, or `<AgentChatProvider>` +
11
+ `useAgentChat()` for custom layouts).
12
+ - 🎨 **Ant Design X UI** — the chat surface is built on
13
+ [@ant-design/x](https://x.ant.design/) (Bubble, Sender, Welcome) with full
14
+ antd theming (`light`/`dark`/`auto` + token overrides).
15
+ - 🛡 **Style isolation** — rendered inside a Shadow DOM with antd's
16
+ `StyleProvider` redirected to the shadow root, so the host page's CSS is
17
+ never touched.
18
+
19
+ > **Status:** v0.1 public beta. The public API surface is stable but the
20
+ > backend HTTP contract is still being refined.
21
+
22
+ ## Quick start
23
+
24
+ ### CDN drop-in (`<script>` tag)
25
+
26
+ ```html
27
+ <!-- Peer dependencies (load order matters) -->
28
+ <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
29
+ <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
30
+ <script crossorigin src="https://unpkg.com/dayjs@1/dayjs.min.js"></script>
31
+ <script crossorigin src="https://unpkg.com/@ant-design/cssinjs/dist/cssinjs.min.js"></script>
32
+ <script crossorigin src="https://unpkg.com/@ant-design/icons/dist/index.umd.min.js"></script>
33
+ <script crossorigin src="https://unpkg.com/antd@5/dist/antd.min.js"></script>
34
+ <script crossorigin src="https://unpkg.com/@ant-design/x@1/dist/index.min.js"></script>
35
+
36
+ <!-- The SDK -->
37
+ <script src="https://unpkg.com/omnix-chat@latest/dist/omnix-chat.umd.js"></script>
38
+ <script>
39
+ AgentChat.init({
40
+ dsn: 'https://YOUR_PUBLIC_KEY@api.example.com/YOUR_PROJECT_ID',
41
+ locale: 'zh-CN',
42
+ theme: 'auto',
43
+ });
44
+ </script>
45
+ ```
46
+
47
+ ### npm + vanilla JavaScript
48
+
49
+ ```bash
50
+ pnpm add omnix-chat react react-dom antd @ant-design/x @ant-design/cssinjs @ant-design/icons dayjs
51
+ ```
52
+
53
+ ```ts
54
+ import { AgentChat } from 'omnix-chat';
55
+
56
+ AgentChat.init({
57
+ dsn: 'https://YOUR_PUBLIC_KEY@api.example.com/YOUR_PROJECT_ID',
58
+ user: { id: 'u-123', email: 'alice@example.com' },
59
+ locale: 'zh-CN',
60
+ theme: 'auto',
61
+ });
62
+ ```
63
+
64
+ ### React (recommended)
65
+
66
+ ```tsx
67
+ import { AgentChat } from 'omnix-chat/react';
68
+
69
+ export function App() {
70
+ return (
71
+ <AgentChat
72
+ dsn="your-app-dsn"
73
+ baseUrl="https://api.example.com"
74
+ accountToken="optional-host-token"
75
+ project={{ name: 'My Assistant', logo: '/logo.png' }}
76
+ locale="zh-CN"
77
+ />
78
+ );
79
+ }
80
+ ```
81
+
82
+ ### React (custom launcher with Provider)
83
+
84
+ ```tsx
85
+ import { AgentChatProvider, AgentChatEmbedded, useAgentChat } from 'omnix-chat/react';
86
+
87
+ export function App() {
88
+ return (
89
+ <AgentChatProvider dsn="your-app-dsn" baseUrl="https://api.example.com">
90
+ <YourApp />
91
+ <ChatShell />
92
+ </AgentChatProvider>
93
+ );
94
+ }
95
+
96
+ function ChatShell() {
97
+ const { instance, isOpen, open, close } = useAgentChat();
98
+ return (
99
+ <>
100
+ <button type="button" onClick={isOpen ? close : open}>
101
+ {isOpen ? 'Hide chat' : 'Need help?'}
102
+ </button>
103
+ <AgentChatEmbedded client={instance} />
104
+ </>
105
+ );
106
+ }
107
+ ```
108
+
109
+ ## DSN format
110
+
111
+ A DSN is a URL-shaped string that encodes everything the SDK needs to talk to
112
+ your backend:
113
+
114
+ ```
115
+ https://<publicKey>@<host>[:<port>][/<basePath>]/<projectId>
116
+ ```
117
+
118
+ - `publicKey` — the project's **public** key. Visible on the client; never
119
+ use it to sign sensitive operations.
120
+ - `host`/`port`/`basePath` — origin and base path of your agent API. The SDK
121
+ computes `apiBase = ${host}:${port}${basePath}/v1`.
122
+ - `projectId` — string or numeric project identifier.
123
+
124
+ Examples:
125
+
126
+ ```
127
+ https://pk_live_abc@api.example.com/42
128
+ https://pk_test@example.com:8443/api/edge/proj-7
129
+ agent://pk_x@api.example.com/9 # alias, normalized to https://
130
+ ```
131
+
132
+ Parsing / normalization:
133
+
134
+ ```ts
135
+ import { normalizeDsn, DEFAULT_BASE_URL } from 'omnix-chat';
136
+
137
+ const dsn = normalizeDsn('your-app-dsn');
138
+ await AgentChat.init({ dsn, baseUrl: DEFAULT_BASE_URL });
139
+ ```
140
+
141
+ ## Configuration reference
142
+
143
+ | Option | Type | Default | Description |
144
+ | --- | --- | --- | --- |
145
+ | `dsn` | `string` | — | **Required.** See [DSN format](#dsn-format). |
146
+ | `user` | `UserContext` | — | End-user identity. Forwarded to the backend at handshake time. |
147
+ | `locale` | `string` | `navigator.language` | BCP-47 locale (`en`, `zh-CN`, …). Drives both SDK and antd copy. |
148
+ | `theme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Visual theme. `auto` follows `prefers-color-scheme`. |
149
+ | `themeToken` | `Record<string, unknown>` | — | antd theme token overrides (e.g. `{ colorPrimary: '#7c3aed' }`). |
150
+ | `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Where the floating launcher anchors. |
151
+ | `container` | `HTMLElement \| string` | `document.body` | Where the Shadow DOM host is appended. |
152
+ | `autoOpen` | `boolean` | `false` | Open the panel as soon as the widget mounts. |
153
+ | `debug` | `boolean` | `false` | Verbose console logs and unhandled-error warnings. |
154
+ | `headers` | `Record<string, string>` | — | Extra HTTP headers added to every backend call. |
155
+ | `onReady` | `() => void` | — | Convenience alias for `instance.on('ready', ...)`. |
156
+
157
+ ## Events
158
+
159
+ ```ts
160
+ const off = AgentChat.on('message', ({ message, source }) => {
161
+ console.log(source, message.content.text);
162
+ });
163
+ off(); // unsubscribe
164
+ ```
165
+
166
+ | Event | Payload | Notes |
167
+ | --- | --- | --- |
168
+ | `ready` | `void` | Fired after `init()` settles. |
169
+ | `error` | `{ code, message, cause? }` | Any SDK-level error. Subscribe in production to forward into Sentry/Datadog. |
170
+ | `open` / `close` | `void` | The chat panel opened/closed. |
171
+ | `session` | `{ sessionId, conversationId }` | Active chat session changed. |
172
+ | `sessions` | `{ sessions: ChatSessionSummary[] }` | Sidebar session list refreshed (`GET /chat`). |
173
+ | `message` | `{ message, source }` | A user, agent, or system message hit the timeline (agent may stream incrementally). |
174
+ | `destroyed` | `void` | The instance was torn down. |
175
+
176
+ ## Lifecycle
177
+
178
+ ```ts
179
+ AgentChat.init({ dsn });
180
+ AgentChat.open();
181
+ AgentChat.identify({ id: 'u-99' });
182
+ // Resolves with the **user** message once POST succeeds.
183
+ // Assistant replies arrive via `message` events (SSE stream per sessionId).
184
+ const userMsg = await AgentChat.sendMessage('Hello!');
185
+
186
+ AgentChat.selectSession('existing-session-id'); // switch sidebar session
187
+
188
+ AgentChat.destroy(); // clean up DOM, abort in-flight requests
189
+ AgentChat.init({ dsn }); // safe to re-init after destroy
190
+ ```
191
+
192
+ For multi-tenant pages use `createAgentChat()` to obtain independent instances.
193
+
194
+ ### React Strict Mode
195
+
196
+ If you call the imperative `AgentChat.init()` from inside a React `useEffect`
197
+ under `<StrictMode>`, dev-mode will run `setup → cleanup → setup`, which
198
+ otherwise causes the launcher to flash on screen. Prefer `<AgentChat dsn="..." />`
199
+ from `omnix-chat/react`, which handles init/teardown for you. If you still call
200
+ the imperative API from an effect, guard with a deferred destroy:
201
+
202
+ ```tsx
203
+ const ref = useRef<{ key: string | null; timer: number | null }>({ key: null, timer: null });
204
+
205
+ useEffect(() => {
206
+ if (ref.current.timer != null) {
207
+ clearTimeout(ref.current.timer);
208
+ ref.current.timer = null;
209
+ }
210
+ if (ref.current.key !== dsn) {
211
+ if (ref.current.key) AgentChat.destroy();
212
+ AgentChat.init({ dsn });
213
+ ref.current.key = dsn;
214
+ }
215
+ return () => {
216
+ ref.current.timer = window.setTimeout(() => {
217
+ AgentChat.destroy();
218
+ ref.current.key = null;
219
+ ref.current.timer = null;
220
+ }, 0);
221
+ };
222
+ }, [dsn]);
223
+ ```
224
+
225
+ ## Multi-session chat & streaming
226
+
227
+ The widget shows a **left sidebar** of conversations (`GET /chat`). Selecting one
228
+ loads `GET /chat/{sessionId}` into the message pane.
229
+
230
+ ### `sendMessage()` pipeline (SDK)
231
+
232
+ ```text
233
+ User hits Send
234
+ → optimistic user bubble (pending) + notifyStateChange ← UI shows immediately
235
+ → ensure sessionId
236
+ → GET /chat/{sessionId}/stream (SSE connected)
237
+ → POST user message (existing session only)
238
+ → SSE events → agent bubble updates + notifyStateChange ← UI streams assistant
239
+ ```
240
+
241
+ **Existing session** (has `activeSessionId`):
242
+
243
+ | Order | HTTP | Purpose |
244
+ | --- | --- | --- |
245
+ | 1 | `GET /chat/{sessionId}/stream` | Listen before agent runs |
246
+ | 2 | `POST /chat/{sessionId}/messages` | `{ role: "user", content }` triggers agent |
247
+ | 3 | same SSE | `think` / `result` / `complete` / `error` |
248
+
249
+ **First message** (no session yet):
250
+
251
+ | Order | HTTP | Purpose |
252
+ | --- | --- | --- |
253
+ | 1 | `POST /chat` | `{ role, content }` → `{ sessionId }` + starts agent (backend contract) |
254
+ | 2 | `GET /chat/{sessionId}/stream` | Subscribe (ReplaySubject replays recent events) |
255
+ | — | skip `POST .../messages` | User text already persisted in step 1 |
256
+
257
+ **Other APIs**
258
+
259
+ | Step | HTTP | Notes |
260
+ | --- | --- | --- |
261
+ | List sessions | `GET /chat` | Sidebar |
262
+ | Load session | `GET /chat/{sessionId}` | `selectSession()` / `prefetch()` |
263
+
264
+ SSE → UI mapping lives in `src/core/chat-sse.ts`. React reads `getState().messages`
265
+ via `useClientState` in `ChatBody` (`useSyncExternalStore` + `notifyStateChange`).
266
+
267
+ `sendMessage()` resolves when the user bubble is `sent` or `failed`. Assistant
268
+ content streams through repeated `message` events and state updates.
269
+
270
+ ## Backend HTTP contract (legacy v1 sketch)
271
+
272
+ The SDK historically documented two endpoints:
273
+
274
+ ### `POST {apiBase}/sessions`
275
+
276
+ Headers: `X-Agent-Public-Key`, `X-Agent-Project-Id`, `X-Agent-Sdk-Version`,
277
+ `Content-Type: application/json`.
278
+
279
+ Body:
280
+
281
+ ```json
282
+ {
283
+ "locale": "zh-CN",
284
+ "sdkVersion": "0.1.0",
285
+ "origin": "https://app.example.com",
286
+ "user": { "id": "u-123", "email": "a@b.c" },
287
+ "existingConversationId": "conv_abc"
288
+ }
289
+ ```
290
+
291
+ Response (200):
292
+
293
+ ```json
294
+ {
295
+ "sessionId": "sess_...",
296
+ "sessionToken": "tok_...",
297
+ "expiresAt": 1731567890000,
298
+ "conversation": { "id": "conv_...", "messages": [] }
299
+ }
300
+ ```
301
+
302
+ ### `POST {apiBase}/messages`
303
+
304
+ Headers: `Authorization: Bearer <sessionToken>`, plus the same
305
+ `X-Agent-*` headers.
306
+
307
+ Body:
308
+
309
+ ```json
310
+ {
311
+ "conversationId": "conv_abc",
312
+ "content": { "type": "text", "text": "Hello!" }
313
+ }
314
+ ```
315
+
316
+ Response (200):
317
+
318
+ ```json
319
+ {
320
+ "message": {
321
+ "id": "msg_...",
322
+ "role": "agent",
323
+ "content": { "type": "text", "text": "Hi there!" },
324
+ "createdAt": 1731567890000,
325
+ "status": "sent"
326
+ }
327
+ }
328
+ ```
329
+
330
+ Errors should follow the shape `{ "error": { "code": "STRING_CODE", "message": "Human readable" } }`
331
+ so the SDK can surface them as typed `AgentChatError` instances.
332
+
333
+ ## Security
334
+
335
+ - The DSN's `publicKey` is **public**. Any rate-limiting or origin allow-list
336
+ must be enforced **server-side** (the SDK forwards `Origin` in the handshake
337
+ body so you can check it).
338
+ - For trusted user identification pass an HMAC of the user id as
339
+ `user.signature` (validate it on the backend with a shared secret).
340
+ - The SDK never executes `eval` or `new Function` and never injects styles
341
+ outside its Shadow DOM, so it works under strict CSP modulo
342
+ `style-src 'unsafe-inline'` (required by antd's css-in-js).
343
+
344
+ ## Local development
345
+
346
+ ```bash
347
+ pnpm install
348
+ pnpm dev # runs the demo playground at http://localhost:5173
349
+ pnpm build # produces dist/omnix-chat.es.js + .umd.js + react.es.js + .umd.js + types
350
+ pnpm typecheck
351
+ pnpm size # asserts gzipped budgets
352
+ ```
353
+
354
+ The playground intercepts `/api/edge/*/v1/sessions` and
355
+ `/api/edge/*/v1/messages` via a built-in Vite middleware, so you can develop
356
+ without a real backend.
357
+
358
+ ## License
359
+
360
+ MIT