@gram-ai/elements 1.25.1 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Chat/stories/Charts.stories.d.ts +37 -0
- package/dist/components/Chat/stories/GenerativeUI.stories.d.ts +17 -0
- package/dist/components/Chat/stories/MessageFeedback.stories.d.ts +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/buttonVariants.d.ts +1 -1
- package/dist/components/ui/charts.stories.d.ts +43 -0
- package/dist/components/ui/generative-ui.stories.d.ts +53 -0
- package/dist/contexts/ChatIdContext.d.ts +11 -0
- package/dist/contexts/contexts.d.ts +1 -0
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +7 -6
- package/dist/index-BJnv49-A.js +37057 -0
- package/dist/index-BJnv49-A.js.map +1 -0
- package/dist/index-BpJstUh1.cjs +280 -0
- package/dist/index-BpJstUh1.cjs.map +1 -0
- package/dist/index-CUitXazZ.js +30426 -0
- package/dist/index-CUitXazZ.js.map +1 -0
- package/dist/index-ChW-CSuu.cjs +147 -0
- package/dist/index-ChW-CSuu.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/plugins/chart/catalog.d.ts +123 -0
- package/dist/plugins/chart/index.d.ts +1 -1
- package/dist/plugins/chart/ui/area-chart.d.ts +16 -0
- package/dist/plugins/chart/ui/bar-chart.d.ts +16 -0
- package/dist/plugins/chart/ui/donut-chart.d.ts +17 -0
- package/dist/plugins/chart/ui/index.d.ts +7 -0
- package/dist/plugins/chart/ui/line-chart.d.ts +17 -0
- package/dist/plugins/chart/ui/pie-chart.d.ts +15 -0
- package/dist/plugins/chart/ui/radar-chart.d.ts +14 -0
- package/dist/plugins/chart/ui/scatter-chart.d.ts +18 -0
- package/dist/plugins/components/MacOSWindowFrame.d.ts +13 -0
- package/dist/plugins/components/PluginLoadingState.d.ts +1 -1
- package/dist/plugins/generative-ui/catalog.d.ts +293 -0
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +18 -0
- package/dist/plugins/generative-ui/ui/accordion.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/action-button.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/alert.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/avatar-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/avatar.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/badge.d.ts +12 -0
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +15 -0
- package/dist/plugins/generative-ui/ui/button.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/card.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/checkbox-wrapper.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/data-table.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/dialog.d.ts +17 -0
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +25 -0
- package/dist/plugins/generative-ui/ui/grid.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/index.d.ts +40 -0
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/input.d.ts +3 -0
- package/dist/plugins/generative-ui/ui/label.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/list.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/metric.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/pagination.d.ts +13 -0
- package/dist/plugins/generative-ui/ui/popover.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/progress.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +5 -0
- package/dist/plugins/generative-ui/ui/select-wrapper.d.ts +13 -0
- package/dist/plugins/generative-ui/ui/select.d.ts +15 -0
- package/dist/plugins/generative-ui/ui/separator.d.ts +4 -0
- package/dist/plugins/generative-ui/ui/skeleton-wrapper.d.ts +9 -0
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +2 -0
- package/dist/plugins/generative-ui/ui/stack.d.ts +8 -0
- package/dist/plugins/generative-ui/ui/switch.d.ts +6 -0
- package/dist/plugins/generative-ui/ui/table.d.ts +10 -0
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +21 -0
- package/dist/plugins/generative-ui/ui/tabs.d.ts +11 -0
- package/dist/plugins/generative-ui/ui/text.d.ts +7 -0
- package/dist/plugins/generative-ui/ui/textarea.d.ts +3 -0
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +7 -0
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-CijCgLrw.js → profiler-D4Tw5ecI.js} +2 -2
- package/dist/{profiler-CijCgLrw.js.map → profiler-D4Tw5ecI.js.map} +1 -1
- package/dist/{profiler-DAT0DL1W.cjs → profiler-DCWYDZ1F.cjs} +2 -2
- package/dist/{profiler-DAT0DL1W.cjs.map → profiler-DCWYDZ1F.cjs.map} +1 -1
- package/dist/{startRecording-DotsE8QT.cjs → startRecording-3sTskM3H.cjs} +2 -2
- package/dist/{startRecording-DotsE8QT.cjs.map → startRecording-3sTskM3H.cjs.map} +1 -1
- package/dist/{startRecording-gmhENmf0.js → startRecording-BHhcCWQE.js} +2 -2
- package/dist/{startRecording-gmhENmf0.js.map → startRecording-BHhcCWQE.js.map} +1 -1
- package/dist/types/index.d.ts +4 -4
- package/package.json +4 -1
- package/src/components/Chat/stories/Charts.stories.tsx +260 -0
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +6 -6
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +113 -0
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +6 -6
- package/src/components/Chat/stories/ToolApproval.stories.tsx +10 -10
- package/src/components/Chat/stories/Tools.stories.tsx +122 -104
- package/src/components/Chat/stories/Variants.stories.tsx +1 -1
- package/src/components/Replay.stories.tsx +1 -1
- package/src/components/Replay.tsx +18 -13
- package/src/components/ShadowRoot.tsx +5 -1
- package/src/components/assistant-ui/message-feedback.tsx +6 -7
- package/src/components/assistant-ui/thread.tsx +76 -11
- package/src/components/ui/charts.stories.tsx +246 -0
- package/src/components/ui/generative-ui.stories.tsx +557 -0
- package/src/components/ui/generative-ui.tsx +60 -360
- package/src/components/ui/tool-ui.stories.tsx +6 -3
- package/src/contexts/ChatIdContext.tsx +21 -0
- package/src/contexts/ElementsProvider.tsx +77 -37
- package/src/contexts/contexts.ts +2 -0
- package/src/hooks/useAuth.ts +18 -3
- package/src/hooks/useFollowOnSuggestions.ts +6 -1
- package/src/index.ts +1 -0
- package/src/plugins/chart/catalog.ts +141 -0
- package/src/plugins/chart/component.tsx +79 -125
- package/src/plugins/chart/index.ts +141 -89
- package/src/plugins/chart/ui/area-chart.tsx +133 -0
- package/src/plugins/chart/ui/bar-chart.tsx +137 -0
- package/src/plugins/chart/ui/donut-chart.tsx +167 -0
- package/src/plugins/chart/ui/index.ts +7 -0
- package/src/plugins/chart/ui/line-chart.tsx +135 -0
- package/src/plugins/chart/ui/pie-chart.tsx +148 -0
- package/src/plugins/chart/ui/radar-chart.tsx +105 -0
- package/src/plugins/chart/ui/scatter-chart.tsx +132 -0
- package/src/plugins/components/MacOSWindowFrame.tsx +55 -0
- package/src/plugins/components/PluginLoadingState.tsx +9 -13
- package/src/plugins/generative-ui/catalog.ts +277 -0
- package/src/plugins/generative-ui/component.tsx +112 -21
- package/src/plugins/generative-ui/index.ts +20 -141
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +57 -0
- package/src/plugins/generative-ui/ui/accordion.tsx +66 -0
- package/src/plugins/generative-ui/ui/action-button.tsx +68 -0
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +26 -0
- package/src/plugins/generative-ui/ui/alert.tsx +66 -0
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +22 -0
- package/src/plugins/generative-ui/ui/avatar.tsx +109 -0
- package/src/plugins/generative-ui/ui/badge.tsx +65 -0
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +32 -0
- package/src/plugins/generative-ui/ui/button.tsx +65 -0
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +36 -0
- package/src/plugins/generative-ui/ui/card.tsx +92 -0
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +39 -0
- package/src/plugins/generative-ui/ui/checkbox.tsx +32 -0
- package/src/plugins/generative-ui/ui/data-table.tsx +53 -0
- package/src/plugins/generative-ui/ui/dialog.tsx +158 -0
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +257 -0
- package/src/plugins/generative-ui/ui/grid.tsx +29 -0
- package/src/plugins/generative-ui/ui/index.ts +43 -0
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +38 -0
- package/src/plugins/generative-ui/ui/input.tsx +21 -0
- package/src/plugins/generative-ui/ui/label.tsx +24 -0
- package/src/plugins/generative-ui/ui/list.tsx +34 -0
- package/src/plugins/generative-ui/ui/metric.tsx +53 -0
- package/src/plugins/generative-ui/ui/pagination.tsx +127 -0
- package/src/plugins/generative-ui/ui/popover.tsx +89 -0
- package/src/plugins/generative-ui/ui/progress.tsx +57 -0
- package/src/plugins/generative-ui/ui/radio-group.tsx +45 -0
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +41 -0
- package/src/plugins/generative-ui/ui/select.tsx +190 -0
- package/src/plugins/generative-ui/ui/separator.tsx +28 -0
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +30 -0
- package/src/plugins/generative-ui/ui/skeleton.tsx +13 -0
- package/src/plugins/generative-ui/ui/stack.tsx +54 -0
- package/src/plugins/generative-ui/ui/switch.tsx +35 -0
- package/src/plugins/generative-ui/ui/table.tsx +116 -0
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +51 -0
- package/src/plugins/generative-ui/ui/tabs.tsx +92 -0
- package/src/plugins/generative-ui/ui/text.tsx +33 -0
- package/src/plugins/generative-ui/ui/textarea.tsx +18 -0
- package/src/plugins/generative-ui/ui/tooltip.tsx +57 -0
- package/src/types/index.ts +4 -4
- package/dist/components/Chat/stories/Plugins.stories.d.ts +0 -12
- package/dist/index-C3UbmFRR.cjs +0 -178
- package/dist/index-C3UbmFRR.cjs.map +0 -1
- package/dist/index-CtyV0c-T.js +0 -27225
- package/dist/index-CtyV0c-T.js.map +0 -1
- package/dist/index-DxJwZ5Kc.js +0 -39975
- package/dist/index-DxJwZ5Kc.js.map +0 -1
- package/dist/index-iUSSoKFz.cjs +0 -251
- package/dist/index-iUSSoKFz.cjs.map +0 -1
- package/src/components/Chat/stories/Plugins.stories.tsx +0 -158
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
2
|
+
import { Chat } from '..'
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Chat> = {
|
|
5
|
+
title: 'Chat/Plugins/Generative UI',
|
|
6
|
+
component: Chat,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'fullscreen',
|
|
9
|
+
},
|
|
10
|
+
} satisfies Meta<typeof Chat>
|
|
11
|
+
|
|
12
|
+
export default meta
|
|
13
|
+
|
|
14
|
+
type Story = StoryFn<typeof Chat>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* E-commerce store assistant with natural task-focused prompts.
|
|
18
|
+
*/
|
|
19
|
+
export const StoreAssistant: Story = () => <Chat />
|
|
20
|
+
StoreAssistant.parameters = {
|
|
21
|
+
elements: {
|
|
22
|
+
config: {
|
|
23
|
+
variant: 'standalone',
|
|
24
|
+
welcome: {
|
|
25
|
+
title: 'Store Assistant',
|
|
26
|
+
subtitle: 'How can I help you today?',
|
|
27
|
+
suggestions: [
|
|
28
|
+
{
|
|
29
|
+
title: 'My Orders',
|
|
30
|
+
label: 'View recent orders',
|
|
31
|
+
prompt: 'Show me my current orders',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
title: 'Browse Products',
|
|
35
|
+
label: "See what's available",
|
|
36
|
+
prompt: 'What products do you have?',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: 'Find Deals',
|
|
40
|
+
label: 'Best prices',
|
|
41
|
+
prompt: 'What are the best deals right now?',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Shopping assistant for product discovery.
|
|
51
|
+
*/
|
|
52
|
+
export const ShoppingAssistant: Story = () => <Chat />
|
|
53
|
+
ShoppingAssistant.parameters = {
|
|
54
|
+
elements: {
|
|
55
|
+
config: {
|
|
56
|
+
variant: 'standalone',
|
|
57
|
+
welcome: {
|
|
58
|
+
title: 'Shopping Assistant',
|
|
59
|
+
subtitle: 'Find the perfect product',
|
|
60
|
+
suggestions: [
|
|
61
|
+
{
|
|
62
|
+
title: 'New Arrivals',
|
|
63
|
+
label: 'Latest products',
|
|
64
|
+
prompt: 'Show me the newest products',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: 'Gift Ideas',
|
|
68
|
+
label: 'Under $50',
|
|
69
|
+
prompt: 'I need a gift under $50, what do you recommend?',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: 'Compare Options',
|
|
73
|
+
label: 'Help me decide',
|
|
74
|
+
prompt: 'Can you compare your top 3 products for me?',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Store management assistant.
|
|
84
|
+
*/
|
|
85
|
+
export const StoreManager: Story = () => <Chat />
|
|
86
|
+
StoreManager.parameters = {
|
|
87
|
+
elements: {
|
|
88
|
+
config: {
|
|
89
|
+
variant: 'standalone',
|
|
90
|
+
welcome: {
|
|
91
|
+
title: 'Store Manager',
|
|
92
|
+
subtitle: 'Manage your store',
|
|
93
|
+
suggestions: [
|
|
94
|
+
{
|
|
95
|
+
title: 'Stock Check',
|
|
96
|
+
label: 'Inventory status',
|
|
97
|
+
prompt: 'Which products are running low on stock?',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
title: 'Sales Summary',
|
|
101
|
+
label: 'How are we doing?',
|
|
102
|
+
prompt: 'How are sales looking this month?',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: 'Top Sellers',
|
|
106
|
+
label: 'Best performers',
|
|
107
|
+
prompt: 'What are our best selling products?',
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Chat } from '..'
|
|
2
|
-
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
3
1
|
import { MessageFeedback } from '@/components/assistant-ui/message-feedback'
|
|
2
|
+
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
4
3
|
import { LazyMotion, domAnimation } from 'motion/react'
|
|
4
|
+
import { Chat } from '..'
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof Chat> = {
|
|
7
7
|
title: 'Chat/Message Feedback',
|
|
@@ -25,7 +25,7 @@ Default.parameters = {
|
|
|
25
25
|
config: {
|
|
26
26
|
variant: 'standalone',
|
|
27
27
|
thread: {
|
|
28
|
-
|
|
28
|
+
showFeedback: true,
|
|
29
29
|
},
|
|
30
30
|
welcome: {
|
|
31
31
|
title: 'Message Feedback Demo',
|
|
@@ -59,7 +59,7 @@ Widget.parameters = {
|
|
|
59
59
|
variant: 'widget',
|
|
60
60
|
modal: { defaultOpen: true },
|
|
61
61
|
thread: {
|
|
62
|
-
|
|
62
|
+
showFeedback: true,
|
|
63
63
|
},
|
|
64
64
|
welcome: {
|
|
65
65
|
title: 'Message Feedback Demo',
|
|
@@ -91,7 +91,7 @@ Sidecar.parameters = {
|
|
|
91
91
|
config: {
|
|
92
92
|
variant: 'sidecar',
|
|
93
93
|
thread: {
|
|
94
|
-
|
|
94
|
+
showFeedback: true,
|
|
95
95
|
},
|
|
96
96
|
welcome: {
|
|
97
97
|
title: 'Message Feedback Demo',
|
|
@@ -122,7 +122,7 @@ WithFollowUpSuggestions.parameters = {
|
|
|
122
122
|
systemPrompt:
|
|
123
123
|
'You are a helpful customer support assistant. Keep ALL responses extremely brief - 1-2 sentences only. No lists, no elaboration.',
|
|
124
124
|
thread: {
|
|
125
|
-
|
|
125
|
+
showFeedback: true,
|
|
126
126
|
followUpSuggestions: true,
|
|
127
127
|
},
|
|
128
128
|
welcome: {
|
|
@@ -24,13 +24,13 @@ SingleTool.parameters = {
|
|
|
24
24
|
suggestions: [
|
|
25
25
|
{
|
|
26
26
|
title: 'Call a tool requiring approval',
|
|
27
|
-
label: '
|
|
28
|
-
prompt: '
|
|
27
|
+
label: 'Add to cart',
|
|
28
|
+
prompt: 'List products and add the first one to my cart',
|
|
29
29
|
},
|
|
30
30
|
],
|
|
31
31
|
},
|
|
32
32
|
tools: {
|
|
33
|
-
toolsRequiringApproval: ['
|
|
33
|
+
toolsRequiringApproval: ['ecommerce_api_add_to_cart'],
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
},
|
|
@@ -45,14 +45,14 @@ SingleToolWithFunction.parameters = {
|
|
|
45
45
|
variant: 'standalone',
|
|
46
46
|
tools: {
|
|
47
47
|
toolsRequiringApproval: ({ toolName }: { toolName: string }) =>
|
|
48
|
-
toolName.
|
|
48
|
+
toolName.includes('order') || toolName.includes('cart'),
|
|
49
49
|
},
|
|
50
50
|
welcome: {
|
|
51
51
|
suggestions: [
|
|
52
52
|
{
|
|
53
53
|
title: 'Call a tool requiring approval',
|
|
54
|
-
label: '
|
|
55
|
-
prompt: '
|
|
54
|
+
label: 'Create an order',
|
|
55
|
+
prompt: 'List products and create an order for the first one',
|
|
56
56
|
},
|
|
57
57
|
],
|
|
58
58
|
},
|
|
@@ -70,16 +70,16 @@ MultipleGroupedTools.parameters = {
|
|
|
70
70
|
suggestions: [
|
|
71
71
|
{
|
|
72
72
|
title: 'Call both tools requiring approval',
|
|
73
|
-
label: '
|
|
73
|
+
label: 'Add to cart and create order',
|
|
74
74
|
prompt:
|
|
75
|
-
'
|
|
75
|
+
'List products, add the first one to my cart, and then create an order',
|
|
76
76
|
},
|
|
77
77
|
],
|
|
78
78
|
},
|
|
79
79
|
tools: {
|
|
80
80
|
toolsRequiringApproval: [
|
|
81
|
-
'
|
|
82
|
-
'
|
|
81
|
+
'ecommerce_api_add_to_cart',
|
|
82
|
+
'ecommerce_api_create_order',
|
|
83
83
|
],
|
|
84
84
|
},
|
|
85
85
|
},
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ToolCallMessagePartProps } from '@assistant-ui/react'
|
|
2
2
|
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
3
|
-
import React from 'react'
|
|
3
|
+
import React, { useState, useCallback } from 'react'
|
|
4
4
|
import z from 'zod'
|
|
5
5
|
import { Chat } from '..'
|
|
6
|
+
import { useToolExecution } from '../../../contexts/ToolExecutionContext'
|
|
6
7
|
import { defineFrontendTool } from '../../../lib/tools'
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof Chat> = {
|
|
@@ -17,128 +18,145 @@ export default meta
|
|
|
17
18
|
|
|
18
19
|
type Story = StoryFn<typeof Chat>
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const ProductCardComponent = ({ result }: ToolCallMessagePartProps) => {
|
|
22
|
+
const { executeTool, isToolAvailable } = useToolExecution()
|
|
23
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
24
|
+
const [addedToCart, setAddedToCart] = useState(false)
|
|
25
|
+
|
|
26
|
+
// Parse the result to get product details
|
|
27
|
+
let product = {
|
|
28
|
+
id: '',
|
|
29
|
+
name: 'Loading...',
|
|
30
|
+
description: '',
|
|
31
|
+
price: 0,
|
|
32
|
+
category: '',
|
|
33
|
+
rating: 0,
|
|
34
|
+
reviewCount: 0,
|
|
35
|
+
imageUrl: '',
|
|
36
|
+
inStock: true,
|
|
37
|
+
}
|
|
25
38
|
|
|
26
|
-
// Parse the result to get the pin
|
|
27
|
-
let pin = '****'
|
|
28
39
|
try {
|
|
29
40
|
if (result) {
|
|
30
41
|
const parsed = typeof result === 'string' ? JSON.parse(result) : result
|
|
31
42
|
if (parsed?.content?.[0]?.text) {
|
|
32
43
|
const content = JSON.parse(parsed.content[0].text)
|
|
33
|
-
|
|
34
|
-
} else if (parsed?.
|
|
35
|
-
|
|
44
|
+
product = { ...product, ...content }
|
|
45
|
+
} else if (parsed?.name) {
|
|
46
|
+
product = { ...product, ...parsed }
|
|
36
47
|
}
|
|
37
48
|
}
|
|
38
49
|
} catch {
|
|
39
50
|
// Fallback to default
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
const
|
|
43
|
-
const cardNumber = args?.queryParameters?.cardNumber || '4532 •••• •••• 1234'
|
|
44
|
-
const cardHolder = 'JOHN DOE'
|
|
45
|
-
const expiry = '12/25'
|
|
46
|
-
const cvv = '123'
|
|
53
|
+
const canAddToCart = isToolAvailable('ecommerce_api_add_to_cart')
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
return
|
|
50
|
-
}
|
|
55
|
+
const handleAddToCart = useCallback(async () => {
|
|
56
|
+
if (!product.id || !canAddToCart) return
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<div className="absolute inset-0 backface-hidden">
|
|
62
|
-
<div className="relative h-full w-full overflow-hidden rounded-xl bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 p-6 text-white shadow-2xl">
|
|
63
|
-
{/* Card pattern overlay */}
|
|
64
|
-
<div className="absolute inset-0 opacity-10">
|
|
65
|
-
<div className="absolute -top-10 -right-10 h-40 w-40 rounded-full bg-white"></div>
|
|
66
|
-
<div className="absolute -bottom-10 -left-10 h-32 w-32 rounded-full bg-white"></div>
|
|
67
|
-
</div>
|
|
58
|
+
setIsLoading(true)
|
|
59
|
+
try {
|
|
60
|
+
// HTTP tools from OpenAPI expect body content wrapped in a 'body' field
|
|
61
|
+
const toolResult = await executeTool('ecommerce_api_add_to_cart', {
|
|
62
|
+
body: {
|
|
63
|
+
productId: product.id,
|
|
64
|
+
quantity: 1,
|
|
65
|
+
},
|
|
66
|
+
})
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
if (toolResult.success) {
|
|
69
|
+
setAddedToCart(true)
|
|
70
|
+
} else {
|
|
71
|
+
console.error('[ProductCard] Tool failed:', toolResult.error)
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error('[ProductCard] Exception:', err)
|
|
75
|
+
} finally {
|
|
76
|
+
setIsLoading(false)
|
|
77
|
+
}
|
|
78
|
+
}, [product.id, canAddToCart, executeTool])
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
</div>
|
|
80
|
+
return (
|
|
81
|
+
<div className="my-4 w-80">
|
|
82
|
+
<div className="overflow-hidden rounded-xl bg-white shadow-lg dark:bg-slate-800">
|
|
83
|
+
{/* Product Image */}
|
|
84
|
+
<div className="relative h-48 bg-gradient-to-br from-indigo-100 to-purple-100 dark:from-indigo-900 dark:to-purple-900">
|
|
85
|
+
{product.imageUrl ? (
|
|
86
|
+
<img
|
|
87
|
+
src={product.imageUrl}
|
|
88
|
+
alt={product.name}
|
|
89
|
+
className="h-full w-full object-cover"
|
|
90
|
+
/>
|
|
91
|
+
) : (
|
|
92
|
+
<div className="flex h-full items-center justify-center">
|
|
93
|
+
<span className="text-6xl">📦</span>
|
|
91
94
|
</div>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<div className="absolute right-2
|
|
95
|
-
|
|
95
|
+
)}
|
|
96
|
+
{!product.inStock && (
|
|
97
|
+
<div className="absolute top-2 right-2 rounded-full bg-red-500 px-2 py-1 text-xs font-semibold text-white">
|
|
98
|
+
Out of Stock
|
|
96
99
|
</div>
|
|
97
|
-
|
|
100
|
+
)}
|
|
98
101
|
</div>
|
|
99
102
|
|
|
100
|
-
{/*
|
|
101
|
-
<div className="
|
|
102
|
-
<div className="
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{cvv}
|
|
112
|
-
</div>
|
|
113
|
-
<div className="text-xs opacity-70">CVV</div>
|
|
114
|
-
</div>
|
|
115
|
-
|
|
116
|
-
{/* PIN Display */}
|
|
117
|
-
<div className="mt-6 space-y-2">
|
|
118
|
-
<div className="text-xs opacity-70">PIN</div>
|
|
119
|
-
<div className="flex items-center gap-3">
|
|
120
|
-
<div className="flex h-16 w-16 items-center justify-center rounded-lg bg-gradient-to-br from-yellow-400 to-orange-500 shadow-lg">
|
|
121
|
-
<span className="text-2xl font-bold text-white">
|
|
122
|
-
{pin}
|
|
123
|
-
</span>
|
|
124
|
-
</div>
|
|
125
|
-
<div className="text-xs opacity-60">
|
|
126
|
-
Keep this PIN secure
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
</div>
|
|
103
|
+
{/* Product Details */}
|
|
104
|
+
<div className="p-4">
|
|
105
|
+
<div className="mb-1 text-xs font-medium tracking-wide text-indigo-500 uppercase dark:text-indigo-400">
|
|
106
|
+
{product.category}
|
|
107
|
+
</div>
|
|
108
|
+
<h3 className="mb-2 text-lg font-bold text-slate-900 dark:text-white">
|
|
109
|
+
{product.name}
|
|
110
|
+
</h3>
|
|
111
|
+
<p className="mb-3 line-clamp-2 text-sm text-slate-600 dark:text-slate-300">
|
|
112
|
+
{product.description}
|
|
113
|
+
</p>
|
|
131
114
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
115
|
+
{/* Rating */}
|
|
116
|
+
<div className="mb-3 flex items-center gap-1">
|
|
117
|
+
<div className="flex">
|
|
118
|
+
{[1, 2, 3, 4, 5].map((star) => (
|
|
119
|
+
<span
|
|
120
|
+
key={star}
|
|
121
|
+
className={
|
|
122
|
+
star <= Math.round(product.rating)
|
|
123
|
+
? 'text-yellow-400'
|
|
124
|
+
: 'text-slate-300'
|
|
125
|
+
}
|
|
126
|
+
>
|
|
127
|
+
★
|
|
128
|
+
</span>
|
|
129
|
+
))}
|
|
136
130
|
</div>
|
|
131
|
+
<span className="text-sm text-slate-500">
|
|
132
|
+
({product.reviewCount} reviews)
|
|
133
|
+
</span>
|
|
134
|
+
</div>
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
{/* Price and Add to Cart */}
|
|
137
|
+
<div className="flex items-center justify-between">
|
|
138
|
+
<span className="text-2xl font-bold text-slate-900 dark:text-white">
|
|
139
|
+
${product.price?.toFixed(2)}
|
|
140
|
+
</span>
|
|
141
|
+
<button
|
|
142
|
+
onClick={handleAddToCart}
|
|
143
|
+
disabled={
|
|
144
|
+
isLoading || addedToCart || !canAddToCart || !product.inStock
|
|
145
|
+
}
|
|
146
|
+
className={`rounded-lg px-4 py-2 text-sm font-semibold text-white transition-colors ${
|
|
147
|
+
addedToCart
|
|
148
|
+
? 'bg-green-500'
|
|
149
|
+
: isLoading
|
|
150
|
+
? 'bg-indigo-400'
|
|
151
|
+
: 'bg-indigo-600 hover:bg-indigo-700'
|
|
152
|
+
} disabled:cursor-not-allowed disabled:opacity-50`}
|
|
153
|
+
>
|
|
154
|
+
{addedToCart
|
|
155
|
+
? '✓ Added'
|
|
156
|
+
: isLoading
|
|
157
|
+
? 'Adding...'
|
|
158
|
+
: 'Add to Cart'}
|
|
159
|
+
</button>
|
|
142
160
|
</div>
|
|
143
161
|
</div>
|
|
144
162
|
</div>
|
|
@@ -154,15 +172,15 @@ CustomToolComponent.parameters = {
|
|
|
154
172
|
welcome: {
|
|
155
173
|
suggestions: [
|
|
156
174
|
{
|
|
157
|
-
title: 'Get
|
|
158
|
-
label: '
|
|
159
|
-
prompt: '
|
|
175
|
+
title: 'Get product details',
|
|
176
|
+
label: 'View a product',
|
|
177
|
+
prompt: 'List products and then show me details for the first one',
|
|
160
178
|
},
|
|
161
179
|
],
|
|
162
180
|
},
|
|
163
181
|
tools: {
|
|
164
182
|
components: {
|
|
165
|
-
|
|
183
|
+
ecommerce_api_get_product: ProductCardComponent,
|
|
166
184
|
},
|
|
167
185
|
},
|
|
168
186
|
},
|
|
@@ -61,7 +61,7 @@ StandaloneWithHistory.parameters = {
|
|
|
61
61
|
history: { enabled: true, showThreadList: true },
|
|
62
62
|
model: { showModelPicker: true },
|
|
63
63
|
tools: {
|
|
64
|
-
toolsRequiringApproval: ['
|
|
64
|
+
toolsRequiringApproval: ['ecommerce_api_create_order'],
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
67
|
},
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import { ROOT_SELECTOR } from '@/constants/tailwind'
|
|
23
|
+
import { ChatIdContext } from '@/contexts/ChatIdContext'
|
|
23
24
|
import { ElementsContext } from '@/contexts/contexts'
|
|
24
25
|
import { ReplayContext } from '@/contexts/ReplayContext'
|
|
25
26
|
import { ToolApprovalProvider } from '@/contexts/ToolApprovalContext'
|
|
@@ -110,24 +111,28 @@ export const Replay = ({
|
|
|
110
111
|
|
|
111
112
|
const replayCtx = useMemo(() => ({ isReplay: true }), [])
|
|
112
113
|
|
|
114
|
+
const chatIdValue = useMemo(() => ({ chatId: 'replay' }), [])
|
|
115
|
+
|
|
113
116
|
return (
|
|
114
117
|
<QueryClientProvider client={replayQueryClient}>
|
|
115
118
|
<AssistantRuntimeProvider runtime={runtime}>
|
|
116
119
|
<ReplayContext.Provider value={replayCtx}>
|
|
117
120
|
<ElementsContext.Provider value={contextValue}>
|
|
118
|
-
<
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
config.variant === '
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
<ChatIdContext.Provider value={chatIdValue}>
|
|
122
|
+
<ToolApprovalProvider>
|
|
123
|
+
<div
|
|
124
|
+
className={cn(
|
|
125
|
+
ROOT_SELECTOR,
|
|
126
|
+
(config.variant === 'standalone' ||
|
|
127
|
+
config.variant === 'sidecar') &&
|
|
128
|
+
'h-full min-h-0 flex-1'
|
|
129
|
+
)}
|
|
130
|
+
>
|
|
131
|
+
{children}
|
|
132
|
+
</div>
|
|
133
|
+
<ReplayController cassette={cassette} options={replayOptions} />
|
|
134
|
+
</ToolApprovalProvider>
|
|
135
|
+
</ChatIdContext.Provider>
|
|
131
136
|
</ElementsContext.Provider>
|
|
132
137
|
</ReplayContext.Provider>
|
|
133
138
|
</AssistantRuntimeProvider>
|
|
@@ -69,7 +69,11 @@ export const ShadowRoot = ({
|
|
|
69
69
|
}, [shadowRoot, elementsStyles])
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<div
|
|
72
|
+
<div
|
|
73
|
+
ref={hostRef}
|
|
74
|
+
className={hostClassName}
|
|
75
|
+
style={{ isolation: 'isolate', ...hostStyle }}
|
|
76
|
+
>
|
|
73
77
|
{shadowRoot
|
|
74
78
|
? createPortal(
|
|
75
79
|
<div
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { X, Heart } from 'lucide-react'
|
|
2
|
-
import * as m from 'motion/react-m'
|
|
3
|
-
import { useState, type FC } from 'react'
|
|
4
|
-
import { AnimatePresence } from 'motion/react'
|
|
5
|
-
|
|
6
|
-
import { cn } from '@/lib/utils'
|
|
7
|
-
import { EASE_OUT_QUINT } from '@/lib/easing'
|
|
8
1
|
import {
|
|
9
2
|
Tooltip,
|
|
10
3
|
TooltipContent,
|
|
11
4
|
TooltipProvider,
|
|
12
5
|
TooltipTrigger,
|
|
13
6
|
} from '@/components/ui/tooltip'
|
|
7
|
+
import { EASE_OUT_QUINT } from '@/lib/easing'
|
|
8
|
+
import { cn } from '@/lib/utils'
|
|
9
|
+
import { Heart, X } from 'lucide-react'
|
|
10
|
+
import { AnimatePresence } from 'motion/react'
|
|
11
|
+
import * as m from 'motion/react-m'
|
|
12
|
+
import { useState, type FC } from 'react'
|
|
14
13
|
|
|
15
14
|
export type FeedbackType = 'dislike' | 'like'
|
|
16
15
|
|