@lobehub/chat 1.108.0 → 1.108.2
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/.cursor/rules/testing-guide/testing-guide.mdc +18 -0
- package/CHANGELOG.md +58 -0
- package/README.md +3 -2
- package/README.zh-CN.md +3 -2
- package/changelog/v1.json +21 -0
- package/package.json +3 -3
- package/src/app/(backend)/trpc/desktop/[trpc]/route.ts +1 -1
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/Checker.tsx +15 -2
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +30 -3
- package/src/app/[variants]/layout.tsx +1 -0
- package/src/components/Analytics/LobeAnalyticsProvider.tsx +10 -13
- package/src/components/Analytics/LobeAnalyticsProviderWrapper.tsx +16 -4
- package/src/database/models/__tests__/_test_template.ts +1 -1
- package/src/database/models/__tests__/agent.test.ts +1 -1
- package/src/database/models/__tests__/aiModel.test.ts +1 -1
- package/src/database/models/__tests__/aiProvider.test.ts +1 -1
- package/src/database/models/__tests__/asyncTask.test.ts +1 -1
- package/src/database/models/__tests__/chunk.test.ts +1 -1
- package/src/database/models/__tests__/file.test.ts +1 -1
- package/src/database/models/__tests__/generationTopic.test.ts +1 -1
- package/src/database/models/__tests__/knowledgeBase.test.ts +1 -1
- package/src/database/models/__tests__/message.test.ts +1 -1
- package/src/database/models/__tests__/session.test.ts +1 -1
- package/src/database/models/__tests__/sessionGroup.test.ts +1 -1
- package/src/database/models/__tests__/topic.test.ts +1 -1
- package/src/database/models/_template.ts +1 -1
- package/src/database/models/agent.ts +1 -1
- package/src/database/models/aiModel.ts +1 -1
- package/src/database/models/aiProvider.ts +1 -1
- package/src/database/models/apiKey.ts +1 -1
- package/src/database/models/asyncTask.ts +1 -1
- package/src/database/models/chunk.ts +1 -2
- package/src/database/models/document.ts +1 -1
- package/src/database/models/embedding.ts +1 -2
- package/src/database/models/file.ts +1 -2
- package/src/database/models/generationTopic.ts +1 -1
- package/src/database/models/knowledgeBase.ts +1 -1
- package/src/database/models/message.ts +1 -2
- package/src/database/models/plugin.ts +1 -1
- package/src/database/models/session.ts +15 -2
- package/src/database/models/sessionGroup.ts +1 -1
- package/src/database/models/thread.ts +1 -1
- package/src/database/models/topic.ts +1 -2
- package/src/database/models/user.ts +1 -1
- package/src/database/repositories/dataExporter/index.ts +1 -1
- package/src/database/repositories/dataImporter/__tests__/index.test.ts +1 -1
- package/src/database/repositories/dataImporter/deprecated/__tests__/index.test.ts +1 -1
- package/src/database/repositories/dataImporter/deprecated/index.ts +1 -2
- package/src/database/repositories/dataImporter/index.ts +1 -1
- package/src/database/server/models/__tests__/adapter.test.ts +1 -1
- package/src/database/server/models/__tests__/nextauth.test.ts +1 -1
- package/src/database/server/models/__tests__/user.test.ts +1 -1
- package/src/database/server/models/ragEval/dataset.ts +1 -1
- package/src/database/server/models/ragEval/datasetRecord.ts +1 -1
- package/src/database/server/models/ragEval/evaluation.ts +1 -2
- package/src/database/server/models/ragEval/evaluationRecord.ts +1 -1
- package/src/database/utils/genWhere.ts +1 -2
- package/src/features/User/UserAvatar.tsx +18 -2
- package/src/libs/model-runtime/RouterRuntime/createRuntime.test.ts +538 -0
- package/src/libs/model-runtime/RouterRuntime/createRuntime.ts +50 -13
- package/src/libs/model-runtime/RouterRuntime/index.ts +1 -1
- package/src/libs/model-runtime/aihubmix/index.ts +10 -5
- package/src/libs/model-runtime/ppio/index.test.ts +3 -6
- package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.ts +8 -6
- package/src/libs/next-auth/adapter/index.ts +1 -1
- package/src/libs/oidc-provider/adapter.ts +1 -2
- package/src/server/globalConfig/genServerAiProviderConfig.test.ts +22 -25
- package/src/server/globalConfig/genServerAiProviderConfig.ts +34 -22
- package/src/server/globalConfig/index.ts +1 -1
- package/src/server/routers/lambda/chunk.ts +1 -1
- package/src/server/services/discover/index.ts +11 -2
- package/src/services/chat.ts +1 -1
- package/src/services/session/client.test.ts +1 -1
- package/src/store/aiInfra/slices/aiProvider/__tests__/action.test.ts +211 -0
- package/src/store/aiInfra/slices/aiProvider/action.ts +46 -35
- package/src/store/user/slices/modelList/action.test.ts +5 -5
- package/src/store/user/slices/modelList/action.ts +4 -4
- package/src/styles/antdOverride.ts +6 -0
- package/src/utils/getFallbackModelProperty.test.ts +52 -45
- package/src/utils/getFallbackModelProperty.ts +4 -3
- package/src/utils/parseModels.test.ts +107 -98
- package/src/utils/parseModels.ts +10 -8
@@ -430,6 +430,22 @@ expect(result!.status).toBe('success');
|
|
430
430
|
// ✅ 使用 any 类型简化复杂的 Mock 设置
|
431
431
|
const mockStream = new ReadableStream() as any;
|
432
432
|
mockStream.toReadableStream = () => mockStream;
|
433
|
+
|
434
|
+
// ✅ 使用中括号访问私有属性和方法(推荐)
|
435
|
+
class MyClass {
|
436
|
+
private _cache = new Map();
|
437
|
+
private getFromCache(key: string) { /* ... */ }
|
438
|
+
}
|
439
|
+
|
440
|
+
const instance = new MyClass();
|
441
|
+
|
442
|
+
// 推荐:使用中括号访问私有成员
|
443
|
+
await instance['getFromCache']('test-key');
|
444
|
+
expect(instance['_cache'].size).toBe(1);
|
445
|
+
|
446
|
+
// 避免:使用 as any 访问私有成员
|
447
|
+
await (instance as any).getFromCache('test-key'); // ❌ 不推荐
|
448
|
+
expect((instance as any)._cache.size).toBe(1); // ❌ 不推荐
|
433
449
|
```
|
434
450
|
|
435
451
|
#### 🎯 适用场景
|
@@ -437,11 +453,13 @@ mockStream.toReadableStream = () => mockStream;
|
|
437
453
|
- **Mock 对象**: 对于测试用的 Mock 数据,使用 `as any` 避免复杂的类型定义
|
438
454
|
- **第三方库**: 处理复杂的第三方库类型时,适当使用 `any` 提高效率
|
439
455
|
- **测试断言**: 在确定对象存在的测试场景中,使用 `!` 非空断言
|
456
|
+
- **私有成员访问**: 优先使用中括号 `instance['privateMethod']()` 而不是 `(instance as any).privateMethod()`
|
440
457
|
- **临时调试**: 快速编写测试时,先用 `any` 保证功能,后续可选择性地优化类型
|
441
458
|
|
442
459
|
#### ⚠️ 注意事项
|
443
460
|
|
444
461
|
- **适度使用**: 不要过度依赖 `any`,核心业务逻辑的类型仍应保持严格
|
462
|
+
- **私有成员访问优先级**: 中括号访问 > `as any` 转换,保持更好的类型安全性
|
445
463
|
- **文档说明**: 对于使用 `any` 的复杂场景,添加注释说明原因
|
446
464
|
- **测试覆盖**: 确保即使使用了 `any`,测试仍能有效验证功能正确性
|
447
465
|
|
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,64 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.108.2](https://github.com/lobehub/lobe-chat/compare/v1.108.1...v1.108.2)
|
6
|
+
|
7
|
+
<sup>Released on **2025-08-05**</sup>
|
8
|
+
|
9
|
+
#### 🐛 Bug Fixes
|
10
|
+
|
11
|
+
- **misc**: Provider config checker uses outdated API key.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### What's fixed
|
19
|
+
|
20
|
+
- **misc**: Provider config checker uses outdated API key, closes [#8666](https://github.com/lobehub/lobe-chat/issues/8666) ([3a3e73e](https://github.com/lobehub/lobe-chat/commit/3a3e73e))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.108.1](https://github.com/lobehub/lobe-chat/compare/v1.108.0...v1.108.1)
|
31
|
+
|
32
|
+
<sup>Released on **2025-08-05**</sup>
|
33
|
+
|
34
|
+
#### 🐛 Bug Fixes
|
35
|
+
|
36
|
+
- **misc**: Fix remote avatar broken in desktop.
|
37
|
+
|
38
|
+
#### 💄 Styles
|
39
|
+
|
40
|
+
- **misc**: Update mask style.
|
41
|
+
|
42
|
+
<br/>
|
43
|
+
|
44
|
+
<details>
|
45
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
46
|
+
|
47
|
+
#### What's fixed
|
48
|
+
|
49
|
+
- **misc**: Fix remote avatar broken in desktop, closes [#8673](https://github.com/lobehub/lobe-chat/issues/8673) ([7eae430](https://github.com/lobehub/lobe-chat/commit/7eae430))
|
50
|
+
|
51
|
+
#### Styles
|
52
|
+
|
53
|
+
- **misc**: Update mask style, closes [#8555](https://github.com/lobehub/lobe-chat/issues/8555) ([b4ac89d](https://github.com/lobehub/lobe-chat/commit/b4ac89d))
|
54
|
+
|
55
|
+
</details>
|
56
|
+
|
57
|
+
<div align="right">
|
58
|
+
|
59
|
+
[](#readme-top)
|
60
|
+
|
61
|
+
</div>
|
62
|
+
|
5
63
|
## [Version 1.108.0](https://github.com/lobehub/lobe-chat/compare/v1.107.6...v1.108.0)
|
6
64
|
|
7
65
|
<sup>Released on **2025-08-05**</sup>
|
package/README.md
CHANGED
@@ -250,7 +250,7 @@ We have implemented support for the following model service providers:
|
|
250
250
|
- **[HuggingFace](https://lobechat.com/discover/provider/huggingface)**: The HuggingFace Inference API provides a fast and free way for you to explore thousands of models for various tasks. Whether you are prototyping for a new application or experimenting with the capabilities of machine learning, this API gives you instant access to high-performance models across multiple domains.
|
251
251
|
- **[Cloudflare Workers AI](https://lobechat.com/discover/provider/cloudflare)**: Run serverless GPU-powered machine learning models on Cloudflare's global network.
|
252
252
|
|
253
|
-
<details><summary><kbd>See more providers (+
|
253
|
+
<details><summary><kbd>See more providers (+32)</kbd></summary>
|
254
254
|
|
255
255
|
- **[GitHub](https://lobechat.com/discover/provider/github)**: With GitHub Models, developers can become AI engineers and leverage the industry's leading AI models.
|
256
256
|
- **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI is a platform providing a variety of large language models and AI image generation API services, flexible, reliable, and cost-effective. It supports the latest open-source models like Llama3 and Mistral, offering a comprehensive, user-friendly, and auto-scaling API solution for generative AI application development, suitable for the rapid growth of AI startups.
|
@@ -283,10 +283,11 @@ We have implemented support for the following model service providers:
|
|
283
283
|
- **[Search1API](https://lobechat.com/discover/provider/search1api)**: Search1API provides access to the DeepSeek series of models that can connect to the internet as needed, including standard and fast versions, supporting a variety of model sizes.
|
284
284
|
- **[InfiniAI](https://lobechat.com/discover/provider/infiniai)**: Provides high-performance, easy-to-use, and secure large model services for application developers, covering the entire process from large model development to service deployment.
|
285
285
|
- **[Qiniu](https://lobechat.com/discover/provider/qiniu)**: Qiniu, as a long-established cloud service provider, delivers cost-effective and reliable AI inference services for both real-time and batch processing, with a simple and user-friendly experience.
|
286
|
+
- **[302.AI](https://lobechat.com/discover/provider/ai302)**:
|
286
287
|
|
287
288
|
</details>
|
288
289
|
|
289
|
-
> 📊 Total providers: [<kbd>**
|
290
|
+
> 📊 Total providers: [<kbd>**42**</kbd>](https://lobechat.com/discover/providers)
|
290
291
|
|
291
292
|
<!-- PROVIDER LIST -->
|
292
293
|
|
package/README.zh-CN.md
CHANGED
@@ -250,7 +250,7 @@ LobeChat 支持文件上传与知识库功能,你可以上传文件、图片
|
|
250
250
|
- **[HuggingFace](https://lobechat.com/discover/provider/huggingface)**: HuggingFace Inference API 提供了一种快速且免费的方式,让您可以探索成千上万种模型,适用于各种任务。无论您是在为新应用程序进行原型设计,还是在尝试机器学习的功能,这个 API 都能让您即时访问多个领域的高性能模型。
|
251
251
|
- **[Cloudflare Workers AI](https://lobechat.com/discover/provider/cloudflare)**: 在 Cloudflare 的全球网络上运行由无服务器 GPU 驱动的机器学习模型。
|
252
252
|
|
253
|
-
<details><summary><kbd>See more providers (+
|
253
|
+
<details><summary><kbd>See more providers (+32)</kbd></summary>
|
254
254
|
|
255
255
|
- **[GitHub](https://lobechat.com/discover/provider/github)**: 通过 GitHub 模型,开发人员可以成为 AI 工程师,并使用行业领先的 AI 模型进行构建。
|
256
256
|
- **[Novita](https://lobechat.com/discover/provider/novita)**: Novita AI 是一个提供多种大语言模型与 AI 图像生成的 API 服务的平台,灵活、可靠且具有成本效益。它支持 Llama3、Mistral 等最新的开源模型,并为生成式 AI 应用开发提供了全面、用户友好且自动扩展的 API 解决方案,适合 AI 初创公司的快速发展。
|
@@ -283,10 +283,11 @@ LobeChat 支持文件上传与知识库功能,你可以上传文件、图片
|
|
283
283
|
- **[Search1API](https://lobechat.com/discover/provider/search1api)**: Search1API 提供可根据需要自行联网的 DeepSeek 系列模型的访问,包括标准版和快速版本,支持多种参数规模的模型选择。
|
284
284
|
- **[InfiniAI](https://lobechat.com/discover/provider/infiniai)**: 为应用开发者提供高性能、易上手、安全可靠的大模型服务,覆盖从大模型开发到大模型服务化部署的全流程。
|
285
285
|
- **[Qiniu](https://lobechat.com/discover/provider/qiniu)**: 七牛作为老牌云服务厂商,提供高性价比稳定的实时、批量 AI 推理服务,简单易用。
|
286
|
+
- **[302.AI](https://lobechat.com/discover/provider/ai302)**:
|
286
287
|
|
287
288
|
</details>
|
288
289
|
|
289
|
-
> 📊 Total providers: [<kbd>**
|
290
|
+
> 📊 Total providers: [<kbd>**42**</kbd>](https://lobechat.com/discover/providers)
|
290
291
|
|
291
292
|
<!-- PROVIDER LIST -->
|
292
293
|
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,25 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"fixes": [
|
5
|
+
"Provider config checker uses outdated API key."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-08-05",
|
9
|
+
"version": "1.108.2"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"fixes": [
|
14
|
+
"Fix remote avatar broken in desktop."
|
15
|
+
],
|
16
|
+
"improvements": [
|
17
|
+
"Update mask style."
|
18
|
+
]
|
19
|
+
},
|
20
|
+
"date": "2025-08-05",
|
21
|
+
"version": "1.108.1"
|
22
|
+
},
|
2
23
|
{
|
3
24
|
"children": {
|
4
25
|
"features": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.108.
|
3
|
+
"version": "1.108.2",
|
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",
|
@@ -146,7 +146,7 @@
|
|
146
146
|
"@lobechat/electron-server-ipc": "workspace:*",
|
147
147
|
"@lobechat/file-loaders": "workspace:*",
|
148
148
|
"@lobechat/web-crawler": "workspace:*",
|
149
|
-
"@lobehub/analytics": "^1.
|
149
|
+
"@lobehub/analytics": "^1.6.0",
|
150
150
|
"@lobehub/charts": "^2.0.0",
|
151
151
|
"@lobehub/chat-plugin-sdk": "^1.32.4",
|
152
152
|
"@lobehub/chat-plugins-gateway": "^1.9.0",
|
@@ -182,7 +182,7 @@
|
|
182
182
|
"debug": "^4.4.1",
|
183
183
|
"dexie": "^3.2.7",
|
184
184
|
"diff": "^7.0.0",
|
185
|
-
"drizzle-orm": "^0.
|
185
|
+
"drizzle-orm": "^0.44.0",
|
186
186
|
"drizzle-zod": "^0.5.1",
|
187
187
|
"epub2": "^3.0.2",
|
188
188
|
"fast-deep-equal": "^3.1.3",
|
@@ -15,7 +15,7 @@ const handler = (req: NextRequest) =>
|
|
15
15
|
endpoint: '/trpc/desktop',
|
16
16
|
|
17
17
|
onError: ({ error, path, type }) => {
|
18
|
-
pino.info(`Error in tRPC handler (
|
18
|
+
pino.info(`Error in tRPC handler (desktop) on path: ${path}, type: ${type}`);
|
19
19
|
console.error(error);
|
20
20
|
},
|
21
21
|
|
@@ -46,11 +46,13 @@ export type CheckErrorRender = (props: {
|
|
46
46
|
interface ConnectionCheckerProps {
|
47
47
|
checkErrorRender?: CheckErrorRender;
|
48
48
|
model: string;
|
49
|
+
onAfterCheck: () => Promise<void>;
|
50
|
+
onBeforeCheck: () => Promise<void>;
|
49
51
|
provider: string;
|
50
52
|
}
|
51
53
|
|
52
54
|
const Checker = memo<ConnectionCheckerProps>(
|
53
|
-
({ model, provider, checkErrorRender: CheckErrorRender }) => {
|
55
|
+
({ model, provider, checkErrorRender: CheckErrorRender, onBeforeCheck, onAfterCheck }) => {
|
54
56
|
const { t } = useTranslation('setting');
|
55
57
|
|
56
58
|
const isProviderConfigUpdating = useAiInfraStore(
|
@@ -152,7 +154,18 @@ const Checker = memo<ConnectionCheckerProps>(
|
|
152
154
|
value={checkModel}
|
153
155
|
virtual
|
154
156
|
/>
|
155
|
-
<Button
|
157
|
+
<Button
|
158
|
+
disabled={isProviderConfigUpdating}
|
159
|
+
loading={loading}
|
160
|
+
onClick={async () => {
|
161
|
+
await onBeforeCheck();
|
162
|
+
try {
|
163
|
+
await checkConnection();
|
164
|
+
} finally {
|
165
|
+
await onAfterCheck();
|
166
|
+
}
|
167
|
+
}}
|
168
|
+
>
|
156
169
|
{t('llm.checker.button')}
|
157
170
|
</Button>
|
158
171
|
</Flexbox>
|
@@ -14,7 +14,7 @@ import { Skeleton, Switch } from 'antd';
|
|
14
14
|
import { createStyles } from 'antd-style';
|
15
15
|
import { Loader2Icon, LockIcon } from 'lucide-react';
|
16
16
|
import Link from 'next/link';
|
17
|
-
import { ReactNode, memo, useLayoutEffect } from 'react';
|
17
|
+
import { ReactNode, memo, useCallback, useLayoutEffect, useRef } from 'react';
|
18
18
|
import { Trans, useTranslation } from 'react-i18next';
|
19
19
|
import { Center, Flexbox } from 'react-layout-kit';
|
20
20
|
import urlJoin from 'url-join';
|
@@ -173,7 +173,24 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
|
173
173
|
form.setFieldsValue(data);
|
174
174
|
}, [isLoading, id, data]);
|
175
175
|
|
176
|
-
|
176
|
+
// 标记是否正在进行连接测试
|
177
|
+
const isCheckingConnection = useRef(false);
|
178
|
+
|
179
|
+
const handleValueChange = useCallback(
|
180
|
+
(...params: Parameters<typeof updateAiProviderConfig>) => {
|
181
|
+
// 虽然 debouncedHandleValueChange 早于 onBeforeCheck 执行,
|
182
|
+
// 但是由于 debouncedHandleValueChange 因为 debounce 的原因,本来就会晚 500ms 执行
|
183
|
+
// 所以 isCheckingConnection.current 这时候已经更新了
|
184
|
+
// 测试链接时已经出发一次了 updateAiProviderConfig , 不应该重复更新
|
185
|
+
if (isCheckingConnection.current) return;
|
186
|
+
|
187
|
+
updateAiProviderConfig(...params);
|
188
|
+
},
|
189
|
+
[updateAiProviderConfig],
|
190
|
+
);
|
191
|
+
const { run: debouncedHandleValueChange } = useDebounceFn(handleValueChange, {
|
192
|
+
wait: 500,
|
193
|
+
});
|
177
194
|
|
178
195
|
const isCustom = source === AiProviderSourceEnum.Custom;
|
179
196
|
|
@@ -318,6 +335,16 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
|
318
335
|
<Checker
|
319
336
|
checkErrorRender={checkErrorRender}
|
320
337
|
model={data?.checkModel || checkModel!}
|
338
|
+
onAfterCheck={async () => {
|
339
|
+
// 重置连接测试状态,允许后续的 onValuesChange 更新
|
340
|
+
isCheckingConnection.current = false;
|
341
|
+
}}
|
342
|
+
onBeforeCheck={async () => {
|
343
|
+
// 设置连接测试状态,阻止 onValuesChange 的重复请求
|
344
|
+
isCheckingConnection.current = true;
|
345
|
+
// 主动保存表单最新值,确保 fetchAiProviderRuntimeState 获取最新数据
|
346
|
+
await updateAiProviderConfig(id, form.getFieldsValue());
|
347
|
+
}}
|
321
348
|
provider={id}
|
322
349
|
/>
|
323
350
|
),
|
@@ -389,7 +416,7 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
|
389
416
|
form={form}
|
390
417
|
items={[model]}
|
391
418
|
onValuesChange={(_, values) => {
|
392
|
-
|
419
|
+
debouncedHandleValueChange(id, values);
|
393
420
|
}}
|
394
421
|
variant={'borderless'}
|
395
422
|
{...FORM_STYLE}
|
@@ -34,6 +34,7 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
|
|
34
34
|
<html dir={direction} lang={locale} suppressHydrationWarning>
|
35
35
|
<head>
|
36
36
|
{process.env.DEBUG_REACT_SCAN === '1' && (
|
37
|
+
// eslint-disable-next-line @next/next/no-sync-scripts
|
37
38
|
<script crossOrigin="anonymous" src="https://unpkg.com/react-scan/dist/auto.global.js" />
|
38
39
|
)}
|
39
40
|
</head>
|
@@ -1,6 +1,10 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
GoogleAnalyticsProviderConfig,
|
5
|
+
PostHogProviderAnalyticsConfig,
|
6
|
+
createSingletonAnalytics,
|
7
|
+
} from '@lobehub/analytics';
|
4
8
|
import { AnalyticsProvider } from '@lobehub/analytics/react';
|
5
9
|
import { ReactNode, memo, useMemo } from 'react';
|
6
10
|
|
@@ -10,16 +14,14 @@ import { isDev } from '@/utils/env';
|
|
10
14
|
|
11
15
|
type Props = {
|
12
16
|
children: ReactNode;
|
13
|
-
|
14
|
-
|
15
|
-
posthogHost: string;
|
16
|
-
posthogToken: string;
|
17
|
+
ga4Config: GoogleAnalyticsProviderConfig;
|
18
|
+
postHogConfig: PostHogProviderAnalyticsConfig;
|
17
19
|
};
|
18
20
|
|
19
21
|
let analyticsInstance: ReturnType<typeof createSingletonAnalytics> | null = null;
|
20
22
|
|
21
23
|
export const LobeAnalyticsProvider = memo(
|
22
|
-
({ children,
|
24
|
+
({ children, ga4Config, postHogConfig }: Props) => {
|
23
25
|
const analytics = useMemo(() => {
|
24
26
|
if (analyticsInstance) {
|
25
27
|
return analyticsInstance;
|
@@ -29,13 +31,8 @@ export const LobeAnalyticsProvider = memo(
|
|
29
31
|
business: BUSINESS_LINE,
|
30
32
|
debug: isDev,
|
31
33
|
providers: {
|
32
|
-
|
33
|
-
|
34
|
-
enabled: posthogEnabled,
|
35
|
-
host: posthogHost,
|
36
|
-
key: posthogToken,
|
37
|
-
person_profiles: 'always',
|
38
|
-
},
|
34
|
+
ga4: ga4Config,
|
35
|
+
posthog: postHogConfig,
|
39
36
|
},
|
40
37
|
});
|
41
38
|
|
@@ -2,6 +2,7 @@ import { ReactNode, memo } from 'react';
|
|
2
2
|
|
3
3
|
import { LobeAnalyticsProvider } from '@/components/Analytics/LobeAnalyticsProvider';
|
4
4
|
import { analyticsEnv } from '@/config/analytics';
|
5
|
+
import { isDev } from '@/utils/env';
|
5
6
|
|
6
7
|
type Props = {
|
7
8
|
children: ReactNode;
|
@@ -10,10 +11,21 @@ type Props = {
|
|
10
11
|
export const LobeAnalyticsProviderWrapper = memo<Props>(({ children }) => {
|
11
12
|
return (
|
12
13
|
<LobeAnalyticsProvider
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
ga4Config={{
|
15
|
+
debug: isDev,
|
16
|
+
enabled: analyticsEnv.ENABLE_GOOGLE_ANALYTICS,
|
17
|
+
gtagConfig: {
|
18
|
+
debug_mode: isDev,
|
19
|
+
},
|
20
|
+
measurementId: analyticsEnv.GOOGLE_ANALYTICS_MEASUREMENT_ID ?? '',
|
21
|
+
}}
|
22
|
+
postHogConfig={{
|
23
|
+
debug: analyticsEnv.DEBUG_POSTHOG_ANALYTICS,
|
24
|
+
enabled: analyticsEnv.ENABLED_POSTHOG_ANALYTICS,
|
25
|
+
host: analyticsEnv.POSTHOG_HOST,
|
26
|
+
key: analyticsEnv.POSTHOG_KEY ?? '',
|
27
|
+
person_profiles: 'always',
|
28
|
+
}}
|
17
29
|
>
|
18
30
|
{children}
|
19
31
|
</LobeAnalyticsProvider>
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { cosineDistance, count, sql } from 'drizzle-orm';
|
2
|
-
import { and, asc, desc, eq, inArray, isNull } from 'drizzle-orm/expressions';
|
1
|
+
import { and, asc, cosineDistance, count, desc, eq, inArray, isNull, sql } from 'drizzle-orm';
|
3
2
|
import { chunk } from 'lodash-es';
|
4
3
|
|
5
4
|
import { LobeChatDatabase } from '@/database/type';
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { count, sum } from 'drizzle-orm';
|
2
|
-
import { and, asc, desc, eq, ilike, inArray, like, notExists, or } from 'drizzle-orm/expressions';
|
1
|
+
import { and, asc, count, desc, eq, ilike, inArray, like, notExists, or, sum } from 'drizzle-orm';
|
3
2
|
import type { PgTransaction } from 'drizzle-orm/pg-core';
|
4
3
|
|
5
4
|
import { LobeChatDatabase, Transaction } from '@/database/type';
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import type { HeatmapsProps } from '@lobehub/charts';
|
2
2
|
import dayjs from 'dayjs';
|
3
|
-
import { count, sql } from 'drizzle-orm';
|
4
|
-
import { and, asc, desc, eq, gt, inArray, isNotNull, isNull, like } from 'drizzle-orm/expressions';
|
3
|
+
import { and, asc, count, desc, eq, gt, inArray, isNotNull, isNull, like, sql } from 'drizzle-orm';
|
5
4
|
|
6
5
|
import { LobeChatDatabase } from '@/database/type';
|
7
6
|
import {
|
@@ -1,5 +1,18 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import {
|
2
|
+
Column,
|
3
|
+
and,
|
4
|
+
asc,
|
5
|
+
count,
|
6
|
+
desc,
|
7
|
+
eq,
|
8
|
+
gt,
|
9
|
+
inArray,
|
10
|
+
isNull,
|
11
|
+
like,
|
12
|
+
not,
|
13
|
+
or,
|
14
|
+
sql,
|
15
|
+
} from 'drizzle-orm';
|
3
16
|
import type { PartialDeep } from 'type-fest';
|
4
17
|
|
5
18
|
import { DEFAULT_INBOX_AVATAR } from '@/const/meta';
|