@docyrus/ui-pro-ai-assistant 0.1.2 → 0.1.4

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 ADDED
@@ -0,0 +1,407 @@
1
+ # @docyrus/ui-pro-ai-assistant
2
+
3
+ A full-featured, drop-in AI assistant chat UI for React. Ships with multi-turn conversations, a work canvas, project management, multi-model and multi-agent support, voice input, file uploads, deep research, and built-in i18n for 9 languages.
4
+
5
+ ## Highlights
6
+
7
+ - **Plug-and-play chat interface** — Modal or inline rendering with a single component.
8
+ - **Work canvas** — AI-generated outputs (text, code, spreadsheets, images, charts, documents) are rendered in type-specific viewers side-by-side with the conversation.
9
+ - **Projects & sessions** — Organize conversations into projects, manage threads, and persist context.
10
+ - **Multi-model & multi-agent** — Let users switch between AI models and agent deployments on the fly.
11
+ - **Deep research** — Extended research mode with live progress streaming.
12
+ - **AI memories** — Persistent memory management across sessions.
13
+ - **Voice input** — Browser-native speech-to-text.
14
+ - **File uploads** — Attach files to messages with configurable format restrictions.
15
+ - **i18n** — English, German, Spanish, French, Italian, Portuguese, Greek, Slovenian, Turkish.
16
+ - **Vite plugin** — Optional dev-server middleware for Plate editor AI commands.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @docyrus/ui-pro-ai-assistant
22
+ ```
23
+
24
+ ### Peer dependencies
25
+
26
+ ```bash
27
+ npm install @docyrus/api-client @docyrus/ui-pro-shared react react-dom
28
+ ```
29
+
30
+ | Peer | Version |
31
+ |------|---------|
32
+ | `@docyrus/api-client` | `>= 0.1.0` |
33
+ | `@docyrus/ui-pro-shared` | `>= 0.0.1` |
34
+ | `react` | `^19` |
35
+ | `react-dom` | `^19` |
36
+ | `vite` | `>= 5.0.0` *(optional)* |
37
+
38
+ ## Quick start
39
+
40
+ ```tsx
41
+ import "@docyrus/ui-pro-ai-assistant/styles.css";
42
+
43
+ import { useCallback, useMemo } from "react";
44
+ import { useDocyrusAuth } from "@docyrus/signin";
45
+ import { AssistantProvider, DocyAssistant } from "@docyrus/ui-pro-ai-assistant";
46
+
47
+ function App() {
48
+ const { client, status } = useDocyrusAuth();
49
+
50
+ const getAuthToken = useCallback(async () => {
51
+ const token = await client?.getAccessToken();
52
+ if (!token) throw new Error("No access token available");
53
+ return token;
54
+ }, [client]);
55
+
56
+ const config = useMemo(() => ({
57
+ apiBaseUrl: "https://api.docyrus.com/v1",
58
+ getAuthToken,
59
+ }), [getAuthToken]);
60
+
61
+ if (status !== "authenticated" || !client) {
62
+ return <p>Authenticating...</p>;
63
+ }
64
+
65
+ return (
66
+ <AssistantProvider config={config}>
67
+ <DocyAssistant
68
+ tenantAiAgentId="your-agent-id"
69
+ renderMode="inline"
70
+ enableSidebar
71
+ enableNavDropdown
72
+ className="h-full w-full"
73
+ />
74
+ </AssistantProvider>
75
+ );
76
+ }
77
+ ```
78
+
79
+ ### Modal mode
80
+
81
+ ```tsx
82
+ function ModalExample() {
83
+ const [open, setOpen] = useState(false);
84
+
85
+ return (
86
+ <>
87
+ <button onClick={() => setOpen(true)}>Open Assistant</button>
88
+ <AssistantProvider config={config}>
89
+ <DocyAssistant
90
+ tenantAiAgentId="your-agent-id"
91
+ renderMode="modal"
92
+ isOpen={open}
93
+ onClose={() => setOpen(false)}
94
+ />
95
+ </AssistantProvider>
96
+ </>
97
+ );
98
+ }
99
+ ```
100
+
101
+ ## Exports
102
+
103
+ | Entry point | Import path | Description |
104
+ |-------------|-------------|-------------|
105
+ | Main | `@docyrus/ui-pro-ai-assistant` | Components, provider, hooks, and types |
106
+ | Vite plugin | `@docyrus/ui-pro-ai-assistant/vite` | Dev-server middleware for Plate AI |
107
+ | Web worker | `@docyrus/ui-pro-ai-assistant/worker` | Worker entry for AI command handlers |
108
+ | Stylesheet | `@docyrus/ui-pro-ai-assistant/styles.css` | Required CSS — import once at app root |
109
+
110
+ ### Exported symbols
111
+
112
+ ```ts
113
+ // Components
114
+ import { DocyAssistant } from "@docyrus/ui-pro-ai-assistant";
115
+
116
+ // Provider & config
117
+ import {
118
+ AssistantProvider,
119
+ useAssistantConfig,
120
+ } from "@docyrus/ui-pro-ai-assistant";
121
+
122
+ // i18n
123
+ import {
124
+ AssistantI18nProvider,
125
+ useAssistantTranslation,
126
+ } from "@docyrus/ui-pro-ai-assistant";
127
+
128
+ // Types
129
+ import type {
130
+ AssistantConfig,
131
+ AssistantUser,
132
+ Project,
133
+ Work,
134
+ WorkTypes,
135
+ } from "@docyrus/ui-pro-ai-assistant";
136
+
137
+ // Vite plugin (separate entry)
138
+ import { plateEditorPlugin } from "@docyrus/ui-pro-ai-assistant/vite";
139
+ ```
140
+
141
+ ## API reference
142
+
143
+ ### `<AssistantProvider>`
144
+
145
+ Wraps your component tree to provide API configuration context. Must be an ancestor of `<DocyAssistant>`.
146
+
147
+ ```tsx
148
+ <AssistantProvider config={config}>
149
+ {children}
150
+ </AssistantProvider>
151
+ ```
152
+
153
+ #### `AssistantConfig`
154
+
155
+ | Property | Type | Required | Description |
156
+ |----------|------|----------|-------------|
157
+ | `apiBaseUrl` | `string` | Yes | Base API URL, e.g. `"https://api.docyrus.com/v1"` |
158
+ | `getAuthToken` | `() => Promise<string>` | Yes | Async callback returning a valid Bearer token |
159
+ | `user` | `AssistantUser \| null` | No | Current user info for display |
160
+ | `getDataSourceSchema` | `(id: string) => Promise<DataSourceSchema \| null>` | No | Resolver for data source schemas |
161
+
162
+ #### `AssistantUser`
163
+
164
+ ```ts
165
+ interface AssistantUser {
166
+ id: string;
167
+ email?: string;
168
+ firstname?: string;
169
+ lastname?: string;
170
+ photo?: string;
171
+ }
172
+ ```
173
+
174
+ ---
175
+
176
+ ### `<DocyAssistant>`
177
+
178
+ The main chat interface component.
179
+
180
+ #### Core
181
+
182
+ | Prop | Type | Default | Description |
183
+ |------|------|---------|-------------|
184
+ | `tenantAiAgentId` | `string` | — | **Required.** ID of the tenant AI agent |
185
+ | `renderMode` | `"modal" \| "inline"` | `"modal"` | Render as overlay dialog or embedded inline |
186
+ | `isOpen` | `boolean` | — | Modal visibility (modal mode only) |
187
+ | `onClose` | `() => void` | — | Called when the modal closes |
188
+ | `className` | `string` | — | CSS class on the root element |
189
+
190
+ #### Appearance
191
+
192
+ | Prop | Type | Default | Description |
193
+ |------|------|---------|-------------|
194
+ | `title` | `string` | — | Header title |
195
+ | `description` | `string` | — | Subtitle below the title |
196
+ | `placeholder` | `string` | — | Chat input placeholder |
197
+ | `logo` | `string` | — | Logo image URL |
198
+ | `footerText` | `string` | — | Footer text |
199
+ | `theme` | `"auto" \| "light" \| "dark"` | `"auto"` | Color theme |
200
+ | `variant` | `"default" \| "docked" \| "expanded"` | `"default"` | Layout variant |
201
+ | `size` | `"default" \| "large"` | `"default"` | Component size |
202
+
203
+ #### Layout
204
+
205
+ | Prop | Type | Default | Description |
206
+ |------|------|---------|-------------|
207
+ | `enableSidebar` | `boolean` | `true` | Show the session list sidebar |
208
+ | `enableNavDropdown` | `boolean` | `false` | Show navigation dropdown |
209
+ | `defaultFullscreen` | `boolean` | `false` | Start in fullscreen |
210
+ | `hideExpand` | `boolean` | `false` | Hide the fullscreen toggle |
211
+ | `maxMessages` | `number` | — | Max messages to keep in context |
212
+
213
+ #### Features
214
+
215
+ | Prop | Type | Default | Description |
216
+ |------|------|---------|-------------|
217
+ | `supportWebSearch` | `boolean` | `true` | Web search |
218
+ | `supportThinking` | `boolean` | `true` | Thinking / reasoning mode |
219
+ | `supportFiles` | `boolean` | `true` | File uploads |
220
+ | `supportDocumentSearch` | `boolean` | `true` | Document search |
221
+ | `supportDeepResearch` | `boolean` | `true` | Deep research mode |
222
+ | `supportMultiModels` | `boolean` | `true` | Model selector |
223
+ | `supportWorkCanvas` | `boolean` | `true` | Work canvas panel |
224
+ | `supportedFileFormats` | `string[]` | — | Allowed upload MIME types / extensions |
225
+ | `enableVoice` | `boolean` | `false` | Voice input mode |
226
+ | `enableMicrophone` | `boolean` | `true` | Microphone button |
227
+
228
+ #### Agent selection
229
+
230
+ | Prop | Type | Default | Description |
231
+ |------|------|---------|-------------|
232
+ | `agentSelectorUrl` | `string` | `"/ai/agent-deployments"` | Deployment selector endpoint |
233
+ | `baseAgentSelectorUrl` | `string` | `"/ai/agent-deployments/base"` | Base agent selector endpoint |
234
+ | `onAgentChange` | `(agentId: string, agentType: "base" \| "deployment") => void` | — | Fires when the active agent changes |
235
+
236
+ #### API
237
+
238
+ | Prop | Type | Default | Description |
239
+ |------|------|---------|-------------|
240
+ | `apiEndpoint` | `string` | `"/ai/agents/:agentId/chat"` | Chat endpoint template (`:agentId` is replaced at runtime) |
241
+
242
+ #### Callbacks
243
+
244
+ | Prop | Type | Description |
245
+ |------|------|-------------|
246
+ | `onMessageSend` | `(message: string) => void` | Fires when a message is sent |
247
+ | `onVoiceStart` | `() => void` | Fires when voice recording starts |
248
+ | `onVoiceEnd` | `() => void` | Fires when voice recording ends |
249
+
250
+ ---
251
+
252
+ ### `useAssistantConfig()`
253
+
254
+ Returns the `AssistantConfig` from the nearest `AssistantProvider`. Throws if used outside the provider.
255
+
256
+ ```tsx
257
+ const { apiBaseUrl, getAuthToken } = useAssistantConfig();
258
+ ```
259
+
260
+ ---
261
+
262
+ ### `useAssistantTranslation()`
263
+
264
+ Returns the `t` function for translating assistant UI strings.
265
+
266
+ ```tsx
267
+ const { t } = useAssistantTranslation();
268
+ // t("common.untitled") → "Untitled"
269
+ ```
270
+
271
+ ---
272
+
273
+ ### `plateEditorPlugin()`
274
+
275
+ Vite plugin that adds dev-server middleware for Plate editor AI commands (`/api/ai/command` and `/api/ai/copilot`). Only needed if you use the Plate rich-text editor AI features.
276
+
277
+ ```ts
278
+ // vite.config.ts
279
+ import { defineConfig } from "vite";
280
+ import { plateEditorPlugin } from "@docyrus/ui-pro-ai-assistant/vite";
281
+
282
+ export default defineConfig({
283
+ plugins: [plateEditorPlugin()],
284
+ });
285
+ ```
286
+
287
+ ## Work canvas types
288
+
289
+ AI-generated outputs open in a side canvas with type-specific viewers:
290
+
291
+ | `WorkTypes` value | Viewer | Description |
292
+ |-------------------|--------|-------------|
293
+ | `Text` | Plate.js rich editor | Editable rich text |
294
+ | `Code` | Sandpack | Live code preview |
295
+ | `Data` / `Xlsx` | Univer spreadsheet | Full spreadsheet with formulas |
296
+ | `Image` | Image viewer | Generated images |
297
+ | `Chart` | VChart | Interactive charts |
298
+ | `Html` / `HtmlTemplate` | HTML iframe | Rendered HTML |
299
+ | `Docyment` / `Docx` / `Pptx` | Document viewer | Office document preview |
300
+ | `App` | App renderer | Custom applications |
301
+ | `Record` | Record view | Structured data display |
302
+ | `DataSource` | Data explorer | Data source output |
303
+ | `CustomQuerySql` / `CustomQueryJson` | Query result | Query output display |
304
+
305
+ ## Internationalization
306
+
307
+ 9 built-in locales: `en`, `de`, `es`, `fr`, `it`, `pt`, `el`, `sl`, `tr`.
308
+
309
+ The language is auto-detected. To override, wrap with `AssistantI18nProvider`:
310
+
311
+ ```tsx
312
+ import { AssistantI18nProvider } from "@docyrus/ui-pro-ai-assistant";
313
+
314
+ <AssistantI18nProvider locale="de">
315
+ <DocyAssistant ... />
316
+ </AssistantI18nProvider>
317
+ ```
318
+
319
+ ## Types
320
+
321
+ ### `Project`
322
+
323
+ ```ts
324
+ interface Project {
325
+ id: string;
326
+ name: string;
327
+ tenant_ai_agent_id: string;
328
+ description?: string;
329
+ instructions?: string;
330
+ tenant_ai_agent_deployment_id?: string;
331
+ color?: string;
332
+ icon?: string;
333
+ shared_to?: string[];
334
+ created_by?: string;
335
+ }
336
+ ```
337
+
338
+ ### `Work`
339
+
340
+ ```ts
341
+ interface Work {
342
+ id: string;
343
+ title: string;
344
+ type?: WorkTypes;
345
+ content_json?: unknown;
346
+ content_text?: string;
347
+ description?: string;
348
+ image_url?: string;
349
+ core_ai_model_id?: string | null;
350
+ base_message_id?: string;
351
+ base_thread_id?: string;
352
+ tenant_ai_agent_id?: string;
353
+ tenant_ai_agent_deployment_id?: string;
354
+ tenant_data_source_id?: string;
355
+ tenant_ai_project_id?: string;
356
+ shared_to?: string[];
357
+ created_by?: string;
358
+ created_on?: Date;
359
+ last_modified_on?: Date;
360
+ }
361
+ ```
362
+
363
+ ### `WorkTypes`
364
+
365
+ ```ts
366
+ const WorkTypes = {
367
+ Record: "record",
368
+ Data: "data",
369
+ Text: "text",
370
+ Code: "code",
371
+ Image: "image",
372
+ Xlsx: "xlsx",
373
+ Docx: "docx",
374
+ Pptx: "pptx",
375
+ Html: "html",
376
+ Docyment: "docyment",
377
+ Chart: "chart",
378
+ DataSource: "data_source",
379
+ HtmlTemplate: "html_template",
380
+ CustomQuerySql: "custom_query_sql",
381
+ CustomQueryJson: "custom_query_json",
382
+ App: "app",
383
+ } as const;
384
+ ```
385
+
386
+ ## Environment variables
387
+
388
+ When using with Vite, set these in your `.env`:
389
+
390
+ ```env
391
+ VITE_DOCYRUS_API_URL=https://api.docyrus.com
392
+ VITE_DOCYRUS_CLIENT_ID=your-client-id
393
+ VITE_DOCYRUS_AGENT_ID=your-agent-id
394
+
395
+ # Optional — for Plate editor AI plugin
396
+ VITE_DOCYRUS_EDITOR_AGENT_ID=your-editor-agent-id
397
+ ```
398
+
399
+ ## Requirements
400
+
401
+ - React 19+
402
+ - ESM only (`"type": "module"`)
403
+ - Tailwind CSS v4 (the stylesheet uses Tailwind utilities)
404
+
405
+ ## License
406
+
407
+ MIT
package/dist/index.js CHANGED
@@ -12946,17 +12946,27 @@ var DiscussionKit = [discussionPlugin];
12946
12946
  var useChat = () => {
12947
12947
  const editor = useEditorRef();
12948
12948
  const { getAccessToken } = useAuthContext();
12949
+ const options3 = usePluginOption(aiChatPlugin, "chatOptions");
12949
12950
  const baseChat = useChat$1({
12950
12951
  id: "editor",
12951
12952
  transport: new DefaultChatTransport({
12952
- api: "/api/ai/command",
12953
- headers: async () => {
12953
+ api: options3?.api || "/api/ai/command",
12954
+ fetch: (async (input, init) => {
12955
+ const bodyOptions = options3?.body;
12956
+ const initBody = init?.body ? JSON.parse(init.body) : {};
12957
+ const body = { ...initBody, ...bodyOptions };
12954
12958
  const token = getAccessToken ? await getAccessToken() : null;
12955
- return {
12956
- "Content-Type": "application/json",
12957
- ...token && { Authorization: `Bearer ${token}` }
12958
- };
12959
- }
12959
+ const res = await fetch(input, {
12960
+ ...init,
12961
+ body: JSON.stringify(body),
12962
+ headers: {
12963
+ "Content-Type": "application/json",
12964
+ ...token && { Authorization: `Bearer ${token}` },
12965
+ ...init?.headers
12966
+ }
12967
+ });
12968
+ return res;
12969
+ })
12960
12970
  }),
12961
12971
  onData(data) {
12962
12972
  if (data.type === "data-toolName") {
@@ -13022,6 +13032,10 @@ var useChat = () => {
13022
13032
  // src/internal/plate-editor/editor/plugins/ai-kit.tsx
13023
13033
  var aiChatPlugin = AIChatPlugin.extend({
13024
13034
  options: {
13035
+ chatOptions: {
13036
+ api: "/api/ai/command",
13037
+ body: {}
13038
+ },
13025
13039
  contentRef: null,
13026
13040
  scrollRef: null
13027
13041
  }
@@ -22677,7 +22691,7 @@ var AssistantView = ({ ref, ...props }) => {
22677
22691
  }
22678
22692
  )
22679
22693
  ] }),
22680
- /* @__PURE__ */ jsx("div", { className: "flex-1 p-4 flex flex-col min-h-0 overflow-hidden", children: renderSidebar() })
22694
+ /* @__PURE__ */ jsx("div", { className: "flex-1 p-4 flex flex-col min-h-0 overflow-hidden", children: renderSidebar(true) })
22681
22695
  ] }) })
22682
22696
  ] }),
22683
22697
  enableSidebar && renderSidebar && /* @__PURE__ */ jsx(
@@ -22714,7 +22728,7 @@ var AssistantView = ({ ref, ...props }) => {
22714
22728
  }
22715
22729
  )
22716
22730
  ] }),
22717
- /* @__PURE__ */ jsx("div", { className: "flex-1 p-4 flex flex-col min-h-0 overflow-hidden", children: renderSidebar() })
22731
+ /* @__PURE__ */ jsx("div", { className: "flex-1 p-4 flex flex-col min-h-0 overflow-hidden", children: renderSidebar(false) })
22718
22732
  ] })
22719
22733
  }
22720
22734
  ),
@@ -24915,7 +24929,7 @@ var DocyAssistant = ({
24915
24929
  const query = sessionState.searchQuery.toLowerCase();
24916
24930
  return session.title.toLowerCase().includes(query);
24917
24931
  });
24918
- const renderSidebarContent = () => /* @__PURE__ */ jsx(
24932
+ const renderSidebarContent = (isFloating) => /* @__PURE__ */ jsx(
24919
24933
  SidebarContent,
24920
24934
  {
24921
24935
  sessions: sessionState.sessions,
@@ -24954,7 +24968,7 @@ var DocyAssistant = ({
24954
24968
  uiActions.setActiveTab(2);
24955
24969
  projectActions.setView("create");
24956
24970
  },
24957
- onToggleSidebar: uiState.isExpanded ? void 0 : () => uiActions.setSidebarOpen(false),
24971
+ onToggleSidebar: isFloating && !uiState.isExpanded ? () => uiActions.setSidebarOpen(false) : void 0,
24958
24972
  t
24959
24973
  }
24960
24974
  );