@gram-ai/elements 1.2.3 → 1.2.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/README.md CHANGED
@@ -4,10 +4,19 @@ Elements is a library built for the agentic age. We provide customizable and ele
4
4
 
5
5
  ## Setup
6
6
 
7
- First ensure that you have installed the required peer dependencies:
7
+ ### Package Exports
8
+
9
+ This package provides two separate exports with different dependencies:
10
+
11
+ - **`@gram-ai/elements`** - React UI components (requires React and related dependencies)
12
+ - **`@gram-ai/elements/server`** - Server-side handlers (does NOT require React)
13
+
14
+ ### Frontend Setup
15
+
16
+ If you're using the React UI components, install the required peer dependencies:
8
17
 
9
18
  ```bash
10
- pnpm add react react-dom @assistant-ui/react @assistant-ui/react-markdown motion remark-gfm zustand ai
19
+ pnpm add react react-dom @assistant-ui/react @assistant-ui/react-markdown motion remark-gfm zustand
11
20
  ```
12
21
 
13
22
  Then install Elements:
@@ -16,6 +25,16 @@ Then install Elements:
16
25
  pnpm add @gram-ai/elements
17
26
  ```
18
27
 
28
+ ### Backend Setup
29
+
30
+ If you're only using the server handlers (`@gram-ai/elements/server`), you can install without React:
31
+
32
+ ```bash
33
+ pnpm add @gram-ai/elements
34
+ ```
35
+
36
+ > **Note:** Your package manager may show peer dependency warnings for React packages. These warnings are safe to ignore when using only `/server` exports, as React dependencies are marked as optional.
37
+
19
38
  ## Setting up your backend
20
39
 
21
40
  At the moment, we provide a set of handlers via the `@gram-ai/elements/server` package that you can use to automatically setup your backend for usage with Gram Elements. The example below demonstrates the setup for Express:
@@ -77,6 +96,207 @@ export const App = () => {
77
96
  }
78
97
  ```
79
98
 
99
+ ## Configuration
100
+
101
+ The `ElementsConfig` object accepts the following configuration options:
102
+
103
+ ### Top-Level Configuration
104
+
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 |
118
+
119
+ ### Welcome Configuration (`WelcomeConfig`)
120
+
121
+ | Property | Type | Required | Status | Default | Description |
122
+ | ------------- | ------------------------------------ | -------- | -------------- | ----------- | --------------------------------------------------------------- |
123
+ | `title` | `string` | Yes | ✅ Implemented | - | The welcome message title to display when the thread is empty |
124
+ | `subtitle` | `string` | Yes | ✅ Implemented | - | The subtitle to display when the thread is empty |
125
+ | `suggestions` | [`Suggestion[]`](#suggestion-object) | No | ✅ Implemented | `undefined` | Array of suggestion prompts to display when the thread is empty |
126
+
127
+ #### Suggestion Object
128
+
129
+ | Property | Type | Required | Status | Description |
130
+ | -------- | -------- | -------- | -------------- | ---------------------------------------------- |
131
+ | `title` | `string` | Yes | ✅ Implemented | The title of the suggestion |
132
+ | `label` | `string` | Yes | ✅ Implemented | The label text for the suggestion |
133
+ | `action` | `string` | Yes | ✅ Implemented | The prompt text that will be sent when clicked |
134
+
135
+ ### Composer Configuration (`ComposerConfig`)
136
+
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 |
141
+
142
+ ### Modal Configuration (`ModalConfig`)
143
+
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 |
149
+
150
+ ### Model Configuration (`ModelConfig`)
151
+
152
+ | Property | Type | Required | Status | Default | Description |
153
+ | ----------------- | ---------------------------- | -------- | -------------- | ------------------------------- | ------------------------------------------------ |
154
+ | `showModelPicker` | `boolean` | No | ✅ Implemented | `false` | Whether to show the model picker in the composer |
155
+ | `defaultModel` | [`Model`](#available-models) | No | ✅ Implemented | `'anthropic/claude-sonnet-4.5'` | The default model to use |
156
+
157
+ #### Available Models
158
+
159
+ The following models are currently supported:
160
+
161
+ - `anthropic/claude-sonnet-4.5`
162
+ - `anthropic/claude-haiku-4.5`
163
+ - `anthropic/claude-sonnet-4`
164
+ - `anthropic/claude-opus-4.5`
165
+ - `openai/gpt-4o`
166
+ - `openai/gpt-4o-mini`
167
+ - `openai/gpt-5.1-codex`
168
+ - `openai/gpt-5`
169
+ - `openai/gpt-5.1`
170
+ - `openai/gpt-4.1`
171
+ - `anthropic/claude-3.7-sonnet`
172
+ - `anthropic/claude-opus-4`
173
+ - `google/gemini-2.5-pro-preview`
174
+ - `google/gemini-3-pro-preview`
175
+ - `moonshotai/kimi-k2`
176
+ - `mistralai/mistral-medium-3`
177
+ - `mistralai/mistral-medium-3.1`
178
+ - `mistralai/codestral-2501`
179
+
180
+ ### Tools Configuration (`ToolsConfig`)
181
+
182
+ | Property | Type | Required | Status | Default | Description |
183
+ | ------------ | ---------------------------------------------- | -------- | -------------- | ----------- | ------------------------------------------------------------------------------------------ |
184
+ | `components` | `Record<string, ToolCallMessagePartComponent>` | No | ✅ Implemented | `undefined` | Override default React components for specific tool results. Tool names must match exactly |
185
+
186
+ ### Configuration Examples
187
+
188
+ #### Minimal Configuration
189
+
190
+ ```typescript
191
+ import { ElementsConfig } from '@gram-ai/elements'
192
+
193
+ const config: ElementsConfig = {
194
+ projectSlug: 'my-project',
195
+ mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
196
+ welcome: {
197
+ title: 'Welcome!',
198
+ subtitle: 'How can I assist you today?',
199
+ },
200
+ }
201
+ ```
202
+
203
+ #### Full Configuration with All Options
204
+
205
+ ```typescript
206
+ import { ElementsConfig } from '@gram-ai/elements'
207
+ import { WeatherComponent } from './components/WeatherComponent'
208
+
209
+ const config: ElementsConfig = {
210
+ projectSlug: 'my-project',
211
+ mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
212
+ chatEndpoint: '/api/chat',
213
+ variant: 'widget',
214
+ theme: 'system',
215
+ environment: {
216
+ API_KEY: 'your-api-key',
217
+ BASE_URL: 'https://api.example.com',
218
+ },
219
+ welcome: {
220
+ title: 'Hello!',
221
+ subtitle: 'How can I help you today?',
222
+ suggestions: [
223
+ {
224
+ title: 'Get Weather',
225
+ label: 'Check current weather',
226
+ action: 'What is the weather like today?',
227
+ },
228
+ {
229
+ title: 'Summarize',
230
+ label: 'Summarize a document',
231
+ action: 'Can you summarize this document for me?',
232
+ },
233
+ ],
234
+ },
235
+ composer: {
236
+ placeholder: 'Type your message...',
237
+ attachments: true,
238
+ },
239
+ modal: {
240
+ defaultOpen: false,
241
+ className: 'custom-modal-class',
242
+ },
243
+ model: {
244
+ showModelPicker: true,
245
+ defaultModel: 'anthropic/claude-sonnet-4.5',
246
+ },
247
+ tools: {
248
+ components: {
249
+ get_current_weather: WeatherComponent,
250
+ },
251
+ },
252
+ }
253
+ ```
254
+
255
+ #### Widget Variant with Custom Modal Icon
256
+
257
+ ```typescript
258
+ import { ElementsConfig } from '@gram-ai/elements'
259
+ import { MessageSquare, X } from 'lucide-react'
260
+
261
+ const config: ElementsConfig = {
262
+ projectSlug: 'my-project',
263
+ mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
264
+ variant: 'widget',
265
+ welcome: {
266
+ title: 'Chat with us!',
267
+ subtitle: 'Ask anything',
268
+ },
269
+ modal: {
270
+ defaultOpen: true,
271
+ icon: (state) => (state === 'open' ? <X /> : <MessageSquare />),
272
+ },
273
+ }
274
+ ```
275
+
276
+ #### Standalone Variant with Model Picker
277
+
278
+ ```typescript
279
+ import { ElementsConfig } from '@gram-ai/elements'
280
+
281
+ const config: ElementsConfig = {
282
+ projectSlug: 'my-project',
283
+ mcp: 'https://app.getgram.ai/mcp/my-mcp-slug',
284
+ variant: 'standalone',
285
+ welcome: {
286
+ title: 'AI Assistant',
287
+ subtitle: 'Choose a model and start chatting',
288
+ },
289
+ composer: {
290
+ placeholder: 'Ask me anything...',
291
+ attachments: true,
292
+ },
293
+ model: {
294
+ showModelPicker: true,
295
+ defaultModel: 'openai/gpt-4o',
296
+ },
297
+ }
298
+ ```
299
+
80
300
  ## Contributing
81
301
 
82
302
  We welcome pull requests to Elements. Please read the contributing guide.
@@ -38,6 +38,8 @@ export interface ElementsConfig {
38
38
  /**
39
39
  * Custom environment variable overrides for the Elements library.
40
40
  * Will be used to override the environment variables for the MCP server.
41
+ *
42
+ * TODO: Not yet functional
41
43
  */
42
44
  environment?: Record<string, unknown>;
43
45
  /**
@@ -58,6 +60,8 @@ export interface ElementsConfig {
58
60
  model?: ModelConfig;
59
61
  /**
60
62
  * The theme to use for the Elements library.
63
+ *
64
+ * TODO: Not yet implemented
61
65
  */
62
66
  theme?: 'light' | 'dark' | 'system';
63
67
  /**
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@gram-ai/elements",
3
3
  "description": "Gram Elements is a library of UI primitives for building chat-like experiences for MCP Servers.",
4
4
  "type": "module",
5
- "version": "1.2.3",
5
+ "version": "1.2.5",
6
6
  "main": "dist/index.js",
7
7
  "exports": {
8
8
  ".": {
@@ -48,7 +48,37 @@
48
48
  "remark-gfm": "^4.0.0",
49
49
  "zustand": "^5.0.0"
50
50
  },
51
+ "peerDependenciesMeta": {
52
+ "@assistant-ui/react": {
53
+ "optional": true
54
+ },
55
+ "@assistant-ui/react-markdown": {
56
+ "optional": true
57
+ },
58
+ "@types/react": {
59
+ "optional": true
60
+ },
61
+ "@types/react-dom": {
62
+ "optional": true
63
+ },
64
+ "motion": {
65
+ "optional": true
66
+ },
67
+ "react": {
68
+ "optional": true
69
+ },
70
+ "react-dom": {
71
+ "optional": true
72
+ },
73
+ "remark-gfm": {
74
+ "optional": true
75
+ },
76
+ "zustand": {
77
+ "optional": true
78
+ }
79
+ },
51
80
  "dependencies": {
81
+ "@ai-sdk/mcp": "^0.0.11",
52
82
  "@openrouter/ai-sdk-provider": "^1.4.1",
53
83
  "@radix-ui/react-avatar": "^1.1.10",
54
84
  "@radix-ui/react-collapsible": "^1.1.12",
@@ -56,6 +86,7 @@
56
86
  "@radix-ui/react-popover": "^1.1.15",
57
87
  "@radix-ui/react-slot": "^1.2.3",
58
88
  "@radix-ui/react-tooltip": "^1.2.8",
89
+ "ai": "5.0.90",
59
90
  "assistant-stream": "^0.2.42",
60
91
  "class-variance-authority": "^0.7.1",
61
92
  "clsx": "^2.1.1",
@@ -65,7 +96,6 @@
65
96
  "zod": "^4.1.13"
66
97
  },
67
98
  "devDependencies": {
68
- "@ai-sdk/mcp": "^0.0.11",
69
99
  "@ai-sdk/openai": "^2.0.0-beta.5",
70
100
  "@assistant-ui/react": "^0.11.37",
71
101
  "@assistant-ui/react-ai-sdk": "^1.1.16",
@@ -79,7 +109,6 @@
79
109
  "@types/lodash.merge": "^4.6.9",
80
110
  "@types/node": "^24.10.1",
81
111
  "@vitejs/plugin-react": "^5.0.3",
82
- "ai": "5.0.90",
83
112
  "chromatic": "^13.3.3",
84
113
  "eslint": "^9.39.1",
85
114
  "eslint-config-prettier": "^10.1.8",