@happyvertical/smrt-chat 0.56.0 → 0.56.2
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/AGENTS.md +13 -0
- package/README.md +28 -0
- package/dist/chunks/chat-stream-CahTvOic.js +2126 -0
- package/dist/chunks/chat-stream-CahTvOic.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/manifest.json +101 -7
- package/dist/smrt-knowledge.json +149 -835
- package/dist/sveltekit.js +1 -1
- package/dist/tool-loop-mcp-serializer.test-support.d.ts +7 -0
- package/dist/tool-loop-mcp-serializer.test-support.d.ts.map +1 -0
- package/dist/tool-loop.d.ts.map +1 -1
- package/package.json +21 -21
- package/dist/chunks/chat-stream-2Z1eUeEj.js +0 -2061
- package/dist/chunks/chat-stream-2Z1eUeEj.js.map +0 -1
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-chat",
|
|
6
|
-
"packageVersion": "0.56.
|
|
6
|
+
"packageVersion": "0.56.2",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
12
|
-
"agents": "
|
|
10
|
+
"manifest": "b9b7036624c4e86ca2f147c3b347807b2d525ef409df1442e9392dd6e52decc0",
|
|
11
|
+
"packageJson": "eb5da27259c829f10d97d919768ab2976fe844fb79523f7ea8dc6f8c0a6d625c",
|
|
12
|
+
"agents": "74a05bfffe21c3f63bc4289112d25054b0351f411a9de8079fc871b66caad27c",
|
|
13
13
|
"moduleDoc:agents/dev-workbench.md": "f07a428519e8cca4a46371da0a3b33b9c8d3102f1d9056e4c8efba3c0b702048",
|
|
14
14
|
"moduleDoc:agents/overview-tools.md": "752a4afb6b57a2e9224f3c65a98b0deb23cda87371f01ac0566f0887e9bb12da",
|
|
15
15
|
"moduleDoc:agents/token-streaming.md": "e92a28a8702d111a3751a86b8cdff30cb5146cc115fed86c227402bef1c683fd",
|
|
@@ -167,46 +167,6 @@
|
|
|
167
167
|
}
|
|
168
168
|
],
|
|
169
169
|
"surfaces": [
|
|
170
|
-
{
|
|
171
|
-
"kind": "api",
|
|
172
|
-
"name": "agentsessions.findActiveByParticipant",
|
|
173
|
-
"operation": "findActiveByParticipant",
|
|
174
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
175
|
-
"path": "/agentsessions/findActiveByParticipant",
|
|
176
|
-
"method": "POST"
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
"kind": "api",
|
|
180
|
-
"name": "agentsessions.findActiveSession",
|
|
181
|
-
"operation": "findActiveSession",
|
|
182
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
183
|
-
"path": "/agentsessions/findActiveSession",
|
|
184
|
-
"method": "POST"
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
"kind": "api",
|
|
188
|
-
"name": "agentsessions.findOrCreate",
|
|
189
|
-
"operation": "findOrCreate",
|
|
190
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
191
|
-
"path": "/agentsessions/findOrCreate",
|
|
192
|
-
"method": "POST"
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
"kind": "api",
|
|
196
|
-
"name": "agentsessions.findByAgent",
|
|
197
|
-
"operation": "findByAgent",
|
|
198
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
199
|
-
"path": "/agentsessions/findByAgent",
|
|
200
|
-
"method": "POST"
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
"kind": "api",
|
|
204
|
-
"name": "agentsessions.expireStale",
|
|
205
|
-
"operation": "expireStale",
|
|
206
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
207
|
-
"path": "/agentsessions/expireStale",
|
|
208
|
-
"method": "POST"
|
|
209
|
-
},
|
|
210
170
|
{
|
|
211
171
|
"kind": "cli",
|
|
212
172
|
"name": "agentsessioncollection_findActiveByParticipant",
|
|
@@ -236,35 +196,42 @@
|
|
|
236
196
|
"name": "agentsessioncollection_expireStale",
|
|
237
197
|
"operation": "expireStale",
|
|
238
198
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
239
|
-
}
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
"withheldSurfaces": [
|
|
240
202
|
{
|
|
241
|
-
"kind": "
|
|
242
|
-
"
|
|
243
|
-
"
|
|
203
|
+
"kind": "api",
|
|
204
|
+
"operation": "expireStale",
|
|
205
|
+
"code": "not-included",
|
|
206
|
+
"reason": "not listed in api.include",
|
|
244
207
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
245
208
|
},
|
|
246
209
|
{
|
|
247
|
-
"kind": "
|
|
248
|
-
"
|
|
249
|
-
"
|
|
210
|
+
"kind": "api",
|
|
211
|
+
"operation": "findActiveByParticipant",
|
|
212
|
+
"code": "not-included",
|
|
213
|
+
"reason": "not listed in api.include",
|
|
250
214
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
251
215
|
},
|
|
252
216
|
{
|
|
253
|
-
"kind": "
|
|
254
|
-
"
|
|
255
|
-
"
|
|
217
|
+
"kind": "api",
|
|
218
|
+
"operation": "findActiveSession",
|
|
219
|
+
"code": "not-included",
|
|
220
|
+
"reason": "not listed in api.include",
|
|
256
221
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
257
222
|
},
|
|
258
223
|
{
|
|
259
|
-
"kind": "
|
|
260
|
-
"name": "agentsessioncollection_findbyagent",
|
|
224
|
+
"kind": "api",
|
|
261
225
|
"operation": "findByAgent",
|
|
226
|
+
"code": "not-included",
|
|
227
|
+
"reason": "not listed in api.include",
|
|
262
228
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
263
229
|
},
|
|
264
230
|
{
|
|
265
|
-
"kind": "
|
|
266
|
-
"
|
|
267
|
-
"
|
|
231
|
+
"kind": "api",
|
|
232
|
+
"operation": "findOrCreate",
|
|
233
|
+
"code": "not-included",
|
|
234
|
+
"reason": "not listed in api.include",
|
|
268
235
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
269
236
|
}
|
|
270
237
|
],
|
|
@@ -349,46 +316,6 @@
|
|
|
349
316
|
}
|
|
350
317
|
],
|
|
351
318
|
"surfaces": [
|
|
352
|
-
{
|
|
353
|
-
"kind": "api",
|
|
354
|
-
"name": "chatmessages.getByRoom",
|
|
355
|
-
"operation": "getByRoom",
|
|
356
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
357
|
-
"path": "/chatmessages/getByRoom",
|
|
358
|
-
"method": "POST"
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
"kind": "api",
|
|
362
|
-
"name": "chatmessages.getByThread",
|
|
363
|
-
"operation": "getByThread",
|
|
364
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
365
|
-
"path": "/chatmessages/getByThread",
|
|
366
|
-
"method": "POST"
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
"kind": "api",
|
|
370
|
-
"name": "chatmessages.getByAgentSession",
|
|
371
|
-
"operation": "getByAgentSession",
|
|
372
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
373
|
-
"path": "/chatmessages/getByAgentSession",
|
|
374
|
-
"method": "POST"
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"kind": "api",
|
|
378
|
-
"name": "chatmessages.getUnreadCount",
|
|
379
|
-
"operation": "getUnreadCount",
|
|
380
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
381
|
-
"path": "/chatmessages/getUnreadCount",
|
|
382
|
-
"method": "POST"
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
"kind": "api",
|
|
386
|
-
"name": "chatmessages.getLatestPerRoom",
|
|
387
|
-
"operation": "getLatestPerRoom",
|
|
388
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
389
|
-
"path": "/chatmessages/getLatestPerRoom",
|
|
390
|
-
"method": "POST"
|
|
391
|
-
},
|
|
392
319
|
{
|
|
393
320
|
"kind": "cli",
|
|
394
321
|
"name": "chatmessagecollection_getByRoom",
|
|
@@ -424,50 +351,49 @@
|
|
|
424
351
|
"name": "chatmessagecollection_getLatestPerRoom",
|
|
425
352
|
"operation": "getLatestPerRoom",
|
|
426
353
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
427
|
-
}
|
|
354
|
+
}
|
|
355
|
+
],
|
|
356
|
+
"withheldSurfaces": [
|
|
428
357
|
{
|
|
429
|
-
"kind": "
|
|
430
|
-
"
|
|
431
|
-
"
|
|
358
|
+
"kind": "api",
|
|
359
|
+
"operation": "getByAgentSession",
|
|
360
|
+
"code": "not-included",
|
|
361
|
+
"reason": "not listed in api.include",
|
|
432
362
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
433
363
|
},
|
|
434
364
|
{
|
|
435
|
-
"kind": "
|
|
436
|
-
"
|
|
437
|
-
"
|
|
365
|
+
"kind": "api",
|
|
366
|
+
"operation": "getByRoom",
|
|
367
|
+
"code": "not-included",
|
|
368
|
+
"reason": "not listed in api.include",
|
|
438
369
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
439
370
|
},
|
|
440
371
|
{
|
|
441
|
-
"kind": "
|
|
442
|
-
"
|
|
443
|
-
"
|
|
372
|
+
"kind": "api",
|
|
373
|
+
"operation": "getByThread",
|
|
374
|
+
"code": "not-included",
|
|
375
|
+
"reason": "not listed in api.include",
|
|
444
376
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
445
377
|
},
|
|
446
378
|
{
|
|
447
|
-
"kind": "
|
|
448
|
-
"
|
|
449
|
-
"
|
|
379
|
+
"kind": "api",
|
|
380
|
+
"operation": "getLatestPerRoom",
|
|
381
|
+
"code": "not-included",
|
|
382
|
+
"reason": "not listed in api.include",
|
|
450
383
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
451
384
|
},
|
|
452
385
|
{
|
|
453
|
-
"kind": "
|
|
454
|
-
"name": "chatmessagecollection_getunreadcount",
|
|
386
|
+
"kind": "api",
|
|
455
387
|
"operation": "getUnreadCount",
|
|
388
|
+
"code": "not-included",
|
|
389
|
+
"reason": "not listed in api.include",
|
|
456
390
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
457
391
|
},
|
|
458
|
-
{
|
|
459
|
-
"kind": "mcp",
|
|
460
|
-
"name": "chatmessagecollection_getlatestperroom",
|
|
461
|
-
"operation": "getLatestPerRoom",
|
|
462
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
463
|
-
}
|
|
464
|
-
],
|
|
465
|
-
"withheldSurfaces": [
|
|
466
392
|
{
|
|
467
393
|
"kind": "api",
|
|
468
394
|
"operation": "search",
|
|
469
|
-
"code": "not-
|
|
470
|
-
"reason": "not
|
|
395
|
+
"code": "not-included",
|
|
396
|
+
"reason": "not listed in api.include",
|
|
471
397
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
472
398
|
}
|
|
473
399
|
],
|
|
@@ -569,70 +495,6 @@
|
|
|
569
495
|
}
|
|
570
496
|
],
|
|
571
497
|
"surfaces": [
|
|
572
|
-
{
|
|
573
|
-
"kind": "api",
|
|
574
|
-
"name": "chatparticipants.getByRoom",
|
|
575
|
-
"operation": "getByRoom",
|
|
576
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
577
|
-
"path": "/chatparticipants/getByRoom",
|
|
578
|
-
"method": "POST"
|
|
579
|
-
},
|
|
580
|
-
{
|
|
581
|
-
"kind": "api",
|
|
582
|
-
"name": "chatparticipants.getByProfile",
|
|
583
|
-
"operation": "getByProfile",
|
|
584
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
585
|
-
"path": "/chatparticipants/getByProfile",
|
|
586
|
-
"method": "POST"
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
"kind": "api",
|
|
590
|
-
"name": "chatparticipants.findMembership",
|
|
591
|
-
"operation": "findMembership",
|
|
592
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
593
|
-
"path": "/chatparticipants/findMembership",
|
|
594
|
-
"method": "POST"
|
|
595
|
-
},
|
|
596
|
-
{
|
|
597
|
-
"kind": "api",
|
|
598
|
-
"name": "chatparticipants.findActiveMembership",
|
|
599
|
-
"operation": "findActiveMembership",
|
|
600
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
601
|
-
"path": "/chatparticipants/findActiveMembership",
|
|
602
|
-
"method": "POST"
|
|
603
|
-
},
|
|
604
|
-
{
|
|
605
|
-
"kind": "api",
|
|
606
|
-
"name": "chatparticipants.isActiveMember",
|
|
607
|
-
"operation": "isActiveMember",
|
|
608
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
609
|
-
"path": "/chatparticipants/isActiveMember",
|
|
610
|
-
"method": "POST"
|
|
611
|
-
},
|
|
612
|
-
{
|
|
613
|
-
"kind": "api",
|
|
614
|
-
"name": "chatparticipants.getOnlineInRoom",
|
|
615
|
-
"operation": "getOnlineInRoom",
|
|
616
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
617
|
-
"path": "/chatparticipants/getOnlineInRoom",
|
|
618
|
-
"method": "POST"
|
|
619
|
-
},
|
|
620
|
-
{
|
|
621
|
-
"kind": "api",
|
|
622
|
-
"name": "chatparticipants.getAdminsInRoom",
|
|
623
|
-
"operation": "getAdminsInRoom",
|
|
624
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
625
|
-
"path": "/chatparticipants/getAdminsInRoom",
|
|
626
|
-
"method": "POST"
|
|
627
|
-
},
|
|
628
|
-
{
|
|
629
|
-
"kind": "api",
|
|
630
|
-
"name": "chatparticipants.countInRoom",
|
|
631
|
-
"operation": "countInRoom",
|
|
632
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
633
|
-
"path": "/chatparticipants/countInRoom",
|
|
634
|
-
"method": "POST"
|
|
635
|
-
},
|
|
636
498
|
{
|
|
637
499
|
"kind": "cli",
|
|
638
500
|
"name": "chatparticipantcollection_getByRoom",
|
|
@@ -680,53 +542,63 @@
|
|
|
680
542
|
"name": "chatparticipantcollection_countInRoom",
|
|
681
543
|
"operation": "countInRoom",
|
|
682
544
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
683
|
-
}
|
|
545
|
+
}
|
|
546
|
+
],
|
|
547
|
+
"withheldSurfaces": [
|
|
684
548
|
{
|
|
685
|
-
"kind": "
|
|
686
|
-
"
|
|
687
|
-
"
|
|
549
|
+
"kind": "api",
|
|
550
|
+
"operation": "countInRoom",
|
|
551
|
+
"code": "not-included",
|
|
552
|
+
"reason": "not listed in api.include",
|
|
688
553
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
689
554
|
},
|
|
690
555
|
{
|
|
691
|
-
"kind": "
|
|
692
|
-
"
|
|
693
|
-
"
|
|
556
|
+
"kind": "api",
|
|
557
|
+
"operation": "findActiveMembership",
|
|
558
|
+
"code": "not-included",
|
|
559
|
+
"reason": "not listed in api.include",
|
|
694
560
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
695
561
|
},
|
|
696
562
|
{
|
|
697
|
-
"kind": "
|
|
698
|
-
"name": "chatparticipantcollection_findmembership",
|
|
563
|
+
"kind": "api",
|
|
699
564
|
"operation": "findMembership",
|
|
565
|
+
"code": "not-included",
|
|
566
|
+
"reason": "not listed in api.include",
|
|
700
567
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
701
568
|
},
|
|
702
569
|
{
|
|
703
|
-
"kind": "
|
|
704
|
-
"
|
|
705
|
-
"
|
|
570
|
+
"kind": "api",
|
|
571
|
+
"operation": "getAdminsInRoom",
|
|
572
|
+
"code": "not-included",
|
|
573
|
+
"reason": "not listed in api.include",
|
|
706
574
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
707
575
|
},
|
|
708
576
|
{
|
|
709
|
-
"kind": "
|
|
710
|
-
"
|
|
711
|
-
"
|
|
577
|
+
"kind": "api",
|
|
578
|
+
"operation": "getByProfile",
|
|
579
|
+
"code": "not-included",
|
|
580
|
+
"reason": "not listed in api.include",
|
|
712
581
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
713
582
|
},
|
|
714
583
|
{
|
|
715
|
-
"kind": "
|
|
716
|
-
"
|
|
717
|
-
"
|
|
584
|
+
"kind": "api",
|
|
585
|
+
"operation": "getByRoom",
|
|
586
|
+
"code": "not-included",
|
|
587
|
+
"reason": "not listed in api.include",
|
|
718
588
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
719
589
|
},
|
|
720
590
|
{
|
|
721
|
-
"kind": "
|
|
722
|
-
"
|
|
723
|
-
"
|
|
591
|
+
"kind": "api",
|
|
592
|
+
"operation": "getOnlineInRoom",
|
|
593
|
+
"code": "not-included",
|
|
594
|
+
"reason": "not listed in api.include",
|
|
724
595
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
725
596
|
},
|
|
726
597
|
{
|
|
727
|
-
"kind": "
|
|
728
|
-
"
|
|
729
|
-
"
|
|
598
|
+
"kind": "api",
|
|
599
|
+
"operation": "isActiveMember",
|
|
600
|
+
"code": "not-included",
|
|
601
|
+
"reason": "not listed in api.include",
|
|
730
602
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
731
603
|
}
|
|
732
604
|
],
|
|
@@ -779,47 +651,27 @@
|
|
|
779
651
|
"returns": "Promise<object>"
|
|
780
652
|
}
|
|
781
653
|
],
|
|
782
|
-
"surfaces": [
|
|
783
|
-
|
|
784
|
-
"kind": "api",
|
|
785
|
-
"name": "chatreactions.getByMessage",
|
|
786
|
-
"operation": "getByMessage",
|
|
787
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
788
|
-
"path": "/chatreactions/getByMessage",
|
|
789
|
-
"method": "POST"
|
|
790
|
-
},
|
|
791
|
-
{
|
|
792
|
-
"kind": "api",
|
|
793
|
-
"name": "chatreactions.getReactionCounts",
|
|
794
|
-
"operation": "getReactionCounts",
|
|
795
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
796
|
-
"path": "/chatreactions/getReactionCounts",
|
|
797
|
-
"method": "POST"
|
|
798
|
-
},
|
|
654
|
+
"surfaces": [],
|
|
655
|
+
"withheldSurfaces": [
|
|
799
656
|
{
|
|
800
657
|
"kind": "api",
|
|
801
|
-
"name": "chatreactions.toggle",
|
|
802
|
-
"operation": "toggle",
|
|
803
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
804
|
-
"path": "/chatreactions/toggle",
|
|
805
|
-
"method": "POST"
|
|
806
|
-
},
|
|
807
|
-
{
|
|
808
|
-
"kind": "mcp",
|
|
809
|
-
"name": "chatreactioncollection_getbymessage",
|
|
810
658
|
"operation": "getByMessage",
|
|
659
|
+
"code": "not-included",
|
|
660
|
+
"reason": "not listed in api.include",
|
|
811
661
|
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
812
662
|
},
|
|
813
663
|
{
|
|
814
|
-
"kind": "
|
|
815
|
-
"name": "chatreactioncollection_getreactioncounts",
|
|
664
|
+
"kind": "api",
|
|
816
665
|
"operation": "getReactionCounts",
|
|
666
|
+
"code": "not-included",
|
|
667
|
+
"reason": "not listed in api.include",
|
|
817
668
|
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
818
669
|
},
|
|
819
670
|
{
|
|
820
|
-
"kind": "
|
|
821
|
-
"name": "chatreactioncollection_toggle",
|
|
671
|
+
"kind": "api",
|
|
822
672
|
"operation": "toggle",
|
|
673
|
+
"code": "not-included",
|
|
674
|
+
"reason": "not listed in api.include",
|
|
823
675
|
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
824
676
|
}
|
|
825
677
|
],
|
|
@@ -892,46 +744,6 @@
|
|
|
892
744
|
}
|
|
893
745
|
],
|
|
894
746
|
"surfaces": [
|
|
895
|
-
{
|
|
896
|
-
"kind": "api",
|
|
897
|
-
"name": "chatrooms.findByType",
|
|
898
|
-
"operation": "findByType",
|
|
899
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
900
|
-
"path": "/chatrooms/findByType",
|
|
901
|
-
"method": "POST"
|
|
902
|
-
},
|
|
903
|
-
{
|
|
904
|
-
"kind": "api",
|
|
905
|
-
"name": "chatrooms.findPublic",
|
|
906
|
-
"operation": "findPublic",
|
|
907
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
908
|
-
"path": "/chatrooms/findPublic",
|
|
909
|
-
"method": "POST"
|
|
910
|
-
},
|
|
911
|
-
{
|
|
912
|
-
"kind": "api",
|
|
913
|
-
"name": "chatrooms.findDMs",
|
|
914
|
-
"operation": "findDMs",
|
|
915
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
916
|
-
"path": "/chatrooms/findDMs",
|
|
917
|
-
"method": "POST"
|
|
918
|
-
},
|
|
919
|
-
{
|
|
920
|
-
"kind": "api",
|
|
921
|
-
"name": "chatrooms.findAgentRooms",
|
|
922
|
-
"operation": "findAgentRooms",
|
|
923
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
924
|
-
"path": "/chatrooms/findAgentRooms",
|
|
925
|
-
"method": "POST"
|
|
926
|
-
},
|
|
927
|
-
{
|
|
928
|
-
"kind": "api",
|
|
929
|
-
"name": "chatrooms.search",
|
|
930
|
-
"operation": "search",
|
|
931
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
932
|
-
"path": "/chatrooms/search",
|
|
933
|
-
"method": "POST"
|
|
934
|
-
},
|
|
935
747
|
{
|
|
936
748
|
"kind": "cli",
|
|
937
749
|
"name": "chatroomcollection_findByType",
|
|
@@ -967,50 +779,49 @@
|
|
|
967
779
|
"name": "chatroomcollection_findOrCreateDM",
|
|
968
780
|
"operation": "findOrCreateDM",
|
|
969
781
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
970
|
-
}
|
|
782
|
+
}
|
|
783
|
+
],
|
|
784
|
+
"withheldSurfaces": [
|
|
971
785
|
{
|
|
972
|
-
"kind": "
|
|
973
|
-
"
|
|
974
|
-
"
|
|
786
|
+
"kind": "api",
|
|
787
|
+
"operation": "findAgentRooms",
|
|
788
|
+
"code": "not-included",
|
|
789
|
+
"reason": "not listed in api.include",
|
|
975
790
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
976
791
|
},
|
|
977
792
|
{
|
|
978
|
-
"kind": "
|
|
979
|
-
"
|
|
980
|
-
"
|
|
793
|
+
"kind": "api",
|
|
794
|
+
"operation": "findByType",
|
|
795
|
+
"code": "not-included",
|
|
796
|
+
"reason": "not listed in api.include",
|
|
981
797
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
982
798
|
},
|
|
983
799
|
{
|
|
984
|
-
"kind": "
|
|
985
|
-
"name": "chatroomcollection_finddms",
|
|
800
|
+
"kind": "api",
|
|
986
801
|
"operation": "findDMs",
|
|
802
|
+
"code": "not-included",
|
|
803
|
+
"reason": "not listed in api.include",
|
|
987
804
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
988
805
|
},
|
|
989
806
|
{
|
|
990
|
-
"kind": "
|
|
991
|
-
"
|
|
992
|
-
"
|
|
807
|
+
"kind": "api",
|
|
808
|
+
"operation": "findOrCreateDM",
|
|
809
|
+
"code": "not-included",
|
|
810
|
+
"reason": "not listed in api.include",
|
|
993
811
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
994
812
|
},
|
|
995
813
|
{
|
|
996
|
-
"kind": "
|
|
997
|
-
"
|
|
998
|
-
"
|
|
814
|
+
"kind": "api",
|
|
815
|
+
"operation": "findPublic",
|
|
816
|
+
"code": "not-included",
|
|
817
|
+
"reason": "not listed in api.include",
|
|
999
818
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
1000
819
|
},
|
|
1001
|
-
{
|
|
1002
|
-
"kind": "mcp",
|
|
1003
|
-
"name": "chatroomcollection_findorcreatedm",
|
|
1004
|
-
"operation": "findOrCreateDM",
|
|
1005
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
1006
|
-
}
|
|
1007
|
-
],
|
|
1008
|
-
"withheldSurfaces": [
|
|
1009
820
|
{
|
|
1010
821
|
"kind": "api",
|
|
1011
|
-
"operation": "
|
|
1012
|
-
"code": "not-
|
|
1013
|
-
"reason": "not
|
|
822
|
+
"operation": "search",
|
|
823
|
+
"code": "not-included",
|
|
824
|
+
"reason": "not listed in api.include",
|
|
1014
825
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
1015
826
|
}
|
|
1016
827
|
],
|
|
@@ -1058,30 +869,6 @@
|
|
|
1058
869
|
}
|
|
1059
870
|
],
|
|
1060
871
|
"surfaces": [
|
|
1061
|
-
{
|
|
1062
|
-
"kind": "api",
|
|
1063
|
-
"name": "chatthreads.getByRoom",
|
|
1064
|
-
"operation": "getByRoom",
|
|
1065
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
1066
|
-
"path": "/chatthreads/getByRoom",
|
|
1067
|
-
"method": "POST"
|
|
1068
|
-
},
|
|
1069
|
-
{
|
|
1070
|
-
"kind": "api",
|
|
1071
|
-
"name": "chatthreads.getActive",
|
|
1072
|
-
"operation": "getActive",
|
|
1073
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
1074
|
-
"path": "/chatthreads/getActive",
|
|
1075
|
-
"method": "POST"
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
"kind": "api",
|
|
1079
|
-
"name": "chatthreads.getUnresolved",
|
|
1080
|
-
"operation": "getUnresolved",
|
|
1081
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
1082
|
-
"path": "/chatthreads/getUnresolved",
|
|
1083
|
-
"method": "POST"
|
|
1084
|
-
},
|
|
1085
872
|
{
|
|
1086
873
|
"kind": "cli",
|
|
1087
874
|
"name": "chatthreadcollection_getByRoom",
|
|
@@ -1099,23 +886,28 @@
|
|
|
1099
886
|
"name": "chatthreadcollection_getUnresolved",
|
|
1100
887
|
"operation": "getUnresolved",
|
|
1101
888
|
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
1102
|
-
}
|
|
889
|
+
}
|
|
890
|
+
],
|
|
891
|
+
"withheldSurfaces": [
|
|
1103
892
|
{
|
|
1104
|
-
"kind": "
|
|
1105
|
-
"
|
|
1106
|
-
"
|
|
893
|
+
"kind": "api",
|
|
894
|
+
"operation": "getActive",
|
|
895
|
+
"code": "not-included",
|
|
896
|
+
"reason": "not listed in api.include",
|
|
1107
897
|
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
1108
898
|
},
|
|
1109
899
|
{
|
|
1110
|
-
"kind": "
|
|
1111
|
-
"
|
|
1112
|
-
"
|
|
900
|
+
"kind": "api",
|
|
901
|
+
"operation": "getByRoom",
|
|
902
|
+
"code": "not-included",
|
|
903
|
+
"reason": "not listed in api.include",
|
|
1113
904
|
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
1114
905
|
},
|
|
1115
906
|
{
|
|
1116
|
-
"kind": "
|
|
1117
|
-
"name": "chatthreadcollection_getunresolved",
|
|
907
|
+
"kind": "api",
|
|
1118
908
|
"operation": "getUnresolved",
|
|
909
|
+
"code": "not-included",
|
|
910
|
+
"reason": "not listed in api.include",
|
|
1119
911
|
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
1120
912
|
}
|
|
1121
913
|
],
|
|
@@ -1147,19 +939,13 @@
|
|
|
1147
939
|
"returns": "Promise<VoiceGatewayTurn>"
|
|
1148
940
|
}
|
|
1149
941
|
],
|
|
1150
|
-
"surfaces": [
|
|
942
|
+
"surfaces": [],
|
|
943
|
+
"withheldSurfaces": [
|
|
1151
944
|
{
|
|
1152
945
|
"kind": "api",
|
|
1153
|
-
"name": "voicegatewayturns.reserveTurn",
|
|
1154
|
-
"operation": "reserveTurn",
|
|
1155
|
-
"objectName": "@happyvertical/smrt-chat:VoiceGatewayTurnCollection",
|
|
1156
|
-
"path": "/voicegatewayturns/reserveTurn",
|
|
1157
|
-
"method": "POST"
|
|
1158
|
-
},
|
|
1159
|
-
{
|
|
1160
|
-
"kind": "mcp",
|
|
1161
|
-
"name": "voicegatewayturncollection_reserveturn",
|
|
1162
946
|
"operation": "reserveTurn",
|
|
947
|
+
"code": "not-included",
|
|
948
|
+
"reason": "not listed in api.include",
|
|
1163
949
|
"objectName": "@happyvertical/smrt-chat:VoiceGatewayTurnCollection"
|
|
1164
950
|
}
|
|
1165
951
|
],
|
|
@@ -1203,22 +989,6 @@
|
|
|
1203
989
|
}
|
|
1204
990
|
],
|
|
1205
991
|
"surfaces": [
|
|
1206
|
-
{
|
|
1207
|
-
"kind": "api",
|
|
1208
|
-
"name": "voicesessions.getActiveById",
|
|
1209
|
-
"operation": "getActiveById",
|
|
1210
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection",
|
|
1211
|
-
"path": "/voicesessions/getActiveById",
|
|
1212
|
-
"method": "POST"
|
|
1213
|
-
},
|
|
1214
|
-
{
|
|
1215
|
-
"kind": "api",
|
|
1216
|
-
"name": "voicesessions.expireStale",
|
|
1217
|
-
"operation": "expireStale",
|
|
1218
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection",
|
|
1219
|
-
"path": "/voicesessions/expireStale",
|
|
1220
|
-
"method": "POST"
|
|
1221
|
-
},
|
|
1222
992
|
{
|
|
1223
993
|
"kind": "cli",
|
|
1224
994
|
"name": "voicesessioncollection_getActiveById",
|
|
@@ -1230,17 +1000,21 @@
|
|
|
1230
1000
|
"name": "voicesessioncollection_expireStale",
|
|
1231
1001
|
"operation": "expireStale",
|
|
1232
1002
|
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
1233
|
-
}
|
|
1003
|
+
}
|
|
1004
|
+
],
|
|
1005
|
+
"withheldSurfaces": [
|
|
1234
1006
|
{
|
|
1235
|
-
"kind": "
|
|
1236
|
-
"
|
|
1237
|
-
"
|
|
1007
|
+
"kind": "api",
|
|
1008
|
+
"operation": "expireStale",
|
|
1009
|
+
"code": "not-included",
|
|
1010
|
+
"reason": "not listed in api.include",
|
|
1238
1011
|
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
1239
1012
|
},
|
|
1240
1013
|
{
|
|
1241
|
-
"kind": "
|
|
1242
|
-
"
|
|
1243
|
-
"
|
|
1014
|
+
"kind": "api",
|
|
1015
|
+
"operation": "getActiveById",
|
|
1016
|
+
"code": "not-included",
|
|
1017
|
+
"reason": "not listed in api.include",
|
|
1244
1018
|
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
1245
1019
|
}
|
|
1246
1020
|
],
|
|
@@ -3834,46 +3608,6 @@
|
|
|
3834
3608
|
}
|
|
3835
3609
|
],
|
|
3836
3610
|
"surfaces": [
|
|
3837
|
-
{
|
|
3838
|
-
"kind": "api",
|
|
3839
|
-
"name": "agentsessions.findActiveByParticipant",
|
|
3840
|
-
"operation": "findActiveByParticipant",
|
|
3841
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
3842
|
-
"path": "/agentsessions/findActiveByParticipant",
|
|
3843
|
-
"method": "POST"
|
|
3844
|
-
},
|
|
3845
|
-
{
|
|
3846
|
-
"kind": "api",
|
|
3847
|
-
"name": "agentsessions.findActiveSession",
|
|
3848
|
-
"operation": "findActiveSession",
|
|
3849
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
3850
|
-
"path": "/agentsessions/findActiveSession",
|
|
3851
|
-
"method": "POST"
|
|
3852
|
-
},
|
|
3853
|
-
{
|
|
3854
|
-
"kind": "api",
|
|
3855
|
-
"name": "agentsessions.findOrCreate",
|
|
3856
|
-
"operation": "findOrCreate",
|
|
3857
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
3858
|
-
"path": "/agentsessions/findOrCreate",
|
|
3859
|
-
"method": "POST"
|
|
3860
|
-
},
|
|
3861
|
-
{
|
|
3862
|
-
"kind": "api",
|
|
3863
|
-
"name": "agentsessions.findByAgent",
|
|
3864
|
-
"operation": "findByAgent",
|
|
3865
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
3866
|
-
"path": "/agentsessions/findByAgent",
|
|
3867
|
-
"method": "POST"
|
|
3868
|
-
},
|
|
3869
|
-
{
|
|
3870
|
-
"kind": "api",
|
|
3871
|
-
"name": "agentsessions.expireStale",
|
|
3872
|
-
"operation": "expireStale",
|
|
3873
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection",
|
|
3874
|
-
"path": "/agentsessions/expireStale",
|
|
3875
|
-
"method": "POST"
|
|
3876
|
-
},
|
|
3877
3611
|
{
|
|
3878
3612
|
"kind": "cli",
|
|
3879
3613
|
"name": "agentsessioncollection_findActiveByParticipant",
|
|
@@ -3904,76 +3638,6 @@
|
|
|
3904
3638
|
"operation": "expireStale",
|
|
3905
3639
|
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3906
3640
|
},
|
|
3907
|
-
{
|
|
3908
|
-
"kind": "mcp",
|
|
3909
|
-
"name": "agentsessioncollection_findactivebyparticipant",
|
|
3910
|
-
"operation": "findActiveByParticipant",
|
|
3911
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3912
|
-
},
|
|
3913
|
-
{
|
|
3914
|
-
"kind": "mcp",
|
|
3915
|
-
"name": "agentsessioncollection_findactivesession",
|
|
3916
|
-
"operation": "findActiveSession",
|
|
3917
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3918
|
-
},
|
|
3919
|
-
{
|
|
3920
|
-
"kind": "mcp",
|
|
3921
|
-
"name": "agentsessioncollection_findorcreate",
|
|
3922
|
-
"operation": "findOrCreate",
|
|
3923
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3924
|
-
},
|
|
3925
|
-
{
|
|
3926
|
-
"kind": "mcp",
|
|
3927
|
-
"name": "agentsessioncollection_findbyagent",
|
|
3928
|
-
"operation": "findByAgent",
|
|
3929
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3930
|
-
},
|
|
3931
|
-
{
|
|
3932
|
-
"kind": "mcp",
|
|
3933
|
-
"name": "agentsessioncollection_expirestale",
|
|
3934
|
-
"operation": "expireStale",
|
|
3935
|
-
"objectName": "@happyvertical/smrt-chat:AgentSessionCollection"
|
|
3936
|
-
},
|
|
3937
|
-
{
|
|
3938
|
-
"kind": "api",
|
|
3939
|
-
"name": "chatmessages.getByRoom",
|
|
3940
|
-
"operation": "getByRoom",
|
|
3941
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
3942
|
-
"path": "/chatmessages/getByRoom",
|
|
3943
|
-
"method": "POST"
|
|
3944
|
-
},
|
|
3945
|
-
{
|
|
3946
|
-
"kind": "api",
|
|
3947
|
-
"name": "chatmessages.getByThread",
|
|
3948
|
-
"operation": "getByThread",
|
|
3949
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
3950
|
-
"path": "/chatmessages/getByThread",
|
|
3951
|
-
"method": "POST"
|
|
3952
|
-
},
|
|
3953
|
-
{
|
|
3954
|
-
"kind": "api",
|
|
3955
|
-
"name": "chatmessages.getByAgentSession",
|
|
3956
|
-
"operation": "getByAgentSession",
|
|
3957
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
3958
|
-
"path": "/chatmessages/getByAgentSession",
|
|
3959
|
-
"method": "POST"
|
|
3960
|
-
},
|
|
3961
|
-
{
|
|
3962
|
-
"kind": "api",
|
|
3963
|
-
"name": "chatmessages.getUnreadCount",
|
|
3964
|
-
"operation": "getUnreadCount",
|
|
3965
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
3966
|
-
"path": "/chatmessages/getUnreadCount",
|
|
3967
|
-
"method": "POST"
|
|
3968
|
-
},
|
|
3969
|
-
{
|
|
3970
|
-
"kind": "api",
|
|
3971
|
-
"name": "chatmessages.getLatestPerRoom",
|
|
3972
|
-
"operation": "getLatestPerRoom",
|
|
3973
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection",
|
|
3974
|
-
"path": "/chatmessages/getLatestPerRoom",
|
|
3975
|
-
"method": "POST"
|
|
3976
|
-
},
|
|
3977
3641
|
{
|
|
3978
3642
|
"kind": "cli",
|
|
3979
3643
|
"name": "chatmessagecollection_getByRoom",
|
|
@@ -4010,106 +3674,6 @@
|
|
|
4010
3674
|
"operation": "getLatestPerRoom",
|
|
4011
3675
|
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4012
3676
|
},
|
|
4013
|
-
{
|
|
4014
|
-
"kind": "mcp",
|
|
4015
|
-
"name": "chatmessagecollection_getbyroom",
|
|
4016
|
-
"operation": "getByRoom",
|
|
4017
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4018
|
-
},
|
|
4019
|
-
{
|
|
4020
|
-
"kind": "mcp",
|
|
4021
|
-
"name": "chatmessagecollection_getbythread",
|
|
4022
|
-
"operation": "getByThread",
|
|
4023
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4024
|
-
},
|
|
4025
|
-
{
|
|
4026
|
-
"kind": "mcp",
|
|
4027
|
-
"name": "chatmessagecollection_getbyagentsession",
|
|
4028
|
-
"operation": "getByAgentSession",
|
|
4029
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4030
|
-
},
|
|
4031
|
-
{
|
|
4032
|
-
"kind": "mcp",
|
|
4033
|
-
"name": "chatmessagecollection_search",
|
|
4034
|
-
"operation": "search",
|
|
4035
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4036
|
-
},
|
|
4037
|
-
{
|
|
4038
|
-
"kind": "mcp",
|
|
4039
|
-
"name": "chatmessagecollection_getunreadcount",
|
|
4040
|
-
"operation": "getUnreadCount",
|
|
4041
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4042
|
-
},
|
|
4043
|
-
{
|
|
4044
|
-
"kind": "mcp",
|
|
4045
|
-
"name": "chatmessagecollection_getlatestperroom",
|
|
4046
|
-
"operation": "getLatestPerRoom",
|
|
4047
|
-
"objectName": "@happyvertical/smrt-chat:ChatMessageCollection"
|
|
4048
|
-
},
|
|
4049
|
-
{
|
|
4050
|
-
"kind": "api",
|
|
4051
|
-
"name": "chatparticipants.getByRoom",
|
|
4052
|
-
"operation": "getByRoom",
|
|
4053
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4054
|
-
"path": "/chatparticipants/getByRoom",
|
|
4055
|
-
"method": "POST"
|
|
4056
|
-
},
|
|
4057
|
-
{
|
|
4058
|
-
"kind": "api",
|
|
4059
|
-
"name": "chatparticipants.getByProfile",
|
|
4060
|
-
"operation": "getByProfile",
|
|
4061
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4062
|
-
"path": "/chatparticipants/getByProfile",
|
|
4063
|
-
"method": "POST"
|
|
4064
|
-
},
|
|
4065
|
-
{
|
|
4066
|
-
"kind": "api",
|
|
4067
|
-
"name": "chatparticipants.findMembership",
|
|
4068
|
-
"operation": "findMembership",
|
|
4069
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4070
|
-
"path": "/chatparticipants/findMembership",
|
|
4071
|
-
"method": "POST"
|
|
4072
|
-
},
|
|
4073
|
-
{
|
|
4074
|
-
"kind": "api",
|
|
4075
|
-
"name": "chatparticipants.findActiveMembership",
|
|
4076
|
-
"operation": "findActiveMembership",
|
|
4077
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4078
|
-
"path": "/chatparticipants/findActiveMembership",
|
|
4079
|
-
"method": "POST"
|
|
4080
|
-
},
|
|
4081
|
-
{
|
|
4082
|
-
"kind": "api",
|
|
4083
|
-
"name": "chatparticipants.isActiveMember",
|
|
4084
|
-
"operation": "isActiveMember",
|
|
4085
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4086
|
-
"path": "/chatparticipants/isActiveMember",
|
|
4087
|
-
"method": "POST"
|
|
4088
|
-
},
|
|
4089
|
-
{
|
|
4090
|
-
"kind": "api",
|
|
4091
|
-
"name": "chatparticipants.getOnlineInRoom",
|
|
4092
|
-
"operation": "getOnlineInRoom",
|
|
4093
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4094
|
-
"path": "/chatparticipants/getOnlineInRoom",
|
|
4095
|
-
"method": "POST"
|
|
4096
|
-
},
|
|
4097
|
-
{
|
|
4098
|
-
"kind": "api",
|
|
4099
|
-
"name": "chatparticipants.getAdminsInRoom",
|
|
4100
|
-
"operation": "getAdminsInRoom",
|
|
4101
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4102
|
-
"path": "/chatparticipants/getAdminsInRoom",
|
|
4103
|
-
"method": "POST"
|
|
4104
|
-
},
|
|
4105
|
-
{
|
|
4106
|
-
"kind": "api",
|
|
4107
|
-
"name": "chatparticipants.countInRoom",
|
|
4108
|
-
"operation": "countInRoom",
|
|
4109
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection",
|
|
4110
|
-
"path": "/chatparticipants/countInRoom",
|
|
4111
|
-
"method": "POST"
|
|
4112
|
-
},
|
|
4113
3677
|
{
|
|
4114
3678
|
"kind": "cli",
|
|
4115
3679
|
"name": "chatparticipantcollection_getByRoom",
|
|
@@ -4158,136 +3722,6 @@
|
|
|
4158
3722
|
"operation": "countInRoom",
|
|
4159
3723
|
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4160
3724
|
},
|
|
4161
|
-
{
|
|
4162
|
-
"kind": "mcp",
|
|
4163
|
-
"name": "chatparticipantcollection_getbyroom",
|
|
4164
|
-
"operation": "getByRoom",
|
|
4165
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4166
|
-
},
|
|
4167
|
-
{
|
|
4168
|
-
"kind": "mcp",
|
|
4169
|
-
"name": "chatparticipantcollection_getbyprofile",
|
|
4170
|
-
"operation": "getByProfile",
|
|
4171
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4172
|
-
},
|
|
4173
|
-
{
|
|
4174
|
-
"kind": "mcp",
|
|
4175
|
-
"name": "chatparticipantcollection_findmembership",
|
|
4176
|
-
"operation": "findMembership",
|
|
4177
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4178
|
-
},
|
|
4179
|
-
{
|
|
4180
|
-
"kind": "mcp",
|
|
4181
|
-
"name": "chatparticipantcollection_findactivemembership",
|
|
4182
|
-
"operation": "findActiveMembership",
|
|
4183
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4184
|
-
},
|
|
4185
|
-
{
|
|
4186
|
-
"kind": "mcp",
|
|
4187
|
-
"name": "chatparticipantcollection_isactivemember",
|
|
4188
|
-
"operation": "isActiveMember",
|
|
4189
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4190
|
-
},
|
|
4191
|
-
{
|
|
4192
|
-
"kind": "mcp",
|
|
4193
|
-
"name": "chatparticipantcollection_getonlineinroom",
|
|
4194
|
-
"operation": "getOnlineInRoom",
|
|
4195
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4196
|
-
},
|
|
4197
|
-
{
|
|
4198
|
-
"kind": "mcp",
|
|
4199
|
-
"name": "chatparticipantcollection_getadminsinroom",
|
|
4200
|
-
"operation": "getAdminsInRoom",
|
|
4201
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4202
|
-
},
|
|
4203
|
-
{
|
|
4204
|
-
"kind": "mcp",
|
|
4205
|
-
"name": "chatparticipantcollection_countinroom",
|
|
4206
|
-
"operation": "countInRoom",
|
|
4207
|
-
"objectName": "@happyvertical/smrt-chat:ChatParticipantCollection"
|
|
4208
|
-
},
|
|
4209
|
-
{
|
|
4210
|
-
"kind": "api",
|
|
4211
|
-
"name": "chatreactions.getByMessage",
|
|
4212
|
-
"operation": "getByMessage",
|
|
4213
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
4214
|
-
"path": "/chatreactions/getByMessage",
|
|
4215
|
-
"method": "POST"
|
|
4216
|
-
},
|
|
4217
|
-
{
|
|
4218
|
-
"kind": "api",
|
|
4219
|
-
"name": "chatreactions.getReactionCounts",
|
|
4220
|
-
"operation": "getReactionCounts",
|
|
4221
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
4222
|
-
"path": "/chatreactions/getReactionCounts",
|
|
4223
|
-
"method": "POST"
|
|
4224
|
-
},
|
|
4225
|
-
{
|
|
4226
|
-
"kind": "api",
|
|
4227
|
-
"name": "chatreactions.toggle",
|
|
4228
|
-
"operation": "toggle",
|
|
4229
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection",
|
|
4230
|
-
"path": "/chatreactions/toggle",
|
|
4231
|
-
"method": "POST"
|
|
4232
|
-
},
|
|
4233
|
-
{
|
|
4234
|
-
"kind": "mcp",
|
|
4235
|
-
"name": "chatreactioncollection_getbymessage",
|
|
4236
|
-
"operation": "getByMessage",
|
|
4237
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
4238
|
-
},
|
|
4239
|
-
{
|
|
4240
|
-
"kind": "mcp",
|
|
4241
|
-
"name": "chatreactioncollection_getreactioncounts",
|
|
4242
|
-
"operation": "getReactionCounts",
|
|
4243
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
4244
|
-
},
|
|
4245
|
-
{
|
|
4246
|
-
"kind": "mcp",
|
|
4247
|
-
"name": "chatreactioncollection_toggle",
|
|
4248
|
-
"operation": "toggle",
|
|
4249
|
-
"objectName": "@happyvertical/smrt-chat:ChatReactionCollection"
|
|
4250
|
-
},
|
|
4251
|
-
{
|
|
4252
|
-
"kind": "api",
|
|
4253
|
-
"name": "chatrooms.findByType",
|
|
4254
|
-
"operation": "findByType",
|
|
4255
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
4256
|
-
"path": "/chatrooms/findByType",
|
|
4257
|
-
"method": "POST"
|
|
4258
|
-
},
|
|
4259
|
-
{
|
|
4260
|
-
"kind": "api",
|
|
4261
|
-
"name": "chatrooms.findPublic",
|
|
4262
|
-
"operation": "findPublic",
|
|
4263
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
4264
|
-
"path": "/chatrooms/findPublic",
|
|
4265
|
-
"method": "POST"
|
|
4266
|
-
},
|
|
4267
|
-
{
|
|
4268
|
-
"kind": "api",
|
|
4269
|
-
"name": "chatrooms.findDMs",
|
|
4270
|
-
"operation": "findDMs",
|
|
4271
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
4272
|
-
"path": "/chatrooms/findDMs",
|
|
4273
|
-
"method": "POST"
|
|
4274
|
-
},
|
|
4275
|
-
{
|
|
4276
|
-
"kind": "api",
|
|
4277
|
-
"name": "chatrooms.findAgentRooms",
|
|
4278
|
-
"operation": "findAgentRooms",
|
|
4279
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
4280
|
-
"path": "/chatrooms/findAgentRooms",
|
|
4281
|
-
"method": "POST"
|
|
4282
|
-
},
|
|
4283
|
-
{
|
|
4284
|
-
"kind": "api",
|
|
4285
|
-
"name": "chatrooms.search",
|
|
4286
|
-
"operation": "search",
|
|
4287
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection",
|
|
4288
|
-
"path": "/chatrooms/search",
|
|
4289
|
-
"method": "POST"
|
|
4290
|
-
},
|
|
4291
3725
|
{
|
|
4292
3726
|
"kind": "cli",
|
|
4293
3727
|
"name": "chatroomcollection_findByType",
|
|
@@ -4324,66 +3758,6 @@
|
|
|
4324
3758
|
"operation": "findOrCreateDM",
|
|
4325
3759
|
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4326
3760
|
},
|
|
4327
|
-
{
|
|
4328
|
-
"kind": "mcp",
|
|
4329
|
-
"name": "chatroomcollection_findbytype",
|
|
4330
|
-
"operation": "findByType",
|
|
4331
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4332
|
-
},
|
|
4333
|
-
{
|
|
4334
|
-
"kind": "mcp",
|
|
4335
|
-
"name": "chatroomcollection_findpublic",
|
|
4336
|
-
"operation": "findPublic",
|
|
4337
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4338
|
-
},
|
|
4339
|
-
{
|
|
4340
|
-
"kind": "mcp",
|
|
4341
|
-
"name": "chatroomcollection_finddms",
|
|
4342
|
-
"operation": "findDMs",
|
|
4343
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4344
|
-
},
|
|
4345
|
-
{
|
|
4346
|
-
"kind": "mcp",
|
|
4347
|
-
"name": "chatroomcollection_findagentrooms",
|
|
4348
|
-
"operation": "findAgentRooms",
|
|
4349
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4350
|
-
},
|
|
4351
|
-
{
|
|
4352
|
-
"kind": "mcp",
|
|
4353
|
-
"name": "chatroomcollection_search",
|
|
4354
|
-
"operation": "search",
|
|
4355
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4356
|
-
},
|
|
4357
|
-
{
|
|
4358
|
-
"kind": "mcp",
|
|
4359
|
-
"name": "chatroomcollection_findorcreatedm",
|
|
4360
|
-
"operation": "findOrCreateDM",
|
|
4361
|
-
"objectName": "@happyvertical/smrt-chat:ChatRoomCollection"
|
|
4362
|
-
},
|
|
4363
|
-
{
|
|
4364
|
-
"kind": "api",
|
|
4365
|
-
"name": "chatthreads.getByRoom",
|
|
4366
|
-
"operation": "getByRoom",
|
|
4367
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
4368
|
-
"path": "/chatthreads/getByRoom",
|
|
4369
|
-
"method": "POST"
|
|
4370
|
-
},
|
|
4371
|
-
{
|
|
4372
|
-
"kind": "api",
|
|
4373
|
-
"name": "chatthreads.getActive",
|
|
4374
|
-
"operation": "getActive",
|
|
4375
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
4376
|
-
"path": "/chatthreads/getActive",
|
|
4377
|
-
"method": "POST"
|
|
4378
|
-
},
|
|
4379
|
-
{
|
|
4380
|
-
"kind": "api",
|
|
4381
|
-
"name": "chatthreads.getUnresolved",
|
|
4382
|
-
"operation": "getUnresolved",
|
|
4383
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection",
|
|
4384
|
-
"path": "/chatthreads/getUnresolved",
|
|
4385
|
-
"method": "POST"
|
|
4386
|
-
},
|
|
4387
3761
|
{
|
|
4388
3762
|
"kind": "cli",
|
|
4389
3763
|
"name": "chatthreadcollection_getByRoom",
|
|
@@ -4402,54 +3776,6 @@
|
|
|
4402
3776
|
"operation": "getUnresolved",
|
|
4403
3777
|
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
4404
3778
|
},
|
|
4405
|
-
{
|
|
4406
|
-
"kind": "mcp",
|
|
4407
|
-
"name": "chatthreadcollection_getbyroom",
|
|
4408
|
-
"operation": "getByRoom",
|
|
4409
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
4410
|
-
},
|
|
4411
|
-
{
|
|
4412
|
-
"kind": "mcp",
|
|
4413
|
-
"name": "chatthreadcollection_getactive",
|
|
4414
|
-
"operation": "getActive",
|
|
4415
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
4416
|
-
},
|
|
4417
|
-
{
|
|
4418
|
-
"kind": "mcp",
|
|
4419
|
-
"name": "chatthreadcollection_getunresolved",
|
|
4420
|
-
"operation": "getUnresolved",
|
|
4421
|
-
"objectName": "@happyvertical/smrt-chat:ChatThreadCollection"
|
|
4422
|
-
},
|
|
4423
|
-
{
|
|
4424
|
-
"kind": "api",
|
|
4425
|
-
"name": "voicegatewayturns.reserveTurn",
|
|
4426
|
-
"operation": "reserveTurn",
|
|
4427
|
-
"objectName": "@happyvertical/smrt-chat:VoiceGatewayTurnCollection",
|
|
4428
|
-
"path": "/voicegatewayturns/reserveTurn",
|
|
4429
|
-
"method": "POST"
|
|
4430
|
-
},
|
|
4431
|
-
{
|
|
4432
|
-
"kind": "mcp",
|
|
4433
|
-
"name": "voicegatewayturncollection_reserveturn",
|
|
4434
|
-
"operation": "reserveTurn",
|
|
4435
|
-
"objectName": "@happyvertical/smrt-chat:VoiceGatewayTurnCollection"
|
|
4436
|
-
},
|
|
4437
|
-
{
|
|
4438
|
-
"kind": "api",
|
|
4439
|
-
"name": "voicesessions.getActiveById",
|
|
4440
|
-
"operation": "getActiveById",
|
|
4441
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection",
|
|
4442
|
-
"path": "/voicesessions/getActiveById",
|
|
4443
|
-
"method": "POST"
|
|
4444
|
-
},
|
|
4445
|
-
{
|
|
4446
|
-
"kind": "api",
|
|
4447
|
-
"name": "voicesessions.expireStale",
|
|
4448
|
-
"operation": "expireStale",
|
|
4449
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection",
|
|
4450
|
-
"path": "/voicesessions/expireStale",
|
|
4451
|
-
"method": "POST"
|
|
4452
|
-
},
|
|
4453
3779
|
{
|
|
4454
3780
|
"kind": "cli",
|
|
4455
3781
|
"name": "voicesessioncollection_getActiveById",
|
|
@@ -4462,18 +3788,6 @@
|
|
|
4462
3788
|
"operation": "expireStale",
|
|
4463
3789
|
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
4464
3790
|
},
|
|
4465
|
-
{
|
|
4466
|
-
"kind": "mcp",
|
|
4467
|
-
"name": "voicesessioncollection_getactivebyid",
|
|
4468
|
-
"operation": "getActiveById",
|
|
4469
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
4470
|
-
},
|
|
4471
|
-
{
|
|
4472
|
-
"kind": "mcp",
|
|
4473
|
-
"name": "voicesessioncollection_expirestale",
|
|
4474
|
-
"operation": "expireStale",
|
|
4475
|
-
"objectName": "@happyvertical/smrt-chat:VoiceSessionCollection"
|
|
4476
|
-
},
|
|
4477
3791
|
{
|
|
4478
3792
|
"kind": "api",
|
|
4479
3793
|
"name": "agentsessions.list",
|
|
@@ -5198,7 +4512,7 @@
|
|
|
5198
4512
|
"polymorphicAssociations": 0,
|
|
5199
4513
|
"uuidColumns": 78
|
|
5200
4514
|
},
|
|
5201
|
-
"agentDoc": "# @happyvertical/smrt-chat\n\nChat rooms, threads, and agent sessions with app-controlled tool whitelisting.\n\n## Dev Server\n\n`pnpm --dir packages/chat dev` runs a package-local SvelteKit workbench. The root\nroute separates **Character setup** and **Chat dev** into tabs; switching tabs\nretains the current character rig and chat state. The chat tab is an interactive\nsurface with a dev-only `/api/dev-chat` endpoint:\nit uses `@happyvertical/ai` when local provider credentials are present and\nfalls back to a deterministic local assistant otherwise. `/api/dev-chat-stream`\nis its SSE companion (#1936) — the same provider/local-fallback resolution wired\nthrough `createChatStreamHandler` in plain mode, so an embedded `SmrtChatBackend`\nclient can exercise token streaming locally. `/previews` hosts the shared\ncomponent playground entries from `src/svelte/playground.ts`.\n\nThe root route also drives the **browser inference path**\n(`@happyvertical/smrt-web/ai`: bitgpu, WebLLM, and route backends composed by\n`createInferencePath`) and an **agent-addressable draft form** (`useViewIntent`\nover `src/routes/chat-dev.intents.ts`, #2588). Their dev-config dependencies\n(static optional-peer imports, `workspace-aliases.js` prefix rules, the theme\nstylesheet import) and the stage→apply tool-call gotchas are in\n[agents/dev-workbench.md](agents/dev-workbench.md).\n\nDev-only voice and opt-in local character persistence are documented in\n[agents/dev-workbench.md](agents/dev-workbench.md#voice-and-local-character-persistence).\nThese endpoints are loopback-only demos; production hosts supply authenticated\nprincipals, tenancy, and authorization to the owning services.\n\n## Models\n\nAll seven models expose only generated REST/MCP `list`/`get`; structural tests\ncheck the registry for accidental mutating operations. Writes go through\nmembership/owner-checked `ChatService` or the binding-checked voice adapter.\n\n`ChatService` is a closed facade. Its collections and security-sensitive\nhelpers use ES `#private` fields/methods (TypeScript `private` is erased).\nCollection classes are not exported from the package index. The agent-reply\nbridge is a Symbol-keyed static accessible through a non-exported symbol held\nby the module-local `sendAgentReply` function.\n\n- **ChatRoom**: `roomType` (public/private/dm/agent), `status`, `topic`, `maxParticipants`, `lastMessageAt`. Tenant-scoped (required).\n- **ChatMessage**: shared by users + agents. `role` (user/assistant/system/tool), `messageType` (text/system/action/file/tool_call/tool_result), `toolCallData` JSON. Unified model — no separate agent message type. Tenant-scoped (required).\n- **ChatParticipant**: `role` (owner/admin/member/viewer), `onlineStatus`, `lastReadMessageId`, `isMuted`. Tenant-scoped (required).\n- **ChatThread**: `rootMessageId`, `isResolved`, `messageCount`. Created via `ChatService.startThread()` (member-checked). Tenant-scoped (required).\n- **ChatReaction**: `messageId`, `profileId`, `emoji`. Added/removed via `ChatService.addReaction()`/`removeReaction()` (member-checked, self-keyed). Tenant-scoped (required).\n- **AgentSession**: `agentId` (application slug, string ref, not FK), `agentProfileId` (nullable `crossPackageRef` to `Profile` — the `bot` profile the agent AUTHORS as, #2995), `allowedTools` (JSON string array), `sessionContext` (JSON, sensitive), `systemPrompt`, limits (`maxTokens`/`maxMessages`/`expiresAt`). Optional tenancy.\n- **VoiceSession**: short-lived voice-gateway binding over `(tenant, actorProfileId, personaId, room/thread/agentSession)` plus a persona snapshot, gateway `session_id`, expiry, replay tracking, and metadata. Tenant-scoped (required). Generated surface is read-only; creation and turns go through `createVoiceChatSession()` / `handleVoiceGatewayTurn()`.\n\n## ChatService\n\nPublic writes take server-supplied `actorProfileId`; never trust a request's\n`senderProfileId`, `role`, owner id, or participant id as authority.\n\n| Operation | Authorization and behavior |\n|---|---|\n| `sendMessage()` | Room member; authors as actor with `role: 'user'`; no public membership bypass |\n| `createRoom()` | Actor becomes owner |\n| `startThread()` | Member; optional root message bound to room and tenant |\n| `addParticipant()` / `removeParticipant()` | Owner/admin; self-leave allowed |\n| `updateRoom()` | Owner/admin |\n| `addReaction()` / `removeReaction()` | Member; self-keyed |\n| `getOrCreateDM()` | Actor must be a DM participant |\n| `createAgentSession()` | Actor becomes session participant; existing-session lookup tenant-bound; optional `sessionKey` isolates conversation subjects |\n| `updateAgentSessionConfig()` | Owner; mandatory tenant-bound lookup |\n| `sendAgentUserMessage()` | Actor must be session participant; authored as participant |\n\nRead facade: `getAgentSession({agentSessionId, tenantId})`,\n`findActiveAgentSessions({tenantId, agentId, participantProfileId})`, and\n`getThread({threadId, tenantId})` are tenant-bound; consumers still check\nownership/context. `listRoomThreads({roomId, actorProfileId, tenantId})`,\n`getThreadMessages({threadId, actorProfileId, tenantId, limit?})` (chronological),\n`getRoomMessages({roomId, actorProfileId, tenantId})`, and\n`getRoomForMember(roomId, actorProfileId, tenantId)` additionally require\nmembership of the server-supplied actor, not a caller-selected subject.\n\nTrusted agent runtime imports `sendAgentReply(service, params)` only from\n`@happyvertical/smrt-chat/internal/agent-runtime`. It is not a `ChatService`\nmethod or package-index export. It authors as `session.agentProfileId` — the\nagent's resolved `bot` Profile, NEVER the `agentId` slug (#2995) — accepts a\nsame-room/tenant thread, and enforces `allowedTools` fail-closed.\n\nPrivate `#writeMessage` alone can select arbitrary authors/roles or bypass\nmembership. It binds every supplied `threadId`, `agentSessionId`, and\n`replyToMessageId` to the same room **and** tenant. Internal enrollment supports\nautomatically created rooms, sessions, and participants.\n\n## Agent Tool Whitelisting\n\n`allowedTools` is a JSON array controlled by the consuming app. Fail-closed: an empty/unparseable whitelist permits NO tools. The internal `sendAgentReply(service, params)` function enforces the whitelist before emitting any `tool`/`tool_call` message; a caller cannot supply a `senderProfileId`/`role` to post as the agent, and the function is not reachable from the package index.\n\nPrincipal-bound data discovery and reads are available as `PrincipalTool[]` via\n`createDataSurfaceTools()` (re-exported by the chat package). Pass the tools as\n`extraTools` to the persona conversation/tool loop. They use the same\nfail-closed `allowedTools` offer/execution gates; RBAC, tenant, redaction,\nbounded query results, and audit authority remain in the authenticated\n`PrincipalRun` supplied by `@happyvertical/smrt-agents`.\n\n## Runtime report tools (#3711)\n\n`createRuntimeReportTools()` (`runtime-report-tools.ts`) returns four\n`PrincipalTool`s for the persona `extraTools` seam: `reports.runtime.sources`,\n`reports.runtime.define` (`preview` / `apply`), `reports.runtime.list`, and\n`reports.runtime.run`. The model supplies only a declarative\n`RuntimeReportSpec` from `@happyvertical/smrt-reports`; sources are a\nserver-owned allow-list gated by `run.assertOperation(collection, 'read')`, and\nfield policy, `readPermission`, and tenancy are enforced by the compiler against\nthe live run on every compile and every stored-report run. `apply` needs the\n`specHash` of the previewed spec plus an app-owned `confirmation` host that\nresolves only after a human approved that exact spec; with no host apply returns an `awaiting_confirmation` proposal for the\nsame-origin browser confirm route and stores nothing and a model-supplied `confirmed` flag is ignored. Saving also needs\n`create` on the `RuntimeReport` collection, and `list`/`run` need `read`; the\ndefault `reportsCollection` is the `RuntimeReport` class itself, which resolves\nto the catalog slug. A string `collection`/`reportsCollection` is used verbatim\nas a catalog slug (never a class name); tests must run the tools under the real\n`assertOperationPermission` guard so a wrong slug fails. A stored report is\nwritten only by this confirmed `apply`: the model layer refuses every other\ninsert/spec change, and the generic manifest tools (`buildManifestToolCatalog`,\n`invokeManifestTool`) never offer or run a `RuntimeReport` write. Stored-report\nreads/saves run under the principal's tenant (`withPrincipalTenant`), refuse a\nmismatching ambient tenant (checked before `confirmSave`), and filter by the principal tenant explicitly. Contract and authority model:\n[`packages/reports/agents/runtime-reports.md`](../reports/agents/runtime-reports.md).\n\n## Overview tools (#3727)\n\n`createOverviewTools({ host })` (`overview-tools.ts`) returns\n`overviews.describe`, `overviews.apply` (an atomic batch of structured widget\noperations) and `overviews.undo` (single step, keyed by tenant, user and page).\nThe host opens a page per `PrincipalRun` (smrt-svelte's\n`createOverviewAssistantSurface`, typed structurally here); validation and\n`canCustomize` are the surface's. Contract:\n[agents/overview-tools.md](agents/overview-tools.md).\n\n## Conversational Harness (L3, #1891)\n\nThe `AgentSession` runtime depends on personas, agents, and users. Keep those\nedges acyclic: none of those packages may depend back on chat.\n\n- **`runToolLoop(options)`** (`tool-loop.ts`) — a bounded `tool_call → observe → respond` loop. Tools are **manifest operations** of installed packages: `buildManifestToolCatalog({ allowedTools })` reads the `PermissionCatalogService` catalog and keeps only the `(collection, action)` entries named in the persona's allow-list (the **offer gate**; absent/empty ⇒ NO tools). The loop runs inside one `executeAsPrincipal` context, and `invokeManifestTool` executes each op **in-process (\"side door\")** against `run.context.database` (the RLS tx when Postgres RLS is on), after re-asserting the fail-closed allow-list (`run.assertToolAllowed`) AND the catalog permission (`run.assertOperation`) — the **execution gate**. Bounded by a max-steps ceiling (`DEFAULT_MAX_STEPS = 8`): on the ceiling it disables tools for one final completion so the turn always terminates with text. A thrown tool error is classified (`classifyToolError`): permission denials and 401/403 are `not_permitted`; a `ValidationError` or 400/404/409/422 is `invalid_request` (observation: actionable message, `publicMessage` first, `code`, fix-and-retry hint); else (incl. 429) `execution_error`.\n- **`runPersonaConversationTurn(options)`** (`persona-conversation.ts`) — binds a conversation to an `AgentPersona`/`ResolvedPersona`: runs as its principal (`runAsUserId`), offers only its `allowedTools`, speaks its instructions (`resolvePersonaInstructions`, layering approved learned directives), and injects its **recalled learning memory** (`personaLearningMemory`, isolated per `memoryScope`) into the system prompt. `bindPersonaToSession()` mirrors the persona's `allowedTools`/instructions onto the `AgentSession` so the chat authoring gate agrees with the loop's offer gate. Authors the reply (and each executed tool) via the internal `sendAgentReply` bridge. Tools run with the run-as user's **live** permissions unless the host passes a `permissions` snapshot (#2978), which `runToolLoop` forwards to `executeAsPrincipal` so a narrowed principal (e.g. a shared station) cannot reach grants — such as `readPermission`-gated data-surface fields — beyond that snapshot, including through `agents.invoke` delegation (the snapshot becomes the worker's permission ceiling).\n- **Agent orchestration** (L3, #1892) — the loop accepts non-manifest **`extraTools`** (`PrincipalTool[]`, from `@happyvertical/smrt-agents`), gated by the *same* fail-closed allow-list. The standard **`invoke-agent`** tool (`createInvokeAgentTool`, slug `agents.invoke`) lets a conversational agent delegate to a **worker agent under its own principal** — the worker runs via `executeAsPrincipal` as the originating user (never its own authority), the principal is immutable along the chain, and its completion is surfaced back into the conversation. `runPersonaConversationTurn` filters `extraTools` by the persona's `allowedTools` (offer gate); the tool's `execute` re-asserts `assertToolAllowed` (execution gate). See `@happyvertical/smrt-agents` for the delegation envelope + transports.\n- **Chat feedback capture** (`chat-feedback.ts`) — `captureChatFeedback()` + `acceptAppliedChange`/`rejectAppliedChange`/`correctResponse`/`rateResponse`/`thumbsUp`/`thumbsDown` write a `Feedback` row (personas) carrying the conversation's **correlation-id**, and (by default) reinforce the persona's learning memory (`reinforceFromFeedback`). So an in-chat reject decays a strategy below the reuse floor and it stops being recalled; a correction supersedes its stored value.\n\n## Voice Gateway Turns (#1910)\n\nVoice is an input mode for the existing persona chat harness, not a separate chat runtime. `createVoiceChatSession()` creates a short-lived `VoiceSession` for an authenticated actor/profile, binding tenant, persona, agent session, room, and optional thread. `handleVoiceGatewayTurn()` resolves that binding from `metadata.voiceSessionId`, checks the gateway's `session_id` and any supplied tenant/profile/persona/session/thread metadata against the server-side binding, persists the transcript through `ChatService.sendAgentUserMessage()`, runs `runPersonaConversationTurn()`, stamps voice/correlation metadata onto the persisted user/assistant/tool messages, records the gateway `turn_id`, and returns the gateway response contract. The Fetch-compatible `createVoiceGatewayTurnHandler()` adds the coarse gateway bearer-token check.\n\nThe gateway bearer token proves only \"this request came from the gateway\"; it never authorizes the end user. The short-lived `VoiceSession` binding is the user/session proof, and untrusted gateway metadata must be validated against that binding before any chat write or tool loop. Tool execution remains fail-closed through the persona allow-list mirrored onto `AgentSession` by `bindPersonaToSession()`.\n\n## Token streaming\n\n`chat-stream.ts` serves browser-safe SSE through `./client`. The host's\n`authorize(request, body)` is the sole trust boundary: resolve identity, tenant,\ncapabilities, and generation limits server-side; never authorize from request\nsession metadata. Persona turns reuse the principal and fail-closed tool gates.\nThe engine and browser-safe `SmrtChatBackend` keep custom-tool resolution\nserver-side. See [agents/token-streaming.md](agents/token-streaming.md) for the\nevent contract, CORS policy, and streaming behavior.\n\n## Streamed assistant turns with browser tools (#2908)\n\n`runAssistantTurn()` (`assistant-turn.ts`) is the host-route engine for the\nAssistantDock: one turn over `runToolLoop` with server tools (offer-gated by\n`principal.allowedTools`), browser tools (validated by\n`sanitizeClientToolDeclarations` + a server allow-list), `maxSteps`, `signal`,\nand `onUsage`. A browser tool call SUSPENDS the turn (`stoppedReason:\n'client_tools'`); the transcript waits in an `AssistantContinuationStore`\n(single-use, 15-minute TTL; `createSessionContinuationStore` keeps it in the\nAgentSession's `sessionContext`) and the browser resumes it with results,\nwhich reach the model wrapped `untrusted`. `createAssistantTurnResponse`\nserves the events as SSE; `assistant-turn-events.ts` is the browser-safe wire\ncontract (`./assistant-turn` subpath, also a vite library entry because the\nSvelte dock imports it). The dock decides whether a browser call runs or waits\nfor the user from the page registry, never the server's echo; destructive\nalways waits. Details: [`docs/assistant-dock.md`](../../docs/assistant-dock.md).\n\n## AssistantDock (#2904)\n\n`AssistantDock` (`svelte/components/assistant/`, exported from `./svelte`)\nuses a host `DataSurfaceRegistry`'s mounted descriptors (none: plain chat).\nActions: `normalizeDataSurfaceActionRequest` → `AssistantActionClient`\n(preview/apply over a server `DataSurfaceActionAdapter`, not the\n`data-surface-bridge.ts` channel). Generated `ChatThread`/`ChatMessage`\n`list`/`get` are tenant- not member-scoped; the dock never calls them.\n\n**Server routes (#3368).** `./sveltekit` `mountAssistantRoutes()` serves the\ndock from one `[...path]` route; `createAssistantHttp{Transport,ActionClient}`\n(`./svelte`) are its browser half. Principal from `event.locals` or\n`resolvePrincipal`; threads only from the actor's keyed session room in that\ntenant (else 404). `allowedTools` is fail-closed; without `tools` it offers\nthose manifest ops (an unprovided name is an error, #3414). `ai` defaults to\nthe config `ai` block. Pass `runtime`: a turn never keeps the RLS request tx\n(own `runAsPrincipal` tx). `clientRequestId` makes the row id a UUIDv5\n(`clientRequestMessageId`): the PK is the retry reservation. See\n[docs](../../docs/assistant-dock.md).\n\n## Recipes (#3719)\n\n`src/recipes.ts` declares `chat.assistant` (the AssistantDock as a `header.end`\nshell widget, an `llm` provider, runtime `both`; help in\n`src/assistant.recipe.md`). Keep each recipe class self-contained. Details:\n[agents/recipes.md](agents/recipes.md).\n\n## Gotchas\n\n- **sessionContext, not context**: `context` is reserved for slug scoping. Use `getSessionContext()`/`updateSessionContext()` for agent memory.\n- **Agent rooms auto-created**: `roomType: 'agent'`, `maxParticipants` defaults to 2; the agent is enrolled as a member so its replies pass the membership check. `createAgentSession()` re-enrolls the participant AND the agent on the existing-session path, so legacy sessions created before the agent was enrolled self-heal.\n- **The agent's author is a Profile, not `agentId` (#2995)**: `senderProfileId`/`profileId` are `crossPackageRef`s to `Profile` and therefore uuid columns on PostgreSQL, so the slug fails the cast (`22P02`) and no agent reply can persist. `createAgentSession()` resolves the agent's `bot` Profile through `resolveAgentProfile()` in `@happyvertical/smrt-profiles` (created on first use, tenant-bound) and records it as `AgentSession.agentProfileId`; both enrolment and `sendAgentReply` use that uuid. A consumer whose agent already has an acting identity passes `agentProfileId` to skip resolution — the voice path does this with the persona's `actsAsProfileId`, so persona replies stay attributed to the configured acting profile. Like `actorProfileId`, `agentProfileId` is SERVER-supplied, never request input: it selects the author of every later assistant message. It is validated (`#requireAgentProfile`) to exist and be visible in the tenant and to differ from the acting participant, and it can never re-point a session that already resolved one — only a pre-#2995 session with none is backfilled. **Migration**: `agent_profile_id` is an ordinary additive manifest field, so a consumer adopts it the same way as any other — `smrt db:migrate` generates and applies the column from the manifest, and `db:status --parity` verifies it; the framework never creates application schema at runtime. It is nullable and needs no offline DATA backfill — a session created before #2995 resolves and persists its `agentProfileId`, and re-enrols the agent, on its first agent turn after the upgrade. Two pre-#2995 cohorts: a session whose `agentId` is an ordinary slug never committed an author on PostgreSQL (the cast failed), so there is nothing to repair there, while SQLite/DuckDB may hold `chat_messages`/`chat_participants` rows whose id column holds the slug — readable, but not joinable to `profiles`. A session whose `agentId` is already a Profile uuid (the voice path used to collapse a persona's `actsAsProfileId` into it) DID commit on PostgreSQL; that profile is ADOPTED as the author, tenant-checked and never the participant, so the conversation's author does not change and the two-seat room gains no third identity. Known one-time effect: because `voice.ts` no longer derives `agentId` from `actsAsProfileId`, a keyless `createVoiceChatSession()` for such a persona opens a new session and room instead of reusing the legacy one; the old room and its messages stay intact and readable, and resuming with an explicit `agentSessionId` is unaffected.\n- **Only SQLite-backed tests would miss this class of bug**: uuid columns accept any text on SQLite. `src/__tests__/agent-reply-postgres.test.ts` (`pnpm --filter @happyvertical/smrt-chat test:postgres`) pins the agent-reply path against real PostgreSQL. That suite runs in `postgres-tests.yml` on every same-repository PR and merge group (#2659); keep a cheap SQLite assertion alongside it anyway, since the default lane is SQLite-only (`chat-service.test.ts` asserts the author is the profile uuid, not the slug).\n- **Per-subject sessions need `sessionKey`**: `createAgentSession()` reuses ANY active session for the same `(agentId, participantProfileId, tenantId)`. Callers that open separate conversations per subject (e.g. one content-editor session per content id) MUST pass a stable `sessionKey` (stored in `sessionContext.__sessionKey`, read via `AgentSession.getSessionKey()`); otherwise a session opened for one subject is reused and its context overwritten for another, surfacing the wrong room/threads (S5 #1392). A keyed create never reuses a keyless/legacy session.\n- **Session expiry**: check `isActive()` before allowing messages (expiresAt or limit-based)\n- **DM identity**: derived from the deterministic per-tenant `canonicalDmRoomId()` and the authoritative `chat_participants` join, not client metadata; concurrent creates upsert onto one row.\n- **Tenant-bound lookups**: membership/session/DM lookups REQUIRE `tenantId` and always bind it into the WHERE clause (`findActiveMembership`/`isActiveMember`/`findActiveSession` take a required `tenantId`; AgentSession's `null` tenant is an explicit bound scope, not \"any tenant\") so they can never resolve a row from another tenant.\n",
|
|
4515
|
+
"agentDoc": "# @happyvertical/smrt-chat\n\nChat rooms, threads, and agent sessions with app-controlled tool whitelisting.\n\n## Dev Server\n\n`pnpm --dir packages/chat dev` runs a package-local SvelteKit workbench. The root\nroute separates **Character setup** and **Chat dev** into tabs; switching tabs\nretains the current character rig and chat state. The chat tab is an interactive\nsurface with a dev-only `/api/dev-chat` endpoint:\nit uses `@happyvertical/ai` when local provider credentials are present and\nfalls back to a deterministic local assistant otherwise. `/api/dev-chat-stream`\nis its SSE companion (#1936) — the same provider/local-fallback resolution wired\nthrough `createChatStreamHandler` in plain mode, so an embedded `SmrtChatBackend`\nclient can exercise token streaming locally. `/previews` hosts the shared\ncomponent playground entries from `src/svelte/playground.ts`.\n\nThe root route also drives the **browser inference path**\n(`@happyvertical/smrt-web/ai`: bitgpu, WebLLM, and route backends composed by\n`createInferencePath`) and an **agent-addressable draft form** (`useViewIntent`\nover `src/routes/chat-dev.intents.ts`, #2588). Their dev-config dependencies\n(static optional-peer imports, `workspace-aliases.js` prefix rules, the theme\nstylesheet import) and the stage→apply tool-call gotchas are in\n[agents/dev-workbench.md](agents/dev-workbench.md).\n\nDev-only voice and opt-in local character persistence are documented in\n[agents/dev-workbench.md](agents/dev-workbench.md#voice-and-local-character-persistence).\nThese endpoints are loopback-only demos; production hosts supply authenticated\nprincipals, tenancy, and authorization to the owning services.\n\n## Models\n\nAll seven models expose only generated REST/MCP `list`/`get`; structural tests\ncheck the registry for accidental mutating operations. Writes go through\nmembership/owner-checked `ChatService` or the binding-checked voice adapter.\n\n`ChatService` is a closed facade. Its collections and security-sensitive\nhelpers use ES `#private` fields/methods (TypeScript `private` is erased).\nCollection classes are not exported from the package index. The agent-reply\nbridge is a Symbol-keyed static accessible through a non-exported symbol held\nby the module-local `sendAgentReply` function.\n\n- **ChatRoom**: `roomType` (public/private/dm/agent), `status`, `topic`, `maxParticipants`, `lastMessageAt`. Tenant-scoped (required).\n- **ChatMessage**: shared by users + agents. `role` (user/assistant/system/tool), `messageType` (text/system/action/file/tool_call/tool_result), `toolCallData` JSON. Unified model — no separate agent message type. Tenant-scoped (required).\n- **ChatParticipant**: `role` (owner/admin/member/viewer), `onlineStatus`, `lastReadMessageId`, `isMuted`. Tenant-scoped (required).\n- **ChatThread**: `rootMessageId`, `isResolved`, `messageCount`. Created via `ChatService.startThread()` (member-checked). Tenant-scoped (required).\n- **ChatReaction**: `messageId`, `profileId`, `emoji`. Added/removed via `ChatService.addReaction()`/`removeReaction()` (member-checked, self-keyed). Tenant-scoped (required).\n- **AgentSession**: `agentId` (application slug, string ref, not FK), `agentProfileId` (nullable `crossPackageRef` to `Profile` — the `bot` profile the agent AUTHORS as, #2995), `allowedTools` (JSON string array), `sessionContext` (JSON, sensitive), `systemPrompt`, limits (`maxTokens`/`maxMessages`/`expiresAt`). Optional tenancy.\n- **VoiceSession**: short-lived voice-gateway binding over `(tenant, actorProfileId, personaId, room/thread/agentSession)` plus a persona snapshot, gateway `session_id`, expiry, replay tracking, and metadata. Tenant-scoped (required). Generated surface is read-only; creation and turns go through `createVoiceChatSession()` / `handleVoiceGatewayTurn()`.\n\n## ChatService\n\nPublic writes take server-supplied `actorProfileId`; never trust a request's\n`senderProfileId`, `role`, owner id, or participant id as authority.\n\n| Operation | Authorization and behavior |\n|---|---|\n| `sendMessage()` | Room member; authors as actor with `role: 'user'`; no public membership bypass |\n| `createRoom()` | Actor becomes owner |\n| `startThread()` | Member; optional root message bound to room and tenant |\n| `addParticipant()` / `removeParticipant()` | Owner/admin; self-leave allowed |\n| `updateRoom()` | Owner/admin |\n| `addReaction()` / `removeReaction()` | Member; self-keyed |\n| `getOrCreateDM()` | Actor must be a DM participant |\n| `createAgentSession()` | Actor becomes session participant; existing-session lookup tenant-bound; optional `sessionKey` isolates conversation subjects |\n| `updateAgentSessionConfig()` | Owner; mandatory tenant-bound lookup |\n| `sendAgentUserMessage()` | Actor must be session participant; authored as participant |\n\nRead facade: `getAgentSession({agentSessionId, tenantId})`,\n`findActiveAgentSessions({tenantId, agentId, participantProfileId})`, and\n`getThread({threadId, tenantId})` are tenant-bound; consumers still check\nownership/context. `listRoomThreads({roomId, actorProfileId, tenantId})`,\n`getThreadMessages({threadId, actorProfileId, tenantId, limit?})` (chronological),\n`getRoomMessages({roomId, actorProfileId, tenantId})`, and\n`getRoomForMember(roomId, actorProfileId, tenantId)` additionally require\nmembership of the server-supplied actor, not a caller-selected subject.\n\nTrusted agent runtime imports `sendAgentReply(service, params)` only from\n`@happyvertical/smrt-chat/internal/agent-runtime`. It is not a `ChatService`\nmethod or package-index export. It authors as `session.agentProfileId` — the\nagent's resolved `bot` Profile, NEVER the `agentId` slug (#2995) — accepts a\nsame-room/tenant thread, and enforces `allowedTools` fail-closed.\n\nPrivate `#writeMessage` alone can select arbitrary authors/roles or bypass\nmembership. It binds every supplied `threadId`, `agentSessionId`, and\n`replyToMessageId` to the same room **and** tenant. Internal enrollment supports\nautomatically created rooms, sessions, and participants.\n\n## Agent Tool Whitelisting\n\n`allowedTools` is a JSON array controlled by the consuming app. Fail-closed: an empty/unparseable whitelist permits NO tools. The internal `sendAgentReply(service, params)` function enforces the whitelist before emitting any `tool`/`tool_call` message; a caller cannot supply a `senderProfileId`/`role` to post as the agent, and the function is not reachable from the package index.\n\nPrincipal-bound data discovery and reads are available as `PrincipalTool[]` via\n`createDataSurfaceTools()` (re-exported by the chat package). Pass the tools as\n`extraTools` to the persona conversation/tool loop. They use the same\nfail-closed `allowedTools` offer/execution gates; RBAC, tenant, redaction,\nbounded query results, and audit authority remain in the authenticated\n`PrincipalRun` supplied by `@happyvertical/smrt-agents`.\n\n## Commerce money tools (#3937)\n\nHosts that offer invoice money work must explicitly register\n`createCommerceMoneyTools()` from `@happyvertical/smrt-commerce` in\ntheir authenticated assistant route's `extraTools` (for example, `extraTools: () => createCommerceMoneyTools()`) and\nadd only the desired `commerce.*` slugs to the persona's `allowedTools`.\nThey are not generic manifest CRUD tools: tax codes are selected by code,\npreview is calculator-only, and line writes run through the document-money\ncoordinator. Each execution reasserts the principal allow-list and required\n`Invoice`, `InvoiceLineItem`, `DocumentTax`, and `TaxCode` operations. The\ngenerated MCP invoice `get` serializer remains commerce-owned; use its\nstored-facts integration when that serializer exposes `DocumentTax` rows.\n\n## Runtime report tools (#3711)\n\n`createRuntimeReportTools()` (`runtime-report-tools.ts`) returns four\n`PrincipalTool`s for the persona `extraTools` seam: `reports.runtime.sources`,\n`reports.runtime.define` (`preview` / `apply`), `reports.runtime.list`, and\n`reports.runtime.run`. The model supplies only a declarative\n`RuntimeReportSpec` from `@happyvertical/smrt-reports`; sources are a\nserver-owned allow-list gated by `run.assertOperation(collection, 'read')`, and\nfield policy, `readPermission`, and tenancy are enforced by the compiler against\nthe live run on every compile and every stored-report run. `apply` needs the\n`specHash` of the previewed spec plus an app-owned `confirmation` host that\nresolves only after a human approved that exact spec; with no host apply returns an `awaiting_confirmation` proposal for the\nsame-origin browser confirm route and stores nothing and a model-supplied `confirmed` flag is ignored. Saving also needs\n`create` on the `RuntimeReport` collection, and `list`/`run` need `read`; the\ndefault `reportsCollection` is the `RuntimeReport` class itself, which resolves\nto the catalog slug. A string `collection`/`reportsCollection` is used verbatim\nas a catalog slug (never a class name); tests must run the tools under the real\n`assertOperationPermission` guard so a wrong slug fails. A stored report is\nwritten only by this confirmed `apply`: the model layer refuses every other\ninsert/spec change, and the generic manifest tools (`buildManifestToolCatalog`,\n`invokeManifestTool`) never offer or run a `RuntimeReport` write. Stored-report\nreads/saves run under the principal's tenant (`withPrincipalTenant`), refuse a\nmismatching ambient tenant (checked before `confirmSave`), and filter by the principal tenant explicitly. Contract and authority model:\n[`packages/reports/agents/runtime-reports.md`](../reports/agents/runtime-reports.md).\n\n## Overview tools (#3727)\n\n`createOverviewTools({ host })` (`overview-tools.ts`) returns\n`overviews.describe`, `overviews.apply` (an atomic batch of structured widget\noperations) and `overviews.undo` (single step, keyed by tenant, user and page).\nThe host opens a page per `PrincipalRun` (smrt-svelte's\n`createOverviewAssistantSurface`, typed structurally here); validation and\n`canCustomize` are the surface's. Contract:\n[agents/overview-tools.md](agents/overview-tools.md).\n\n## Conversational Harness (L3, #1891)\n\nThe `AgentSession` runtime depends on personas, agents, and users. Keep those\nedges acyclic: none of those packages may depend back on chat.\n\n- **`runToolLoop(options)`** (`tool-loop.ts`) — a bounded `tool_call → observe → respond` loop. Tools are **manifest operations** of installed packages: `buildManifestToolCatalog({ allowedTools })` reads the `PermissionCatalogService` catalog and keeps only the `(collection, action)` entries named in the persona's allow-list (the **offer gate**; absent/empty ⇒ NO tools). The loop runs inside one `executeAsPrincipal` context, and `invokeManifestTool` executes each op **in-process (\"side door\")** against `run.context.database` (the RLS tx when Postgres RLS is on), after re-asserting the fail-closed allow-list (`run.assertToolAllowed`) AND the catalog permission (`run.assertOperation`) — the **execution gate**. Bounded by a max-steps ceiling (`DEFAULT_MAX_STEPS = 8`): on the ceiling it disables tools for one final completion so the turn always terminates with text. A thrown tool error is classified (`classifyToolError`): permission denials and 401/403 are `not_permitted`; a `ValidationError` or 400/404/409/422 is `invalid_request` (observation: actionable message, `publicMessage` first, `code`, fix-and-retry hint); else (incl. 429) `execution_error`.\n- **`runPersonaConversationTurn(options)`** (`persona-conversation.ts`) — binds a conversation to an `AgentPersona`/`ResolvedPersona`: runs as its principal (`runAsUserId`), offers only its `allowedTools`, speaks its instructions (`resolvePersonaInstructions`, layering approved learned directives), and injects its **recalled learning memory** (`personaLearningMemory`, isolated per `memoryScope`) into the system prompt. `bindPersonaToSession()` mirrors the persona's `allowedTools`/instructions onto the `AgentSession` so the chat authoring gate agrees with the loop's offer gate. Authors the reply (and each executed tool) via the internal `sendAgentReply` bridge. Tools run with the run-as user's **live** permissions unless the host passes a `permissions` snapshot (#2978), which `runToolLoop` forwards to `executeAsPrincipal` so a narrowed principal (e.g. a shared station) cannot reach grants — such as `readPermission`-gated data-surface fields — beyond that snapshot, including through `agents.invoke` delegation (the snapshot becomes the worker's permission ceiling).\n- **Agent orchestration** (L3, #1892) — the loop accepts non-manifest **`extraTools`** (`PrincipalTool[]`, from `@happyvertical/smrt-agents`), gated by the *same* fail-closed allow-list. The standard **`invoke-agent`** tool (`createInvokeAgentTool`, slug `agents.invoke`) lets a conversational agent delegate to a **worker agent under its own principal** — the worker runs via `executeAsPrincipal` as the originating user (never its own authority), the principal is immutable along the chain, and its completion is surfaced back into the conversation. `runPersonaConversationTurn` filters `extraTools` by the persona's `allowedTools` (offer gate); the tool's `execute` re-asserts `assertToolAllowed` (execution gate). See `@happyvertical/smrt-agents` for the delegation envelope + transports.\n- **Chat feedback capture** (`chat-feedback.ts`) — `captureChatFeedback()` + `acceptAppliedChange`/`rejectAppliedChange`/`correctResponse`/`rateResponse`/`thumbsUp`/`thumbsDown` write a `Feedback` row (personas) carrying the conversation's **correlation-id**, and (by default) reinforce the persona's learning memory (`reinforceFromFeedback`). So an in-chat reject decays a strategy below the reuse floor and it stops being recalled; a correction supersedes its stored value.\n\n## Voice Gateway Turns (#1910)\n\nVoice is an input mode for the existing persona chat harness, not a separate chat runtime. `createVoiceChatSession()` creates a short-lived `VoiceSession` for an authenticated actor/profile, binding tenant, persona, agent session, room, and optional thread. `handleVoiceGatewayTurn()` resolves that binding from `metadata.voiceSessionId`, checks the gateway's `session_id` and any supplied tenant/profile/persona/session/thread metadata against the server-side binding, persists the transcript through `ChatService.sendAgentUserMessage()`, runs `runPersonaConversationTurn()`, stamps voice/correlation metadata onto the persisted user/assistant/tool messages, records the gateway `turn_id`, and returns the gateway response contract. The Fetch-compatible `createVoiceGatewayTurnHandler()` adds the coarse gateway bearer-token check.\n\nThe gateway bearer token proves only \"this request came from the gateway\"; it never authorizes the end user. The short-lived `VoiceSession` binding is the user/session proof, and untrusted gateway metadata must be validated against that binding before any chat write or tool loop. Tool execution remains fail-closed through the persona allow-list mirrored onto `AgentSession` by `bindPersonaToSession()`.\n\n## Token streaming\n\n`chat-stream.ts` serves browser-safe SSE through `./client`. The host's\n`authorize(request, body)` is the sole trust boundary: resolve identity, tenant,\ncapabilities, and generation limits server-side; never authorize from request\nsession metadata. Persona turns reuse the principal and fail-closed tool gates.\nThe engine and browser-safe `SmrtChatBackend` keep custom-tool resolution\nserver-side. See [agents/token-streaming.md](agents/token-streaming.md) for the\nevent contract, CORS policy, and streaming behavior.\n\n## Streamed assistant turns with browser tools (#2908)\n\n`runAssistantTurn()` (`assistant-turn.ts`) is the host-route engine for the\nAssistantDock: one turn over `runToolLoop` with server tools (offer-gated by\n`principal.allowedTools`), browser tools (validated by\n`sanitizeClientToolDeclarations` + a server allow-list), `maxSteps`, `signal`,\nand `onUsage`. A browser tool call SUSPENDS the turn (`stoppedReason:\n'client_tools'`); the transcript waits in an `AssistantContinuationStore`\n(single-use, 15-minute TTL; `createSessionContinuationStore` keeps it in the\nAgentSession's `sessionContext`) and the browser resumes it with results,\nwhich reach the model wrapped `untrusted`. `createAssistantTurnResponse`\nserves the events as SSE; `assistant-turn-events.ts` is the browser-safe wire\ncontract (`./assistant-turn` subpath, also a vite library entry because the\nSvelte dock imports it). The dock decides whether a browser call runs or waits\nfor the user from the page registry, never the server's echo; destructive\nalways waits. Details: [`docs/assistant-dock.md`](../../docs/assistant-dock.md).\n\n## AssistantDock (#2904)\n\n`AssistantDock` (`svelte/components/assistant/`, exported from `./svelte`)\nuses a host `DataSurfaceRegistry`'s mounted descriptors (none: plain chat).\nActions: `normalizeDataSurfaceActionRequest` → `AssistantActionClient`\n(preview/apply over a server `DataSurfaceActionAdapter`, not the\n`data-surface-bridge.ts` channel). Generated `ChatThread`/`ChatMessage`\n`list`/`get` are tenant- not member-scoped; the dock never calls them.\n\n**Server routes (#3368).** `./sveltekit` `mountAssistantRoutes()` serves the\ndock from one `[...path]` route; `createAssistantHttp{Transport,ActionClient}`\n(`./svelte`) are its browser half. Principal from `event.locals` or\n`resolvePrincipal`; threads only from the actor's keyed session room in that\ntenant (else 404). `allowedTools` is fail-closed; without `tools` it offers\nthose manifest ops (an unprovided name is an error, #3414). `ai` defaults to\nthe config `ai` block. Pass `runtime`: a turn never keeps the RLS request tx\n(own `runAsPrincipal` tx). `clientRequestId` makes the row id a UUIDv5\n(`clientRequestMessageId`): the PK is the retry reservation. See\n[docs](../../docs/assistant-dock.md).\n\n## Recipes (#3719)\n\n`src/recipes.ts` declares `chat.assistant` (the AssistantDock as a `header.end`\nshell widget, an `llm` provider, runtime `both`; help in\n`src/assistant.recipe.md`). Keep each recipe class self-contained. Details:\n[agents/recipes.md](agents/recipes.md).\n\n## Gotchas\n\n- **sessionContext, not context**: `context` is reserved for slug scoping. Use `getSessionContext()`/`updateSessionContext()` for agent memory.\n- **Agent rooms auto-created**: `roomType: 'agent'`, `maxParticipants` defaults to 2; the agent is enrolled as a member so its replies pass the membership check. `createAgentSession()` re-enrolls the participant AND the agent on the existing-session path, so legacy sessions created before the agent was enrolled self-heal.\n- **The agent's author is a Profile, not `agentId` (#2995)**: `senderProfileId`/`profileId` are `crossPackageRef`s to `Profile` and therefore uuid columns on PostgreSQL, so the slug fails the cast (`22P02`) and no agent reply can persist. `createAgentSession()` resolves the agent's `bot` Profile through `resolveAgentProfile()` in `@happyvertical/smrt-profiles` (created on first use, tenant-bound) and records it as `AgentSession.agentProfileId`; both enrolment and `sendAgentReply` use that uuid. A consumer whose agent already has an acting identity passes `agentProfileId` to skip resolution — the voice path does this with the persona's `actsAsProfileId`, so persona replies stay attributed to the configured acting profile. Like `actorProfileId`, `agentProfileId` is SERVER-supplied, never request input: it selects the author of every later assistant message. It is validated (`#requireAgentProfile`) to exist and be visible in the tenant and to differ from the acting participant, and it can never re-point a session that already resolved one — only a pre-#2995 session with none is backfilled. **Migration**: `agent_profile_id` is an ordinary additive manifest field, so a consumer adopts it the same way as any other — `smrt db:migrate` generates and applies the column from the manifest, and `db:status --parity` verifies it; the framework never creates application schema at runtime. It is nullable and needs no offline DATA backfill — a session created before #2995 resolves and persists its `agentProfileId`, and re-enrols the agent, on its first agent turn after the upgrade. Two pre-#2995 cohorts: a session whose `agentId` is an ordinary slug never committed an author on PostgreSQL (the cast failed), so there is nothing to repair there, while SQLite/DuckDB may hold `chat_messages`/`chat_participants` rows whose id column holds the slug — readable, but not joinable to `profiles`. A session whose `agentId` is already a Profile uuid (the voice path used to collapse a persona's `actsAsProfileId` into it) DID commit on PostgreSQL; that profile is ADOPTED as the author, tenant-checked and never the participant, so the conversation's author does not change and the two-seat room gains no third identity. Known one-time effect: because `voice.ts` no longer derives `agentId` from `actsAsProfileId`, a keyless `createVoiceChatSession()` for such a persona opens a new session and room instead of reusing the legacy one; the old room and its messages stay intact and readable, and resuming with an explicit `agentSessionId` is unaffected.\n- **Only SQLite-backed tests would miss this class of bug**: uuid columns accept any text on SQLite. `src/__tests__/agent-reply-postgres.test.ts` (`pnpm --filter @happyvertical/smrt-chat test:postgres`) pins the agent-reply path against real PostgreSQL. That suite runs in `postgres-tests.yml` on every same-repository PR and merge group (#2659); keep a cheap SQLite assertion alongside it anyway, since the default lane is SQLite-only (`chat-service.test.ts` asserts the author is the profile uuid, not the slug).\n- **Per-subject sessions need `sessionKey`**: `createAgentSession()` reuses ANY active session for the same `(agentId, participantProfileId, tenantId)`. Callers that open separate conversations per subject (e.g. one content-editor session per content id) MUST pass a stable `sessionKey` (stored in `sessionContext.__sessionKey`, read via `AgentSession.getSessionKey()`); otherwise a session opened for one subject is reused and its context overwritten for another, surfacing the wrong room/threads (S5 #1392). A keyed create never reuses a keyless/legacy session.\n- **Session expiry**: check `isActive()` before allowing messages (expiresAt or limit-based)\n- **DM identity**: derived from the deterministic per-tenant `canonicalDmRoomId()` and the authoritative `chat_participants` join, not client metadata; concurrent creates upsert onto one row.\n- **Tenant-bound lookups**: membership/session/DM lookups REQUIRE `tenantId` and always bind it into the WHERE clause (`findActiveMembership`/`isActiveMember`/`findActiveSession` take a required `tenantId`; AgentSession's `null` tenant is an explicit bound scope, not \"any tenant\") so they can never resolve a row from another tenant.\n",
|
|
5202
4516
|
"moduleDocs": [
|
|
5203
4517
|
{
|
|
5204
4518
|
"path": "agents/dev-workbench.md",
|