@aigentyc/chat-sdk 0.1.2 → 0.1.5
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 +187 -0
- package/dist/ai-elements.cjs +119 -162
- package/dist/ai-elements.cjs.map +1 -1
- package/dist/ai-elements.js +5 -60
- package/dist/ai-elements.js.map +1 -1
- package/dist/{chunk-UZEPBDP3.js → chunk-2677FDTG.js} +108 -60
- package/dist/chunk-2677FDTG.js.map +1 -0
- package/dist/{chunk-42ARGQXE.js → chunk-7L4FS6G7.js} +7 -3
- package/dist/chunk-7L4FS6G7.js.map +1 -0
- package/dist/{chunk-VS3NZ7FX.js → chunk-A7PCSWIK.js} +60 -5
- package/dist/chunk-A7PCSWIK.js.map +1 -0
- package/dist/{chunk-WZLWAVSS.cjs → chunk-C24QG43M.cjs} +10 -2
- package/dist/chunk-C24QG43M.cjs.map +1 -0
- package/dist/{chunk-7QWHS57I.cjs → chunk-DMGYQ6NN.cjs} +6 -3
- package/dist/chunk-DMGYQ6NN.cjs.map +1 -0
- package/dist/{chunk-NW2ESHRV.js → chunk-KVEJAPWA.js} +4 -8
- package/dist/chunk-KVEJAPWA.js.map +1 -0
- package/dist/{chunk-X5YEOOPK.cjs → chunk-QDFPJJ5Y.cjs} +5 -13
- package/dist/chunk-QDFPJJ5Y.cjs.map +1 -0
- package/dist/{chunk-FQN6OBGN.cjs → chunk-RTVEBPAJ.cjs} +63 -4
- package/dist/chunk-RTVEBPAJ.cjs.map +1 -0
- package/dist/{chunk-XIBB3W5L.js → chunk-U3FXVLUK.js} +6 -3
- package/dist/chunk-U3FXVLUK.js.map +1 -0
- package/dist/{chunk-CPUELN57.cjs → chunk-WQARQ2FJ.cjs} +110 -62
- package/dist/chunk-WQARQ2FJ.cjs.map +1 -0
- package/dist/components.cjs +15 -15
- package/dist/components.d.cts +5 -0
- package/dist/components.d.ts +5 -0
- package/dist/components.js +5 -5
- package/dist/index.cjs +15 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/tools.cjs +4 -4
- package/dist/tools.js +1 -1
- package/dist/ui.cjs +51 -51
- package/dist/ui.js +2 -2
- package/llms.txt +128 -0
- package/package.json +4 -1
- package/dist/chunk-42ARGQXE.js.map +0 -1
- package/dist/chunk-7QWHS57I.cjs.map +0 -1
- package/dist/chunk-CPUELN57.cjs.map +0 -1
- package/dist/chunk-FQN6OBGN.cjs.map +0 -1
- package/dist/chunk-NW2ESHRV.js.map +0 -1
- package/dist/chunk-UZEPBDP3.js.map +0 -1
- package/dist/chunk-VS3NZ7FX.js.map +0 -1
- package/dist/chunk-WZLWAVSS.cjs.map +0 -1
- package/dist/chunk-X5YEOOPK.cjs.map +0 -1
- package/dist/chunk-XIBB3W5L.js.map +0 -1
package/dist/ui.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkQDFPJJ5Y_cjs = require('./chunk-QDFPJJ5Y.cjs');
|
|
5
|
+
var chunkC24QG43M_cjs = require('./chunk-C24QG43M.cjs');
|
|
6
6
|
var chunkJI5KCSOI_cjs = require('./chunk-JI5KCSOI.cjs');
|
|
7
7
|
var chunkAWAJOSFP_cjs = require('./chunk-AWAJOSFP.cjs');
|
|
8
8
|
var chunk525KS5HM_cjs = require('./chunk-525KS5HM.cjs');
|
|
@@ -442,163 +442,163 @@ TableCaption.displayName = "TableCaption";
|
|
|
442
442
|
|
|
443
443
|
Object.defineProperty(exports, "Alert", {
|
|
444
444
|
enumerable: true,
|
|
445
|
-
get: function () { return
|
|
445
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Alert; }
|
|
446
446
|
});
|
|
447
447
|
Object.defineProperty(exports, "AlertDescription", {
|
|
448
448
|
enumerable: true,
|
|
449
|
-
get: function () { return
|
|
449
|
+
get: function () { return chunkQDFPJJ5Y_cjs.AlertDescription; }
|
|
450
450
|
});
|
|
451
451
|
Object.defineProperty(exports, "AlertTitle", {
|
|
452
452
|
enumerable: true,
|
|
453
|
-
get: function () { return
|
|
453
|
+
get: function () { return chunkQDFPJJ5Y_cjs.AlertTitle; }
|
|
454
454
|
});
|
|
455
455
|
Object.defineProperty(exports, "Badge", {
|
|
456
456
|
enumerable: true,
|
|
457
|
-
get: function () { return
|
|
457
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Badge; }
|
|
458
458
|
});
|
|
459
459
|
Object.defineProperty(exports, "Carousel", {
|
|
460
460
|
enumerable: true,
|
|
461
|
-
get: function () { return
|
|
461
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Carousel; }
|
|
462
462
|
});
|
|
463
463
|
Object.defineProperty(exports, "CarouselContent", {
|
|
464
464
|
enumerable: true,
|
|
465
|
-
get: function () { return
|
|
465
|
+
get: function () { return chunkQDFPJJ5Y_cjs.CarouselContent; }
|
|
466
466
|
});
|
|
467
467
|
Object.defineProperty(exports, "CarouselItem", {
|
|
468
468
|
enumerable: true,
|
|
469
|
-
get: function () { return
|
|
469
|
+
get: function () { return chunkQDFPJJ5Y_cjs.CarouselItem; }
|
|
470
470
|
});
|
|
471
471
|
Object.defineProperty(exports, "CarouselNext", {
|
|
472
472
|
enumerable: true,
|
|
473
|
-
get: function () { return
|
|
473
|
+
get: function () { return chunkQDFPJJ5Y_cjs.CarouselNext; }
|
|
474
474
|
});
|
|
475
475
|
Object.defineProperty(exports, "CarouselPrevious", {
|
|
476
476
|
enumerable: true,
|
|
477
|
-
get: function () { return
|
|
478
|
-
});
|
|
479
|
-
Object.defineProperty(exports, "Collapsible", {
|
|
480
|
-
enumerable: true,
|
|
481
|
-
get: function () { return chunkX5YEOOPK_cjs.Collapsible; }
|
|
482
|
-
});
|
|
483
|
-
Object.defineProperty(exports, "CollapsibleContent", {
|
|
484
|
-
enumerable: true,
|
|
485
|
-
get: function () { return chunkX5YEOOPK_cjs.CollapsibleContent; }
|
|
486
|
-
});
|
|
487
|
-
Object.defineProperty(exports, "CollapsibleTrigger", {
|
|
488
|
-
enumerable: true,
|
|
489
|
-
get: function () { return chunkX5YEOOPK_cjs.CollapsibleTrigger; }
|
|
477
|
+
get: function () { return chunkQDFPJJ5Y_cjs.CarouselPrevious; }
|
|
490
478
|
});
|
|
491
479
|
Object.defineProperty(exports, "Dialog", {
|
|
492
480
|
enumerable: true,
|
|
493
|
-
get: function () { return
|
|
481
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Dialog; }
|
|
494
482
|
});
|
|
495
483
|
Object.defineProperty(exports, "DialogClose", {
|
|
496
484
|
enumerable: true,
|
|
497
|
-
get: function () { return
|
|
485
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogClose; }
|
|
498
486
|
});
|
|
499
487
|
Object.defineProperty(exports, "DialogContent", {
|
|
500
488
|
enumerable: true,
|
|
501
|
-
get: function () { return
|
|
489
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogContent; }
|
|
502
490
|
});
|
|
503
491
|
Object.defineProperty(exports, "DialogDescription", {
|
|
504
492
|
enumerable: true,
|
|
505
|
-
get: function () { return
|
|
493
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogDescription; }
|
|
506
494
|
});
|
|
507
495
|
Object.defineProperty(exports, "DialogFooter", {
|
|
508
496
|
enumerable: true,
|
|
509
|
-
get: function () { return
|
|
497
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogFooter; }
|
|
510
498
|
});
|
|
511
499
|
Object.defineProperty(exports, "DialogHeader", {
|
|
512
500
|
enumerable: true,
|
|
513
|
-
get: function () { return
|
|
501
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogHeader; }
|
|
514
502
|
});
|
|
515
503
|
Object.defineProperty(exports, "DialogTitle", {
|
|
516
504
|
enumerable: true,
|
|
517
|
-
get: function () { return
|
|
505
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogTitle; }
|
|
518
506
|
});
|
|
519
507
|
Object.defineProperty(exports, "DialogTrigger", {
|
|
520
508
|
enumerable: true,
|
|
521
|
-
get: function () { return
|
|
509
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DialogTrigger; }
|
|
522
510
|
});
|
|
523
511
|
Object.defineProperty(exports, "DropdownMenu", {
|
|
524
512
|
enumerable: true,
|
|
525
|
-
get: function () { return
|
|
513
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DropdownMenu; }
|
|
526
514
|
});
|
|
527
515
|
Object.defineProperty(exports, "DropdownMenuContent", {
|
|
528
516
|
enumerable: true,
|
|
529
|
-
get: function () { return
|
|
517
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DropdownMenuContent; }
|
|
530
518
|
});
|
|
531
519
|
Object.defineProperty(exports, "DropdownMenuItem", {
|
|
532
520
|
enumerable: true,
|
|
533
|
-
get: function () { return
|
|
521
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DropdownMenuItem; }
|
|
534
522
|
});
|
|
535
523
|
Object.defineProperty(exports, "DropdownMenuTrigger", {
|
|
536
524
|
enumerable: true,
|
|
537
|
-
get: function () { return
|
|
525
|
+
get: function () { return chunkQDFPJJ5Y_cjs.DropdownMenuTrigger; }
|
|
538
526
|
});
|
|
539
527
|
Object.defineProperty(exports, "Input", {
|
|
540
528
|
enumerable: true,
|
|
541
|
-
get: function () { return
|
|
529
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Input; }
|
|
542
530
|
});
|
|
543
531
|
Object.defineProperty(exports, "Progress", {
|
|
544
532
|
enumerable: true,
|
|
545
|
-
get: function () { return
|
|
533
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Progress; }
|
|
546
534
|
});
|
|
547
535
|
Object.defineProperty(exports, "ScrollArea", {
|
|
548
536
|
enumerable: true,
|
|
549
|
-
get: function () { return
|
|
537
|
+
get: function () { return chunkQDFPJJ5Y_cjs.ScrollArea; }
|
|
550
538
|
});
|
|
551
539
|
Object.defineProperty(exports, "ScrollBar", {
|
|
552
540
|
enumerable: true,
|
|
553
|
-
get: function () { return
|
|
541
|
+
get: function () { return chunkQDFPJJ5Y_cjs.ScrollBar; }
|
|
554
542
|
});
|
|
555
543
|
Object.defineProperty(exports, "Select", {
|
|
556
544
|
enumerable: true,
|
|
557
|
-
get: function () { return
|
|
545
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Select; }
|
|
558
546
|
});
|
|
559
547
|
Object.defineProperty(exports, "SelectContent", {
|
|
560
548
|
enumerable: true,
|
|
561
|
-
get: function () { return
|
|
549
|
+
get: function () { return chunkQDFPJJ5Y_cjs.SelectContent; }
|
|
562
550
|
});
|
|
563
551
|
Object.defineProperty(exports, "SelectItem", {
|
|
564
552
|
enumerable: true,
|
|
565
|
-
get: function () { return
|
|
553
|
+
get: function () { return chunkQDFPJJ5Y_cjs.SelectItem; }
|
|
566
554
|
});
|
|
567
555
|
Object.defineProperty(exports, "SelectTrigger", {
|
|
568
556
|
enumerable: true,
|
|
569
|
-
get: function () { return
|
|
557
|
+
get: function () { return chunkQDFPJJ5Y_cjs.SelectTrigger; }
|
|
570
558
|
});
|
|
571
559
|
Object.defineProperty(exports, "SelectValue", {
|
|
572
560
|
enumerable: true,
|
|
573
|
-
get: function () { return
|
|
561
|
+
get: function () { return chunkQDFPJJ5Y_cjs.SelectValue; }
|
|
574
562
|
});
|
|
575
563
|
Object.defineProperty(exports, "Separator", {
|
|
576
564
|
enumerable: true,
|
|
577
|
-
get: function () { return
|
|
565
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Separator; }
|
|
578
566
|
});
|
|
579
567
|
Object.defineProperty(exports, "Textarea", {
|
|
580
568
|
enumerable: true,
|
|
581
|
-
get: function () { return
|
|
569
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Textarea; }
|
|
582
570
|
});
|
|
583
571
|
Object.defineProperty(exports, "Tooltip", {
|
|
584
572
|
enumerable: true,
|
|
585
|
-
get: function () { return
|
|
573
|
+
get: function () { return chunkQDFPJJ5Y_cjs.Tooltip; }
|
|
586
574
|
});
|
|
587
575
|
Object.defineProperty(exports, "TooltipContent", {
|
|
588
576
|
enumerable: true,
|
|
589
|
-
get: function () { return
|
|
577
|
+
get: function () { return chunkQDFPJJ5Y_cjs.TooltipContent; }
|
|
590
578
|
});
|
|
591
579
|
Object.defineProperty(exports, "TooltipProvider", {
|
|
592
580
|
enumerable: true,
|
|
593
|
-
get: function () { return
|
|
581
|
+
get: function () { return chunkQDFPJJ5Y_cjs.TooltipProvider; }
|
|
594
582
|
});
|
|
595
583
|
Object.defineProperty(exports, "TooltipTrigger", {
|
|
596
584
|
enumerable: true,
|
|
597
|
-
get: function () { return
|
|
585
|
+
get: function () { return chunkQDFPJJ5Y_cjs.TooltipTrigger; }
|
|
598
586
|
});
|
|
599
587
|
Object.defineProperty(exports, "Button", {
|
|
600
588
|
enumerable: true,
|
|
601
|
-
get: function () { return
|
|
589
|
+
get: function () { return chunkC24QG43M_cjs.Button; }
|
|
590
|
+
});
|
|
591
|
+
Object.defineProperty(exports, "Collapsible", {
|
|
592
|
+
enumerable: true,
|
|
593
|
+
get: function () { return chunkC24QG43M_cjs.Collapsible; }
|
|
594
|
+
});
|
|
595
|
+
Object.defineProperty(exports, "CollapsibleContent", {
|
|
596
|
+
enumerable: true,
|
|
597
|
+
get: function () { return chunkC24QG43M_cjs.CollapsibleContent; }
|
|
598
|
+
});
|
|
599
|
+
Object.defineProperty(exports, "CollapsibleTrigger", {
|
|
600
|
+
enumerable: true,
|
|
601
|
+
get: function () { return chunkC24QG43M_cjs.CollapsibleTrigger; }
|
|
602
602
|
});
|
|
603
603
|
Object.defineProperty(exports, "Spinner", {
|
|
604
604
|
enumerable: true,
|
package/dist/ui.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { Alert, AlertDescription, AlertTitle, Badge, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,
|
|
3
|
-
export { Button } from './chunk-
|
|
2
|
+
export { Alert, AlertDescription, AlertTitle, Badge, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Input, Progress, ScrollArea, ScrollBar, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Separator, Textarea, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-KVEJAPWA.js';
|
|
3
|
+
export { Button, Collapsible, CollapsibleContent, CollapsibleTrigger } from './chunk-7L4FS6G7.js';
|
|
4
4
|
export { Spinner } from './chunk-4QT25AXI.js';
|
|
5
5
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-NPJKLYLV.js';
|
|
6
6
|
import { cn } from './chunk-3RW7O444.js';
|
package/llms.txt
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# @aigentyc/chat-sdk
|
|
2
|
+
|
|
3
|
+
> React 19 SDK for embedding AI-powered chat UIs connected to the Aigentyc platform. Ships drop-in components, a composable component layer, and a fully headless hook. SSR-safe (Next.js App Router). White-label, themeable, i18n-ready, with backend-driven tool rendering and optional live-chat handoff.
|
|
4
|
+
|
|
5
|
+
## Fastest path — scaffold a starter
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm create aigentyc-chat@latest my-app
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Prompts for template (`vite-react` or `next`) and `projectId`, then produces a working app. Non-interactive:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm create aigentyc-chat@latest my-app -- --template=next --project-id=YOUR_ID
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Installation (add to existing app)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @aigentyc/chat-sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Only `react>=19` and `react-dom>=19` are required peers. Everything else needed for core chat (streaming, tools, transport) is bundled.
|
|
24
|
+
|
|
25
|
+
Optional peers — install only if you use that feature:
|
|
26
|
+
- `socket.io-client` — live chat handoff
|
|
27
|
+
- `recharts` — visualization tool renderer
|
|
28
|
+
- `@json-render/core @json-render/react @json-render/shadcn zod` — json-render tools
|
|
29
|
+
|
|
30
|
+
## Golden-path quick start
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { Chat } from "@aigentyc/chat-sdk"
|
|
34
|
+
import "@aigentyc/chat-sdk/theme/styles.css"
|
|
35
|
+
|
|
36
|
+
export function App() {
|
|
37
|
+
return (
|
|
38
|
+
<Chat
|
|
39
|
+
projectId="your-project-id"
|
|
40
|
+
apiEndpoint="https://app.aigentyc.ai"
|
|
41
|
+
apiKey="your-api-key"
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Peer deps required: `react>=19`, `react-dom>=19`. The CSS import is required for theming.
|
|
48
|
+
|
|
49
|
+
## Four levels of control
|
|
50
|
+
|
|
51
|
+
1. **Drop-in** — `<Chat projectId apiEndpoint />`
|
|
52
|
+
2. **Customize** — add `theme`, `slots`, event handlers like `onMessageSent`
|
|
53
|
+
3. **Compose** — `<ChatProvider>` + individual components (`ChatInterface`, `ChatInput`)
|
|
54
|
+
4. **Headless** — `useAigentycChat({ projectId, apiEndpoint })` returns `{ messages, sendMessage, status }`
|
|
55
|
+
|
|
56
|
+
## Package entry points
|
|
57
|
+
|
|
58
|
+
- `@aigentyc/chat-sdk` — `Chat`, `ChatWidget`, `ChatProvider` (main)
|
|
59
|
+
- `@aigentyc/chat-sdk/hooks` — `useAigentycChat` and other hooks
|
|
60
|
+
- `@aigentyc/chat-sdk/components` — granular chat components
|
|
61
|
+
- `@aigentyc/chat-sdk/ai-elements` — `Message`, `Conversation`, primitives
|
|
62
|
+
- `@aigentyc/chat-sdk/tools` — `ToolRenderer`, `VisualizationRenderer`
|
|
63
|
+
- `@aigentyc/chat-sdk/json-render` — json-render integration
|
|
64
|
+
- `@aigentyc/chat-sdk/ui` — shadcn-style UI primitives
|
|
65
|
+
- `@aigentyc/chat-sdk/theme` — `ThemeProvider`; CSS at `@aigentyc/chat-sdk/theme/styles.css`
|
|
66
|
+
- `@aigentyc/chat-sdk/i18n` — `addLanguage`, built-in `en`, `he`
|
|
67
|
+
- `@aigentyc/chat-sdk/core` — types, transport, utils
|
|
68
|
+
|
|
69
|
+
## Slots
|
|
70
|
+
|
|
71
|
+
Replace any UI piece via the `slots` prop:
|
|
72
|
+
|
|
73
|
+
`header`, `welcome`, `message`, `input`, `footer`, `loader`, `suggestions`, `tools` (keyed per tool name).
|
|
74
|
+
|
|
75
|
+
## Tool rendering
|
|
76
|
+
|
|
77
|
+
The Aigentyc backend returns a `uiRenderMode` per tool result. The SDK auto-dispatches:
|
|
78
|
+
- `visualization` → recharts
|
|
79
|
+
- `json_render` → `@json-render/shadcn` component spec
|
|
80
|
+
- `legacy` → custom HTML/CSS template
|
|
81
|
+
- `preset` → built-in renderer
|
|
82
|
+
|
|
83
|
+
Override a specific tool:
|
|
84
|
+
```tsx
|
|
85
|
+
<Chat slots={{ tools: { searchProducts: MyProductGrid } }} />
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Theming
|
|
89
|
+
|
|
90
|
+
All tokens are CSS variables scoped under `[data-aigentyc-chat]`. Override via the `theme` prop or plain CSS. No forced branding.
|
|
91
|
+
|
|
92
|
+
## i18n
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import { addLanguage } from "@aigentyc/chat-sdk/i18n"
|
|
96
|
+
addLanguage("fr", { welcomeTitle: "Bienvenue" })
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Live chat
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<Chat enableLiveChat chatServiceUrl="wss://..." />
|
|
103
|
+
```
|
|
104
|
+
Requires `socket.io-client`.
|
|
105
|
+
|
|
106
|
+
## Next.js / SSR
|
|
107
|
+
|
|
108
|
+
All client components declare `"use client"`. Works in App Router and Pages Router without extra config.
|
|
109
|
+
|
|
110
|
+
## Common pitfalls (do not)
|
|
111
|
+
|
|
112
|
+
- Don't forget the CSS import — unstyled UI is almost always a missing `@aigentyc/chat-sdk/theme/styles.css`.
|
|
113
|
+
- Don't import from `dist/` or deep subpaths — use the public entry points above.
|
|
114
|
+
- Don't wrap in `<Chat>` twice; use `<ChatProvider>` + sub-components for layouts, not nested `<Chat>`.
|
|
115
|
+
- React 18 is not supported — peer is `>=19`.
|
|
116
|
+
- `apiKey` is optional for public/anon projects; required for authenticated ones.
|
|
117
|
+
|
|
118
|
+
## Links
|
|
119
|
+
|
|
120
|
+
- Package: https://www.npmjs.com/package/@aigentyc/chat-sdk
|
|
121
|
+
- Scaffolder: `npm create aigentyc-chat@latest my-app`
|
|
122
|
+
- Dashboard: https://app.aigentyc.ai
|
|
123
|
+
|
|
124
|
+
## Files included in this package
|
|
125
|
+
|
|
126
|
+
- `README.md` — install + quickstart
|
|
127
|
+
- `AGENTS.md` — agent-oriented guide (rules, decision tree, troubleshooting)
|
|
128
|
+
- `llms.txt` — this file (LLM-friendly summary)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigentyc/chat-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "React SDK for building AI-powered chat interfaces connected to the Aigentyc platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -115,8 +115,11 @@
|
|
|
115
115
|
"files": [
|
|
116
116
|
"dist",
|
|
117
117
|
"README.md",
|
|
118
|
+
"AGENTS.md",
|
|
119
|
+
"llms.txt",
|
|
118
120
|
"LICENSE"
|
|
119
121
|
],
|
|
122
|
+
"homepage": "https://www.npmjs.com/package/@aigentyc/chat-sdk",
|
|
120
123
|
"scripts": {
|
|
121
124
|
"build": "tsup && pnpm build:css",
|
|
122
125
|
"build:js": "tsup",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/button.tsx"],"names":[],"mappings":";;;;;;AAOA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACtB,uSAAA;AAAA,EACA;AAAA,IACC,QAAA,EAAU;AAAA,MACT,OAAA,EAAS;AAAA,QACR,OAAA,EACC,+DAAA;AAAA,QACD,WAAA,EACC,8EAAA;AAAA,QACD,OAAA,EACC,0FAAA;AAAA,QACD,SAAA,EACC,wEAAA;AAAA,QACD,KAAA,EAAO,8CAAA;AAAA,QACP,IAAA,EAAM;AAAA,OACP;AAAA,MACA,IAAA,EAAM;AAAA,QACL,OAAA,EAAS,eAAA;AAAA,QACT,EAAA,EAAI,6BAAA;AAAA,QACJ,EAAA,EAAI,sBAAA;AAAA,QACJ,IAAA,EAAM,SAAA;AAAA,QACN,SAAA,EAAW;AAAA;AACZ,KACD;AAAA,IACA,eAAA,EAAiB;AAAA,MAChB,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACP;AAEF,CAAA;AAQA,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACpB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,IAAA,EAAM,UAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACjE,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,IAAA,uBACC,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACA,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,QAC1D,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACL;AAAA,EAEF;AACD;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-42ARGQXE.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../core/utils\";\n\nconst buttonVariants = cva(\n\t\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault:\n\t\t\t\t\t\"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n\t\t\t\toutline:\n\t\t\t\t\t\"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tsecondary:\n\t\t\t\t\t\"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n\t\t\t\tghost: \"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault: \"h-9 px-4 py-2\",\n\t\t\t\tsm: \"h-8 rounded-md px-3 text-xs\",\n\t\t\t\tlg: \"h-10 rounded-md px-8\",\n\t\t\t\ticon: \"h-9 w-9\",\n\t\t\t\t\"icon-sm\": \"h-7 w-7\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport interface ButtonProps\n\textends React.ButtonHTMLAttributes<HTMLButtonElement>,\n\tVariantProps<typeof buttonVariants> {\n\tasChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t({ className, variant, size, asChild = false, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"button\";\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tclassName={cn(buttonVariants({ variant, size, className }))}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/SearchKnowledgeBaseRenderer.tsx","../src/tools/ComponentRenderer.tsx","../src/tools/useSafeChatCallbacks.ts","../src/tools/tool-registry.ts","../src/tools/ToolRenderer.tsx"],"names":["useState","jsxs","Card","jsx","useId","useRef","useSyncExternalStore","useEffect","processImagesInHtml","useContext","ChatContext","lazy","Spinner","Suspense","useSlots","useMemo"],"mappings":"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","file":"chunk-7QWHS57I.cjs","sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Card } from \"../ui/card\";\nimport type { ToolRendererProps } from \"../core/types\";\n\ninterface KbSource {\n rank?: number;\n id?: number | string;\n content?: string;\n documentName?: string;\n sourceUrl?: string | null;\n similarity?: number;\n pageTitle?: string | null;\n summary?: string | null;\n relevance?: string;\n}\n\ninterface KbResult {\n found?: boolean;\n totalResults?: number;\n generatedQueries?: string[];\n sources?: KbSource[];\n}\n\nfunction truncate(text: string, max = 220) {\n if (text.length <= max) return text;\n return text.slice(0, max).trimEnd() + \"…\";\n}\n\nexport function SearchKnowledgeBaseRenderer(props: ToolRendererProps) {\n const data = (props.result?._displayData ?? props.result?.data) as KbResult | undefined;\n const [expanded, setExpanded] = useState(false);\n\n if (!data || !data.found || !Array.isArray(data.sources) || data.sources.length === 0) {\n return null;\n }\n\n const sources = data.sources;\n const visible = expanded ? sources : sources.slice(0, 3);\n\n return (\n <Card className=\"p-3 text-sm\">\n <div className=\"mb-2 flex items-center justify-between text-xs text-muted-foreground\">\n <span>\n Found <strong className=\"text-foreground\">{data.totalResults ?? sources.length}</strong>{\" \"}\n source{(data.totalResults ?? sources.length) === 1 ? \"\" : \"s\"}\n {data.generatedQueries?.length\n ? ` for \"${data.generatedQueries.join(\", \")}\"`\n : \"\"}\n </span>\n </div>\n\n <ul className=\"flex flex-col gap-2\">\n {visible.map((s, i) => {\n const snippet = truncate((s.summary || s.content || \"\").replace(/\\s+/g, \" \").trim());\n const title = s.documentName || s.pageTitle || `Source ${s.rank ?? i + 1}`;\n return (\n <li\n key={`${s.id ?? i}`}\n className=\"rounded-md border border-border/60 bg-muted/20 p-2\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium truncate\">{title}</span>\n {typeof s.similarity === \"number\" && (\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n {(s.similarity * 100).toFixed(0)}%\n </span>\n )}\n </div>\n {snippet && (\n <p className=\"mt-1 text-xs text-muted-foreground leading-relaxed\">\n {snippet}\n </p>\n )}\n {s.sourceUrl && (\n <a\n href={s.sourceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"mt-1 inline-block text-xs text-primary hover:underline\"\n >\n Open source ↗\n </a>\n )}\n </li>\n );\n })}\n </ul>\n\n {sources.length > 3 && (\n <button\n type=\"button\"\n onClick={() => setExpanded((e) => !e)}\n className=\"mt-2 text-xs text-muted-foreground hover:text-foreground\"\n >\n {expanded ? \"Show less\" : `Show ${sources.length - 3} more`}\n </button>\n )}\n </Card>\n );\n}\n\nexport default SearchKnowledgeBaseRenderer;\n","\"use client\";\n\n/**\n * ComponentRenderer — renders a \"legacy\" tool result that ships custom\n * HTML + CSS with Handlebars-style `{{field}}` template variables.\n *\n * Supports single objects and arrays with a responsive grid and a\n * show-more pagination fold. All window access is SSR-guarded.\n */\n\nimport {\n useEffect,\n useId,\n useRef,\n useState,\n useSyncExternalStore,\n type MouseEvent as ReactMouseEvent,\n} from \"react\";\nimport { processImagesInHtml } from \"../core/image-utils\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nfunction subscribeToResize(cb: () => void) {\n if (typeof window === \"undefined\") return () => {};\n window.addEventListener(\"resize\", cb);\n return () => window.removeEventListener(\"resize\", cb);\n}\n\nfunction getIsMobile() {\n if (typeof window === \"undefined\") return false;\n return window.innerWidth < MOBILE_BREAKPOINT;\n}\n\n/** Props for `ComponentRenderer`. */\nexport interface ComponentRendererProps {\n /** Raw HTML template with `{{field}}` placeholders. */\n htmlCode: string;\n /** Scoped CSS for the template. */\n cssCode: string;\n /** Data payload — object (single render) or array (grid). */\n data: unknown;\n /** Columns on mobile when `data` is an array. Default: 1 */\n mobileGridCols?: number;\n /** Columns on desktop when `data` is an array. Default: 3 */\n desktopGridCols?: number;\n /** Optional interaction tracker. */\n onInteraction?: (params: {\n type: string;\n target: string;\n label: string;\n metadata?: Record<string, unknown>;\n messageId?: string;\n eventId?: string;\n }) => void;\n messageId?: string;\n eventId?: string;\n /** Items per page on mobile (default: 4). */\n mobilePageSize?: number;\n /** Items per page on desktop (default: 4). */\n desktopPageSize?: number;\n}\n\n/**\n * Renders a tool-provided HTML/CSS template against data. Strings such as\n * `{{user.name}}` and `{{#each items}}...{{/each}}` are resolved before\n * insertion.\n */\nexport function ComponentRenderer({\n htmlCode,\n cssCode,\n data,\n mobileGridCols = 1,\n desktopGridCols = 3,\n onInteraction,\n messageId,\n eventId,\n mobilePageSize = 4,\n desktopPageSize = 4,\n}: ComponentRendererProps) {\n const containerId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n const [currentPage, setCurrentPage] = useState(0);\n const isMobile = useSyncExternalStore(\n subscribeToResize,\n getIsMobile,\n () => true\n );\n\n const pageSize = isMobile ? mobilePageSize : desktopPageSize;\n\n const isArray = Array.isArray(data);\n const totalItems = isArray ? (data as unknown[]).length : 1;\n const totalPages = isArray ? Math.ceil(totalItems / pageSize) : 1;\n const hasPagination = isArray && totalItems > pageSize;\n\n useEffect(() => {\n setCurrentPage((p) => Math.min(p, Math.max(0, totalPages - 1)));\n }, [totalPages]);\n\n const displayData =\n isArray && hasPagination\n ? (data as unknown[]).slice(\n currentPage * pageSize,\n (currentPage + 1) * pageSize\n )\n : data;\n\n useEffect(() => {\n if (!containerRef.current) return;\n if (typeof document === \"undefined\") return;\n\n let processedHtml = \"\";\n\n if (Array.isArray(displayData)) {\n const gridId = `grid-${containerId}`;\n const items = displayData\n .map((item, idx) => {\n let rendered = replaceTemplateVariables(htmlCode, item);\n rendered = processImagesInHtml(rendered);\n const globalIndex = currentPage * pageSize + idx;\n return `<div class=\"grid-item\" data-item-index=\"${globalIndex}\">${rendered}</div>`;\n })\n .join(\"\");\n processedHtml = `<div class=\"grid-container\" id=\"${gridId}\">${items}</div>`;\n } else {\n processedHtml = replaceTemplateVariables(htmlCode, displayData);\n processedHtml = processImagesInHtml(processedHtml);\n }\n\n containerRef.current.innerHTML = processedHtml;\n\n const styleId = `component-style-${containerId}`;\n const existingStyle = document.getElementById(styleId);\n if (existingStyle) {\n existingStyle.remove();\n }\n\n let finalCss = cssCode;\n if (Array.isArray(displayData)) {\n const gridCss = `\n#${containerId} .grid-container {\n display: grid;\n grid-template-columns: repeat(${mobileGridCols}, 1fr);\n gap: 1rem;\n width: 100%;\n}\n\n#${containerId} .grid-item {\n width: 100%;\n}\n\n@media (min-width: 768px) {\n #${containerId} .grid-container {\n grid-template-columns: repeat(${desktopGridCols}, 1fr);\n }\n}\n`;\n finalCss = `${cssCode}\\n${gridCss}`;\n }\n\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.textContent = finalCss;\n containerRef.current.appendChild(style);\n\n const images = containerRef.current.querySelectorAll(\"img\");\n images.forEach((img) => {\n if (!img.hasAttribute(\"loading\")) {\n img.setAttribute(\"loading\", \"lazy\");\n }\n });\n\n const links = containerRef.current.querySelectorAll(\"a\");\n links.forEach((link) => {\n link.setAttribute(\"target\", \"_blank\");\n link.setAttribute(\"rel\", \"noopener noreferrer\");\n });\n }, [\n htmlCode,\n cssCode,\n displayData,\n mobileGridCols,\n desktopGridCols,\n containerId,\n currentPage,\n pageSize,\n totalItems,\n totalPages,\n ]);\n\n const handleClick = (e: ReactMouseEvent<HTMLDivElement>) => {\n if (!onInteraction) return;\n const target = e.target as HTMLElement;\n const link = target.closest(\"a\");\n const button = target.closest(\"button\");\n\n if (link?.href) {\n onInteraction({\n type: \"link_click\",\n target: link.href,\n label: link.textContent || link.href,\n metadata: { url: link.href, text: link.textContent },\n messageId,\n eventId,\n });\n } else if (button && !button.hasAttribute(\"data-no-track\")) {\n onInteraction({\n type: \"button_click\",\n target: button.textContent || \"button\",\n label: button.textContent || \"button\",\n metadata: { buttonText: button.textContent },\n messageId,\n eventId,\n });\n }\n };\n\n return (\n <div className=\"component-renderer-wrapper\">\n <div\n ref={containerRef}\n id={containerId}\n className=\"component-render w-full rounded\"\n onClick={handleClick}\n style={{ display: \"block\" }}\n />\n\n {hasPagination && (\n <div className=\"flex items-center justify-center gap-2 mt-4\" dir=\"ltr\">\n <button\n onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}\n disabled={currentPage === 0}\n className=\"px-3 py-1.5 text-sm rounded-md border border-gray-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-gray-100 transition-colors\"\n aria-label=\"Previous page\"\n >\n {\"‹\"}\n </button>\n\n <span className=\"text-sm text-gray-600 px-2 tabular-nums\">\n {currentPage + 1} / {totalPages}\n </span>\n\n <button\n onClick={() =>\n setCurrentPage((p) => Math.min(totalPages - 1, p + 1))\n }\n disabled={currentPage >= totalPages - 1}\n className=\"px-3 py-1.5 text-sm rounded-md border border-gray-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-gray-100 transition-colors\"\n aria-label=\"Next page\"\n >\n {\"›\"}\n </button>\n </div>\n )}\n </div>\n );\n}\n\nexport default ComponentRenderer;\n\n// ---------------------------------------------------------------------------\n// Template engine\n// ---------------------------------------------------------------------------\n\n/**\n * Replace `{{template}}` variables in HTML with actual data values.\n * Supports `{{field}}`, `{{nested.field}}`, `{{#each field}}...{{/each}}`,\n * `{{this}}`, and `{{this.field}}`.\n */\nfunction replaceTemplateVariables(html: string, data: unknown): string {\n let processed = processEachBlocks(html, data);\n\n // Strip unsupported control flow (e.g. {{#if}})\n processed = processed.replace(/\\{\\{[#/][^}]+\\}\\}/g, \"\");\n\n processed = processed.replace(/\\{\\{this\\}\\}/g, () =>\n data !== undefined && data !== null ? String(data) : \"\"\n );\n\n processed = processed.replace(/\\{\\{this\\.([^}]+)\\}\\}/g, \"{{$1}}\");\n\n return processed.replace(/\\{\\{([^}]+)\\}\\}/g, (match, path: string) => {\n try {\n const trimmedPath = path.trim();\n const value = getNestedValue(data, trimmedPath);\n\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n } catch {\n return match;\n }\n });\n}\n\nfunction processEachBlocks(html: string, data: unknown): string {\n const eachRegex = /\\{\\{#each\\s+([^}]+)\\}\\}([\\s\\S]*?)\\{\\{\\/each\\}\\}/g;\n\n return html.replace(eachRegex, (_match, field: string, content: string) => {\n const trimmedField = field.trim();\n const array = getNestedValue(data, trimmedField);\n if (!Array.isArray(array)) return \"\";\n\n return array\n .map((item) => {\n let itemHtml = processEachBlocks(content, item);\n\n if (typeof item !== \"object\" || item === null) {\n itemHtml = itemHtml.replace(/\\{\\{this\\}\\}/g, String(item));\n return itemHtml;\n }\n\n itemHtml = itemHtml.replace(/\\{\\{this\\.([^}]+)\\}\\}/g, \"{{$1}}\");\n itemHtml = itemHtml.replace(/\\{\\{([^}]+)\\}\\}/g, (m, path: string) => {\n const trimmedPath = path.trim();\n if (trimmedPath.startsWith(\"#\") || trimmedPath.startsWith(\"/\"))\n return m;\n const value = getNestedValue(item, trimmedPath);\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n });\n\n return itemHtml;\n })\n .join(\"\");\n });\n}\n\nfunction getNestedValue(obj: unknown, path: string): unknown {\n if (!path || obj === null || obj === undefined) return undefined;\n\n const parts = path.split(/\\.(?![^[]*\\])/);\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n\n const arrayMatch = part.match(/^([^[]+)\\[([^\\]]+)\\]$/);\n if (arrayMatch) {\n const [, key, index] = arrayMatch;\n current = (current as Record<string, unknown>)[key];\n if (Array.isArray(current)) {\n current = current[parseInt(index, 10)];\n }\n } else {\n current = (current as Record<string, unknown>)[part];\n }\n }\n\n return current;\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { ChatContext } from \"../providers/ChatContext\";\nimport type { ChatEventCallbacks } from \"../core/types\";\n\n/**\n * Read chat event callbacks from ChatContext if available, otherwise return\n * an empty object. Safe to call from components that may render outside a\n * ChatProvider (e.g. standalone tool previews).\n */\nexport function useSafeChatCallbacks(): ChatEventCallbacks {\n\tconst ctx = useContext(ChatContext);\n\treturn ctx?.callbacks ?? {};\n}\n","\"use client\";\n\n/**\n * Built-in tool renderer registry.\n *\n * The `ToolRenderer` router consults these maps after slot overrides and\n * before falling back to a generic JSON preview.\n */\n\nimport type { ComponentType } from \"react\";\nimport type { ToolRendererProps } from \"../core/types\";\nimport { SearchKnowledgeBaseRenderer } from \"./SearchKnowledgeBaseRenderer\";\n\n/**\n * Map of built-in renderers keyed by the tool result's `uiRenderMode`.\n *\n * Entries are populated lazily by `ToolRenderer` (via `React.lazy`) so the\n * heavy renderers (recharts, JSON-render catalog) don't end up in the core\n * bundle unless used. This map is intentionally empty at module scope — look\n * at `ToolRenderer.tsx` for the actual dispatch logic.\n */\nexport const BUILTIN_TOOL_RENDERERS: Record<\n string,\n ComponentType<ToolRendererProps> | null\n> = {\n visualization: null,\n json_render: null,\n legacy: null,\n preset: null,\n none: null,\n};\n\n/**\n * Built-in renderers addressed by tool *name* (not render mode).\n *\n * A `null` value signals \"render nothing\" — useful for tools whose side\n * effects are handled elsewhere (e.g. `requestHumanChat` is consumed by the\n * `LiveChatProvider` and must not produce UI inside the message stream).\n */\nexport const BUILTIN_NAMED_RENDERERS: Record<\n string,\n ComponentType<ToolRendererProps> | null\n> = {\n requestHumanChat: null,\n searchKnowledgeBase: SearchKnowledgeBaseRenderer,\n};\n","\"use client\";\n\n/**\n * ToolRenderer — the main dispatcher for tool invocations in the chat stream.\n *\n * Resolution order:\n * 1. `slots.tools[toolName]` — per-tool-name slot override\n * 2. `slots.toolRenderers[result.uiRenderMode]` — per-render-mode slot override\n * 3. `BUILTIN_NAMED_RENDERERS[toolName]` — special named built-ins\n * 4. `BUILTIN_TOOL_RENDERERS[result.uiRenderMode]` — built-in mode dispatch\n * 5. Fallback — clean JSON preview inside a Card\n *\n * Heavy renderers (`VisualizationRenderer`, `JsonRenderResult`) are loaded\n * lazily via `React.lazy` + `Suspense` to keep the core bundle small.\n */\n\nimport {\n lazy,\n Suspense,\n useEffect,\n useMemo,\n type ComponentType,\n} from \"react\";\nimport { useSlots } from \"../providers/SlotsContext\";\nimport { Card } from \"../ui/card\";\nimport { Spinner } from \"../ui/spinner\";\nimport type {\n ComponentAction,\n ToolRendererProps,\n ToolResult,\n} from \"../core/types\";\n// ToolRenderer may be rendered outside a ChatContext (e.g. standalone\n// previews), so we read the context defensively via a safe hook.\nimport { useSafeChatCallbacks } from \"./useSafeChatCallbacks\";\nimport {\n BUILTIN_NAMED_RENDERERS,\n BUILTIN_TOOL_RENDERERS,\n} from \"./tool-registry\";\nimport { ComponentRenderer } from \"./ComponentRenderer\";\n\n// ---------------------------------------------------------------------------\n// Lazy renderers\n// ---------------------------------------------------------------------------\n\nconst LazyVisualization = lazy(() =>\n import(\"./VisualizationRenderer\").then((m) => ({\n default: m.VisualizationRenderer,\n }))\n);\n\nconst LazyJsonRender = lazy(() =>\n import(\"../json-render/JsonRenderResult\").then((m) => ({\n default: m.JsonRenderResult as unknown as ComponentType<Record<string, unknown>>,\n }))\n);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Return the best display payload for a tool result, preferring `_displayData`\n * (which the server strips before sending back to the LLM) over `data`.\n */\nfunction getDisplayData(result: ToolResult | undefined): unknown {\n if (!result) return undefined;\n if (result._displayData !== undefined) return result._displayData;\n return result.data;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Default (fallback) renderers\n// ---------------------------------------------------------------------------\n\nfunction LoadingFallback({ text }: { text?: string }) {\n return (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n <span>{text || \"Working...\"}</span>\n </div>\n );\n}\n\nfunction PresetPreview(props: ToolRendererProps) {\n const payload = getDisplayData(props.result);\n if (payload === undefined || payload === null) return null;\n return (\n <Card className=\"p-3\">\n <pre className=\"text-xs overflow-x-auto whitespace-pre-wrap break-words\">\n {safeStringify(payload)}\n </pre>\n </Card>\n );\n}\n\nfunction VisualizationWrapper(props: ToolRendererProps) {\n const payload = getDisplayData(props.result);\n // Accept either a full spec or `{ spec: ... }`.\n const spec =\n payload && typeof payload === \"object\" && \"type\" in (payload as object)\n ? (payload as Record<string, unknown>)\n : (payload as { spec?: Record<string, unknown> })?.spec;\n if (!spec) return null;\n return (\n <Suspense fallback={<LoadingFallback text={props.result?.loadingText} />}>\n {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}\n <LazyVisualization spec={spec as any} />\n </Suspense>\n );\n}\n\nfunction JsonRenderWrapper(props: ToolRendererProps) {\n const spec = props.result?.jsonRenderSpec;\n const payload = getDisplayData(props.result);\n if (!spec) return null;\n return (\n <Suspense fallback={<LoadingFallback text={props.result?.loadingText} />}>\n <LazyJsonRender\n spec={spec}\n data={payload}\n onSendMessage={props.onSendMessage}\n onAction={props.onAction}\n />\n </Suspense>\n );\n}\n\nfunction LegacyWrapper(props: ToolRendererProps) {\n const result = props.result;\n const payload = getDisplayData(result);\n const config = result?.customComponent;\n // `customComponent` in core/types is declared as `string`, but when used by\n // the legacy render mode the server inlines the `{ htmlCode, cssCode, ... }`\n // object. Widen the type locally.\n const cfg =\n typeof config === \"object\" && config !== null\n ? (config as {\n htmlCode?: string;\n cssCode?: string;\n mobileGridCols?: number;\n desktopGridCols?: number;\n mobilePageSize?: number;\n desktopPageSize?: number;\n })\n : null;\n if (!cfg?.htmlCode) return null;\n\n return (\n <ComponentRenderer\n htmlCode={cfg.htmlCode}\n cssCode={cfg.cssCode || \"\"}\n data={payload}\n mobileGridCols={cfg.mobileGridCols}\n desktopGridCols={cfg.desktopGridCols}\n mobilePageSize={cfg.mobilePageSize}\n desktopPageSize={cfg.desktopPageSize}\n />\n );\n}\n\nfunction FallbackPreview(props: ToolRendererProps) {\n const payload = getDisplayData(props.result);\n if (payload === undefined) return null;\n return (\n <Card className=\"p-3 bg-muted/30\">\n <pre className=\"text-xs overflow-x-auto whitespace-pre-wrap break-words\">\n {safeStringify(payload)}\n </pre>\n </Card>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Router\n// ---------------------------------------------------------------------------\n\n/**\n * Main tool renderer. Place one of these per tool invocation inside the\n * assistant message stream.\n */\ninterface PublicSlotMap {\n loader?: ComponentType<{ text?: string }>;\n tools?: Record<string, ComponentType<ToolRendererProps>>;\n toolRenderers?: Record<string, ComponentType<ToolRendererProps>>;\n}\n\nexport function ToolRenderer(props: ToolRendererProps) {\n const { toolName, state, result } = props;\n const slots = useSlots() as unknown as PublicSlotMap;\n const callbacks = useSafeChatCallbacks();\n\n // ----- Fire analytics callbacks -----\n useEffect(() => {\n if (state === \"output-available\" && result) {\n (callbacks as { onToolResult?: (...args: unknown[]) => void } | undefined)?.onToolResult?.(toolName, result, result.uiRenderMode);\n }\n }, [state, toolName, result, callbacks]);\n\n // Wrap onAction to also forward to callbacks.onToolAction.\n const onAction = useMemo(() => {\n const userOnAction = props.onAction;\n return (action: ComponentAction, itemData?: unknown) => {\n (callbacks as { onToolAction?: (...args: unknown[]) => void } | undefined)?.onToolAction?.(action, itemData);\n userOnAction?.(action);\n };\n }, [callbacks, props.onAction]);\n\n // Build a prop-forwarding wrapper that swaps `onAction`.\n const forwardedProps: ToolRendererProps = { ...props, onAction };\n\n // ----- Pending / in-flight states -----\n if (state === \"partial-call\" || state === \"call\") {\n const slotLoader = (slots as { loader?: ComponentType<unknown> }).loader;\n if (slotLoader) {\n const L = slotLoader as ComponentType<{ text?: string }>;\n return <L text={result?.loadingText} />;\n }\n return <LoadingFallback text={result?.loadingText} />;\n }\n\n // Output-available — nothing to show if the result explicitly hides itself\n const mode = (result?.uiRenderMode as string | undefined) ?? \"preset\";\n if (mode === \"none\" || mode === \"hidden\") {\n // Still check named overrides in case a host wants to render a\n // side-effect-y tool.\n const named = slots.tools?.[toolName];\n if (named) {\n return renderWithDefault(named, forwardedProps, FallbackPreview);\n }\n return null;\n }\n\n // 1. per-tool slot override\n const toolSlot = slots.tools?.[toolName];\n if (toolSlot) {\n return renderWithDefault(toolSlot, forwardedProps, pickDefaultForMode(mode));\n }\n\n // 2. per-render-mode slot override\n const modeSlot = slots.toolRenderers?.[mode];\n if (modeSlot) {\n return renderWithDefault(modeSlot, forwardedProps, pickDefaultForMode(mode));\n }\n\n // 3. named built-in\n const namedBuiltin = BUILTIN_NAMED_RENDERERS[toolName];\n if (namedBuiltin === null && toolName in BUILTIN_NAMED_RENDERERS) {\n // explicit \"render nothing\" for this tool\n return null;\n }\n if (namedBuiltin) {\n const N = namedBuiltin;\n return <N {...forwardedProps} />;\n }\n\n // 4. built-in by render mode\n switch (mode) {\n case \"visualization\":\n return <VisualizationWrapper {...forwardedProps} />;\n case \"json_render\":\n case \"json\":\n return <JsonRenderWrapper {...forwardedProps} />;\n case \"legacy\":\n case \"display\":\n return <LegacyWrapper {...forwardedProps} />;\n case \"preset\":\n case \"text\":\n return <PresetPreview {...forwardedProps} />;\n default:\n // 5. fallback JSON card\n return <FallbackPreview {...forwardedProps} />;\n }\n}\n\nexport default ToolRenderer;\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Render a slot override and inject the matching `DefaultComponent` so the\n * override can fall back to the built-in rendering.\n */\nfunction renderWithDefault(\n Override: ComponentType<ToolRendererProps & { DefaultComponent?: ComponentType<ToolRendererProps> }>,\n props: ToolRendererProps,\n Default: ComponentType<ToolRendererProps>\n) {\n return <Override {...props} DefaultComponent={Default} />;\n}\n\nfunction pickDefaultForMode(mode: string): ComponentType<ToolRendererProps> {\n switch (mode) {\n case \"visualization\":\n return VisualizationWrapper;\n case \"json_render\":\n case \"json\":\n return JsonRenderWrapper;\n case \"legacy\":\n case \"display\":\n return LegacyWrapper;\n case \"preset\":\n case \"text\":\n return PresetPreview;\n default:\n return FallbackPreview;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports for convenience\n// ---------------------------------------------------------------------------\n\nexport type { ToolRendererProps, ToolResult, ComponentAction };\n"]}
|