@gram-ai/elements 1.18.7 → 1.18.8
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/ConnectionConfiguration.stories.d.ts +10 -0
- package/dist/components/Chat/stories/{Customization.stories.d.ts → CustomComponents.stories.d.ts} +1 -3
- package/dist/elements.cjs +28 -28
- package/dist/elements.cjs.map +1 -1
- package/dist/elements.js +1248 -1244
- package/dist/elements.js.map +1 -1
- package/dist/hooks/useAuth.d.ts +2 -2
- package/dist/lib/auth.d.ts +3 -2
- package/dist/types/index.d.ts +33 -12
- package/package.json +1 -1
- package/src/components/Chat/stories/{Customization.stories.tsx → ConnectionConfiguration.stories.tsx} +38 -19
- package/src/components/Chat/stories/CustomComponents.stories.tsx +46 -0
- package/src/hooks/useAuth.ts +14 -6
- package/src/lib/auth.ts +9 -2
- package/src/types/index.ts +37 -12
package/dist/hooks/useAuth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ApiConfig } from '../types';
|
|
2
2
|
export type Auth = {
|
|
3
3
|
headers: Record<string, string>;
|
|
4
4
|
isLoading: false;
|
|
@@ -11,6 +11,6 @@ export type Auth = {
|
|
|
11
11
|
* @returns The session token string or null
|
|
12
12
|
*/
|
|
13
13
|
export declare const useAuth: ({ projectSlug, auth, }: {
|
|
14
|
-
auth?:
|
|
14
|
+
auth?: ApiConfig;
|
|
15
15
|
projectSlug: string;
|
|
16
16
|
}) => Auth;
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ApiKeyAuthConfig,
|
|
1
|
+
import { ApiKeyAuthConfig, ApiConfig, SessionAuthConfig } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Checks if the auth config is an API key auth config
|
|
4
4
|
*/
|
|
5
|
-
export declare function isApiKeyAuth(auth:
|
|
5
|
+
export declare function isApiKeyAuth(auth: ApiConfig | undefined): auth is ApiKeyAuthConfig;
|
|
6
|
+
export declare function hasExplicitSessionAuth(auth: ApiConfig | undefined): auth is SessionAuthConfig;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -231,18 +231,36 @@ export interface ElementsConfig {
|
|
|
231
231
|
* }
|
|
232
232
|
*/
|
|
233
233
|
tools?: ToolsConfig;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
234
|
+
/**
|
|
235
|
+
* The API configuration to use for the Elements library.
|
|
236
|
+
*
|
|
237
|
+
* Use this to override the default API URL, or add explicit auth configuration
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* const config: ElementsConfig = {
|
|
241
|
+
* api: {
|
|
242
|
+
* url: 'https://api.getgram.ai',
|
|
243
|
+
* },
|
|
244
|
+
* }
|
|
245
|
+
*/
|
|
246
|
+
api?: ApiConfig;
|
|
245
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Base API configuration with the server URL.
|
|
250
|
+
*/
|
|
251
|
+
export type BaseApiConfig = {
|
|
252
|
+
/**
|
|
253
|
+
* The Gram API URL to use for the Elements library.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* const config: ElementsConfig = {
|
|
257
|
+
* api: {
|
|
258
|
+
* url: 'https://api.getgram.ai',
|
|
259
|
+
* },
|
|
260
|
+
* }
|
|
261
|
+
*/
|
|
262
|
+
url?: string;
|
|
263
|
+
};
|
|
246
264
|
export type SessionAuthConfig = {
|
|
247
265
|
/**
|
|
248
266
|
* The function to use to retrieve the session token from the backend endpoint.
|
|
@@ -287,7 +305,10 @@ export type ApiKeyAuthConfig = {
|
|
|
287
305
|
*/
|
|
288
306
|
UNSAFE_apiKey: string;
|
|
289
307
|
};
|
|
290
|
-
|
|
308
|
+
/**
|
|
309
|
+
* API configuration - can be just the URL, or URL with session auth, or URL with API key auth.
|
|
310
|
+
*/
|
|
311
|
+
export type ApiConfig = BaseApiConfig | (BaseApiConfig & SessionAuthConfig) | (BaseApiConfig & ApiKeyAuthConfig);
|
|
291
312
|
/**
|
|
292
313
|
* The LLM model to use for the Elements library.
|
|
293
314
|
*
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
1
|
import { Chat } from '..'
|
|
3
2
|
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
4
|
-
import { useAssistantState } from '@assistant-ui/react'
|
|
5
3
|
import { google } from '@ai-sdk/google'
|
|
6
|
-
import {
|
|
4
|
+
import { GetSessionFn } from '@/types'
|
|
7
5
|
|
|
8
6
|
const meta: Meta<typeof Chat> = {
|
|
9
|
-
title: 'Chat/
|
|
7
|
+
title: 'Chat/Connection Configuration',
|
|
10
8
|
component: Chat,
|
|
11
9
|
parameters: {
|
|
12
10
|
layout: 'fullscreen',
|
|
@@ -35,26 +33,47 @@ SystemPrompt.parameters = {
|
|
|
35
33
|
},
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
export const WithImplicitSessionAuth: Story = () => <Chat />
|
|
37
|
+
WithImplicitSessionAuth.storyName = 'With Implicit Session Auth'
|
|
38
|
+
WithImplicitSessionAuth.parameters = {
|
|
39
|
+
elements: {
|
|
40
|
+
config: {
|
|
41
|
+
// This story tests the case where no API config is provided, which should default to implicit session auth
|
|
42
|
+
api: undefined,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const sessionFn: GetSessionFn = async () => {
|
|
48
|
+
const response = await fetch('/chat/session', {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: {
|
|
51
|
+
'Gram-Project':
|
|
52
|
+
import.meta.env.VITE_GRAM_ELEMENTS_STORYBOOK_PROJECT_SLUG ?? '',
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
const data = await response.json()
|
|
56
|
+
return data.client_token
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const WithExplicitSessionAuth: Story = () => <Chat />
|
|
60
|
+
WithExplicitSessionAuth.storyName = 'With Explicit Session Auth'
|
|
61
|
+
WithExplicitSessionAuth.parameters = {
|
|
62
|
+
elements: {
|
|
63
|
+
config: {
|
|
64
|
+
api: { sessionFn },
|
|
65
|
+
},
|
|
48
66
|
},
|
|
49
67
|
}
|
|
50
68
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
69
|
+
// NOTE: api key auth is currently non functional due to concerns with security
|
|
70
|
+
// Update this story when api key auth is secure
|
|
71
|
+
export const WithExplicitAPIKeyAuth: Story = () => <Chat />
|
|
72
|
+
WithExplicitAPIKeyAuth.storyName = 'With Explicit API Key Auth'
|
|
73
|
+
WithExplicitAPIKeyAuth.parameters = {
|
|
54
74
|
elements: {
|
|
55
75
|
config: {
|
|
56
|
-
|
|
57
|
-
components: customComponents,
|
|
76
|
+
api: { UNSAFE_apiKey: 'test' },
|
|
58
77
|
},
|
|
59
78
|
},
|
|
60
79
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Chat, ComponentOverrides } from '@/index'
|
|
2
|
+
import { useAssistantState } from '@assistant-ui/react'
|
|
3
|
+
import { Meta, StoryFn } from '@storybook/react-vite'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Chat> = {
|
|
6
|
+
title: 'Chat/Customization',
|
|
7
|
+
component: Chat,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'fullscreen',
|
|
10
|
+
},
|
|
11
|
+
decorators: [
|
|
12
|
+
(Story) => (
|
|
13
|
+
<div className="m-auto flex h-screen w-full max-w-3xl flex-col">
|
|
14
|
+
<Story />
|
|
15
|
+
</div>
|
|
16
|
+
),
|
|
17
|
+
],
|
|
18
|
+
} satisfies Meta<typeof Chat>
|
|
19
|
+
|
|
20
|
+
export default meta
|
|
21
|
+
|
|
22
|
+
type Story = StoryFn<typeof Chat>
|
|
23
|
+
|
|
24
|
+
const customComponents: ComponentOverrides = {
|
|
25
|
+
Text: () => {
|
|
26
|
+
const message = useAssistantState(({ message }) => message)
|
|
27
|
+
return (
|
|
28
|
+
<div className="text-red-500">
|
|
29
|
+
{message.parts
|
|
30
|
+
.map((part) => (part.type === 'text' ? part.text : ''))
|
|
31
|
+
.join('')}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const ComponentOverridesStory: Story = () => <Chat />
|
|
38
|
+
ComponentOverridesStory.storyName = 'Component Overrides'
|
|
39
|
+
ComponentOverridesStory.parameters = {
|
|
40
|
+
elements: {
|
|
41
|
+
config: {
|
|
42
|
+
variant: 'standalone',
|
|
43
|
+
components: customComponents,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
}
|
package/src/hooks/useAuth.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isApiKeyAuth } from '@/lib/auth'
|
|
2
|
-
import {
|
|
1
|
+
import { hasExplicitSessionAuth, isApiKeyAuth } from '@/lib/auth'
|
|
2
|
+
import { ApiConfig } from '../types'
|
|
3
3
|
import { useSession } from './useSession'
|
|
4
|
+
import { useMemo } from 'react'
|
|
4
5
|
|
|
5
6
|
export type Auth =
|
|
6
7
|
| {
|
|
@@ -33,17 +34,24 @@ export const useAuth = ({
|
|
|
33
34
|
projectSlug,
|
|
34
35
|
auth,
|
|
35
36
|
}: {
|
|
36
|
-
auth?:
|
|
37
|
+
auth?: ApiConfig
|
|
37
38
|
projectSlug: string
|
|
38
39
|
}): Auth => {
|
|
40
|
+
const getSession = useMemo(() => {
|
|
41
|
+
if (isApiKeyAuth(auth)) {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
return !isApiKeyAuth(auth) && hasExplicitSessionAuth(auth)
|
|
45
|
+
? auth.sessionFn
|
|
46
|
+
: defaultGetSession
|
|
47
|
+
}, [auth])
|
|
39
48
|
// The session request is only neccessary if we are not using an API key auth
|
|
40
49
|
// configuration. If a custom session fetcher is provided, we use it,
|
|
41
50
|
// otherwise we fallback to the default session fetcher
|
|
42
51
|
const session = useSession({
|
|
52
|
+
// We want to check it's NOT API key auth, as the default auth scheme is session auth (if the user hasn't provided an explicit API config, we have a session auth config by default)
|
|
43
53
|
enabled: !isApiKeyAuth(auth),
|
|
44
|
-
getSession
|
|
45
|
-
? (auth?.sessionFn ?? defaultGetSession)
|
|
46
|
-
: null,
|
|
54
|
+
getSession,
|
|
47
55
|
projectSlug,
|
|
48
56
|
})
|
|
49
57
|
|
package/src/lib/auth.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import { ApiKeyAuthConfig,
|
|
1
|
+
import { ApiKeyAuthConfig, ApiConfig, SessionAuthConfig } from '@/types'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Checks if the auth config is an API key auth config
|
|
5
5
|
*/
|
|
6
6
|
export function isApiKeyAuth(
|
|
7
|
-
auth:
|
|
7
|
+
auth: ApiConfig | undefined
|
|
8
8
|
): auth is ApiKeyAuthConfig {
|
|
9
9
|
return !!auth && 'UNSAFE_apiKey' in auth
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
export function hasExplicitSessionAuth(
|
|
13
|
+
auth: ApiConfig | undefined
|
|
14
|
+
): auth is SessionAuthConfig {
|
|
15
|
+
if (!auth) return false
|
|
16
|
+
return 'sessionFn' in auth
|
|
17
|
+
}
|
package/src/types/index.ts
CHANGED
|
@@ -261,17 +261,36 @@ export interface ElementsConfig {
|
|
|
261
261
|
*/
|
|
262
262
|
tools?: ToolsConfig
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
264
|
+
/**
|
|
265
|
+
* The API configuration to use for the Elements library.
|
|
266
|
+
*
|
|
267
|
+
* Use this to override the default API URL, or add explicit auth configuration
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* const config: ElementsConfig = {
|
|
271
|
+
* api: {
|
|
272
|
+
* url: 'https://api.getgram.ai',
|
|
273
|
+
* },
|
|
274
|
+
* }
|
|
275
|
+
*/
|
|
276
|
+
api?: ApiConfig
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Base API configuration with the server URL.
|
|
281
|
+
*/
|
|
282
|
+
export type BaseApiConfig = {
|
|
283
|
+
/**
|
|
284
|
+
* The Gram API URL to use for the Elements library.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* const config: ElementsConfig = {
|
|
288
|
+
* api: {
|
|
289
|
+
* url: 'https://api.getgram.ai',
|
|
290
|
+
* },
|
|
291
|
+
* }
|
|
292
|
+
*/
|
|
293
|
+
url?: string
|
|
275
294
|
}
|
|
276
295
|
|
|
277
296
|
export type SessionAuthConfig = {
|
|
@@ -320,7 +339,13 @@ export type ApiKeyAuthConfig = {
|
|
|
320
339
|
UNSAFE_apiKey: string
|
|
321
340
|
}
|
|
322
341
|
|
|
323
|
-
|
|
342
|
+
/**
|
|
343
|
+
* API configuration - can be just the URL, or URL with session auth, or URL with API key auth.
|
|
344
|
+
*/
|
|
345
|
+
export type ApiConfig =
|
|
346
|
+
| BaseApiConfig
|
|
347
|
+
| (BaseApiConfig & SessionAuthConfig)
|
|
348
|
+
| (BaseApiConfig & ApiKeyAuthConfig)
|
|
324
349
|
|
|
325
350
|
/**
|
|
326
351
|
* The LLM model to use for the Elements library.
|