@lobehub/chat 1.9.1 → 1.9.3

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 (37) hide show
  1. package/.env.example +1 -1
  2. package/CHANGELOG.md +50 -0
  3. package/docs/self-hosting/examples/azure-openai.zh-CN.mdx +1 -1
  4. package/drizzle.config.ts +1 -1
  5. package/locales/ar/modelProvider.json +1 -1
  6. package/locales/bg-BG/modelProvider.json +1 -1
  7. package/locales/en-US/setting.json +1 -1
  8. package/locales/ja-JP/modelProvider.json +1 -1
  9. package/locales/nl-NL/modelProvider.json +1 -1
  10. package/locales/pl-PL/modelProvider.json +1 -1
  11. package/locales/pt-BR/setting.json +1 -1
  12. package/locales/tr-TR/modelProvider.json +1 -1
  13. package/locales/tr-TR/setting.json +1 -1
  14. package/locales/vi-VN/setting.json +1 -1
  15. package/locales/zh-CN/error.json +1 -1
  16. package/locales/zh-CN/modelProvider.json +1 -1
  17. package/locales/zh-CN/setting.json +1 -1
  18. package/locales/zh-TW/modelProvider.json +1 -1
  19. package/package.json +3 -3
  20. package/src/app/(main)/settings/llm/ProviderList/Azure/index.tsx +3 -0
  21. package/src/app/api/chat/agentRuntime.test.ts +1 -1
  22. package/src/config/modelProviders/ai360.ts +0 -10
  23. package/src/config/modelProviders/anthropic.ts +1 -4
  24. package/src/config/modelProviders/azure.ts +23 -4
  25. package/src/config/modelProviders/groq.ts +0 -1
  26. package/src/database/server/schemas/lobechat/_helpers.ts +6 -0
  27. package/src/database/server/schemas/{lobechat.ts → lobechat/chat.ts} +4 -335
  28. package/src/database/server/schemas/lobechat/discover.ts +84 -0
  29. package/src/database/server/schemas/lobechat/file.ts +28 -0
  30. package/src/database/server/schemas/lobechat/index.ts +6 -0
  31. package/src/database/server/schemas/{nextauth.ts → lobechat/nextauth.ts} +1 -2
  32. package/src/database/server/schemas/lobechat/relations.ts +138 -0
  33. package/src/database/server/schemas/lobechat/user.ts +111 -0
  34. package/src/libs/agent-runtime/AgentRuntime.test.ts +1 -1
  35. package/src/locales/default/modelProvider.ts +1 -1
  36. package/src/services/__tests__/chat.test.ts +1 -1
  37. package/src/database/server/schemas/_id.ts +0 -15
package/.env.example CHANGED
@@ -33,7 +33,7 @@ OPENAI_API_KEY=sk-xxxxxxxxx
33
33
  # AZURE_ENDPOINT=https://docs-test-001.openai.azure.com
34
34
 
35
35
  # Azure's API version, follows the YYYY-MM-DD format
36
- # AZURE_API_VERSION=2024-02-01
36
+ # AZURE_API_VERSION=2024-06-01
37
37
 
38
38
 
39
39
  ### Anthropic Service ####
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.9.3](https://github.com/lobehub/lobe-chat/compare/v1.9.2...v1.9.3)
6
+
7
+ <sup>Released on **2024-08-06**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor server db schema for better code organize.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor server db schema for better code organize, closes [#3410](https://github.com/lobehub/lobe-chat/issues/3410) ([4743bfd](https://github.com/lobehub/lobe-chat/commit/4743bfd))
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.9.2](https://github.com/lobehub/lobe-chat/compare/v1.9.1...v1.9.2)
31
+
32
+ <sup>Released on **2024-08-05**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **config**: Update Azure model and API versions.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **config**: Update Azure model and API versions, closes [#3405](https://github.com/lobehub/lobe-chat/issues/3405) ([a4938eb](https://github.com/lobehub/lobe-chat/commit/a4938eb))
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.9.1](https://github.com/lobehub/lobe-chat/compare/v1.9.0...v1.9.1)
6
56
 
7
57
  <sup>Released on **2024-08-05**</sup>
@@ -28,7 +28,7 @@ LobeChat 支持使用 [Azure OpenAI](https://learn.microsoft.com/zh-cn/azure/ai-
28
28
 
29
29
  - **APIKey**:你在 Azure OpenAI 账户页面申请的 API 密钥,可在 “密钥和终结点” 部分中找到此值
30
30
  - **API 地址**:Azure API 地址,从 Azure 门户检查资源时,可在 “密钥和终结点” 部分中找到此值
31
- - **Azure Api Version**: Azure 的 API 版本,遵循 YYYY-MM-DD 格式,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)
31
+ - **Azure API Version**: Azure 的 API 版本,遵循 YYYY-MM-DD 格式,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)
32
32
  - **模型列表**: 用来控制模型列表,你可以自行配置你的部署模型。
33
33
 
34
34
  完成上述字段配置后,点击「检查」,如果提示「检查通过」,则说明配置成功。
package/drizzle.config.ts CHANGED
@@ -24,6 +24,6 @@ export default {
24
24
  dialect: 'postgresql',
25
25
  out: './src/database/server/migrations',
26
26
 
27
- schema: './src/database/server/schemas/lobechat.ts',
27
+ schema: './src/database/server/schemas/lobechat',
28
28
  strict: true,
29
29
  } satisfies Config;
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "نسخة API الخاصة بـ Azure، والتي تتبع تنسيق YYYY-MM-DD، راجع [الإصدارات الأحدث](https://learn.microsoft.com/zh-en/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "جلب القائمة",
6
- "title": "Azure Api Version"
6
+ "title": "Azure API Version"
7
7
  },
8
8
  "empty": "الرجاء إدخال معرف النموذج لإضافة أول نموذج",
9
9
  "endpoint": {
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Версия на Azure API, в формат YYYY-MM-DD, вижте [най-новата версия](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "Извличане на списък",
6
- "title": "Версия на Azure Api"
6
+ "title": "Версия на Azure API"
7
7
  },
8
8
  "empty": "Моля, въведете идентификатор на модела, за да добавите първия модел",
9
9
  "endpoint": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "checker": {
53
53
  "button": "Check",
54
- "desc": "Test if the Api Key and proxy address are filled in correctly",
54
+ "desc": "Test if the API Key and proxy address are filled in correctly",
55
55
  "pass": "Check Passed",
56
56
  "title": "Connectivity Check"
57
57
  },
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Azure の API バージョン、YYYY-MM-DD 形式に従う、[最新バージョン](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)を参照",
5
5
  "fetch": "リストを取得",
6
- "title": "Azure Api Version"
6
+ "title": "Azure API Version"
7
7
  },
8
8
  "empty": "モデル ID を入力して最初のモデルを追加してください",
9
9
  "endpoint": {
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "De API-versie van Azure, volgt het formaat YYYY-MM-DD, raadpleeg [de nieuwste versie](https://learn.microsoft.com/nl-nl/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "Lijst ophalen",
6
- "title": "Azure Api Versie"
6
+ "title": "Azure API Versie"
7
7
  },
8
8
  "empty": "Voer een model-ID in om het eerste model toe te voegen",
9
9
  "endpoint": {
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Wersja API Azure, stosuj format YYYY-MM-DD, zobacz [najnowszą wersję](https://learn.microsoft.com/pl-pl/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "Pobierz listę",
6
- "title": "Wersja Azure Api"
6
+ "title": "Wersja Azure API"
7
7
  },
8
8
  "empty": "Wprowadź identyfikator modelu, aby dodać pierwszy model",
9
9
  "endpoint": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "checker": {
53
53
  "button": "Verificar",
54
- "desc": "Verifica se a Api Key e o endereço do proxy estão preenchidos corretamente",
54
+ "desc": "Verifica se a API Key e o endereço do proxy estão preenchidos corretamente",
55
55
  "pass": "Verificação aprovada",
56
56
  "title": "Verificação de Conectividade"
57
57
  },
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Azure'un API versiyonu, YYYY-AA-GG formatına uygun, [en son versiyonu](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions) kontrol edin",
5
5
  "fetch": "Listeyi al",
6
- "title": "Azure Api Versiyonu"
6
+ "title": "Azure API Versiyonu"
7
7
  },
8
8
  "empty": "İlk modeli eklemek için model kimliğini girin",
9
9
  "endpoint": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "checker": {
53
53
  "button": "Kontrol Et",
54
- "desc": "Api Anahtarı ve vekil adresinin doğru şekilde doldurulup doldurulmadığını test eder",
54
+ "desc": "API Anahtarı ve vekil adresinin doğru şekilde doldurulup doldurulmadığını test eder",
55
55
  "pass": "Kontrol Başarılı",
56
56
  "title": "Bağlantı Kontrolü"
57
57
  },
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "checker": {
53
53
  "button": "Kiểm tra",
54
- "desc": "Kiểm tra xem Api Key và địa chỉ proxy đã được điền đúng chưa",
54
+ "desc": "Kiểm tra xem API Key và địa chỉ proxy đã được điền đúng chưa",
55
55
  "pass": "Kiểm tra thành công",
56
56
  "title": "Kiểm tra kết nối"
57
57
  },
@@ -60,7 +60,7 @@
60
60
  "PluginManifestNotFound": "很抱歉,服务器没有找到该插件的描述清单 (manifest.json),请检查插件描述文件地址是否正确",
61
61
  "PluginManifestInvalid": "很抱歉,该插件的描述清单校验未通过,请检查描述清单格式是否规范",
62
62
  "PluginApiNotFound": "很抱歉,插件描述清单中不存在该 API ,请检查你的请求方法与插件清单 API 是否匹配",
63
- "PluginApiParamsError": "很抱歉,该插件请求的入参校验未通过,请检查入参与 Api 描述信息是否匹配",
63
+ "PluginApiParamsError": "很抱歉,该插件请求的入参校验未通过,请检查入参与 API 描述信息是否匹配",
64
64
  "PluginSettingsInvalid": "该插件需要正确配置后才可以使用,请检查你的配置是否正确",
65
65
  "PluginServerError": "插件服务端请求返回出错,请检查根据下面的报错信息检查你的插件描述文件、插件配置或服务端实现",
66
66
  "PluginGatewayError": "很抱歉,插件网关出现错误,请检查插件网关配置是否正确",
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Azure 的 API 版本,遵循 YYYY-MM-DD 格式,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "获取列表",
6
- "title": "Azure Api Version"
6
+ "title": "Azure API Version"
7
7
  },
8
8
  "empty": "请输入模型 ID 添加第一个模型",
9
9
  "endpoint": {
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "checker": {
53
53
  "button": "检查",
54
- "desc": "测试 Api Key 与代理地址是否正确填写",
54
+ "desc": "测试 API Key 与代理地址是否正确填写",
55
55
  "pass": "检查通过",
56
56
  "title": "连通性检查"
57
57
  },
@@ -3,7 +3,7 @@
3
3
  "azureApiVersion": {
4
4
  "desc": "Azure 的 API 版本,遵循 YYYY-MM-DD 格式,查閱[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)",
5
5
  "fetch": "獲取列表",
6
- "title": "Azure Api 版本"
6
+ "title": "Azure API 版本"
7
7
  },
8
8
  "empty": "請輸入模型 ID 添加第一個模型",
9
9
  "endpoint": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.9.1",
3
+ "version": "1.9.3",
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",
@@ -115,9 +115,9 @@
115
115
  "@khmyznikov/pwa-install": "^0.3.9",
116
116
  "@lobehub/chat-plugin-sdk": "^1.32.4",
117
117
  "@lobehub/chat-plugins-gateway": "^1.9.0",
118
- "@lobehub/icons": "^1.27.0",
118
+ "@lobehub/icons": "^1.28.0",
119
119
  "@lobehub/tts": "^1.24.3",
120
- "@lobehub/ui": "^1.146.9",
120
+ "@lobehub/ui": "^1.147.0",
121
121
  "@microsoft/fetch-event-source": "^2.0.1",
122
122
  "@neondatabase/serverless": "^0.9.4",
123
123
  "@next/third-parties": "^14.2.4",
@@ -77,7 +77,10 @@ export const useAzureProvider = (): ProviderItem => {
77
77
  children: (
78
78
  <AutoComplete
79
79
  options={[
80
+ '2024-06-01',
80
81
  '2024-02-01',
82
+ '2024-05-01-preview',
83
+ '2024-04-01-preview',
81
84
  '2024-03-01-preview',
82
85
  '2024-02-15-preview',
83
86
  '2023-10-01-preview',
@@ -76,7 +76,7 @@ describe('initAgentRuntimeWithUserPayload method', () => {
76
76
  const jwtPayload: JWTPayload = {
77
77
  apiKey: 'user-azure-key',
78
78
  endpoint: 'user-azure-endpoint',
79
- azureApiVersion: '2024-02-01',
79
+ azureApiVersion: '2024-06-01',
80
80
  };
81
81
  const runtime = await initAgentRuntimeWithUserPayload(ModelProvider.Azure, jwtPayload);
82
82
  expect(runtime).toBeInstanceOf(AgentRuntime);
@@ -13,7 +13,6 @@ const Ai360: ModelProviderCard = {
13
13
  },
14
14
  {
15
15
  displayName: '360GPT Pro',
16
- enabled: false,
17
16
  functionCall: false,
18
17
  id: '360gpt-pro',
19
18
  maxOutput: 7000,
@@ -21,7 +20,6 @@ const Ai360: ModelProviderCard = {
21
20
  },
22
21
  {
23
22
  displayName: '360GPT Pro Perf',
24
- enabled: false,
25
23
  functionCall: false,
26
24
  id: '360gpt-pro-perf',
27
25
  maxOutput: 7000,
@@ -29,7 +27,6 @@ const Ai360: ModelProviderCard = {
29
27
  },
30
28
  {
31
29
  displayName: '360GPT Pro sc202401v3',
32
- enabled: false,
33
30
  functionCall: false,
34
31
  id: '360gpt-pro-sc202401v3',
35
32
  maxOutput: 2048,
@@ -37,7 +34,6 @@ const Ai360: ModelProviderCard = {
37
34
  },
38
35
  {
39
36
  displayName: '360GPT Pro sc202401v2',
40
- enabled: false,
41
37
  functionCall: false,
42
38
  id: '360gpt-pro-sc202401v2',
43
39
  maxOutput: 2048,
@@ -45,7 +41,6 @@ const Ai360: ModelProviderCard = {
45
41
  },
46
42
  {
47
43
  displayName: '360GPT Pro sc202401v1',
48
- enabled: false,
49
44
  functionCall: false,
50
45
  id: '360gpt-pro-sc202401v1',
51
46
  maxOutput: 2048,
@@ -53,7 +48,6 @@ const Ai360: ModelProviderCard = {
53
48
  },
54
49
  {
55
50
  displayName: '360GPT Pro v2.0.3',
56
- enabled: false,
57
51
  functionCall: false,
58
52
  id: '360gpt-pro-v2.0.3',
59
53
  maxOutput: 2048,
@@ -77,7 +71,6 @@ const Ai360: ModelProviderCard = {
77
71
  },
78
72
  {
79
73
  displayName: '360GPT Turbo 32K Responsibility 240530',
80
- enabled: false,
81
74
  functionCall: false,
82
75
  id: '360gpt-turbo-32k-responsibility-240530',
83
76
  maxOutput: 32_000,
@@ -85,7 +78,6 @@ const Ai360: ModelProviderCard = {
85
78
  },
86
79
  {
87
80
  displayName: '360GPT Turbo 32K Responsibility 240516',
88
- enabled: false,
89
81
  functionCall: false,
90
82
  id: '360gpt-turbo-32k-responsibility-240516',
91
83
  maxOutput: 32_000,
@@ -93,7 +85,6 @@ const Ai360: ModelProviderCard = {
93
85
  },
94
86
  {
95
87
  displayName: '360GPT_S1_QIYUAN',
96
- enabled: false,
97
88
  functionCall: false,
98
89
  id: '360GPT_S1_QIYUAN',
99
90
  maxOutput: 2048,
@@ -101,7 +92,6 @@ const Ai360: ModelProviderCard = {
101
92
  },
102
93
  {
103
94
  displayName: '360GPT_S2_V9',
104
- enabled: false,
105
95
  functionCall: false,
106
96
  id: '360GPT_S2_V9',
107
97
  maxOutput: 7000,
@@ -49,28 +49,25 @@ const Anthropic: ModelProviderCard = {
49
49
  },
50
50
  {
51
51
  displayName: 'Claude 2.1',
52
- enabled: false,
53
52
  id: 'claude-2.1',
54
53
  maxOutput: 4096,
55
54
  tokens: 200_000,
56
55
  },
57
56
  {
58
57
  displayName: 'Claude 2.0',
59
- enabled: false,
60
58
  id: 'claude-2.0',
61
59
  maxOutput: 4096,
62
60
  tokens: 100_000,
63
61
  },
64
62
  {
65
63
  displayName: 'Claude Instant 1.2',
66
- enabled: false,
67
64
  id: 'claude-instant-1.2',
68
65
  maxOutput: 4096,
69
66
  tokens: 100_000,
70
67
  },
71
68
  ],
72
69
  checkModel: 'claude-3-haiku-20240307',
73
- disableBrowserRequest: true,
70
+ disableBrowserRequest: true,
74
71
  id: 'anthropic',
75
72
  name: 'Anthropic',
76
73
  proxyUrl: {
@@ -6,7 +6,7 @@ const Azure: ModelProviderCard = {
6
6
  {
7
7
  deploymentName: 'gpt-35-turbo',
8
8
  description: 'GPT 3.5 Turbo,适用于各种文本生成和理解任务',
9
- displayName: 'GPT-3.5 Turbo',
9
+ displayName: 'GPT 3.5 Turbo',
10
10
  enabled: true,
11
11
  functionCall: true,
12
12
  id: 'gpt-35-turbo',
@@ -15,27 +15,46 @@ const Azure: ModelProviderCard = {
15
15
  },
16
16
  {
17
17
  deploymentName: 'gpt-35-turbo-16k',
18
- displayName: 'GPT-3.5 Turbo',
18
+ displayName: 'GPT 3.5 Turbo',
19
19
  functionCall: true,
20
20
  id: 'gpt-35-turbo-16k',
21
21
  tokens: 16_384,
22
22
  },
23
23
  {
24
24
  deploymentName: 'gpt-4-turbo',
25
- displayName: 'GPT-4 Turbo',
25
+ displayName: 'GPT 4 Turbo',
26
26
  enabled: true,
27
27
  functionCall: true,
28
28
  id: 'gpt-4',
29
29
  tokens: 128_000,
30
+ vision: true,
30
31
  },
31
32
  {
32
33
  deploymentName: 'gpt-4-vision',
33
34
  description: 'GPT-4 视觉预览版,支持视觉任务',
34
- displayName: 'GPT-4 Turbo with Vision Preview',
35
+ displayName: 'GPT 4 Turbo with Vision Preview',
35
36
  id: 'gpt-4-vision-preview',
36
37
  tokens: 128_000,
37
38
  vision: true,
38
39
  },
40
+ {
41
+ deploymentName: 'gpt-4o-mini',
42
+ displayName: 'GPT 4o Mini',
43
+ enabled: true,
44
+ functionCall: true,
45
+ id: 'gpt-4o-mini',
46
+ tokens: 128_000,
47
+ vision: true,
48
+ },
49
+ {
50
+ deploymentName: 'gpt-4o',
51
+ displayName: 'GPT 4o',
52
+ enabled: true,
53
+ functionCall: true,
54
+ id: 'gpt-4o',
55
+ tokens: 128_000,
56
+ vision: true,
57
+ },
39
58
  ],
40
59
  defaultShowBrowserRequest: true,
41
60
  id: 'azure',
@@ -5,7 +5,6 @@ const Groq: ModelProviderCard = {
5
5
  chatModels: [
6
6
  {
7
7
  displayName: 'LLaMA3.1 405B (Preview)',
8
- enabled: false,
9
8
  functionCall: true,
10
9
  id: 'llama-3.1-405b-reasoning',
11
10
  tokens: 16_000,
@@ -0,0 +1,6 @@
1
+ import { timestamp } from 'drizzle-orm/pg-core';
2
+
3
+ export const timestamptz = (name: string) => timestamp(name, { withTimezone: true });
4
+
5
+ export const createdAt = () => timestamptz('created_at').notNull().defaultNow();
6
+ export const updatedAt = () => timestamptz('updated_at').notNull().defaultNow();
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix */
2
2
  import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
3
- import { relations } from 'drizzle-orm';
4
3
  import {
5
4
  boolean,
6
5
  index,
@@ -8,177 +7,20 @@ import {
8
7
  jsonb,
9
8
  pgTable,
10
9
  primaryKey,
11
- serial,
12
10
  text,
13
- timestamp,
14
11
  unique,
15
12
  uniqueIndex,
16
13
  varchar,
17
14
  } from 'drizzle-orm/pg-core';
18
15
  import { createInsertSchema, createSelectSchema } from 'drizzle-zod';
19
16
 
20
- import { DEFAULT_PREFERENCE } from '@/const/user';
21
17
  import { LobeAgentChatConfig, LobeAgentTTSConfig } from '@/types/agent';
22
18
  import { CustomPluginParams } from '@/types/tool/plugin';
23
19
 
24
- import { idGenerator, randomSlug } from '../utils/idGenerator';
25
-
26
- // Schema for nextauth
27
- export * from './nextauth';
28
-
29
- const timestamptz = (name: string) => timestamp(name, { withTimezone: true });
30
-
31
- const createdAt = () => timestamptz('created_at').notNull().defaultNow();
32
- const updatedAt = () => timestamptz('updated_at').notNull().defaultNow();
33
-
34
- /**
35
- * This table stores users. Users are created in Clerk, then Clerk calls a
36
- * webhook at /api/webhook/clerk to inform this application a user was created.
37
- */
38
- export const users = pgTable('users', {
39
- // The ID will be the user's ID from Clerk
40
- id: text('id').primaryKey().notNull(),
41
- username: text('username').unique(),
42
- email: text('email'),
43
-
44
- avatar: text('avatar'),
45
- phone: text('phone'),
46
- firstName: text('first_name'),
47
- lastName: text('last_name'),
48
- fullName: text('full_name'),
49
-
50
- isOnboarded: boolean('is_onboarded').default(false),
51
- // Time user was created in Clerk
52
- clerkCreatedAt: timestamptz('clerk_created_at'),
53
-
54
- // Required by nextauth, all null allowed
55
- emailVerifiedAt: timestamptz('email_verified_at'),
56
-
57
- preference: jsonb('preference').$defaultFn(() => DEFAULT_PREFERENCE),
58
-
59
- createdAt: createdAt(),
60
- updatedAt: updatedAt(),
61
- });
62
-
63
- export type NewUser = typeof users.$inferInsert;
64
- export type UserItem = typeof users.$inferSelect;
65
-
66
- export const userSubscriptions = pgTable('user_subscriptions', {
67
- id: text('id').primaryKey().notNull(),
68
- userId: text('user_id')
69
- .references(() => users.id, { onDelete: 'cascade' })
70
- .notNull(),
71
- stripeId: text('stripe_id'),
72
-
73
- currency: text('currency'),
74
- pricing: integer('pricing'),
75
- billingPaidAt: integer('billing_paid_at'),
76
- billingCycleStart: integer('billing_cycle_start'),
77
- billingCycleEnd: integer('billing_cycle_end'),
78
-
79
- cancelAtPeriodEnd: boolean('cancel_at_period_end'),
80
- cancelAt: integer('cancel_at'),
81
-
82
- nextBilling: jsonb('next_billing'),
83
-
84
- plan: text('plan'),
85
- recurring: text('recurring'),
86
-
87
- storageLimit: integer('storage_limit'),
88
-
89
- status: integer('status'),
90
- createdAt: createdAt(),
91
- updatedAt: updatedAt(),
92
- });
93
-
94
- export type NewUserSubscription = typeof userSubscriptions.$inferInsert;
95
- export type UserSubscriptionItem = typeof userSubscriptions.$inferSelect;
96
-
97
- export const userBudgets = pgTable('user_budgets', {
98
- id: text('id')
99
- .primaryKey()
100
- .references(() => users.id, { onDelete: 'cascade' })
101
- .notNull(),
102
-
103
- freeBudgetId: text('free_budget_id'),
104
- freeBudgetKey: text('free_budget_key'),
105
-
106
- subscriptionBudgetId: text('subscription_budget_id'),
107
- subscriptionBudgetKey: text('subscription_budget_key'),
108
-
109
- packageBudgetId: text('package_budget_id'),
110
- packageBudgetKey: text('package_budget_key'),
111
-
112
- createdAt: createdAt(),
113
- updatedAt: updatedAt(),
114
- });
115
-
116
- export type NewUserBudgets = typeof userBudgets.$inferInsert;
117
- export type UserBudgetItem = typeof userBudgets.$inferSelect;
118
-
119
- export const userSettings = pgTable('user_settings', {
120
- id: text('id')
121
- .references(() => users.id, { onDelete: 'cascade' })
122
- .primaryKey(),
123
-
124
- tts: jsonb('tts'),
125
- keyVaults: text('key_vaults'),
126
- general: jsonb('general'),
127
- languageModel: jsonb('language_model'),
128
- systemAgent: jsonb('system_agent'),
129
- defaultAgent: jsonb('default_agent'),
130
- tool: jsonb('tool'),
131
- });
132
-
133
- export const tags = pgTable('tags', {
134
- id: serial('id').primaryKey(),
135
- slug: text('slug').notNull().unique(),
136
- name: text('name'),
137
-
138
- userId: text('user_id')
139
- .references(() => users.id, { onDelete: 'cascade' })
140
- .notNull(),
141
-
142
- createdAt: createdAt(),
143
- updatedAt: updatedAt(),
144
- });
145
-
146
- export const files = pgTable('files', {
147
- id: text('id')
148
- .$defaultFn(() => idGenerator('files'))
149
- .primaryKey(),
150
-
151
- userId: text('user_id')
152
- .references(() => users.id, { onDelete: 'cascade' })
153
- .notNull(),
154
- fileType: varchar('file_type', { length: 255 }).notNull(),
155
- name: text('name').notNull(),
156
- size: integer('size').notNull(),
157
- url: text('url').notNull(),
158
-
159
- metadata: jsonb('metadata'),
160
-
161
- createdAt: createdAt(),
162
- updatedAt: updatedAt(),
163
- });
164
-
165
- export type NewFile = typeof files.$inferInsert;
166
- export type FileItem = typeof files.$inferSelect;
167
-
168
- export const plugins = pgTable('plugins', {
169
- id: serial('id').primaryKey(),
170
- identifier: text('identifier').notNull().unique(),
171
-
172
- title: text('title').notNull(),
173
- description: text('description'),
174
- avatar: text('avatar'),
175
- author: text('author'),
176
-
177
- manifest: text('manifest').notNull(),
178
- locale: text('locale').notNull(),
179
- createdAt: createdAt(),
180
- updatedAt: updatedAt(),
181
- });
20
+ import { idGenerator, randomSlug } from '../../utils/idGenerator';
21
+ import { createdAt, updatedAt } from './_helpers';
22
+ import { files } from './file';
23
+ import { users } from './user';
182
24
 
183
25
  export const installedPlugins = pgTable(
184
26
  'user_installed_plugins',
@@ -204,21 +46,6 @@ export const installedPlugins = pgTable(
204
46
  export type NewInstalledPlugin = typeof installedPlugins.$inferInsert;
205
47
  export type InstalledPluginItem = typeof installedPlugins.$inferSelect;
206
48
 
207
- export const pluginsTags = pgTable(
208
- 'plugins_tags',
209
- {
210
- pluginId: integer('plugin_id')
211
- .notNull()
212
- .references(() => plugins.id, { onDelete: 'cascade' }),
213
- tagId: integer('tag_id')
214
- .notNull()
215
- .references(() => tags.id, { onDelete: 'cascade' }),
216
- },
217
- (t) => ({
218
- pk: primaryKey({ columns: [t.pluginId, t.tagId] }),
219
- }),
220
- );
221
-
222
49
  // ======= agents ======= //
223
50
  export const agents = pgTable('agents', {
224
51
  id: text('id')
@@ -252,47 +79,11 @@ export const agents = pgTable('agents', {
252
79
  updatedAt: updatedAt(),
253
80
  });
254
81
 
255
- export const agentsTags = pgTable(
256
- 'agents_tags',
257
- {
258
- agentId: text('agent_id')
259
- .notNull()
260
- .references(() => agents.id, { onDelete: 'cascade' }),
261
- tagId: integer('tag_id')
262
- .notNull()
263
- .references(() => tags.id, { onDelete: 'cascade' }),
264
- },
265
- (t) => ({
266
- pk: primaryKey({ columns: [t.agentId, t.tagId] }),
267
- }),
268
- );
269
82
  export const insertAgentSchema = createInsertSchema(agents);
270
83
 
271
84
  export type NewAgent = typeof agents.$inferInsert;
272
85
  export type AgentItem = typeof agents.$inferSelect;
273
86
 
274
- // ======= market ======= //
275
-
276
- export const market = pgTable('market', {
277
- id: serial('id').primaryKey(),
278
-
279
- agentId: text('agent_id').references(() => agents.id, { onDelete: 'cascade' }),
280
- pluginId: integer('plugin_id').references(() => plugins.id, { onDelete: 'cascade' }),
281
-
282
- type: text('type', { enum: ['plugin', 'model', 'agent', 'group'] }).notNull(),
283
-
284
- view: integer('view').default(0),
285
- like: integer('like').default(0),
286
- used: integer('used').default(0),
287
-
288
- userId: text('user_id')
289
- .references(() => users.id, { onDelete: 'cascade' })
290
- .notNull(),
291
-
292
- createdAt: createdAt(),
293
- updatedAt: updatedAt(),
294
- });
295
-
296
87
  // ======= sessionGroups ======= //
297
88
 
298
89
  export const sessionGroups = pgTable(
@@ -538,125 +329,3 @@ export const filesToAgents = pgTable(
538
329
  pk: primaryKey({ columns: [t.fileId, t.agentId] }),
539
330
  }),
540
331
  );
541
-
542
- export const filesRelations = relations(files, ({ many }) => ({
543
- filesToMessages: many(filesToMessages),
544
- filesToSessions: many(filesToSessions),
545
- filesToAgents: many(filesToAgents),
546
- }));
547
-
548
- export const topicRelations = relations(topics, ({ one }) => ({
549
- session: one(sessions, {
550
- fields: [topics.sessionId],
551
- references: [sessions.id],
552
- }),
553
- }));
554
-
555
- export const pluginsRelations = relations(plugins, ({ many }) => ({
556
- pluginsTags: many(pluginsTags),
557
- }));
558
-
559
- export const pluginsTagsRelations = relations(pluginsTags, ({ one }) => ({
560
- plugin: one(plugins, {
561
- fields: [pluginsTags.pluginId],
562
- references: [plugins.id],
563
- }),
564
- tag: one(tags, {
565
- fields: [pluginsTags.tagId],
566
- references: [tags.id],
567
- }),
568
- }));
569
-
570
- export const tagsRelations = relations(tags, ({ many }) => ({
571
- agentsTags: many(agentsTags),
572
- pluginsTags: many(pluginsTags),
573
- }));
574
-
575
- export const messagesRelations = relations(messages, ({ many, one }) => ({
576
- filesToMessages: many(filesToMessages),
577
-
578
- session: one(sessions, {
579
- fields: [messages.sessionId],
580
- references: [sessions.id],
581
- }),
582
-
583
- parent: one(messages, {
584
- fields: [messages.parentId],
585
- references: [messages.id],
586
- }),
587
-
588
- topic: one(topics, {
589
- fields: [messages.topicId],
590
- references: [topics.id],
591
- }),
592
- }));
593
-
594
- export const agentsRelations = relations(agents, ({ many }) => ({
595
- agentsToSessions: many(agentsToSessions),
596
- filesToAgents: many(filesToAgents),
597
- agentsTags: many(agentsTags),
598
- }));
599
-
600
- export const agentsToSessionsRelations = relations(agentsToSessions, ({ one }) => ({
601
- session: one(sessions, {
602
- fields: [agentsToSessions.sessionId],
603
- references: [sessions.id],
604
- }),
605
- agent: one(agents, {
606
- fields: [agentsToSessions.agentId],
607
- references: [agents.id],
608
- }),
609
- }));
610
-
611
- export const filesToAgentsRelations = relations(filesToAgents, ({ one }) => ({
612
- agent: one(agents, {
613
- fields: [filesToAgents.agentId],
614
- references: [agents.id],
615
- }),
616
- file: one(files, {
617
- fields: [filesToAgents.fileId],
618
- references: [files.id],
619
- }),
620
- }));
621
-
622
- export const filesToMessagesRelations = relations(filesToMessages, ({ one }) => ({
623
- file: one(files, {
624
- fields: [filesToMessages.fileId],
625
- references: [files.id],
626
- }),
627
- message: one(messages, {
628
- fields: [filesToMessages.messageId],
629
- references: [messages.id],
630
- }),
631
- }));
632
-
633
- export const filesToSessionsRelations = relations(filesToSessions, ({ one }) => ({
634
- file: one(files, {
635
- fields: [filesToSessions.fileId],
636
- references: [files.id],
637
- }),
638
- session: one(sessions, {
639
- fields: [filesToSessions.sessionId],
640
- references: [sessions.id],
641
- }),
642
- }));
643
-
644
- export const agentsTagsRelations = relations(agentsTags, ({ one }) => ({
645
- agent: one(agents, {
646
- fields: [agentsTags.agentId],
647
- references: [agents.id],
648
- }),
649
- tag: one(tags, {
650
- fields: [agentsTags.tagId],
651
- references: [tags.id],
652
- }),
653
- }));
654
-
655
- export const sessionsRelations = relations(sessions, ({ many, one }) => ({
656
- filesToSessions: many(filesToSessions),
657
- agentsToSessions: many(agentsToSessions),
658
- group: one(sessionGroups, {
659
- fields: [sessions.groupId],
660
- references: [sessionGroups.id],
661
- }),
662
- }));
@@ -0,0 +1,84 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { integer, pgTable, primaryKey, serial, text } from 'drizzle-orm/pg-core';
3
+
4
+ import { createdAt, updatedAt } from './_helpers';
5
+ import { agents } from './chat';
6
+ import { users } from './user';
7
+
8
+ export const tags = pgTable('tags', {
9
+ id: serial('id').primaryKey(),
10
+ slug: text('slug').notNull().unique(),
11
+ name: text('name'),
12
+
13
+ userId: text('user_id')
14
+ .references(() => users.id, { onDelete: 'cascade' })
15
+ .notNull(),
16
+
17
+ createdAt: createdAt(),
18
+ updatedAt: updatedAt(),
19
+ });
20
+
21
+ export const plugins = pgTable('plugins', {
22
+ id: serial('id').primaryKey(),
23
+ identifier: text('identifier').notNull().unique(),
24
+
25
+ title: text('title').notNull(),
26
+ description: text('description'),
27
+ avatar: text('avatar'),
28
+ author: text('author'),
29
+
30
+ manifest: text('manifest').notNull(),
31
+ locale: text('locale').notNull(),
32
+ createdAt: createdAt(),
33
+ updatedAt: updatedAt(),
34
+ });
35
+
36
+ export const pluginsTags = pgTable(
37
+ 'plugins_tags',
38
+ {
39
+ pluginId: integer('plugin_id')
40
+ .notNull()
41
+ .references(() => plugins.id, { onDelete: 'cascade' }),
42
+ tagId: integer('tag_id')
43
+ .notNull()
44
+ .references(() => tags.id, { onDelete: 'cascade' }),
45
+ },
46
+ (t) => ({
47
+ pk: primaryKey({ columns: [t.pluginId, t.tagId] }),
48
+ }),
49
+ );
50
+
51
+ export const agentsTags = pgTable(
52
+ 'agents_tags',
53
+ {
54
+ agentId: text('agent_id')
55
+ .notNull()
56
+ .references(() => agents.id, { onDelete: 'cascade' }),
57
+ tagId: integer('tag_id')
58
+ .notNull()
59
+ .references(() => tags.id, { onDelete: 'cascade' }),
60
+ },
61
+ (t) => ({
62
+ pk: primaryKey({ columns: [t.agentId, t.tagId] }),
63
+ }),
64
+ );
65
+
66
+ export const market = pgTable('market', {
67
+ id: serial('id').primaryKey(),
68
+
69
+ agentId: text('agent_id').references(() => agents.id, { onDelete: 'cascade' }),
70
+ pluginId: integer('plugin_id').references(() => plugins.id, { onDelete: 'cascade' }),
71
+
72
+ type: text('type', { enum: ['plugin', 'model', 'agent', 'group'] }).notNull(),
73
+
74
+ view: integer('view').default(0),
75
+ like: integer('like').default(0),
76
+ used: integer('used').default(0),
77
+
78
+ userId: text('user_id')
79
+ .references(() => users.id, { onDelete: 'cascade' })
80
+ .notNull(),
81
+
82
+ createdAt: createdAt(),
83
+ updatedAt: updatedAt(),
84
+ });
@@ -0,0 +1,28 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { integer, jsonb, pgTable, text, varchar } from 'drizzle-orm/pg-core';
3
+
4
+ import { idGenerator } from '../../utils/idGenerator';
5
+ import { createdAt, updatedAt } from './_helpers';
6
+ import { users } from './user';
7
+
8
+ export const files = pgTable('files', {
9
+ id: text('id')
10
+ .$defaultFn(() => idGenerator('files'))
11
+ .primaryKey(),
12
+
13
+ userId: text('user_id')
14
+ .references(() => users.id, { onDelete: 'cascade' })
15
+ .notNull(),
16
+ fileType: varchar('file_type', { length: 255 }).notNull(),
17
+ name: text('name').notNull(),
18
+ size: integer('size').notNull(),
19
+ url: text('url').notNull(),
20
+
21
+ metadata: jsonb('metadata'),
22
+
23
+ createdAt: createdAt(),
24
+ updatedAt: updatedAt(),
25
+ });
26
+
27
+ export type NewFile = typeof files.$inferInsert;
28
+ export type FileItem = typeof files.$inferSelect;
@@ -0,0 +1,6 @@
1
+ export * from './chat';
2
+ export * from './discover';
3
+ export * from './file';
4
+ export * from './nextauth';
5
+ export * from './relations';
6
+ export * from './user';
@@ -1,8 +1,7 @@
1
- // ======= nextauth ======= //
2
1
  import { boolean, integer, pgTable, primaryKey, text, timestamp } from 'drizzle-orm/pg-core';
3
2
  import { AdapterAccount } from 'next-auth/adapters';
4
3
 
5
- import { users } from '@/database/server/schemas/lobechat';
4
+ import { users } from './user';
6
5
 
7
6
  /**
8
7
  * This table stores nextauth accounts. This is used to link users to their sso profiles.
@@ -0,0 +1,138 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { relations } from 'drizzle-orm';
3
+
4
+ import {
5
+ agents,
6
+ agentsToSessions,
7
+ filesToAgents,
8
+ filesToMessages,
9
+ filesToSessions,
10
+ messages,
11
+ sessionGroups,
12
+ sessions,
13
+ topics,
14
+ } from './chat';
15
+ import { agentsTags, plugins, pluginsTags, tags } from './discover';
16
+ import { files } from './file';
17
+
18
+ export const filesRelations = relations(files, ({ many }) => ({
19
+ filesToMessages: many(filesToMessages),
20
+ filesToSessions: many(filesToSessions),
21
+ filesToAgents: many(filesToAgents),
22
+ }));
23
+
24
+ export const topicRelations = relations(topics, ({ one }) => ({
25
+ session: one(sessions, {
26
+ fields: [topics.sessionId],
27
+ references: [sessions.id],
28
+ }),
29
+ }));
30
+
31
+ export const pluginsRelations = relations(plugins, ({ many }) => ({
32
+ pluginsTags: many(pluginsTags),
33
+ }));
34
+
35
+ export const pluginsTagsRelations = relations(pluginsTags, ({ one }) => ({
36
+ plugin: one(plugins, {
37
+ fields: [pluginsTags.pluginId],
38
+ references: [plugins.id],
39
+ }),
40
+ tag: one(tags, {
41
+ fields: [pluginsTags.tagId],
42
+ references: [tags.id],
43
+ }),
44
+ }));
45
+
46
+ export const tagsRelations = relations(tags, ({ many }) => ({
47
+ agentsTags: many(agentsTags),
48
+ pluginsTags: many(pluginsTags),
49
+ }));
50
+
51
+ export const messagesRelations = relations(messages, ({ many, one }) => ({
52
+ filesToMessages: many(filesToMessages),
53
+
54
+ session: one(sessions, {
55
+ fields: [messages.sessionId],
56
+ references: [sessions.id],
57
+ }),
58
+
59
+ parent: one(messages, {
60
+ fields: [messages.parentId],
61
+ references: [messages.id],
62
+ }),
63
+
64
+ topic: one(topics, {
65
+ fields: [messages.topicId],
66
+ references: [topics.id],
67
+ }),
68
+ }));
69
+
70
+ export const agentsRelations = relations(agents, ({ many }) => ({
71
+ agentsToSessions: many(agentsToSessions),
72
+ filesToAgents: many(filesToAgents),
73
+ agentsTags: many(agentsTags),
74
+ }));
75
+
76
+ export const agentsToSessionsRelations = relations(agentsToSessions, ({ one }) => ({
77
+ session: one(sessions, {
78
+ fields: [agentsToSessions.sessionId],
79
+ references: [sessions.id],
80
+ }),
81
+ agent: one(agents, {
82
+ fields: [agentsToSessions.agentId],
83
+ references: [agents.id],
84
+ }),
85
+ }));
86
+
87
+ export const filesToAgentsRelations = relations(filesToAgents, ({ one }) => ({
88
+ agent: one(agents, {
89
+ fields: [filesToAgents.agentId],
90
+ references: [agents.id],
91
+ }),
92
+ file: one(files, {
93
+ fields: [filesToAgents.fileId],
94
+ references: [files.id],
95
+ }),
96
+ }));
97
+
98
+ export const filesToMessagesRelations = relations(filesToMessages, ({ one }) => ({
99
+ file: one(files, {
100
+ fields: [filesToMessages.fileId],
101
+ references: [files.id],
102
+ }),
103
+ message: one(messages, {
104
+ fields: [filesToMessages.messageId],
105
+ references: [messages.id],
106
+ }),
107
+ }));
108
+
109
+ export const filesToSessionsRelations = relations(filesToSessions, ({ one }) => ({
110
+ file: one(files, {
111
+ fields: [filesToSessions.fileId],
112
+ references: [files.id],
113
+ }),
114
+ session: one(sessions, {
115
+ fields: [filesToSessions.sessionId],
116
+ references: [sessions.id],
117
+ }),
118
+ }));
119
+
120
+ export const agentsTagsRelations = relations(agentsTags, ({ one }) => ({
121
+ agent: one(agents, {
122
+ fields: [agentsTags.agentId],
123
+ references: [agents.id],
124
+ }),
125
+ tag: one(tags, {
126
+ fields: [agentsTags.tagId],
127
+ references: [tags.id],
128
+ }),
129
+ }));
130
+
131
+ export const sessionsRelations = relations(sessions, ({ many, one }) => ({
132
+ filesToSessions: many(filesToSessions),
133
+ agentsToSessions: many(agentsToSessions),
134
+ group: one(sessionGroups, {
135
+ fields: [sessions.groupId],
136
+ references: [sessionGroups.id],
137
+ }),
138
+ }));
@@ -0,0 +1,111 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import {
3
+ boolean,
4
+ integer,
5
+ jsonb,
6
+ pgTable,
7
+ text,
8
+ } from 'drizzle-orm/pg-core';
9
+
10
+ import { DEFAULT_PREFERENCE } from '@/const/user';
11
+
12
+ import { createdAt, timestamptz, updatedAt } from './_helpers';
13
+
14
+ /**
15
+ * This table stores users. Users are created in Clerk, then Clerk calls a
16
+ * webhook at /api/webhook/clerk to inform this application a user was created.
17
+ */
18
+ export const users = pgTable('users', {
19
+ // The ID will be the user's ID from Clerk
20
+ id: text('id').primaryKey().notNull(),
21
+ username: text('username').unique(),
22
+ email: text('email'),
23
+
24
+ avatar: text('avatar'),
25
+ phone: text('phone'),
26
+ firstName: text('first_name'),
27
+ lastName: text('last_name'),
28
+ fullName: text('full_name'),
29
+
30
+ isOnboarded: boolean('is_onboarded').default(false),
31
+ // Time user was created in Clerk
32
+ clerkCreatedAt: timestamptz('clerk_created_at'),
33
+
34
+ // Required by nextauth, all null allowed
35
+ emailVerifiedAt: timestamptz('email_verified_at'),
36
+
37
+ preference: jsonb('preference').$defaultFn(() => DEFAULT_PREFERENCE),
38
+
39
+ createdAt: createdAt(),
40
+ updatedAt: updatedAt(),
41
+ });
42
+
43
+ export type NewUser = typeof users.$inferInsert;
44
+ export type UserItem = typeof users.$inferSelect;
45
+
46
+ export const userSubscriptions = pgTable('user_subscriptions', {
47
+ id: text('id').primaryKey().notNull(),
48
+ userId: text('user_id')
49
+ .references(() => users.id, { onDelete: 'cascade' })
50
+ .notNull(),
51
+ stripeId: text('stripe_id'),
52
+
53
+ currency: text('currency'),
54
+ pricing: integer('pricing'),
55
+ billingPaidAt: integer('billing_paid_at'),
56
+ billingCycleStart: integer('billing_cycle_start'),
57
+ billingCycleEnd: integer('billing_cycle_end'),
58
+
59
+ cancelAtPeriodEnd: boolean('cancel_at_period_end'),
60
+ cancelAt: integer('cancel_at'),
61
+
62
+ nextBilling: jsonb('next_billing'),
63
+
64
+ plan: text('plan'),
65
+ recurring: text('recurring'),
66
+
67
+ storageLimit: integer('storage_limit'),
68
+
69
+ status: integer('status'),
70
+ createdAt: createdAt(),
71
+ updatedAt: updatedAt(),
72
+ });
73
+
74
+ export type NewUserSubscription = typeof userSubscriptions.$inferInsert;
75
+ export type UserSubscriptionItem = typeof userSubscriptions.$inferSelect;
76
+
77
+ export const userBudgets = pgTable('user_budgets', {
78
+ id: text('id')
79
+ .primaryKey()
80
+ .references(() => users.id, { onDelete: 'cascade' })
81
+ .notNull(),
82
+
83
+ freeBudgetId: text('free_budget_id'),
84
+ freeBudgetKey: text('free_budget_key'),
85
+
86
+ subscriptionBudgetId: text('subscription_budget_id'),
87
+ subscriptionBudgetKey: text('subscription_budget_key'),
88
+
89
+ packageBudgetId: text('package_budget_id'),
90
+ packageBudgetKey: text('package_budget_key'),
91
+
92
+ createdAt: createdAt(),
93
+ updatedAt: updatedAt(),
94
+ });
95
+
96
+ export type NewUserBudgets = typeof userBudgets.$inferInsert;
97
+ export type UserBudgetItem = typeof userBudgets.$inferSelect;
98
+
99
+ export const userSettings = pgTable('user_settings', {
100
+ id: text('id')
101
+ .references(() => users.id, { onDelete: 'cascade' })
102
+ .primaryKey(),
103
+
104
+ tts: jsonb('tts'),
105
+ keyVaults: text('key_vaults'),
106
+ general: jsonb('general'),
107
+ languageModel: jsonb('language_model'),
108
+ systemAgent: jsonb('system_agent'),
109
+ defaultAgent: jsonb('default_agent'),
110
+ tool: jsonb('tool'),
111
+ });
@@ -76,7 +76,7 @@ describe('AgentRuntime', () => {
76
76
  const jwtPayload = {
77
77
  apikey: 'user-azure-key',
78
78
  endpoint: 'user-azure-endpoint',
79
- apiVersion: '2024-02-01',
79
+ apiVersion: '2024-06-01',
80
80
  };
81
81
 
82
82
  const runtime = await AgentRuntime.initializeWithProviderOptions(ModelProvider.Azure, {
@@ -3,7 +3,7 @@ export default {
3
3
  azureApiVersion: {
4
4
  desc: 'Azure 的 API 版本,遵循 YYYY-MM-DD 格式,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)',
5
5
  fetch: '获取列表',
6
- title: 'Azure Api Version',
6
+ title: 'Azure API Version',
7
7
  },
8
8
  empty: '请输入模型 ID 添加第一个模型',
9
9
  endpoint: {
@@ -838,7 +838,7 @@ describe('AgentRuntimeOnClient', () => {
838
838
  azure: {
839
839
  apiKey: 'user-azure-key',
840
840
  endpoint: 'user-azure-endpoint',
841
- apiVersion: '2024-02-01',
841
+ apiVersion: '2024-06-01',
842
842
  },
843
843
  },
844
844
  },
@@ -1,15 +0,0 @@
1
- // refs: https://unkey.dev/blog/uuid-ux
2
-
3
- // If I have 100 million users, each generating up to 1 million messages.
4
- // Then the total number of IDs that need to be generated: 100 million × 1 million = 10^14 (100 trillion)
5
- // 11-digit Nano ID: 36^11 ≈ 1.3 × 10^17 (130 trillion trillion)
6
-
7
- export const FILE_ID_LENGTH = 19; // 5 prefix + 14 random, e.g. file_ydGX5gmaxL32fh
8
-
9
- export const MESSAGE_ID_LENGTH = 18; // 4 prefix + 14 random, e.g. msg_GX5ymaxL3d2ds2
10
-
11
- export const SESSION_ID_LENGTH = 16; // 4 prefix + 12 random, e.g. ssn_GX5y3d2dmaxL
12
-
13
- export const TOPIC_ID_LENGTH = 16; // 4 prefix + 12 random, e.g. tpc_GX5ymd7axL3y
14
-
15
- export const USER_ID_LENGTH = 14; // 4 prefix + 10 random, e.g. user_GXyxLmd75a