@gram-ai/elements 1.8.4 → 1.10.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/README.md CHANGED
@@ -80,7 +80,6 @@ const config: ElementsConfig = {
80
80
  },
81
81
  composer: {
82
82
  placeholder: 'Ask me anything...',
83
- attachments: true,
84
83
  },
85
84
  modal: {
86
85
  defaultOpen: true,
@@ -102,19 +101,21 @@ The `ElementsConfig` object accepts the following configuration options:
102
101
 
103
102
  ### Top-Level Configuration
104
103
 
105
- | Property | Type | Required | Status | Default | Description |
106
- | -------------- | ---------------------------------------------------------- | -------- | ---------------------- | --------------------- | --------------------------------------------------------------------------------------------------- |
107
- | `projectSlug` | `string` | Yes | ✅ Implemented | - | The project slug to use for the Elements library |
108
- | `mcp` | `string` | Yes | ✅ Implemented | - | The Gram Server URL. Can be retrieved from `https://app.getgram.ai/{team}/{project}/mcp/{mcp_slug}` |
109
- | `chatEndpoint` | `string` | No | ✅ Implemented | `'/chat/completions'` | The path of your backend's chat endpoint |
110
- | `environment` | `Record<string, unknown>` | No | ✅ Implemented | `undefined` | Custom environment variable overrides for the MCP server |
111
- | `variant` | `'widget' \| 'standalone'` | No | ✅ Implemented | `undefined` | Whether to render the chat window inside an expandable modal or as a standalone chat window |
112
- | `theme` | `'light' \| 'dark' \| 'system'` | No | ⚠️ Not yet implemented | `undefined` | The theme to use for the Elements library |
113
- | `welcome` | [`WelcomeConfig`](#welcome-configuration-welcomeconfig) | Yes | ✅ Implemented | - | Configuration for the welcome message and initial suggestions |
114
- | `composer` | [`ComposerConfig`](#composer-configuration-composerconfig) | No | ✅ Implemented | `undefined` | Configuration for the composer input |
115
- | `modal` | [`ModalConfig`](#modal-configuration-modalconfig) | No | ✅ Implemented | `undefined` | Configuration for the modal window (only applies when `variant` is `'widget'`) |
116
- | `model` | [`ModelConfig`](#model-configuration-modelconfig) | No | ✅ Implemented | `undefined` | LLM model configuration |
117
- | `tools` | [`ToolsConfig`](#tools-configuration-toolsconfig) | No | ✅ Implemented | `undefined` | Configuration for custom tool components |
104
+ | Property | Type | Required | Status | Default | Description |
105
+ | -------------- | ---------------------------------------------------------- | -------- | -------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
106
+ | `systemPrompt` | `string` | No | ✅ Implemented | `undefined` | The system prompt to use for the Elements library |
107
+ | `projectSlug` | `string` | Yes | ✅ Implemented | - | The project slug to use for the Elements library |
108
+ | `mcp` | `string` | Yes | ✅ Implemented | - | The Gram Server URL. Can be retrieved from `https://app.getgram.ai/{team}/{project}/mcp/{mcp_slug}` |
109
+ | `chatEndpoint` | `string` | No | ✅ Implemented | `'/chat/completions'` | The path of your backend's chat endpoint |
110
+ | `environment` | `Record<string, unknown>` | No | ✅ Implemented | `undefined` | Custom environment variable overrides for the MCP server. See [Gram documentation](https://www.speakeasy.com/docs/gram/host-mcp/public-private-servers#pass-through-authentication) for pass-through authentication |
111
+ | `variant` | `'widget' \| 'sidecar' \| 'standalone'` | No | Implemented | `'widget'` | The layout variant for the chat interface. `widget` is a popup modal, `sidecar` is a side panel, `standalone` is a full-page experience |
112
+ | `theme` | [`ThemeConfig`](#theme-configuration-themeconfig) | No | ✅ Implemented | `undefined` | Visual appearance configuration options |
113
+ | `welcome` | [`WelcomeConfig`](#welcome-configuration-welcomeconfig) | Yes | ✅ Implemented | - | Configuration for the welcome message and initial suggestions |
114
+ | `composer` | [`ComposerConfig`](#composer-configuration-composerconfig) | No | ✅ Implemented | `undefined` | Configuration for the composer input |
115
+ | `modal` | [`ModalConfig`](#modal-configuration-modalconfig) | No | ✅ Implemented | `undefined` | Configuration for the modal window (does not apply if variant is `'standalone'`) |
116
+ | `sidecar` | [`SidecarConfig`](#sidecar-configuration-sidecarconfig) | No | ✅ Implemented | `undefined` | Configuration for the sidecar panel (only applies if variant is `'sidecar'`) |
117
+ | `model` | [`ModelConfig`](#model-configuration-modelconfig) | No | ✅ Implemented | `undefined` | LLM model configuration |
118
+ | `tools` | [`ToolsConfig`](#tools-configuration-toolsconfig) | No | ✅ Implemented | `undefined` | Configuration for custom tool components |
118
119
 
119
120
  ### Welcome Configuration (`WelcomeConfig`)
120
121
 
@@ -134,18 +135,53 @@ The `ElementsConfig` object accepts the following configuration options:
134
135
 
135
136
  ### Composer Configuration (`ComposerConfig`)
136
137
 
137
- | Property | Type | Required | Status | Default | Description |
138
- | ------------- | --------- | -------- | ---------------------- | ------- | --------------------------------------------- |
139
- | `placeholder` | `string` | Yes | ✅ Implemented | - | The placeholder text for the composer input |
140
- | `attachments` | `boolean` | Yes | ⚠️ Not yet implemented | - | Whether to enable attachments in the composer |
138
+ | Property | Type | Required | Status | Default | Description |
139
+ | ------------- | -------------------------------------------------------------------------------- | -------- | ---------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
140
+ | `placeholder` | `string` | No | ✅ Implemented | `'Send a message...'` | The placeholder text for the composer input |
141
+ | `attachments` | `boolean \| `[`AttachmentsConfig`](#attachments-configuration-attachmentsconfig) | No | ⚠️ Not yet implemented | `true` | Configuration for file attachments. Set to `false` to disable, `true` for defaults, or provide an object for fine-grained control |
142
+
143
+ #### Attachments Configuration (`AttachmentsConfig`)
144
+
145
+ | Property | Type | Required | Status | Default | Description |
146
+ | ---------- | ---------- | -------- | ---------------------- | ----------- | --------------------------------------------------------------------------- |
147
+ | `accept` | `string[]` | No | ⚠️ Not yet implemented | `undefined` | Accepted file types (MIME types or extensions), e.g., `['image/*', '.pdf']` |
148
+ | `maxCount` | `number` | No | ⚠️ Not yet implemented | `10` | Maximum number of files that can be attached at once |
149
+ | `maxSize` | `number` | No | ⚠️ Not yet implemented | `104857600` | Maximum file size in bytes (default: 100MB) |
141
150
 
142
151
  ### Modal Configuration (`ModalConfig`)
143
152
 
144
- | Property | Type | Required | Status | Default | Description |
145
- | ------------- | ------------------------------------------------------- | -------- | -------------- | ----------- | ------------------------------------------------------------ |
146
- | `defaultOpen` | `boolean` | No | ✅ Implemented | `false` | Whether to open the modal window by default |
147
- | `icon` | `(state: 'open' \| 'closed' \| undefined) => ReactNode` | No | ✅ Implemented | `undefined` | Custom icon component function that receives the modal state |
148
- | `className` | `string` | No | ✅ Implemented | `undefined` | Additional CSS class name to apply to the modal window |
153
+ | Property | Type | Required | Status | Default | Description |
154
+ | ------------- | ----------------------------------------------------------------------------------- | -------- | -------------- | ---------------- | ------------------------------------------------------------ |
155
+ | `defaultOpen` | `boolean` | No | ✅ Implemented | `false` | Whether to open the modal window by default |
156
+ | `title` | `string` | No | ✅ Implemented | `'Chat'` | The title displayed in the modal header |
157
+ | `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | No | ✅ Implemented | `'bottom-right'` | The position of the modal trigger button |
158
+ | `icon` | `(state: 'open' \| 'closed' \| undefined) => ReactNode` | No | ✅ Implemented | `undefined` | Custom icon component function that receives the modal state |
159
+ | `expandable` | `boolean` | No | ✅ Implemented | `false` | Whether the modal can be expanded to full screen |
160
+ | `dimensions` | `{ default: ModalDimension, expanded?: Pick<ModalDimension, 'width' \| 'height'> }` | No | ✅ Implemented | `undefined` | The dimensions for default and expanded states of the modal |
161
+
162
+ #### Modal Dimension Object
163
+
164
+ | Property | Type | Description |
165
+ | ----------- | ------------------------ | -------------------------------------- |
166
+ | `width` | `number \| '${number}%'` | Width of the modal |
167
+ | `height` | `number \| '${number}%'` | Height of the modal |
168
+ | `maxHeight` | `number \| '${number}%'` | Maximum height of the modal (optional) |
169
+
170
+ ### Sidecar Configuration (`SidecarConfig`)
171
+
172
+ | Property | Type | Required | Status | Default | Description |
173
+ | --------------- | ---------------------------------- | -------- | -------------- | --------- | -------------------------------------------- |
174
+ | `title` | `string` | No | ✅ Implemented | `'Chat'` | The title displayed in the sidecar header |
175
+ | `width` | `string \| number \| '${number}%'` | No | ✅ Implemented | `'400px'` | The width of the sidecar panel |
176
+ | `expandedWidth` | `string \| number \| '${number}%'` | No | ✅ Implemented | `'800px'` | The width of the sidecar panel when expanded |
177
+
178
+ ### Theme Configuration (`ThemeConfig`)
179
+
180
+ | Property | Type | Required | Status | Default | Description |
181
+ | ------------- | ------------------------------------- | -------- | -------------- | ---------- | --------------------------------------------------------------------------------------- |
182
+ | `colorScheme` | `'light' \| 'dark' \| 'system'` | No | ✅ Implemented | `'light'` | The color scheme to use for the UI |
183
+ | `density` | `'compact' \| 'normal' \| 'spacious'` | No | ✅ Implemented | `'normal'` | Determines the overall spacing. `compact` reduces padding, `spacious` increases padding |
184
+ | `radius` | `'round' \| 'soft' \| 'sharp'` | No | ✅ Implemented | `'soft'` | Determines the overall roundness. `round` is large radius, `sharp` is minimal radius |
149
185
 
150
186
  ### Model Configuration (`ModelConfig`)
151
187
 
@@ -207,11 +243,16 @@ import { ElementsConfig } from '@gram-ai/elements'
207
243
  import { WeatherComponent } from './components/WeatherComponent'
208
244
 
209
245
  const config: ElementsConfig = {
246
+ systemPrompt: 'You are a helpful AI assistant.',
210
247
  projectSlug: 'my-project',
211
248
  mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
212
249
  chatEndpoint: '/api/chat',
213
250
  variant: 'widget',
214
- theme: 'system',
251
+ theme: {
252
+ colorScheme: 'system',
253
+ density: 'normal',
254
+ radius: 'soft',
255
+ },
215
256
  environment: {
216
257
  API_KEY: 'your-api-key',
217
258
  BASE_URL: 'https://api.example.com',
@@ -234,11 +275,23 @@ const config: ElementsConfig = {
234
275
  },
235
276
  composer: {
236
277
  placeholder: 'Type your message...',
237
- attachments: true,
238
278
  },
239
279
  modal: {
240
280
  defaultOpen: false,
241
- className: 'custom-modal-class',
281
+ title: 'AI Assistant',
282
+ position: 'bottom-right',
283
+ expandable: true,
284
+ dimensions: {
285
+ default: {
286
+ width: 400,
287
+ height: 600,
288
+ maxHeight: '90%',
289
+ },
290
+ expanded: {
291
+ width: '90%',
292
+ height: '90%',
293
+ },
294
+ },
242
295
  },
243
296
  model: {
244
297
  showModelPicker: true,
@@ -288,7 +341,6 @@ const config: ElementsConfig = {
288
341
  },
289
342
  composer: {
290
343
  placeholder: 'Ask me anything...',
291
- attachments: true,
292
344
  },
293
345
  model: {
294
346
  showModelPicker: true,
@@ -297,6 +349,32 @@ const config: ElementsConfig = {
297
349
  }
298
350
  ```
299
351
 
352
+ #### Sidecar Variant with Custom Theme
353
+
354
+ ```typescript
355
+ import { ElementsConfig } from '@gram-ai/elements'
356
+
357
+ const config: ElementsConfig = {
358
+ projectSlug: 'my-project',
359
+ mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
360
+ variant: 'sidecar',
361
+ theme: {
362
+ colorScheme: 'dark',
363
+ density: 'compact',
364
+ radius: 'round',
365
+ },
366
+ welcome: {
367
+ title: 'Support Chat',
368
+ subtitle: "We're here to help",
369
+ },
370
+ sidecar: {
371
+ title: 'Customer Support',
372
+ width: '450px',
373
+ expandedWidth: '900px',
374
+ },
375
+ }
376
+ ```
377
+
300
378
  ## Contributing
301
379
 
302
380
  We welcome pull requests to Elements. Please read the contributing guide.
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const AssistantSidecar: FC;
@@ -0,0 +1,5 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ export declare const ToolGroup: FC<PropsWithChildren<{
3
+ startIndex: number;
4
+ endIndex: number;
5
+ }>>;
@@ -1,7 +1,7 @@
1
1
  import { VariantProps } from 'class-variance-authority';
2
2
  import * as React from 'react';
3
3
  declare const Button: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
4
- variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
4
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
5
  size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
6
6
  } & import('class-variance-authority/types').ClassProp) | undefined) => string> & {
7
7
  asChild?: boolean;
@@ -1,4 +1,4 @@
1
1
  export declare const buttonVariants: (props?: ({
2
- variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
2
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
3
3
  size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
4
4
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -0,0 +1,32 @@
1
+ import * as React from 'react';
2
+ type ToolStatus = 'pending' | 'running' | 'complete' | 'error';
3
+ interface ToolUIProps {
4
+ /** Display name of the tool */
5
+ name: string;
6
+ /** Optional icon to display (defaults to first letter of name) */
7
+ icon?: React.ReactNode;
8
+ /** Provider/source name (e.g., "Notion", "GitHub") */
9
+ provider?: string;
10
+ /** Current status of the tool execution */
11
+ status?: ToolStatus;
12
+ /** Request/input data - can be string or object */
13
+ request?: string | Record<string, unknown>;
14
+ /** Result/output data - can be string or object */
15
+ result?: string | Record<string, unknown>;
16
+ /** Whether the tool card starts expanded */
17
+ defaultExpanded?: boolean;
18
+ /** Additional class names */
19
+ className?: string;
20
+ }
21
+ interface ToolUISectionProps {
22
+ /** Section title */
23
+ title: string;
24
+ /** Content to display - string or object (will be JSON stringified) */
25
+ content: string | Record<string, unknown>;
26
+ /** Whether section starts expanded */
27
+ defaultExpanded?: boolean;
28
+ }
29
+ declare function ToolUISection({ title, content, defaultExpanded, }: ToolUISectionProps): import("react/jsx-runtime").JSX.Element;
30
+ declare function ToolUI({ name, icon, provider, status, request, result, defaultExpanded, className, }: ToolUIProps): import("react/jsx-runtime").JSX.Element;
31
+ export { ToolUI, ToolUISection };
32
+ export type { ToolUIProps, ToolUISectionProps, ToolStatus };