@gram-ai/elements 1.23.0 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/dist/components/Chat/stories/MessageFeedback.stories.d.ts +28 -0
- package/dist/components/Chat/stories/Thread.stories.d.ts +15 -0
- package/dist/components/Replay.d.ts +11 -0
- package/dist/components/Replay.stories.d.ts +34 -0
- package/dist/components/assistant-ui/follow-on-suggestions.d.ts +6 -0
- package/dist/components/assistant-ui/message-feedback.d.ts +9 -0
- package/dist/components/ui/popover.d.ts +3 -1
- package/dist/contexts/ReplayContext.d.ts +6 -0
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +10 -8
- package/dist/hooks/useFollowOnSuggestions.d.ts +14 -0
- package/dist/hooks/useMCPTools.d.ts +4 -3
- package/dist/hooks/useRecordCassette.d.ts +32 -0
- package/dist/{index-D-QXb5EF.js → index-BdS8cb9a.js} +12083 -10638
- package/dist/index-BdS8cb9a.js.map +1 -0
- package/dist/index-ChnOovCM.cjs +178 -0
- package/dist/index-ChnOovCM.cjs.map +1 -0
- package/dist/{index-vM3v0unX.js → index-CtyV0c-T.js} +5477 -5450
- package/dist/index-CtyV0c-T.js.map +1 -0
- package/dist/{index-Co05S1C8.cjs → index-iUSSoKFz.cjs} +12 -12
- package/dist/index-iUSSoKFz.cjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/lib/cassette.d.ts +46 -0
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-Dshm-O8k.cjs → profiler-DLQjMw2x.cjs} +2 -2
- package/dist/{profiler-Dshm-O8k.cjs.map → profiler-DLQjMw2x.cjs.map} +1 -1
- package/dist/{profiler-D8-vgPGn.js → profiler-zOZcyzDP.js} +2 -2
- package/dist/{profiler-D8-vgPGn.js.map → profiler-zOZcyzDP.js.map} +1 -1
- package/dist/{startRecording-DnWeZRhl.js → startRecording-BwSGOvz9.js} +2 -2
- package/dist/{startRecording-DnWeZRhl.js.map → startRecording-BwSGOvz9.js.map} +1 -1
- package/dist/{startRecording-2p7-xVUh.cjs → startRecording-D7lN7PSs.cjs} +2 -2
- package/dist/{startRecording-2p7-xVUh.cjs.map → startRecording-D7lN7PSs.cjs.map} +1 -1
- package/dist/types/index.d.ts +37 -0
- package/package.json +5 -4
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +169 -0
- package/src/components/Chat/stories/Thread.stories.tsx +78 -0
- package/src/components/Chat/stories/Variants.stories.tsx +5 -1
- package/src/components/Replay.stories.tsx +326 -0
- package/src/components/Replay.tsx +241 -0
- package/src/components/assistant-ui/follow-on-suggestions.tsx +122 -0
- package/src/components/assistant-ui/markdown-text.tsx +6 -7
- package/src/components/assistant-ui/message-feedback.tsx +177 -0
- package/src/components/assistant-ui/thread-list.tsx +6 -6
- package/src/components/assistant-ui/thread.tsx +322 -83
- package/src/components/assistant-ui/tool-fallback.tsx +1 -1
- package/src/components/assistant-ui/tool-group.tsx +27 -16
- package/src/components/ui/popover.tsx +18 -11
- package/src/components/ui/tool-ui.tsx +107 -32
- package/src/components/ui/tooltip.tsx +2 -2
- package/src/contexts/ElementsProvider.tsx +7 -2
- package/src/contexts/ReplayContext.ts +7 -0
- package/src/global.css +14 -8
- package/src/hooks/useAuth.ts +3 -0
- package/src/hooks/useFollowOnSuggestions.ts +237 -0
- package/src/hooks/useMCPTools.ts +32 -12
- package/src/hooks/useRecordCassette.ts +79 -0
- package/src/index.ts +10 -0
- package/src/lib/cassette.ts +260 -0
- package/src/plugins/chart/component.tsx +48 -11
- package/src/plugins/components/PluginLoadingState.tsx +2 -2
- package/src/types/index.ts +40 -0
- package/src/vite-env.d.ts +1 -0
- package/dist/index-CVYyyxfm.cjs +0 -147
- package/dist/index-CVYyyxfm.cjs.map +0 -1
- package/dist/index-Co05S1C8.cjs.map +0 -1
- package/dist/index-D-QXb5EF.js.map +0 -1
- package/dist/index-vM3v0unX.js.map +0 -1
package/README.md
CHANGED
|
@@ -263,6 +263,67 @@ To create your own plugins, see the comprehensive [Plugin Development Guide](./s
|
|
|
263
263
|
- Real-world examples
|
|
264
264
|
- Troubleshooting tips
|
|
265
265
|
|
|
266
|
+
## Replay
|
|
267
|
+
|
|
268
|
+
Replay lets you play back a pre-recorded conversation with streaming animations — no auth, MCP, or network calls required. This is useful for marketing demos, documentation, and testing.
|
|
269
|
+
|
|
270
|
+
### Recording a cassette
|
|
271
|
+
|
|
272
|
+
A cassette is a JSON file that captures a conversation. To record one from a live chat session, enable the built-in recorder by setting this environment variable:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
VITE_ELEMENTS_ENABLE_CASSETTE_RECORDING=true
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
This adds a record button to the composer. Click it to open the recorder popover, then start recording. Chat normally, and when you're done, click **Stop & Download** to save the cassette as a `.cassette.json` file.
|
|
279
|
+
|
|
280
|
+
You can also record programmatically using the `useRecordCassette` hook:
|
|
281
|
+
|
|
282
|
+
```tsx
|
|
283
|
+
import {
|
|
284
|
+
GramElementsProvider,
|
|
285
|
+
Chat,
|
|
286
|
+
useRecordCassette,
|
|
287
|
+
} from '@gram-ai/elements'
|
|
288
|
+
|
|
289
|
+
function RecordableChat() {
|
|
290
|
+
const { isRecording, startRecording, download } = useRecordCassette()
|
|
291
|
+
return (
|
|
292
|
+
<>
|
|
293
|
+
<Chat />
|
|
294
|
+
<button onClick={startRecording}>Record</button>
|
|
295
|
+
<button onClick={() => download('demo')}>Save</button>
|
|
296
|
+
</>
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Playing back a cassette
|
|
302
|
+
|
|
303
|
+
Use the `<Replay>` component, which replaces `GramElementsProvider` entirely:
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
import { Replay, Chat } from '@gram-ai/elements'
|
|
307
|
+
import cassette from './demo.cassette.json'
|
|
308
|
+
|
|
309
|
+
function MarketingDemo() {
|
|
310
|
+
return (
|
|
311
|
+
<Replay cassette={cassette} config={{ variant: 'standalone' }}>
|
|
312
|
+
<Chat />
|
|
313
|
+
</Replay>
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
`<Replay>` accepts optional timing props to control the playback speed:
|
|
319
|
+
|
|
320
|
+
| Prop | Default | Description |
|
|
321
|
+
| --------------------- | ------- | ----------------------------------------------- |
|
|
322
|
+
| `typingSpeed` | `15` | Milliseconds per character for streaming |
|
|
323
|
+
| `userMessageDelay` | `800` | Milliseconds before each user message appears |
|
|
324
|
+
| `assistantStartDelay` | `400` | Milliseconds before the assistant starts typing |
|
|
325
|
+
| `onComplete` | — | Callback when replay finishes |
|
|
326
|
+
|
|
266
327
|
## Contributing
|
|
267
328
|
|
|
268
329
|
We welcome pull requests to Elements. Please read the contributing guide.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Chat } from '..';
|
|
2
|
+
import { Meta, StoryFn } from '@storybook/react-vite';
|
|
3
|
+
declare const meta: Meta<typeof Chat>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryFn<typeof Chat>;
|
|
6
|
+
/**
|
|
7
|
+
* The feedback buttons appear on the last assistant message after it finishes streaming.
|
|
8
|
+
* Send a message to see the feedback UI animate in.
|
|
9
|
+
*/
|
|
10
|
+
export declare const Default: Story;
|
|
11
|
+
/**
|
|
12
|
+
* Widget variant with feedback buttons.
|
|
13
|
+
*/
|
|
14
|
+
export declare const Widget: Story;
|
|
15
|
+
/**
|
|
16
|
+
* Sidecar variant with feedback buttons.
|
|
17
|
+
*/
|
|
18
|
+
export declare const Sidecar: Story;
|
|
19
|
+
/**
|
|
20
|
+
* Demonstrates feedback UI combined with follow-up suggestions.
|
|
21
|
+
* After the assistant responds, you'll see both AI-generated follow-up questions
|
|
22
|
+
* and feedback buttons (like/dislike) to mark the conversation as resolved.
|
|
23
|
+
*/
|
|
24
|
+
export declare const WithFollowUpSuggestions: Story;
|
|
25
|
+
/**
|
|
26
|
+
* Standalone component demo showing the feedback buttons in isolation.
|
|
27
|
+
*/
|
|
28
|
+
export declare const ComponentOnly: StoryFn;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Meta, StoryFn } from '@storybook/react-vite';
|
|
2
|
+
import { Chat } from '..';
|
|
3
|
+
declare const meta: Meta<typeof Chat>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryFn<typeof Chat>;
|
|
6
|
+
/**
|
|
7
|
+
* Demonstrates follow-up suggestions that appear after the assistant responds.
|
|
8
|
+
* Send a message and watch as AI-generated follow-up questions appear below the response.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FollowUpSuggestions: Story;
|
|
11
|
+
/**
|
|
12
|
+
* Shows the thread with follow-up suggestions disabled.
|
|
13
|
+
* No suggestions will appear after the assistant responds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const FollowUpSuggestionsDisabled: Story;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Cassette, ReplayOptions } from '../lib/cassette';
|
|
2
|
+
import { ElementsConfig } from '../types';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
export interface ReplayProps extends ReplayOptions {
|
|
5
|
+
/** The recorded cassette to replay. */
|
|
6
|
+
cassette: Cassette;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
/** Optional ElementsConfig for visual customization (theme, variant, etc.) */
|
|
9
|
+
config?: Partial<ElementsConfig>;
|
|
10
|
+
}
|
|
11
|
+
export declare const Replay: ({ cassette, children, config: partialConfig, typingSpeed, userMessageDelay, assistantStartDelay, onComplete, }: ReplayProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { StoryFn } from '@storybook/react-vite';
|
|
2
|
+
import { Replay } from './Replay';
|
|
3
|
+
declare const meta: any;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryFn<typeof Replay>;
|
|
6
|
+
/**
|
|
7
|
+
* Basic text conversation replay. Messages stream in character-by-character
|
|
8
|
+
* with a typing effect, just like a real chat session.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TextConversation: Story;
|
|
11
|
+
/**
|
|
12
|
+
* Replay with tool calls. The assistant invokes tools with visible
|
|
13
|
+
* arguments and results, demonstrating the tool call rendering pipeline.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ToolCalls: Story;
|
|
16
|
+
/**
|
|
17
|
+
* Replay with reasoning (chain-of-thought) content. The assistant's
|
|
18
|
+
* internal reasoning is shown before the final response.
|
|
19
|
+
*/
|
|
20
|
+
export declare const Reasoning: Story;
|
|
21
|
+
/**
|
|
22
|
+
* Multi-turn conversation with multiple user/assistant exchanges,
|
|
23
|
+
* demonstrating extended conversations with rich markdown formatting.
|
|
24
|
+
*/
|
|
25
|
+
export declare const MultiTurn: Story;
|
|
26
|
+
/**
|
|
27
|
+
* Replay rendered in the widget (modal) variant, showing how replays
|
|
28
|
+
* work inside a modal container.
|
|
29
|
+
*/
|
|
30
|
+
export declare const WidgetVariant: Story;
|
|
31
|
+
/**
|
|
32
|
+
* Fast replay with minimal delays — useful for quick demos or testing.
|
|
33
|
+
*/
|
|
34
|
+
export declare const FastReplay: Story;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
export type FeedbackType = 'dislike' | 'like';
|
|
3
|
+
interface MessageFeedbackProps {
|
|
4
|
+
onFeedback?: (type: FeedbackType) => void;
|
|
5
|
+
onResolved?: () => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const MessageFeedback: FC<MessageFeedbackProps>;
|
|
9
|
+
export {};
|
|
@@ -2,6 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
3
3
|
declare function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
declare function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
declare function PopoverContent({ className, align, sideOffset, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>
|
|
5
|
+
declare function PopoverContent({ className, align, sideOffset, container, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content> & {
|
|
6
|
+
container?: HTMLElement | null;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
8
|
declare function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>): import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
package/dist/elements.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-ChnOovCM.cjs"),r=require("./index-iUSSoKFz.cjs");exports.Chat=e.Chat;exports.ChatHistory=e.ChatHistory;exports.ElementsProvider=e.ElementsProvider;exports.GramElementsProvider=e.ElementsProvider;exports.MODELS=e.MODELS;exports.Replay=e.Replay;exports.ShareButton=e.ShareButton;exports.defineFrontendTool=e.defineFrontendTool;exports.trackError=e.trackError;exports.useRecordCassette=e.useRecordCassette;exports.useThreadId=e.useThreadId;exports.useElements=r.useElements;exports.useGramElements=r.useElements;
|
|
2
2
|
//# sourceMappingURL=elements.cjs.map
|