@lobehub/chat 1.52.5 → 1.52.7
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/CHANGELOG.md +58 -0
- package/Dockerfile +4 -0
- package/Dockerfile.database +4 -0
- package/changelog/v1.json +21 -0
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +18 -0
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +18 -0
- package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +12 -0
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +12 -0
- package/package.json +5 -3
- package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +2 -3
- package/src/app/[variants]/(main)/settings/about/page.tsx +2 -3
- package/src/app/[variants]/(main)/settings/sync/page.tsx +3 -3
- package/src/config/aiModels/cloudflare.ts +5 -11
- package/src/config/aiModels/zeroone.ts +16 -7
- package/src/config/app.ts +3 -0
- package/src/config/modelProviders/cloudflare.ts +5 -14
- package/src/config/modelProviders/zeroone.ts +13 -7
- package/src/middleware.ts +20 -25
- package/src/utils/server/geo.ts +39 -0
- package/src/utils/server/responsive.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,64 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.52.7](https://github.com/lobehub/lobe-chat/compare/v1.52.6...v1.52.7)
|
6
|
+
|
7
|
+
<sup>Released on **2025-02-09**</sup>
|
8
|
+
|
9
|
+
#### 🐛 Bug Fixes
|
10
|
+
|
11
|
+
- **misc**: Rewrite to local container in docker deployment mode.
|
12
|
+
|
13
|
+
#### 💄 Styles
|
14
|
+
|
15
|
+
- **misc**: Update Cloudflare models.
|
16
|
+
|
17
|
+
<br/>
|
18
|
+
|
19
|
+
<details>
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
21
|
+
|
22
|
+
#### What's fixed
|
23
|
+
|
24
|
+
- **misc**: Rewrite to local container in docker deployment mode, closes [#5910](https://github.com/lobehub/lobe-chat/issues/5910) ([f399197](https://github.com/lobehub/lobe-chat/commit/f399197))
|
25
|
+
|
26
|
+
#### Styles
|
27
|
+
|
28
|
+
- **misc**: Update Cloudflare models, closes [#5899](https://github.com/lobehub/lobe-chat/issues/5899) ([b71206d](https://github.com/lobehub/lobe-chat/commit/b71206d))
|
29
|
+
|
30
|
+
</details>
|
31
|
+
|
32
|
+
<div align="right">
|
33
|
+
|
34
|
+
[](#readme-top)
|
35
|
+
|
36
|
+
</div>
|
37
|
+
|
38
|
+
### [Version 1.52.6](https://github.com/lobehub/lobe-chat/compare/v1.52.5...v1.52.6)
|
39
|
+
|
40
|
+
<sup>Released on **2025-02-08**</sup>
|
41
|
+
|
42
|
+
#### 💄 Styles
|
43
|
+
|
44
|
+
- **misc**: Update ZeroOne models.
|
45
|
+
|
46
|
+
<br/>
|
47
|
+
|
48
|
+
<details>
|
49
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
50
|
+
|
51
|
+
#### Styles
|
52
|
+
|
53
|
+
- **misc**: Update ZeroOne models, closes [#5904](https://github.com/lobehub/lobe-chat/issues/5904) ([6e8d1a7](https://github.com/lobehub/lobe-chat/commit/6e8d1a7))
|
54
|
+
|
55
|
+
</details>
|
56
|
+
|
57
|
+
<div align="right">
|
58
|
+
|
59
|
+
[](#readme-top)
|
60
|
+
|
61
|
+
</div>
|
62
|
+
|
5
63
|
### [Version 1.52.5](https://github.com/lobehub/lobe-chat/compare/v1.52.4...v1.52.5)
|
6
64
|
|
7
65
|
<sup>Released on **2025-02-08**</sup>
|
package/Dockerfile
CHANGED
@@ -47,6 +47,10 @@ ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
|
47
47
|
|
48
48
|
ENV NEXT_PUBLIC_BASE_PATH="${NEXT_PUBLIC_BASE_PATH}"
|
49
49
|
|
50
|
+
# Make the middleware rewrite through local as default
|
51
|
+
# refs: https://github.com/lobehub/lobe-chat/issues/5876
|
52
|
+
ENV MIDDLEWARE_REWRITE_THROUGH_LOCAL="1"
|
53
|
+
|
50
54
|
# Sentry
|
51
55
|
ENV NEXT_PUBLIC_SENTRY_DSN="${NEXT_PUBLIC_SENTRY_DSN}" \
|
52
56
|
SENTRY_ORG="" \
|
package/Dockerfile.database
CHANGED
@@ -49,6 +49,10 @@ ARG NEXT_PUBLIC_UMAMI_WEBSITE_ID
|
|
49
49
|
|
50
50
|
ENV NEXT_PUBLIC_BASE_PATH="${NEXT_PUBLIC_BASE_PATH}"
|
51
51
|
|
52
|
+
# Make the middleware rewrite through local as default
|
53
|
+
# refs: https://github.com/lobehub/lobe-chat/issues/5876
|
54
|
+
ENV MIDDLEWARE_REWRITE_THROUGH_LOCAL="1"
|
55
|
+
|
52
56
|
ENV NEXT_PUBLIC_SERVICE_MODE="${NEXT_PUBLIC_SERVICE_MODE:-server}" \
|
53
57
|
NEXT_PUBLIC_ENABLE_NEXT_AUTH="${NEXT_PUBLIC_ENABLE_NEXT_AUTH:-1}" \
|
54
58
|
APP_URL="http://app.com" \
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,25 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"fixes": [
|
5
|
+
"Rewrite to local container in docker deployment mode."
|
6
|
+
],
|
7
|
+
"improvements": [
|
8
|
+
"Update Cloudflare models."
|
9
|
+
]
|
10
|
+
},
|
11
|
+
"date": "2025-02-09",
|
12
|
+
"version": "1.52.7"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"children": {
|
16
|
+
"improvements": [
|
17
|
+
"Update ZeroOne models."
|
18
|
+
]
|
19
|
+
},
|
20
|
+
"date": "2025-02-08",
|
21
|
+
"version": "1.52.6"
|
22
|
+
},
|
2
23
|
{
|
3
24
|
"children": {
|
4
25
|
"fixes": [
|
@@ -95,6 +95,23 @@ If you are deploying using a public network, the following assumptions apply:
|
|
95
95
|
|
96
96
|
Then, copy the `Client ID` and `Client Secret` and save them.
|
97
97
|
|
98
|
+
### Configure Webhook (Optional)
|
99
|
+
|
100
|
+
Configure the Casdoor webhook so that LobeChat can receive notifications when user information is updated.
|
101
|
+
|
102
|
+
Go to `Admin ` -> `Webhooks`, add a webhook, and fill in the following fields:
|
103
|
+
|
104
|
+
- URL: `https://lobe.example.com/api/auth/webhooks/casdoor`
|
105
|
+
- Method: `POST`
|
106
|
+
- Content Type: `application/json`
|
107
|
+
- Headers: `casdoor-secret`: `Your Webhook Secret`
|
108
|
+
> The webhook is generated by yourself, you can visit https://generate-secret.vercel.app/10 to generate a 10 bit secret.
|
109
|
+
|
110
|
+
- Event: `update-user`
|
111
|
+
- Is user extented: `true`
|
112
|
+
|
113
|
+
Save and Exit, then copy the Webhook secret and fill it in the environment variable `CASDOOR_WEBHOOK_SECRET.
|
114
|
+
|
98
115
|
### Configure Environment Variables
|
99
116
|
|
100
117
|
Set the obtained `Client ID` and `Client Secret` as `AUTH_CASDOOR_ID` and `AUTH_CASDOOR_SECRET` in the LobeChat environment variables.
|
@@ -115,6 +132,7 @@ If you are deploying using a public network, the following assumptions apply:
|
|
115
132
|
| `AUTH_CASDOOR_SECRET` | Required | The client secret from the Casdoor application details page. |
|
116
133
|
| `AUTH_CASDOOR_ISSUER` | Required | The OpenID Connect issuer for the Casdoor provider. |
|
117
134
|
| `NEXTAUTH_URL` | Required | This URL specifies the callback address for Auth.js during OAuth verification and needs to be set only if the default generated redirect address is incorrect. `https://lobe.example.com/api/auth` |
|
135
|
+
| `CASDOOR_WEBHOOK_SECRET` | Optional | A key used to verify whether the request sent by Casdoor is legal. |
|
118
136
|
|
119
137
|
<Callout type={'tip'}>
|
120
138
|
Visit [📘 Environment Variables](/docs/self-hosting/environment-variables/auth#casdoor) for
|
@@ -92,6 +92,23 @@ tags:
|
|
92
92
|
|
93
93
|
随后,复制 `客户端 ID` 和 `客户端密钥`,并保存。
|
94
94
|
|
95
|
+
### 配置 Webhook (可选)
|
96
|
+
|
97
|
+
配置 Casdoor 的 Webhook 以便在用户信息更新时同步到 LobeChat 。
|
98
|
+
|
99
|
+
前往 `管理工具` -> `Webhooks`,创建一个 Webhook,添加一个 Webhook,填写以下字段:
|
100
|
+
|
101
|
+
- 链接:`http://lobe.example.com/api/auth/webhooks/casdoor`
|
102
|
+
- 方法:`POST`
|
103
|
+
- 内容类型:`application/json`
|
104
|
+
- 协议头:`casdoor-secret`: `你的Webhook密钥`
|
105
|
+
> 密钥由你自己生成,用于验证 Casdoor 发送的请求是否合法。 可以前往 https://generate-secret.vercel.app/10 生成一个 10 位的密钥。
|
106
|
+
|
107
|
+
- 事件:`update-user`
|
108
|
+
- 拓展用户字段:`true`
|
109
|
+
|
110
|
+
保存,并退出。 将该密钥填写到环境变量中的 `CASDOOR_WEBHOOK_SECRET`。
|
111
|
+
|
95
112
|
### 配置环境变量
|
96
113
|
|
97
114
|
将获取到的 `客户端 ID` 和 `客户端`,设为 LobeChat 环境变量中的 `AUTH_CASDOOR_ID` 和 `AUTH_CASDOOR_SECRET`。
|
@@ -112,6 +129,7 @@ tags:
|
|
112
129
|
| `AUTH_CASDOOR_SECRET` | 必选 | Casdoor 应用详情页的客户端密钥 |
|
113
130
|
| `AUTH_CASDOOR_ISSUER` | 必选 | Casdoor 提供程序的 OpenID Connect 颁发者。 |
|
114
131
|
| `NEXTAUTH_URL` | 必选 | 该 URL 用于指定 Auth.js 在执行 OAuth 验证时的回调地址,当默认生成的重定向地址发生不正确时才需要设置。`https://lobe.example.com/api/auth` |
|
132
|
+
| `CASDOOR_WEBHOOK_SECRET` | 可选 | 用于验证 Casdoor 发送的 Webhook 请求是否合法的密钥。 |
|
115
133
|
|
116
134
|
<Callout type={'tip'}>
|
117
135
|
前往 [📘 环境变量](/zh/docs/self-hosting/environment-variables/auth#casdoor) 可查阅相关变量详情。
|
@@ -43,6 +43,17 @@ If you are using Logto Cloud, assume its endpoint domain is `https://example.log
|
|
43
43
|
|
44
44
|
After successful creation, save the `Client ID` and `Client Secret`.
|
45
45
|
|
46
|
+
### Configure Webhook (Optional)
|
47
|
+
|
48
|
+
Configure the Logto Webhook so that LobeChat can receive notifications when user information is updated.
|
49
|
+
|
50
|
+
Go to `Webhooks`, create a Webhook, and fill in the following fields:
|
51
|
+
|
52
|
+
- Endpoint URL: `https://lobe.example.com/api/auth/webhooks/logto`
|
53
|
+
- Events: `User.Data.Updated`
|
54
|
+
|
55
|
+
After successful creation, copy the Webhook's `Signing Key` and fill it in the `LOGTO_WEBHOOK_SIGNING_KEY` environment variable.
|
56
|
+
|
46
57
|
### Configure Environment Variables
|
47
58
|
|
48
59
|
<Image alt="Configure Environment Variables" inStep src="https://github.com/user-attachments/assets/15af6d94-af4f-4aa9-bbab-7a46e9f9e837" />
|
@@ -64,6 +75,7 @@ If you are using Logto Cloud, assume its endpoint domain is `https://example.log
|
|
64
75
|
| `AUTH_LOGTO_SECRET` | Required | The Client Secret from the Logto App details page |
|
65
76
|
| `AUTH_LOGTO_ISSUER` | Required | OpenID Connect issuer of the Logto provider |
|
66
77
|
| `NEXTAUTH_URL` | Required | This URL specifies the callback address for Auth.js during OAuth verification, needed only if the default generated redirect address is incorrect. `https://lobe.example.com/api/auth` |
|
78
|
+
| `LOGTO_WEBHOOK_SIGNING_KEY` | Optional | The key used to verify the legality of Webhook requests sent by Logto. |
|
67
79
|
|
68
80
|
<Callout type={'tip'}>
|
69
81
|
Visit [📘 Environment Variables](/docs/self-hosting/environment-variables/auth#logto) for details on related variables.
|
@@ -40,6 +40,17 @@ tags:
|
|
40
40
|
|
41
41
|
创建成功后, 将 `Client ID` 和 `Client Secret` 保存下来。
|
42
42
|
|
43
|
+
### 配置 Webhook (可选)
|
44
|
+
|
45
|
+
配置 Logto 的 Webhook,以便在用户信息更新时 LobeChat 可以接收到通知。
|
46
|
+
|
47
|
+
前往 `Webhooks` ,创建一个 Webhook,填写以下字段:
|
48
|
+
|
49
|
+
- 端点 URL: `https://lobe.example.com/api/auth/webhooks/logto`
|
50
|
+
- 事件: `User.Data.Updated`
|
51
|
+
|
52
|
+
创建成功后,复制 Webhook 的 `签名密钥`。填写到环境变量中的 `LOGTO_WEBHOOK_SIGNING_KEY`。
|
53
|
+
|
43
54
|
### 配置环境变量
|
44
55
|
|
45
56
|
<Image alt="配置环境变量" inStep src="https://github.com/user-attachments/assets/15af6d94-af4f-4aa9-bbab-7a46e9f9e837" />
|
@@ -61,6 +72,7 @@ tags:
|
|
61
72
|
| `AUTH_LOGTO_SECRET` | 必选 | Logto App 详情页的 Client Secret |
|
62
73
|
| `AUTH_LOGTO_ISSUER` | 必选 | Logto 提供程序的 OpenID Connect 颁发者 |
|
63
74
|
| `NEXTAUTH_URL` | 必选 | 该 URL 用于指定 Auth.js 在执行 OAuth 验证时的回调地址,当默认生成的重定向地址发生不正确时才需要设置。`https://lobe.example.com/api/auth` |
|
75
|
+
| `LOGTO_WEBHOOK_SIGNING_KEY` | 可选 | 用于验证 Logto 发送的 Webhook 请求是否合法的密钥。 |
|
64
76
|
|
65
77
|
<Callout type={'tip'}>
|
66
78
|
前往 [📘 环境变量](/zh/docs/self-hosting/environment-variables/auth#logto) 可查阅相关变量详情。
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.52.
|
3
|
+
"version": "1.52.7",
|
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",
|
@@ -142,6 +142,7 @@
|
|
142
142
|
"@trpc/server": "next",
|
143
143
|
"@vercel/analytics": "^1.4.1",
|
144
144
|
"@vercel/edge-config": "^1.4.0",
|
145
|
+
"@vercel/functions": "^2",
|
145
146
|
"@vercel/speed-insights": "^1.1.0",
|
146
147
|
"ahooks": "^3.8.4",
|
147
148
|
"ai": "^3.4.33",
|
@@ -149,6 +150,7 @@
|
|
149
150
|
"antd-style": "^3.7.1",
|
150
151
|
"brotli-wasm": "^3.0.1",
|
151
152
|
"chroma-js": "^3.1.2",
|
153
|
+
"countries-and-timezones": "^3.7.2",
|
152
154
|
"dayjs": "^1.11.13",
|
153
155
|
"debug": "^4.4.0",
|
154
156
|
"dexie": "^3.2.7",
|
@@ -289,7 +291,7 @@
|
|
289
291
|
"fs-extra": "^11.2.0",
|
290
292
|
"glob": "^11.0.0",
|
291
293
|
"gray-matter": "^4.0.3",
|
292
|
-
"happy-dom": "^
|
294
|
+
"happy-dom": "^17.0.0",
|
293
295
|
"husky": "^9.1.7",
|
294
296
|
"just-diff": "^6.0.2",
|
295
297
|
"lint-staged": "^15.3.0",
|
@@ -317,7 +319,7 @@
|
|
317
319
|
"vitest": "~1.2.2",
|
318
320
|
"vitest-canvas-mock": "^0.3.3"
|
319
321
|
},
|
320
|
-
"packageManager": "pnpm@9.15.
|
322
|
+
"packageManager": "pnpm@9.15.5",
|
321
323
|
"publishConfig": {
|
322
324
|
"access": "public",
|
323
325
|
"registry": "https://registry.npmjs.org"
|
@@ -3,7 +3,6 @@ import { redirect } from 'next/navigation';
|
|
3
3
|
import { metadataModule } from '@/server/metadata';
|
4
4
|
import { translation } from '@/server/translation';
|
5
5
|
import { DynamicLayoutProps } from '@/types/next';
|
6
|
-
import { isMobileDevice } from '@/utils/server/responsive';
|
7
6
|
import { RouteVariants } from '@/utils/server/routeVariants';
|
8
7
|
|
9
8
|
import Category from './features/Category';
|
@@ -17,8 +16,8 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
|
|
17
16
|
});
|
18
17
|
};
|
19
18
|
|
20
|
-
const Page = async () => {
|
21
|
-
const mobile = await
|
19
|
+
const Page = async (props: DynamicLayoutProps) => {
|
20
|
+
const mobile = await RouteVariants.getIsMobile(props);
|
22
21
|
|
23
22
|
if (!mobile) return redirect('/chat');
|
24
23
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { metadataModule } from '@/server/metadata';
|
2
2
|
import { translation } from '@/server/translation';
|
3
3
|
import { DynamicLayoutProps } from '@/types/next';
|
4
|
-
import { isMobileDevice } from '@/utils/server/responsive';
|
5
4
|
import { RouteVariants } from '@/utils/server/routeVariants';
|
6
5
|
|
7
6
|
import Page from './index';
|
@@ -16,8 +15,8 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
|
|
16
15
|
});
|
17
16
|
};
|
18
17
|
|
19
|
-
export default async () => {
|
20
|
-
const isMobile = await
|
18
|
+
export default async (props: DynamicLayoutProps) => {
|
19
|
+
const isMobile = await RouteVariants.getIsMobile(props);
|
21
20
|
|
22
21
|
return <Page mobile={isMobile} />;
|
23
22
|
};
|
@@ -4,7 +4,7 @@ import { serverFeatureFlags } from '@/config/featureFlags';
|
|
4
4
|
import { metadataModule } from '@/server/metadata';
|
5
5
|
import { translation } from '@/server/translation';
|
6
6
|
import { DynamicLayoutProps } from '@/types/next';
|
7
|
-
import { gerServerDeviceInfo
|
7
|
+
import { gerServerDeviceInfo } from '@/utils/server/responsive';
|
8
8
|
import { RouteVariants } from '@/utils/server/routeVariants';
|
9
9
|
|
10
10
|
import Page from './index';
|
@@ -18,11 +18,11 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
|
|
18
18
|
url: '/settings/sync',
|
19
19
|
});
|
20
20
|
};
|
21
|
-
export default async () => {
|
21
|
+
export default async (props: DynamicLayoutProps) => {
|
22
22
|
const enableWebrtc = serverFeatureFlags().enableWebrtc;
|
23
23
|
if (!enableWebrtc) return notFound();
|
24
24
|
|
25
|
-
const isMobile = await
|
25
|
+
const isMobile = await RouteVariants.getIsMobile(props);
|
26
26
|
const { os, browser } = await gerServerDeviceInfo();
|
27
27
|
|
28
28
|
return <Page browser={browser} mobile={isMobile} os={os} />;
|
@@ -3,29 +3,27 @@ import { AIChatModelCard } from '@/types/aiModel';
|
|
3
3
|
const cloudflareChatModels: AIChatModelCard[] = [
|
4
4
|
{
|
5
5
|
contextWindowTokens: 16_384,
|
6
|
-
displayName: '
|
6
|
+
displayName: 'DeepSeek R1 Distill Qwen 32B',
|
7
7
|
enabled: true,
|
8
|
-
id: '@
|
8
|
+
id: '@cf/deepseek-ai/deepseek-r1-distill-qwen-32b',
|
9
9
|
type: 'chat',
|
10
10
|
},
|
11
11
|
{
|
12
12
|
contextWindowTokens: 2048,
|
13
13
|
displayName: 'gemma-7b-it',
|
14
|
-
enabled: true,
|
15
14
|
id: '@hf/google/gemma-7b-it',
|
16
15
|
type: 'chat',
|
17
16
|
},
|
18
17
|
{
|
19
18
|
contextWindowTokens: 4096,
|
20
19
|
displayName: 'hermes-2-pro-mistral-7b',
|
21
|
-
enabled: true,
|
22
20
|
id: '@hf/nousresearch/hermes-2-pro-mistral-7b',
|
23
21
|
type: 'chat',
|
24
22
|
},
|
25
23
|
{
|
26
|
-
contextWindowTokens:
|
27
|
-
displayName: 'llama
|
28
|
-
id: '@cf/meta/llama-3-
|
24
|
+
contextWindowTokens: 131_072,
|
25
|
+
displayName: 'llama 3.3 70b',
|
26
|
+
id: '@cf/meta/llama-3.3-70b-instruct-fp8-fast',
|
29
27
|
type: 'chat',
|
30
28
|
},
|
31
29
|
{
|
@@ -50,7 +48,6 @@ const cloudflareChatModels: AIChatModelCard[] = [
|
|
50
48
|
{
|
51
49
|
contextWindowTokens: 32_768,
|
52
50
|
displayName: 'openhermes-2.5-mistral-7b-awq',
|
53
|
-
enabled: true,
|
54
51
|
id: '@hf/thebloke/openhermes-2.5-mistral-7b-awq',
|
55
52
|
type: 'chat',
|
56
53
|
},
|
@@ -64,20 +61,17 @@ const cloudflareChatModels: AIChatModelCard[] = [
|
|
64
61
|
{
|
65
62
|
contextWindowTokens: 4096,
|
66
63
|
displayName: 'starling-lm-7b-beta',
|
67
|
-
enabled: true,
|
68
64
|
id: '@hf/nexusflow/starling-lm-7b-beta',
|
69
65
|
type: 'chat',
|
70
66
|
},
|
71
67
|
{
|
72
68
|
contextWindowTokens: 32_768,
|
73
69
|
displayName: 'zephyr-7b-beta-awq',
|
74
|
-
enabled: true,
|
75
70
|
id: '@hf/thebloke/zephyr-7b-beta-awq',
|
76
71
|
type: 'chat',
|
77
72
|
},
|
78
73
|
{
|
79
74
|
displayName: 'meta-llama-3-8b-instruct',
|
80
|
-
enabled: true,
|
81
75
|
id: '@hf/meta-llama/meta-llama-3-8b-instruct',
|
82
76
|
type: 'chat',
|
83
77
|
},
|
@@ -14,11 +14,26 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
14
14
|
},
|
15
15
|
type: 'chat',
|
16
16
|
},
|
17
|
+
{
|
18
|
+
abilities: {
|
19
|
+
vision: true,
|
20
|
+
},
|
21
|
+
contextWindowTokens: 16_384,
|
22
|
+
description: '复杂视觉任务模型,提供基于多张图片的高性能理解、分析能力。',
|
23
|
+
displayName: 'Yi Vision V2',
|
24
|
+
enabled: true,
|
25
|
+
id: 'yi-vision-v2',
|
26
|
+
pricing: {
|
27
|
+
currency: 'CNY',
|
28
|
+
input: 6,
|
29
|
+
output: 6,
|
30
|
+
},
|
31
|
+
type: 'chat',
|
32
|
+
},
|
17
33
|
{
|
18
34
|
contextWindowTokens: 16_384,
|
19
35
|
description: '小而精悍,轻量极速模型。提供强化数学运算和代码编写能力。',
|
20
36
|
displayName: 'Yi Spark',
|
21
|
-
enabled: true,
|
22
37
|
id: 'yi-spark',
|
23
38
|
pricing: {
|
24
39
|
currency: 'CNY',
|
@@ -31,7 +46,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
31
46
|
contextWindowTokens: 16_384,
|
32
47
|
description: '中型尺寸模型升级微调,能力均衡,性价比高。深度优化指令遵循能力。',
|
33
48
|
displayName: 'Yi Medium',
|
34
|
-
enabled: true,
|
35
49
|
id: 'yi-medium',
|
36
50
|
pricing: {
|
37
51
|
currency: 'CNY',
|
@@ -44,7 +58,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
44
58
|
contextWindowTokens: 200_000,
|
45
59
|
description: '200K 超长上下文窗口,提供长文本深度理解和生成能力。',
|
46
60
|
displayName: 'Yi Medium 200K',
|
47
|
-
enabled: true,
|
48
61
|
id: 'yi-medium-200k',
|
49
62
|
pricing: {
|
50
63
|
currency: 'CNY',
|
@@ -57,7 +70,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
57
70
|
contextWindowTokens: 16_384,
|
58
71
|
description: '超高性价比、卓越性能。根据性能和推理速度、成本,进行平衡性高精度调优。',
|
59
72
|
displayName: 'Yi Large Turbo',
|
60
|
-
enabled: true,
|
61
73
|
id: 'yi-large-turbo',
|
62
74
|
pricing: {
|
63
75
|
currency: 'CNY',
|
@@ -71,7 +83,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
71
83
|
description:
|
72
84
|
'基于 yi-large 超强模型的高阶服务,结合检索与生成技术提供精准答案,实时全网检索信息服务。',
|
73
85
|
displayName: 'Yi Large RAG',
|
74
|
-
enabled: true,
|
75
86
|
id: 'yi-large-rag',
|
76
87
|
pricing: {
|
77
88
|
currency: 'CNY',
|
@@ -88,7 +99,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
88
99
|
description:
|
89
100
|
'在 yi-large 模型的基础上支持并强化了工具调用的能力,适用于各种需要搭建 agent 或 workflow 的业务场景。',
|
90
101
|
displayName: 'Yi Large FC',
|
91
|
-
enabled: true,
|
92
102
|
id: 'yi-large-fc',
|
93
103
|
pricing: {
|
94
104
|
currency: 'CNY',
|
@@ -116,7 +126,6 @@ const zerooneChatModels: AIChatModelCard[] = [
|
|
116
126
|
contextWindowTokens: 16_384,
|
117
127
|
description: '复杂视觉任务模型,提供高性能图片理解、分析能力。',
|
118
128
|
displayName: 'Yi Vision',
|
119
|
-
enabled: true,
|
120
129
|
id: 'yi-vision',
|
121
130
|
pricing: {
|
122
131
|
currency: 'CNY',
|
package/src/config/app.ts
CHANGED
@@ -48,6 +48,7 @@ export const getAppConfig = () => {
|
|
48
48
|
|
49
49
|
APP_URL: z.string().optional(),
|
50
50
|
VERCEL_EDGE_CONFIG: z.string().optional(),
|
51
|
+
MIDDLEWARE_REWRITE_THROUGH_LOCAL: z.boolean().optional(),
|
51
52
|
|
52
53
|
CDN_USE_GLOBAL: z.boolean().optional(),
|
53
54
|
CUSTOM_FONT_FAMILY: z.string().optional(),
|
@@ -80,6 +81,8 @@ export const getAppConfig = () => {
|
|
80
81
|
VERCEL_EDGE_CONFIG: process.env.VERCEL_EDGE_CONFIG,
|
81
82
|
|
82
83
|
APP_URL,
|
84
|
+
MIDDLEWARE_REWRITE_THROUGH_LOCAL: process.env.MIDDLEWARE_REWRITE_THROUGH_LOCAL === '1',
|
85
|
+
|
83
86
|
CUSTOM_FONT_FAMILY: process.env.CUSTOM_FONT_FAMILY,
|
84
87
|
CUSTOM_FONT_URL: process.env.CUSTOM_FONT_URL,
|
85
88
|
CDN_USE_GLOBAL: process.env.CDN_USE_GLOBAL === '1',
|
@@ -6,28 +6,25 @@ const Cloudflare: ModelProviderCard = {
|
|
6
6
|
chatModels: [
|
7
7
|
{
|
8
8
|
contextWindowTokens: 16_384,
|
9
|
-
displayName: '
|
9
|
+
displayName: 'DeepSeek R1 Distill Qwen 32B',
|
10
10
|
enabled: true,
|
11
|
-
id: '@
|
11
|
+
id: '@cf/deepseek-ai/deepseek-r1-distill-qwen-32b',
|
12
12
|
},
|
13
13
|
{
|
14
14
|
contextWindowTokens: 2048,
|
15
15
|
displayName: 'gemma-7b-it',
|
16
|
-
enabled: true,
|
17
16
|
id: '@hf/google/gemma-7b-it',
|
18
17
|
},
|
19
18
|
{
|
20
19
|
contextWindowTokens: 4096,
|
21
20
|
displayName: 'hermes-2-pro-mistral-7b',
|
22
|
-
|
23
|
-
enabled: true,
|
24
21
|
// functionCall: true,
|
25
22
|
id: '@hf/nousresearch/hermes-2-pro-mistral-7b',
|
26
23
|
},
|
27
24
|
{
|
28
|
-
contextWindowTokens:
|
29
|
-
displayName: 'llama
|
30
|
-
id: '@cf/meta/llama-3-
|
25
|
+
contextWindowTokens: 131_072,
|
26
|
+
displayName: 'llama 3.3 70b',
|
27
|
+
id: '@cf/meta/llama-3.3-70b-instruct-fp8-fast',
|
31
28
|
},
|
32
29
|
{
|
33
30
|
contextWindowTokens: 4096,
|
@@ -37,7 +34,6 @@ const Cloudflare: ModelProviderCard = {
|
|
37
34
|
{
|
38
35
|
contextWindowTokens: 32_768,
|
39
36
|
displayName: 'neural-chat-7b-v3-1-awq',
|
40
|
-
enabled: true,
|
41
37
|
id: '@hf/thebloke/neural-chat-7b-v3-1-awq',
|
42
38
|
},
|
43
39
|
{
|
@@ -48,7 +44,6 @@ const Cloudflare: ModelProviderCard = {
|
|
48
44
|
{
|
49
45
|
contextWindowTokens: 32_768,
|
50
46
|
displayName: 'openhermes-2.5-mistral-7b-awq',
|
51
|
-
enabled: true,
|
52
47
|
id: '@hf/thebloke/openhermes-2.5-mistral-7b-awq',
|
53
48
|
},
|
54
49
|
{
|
@@ -60,19 +55,15 @@ const Cloudflare: ModelProviderCard = {
|
|
60
55
|
{
|
61
56
|
contextWindowTokens: 4096,
|
62
57
|
displayName: 'starling-lm-7b-beta',
|
63
|
-
enabled: true,
|
64
58
|
id: '@hf/nexusflow/starling-lm-7b-beta',
|
65
59
|
},
|
66
60
|
{
|
67
61
|
contextWindowTokens: 32_768,
|
68
62
|
displayName: 'zephyr-7b-beta-awq',
|
69
|
-
enabled: true,
|
70
63
|
id: '@hf/thebloke/zephyr-7b-beta-awq',
|
71
64
|
},
|
72
65
|
{
|
73
66
|
displayName: 'meta-llama-3-8b-instruct',
|
74
|
-
enabled: true,
|
75
|
-
functionCall: false,
|
76
67
|
id: '@hf/meta-llama/meta-llama-3-8b-instruct',
|
77
68
|
},
|
78
69
|
],
|
@@ -15,11 +15,23 @@ const ZeroOne: ModelProviderCard = {
|
|
15
15
|
output: 0.99,
|
16
16
|
},
|
17
17
|
},
|
18
|
+
{
|
19
|
+
contextWindowTokens: 16_384,
|
20
|
+
description: '复杂视觉任务模型,提供基于多张图片的高性能理解、分析能力。',
|
21
|
+
displayName: 'Yi Vision V2',
|
22
|
+
enabled: true,
|
23
|
+
id: 'yi-vision-v2',
|
24
|
+
pricing: {
|
25
|
+
currency: 'CNY',
|
26
|
+
input: 6,
|
27
|
+
output: 6,
|
28
|
+
},
|
29
|
+
vision: true,
|
30
|
+
},
|
18
31
|
{
|
19
32
|
contextWindowTokens: 16_384,
|
20
33
|
description: '小而精悍,轻量极速模型。提供强化数学运算和代码编写能力。',
|
21
34
|
displayName: 'Yi Spark',
|
22
|
-
enabled: true,
|
23
35
|
id: 'yi-spark',
|
24
36
|
pricing: {
|
25
37
|
currency: 'CNY',
|
@@ -31,7 +43,6 @@ const ZeroOne: ModelProviderCard = {
|
|
31
43
|
contextWindowTokens: 16_384,
|
32
44
|
description: '中型尺寸模型升级微调,能力均衡,性价比高。深度优化指令遵循能力。',
|
33
45
|
displayName: 'Yi Medium',
|
34
|
-
enabled: true,
|
35
46
|
id: 'yi-medium',
|
36
47
|
pricing: {
|
37
48
|
currency: 'CNY',
|
@@ -43,7 +54,6 @@ const ZeroOne: ModelProviderCard = {
|
|
43
54
|
contextWindowTokens: 200_000,
|
44
55
|
description: '200K 超长上下文窗口,提供长文本深度理解和生成能力。',
|
45
56
|
displayName: 'Yi Medium 200K',
|
46
|
-
enabled: true,
|
47
57
|
id: 'yi-medium-200k',
|
48
58
|
pricing: {
|
49
59
|
currency: 'CNY',
|
@@ -55,7 +65,6 @@ const ZeroOne: ModelProviderCard = {
|
|
55
65
|
contextWindowTokens: 16_384,
|
56
66
|
description: '超高性价比、卓越性能。根据性能和推理速度、成本,进行平衡性高精度调优。',
|
57
67
|
displayName: 'Yi Large Turbo',
|
58
|
-
enabled: true,
|
59
68
|
id: 'yi-large-turbo',
|
60
69
|
pricing: {
|
61
70
|
currency: 'CNY',
|
@@ -68,7 +77,6 @@ const ZeroOne: ModelProviderCard = {
|
|
68
77
|
description:
|
69
78
|
'基于 yi-large 超强模型的高阶服务,结合检索与生成技术提供精准答案,实时全网检索信息服务。',
|
70
79
|
displayName: 'Yi Large RAG',
|
71
|
-
enabled: true,
|
72
80
|
id: 'yi-large-rag',
|
73
81
|
pricing: {
|
74
82
|
currency: 'CNY',
|
@@ -81,7 +89,6 @@ const ZeroOne: ModelProviderCard = {
|
|
81
89
|
description:
|
82
90
|
'在 yi-large 模型的基础上支持并强化了工具调用的能力,适用于各种需要搭建 agent 或 workflow 的业务场景。',
|
83
91
|
displayName: 'Yi Large FC',
|
84
|
-
enabled: true,
|
85
92
|
functionCall: true,
|
86
93
|
id: 'yi-large-fc',
|
87
94
|
pricing: {
|
@@ -105,7 +112,6 @@ const ZeroOne: ModelProviderCard = {
|
|
105
112
|
contextWindowTokens: 16_384,
|
106
113
|
description: '复杂视觉任务模型,提供高性能图片理解、分析能力。',
|
107
114
|
displayName: 'Yi Vision',
|
108
|
-
enabled: true,
|
109
115
|
id: 'yi-vision',
|
110
116
|
pricing: {
|
111
117
|
currency: 'CNY',
|
package/src/middleware.ts
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
3
3
|
import { UAParser } from 'ua-parser-js';
|
4
|
+
import urlJoin from 'url-join';
|
4
5
|
|
6
|
+
import { appEnv } from '@/config/app';
|
5
7
|
import { authEnv } from '@/config/auth';
|
6
8
|
import { LOBE_THEME_APPEARANCE } from '@/const/theme';
|
7
9
|
import NextAuthEdge from '@/libs/next-auth/edge';
|
8
10
|
import { Locales } from '@/locales/resources';
|
9
11
|
import { parseBrowserLanguage } from '@/utils/locale';
|
12
|
+
import { parseDefaultThemeFromCountry } from '@/utils/server/geo';
|
10
13
|
import { RouteVariants } from '@/utils/server/routeVariants';
|
11
14
|
|
12
15
|
import { OAUTH_AUTHORIZED } from './const/auth';
|
@@ -37,30 +40,17 @@ export const config = {
|
|
37
40
|
],
|
38
41
|
};
|
39
42
|
|
40
|
-
const
|
41
|
-
|
42
|
-
const longitude = 'geo' in request && (request.geo as any)?.longitude;
|
43
|
-
|
44
|
-
if (typeof longitude === 'number') {
|
45
|
-
// 计算时区偏移(每15度经度对应1小时)
|
46
|
-
// 东经为正,西经为负
|
47
|
-
const offsetHours = Math.round(longitude / 15);
|
48
|
-
|
49
|
-
// 计算当地时间
|
50
|
-
const localHour = (new Date().getUTCHours() + offsetHours + 24) % 24;
|
51
|
-
console.log(`[theme] localHour: ${localHour}`);
|
43
|
+
const defaultMiddleware = (request: NextRequest) => {
|
44
|
+
const url = new URL(request.url);
|
52
45
|
|
53
|
-
|
54
|
-
|
46
|
+
// skip all api requests
|
47
|
+
if (['/api', '/trpc', '/webapi'].some((path) => url.pathname.startsWith(path))) {
|
48
|
+
return NextResponse.next();
|
55
49
|
}
|
56
50
|
|
57
|
-
return 'light';
|
58
|
-
};
|
59
|
-
|
60
|
-
const defaultMiddleware = (request: NextRequest) => {
|
61
51
|
// 1. 从 cookie 中读取用户偏好
|
62
52
|
const theme =
|
63
|
-
request.cookies.get(LOBE_THEME_APPEARANCE)?.value ||
|
53
|
+
request.cookies.get(LOBE_THEME_APPEARANCE)?.value || parseDefaultThemeFromCountry(request);
|
64
54
|
|
65
55
|
// if it's a new user, there's no cookie
|
66
56
|
// So we need to use the fallback language parsed by accept-language
|
@@ -80,11 +70,12 @@ const defaultMiddleware = (request: NextRequest) => {
|
|
80
70
|
theme,
|
81
71
|
});
|
82
72
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
73
|
+
// if app is in docker, rewrite to self container
|
74
|
+
// https://github.com/lobehub/lobe-chat/issues/5876
|
75
|
+
if (appEnv.MIDDLEWARE_REWRITE_THROUGH_LOCAL) {
|
76
|
+
url.protocol = 'http';
|
77
|
+
url.host = '127.0.0.1';
|
78
|
+
url.port = process.env.PORT || '3210';
|
88
79
|
}
|
89
80
|
|
90
81
|
// refs: https://github.com/lobehub/lobe-chat/pull/5866
|
@@ -92,7 +83,11 @@ const defaultMiddleware = (request: NextRequest) => {
|
|
92
83
|
// / -> /zh-CN__0__dark
|
93
84
|
// /discover -> /zh-CN__0__dark/discover
|
94
85
|
const nextPathname = `/${route}` + (url.pathname === '/' ? '' : url.pathname);
|
95
|
-
|
86
|
+
const nextURL = appEnv.MIDDLEWARE_REWRITE_THROUGH_LOCAL
|
87
|
+
? urlJoin(url.origin, nextPathname)
|
88
|
+
: nextPathname;
|
89
|
+
|
90
|
+
console.log(`[rewrite] ${url.pathname} -> ${nextURL}`);
|
96
91
|
|
97
92
|
url.pathname = nextPathname;
|
98
93
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { geolocation } from '@vercel/functions';
|
2
|
+
import { getCountry } from 'countries-and-timezones';
|
3
|
+
import { NextRequest } from 'next/server';
|
4
|
+
|
5
|
+
export const parseDefaultThemeFromCountry = (request: NextRequest) => {
|
6
|
+
// 1. 从请求头中获取国家代码
|
7
|
+
const geo = geolocation(request);
|
8
|
+
|
9
|
+
const countryCode =
|
10
|
+
geo?.country ||
|
11
|
+
request.headers.get('x-vercel-ip-country') || // Vercel
|
12
|
+
request.headers.get('cf-ipcountry') || // Cloudflare
|
13
|
+
request.headers.get('x-zeabur-ip-country') || // Zeabur
|
14
|
+
request.headers.get('x-country-code'); // Netlify
|
15
|
+
|
16
|
+
// 如果没有获取到国家代码,直接返回 light 主题
|
17
|
+
if (!countryCode) return 'light';
|
18
|
+
|
19
|
+
// 2. 获取国家的时区信息
|
20
|
+
const country = getCountry(countryCode);
|
21
|
+
|
22
|
+
// 如果找不到国家信息或该国家没有时区信息,返回 light 主题
|
23
|
+
if (!country?.timezones?.length) return 'light';
|
24
|
+
|
25
|
+
// 3. 获取该国家的第一个 时区下的当前时间
|
26
|
+
const localTime = new Date().toLocaleString('en-US', {
|
27
|
+
hour: 'numeric',
|
28
|
+
hour12: false,
|
29
|
+
timeZone: country.timezones[0],
|
30
|
+
});
|
31
|
+
|
32
|
+
// 4. 解析小时数并确定主题
|
33
|
+
const localHour = parseInt(localTime);
|
34
|
+
// console.log(
|
35
|
+
// `[theme] Country: ${countryCode}, Timezone: ${country.timezones[0]}, LocalHour: ${localHour}`,
|
36
|
+
// );
|
37
|
+
|
38
|
+
return localHour >= 6 && localHour < 18 ? 'light' : 'dark';
|
39
|
+
};
|
@@ -4,7 +4,7 @@ import { UAParser } from 'ua-parser-js';
|
|
4
4
|
/**
|
5
5
|
* check mobile device in server
|
6
6
|
*/
|
7
|
-
|
7
|
+
const isMobileDevice = async () => {
|
8
8
|
if (typeof process === 'undefined') {
|
9
9
|
throw new Error('[Server method] you are importing a server-only module outside of server');
|
10
10
|
}
|