@lobehub/chat 1.7.9 → 1.8.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.
Files changed (43) hide show
  1. package/.env.example +8 -0
  2. package/CHANGELOG.md +50 -0
  3. package/package.json +1 -1
  4. package/src/app/(main)/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +9 -5
  5. package/src/app/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +27 -10
  6. package/src/app/(main)/(mobile)/me/(home)/features/UserBanner.tsx +22 -3
  7. package/src/app/(main)/(mobile)/me/(home)/features/useCategory.tsx +2 -2
  8. package/src/app/(main)/settings/_layout/Mobile/Header.tsx +3 -2
  9. package/src/app/(main)/settings/common/features/Common.tsx +2 -43
  10. package/src/app/(main)/settings/common/features/Theme/index.tsx +10 -3
  11. package/src/app/api/auth/[...nextauth]/route.ts +2 -2
  12. package/src/app/api/auth/error/AuthErrorPage.tsx +38 -0
  13. package/src/app/api/auth/error/page.tsx +5 -0
  14. package/src/config/modelProviders/google.ts +12 -2
  15. package/src/database/server/migrations/0004_add_next_auth.sql +60 -0
  16. package/src/database/server/migrations/meta/0004_snapshot.json +2119 -0
  17. package/src/database/server/migrations/meta/_journal.json +7 -0
  18. package/src/database/server/models/__tests__/nextauth.test.ts +496 -0
  19. package/src/database/server/models/__tests__/user.test.ts +13 -0
  20. package/src/database/server/models/user.ts +4 -0
  21. package/src/database/server/schemas/lobechat.ts +7 -0
  22. package/src/database/server/schemas/nextauth.ts +90 -0
  23. package/src/layout/GlobalProvider/StoreInitialization.tsx +18 -3
  24. package/src/libs/next-auth/adapter/index.ts +264 -0
  25. package/src/libs/next-auth/adapter/utils.ts +62 -0
  26. package/src/libs/next-auth/auth.config.ts +45 -0
  27. package/src/libs/next-auth/edge.ts +26 -0
  28. package/src/libs/next-auth/index.ts +26 -39
  29. package/src/libs/next-auth/sso-providers/auth0.ts +11 -0
  30. package/src/libs/next-auth/sso-providers/authentik.ts +12 -0
  31. package/src/libs/next-auth/sso-providers/azure-ad.ts +12 -0
  32. package/src/libs/next-auth/sso-providers/github.ts +11 -0
  33. package/src/libs/next-auth/sso-providers/sso.config.ts +8 -0
  34. package/src/libs/next-auth/sso-providers/zitadel.ts +9 -0
  35. package/src/libs/trpc/middleware/password.test.ts +6 -0
  36. package/src/libs/trpc/middleware/userAuth.test.ts +6 -0
  37. package/src/middleware.ts +3 -2
  38. package/src/server/context.ts +22 -5
  39. package/src/server/routers/edge/config/index.test.ts +6 -0
  40. package/src/store/agent/slices/chat/action.test.ts +16 -2
  41. package/src/store/agent/slices/chat/action.ts +3 -2
  42. package/src/store/user/slices/auth/selectors.ts +2 -0
  43. package/src/types/next-auth.d.ts +3 -0
package/.env.example CHANGED
@@ -168,6 +168,14 @@ OPENAI_API_KEY=sk-xxxxxxxxx
168
168
  #CLERK_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxx
169
169
 
170
170
 
171
+ # NextAuth related configurations
172
+ # NEXT_AUTH_SECRET=
173
+
174
+ # Auth0 configurations
175
+ # AUTH0_CLIENT_ID=
176
+ # AUTH0_CLIENT_SECRET=
177
+ # AUTH0_ISSUER=https://your-domain.auth0.com
178
+
171
179
  ########################################
172
180
  ########## Server Database #############
173
181
  ########################################
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 1.8.0](https://github.com/lobehub/lobe-chat/compare/v1.7.10...v1.8.0)
6
+
7
+ <sup>Released on **2024-08-02**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Add NextAuth as authentication service in server database.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Add NextAuth as authentication service in server database, closes [#2935](https://github.com/lobehub/lobe-chat/issues/2935) ([5a0b972](https://github.com/lobehub/lobe-chat/commit/5a0b972))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 1.7.10](https://github.com/lobehub/lobe-chat/compare/v1.7.9...v1.7.10)
31
+
32
+ <sup>Released on **2024-08-02**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Add Gemini 1.5 Pro Exp model.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Add Gemini 1.5 Pro Exp model, closes [#3384](https://github.com/lobehub/lobe-chat/issues/3384) ([0de8b7b](https://github.com/lobehub/lobe-chat/commit/0de8b7b))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 1.7.9](https://github.com/lobehub/lobe-chat/compare/v1.7.8...v1.7.9)
6
56
 
7
57
  <sup>Released on **2024-08-01**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.7.9",
3
+ "version": "1.8.0",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -26,12 +26,16 @@ vi.mock('@/features/User/UserLoginOrSignup/Community', () => ({
26
26
 
27
27
  // 定义一个变量来存储 enableAuth 的值
28
28
  let enableAuth = true;
29
+ let enableClerk = false;
29
30
 
30
31
  // 模拟 @/const/auth 模块
31
32
  vi.mock('@/const/auth', () => ({
32
33
  get enableAuth() {
33
34
  return enableAuth;
34
35
  },
36
+ get enableClerk() {
37
+ return enableClerk;
38
+ },
35
39
  }));
36
40
 
37
41
  afterEach(() => {
@@ -41,9 +45,8 @@ afterEach(() => {
41
45
  describe('UserBanner', () => {
42
46
  it('should render UserInfo and DataStatistics when auth is disabled', () => {
43
47
  act(() => {
44
- useUserStore.setState({ isSignedIn: false });
48
+ useUserStore.setState({ isSignedIn: false, enableAuth: () => false });
45
49
  });
46
- enableAuth = false;
47
50
 
48
51
  render(<UserBanner />);
49
52
 
@@ -56,7 +59,8 @@ describe('UserBanner', () => {
56
59
  act(() => {
57
60
  useUserStore.setState({ isSignedIn: true });
58
61
  });
59
- enableAuth = true;
62
+
63
+ enableClerk = true;
60
64
 
61
65
  render(<UserBanner />);
62
66
 
@@ -67,9 +71,9 @@ describe('UserBanner', () => {
67
71
 
68
72
  it('should render UserLoginOrSignup when user is not logged in with auth enabled', () => {
69
73
  act(() => {
70
- useUserStore.setState({ isSignedIn: false });
74
+ useUserStore.setState({ isSignedIn: false, enableAuth: () => true });
71
75
  });
72
- enableAuth = true;
76
+ enableClerk = true;
73
77
 
74
78
  render(<UserBanner />);
75
79
 
@@ -24,7 +24,7 @@ vi.mock('../../settings/features/useCategory', () => ({
24
24
 
25
25
  // 定义一个变量来存储 enableAuth 的值
26
26
  let enableAuth = true;
27
- let enableClerk = true;
27
+ let enableClerk = false;
28
28
  // 模拟 @/const/auth 模块
29
29
  vi.mock('@/const/auth', () => ({
30
30
  get enableAuth() {
@@ -37,16 +37,16 @@ vi.mock('@/const/auth', () => ({
37
37
 
38
38
  afterEach(() => {
39
39
  enableAuth = true;
40
- enableClerk = true;
40
+ enableClerk = false;
41
41
  });
42
42
 
43
+ // 目前对 enableAuth 的判定是在 useUserStore 中,所以需要 mock useUserStore
44
+ // 类型定义: enableAuth: () => boolean
43
45
  describe('useCategory', () => {
44
46
  it('should return correct items when the user is logged in with authentication', () => {
45
47
  act(() => {
46
- useUserStore.setState({ isSignedIn: true });
48
+ useUserStore.setState({ isSignedIn: true, enableAuth: () => true });
47
49
  });
48
- enableAuth = true;
49
- enableClerk = false;
50
50
 
51
51
  const { result } = renderHook(() => useCategory());
52
52
 
@@ -65,7 +65,6 @@ describe('useCategory', () => {
65
65
  act(() => {
66
66
  useUserStore.setState({ isSignedIn: true });
67
67
  });
68
- enableAuth = true;
69
68
  enableClerk = true;
70
69
 
71
70
  const { result } = renderHook(() => useCategory());
@@ -81,11 +80,29 @@ describe('useCategory', () => {
81
80
  });
82
81
  });
83
82
 
83
+ it('should return correct items when the user is logged in with NextAuth', () => {
84
+ act(() => {
85
+ useUserStore.setState({ isSignedIn: true, enableAuth: () => true, enabledNextAuth: true });
86
+ });
87
+
88
+ const { result } = renderHook(() => useCategory());
89
+
90
+ act(() => {
91
+ const items = result.current;
92
+ // Should not render profile for NextAuth, it's Clerk only
93
+ expect(items.some((item) => item.key === 'profile')).toBe(false);
94
+ expect(items.some((item) => item.key === 'setting')).toBe(true);
95
+ expect(items.some((item) => item.key === 'data')).toBe(true);
96
+ expect(items.some((item) => item.key === 'docs')).toBe(true);
97
+ expect(items.some((item) => item.key === 'feedback')).toBe(true);
98
+ expect(items.some((item) => item.key === 'discord')).toBe(true);
99
+ });
100
+ });
101
+
84
102
  it('should return correct items when the user is not logged in', () => {
85
103
  act(() => {
86
- useUserStore.setState({ isSignedIn: false });
104
+ useUserStore.setState({ isSignedIn: false, enableAuth: () => true });
87
105
  });
88
- enableAuth = true;
89
106
 
90
107
  const { result } = renderHook(() => useCategory());
91
108
 
@@ -102,9 +119,9 @@ describe('useCategory', () => {
102
119
 
103
120
  it('should handle settings for non-authenticated users', () => {
104
121
  act(() => {
105
- useUserStore.setState({ isSignedIn: false });
122
+ useUserStore.setState({ isSignedIn: false, enableAuth: () => false });
106
123
  });
107
- enableAuth = false;
124
+ enableClerk = false;
108
125
 
109
126
  const { result } = renderHook(() => useCategory());
110
127
 
@@ -4,7 +4,6 @@ import { useRouter } from 'next/navigation';
4
4
  import { memo } from 'react';
5
5
  import { Flexbox } from 'react-layout-kit';
6
6
 
7
- import { enableAuth } from '@/const/auth';
8
7
  import DataStatistics from '@/features/User/DataStatistics';
9
8
  import UserInfo from '@/features/User/UserInfo';
10
9
  import UserLoginOrSignup from '@/features/User/UserLoginOrSignup/Community';
@@ -14,6 +13,11 @@ import { authSelectors } from '@/store/user/selectors';
14
13
  const UserBanner = memo(() => {
15
14
  const router = useRouter();
16
15
  const isLoginWithAuth = useUserStore(authSelectors.isLoginWithAuth);
16
+ const [enableAuth, signIn, enabledNextAuth] = useUserStore((s) => [
17
+ authSelectors.enabledAuth(s),
18
+ s.openLogin,
19
+ authSelectors.enabledNextAuth(s),
20
+ ]);
17
21
 
18
22
  return (
19
23
  <Flexbox gap={12} paddingBlock={8}>
@@ -24,11 +28,26 @@ const UserBanner = memo(() => {
24
28
  </>
25
29
  ) : isLoginWithAuth ? (
26
30
  <>
27
- <UserInfo onClick={() => router.push('/me/profile')} />
31
+ <UserInfo
32
+ onClick={() => {
33
+ // Profile page only works with Clerk
34
+ if (enabledNextAuth) return;
35
+ router.push('/me/profile');
36
+ }}
37
+ />
28
38
  <DataStatistics paddingInline={12} />
29
39
  </>
30
40
  ) : (
31
- <UserLoginOrSignup onClick={() => router.push('/login')} />
41
+ <UserLoginOrSignup
42
+ onClick={() => {
43
+ // If use NextAuth, call openLogin method directly
44
+ if (enabledNextAuth) {
45
+ signIn();
46
+ return;
47
+ }
48
+ router.push('/login');
49
+ }}
50
+ />
32
51
  )}
33
52
  </Flexbox>
34
53
  );
@@ -4,7 +4,6 @@ import { useRouter } from 'next/navigation';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
6
  import { CellProps } from '@/components/Cell';
7
- import { enableAuth } from '@/const/auth';
8
7
  import { DISCORD, DOCUMENTS, FEEDBACK } from '@/const/url';
9
8
  import { isServerMode } from '@/const/version';
10
9
  import { usePWAInstall } from '@/hooks/usePWAInstall';
@@ -17,10 +16,11 @@ export const useCategory = () => {
17
16
  const router = useRouter();
18
17
  const { canInstall, install } = usePWAInstall();
19
18
  const { t } = useTranslation(['common', 'setting', 'auth']);
20
- const [isLogin, isLoginWithAuth, isLoginWithClerk] = useUserStore((s) => [
19
+ const [isLogin, isLoginWithAuth, isLoginWithClerk, enableAuth] = useUserStore((s) => [
21
20
  authSelectors.isLogin(s),
22
21
  authSelectors.isLoginWithAuth(s),
23
22
  authSelectors.isLoginWithClerk(s),
23
+ authSelectors.enabledAuth(s),
24
24
  ]);
25
25
 
26
26
  const profile: CellProps[] = [
@@ -7,9 +7,10 @@ import { memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
9
 
10
- import { enableAuth } from '@/const/auth';
11
10
  import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
12
11
  import { SettingsTabs } from '@/store/global/initialState';
12
+ import { useUserStore } from '@/store/user';
13
+ import { authSelectors } from '@/store/user/selectors';
13
14
  import { mobileHeaderSticky } from '@/styles/mobileHeader';
14
15
 
15
16
  const Header = memo(() => {
@@ -19,6 +20,7 @@ const Header = memo(() => {
19
20
  const searchParams = useSearchParams();
20
21
  const activeSettingsKey = useActiveSettingsKey();
21
22
 
23
+ const enableAuth = useUserStore(authSelectors.enabledAuth);
22
24
  const handleBackClick = () => {
23
25
  if (searchParams.has('session') && searchParams.has('showMobileWorkspace')) {
24
26
  router.push(`/chat?${searchParams.toString()}`);
@@ -26,7 +28,6 @@ const Header = memo(() => {
26
28
  router.push(enableAuth ? '/me/settings' : '/me');
27
29
  }
28
30
  };
29
-
30
31
  return (
31
32
  <MobileNavBar
32
33
  center={
@@ -16,7 +16,7 @@ import { serverConfigSelectors } from '@/store/serverConfig/selectors';
16
16
  import { useSessionStore } from '@/store/session';
17
17
  import { useToolStore } from '@/store/tool';
18
18
  import { useUserStore } from '@/store/user';
19
- import { settingsSelectors, userProfileSelectors } from '@/store/user/selectors';
19
+ import { settingsSelectors } from '@/store/user/selectors';
20
20
 
21
21
  type SettingItemGroup = ItemGroup;
22
22
 
@@ -24,10 +24,7 @@ const Common = memo(() => {
24
24
  const { t } = useTranslation('setting');
25
25
  const [form] = Form.useForm();
26
26
 
27
- const isSignedIn = useUserStore((s) => s.isSignedIn);
28
27
  const showAccessCodeConfig = useServerConfigStore(serverConfigSelectors.enabledAccessCode);
29
- const showOAuthLogin = useServerConfigStore(serverConfigSelectors.enabledOAuthSSO);
30
- const user = useUserStore(userProfileSelectors.userProfile, isEqual);
31
28
 
32
29
  const [clearSessions, clearSessionGroups] = useSessionStore((s) => [
33
30
  s.clearSessions,
@@ -40,31 +37,10 @@ const Common = memo(() => {
40
37
  const [removeAllFiles] = useFileStore((s) => [s.removeAllFiles]);
41
38
  const removeAllPlugins = useToolStore((s) => s.removeAllPlugins);
42
39
  const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
43
- const [setSettings, resetSettings, signIn, signOut] = useUserStore((s) => [
44
- s.setSettings,
45
- s.resetSettings,
46
- s.openLogin,
47
- s.logout,
48
- ]);
40
+ const [setSettings, resetSettings] = useUserStore((s) => [s.setSettings, s.resetSettings]);
49
41
 
50
42
  const { message, modal } = App.useApp();
51
43
 
52
- const handleSignOut = useCallback(() => {
53
- modal.confirm({
54
- centered: true,
55
- okButtonProps: { danger: true },
56
- onOk: () => {
57
- signOut();
58
- message.success(t('settingSystem.oauth.signout.success'));
59
- },
60
- title: t('settingSystem.oauth.signout.confirm'),
61
- });
62
- }, []);
63
-
64
- const handleSignIn = useCallback(() => {
65
- signIn();
66
- }, []);
67
-
68
44
  const handleReset = useCallback(() => {
69
45
  modal.confirm({
70
46
  centered: true,
@@ -112,23 +88,6 @@ const Common = memo(() => {
112
88
  label: t('settingSystem.accessCode.title'),
113
89
  name: ['keyVaults', 'password'],
114
90
  },
115
- {
116
- children: isSignedIn ? (
117
- <Button onClick={handleSignOut}>{t('settingSystem.oauth.signout.action')}</Button>
118
- ) : (
119
- <Button onClick={handleSignIn} type="primary">
120
- {t('settingSystem.oauth.signin.action')}
121
- </Button>
122
- ),
123
- desc: isSignedIn
124
- ? `${user?.email} ${t('settingSystem.oauth.info.desc')}`
125
- : t('settingSystem.oauth.signin.desc'),
126
- hidden: !showOAuthLogin,
127
- label: isSignedIn
128
- ? t('settingSystem.oauth.info.title')
129
- : t('settingSystem.oauth.signin.title'),
130
- minWidth: undefined,
131
- },
132
91
  {
133
92
  children: (
134
93
  <Button danger onClick={handleReset} type="primary">
@@ -9,13 +9,16 @@ import { memo } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
11
11
  import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
12
- import { enableAuth } from '@/const/auth';
13
12
  import { FORM_STYLE } from '@/const/layoutTokens';
14
13
  import { imageUrl } from '@/const/url';
15
14
  import AvatarWithUpload from '@/features/AvatarWithUpload';
16
15
  import { Locales, localeOptions } from '@/locales/resources';
17
16
  import { useUserStore } from '@/store/user';
18
- import { settingsSelectors, userGeneralSettingsSelectors } from '@/store/user/selectors';
17
+ import {
18
+ authSelectors,
19
+ settingsSelectors,
20
+ userGeneralSettingsSelectors,
21
+ } from '@/store/user/selectors';
19
22
  import { switchLang } from '@/utils/client/switchLang';
20
23
 
21
24
  import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from './ThemeSwatches';
@@ -28,7 +31,11 @@ const Theme = memo(() => {
28
31
  const [form] = Form.useForm();
29
32
  const settings = useUserStore(settingsSelectors.currentSettings, isEqual);
30
33
  const themeMode = useUserStore(userGeneralSettingsSelectors.currentThemeMode);
31
- const [setThemeMode, setSettings] = useUserStore((s) => [s.switchThemeMode, s.setSettings]);
34
+ const [setThemeMode, setSettings, enableAuth] = useUserStore((s) => [
35
+ s.switchThemeMode,
36
+ s.setSettings,
37
+ authSelectors.enabledAuth(s),
38
+ ]);
32
39
 
33
40
  useSyncSettings(form);
34
41
 
@@ -1,3 +1,3 @@
1
- export { GET, POST } from '@/libs/next-auth';
1
+ import NextAuthNode from '@/libs/next-auth';
2
2
 
3
- export const runtime = 'edge'; // optional
3
+ export const { GET, POST } = NextAuthNode.handlers;
@@ -0,0 +1,38 @@
1
+ import { signIn } from 'next-auth/react';
2
+ import { useSearchParams } from 'next/navigation';
3
+ import { memo } from 'react';
4
+
5
+ import ErrorCapture from '@/components/Error';
6
+
7
+ enum ErrorEnum {
8
+ AccessDenied = 'AccessDenied',
9
+ Configuration = 'Configuration',
10
+ Default = 'Default',
11
+ Verification = 'Verification',
12
+ }
13
+
14
+ const errorMap = {
15
+ [ErrorEnum.Configuration]:
16
+ 'Wrong configuration, make sure you have the correct environment variables set. Visit https://lobehub.com/docs/self-hosting/advanced/authentication for more details.',
17
+ [ErrorEnum.AccessDenied]:
18
+ 'Access was denied. Visit https://authjs.dev/reference/core/errors#accessdenied for more details. ',
19
+ [ErrorEnum.Verification]:
20
+ 'Verification error, visit https://authjs.dev/reference/core/errors#verification for more details.',
21
+ [ErrorEnum.Default]:
22
+ 'There was a problem when trying to authenticate. Visit https://authjs.dev/reference/core/errors for more details.',
23
+ };
24
+
25
+ export default memo(() => {
26
+ const search = useSearchParams();
27
+ const error = search.get('error') as ErrorEnum;
28
+ const props = {
29
+ error: {
30
+ cause: error,
31
+ message: errorMap[error] || 'Unknown error type.',
32
+ name: 'NextAuth Error',
33
+ },
34
+ reset: () => signIn(undefined, { callbackUrl: '/' }),
35
+ };
36
+ console.log('[NextAuth] Error:', props.error);
37
+ return <ErrorCapture {...props} />;
38
+ });
@@ -0,0 +1,5 @@
1
+ 'use client';
2
+
3
+ import dynamic from 'next/dynamic';
4
+
5
+ export default dynamic(() => import('./AuthErrorPage'));
@@ -24,7 +24,7 @@ const Google: ModelProviderCard = {
24
24
  vision: true,
25
25
  },
26
26
  {
27
- description: 'Mid-size multimodal model that supports up to 1 million tokens',
27
+ description: 'Mid-size multimodal model that supports up to 2 million tokens',
28
28
  displayName: 'Gemini 1.5 Pro',
29
29
  enabled: true,
30
30
  functionCall: true,
@@ -34,7 +34,7 @@ const Google: ModelProviderCard = {
34
34
  vision: true,
35
35
  },
36
36
  {
37
- description: 'Mid-size multimodal model that supports up to 1 million tokens',
37
+ description: 'Mid-size multimodal model that supports up to 2 million tokens',
38
38
  displayName: 'Gemini 1.5 Pro 001',
39
39
  functionCall: true,
40
40
  id: 'gemini-1.5-pro-001',
@@ -42,6 +42,16 @@ const Google: ModelProviderCard = {
42
42
  tokens: 2_097_152 + 8192,
43
43
  vision: true,
44
44
  },
45
+ {
46
+ description: 'Mid-size multimodal model that supports up to 2 million tokens',
47
+ displayName: 'Gemini 1.5 Pro Experimental 0801',
48
+ enabled: true,
49
+ functionCall: true,
50
+ id: 'gemini-1.5-pro-exp-0801',
51
+ maxOutput: 8192,
52
+ tokens: 2_097_152 + 8192,
53
+ vision: true,
54
+ },
45
55
  {
46
56
  description:
47
57
  'The best model for scaling across a wide range of tasks. This is the latest model.',
@@ -0,0 +1,60 @@
1
+ CREATE TABLE IF NOT EXISTS "nextauth_accounts" (
2
+ "access_token" text,
3
+ "expires_at" integer,
4
+ "id_token" text,
5
+ "provider" text NOT NULL,
6
+ "providerAccountId" text NOT NULL,
7
+ "refresh_token" text,
8
+ "scope" text,
9
+ "session_state" text,
10
+ "token_type" text,
11
+ "type" text NOT NULL,
12
+ "userId" text NOT NULL,
13
+ CONSTRAINT "nextauth_accounts_provider_providerAccountId_pk" PRIMARY KEY("provider","providerAccountId")
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE TABLE IF NOT EXISTS "nextauth_authenticators" (
17
+ "counter" integer NOT NULL,
18
+ "credentialBackedUp" boolean NOT NULL,
19
+ "credentialDeviceType" text NOT NULL,
20
+ "credentialID" text NOT NULL,
21
+ "credentialPublicKey" text NOT NULL,
22
+ "providerAccountId" text NOT NULL,
23
+ "transports" text,
24
+ "userId" text NOT NULL,
25
+ CONSTRAINT "nextauth_authenticators_userId_credentialID_pk" PRIMARY KEY("userId","credentialID"),
26
+ CONSTRAINT "nextauth_authenticators_credentialID_unique" UNIQUE("credentialID")
27
+ );
28
+ --> statement-breakpoint
29
+ CREATE TABLE IF NOT EXISTS "nextauth_sessions" (
30
+ "expires" timestamp NOT NULL,
31
+ "sessionToken" text PRIMARY KEY NOT NULL,
32
+ "userId" text NOT NULL
33
+ );
34
+ --> statement-breakpoint
35
+ CREATE TABLE IF NOT EXISTS "nextauth_verificationtokens" (
36
+ "expires" timestamp NOT NULL,
37
+ "identifier" text NOT NULL,
38
+ "token" text NOT NULL,
39
+ CONSTRAINT "nextauth_verificationtokens_identifier_token_pk" PRIMARY KEY("identifier","token")
40
+ );
41
+ --> statement-breakpoint
42
+ ALTER TABLE "users" ADD COLUMN "full_name" text;--> statement-breakpoint
43
+ ALTER TABLE "users" ADD COLUMN "email_verified_at" timestamp with time zone;--> statement-breakpoint
44
+ DO $$ BEGIN
45
+ ALTER TABLE "nextauth_accounts" ADD CONSTRAINT "nextauth_accounts_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
46
+ EXCEPTION
47
+ WHEN duplicate_object THEN null;
48
+ END $$;
49
+ --> statement-breakpoint
50
+ DO $$ BEGIN
51
+ ALTER TABLE "nextauth_authenticators" ADD CONSTRAINT "nextauth_authenticators_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
52
+ EXCEPTION
53
+ WHEN duplicate_object THEN null;
54
+ END $$;
55
+ --> statement-breakpoint
56
+ DO $$ BEGIN
57
+ ALTER TABLE "nextauth_sessions" ADD CONSTRAINT "nextauth_sessions_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
58
+ EXCEPTION
59
+ WHEN duplicate_object THEN null;
60
+ END $$;