codicent-app-sdk 0.4.14 → 0.4.17
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 +556 -521
- package/dist/cjs/components/AiInput.js +1 -1
- package/dist/cjs/components/AudioIcon.js +1 -1
- package/dist/cjs/components/ChatInput.js +1 -1
- package/dist/cjs/components/ChatMessage.js +1 -1
- package/dist/cjs/components/CombinedPlaceholderDialog.js +1 -1
- package/dist/cjs/components/DataMessagePicker.d.ts +33 -0
- package/dist/cjs/components/DataMessagePicker.d.ts.map +1 -0
- package/dist/cjs/components/DataMessagePicker.js +1 -0
- package/dist/cjs/components/Footer.js +1 -1
- package/dist/cjs/components/Header.js +1 -1
- package/dist/cjs/components/HtmlView.js +1 -1
- package/dist/cjs/components/MermaidChart.d.ts.map +1 -1
- package/dist/cjs/components/MermaidChart.js +1 -1
- package/dist/cjs/components/MessageInput.js +1 -1
- package/dist/cjs/components/MessageItem.js +1 -1
- package/dist/cjs/components/Profile.js +1 -1
- package/dist/cjs/components/Prompt.js +1 -1
- package/dist/cjs/components/SnapFooter.js +1 -1
- package/dist/cjs/components/TextHeader.js +1 -1
- package/dist/cjs/components/TypingIndicator.js +1 -1
- package/dist/cjs/components/UploadFile.js +1 -1
- package/dist/cjs/components/UrlProcessor.js +1 -1
- package/dist/cjs/components/VoiceIcon.js +1 -1
- package/dist/cjs/components/index.d.ts +2 -0
- package/dist/cjs/components/index.d.ts.map +1 -1
- package/dist/cjs/config/index.d.ts.map +1 -1
- package/dist/cjs/config/index.js +1 -1
- package/dist/cjs/hooks/useAuthState.js +1 -1
- package/dist/cjs/hooks/useCodicentState.js +1 -1
- package/dist/cjs/hooks/useLocalization.d.ts.map +1 -1
- package/dist/cjs/hooks/useLocalization.js +1 -1
- package/dist/cjs/hooks/useTools.d.ts.map +1 -1
- package/dist/cjs/hooks/useTools.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/pages/AppFrame.js +1 -1
- package/dist/cjs/pages/Chat.js +1 -1
- package/dist/cjs/pages/Compose.js +1 -1
- package/dist/cjs/pages/CrmPage.js +1 -1
- package/dist/cjs/pages/CrmPagePersistent.js +1 -1
- package/dist/cjs/pages/FormAccept.js +1 -1
- package/dist/cjs/pages/FormInvite.js +1 -1
- package/dist/cjs/pages/HtmlViewer.js +1 -1
- package/dist/cjs/pages/Login.js +1 -1
- package/dist/cjs/pages/Purchase.js +1 -1
- package/dist/cjs/pages/Sales.js +1 -1
- package/dist/cjs/pages/Search.js +1 -1
- package/dist/cjs/pages/Snap.js +1 -1
- package/dist/esm/components/AiInput.js +1 -1
- package/dist/esm/components/AudioIcon.js +1 -1
- package/dist/esm/components/ChatInput.js +1 -1
- package/dist/esm/components/ChatMessage.js +1 -1
- package/dist/esm/components/CombinedPlaceholderDialog.js +1 -1
- package/dist/esm/components/DataMessagePicker.d.ts +33 -0
- package/dist/esm/components/DataMessagePicker.d.ts.map +1 -0
- package/dist/esm/components/DataMessagePicker.js +1 -0
- package/dist/esm/components/Footer.js +1 -1
- package/dist/esm/components/Header.js +1 -1
- package/dist/esm/components/HtmlView.js +1 -1
- package/dist/esm/components/MermaidChart.d.ts.map +1 -1
- package/dist/esm/components/MermaidChart.js +1 -1
- package/dist/esm/components/MessageInput.js +1 -1
- package/dist/esm/components/MessageItem.js +1 -1
- package/dist/esm/components/Profile.js +1 -1
- package/dist/esm/components/Prompt.js +1 -1
- package/dist/esm/components/SnapFooter.js +1 -1
- package/dist/esm/components/TextHeader.js +1 -1
- package/dist/esm/components/TypingIndicator.js +1 -1
- package/dist/esm/components/UploadFile.js +1 -1
- package/dist/esm/components/UrlProcessor.js +1 -1
- package/dist/esm/components/VoiceIcon.js +1 -1
- package/dist/esm/components/index.d.ts +2 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/config/index.d.ts.map +1 -1
- package/dist/esm/config/index.js +1 -1
- package/dist/esm/hooks/useAuthState.js +1 -1
- package/dist/esm/hooks/useCodicentState.js +1 -1
- package/dist/esm/hooks/useLocalization.d.ts.map +1 -1
- package/dist/esm/hooks/useLocalization.js +1 -1
- package/dist/esm/hooks/useTools.d.ts.map +1 -1
- package/dist/esm/hooks/useTools.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/pages/AppFrame.js +1 -1
- package/dist/esm/pages/Chat.js +1 -1
- package/dist/esm/pages/Compose.js +1 -1
- package/dist/esm/pages/CrmPage.js +1 -1
- package/dist/esm/pages/CrmPagePersistent.js +1 -1
- package/dist/esm/pages/FormAccept.js +1 -1
- package/dist/esm/pages/FormInvite.js +1 -1
- package/dist/esm/pages/HtmlViewer.js +1 -1
- package/dist/esm/pages/Login.js +1 -1
- package/dist/esm/pages/Purchase.js +1 -1
- package/dist/esm/pages/Sales.js +1 -1
- package/dist/esm/pages/Search.js +1 -1
- package/dist/esm/pages/Snap.js +1 -1
- package/dist/index.d.ts +263 -233
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,521 +1,556 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
//
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
1
|
+
# codicent-app-sdk
|
|
2
|
+
|
|
3
|
+
React SDK for building AI-powered, multi-tenant white-label applications on top of the Codicent platform.
|
|
4
|
+
|
|
5
|
+
**Current version:** 0.4.16 · **License:** MIT · **Peer deps:** React ≥16.8, Fluent UI v9, react-router-dom v6
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it provides
|
|
10
|
+
|
|
11
|
+
- `CodicentService` — data CRUD, chat, file upload, token management
|
|
12
|
+
- React components — `Page`, `Content`, `Chat`, `ListView`, `Markdown`, `UploadFile`, and ~25 more
|
|
13
|
+
- Pages — `AppFrame`, `Chat`, `Compose`, `Sales`, `Search`, `Snap`, `Login`, `Logout`, and more
|
|
14
|
+
- Hooks — `useCodicentApp`, `useLocalization`, `useChat`, `useRealtimeVoiceAI`, `useAuthState`, and more
|
|
15
|
+
- Global config — `initCodicentApp()` initializer consumed by all SDK components
|
|
16
|
+
- Full TypeScript types
|
|
17
|
+
|
|
18
|
+
This SDK is the primary dependency of `codicentapp/` (the modern white-label Vite app) in the monorepo. See `codicentapp/` for a complete real-world usage reference.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### From npm
|
|
25
|
+
```bash
|
|
26
|
+
npm install codicent-app-sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Monorepo local dependency (recommended during development)
|
|
30
|
+
In your app's `package.json`:
|
|
31
|
+
```json
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"codicent-app-sdk": "file:../codicent-app-sdk"
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
Then `npm install` in your app.
|
|
37
|
+
|
|
38
|
+
### Peer dependencies
|
|
39
|
+
Install these alongside the SDK:
|
|
40
|
+
```bash
|
|
41
|
+
npm install react react-dom react-router-dom @fluentui/react-components mermaid
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### 1. Initialize the SDK (once, at app startup)
|
|
49
|
+
|
|
50
|
+
Call `initCodicentApp()` before rendering your React tree. It stores config globally so all SDK components and hooks can read it.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
// main.tsx
|
|
54
|
+
import { initCodicentApp } from 'codicent-app-sdk';
|
|
55
|
+
import { translations } from './services/translationService';
|
|
56
|
+
import { getAppConfig } from './appconfig';
|
|
57
|
+
|
|
58
|
+
initCodicentApp({
|
|
59
|
+
API_BASE_URL: 'https://codicent.com/',
|
|
60
|
+
APP_NAME: 'my-crm',
|
|
61
|
+
APP_PREFIX: 'mycrm',
|
|
62
|
+
USER_PREFIX: 'users',
|
|
63
|
+
APP_CONFIG: getAppConfig(), // buttons, listDefinitions, chatInstructions
|
|
64
|
+
TRANSLATIONS: translations, // { sv: {...}, en: {...}, ... }
|
|
65
|
+
USE_REALTIME_SESSION_ENDPOINT: true,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Wrap with Auth0 and FluentProvider
|
|
70
|
+
|
|
71
|
+
The SDK components depend on these providers being present in the React tree:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// main.tsx (continued)
|
|
75
|
+
import { Auth0Provider } from '@auth0/auth0-react';
|
|
76
|
+
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
|
|
77
|
+
import { createRoot } from 'react-dom/client';
|
|
78
|
+
|
|
79
|
+
createRoot(document.getElementById('root')!).render(
|
|
80
|
+
<Auth0Provider domain={AUTH0_DOMAIN} clientId={AUTH0_CLIENT_ID} authorizationParams={{ redirect_uri: window.location.origin }}>
|
|
81
|
+
<FluentProvider theme={webLightTheme}>
|
|
82
|
+
<App />
|
|
83
|
+
</FluentProvider>
|
|
84
|
+
</Auth0Provider>
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Use `useCodicentApp()` in your root App component
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// App.tsx
|
|
92
|
+
import { useCodicentApp } from 'codicent-app-sdk';
|
|
93
|
+
import { useAuth0 } from '@auth0/auth0-react';
|
|
94
|
+
import { HashRouter, Routes, Route } from 'react-router-dom';
|
|
95
|
+
import { Chat } from 'codicent-app-sdk';
|
|
96
|
+
import { ListPage } from './pages/ListPage';
|
|
97
|
+
|
|
98
|
+
export default function App() {
|
|
99
|
+
const auth0 = useAuth0();
|
|
100
|
+
const state = useCodicentApp({ auth0 });
|
|
101
|
+
|
|
102
|
+
if (!auth0.isAuthenticated) {
|
|
103
|
+
auth0.loginWithRedirect();
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<HashRouter>
|
|
109
|
+
<Routes>
|
|
110
|
+
<Route path="/chat" element={<Chat state={state} title="Chat" />} />
|
|
111
|
+
<Route path="/list" element={<ListPage state={state} />} />
|
|
112
|
+
</Routes>
|
|
113
|
+
</HashRouter>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 4. Build pages using SDK components
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
// pages/ListPage.tsx
|
|
122
|
+
import { Page, Content, ListView, useLocalization, CodicentAppState, DataMessage } from 'codicent-app-sdk';
|
|
123
|
+
import { useEffect, useState } from 'react';
|
|
124
|
+
import { APP_CONFIG } from '../appconfig';
|
|
125
|
+
import { APP_BUTTONS } from '../constants';
|
|
126
|
+
|
|
127
|
+
export const ListPage: React.FC<{ state: CodicentAppState }> = ({ state }) => {
|
|
128
|
+
const { service } = state;
|
|
129
|
+
const { t } = useLocalization();
|
|
130
|
+
const [data, setData] = useState<DataMessage[]>([]);
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
service.readDataMessages('customer2').then(setData);
|
|
134
|
+
}, [service]);
|
|
135
|
+
|
|
136
|
+
const columns = APP_CONFIG.apps[APP_BUTTONS].listDefinitions['customer2'];
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<Page title={t('Kunder')}>
|
|
140
|
+
<Content>
|
|
141
|
+
<ListView data={data} columns={columns} />
|
|
142
|
+
</Content>
|
|
143
|
+
</Page>
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## `initCodicentApp()` configuration options
|
|
151
|
+
|
|
152
|
+
**Required:**
|
|
153
|
+
|
|
154
|
+
| Key | Type | Description |
|
|
155
|
+
|-----|------|-------------|
|
|
156
|
+
| `API_BASE_URL` | `string` | Codicent backend URL, e.g. `"https://codicent.com/"` |
|
|
157
|
+
| `APP_NAME` | `string` | Application identifier |
|
|
158
|
+
|
|
159
|
+
**Common optional:**
|
|
160
|
+
|
|
161
|
+
| Key | Type | Description |
|
|
162
|
+
|-----|------|-------------|
|
|
163
|
+
| `APP_PREFIX` | `string` | URL/namespace prefix for this app |
|
|
164
|
+
| `USER_PREFIX` | `string` | User namespace prefix (default: `"users"`) |
|
|
165
|
+
| `APP_CONFIG` | `AppConfig` | Per-app config: buttons, listDefinitions, chatInstructions |
|
|
166
|
+
| `TRANSLATIONS` | `object` | i18n map `{ sv: {...}, en: {...} }`. Swedish strings are used as keys. |
|
|
167
|
+
| `DEFAULT_LANGUAGE` | `string` | Default language code (e.g. `"sv"`, `"en"`) |
|
|
168
|
+
| `USE_REALTIME_SESSION_ENDPOINT` | `boolean` | Use secure backend session token for voice AI (default: `true`) |
|
|
169
|
+
| `REALTIME_VOICE_MODEL` | `string` | Voice model: `"alloy"`, `"shimmer"`, or `"echo"` (default: `"alloy"`) |
|
|
170
|
+
| `SUBSCRIPTION_NEEDED` | `boolean` | Redirect to purchase page if no active subscription |
|
|
171
|
+
| `BUTTON_BORDER_RADIUS` | `string` | CSS border-radius for nav buttons |
|
|
172
|
+
| `BUTTON_BACKGROUND_COLOR` | `string` | Background color for nav buttons |
|
|
173
|
+
|
|
174
|
+
**Compose page GPS options:**
|
|
175
|
+
|
|
176
|
+
| Key | Value | Behaviour |
|
|
177
|
+
|-----|-------|-----------|
|
|
178
|
+
| `COMPOSE_HIDE_LOCATION` | `"true"` | Hides GPS toggle button entirely |
|
|
179
|
+
| `COMPOSE_HIDE_LOCATION` | `"false"` (default) | Shows GPS toggle; users opt-in per post |
|
|
180
|
+
| `COMPOSE_AUTO_LOCATION` | `"true"` | Captures GPS automatically on page open |
|
|
181
|
+
|
|
182
|
+
When a location is attached, `#gps(lat,lon)` is appended to message content — queryable via tag search and readable by AI.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## API Reference
|
|
187
|
+
|
|
188
|
+
### `CodicentService`
|
|
189
|
+
|
|
190
|
+
The main service class for all data and chat operations. Access it via `state.service` from `useCodicentApp()`.
|
|
191
|
+
|
|
192
|
+
**Data message CRUD:**
|
|
193
|
+
```ts
|
|
194
|
+
createDataMessage(tag: string, data: object, codicent?: string): Promise<string>
|
|
195
|
+
|
|
196
|
+
readDataMessages(
|
|
197
|
+
tag: string,
|
|
198
|
+
search?: string,
|
|
199
|
+
codicent?: string,
|
|
200
|
+
start?: number,
|
|
201
|
+
length?: number,
|
|
202
|
+
afterTimestamp?: string,
|
|
203
|
+
beforeTimestamp?: string,
|
|
204
|
+
dataFilters?: Record<string, string>
|
|
205
|
+
): Promise<DataMessage[]>
|
|
206
|
+
|
|
207
|
+
readOneDataMessage(id: string): Promise<DataMessage | null>
|
|
208
|
+
|
|
209
|
+
updateDataMessage(id: string, data: object, codicent?: string): Promise<string>
|
|
210
|
+
|
|
211
|
+
deleteDataMessage(id: string, codicent?: string): Promise<string>
|
|
212
|
+
|
|
213
|
+
getSchema(tag: string, codicent?: string): Promise<object | null>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Chat and messages:**
|
|
217
|
+
```ts
|
|
218
|
+
sendMessage(message: string, parentId?: string, codicent?: string): Promise<Message>
|
|
219
|
+
chat(message: string, messageId?: string, codicent?: string): Promise<Message>
|
|
220
|
+
getMessages(tags: string[], codicent?: string, length?: number): Promise<Message[]>
|
|
221
|
+
getMessagesFast(tags: string[], search?: string, length?: number, publicCodicent?: string, codicent?: string, start?: number): Promise<Message[]>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Files:**
|
|
225
|
+
```ts
|
|
226
|
+
uploadFile(filename: string, formData: FormData): Promise<string>
|
|
227
|
+
getFileInfo(fileId: string): Promise<FileInfo>
|
|
228
|
+
static getImageUrl(fileId: string, width: number): string
|
|
229
|
+
static getFileUrl(fileId: string, extension?: string): string
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Auth and tokens:**
|
|
233
|
+
```ts
|
|
234
|
+
getToken(): string
|
|
235
|
+
generateApiToken(expires?: Date, forUserNickname?: string): Promise<string>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### `useCodicentApp(options)`
|
|
241
|
+
|
|
242
|
+
Core hook that bootstraps app state, authentication, and the `CodicentService` instance.
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
const state = useCodicentApp({
|
|
246
|
+
auth0: useAuth0(), // Required: Auth0 hook result
|
|
247
|
+
toolsConfig?: object, // Optional: custom AI tool handlers
|
|
248
|
+
authOptions?: object, // Optional: override auth behaviour
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Returns `CodicentAppState`:
|
|
253
|
+
```ts
|
|
254
|
+
{
|
|
255
|
+
service: CodicentService; // Use for all data/chat operations
|
|
256
|
+
context: StateContext; // Project nickname, user info
|
|
257
|
+
auth: UseAuthState;
|
|
258
|
+
voice?: RealtimeVoice; // Voice AI connection (when active)
|
|
259
|
+
audio: AudioRecorderState;
|
|
260
|
+
stateMachine: AppStateMachine;
|
|
261
|
+
state: string; // Current state machine state
|
|
262
|
+
nickname: string; // Active project nickname
|
|
263
|
+
error: string;
|
|
264
|
+
isBusy: () => boolean;
|
|
265
|
+
html: string; // AI-generated HTML output
|
|
266
|
+
setHtml: (html: string) => void;
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 5. Use `DataMessagePicker` for tagged record lookup
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { DataMessagePicker } from 'codicent-app-sdk';
|
|
274
|
+
|
|
275
|
+
<DataMessagePicker
|
|
276
|
+
service={state.service}
|
|
277
|
+
tag="customer2"
|
|
278
|
+
placeholder="Search customers"
|
|
279
|
+
primaryKey="Company Name"
|
|
280
|
+
displayKeys={["Company Name", "City"]}
|
|
281
|
+
secondaryKeys={["Customer Number", "City"]}
|
|
282
|
+
searchKeys={["Company Name", "Customer Number", "City"]}
|
|
283
|
+
onSelect={(selection) => {
|
|
284
|
+
console.log('Selected customer', selection.id, selection.data);
|
|
285
|
+
}}
|
|
286
|
+
/>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The picker debounces lookups through `readDataMessages(...)`, shows compact autosuggest results, and returns the raw `DataMessage` plus a normalized selection payload.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### `useLocalization()`
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
const { t, tAsync, getLanguageInfo } = useLocalization();
|
|
297
|
+
|
|
298
|
+
t('Kunder') // → "Customers" (in English)
|
|
299
|
+
await tAsync('Kunder') // → API-backed translation with fallback
|
|
300
|
+
getLanguageInfo() // → { code: 'en', name: 'English', ... }
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Swedish strings are used as keys. Pass your translation maps via `TRANSLATIONS` in `initCodicentApp()`.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
### Components
|
|
308
|
+
|
|
309
|
+
#### `Page`
|
|
310
|
+
Full-screen layout wrapper with optional header and footer.
|
|
311
|
+
```tsx
|
|
312
|
+
<Page title="Customers" hideFooter={false} audio={state.audio} voice={state.voice}>
|
|
313
|
+
<Content>...</Content>
|
|
314
|
+
</Page>
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### `Content`
|
|
318
|
+
Flex content container — use inside `Page`.
|
|
319
|
+
```tsx
|
|
320
|
+
<Content>
|
|
321
|
+
<ListView data={data} columns={columns} />
|
|
322
|
+
</Content>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### `Chat` (page)
|
|
326
|
+
Full chat UI with message history, input, typing indicators, file uploads.
|
|
327
|
+
```tsx
|
|
328
|
+
<Chat
|
|
329
|
+
state={state}
|
|
330
|
+
title="AI Assistant"
|
|
331
|
+
codicent="my-project" // Optional: override which project to chat with
|
|
332
|
+
welcomeMessage="Hi!" // Optional: shown when no messages exist
|
|
333
|
+
hideFooter={false}
|
|
334
|
+
/>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### `ListView`
|
|
338
|
+
Tabular data view with sorting, filtering, and column actions.
|
|
339
|
+
```tsx
|
|
340
|
+
import { ListView } from 'codicent-app-sdk';
|
|
341
|
+
|
|
342
|
+
<ListView
|
|
343
|
+
data={dataMessages}
|
|
344
|
+
columns={[
|
|
345
|
+
{ key: 'name', title: 'Name', filterable: true },
|
|
346
|
+
{ key: ['offer_number', 'offerNumber'], title: 'Quote #', filterable: true },
|
|
347
|
+
{ key: 'grand_total', title: 'Total', format: formatNumber },
|
|
348
|
+
{ key: 'pdf', title: 'PDF', type: 'file' },
|
|
349
|
+
]}
|
|
350
|
+
onSelect={(item) => navigate(`/chat?id=${item.originalMessageId}`)}
|
|
351
|
+
/>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Column definition options:
|
|
355
|
+
- `key: string | string[]` — JSON field name; array = fallback chain
|
|
356
|
+
- `format: (value) => string` — display transformer
|
|
357
|
+
- `filterable: true` — per-column text filter
|
|
358
|
+
- `type: "file"` — renders download link
|
|
359
|
+
- `type: "checkbox"` — renders checkbox
|
|
360
|
+
- `action` — icon button with click handler
|
|
361
|
+
|
|
362
|
+
#### `AppFrame`
|
|
363
|
+
Embeds an external URL in an iframe within the page layout.
|
|
364
|
+
```tsx
|
|
365
|
+
<AppFrame src="https://example.com/embed" title="External view" showFooter={true} />
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### `Markdown`
|
|
369
|
+
Renders markdown content including GFM and Mermaid diagrams.
|
|
370
|
+
```tsx
|
|
371
|
+
<Markdown content={message.content} />
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### `UploadFile`
|
|
375
|
+
File upload UI with progress.
|
|
376
|
+
```tsx
|
|
377
|
+
<UploadFile service={state.service} codicent="my-project" />
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### Hooks summary
|
|
383
|
+
|
|
384
|
+
| Hook | Purpose |
|
|
385
|
+
|------|---------|
|
|
386
|
+
| `useCodicentApp()` | Core app state, service, auth |
|
|
387
|
+
| `useLocalization()` | i18n translation |
|
|
388
|
+
| `useChat(service)` | Chat message state and send |
|
|
389
|
+
| `useRealtimeVoiceAI(options)` | Real-time voice AI connection |
|
|
390
|
+
| `useAuthState(auth0)` | Auth lifecycle and token |
|
|
391
|
+
| `useTheme()` | App theme/branding |
|
|
392
|
+
| `useToaster()` | Toast notification helpers |
|
|
393
|
+
| `useStateWithLocalStorage()` | Persistent local state |
|
|
394
|
+
| `useAudioRecorder()` | Microphone recording |
|
|
395
|
+
| `useTemplateVariables()` | Template string utilities |
|
|
396
|
+
| `useTools()` | AI tool handler registration |
|
|
397
|
+
| `useEmbeddings()` | Vector embedding operations |
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## TypeScript types
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
import type {
|
|
405
|
+
CodicentAppState,
|
|
406
|
+
ButtonConfig,
|
|
407
|
+
ColumnDefinition,
|
|
408
|
+
ListDefinitions,
|
|
409
|
+
DataMessage,
|
|
410
|
+
Message,
|
|
411
|
+
} from 'codicent-app-sdk';
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**`ButtonConfig`** — navigation button with optional RBAC claims:
|
|
415
|
+
```ts
|
|
416
|
+
{
|
|
417
|
+
title: string;
|
|
418
|
+
url: string; // "#/list?tag=customer2", "voice:...", "mailto:...", etc.
|
|
419
|
+
claim?: string; // Show only if user has this claim
|
|
420
|
+
notClaim?: string; // Hide if user has this claim
|
|
421
|
+
subtitle?: string;
|
|
422
|
+
options?: ButtonConfig[];
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**`DataMessage`** — result from `readDataMessages()`:
|
|
427
|
+
```ts
|
|
428
|
+
{
|
|
429
|
+
id: string;
|
|
430
|
+
originalMessageId: string; // Stable ID across updates — use this for references/tags
|
|
431
|
+
content: string; // Raw: "@project #data #tag\n{json}"
|
|
432
|
+
data: Record<string, unknown>; // Parsed JSON payload
|
|
433
|
+
tags: string[];
|
|
434
|
+
createdAt: string;
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Alternative: `createCodicentApp()` factory
|
|
441
|
+
|
|
442
|
+
For standalone deployments where you do not control the React entry point, `createCodicentApp()` wraps the full initialization (including Auth0Provider, FluentProvider, HashRouter) and renders to a DOM element:
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
import { createCodicentApp } from 'codicent-app-sdk';
|
|
446
|
+
|
|
447
|
+
const app = createCodicentApp({
|
|
448
|
+
name: 'My CRM',
|
|
449
|
+
apiBaseUrl: 'https://codicent.com/',
|
|
450
|
+
auth0: { domain: '...', clientId: '...' },
|
|
451
|
+
buttons: [
|
|
452
|
+
{ title: 'Customers', url: './#/list?tag=customer2' },
|
|
453
|
+
{ title: 'Chat', url: './#/chat' },
|
|
454
|
+
],
|
|
455
|
+
listDefinitions: {
|
|
456
|
+
customer2: [
|
|
457
|
+
{ key: 'name', title: 'Name', filterable: true },
|
|
458
|
+
{ key: 'email', title: 'Email' },
|
|
459
|
+
],
|
|
460
|
+
},
|
|
461
|
+
chatInstructions: 'You are a helpful CRM assistant.',
|
|
462
|
+
modules: { sales: true, voice: true },
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
app.render('#root');
|
|
466
|
+
// app.unmount();
|
|
467
|
+
// app.getConfig();
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
The `codicentapp/` reference implementation uses `initCodicentApp()` + manual React tree setup, which gives more control over routing and layout. `createCodicentApp()` is appropriate for simpler or standalone deployments.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Local development workflow
|
|
475
|
+
|
|
476
|
+
### Build the SDK
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
cd codicent-app-sdk
|
|
480
|
+
npm install
|
|
481
|
+
npm run build # Output: dist/cjs/, dist/esm/, dist/index.d.ts
|
|
482
|
+
npm run dev # Watch mode
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Test in codicentapp (file: reference)
|
|
486
|
+
|
|
487
|
+
In `codicentapp/package.json`:
|
|
488
|
+
```json
|
|
489
|
+
"codicent-app-sdk": "file:../codicent-app-sdk"
|
|
490
|
+
```
|
|
491
|
+
Then:
|
|
492
|
+
```bash
|
|
493
|
+
cd codicentapp
|
|
494
|
+
npm install
|
|
495
|
+
npm run build
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Test with npm link
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
# In SDK directory
|
|
502
|
+
npm link
|
|
503
|
+
|
|
504
|
+
# In your app directory
|
|
505
|
+
npm link codicent-app-sdk
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
To restore npm version:
|
|
509
|
+
```bash
|
|
510
|
+
npm uninstall codicent-app-sdk
|
|
511
|
+
npm install codicent-app-sdk
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Build output layout
|
|
515
|
+
|
|
516
|
+
```
|
|
517
|
+
dist/
|
|
518
|
+
cjs/ CommonJS modules
|
|
519
|
+
esm/ ES modules
|
|
520
|
+
index.d.ts TypeScript definitions
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Release
|
|
524
|
+
|
|
525
|
+
```bash
|
|
526
|
+
npm version patch # or minor / major
|
|
527
|
+
npm run build
|
|
528
|
+
npm publish --access public
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Debugging
|
|
534
|
+
|
|
535
|
+
The SDK emits `codicent-log` custom events on `window`:
|
|
536
|
+
|
|
537
|
+
```tsx
|
|
538
|
+
window.addEventListener('codicent-log', (event: CustomEvent) => {
|
|
539
|
+
console.log(event.detail); // { level, message, context }
|
|
540
|
+
});
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## Related
|
|
546
|
+
|
|
547
|
+
- `codicentapp/` — primary consumer; complete reference implementation
|
|
548
|
+
- `codicent-api-client/` — framework-agnostic fetch-based API client (shared with web components)
|
|
549
|
+
- `codicent-components/` — zero-build Web Components library using the same Codicent API
|
|
550
|
+
- [Voice Upgrade Guide](VOICE_UPGRADE_GUIDE.md) — real-time voice AI setup and security
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## License
|
|
555
|
+
|
|
556
|
+
MIT © Codicent Inside AB
|