@lobehub/chat 1.46.6 → 1.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/changelog/v1.json +18 -0
- package/netlify.toml +1 -1
- package/package.json +2 -1
- package/src/app/(main)/discover/(detail)/provider/[slug]/features/ProviderConfig.tsx +2 -2
- package/src/app/(main)/settings/hooks/useCategory.tsx +3 -3
- package/src/app/(main)/settings/provider/(detail)/[id]/ClientMode.tsx +25 -0
- package/src/app/(main)/settings/provider/(detail)/[id]/page.tsx +2 -1
- package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/index.tsx +0 -1
- package/src/const/settings/knowledge.ts +1 -1
- package/src/database/client/migrations.json +11 -0
- package/src/database/repositories/tableViewer/index.test.ts +256 -0
- package/src/database/repositories/tableViewer/index.ts +251 -0
- package/src/database/server/models/aiProvider.ts +2 -2
- package/src/features/DevPanel/FloatPanel.tsx +136 -0
- package/src/features/DevPanel/PostgresViewer/DataTable/Table.tsx +157 -0
- package/src/features/DevPanel/PostgresViewer/DataTable/TableCell.tsx +34 -0
- package/src/features/DevPanel/PostgresViewer/DataTable/index.tsx +67 -0
- package/src/features/DevPanel/PostgresViewer/Schema.tsx +196 -0
- package/src/features/DevPanel/PostgresViewer/TableColumns.tsx +67 -0
- package/src/features/DevPanel/PostgresViewer/index.tsx +19 -0
- package/src/features/DevPanel/PostgresViewer/useTableColumns.ts +13 -0
- package/src/features/DevPanel/index.tsx +12 -0
- package/src/features/ModelSwitchPanel/index.tsx +4 -2
- package/src/hooks/useEnabledChatModels.ts +2 -2
- package/src/hooks/useModelContextWindowTokens.ts +2 -2
- package/src/hooks/useModelHasContextWindowToken.ts +2 -2
- package/src/hooks/useModelSupportToolUse.ts +2 -2
- package/src/hooks/useModelSupportVision.ts +2 -2
- package/src/layout/GlobalProvider/index.tsx +2 -2
- package/src/server/globalConfig/parseFilesConfig.test.ts +122 -3
- package/src/server/globalConfig/parseFilesConfig.ts +19 -13
- package/src/server/modules/S3/index.ts +3 -0
- package/src/services/_auth.ts +2 -2
- package/src/services/aiModel/client.ts +60 -0
- package/src/services/aiModel/index.test.ts +10 -0
- package/src/services/aiModel/index.ts +5 -0
- package/src/services/aiModel/server.ts +47 -0
- package/src/services/aiModel/type.ts +30 -0
- package/src/services/aiProvider/client.ts +64 -0
- package/src/services/aiProvider/index.test.ts +10 -0
- package/src/services/aiProvider/index.ts +5 -0
- package/src/services/aiProvider/server.ts +43 -0
- package/src/services/aiProvider/type.ts +26 -0
- package/src/services/chat.ts +5 -5
- package/src/services/tableViewer/client.ts +16 -0
- package/src/services/tableViewer/index.ts +3 -0
- package/src/store/aiInfra/slices/aiProvider/action.ts +2 -2
- package/src/types/knowledgeBase/index.ts +1 -1
- package/src/types/serverConfig.ts +6 -0
- package/src/types/tableViewer.ts +30 -0
- package/src/types/user/settings/filesConfig.ts +1 -1
- package/tests/utils.tsx +46 -0
- package/src/features/DebugUI/Content.tsx +0 -34
- package/src/features/DebugUI/index.tsx +0 -20
- package/src/services/aiModel.ts +0 -52
- package/src/services/aiProvider.ts +0 -47
@@ -0,0 +1,60 @@
|
|
1
|
+
import { clientDB } from '@/database/client/db';
|
2
|
+
import { AiInfraRepos } from '@/database/repositories/aiInfra';
|
3
|
+
import { AiModelModel } from '@/database/server/models/aiModel';
|
4
|
+
import { BaseClientService } from '@/services/baseClientService';
|
5
|
+
|
6
|
+
import { IAiModelService } from './type';
|
7
|
+
|
8
|
+
export class ClientService extends BaseClientService implements IAiModelService {
|
9
|
+
private get aiModel(): AiModelModel {
|
10
|
+
return new AiModelModel(clientDB as any, this.userId);
|
11
|
+
}
|
12
|
+
private get aiInfraRepos(): AiInfraRepos {
|
13
|
+
return new AiInfraRepos(clientDB as any, this.userId, {});
|
14
|
+
}
|
15
|
+
|
16
|
+
createAiModel: IAiModelService['createAiModel'] = async (params) => {
|
17
|
+
const data = await this.aiModel.create(params);
|
18
|
+
|
19
|
+
return data?.id;
|
20
|
+
};
|
21
|
+
|
22
|
+
getAiProviderModelList: IAiModelService['getAiProviderModelList'] = async (id) => {
|
23
|
+
return this.aiInfraRepos.getAiProviderModelList(id);
|
24
|
+
};
|
25
|
+
|
26
|
+
getAiModelById: IAiModelService['getAiModelById'] = async (id) => {
|
27
|
+
return this.aiModel.findById(id);
|
28
|
+
};
|
29
|
+
|
30
|
+
toggleModelEnabled: IAiModelService['toggleModelEnabled'] = async (params) => {
|
31
|
+
return this.aiModel.toggleModelEnabled(params);
|
32
|
+
};
|
33
|
+
|
34
|
+
updateAiModel: IAiModelService['updateAiModel'] = async (id, providerId, value) => {
|
35
|
+
return this.aiModel.update(id, providerId, value);
|
36
|
+
};
|
37
|
+
|
38
|
+
batchUpdateAiModels: IAiModelService['batchUpdateAiModels'] = async (id, models) => {
|
39
|
+
return this.aiModel.batchUpdateAiModels(id, models);
|
40
|
+
};
|
41
|
+
|
42
|
+
batchToggleAiModels: IAiModelService['batchToggleAiModels'] = async (id, models, enabled) => {
|
43
|
+
return this.aiModel.batchToggleAiModels(id, models, enabled);
|
44
|
+
};
|
45
|
+
|
46
|
+
clearRemoteModels: IAiModelService['clearRemoteModels'] = async (providerId) => {
|
47
|
+
return this.aiModel.clearRemoteModels(providerId);
|
48
|
+
};
|
49
|
+
|
50
|
+
updateAiModelOrder: IAiModelService['updateAiModelOrder'] = async (providerId, items) => {
|
51
|
+
return this.aiModel.updateModelsOrder(providerId, items);
|
52
|
+
};
|
53
|
+
|
54
|
+
deleteAiModel: IAiModelService['deleteAiModel'] = async (params: {
|
55
|
+
id: string;
|
56
|
+
providerId: string;
|
57
|
+
}) => {
|
58
|
+
return this.aiModel.delete(params.id, params.providerId);
|
59
|
+
};
|
60
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
2
|
+
import { IAiModelService } from '@/services/aiModel/type';
|
3
|
+
|
4
|
+
export class ServerService implements IAiModelService {
|
5
|
+
createAiModel: IAiModelService['createAiModel'] = async (params) => {
|
6
|
+
return lambdaClient.aiModel.createAiModel.mutate(params);
|
7
|
+
};
|
8
|
+
|
9
|
+
getAiProviderModelList: IAiModelService['getAiProviderModelList'] = async (id) => {
|
10
|
+
return lambdaClient.aiModel.getAiProviderModelList.query({ id });
|
11
|
+
};
|
12
|
+
|
13
|
+
getAiModelById: IAiModelService['getAiModelById'] = async (id) => {
|
14
|
+
return lambdaClient.aiModel.getAiModelById.query({ id });
|
15
|
+
};
|
16
|
+
|
17
|
+
toggleModelEnabled: IAiModelService['toggleModelEnabled'] = async (params) => {
|
18
|
+
return lambdaClient.aiModel.toggleModelEnabled.mutate(params);
|
19
|
+
};
|
20
|
+
|
21
|
+
updateAiModel: IAiModelService['updateAiModel'] = async (id, providerId, value) => {
|
22
|
+
return lambdaClient.aiModel.updateAiModel.mutate({ id, providerId, value });
|
23
|
+
};
|
24
|
+
|
25
|
+
batchUpdateAiModels: IAiModelService['batchUpdateAiModels'] = async (id, models) => {
|
26
|
+
return lambdaClient.aiModel.batchUpdateAiModels.mutate({ id, models });
|
27
|
+
};
|
28
|
+
|
29
|
+
batchToggleAiModels: IAiModelService['batchToggleAiModels'] = async (id, models, enabled) => {
|
30
|
+
return lambdaClient.aiModel.batchToggleAiModels.mutate({ enabled, id, models });
|
31
|
+
};
|
32
|
+
|
33
|
+
clearRemoteModels: IAiModelService['clearRemoteModels'] = async (providerId) => {
|
34
|
+
return lambdaClient.aiModel.clearRemoteModels.mutate({ providerId });
|
35
|
+
};
|
36
|
+
|
37
|
+
updateAiModelOrder: IAiModelService['updateAiModelOrder'] = async (providerId, items) => {
|
38
|
+
return lambdaClient.aiModel.updateAiModelOrder.mutate({ providerId, sortMap: items });
|
39
|
+
};
|
40
|
+
|
41
|
+
deleteAiModel: IAiModelService['deleteAiModel'] = async (params: {
|
42
|
+
id: string;
|
43
|
+
providerId: string;
|
44
|
+
}) => {
|
45
|
+
return lambdaClient.aiModel.removeAiModel.mutate(params);
|
46
|
+
};
|
47
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/* eslint-disable typescript-sort-keys/interface */
|
2
|
+
import {
|
3
|
+
AiModelSortMap,
|
4
|
+
AiProviderModelListItem,
|
5
|
+
CreateAiModelParams,
|
6
|
+
ToggleAiModelEnableParams,
|
7
|
+
UpdateAiModelParams,
|
8
|
+
} from '@/types/aiModel';
|
9
|
+
|
10
|
+
export interface IAiModelService {
|
11
|
+
createAiModel: (params: CreateAiModelParams) => Promise<any>;
|
12
|
+
|
13
|
+
getAiProviderModelList: (id: string) => Promise<AiProviderModelListItem[]>;
|
14
|
+
|
15
|
+
getAiModelById: (id: string) => Promise<any>;
|
16
|
+
|
17
|
+
toggleModelEnabled: (params: ToggleAiModelEnableParams) => Promise<any>;
|
18
|
+
|
19
|
+
updateAiModel: (id: string, providerId: string, value: UpdateAiModelParams) => Promise<any>;
|
20
|
+
|
21
|
+
batchUpdateAiModels: (id: string, models: AiProviderModelListItem[]) => Promise<any>;
|
22
|
+
|
23
|
+
batchToggleAiModels: (id: string, models: string[], enabled: boolean) => Promise<any>;
|
24
|
+
|
25
|
+
clearRemoteModels: (providerId: string) => Promise<any>;
|
26
|
+
|
27
|
+
updateAiModelOrder: (providerId: string, items: AiModelSortMap[]) => Promise<any>;
|
28
|
+
|
29
|
+
deleteAiModel: (params: { id: string; providerId: string }) => Promise<any>;
|
30
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import { clientDB } from '@/database/client/db';
|
2
|
+
import { AiInfraRepos } from '@/database/repositories/aiInfra';
|
3
|
+
import { AiProviderModel } from '@/database/server/models/aiProvider';
|
4
|
+
import { BaseClientService } from '@/services/baseClientService';
|
5
|
+
|
6
|
+
import { IAiProviderService } from './type';
|
7
|
+
|
8
|
+
export class ClientService extends BaseClientService implements IAiProviderService {
|
9
|
+
private get aiProviderModel(): AiProviderModel {
|
10
|
+
return new AiProviderModel(clientDB as any, this.userId);
|
11
|
+
}
|
12
|
+
private get aiInfraRepos(): AiInfraRepos {
|
13
|
+
let config = {};
|
14
|
+
if (typeof window !== 'undefined') {
|
15
|
+
config = window.global_serverConfigStore.getState().serverConfig.aiProvider || {};
|
16
|
+
}
|
17
|
+
|
18
|
+
return new AiInfraRepos(clientDB as any, this.userId, config);
|
19
|
+
}
|
20
|
+
|
21
|
+
createAiProvider: IAiProviderService['createAiProvider'] = async (params) => {
|
22
|
+
const data = await this.aiProviderModel.create(params);
|
23
|
+
|
24
|
+
return data?.id;
|
25
|
+
};
|
26
|
+
|
27
|
+
getAiProviderById: IAiProviderService['getAiProviderById'] = async (id) => {
|
28
|
+
return this.aiProviderModel.getAiProviderById(id);
|
29
|
+
};
|
30
|
+
|
31
|
+
getAiProviderList: IAiProviderService['getAiProviderList'] = async () => {
|
32
|
+
return await this.aiInfraRepos.getAiProviderList();
|
33
|
+
};
|
34
|
+
|
35
|
+
getAiProviderRuntimeState: IAiProviderService['getAiProviderRuntimeState'] = async () => {
|
36
|
+
const runtimeConfig = await this.aiProviderModel.getAiProviderRuntimeConfig();
|
37
|
+
|
38
|
+
const enabledAiProviders = await this.aiInfraRepos.getUserEnabledProviderList();
|
39
|
+
|
40
|
+
const enabledAiModels = await this.aiInfraRepos.getEnabledModels();
|
41
|
+
|
42
|
+
return { enabledAiModels, enabledAiProviders, runtimeConfig };
|
43
|
+
};
|
44
|
+
|
45
|
+
toggleProviderEnabled: IAiProviderService['toggleProviderEnabled'] = async (id, enabled) => {
|
46
|
+
return this.aiProviderModel.toggleProviderEnabled(id, enabled);
|
47
|
+
};
|
48
|
+
|
49
|
+
updateAiProvider: IAiProviderService['updateAiProvider'] = async (id, value) => {
|
50
|
+
return this.aiProviderModel.update(id, value);
|
51
|
+
};
|
52
|
+
|
53
|
+
updateAiProviderConfig: IAiProviderService['updateAiProviderConfig'] = async (id, value) => {
|
54
|
+
return this.aiProviderModel.updateConfig(id, value);
|
55
|
+
};
|
56
|
+
|
57
|
+
updateAiProviderOrder: IAiProviderService['updateAiProviderOrder'] = async (items) => {
|
58
|
+
return this.aiProviderModel.updateOrder(items);
|
59
|
+
};
|
60
|
+
|
61
|
+
deleteAiProvider: IAiProviderService['deleteAiProvider'] = async (id) => {
|
62
|
+
return this.aiProviderModel.delete(id);
|
63
|
+
};
|
64
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
2
|
+
|
3
|
+
import { IAiProviderService } from './type';
|
4
|
+
|
5
|
+
export class ServerService implements IAiProviderService {
|
6
|
+
createAiProvider: IAiProviderService['createAiProvider'] = async (params) => {
|
7
|
+
return lambdaClient.aiProvider.createAiProvider.mutate(params);
|
8
|
+
};
|
9
|
+
|
10
|
+
getAiProviderList: IAiProviderService['getAiProviderList'] = async () => {
|
11
|
+
return lambdaClient.aiProvider.getAiProviderList.query();
|
12
|
+
};
|
13
|
+
|
14
|
+
getAiProviderById: IAiProviderService['getAiProviderById'] = async (id) => {
|
15
|
+
return lambdaClient.aiProvider.getAiProviderById.query({ id });
|
16
|
+
};
|
17
|
+
|
18
|
+
toggleProviderEnabled: IAiProviderService['toggleProviderEnabled'] = async (id, enabled) => {
|
19
|
+
return lambdaClient.aiProvider.toggleProviderEnabled.mutate({ enabled, id });
|
20
|
+
};
|
21
|
+
|
22
|
+
updateAiProvider: IAiProviderService['updateAiProvider'] = async (id, value) => {
|
23
|
+
return lambdaClient.aiProvider.updateAiProvider.mutate({ id, value });
|
24
|
+
};
|
25
|
+
|
26
|
+
updateAiProviderConfig: IAiProviderService['updateAiProviderConfig'] = async (id, value) => {
|
27
|
+
return lambdaClient.aiProvider.updateAiProviderConfig.mutate({ id, value });
|
28
|
+
};
|
29
|
+
|
30
|
+
updateAiProviderOrder: IAiProviderService['updateAiProviderOrder'] = async (items) => {
|
31
|
+
return lambdaClient.aiProvider.updateAiProviderOrder.mutate({ sortMap: items });
|
32
|
+
};
|
33
|
+
|
34
|
+
deleteAiProvider: IAiProviderService['deleteAiProvider'] = async (id) => {
|
35
|
+
return lambdaClient.aiProvider.removeAiProvider.mutate({ id });
|
36
|
+
};
|
37
|
+
|
38
|
+
getAiProviderRuntimeState: IAiProviderService['getAiProviderRuntimeState'] = async (
|
39
|
+
isLogin?: boolean,
|
40
|
+
) => {
|
41
|
+
return lambdaClient.aiProvider.getAiProviderRuntimeState.query({ isLogin });
|
42
|
+
};
|
43
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import {
|
2
|
+
AiProviderRuntimeState,
|
3
|
+
AiProviderSortMap,
|
4
|
+
CreateAiProviderParams,
|
5
|
+
UpdateAiProviderConfigParams,
|
6
|
+
} from '@/types/aiProvider';
|
7
|
+
|
8
|
+
export interface IAiProviderService {
|
9
|
+
createAiProvider: (params: CreateAiProviderParams) => Promise<any>;
|
10
|
+
|
11
|
+
deleteAiProvider: (id: string) => Promise<any>;
|
12
|
+
|
13
|
+
getAiProviderById: (id: string) => Promise<any>;
|
14
|
+
|
15
|
+
getAiProviderList: () => Promise<any>;
|
16
|
+
|
17
|
+
getAiProviderRuntimeState: (isLogin?: boolean) => Promise<AiProviderRuntimeState>;
|
18
|
+
|
19
|
+
toggleProviderEnabled: (id: string, enabled: boolean) => Promise<any>;
|
20
|
+
|
21
|
+
updateAiProvider: (id: string, value: any) => Promise<any>;
|
22
|
+
|
23
|
+
updateAiProviderConfig: (id: string, value: UpdateAiProviderConfigParams) => Promise<any>;
|
24
|
+
|
25
|
+
updateAiProviderOrder: (items: AiProviderSortMap[]) => Promise<any>;
|
26
|
+
}
|
package/src/services/chat.ts
CHANGED
@@ -7,7 +7,7 @@ import { INBOX_GUIDE_SYSTEMROLE } from '@/const/guide';
|
|
7
7
|
import { INBOX_SESSION_ID } from '@/const/session';
|
8
8
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
9
9
|
import { TracePayload, TraceTagMap } from '@/const/trace';
|
10
|
-
import { isServerMode } from '@/const/version';
|
10
|
+
import { isDeprecatedEdition, isServerMode } from '@/const/version';
|
11
11
|
import {
|
12
12
|
AgentRuntime,
|
13
13
|
AgentRuntimeError,
|
@@ -42,7 +42,7 @@ import { API_ENDPOINTS } from './_url';
|
|
42
42
|
|
43
43
|
const isCanUseFC = (model: string, provider: string) => {
|
44
44
|
// TODO: remove isDeprecatedEdition condition in V2.0
|
45
|
-
if (
|
45
|
+
if (isDeprecatedEdition) {
|
46
46
|
return modelProviderSelectors.isModelEnabledFunctionCall(model)(useUserStore.getState());
|
47
47
|
}
|
48
48
|
|
@@ -53,7 +53,7 @@ const findAzureDeploymentName = (model: string) => {
|
|
53
53
|
let deploymentId = model;
|
54
54
|
|
55
55
|
// TODO: remove isDeprecatedEdition condition in V2.0
|
56
|
-
if (
|
56
|
+
if (isDeprecatedEdition) {
|
57
57
|
const chatModelCards = modelProviderSelectors.getModelCardsById(ModelProvider.Azure)(
|
58
58
|
useUserStore.getState(),
|
59
59
|
);
|
@@ -74,7 +74,7 @@ const findAzureDeploymentName = (model: string) => {
|
|
74
74
|
|
75
75
|
const isEnableFetchOnClient = (provider: string) => {
|
76
76
|
// TODO: remove this condition in V2.0
|
77
|
-
if (
|
77
|
+
if (isDeprecatedEdition) {
|
78
78
|
return modelConfigSelectors.isProviderFetchOnClient(provider)(useUserStore.getState());
|
79
79
|
} else {
|
80
80
|
return aiProviderSelectors.isProviderFetchOnClient(provider)(useAiInfraStore.getState());
|
@@ -341,7 +341,7 @@ class ChatService {
|
|
341
341
|
const isBuiltin = Object.values(ModelProvider).includes(provider as any);
|
342
342
|
|
343
343
|
// TODO: remove `!isDeprecatedEdition` condition in V2.0
|
344
|
-
if (
|
344
|
+
if (!isDeprecatedEdition && !isBuiltin) {
|
345
345
|
const providerConfig = aiProviderSelectors.providerConfigById(provider)(
|
346
346
|
useAiInfraStore.getState(),
|
347
347
|
);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { clientDB } from '@/database/client/db';
|
2
|
+
import { TableViewerRepo } from '@/database/repositories/tableViewer';
|
3
|
+
import { BaseClientService } from '@/services/baseClientService';
|
4
|
+
|
5
|
+
export class ClientService extends BaseClientService {
|
6
|
+
private get tableViewerRepo(): TableViewerRepo {
|
7
|
+
return new TableViewerRepo(clientDB as any, this.userId);
|
8
|
+
}
|
9
|
+
|
10
|
+
getAllTables = async () => this.tableViewerRepo.getAllTables();
|
11
|
+
|
12
|
+
getTableDetails = async (tableName: string) => this.tableViewerRepo.getTableDetails(tableName);
|
13
|
+
|
14
|
+
getTableData = async (tableName: string) =>
|
15
|
+
this.tableViewerRepo.getTableData(tableName, { page: 1, pageSize: 300 });
|
16
|
+
}
|
@@ -3,7 +3,7 @@ import { SWRResponse, mutate } from 'swr';
|
|
3
3
|
import { StateCreator } from 'zustand/vanilla';
|
4
4
|
|
5
5
|
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
|
6
|
-
import {
|
6
|
+
import { isDeprecatedEdition } from '@/const/version';
|
7
7
|
import { useClientDataSWR } from '@/libs/swr';
|
8
8
|
import { aiProviderService } from '@/services/aiProvider';
|
9
9
|
import { AiInfraStore } from '@/store/aiInfra/store';
|
@@ -170,7 +170,7 @@ export const createAiProviderSlice: StateCreator<
|
|
170
170
|
|
171
171
|
useFetchAiProviderRuntimeState: (isLogin) =>
|
172
172
|
useClientDataSWR<AiProviderRuntimeState | undefined>(
|
173
|
-
|
173
|
+
!isDeprecatedEdition ? [AiProviderSwrKey.fetchAiProviderRuntimeState, isLogin] : null,
|
174
174
|
async ([, isLogin]) => {
|
175
175
|
if (isLogin) return aiProviderService.getAiProviderRuntimeState();
|
176
176
|
|
@@ -24,7 +24,13 @@ export interface GlobalServerConfig {
|
|
24
24
|
defaultAgent?: DeepPartial<UserDefaultAgent>;
|
25
25
|
enableUploadFileToServer?: boolean;
|
26
26
|
enabledAccessCode?: boolean;
|
27
|
+
/**
|
28
|
+
* @deprecated
|
29
|
+
*/
|
27
30
|
enabledOAuthSSO?: boolean;
|
31
|
+
/**
|
32
|
+
* @deprecated
|
33
|
+
*/
|
28
34
|
languageModel?: ServerLanguageModel;
|
29
35
|
oAuthSSOProviders?: string[];
|
30
36
|
systemAgent?: DeepPartial<UserSystemAgentConfig>;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
export interface TableBasicInfo {
|
2
|
+
count: number;
|
3
|
+
name: string;
|
4
|
+
type: 'BASE TABLE' | 'VIEW';
|
5
|
+
}
|
6
|
+
|
7
|
+
export interface TableColumnInfo {
|
8
|
+
defaultValue?: string;
|
9
|
+
foreignKey?: {
|
10
|
+
column: string;
|
11
|
+
table: string;
|
12
|
+
};
|
13
|
+
isPrimaryKey: boolean;
|
14
|
+
name: string;
|
15
|
+
nullable: boolean;
|
16
|
+
type: string;
|
17
|
+
}
|
18
|
+
|
19
|
+
export interface PaginationParams {
|
20
|
+
page: number;
|
21
|
+
pageSize: number;
|
22
|
+
sortBy?: string;
|
23
|
+
sortOrder?: 'asc' | 'desc';
|
24
|
+
}
|
25
|
+
|
26
|
+
export interface FilterCondition {
|
27
|
+
column: string;
|
28
|
+
operator: 'equals' | 'contains' | 'startsWith' | 'endsWith';
|
29
|
+
value: any;
|
30
|
+
}
|
package/tests/utils.tsx
CHANGED
@@ -9,3 +9,49 @@ const swrConfig = {
|
|
9
9
|
export const withSWR = ({ children }: PropsWithChildren) => (
|
10
10
|
<SWRConfig value={swrConfig}>{children}</SWRConfig>
|
11
11
|
);
|
12
|
+
|
13
|
+
interface TestServiceOptions {
|
14
|
+
/** 是否检查 async */
|
15
|
+
checkAsync?: boolean;
|
16
|
+
/** 自定义的额外检查 */
|
17
|
+
extraChecks?: (method: string, func: () => any) => void;
|
18
|
+
/** 是否跳过某些方法 */
|
19
|
+
skipMethods?: string[];
|
20
|
+
}
|
21
|
+
|
22
|
+
const builtinSkipProps = new Set(['userId']);
|
23
|
+
|
24
|
+
export const testService = (ServiceClass: new () => any, options: TestServiceOptions = {}) => {
|
25
|
+
const { checkAsync = true, skipMethods = ['userId'], extraChecks } = options;
|
26
|
+
|
27
|
+
describe(ServiceClass.name, () => {
|
28
|
+
it('should implement all methods as arrow functions', () => {
|
29
|
+
const service = new ServiceClass();
|
30
|
+
|
31
|
+
const methods = Object.getOwnPropertyNames(service).filter(
|
32
|
+
(method) => !builtinSkipProps.has(method) || !skipMethods.includes(method),
|
33
|
+
);
|
34
|
+
|
35
|
+
methods.forEach((method) => {
|
36
|
+
const func = service[method];
|
37
|
+
// 检查是否为函数
|
38
|
+
expect(typeof func).toBe('function');
|
39
|
+
|
40
|
+
const funcString = func.toString();
|
41
|
+
|
42
|
+
// 验证是否是箭头函数
|
43
|
+
expect(funcString).toContain('=>');
|
44
|
+
|
45
|
+
// 可选的 async 检查
|
46
|
+
if (checkAsync) {
|
47
|
+
expect(funcString).toMatch(/^async.*=>/);
|
48
|
+
}
|
49
|
+
|
50
|
+
// 运行额外的自定义检查
|
51
|
+
if (extraChecks) {
|
52
|
+
extraChecks(method, func);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
});
|
56
|
+
});
|
57
|
+
};
|
@@ -1,34 +0,0 @@
|
|
1
|
-
import { Icon } from '@lobehub/ui';
|
2
|
-
import { App, FloatButton, Spin } from 'antd';
|
3
|
-
import { DatabaseIcon, Loader2 } from 'lucide-react';
|
4
|
-
import { memo, useState } from 'react';
|
5
|
-
|
6
|
-
import { debugService } from '@/services/debug';
|
7
|
-
|
8
|
-
const DebugUI = memo(() => {
|
9
|
-
const [loading, setLoading] = useState(false);
|
10
|
-
const { message } = App.useApp();
|
11
|
-
return (
|
12
|
-
<>
|
13
|
-
{loading && <Spin fullscreen />}
|
14
|
-
<FloatButton
|
15
|
-
icon={<Icon icon={loading ? Loader2 : DatabaseIcon} spin={loading} />}
|
16
|
-
onClick={async () => {
|
17
|
-
setLoading(true);
|
18
|
-
|
19
|
-
const startTime = Date.now();
|
20
|
-
|
21
|
-
await debugService.insertLargeDataToDB();
|
22
|
-
|
23
|
-
const duration = Date.now() - startTime;
|
24
|
-
|
25
|
-
setLoading(false);
|
26
|
-
message.success(`插入成功,耗时:${(duration / 1000).toFixed(1)} s`);
|
27
|
-
}}
|
28
|
-
tooltip={'性能压测,插入100w数据'}
|
29
|
-
/>
|
30
|
-
</>
|
31
|
-
);
|
32
|
-
});
|
33
|
-
|
34
|
-
export default DebugUI;
|
@@ -1,20 +0,0 @@
|
|
1
|
-
'use client';
|
2
|
-
|
3
|
-
import dynamic from 'next/dynamic';
|
4
|
-
import { FC } from 'react';
|
5
|
-
|
6
|
-
import { getDebugConfig } from '@/config/debug';
|
7
|
-
|
8
|
-
let DebugUI: FC = () => null;
|
9
|
-
|
10
|
-
// we need use Constant Folding to remove code below in production
|
11
|
-
// refs: https://webpack.js.org/plugins/internal-plugins/#constplugin
|
12
|
-
if (process.env.NODE_ENV === 'development') {
|
13
|
-
// eslint-disable-next-line unicorn/no-lonely-if
|
14
|
-
if (getDebugConfig().DEBUG_MODE) {
|
15
|
-
// @ts-ignore
|
16
|
-
DebugUI = dynamic(() => import('./Content'), { ssr: false });
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
export default DebugUI;
|
package/src/services/aiModel.ts
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
import { lambdaClient } from '@/libs/trpc/client';
|
2
|
-
import {
|
3
|
-
AiModelSortMap,
|
4
|
-
AiProviderModelListItem,
|
5
|
-
CreateAiModelParams,
|
6
|
-
ToggleAiModelEnableParams,
|
7
|
-
UpdateAiModelParams,
|
8
|
-
} from '@/types/aiModel';
|
9
|
-
|
10
|
-
class AiModelService {
|
11
|
-
createAiModel = async (params: CreateAiModelParams) => {
|
12
|
-
return lambdaClient.aiModel.createAiModel.mutate(params);
|
13
|
-
};
|
14
|
-
|
15
|
-
getAiProviderModelList = async (id: string): Promise<AiProviderModelListItem[]> => {
|
16
|
-
return lambdaClient.aiModel.getAiProviderModelList.query({ id });
|
17
|
-
};
|
18
|
-
|
19
|
-
getAiModelById = async (id: string) => {
|
20
|
-
return lambdaClient.aiModel.getAiModelById.query({ id });
|
21
|
-
};
|
22
|
-
|
23
|
-
toggleModelEnabled = async (params: ToggleAiModelEnableParams) => {
|
24
|
-
return lambdaClient.aiModel.toggleModelEnabled.mutate(params);
|
25
|
-
};
|
26
|
-
|
27
|
-
updateAiModel = async (id: string, providerId: string, value: UpdateAiModelParams) => {
|
28
|
-
return lambdaClient.aiModel.updateAiModel.mutate({ id, providerId, value });
|
29
|
-
};
|
30
|
-
|
31
|
-
batchUpdateAiModels = async (id: string, models: AiProviderModelListItem[]) => {
|
32
|
-
return lambdaClient.aiModel.batchUpdateAiModels.mutate({ id, models });
|
33
|
-
};
|
34
|
-
|
35
|
-
batchToggleAiModels = async (id: string, models: string[], enabled: boolean) => {
|
36
|
-
return lambdaClient.aiModel.batchToggleAiModels.mutate({ enabled, id, models });
|
37
|
-
};
|
38
|
-
|
39
|
-
clearRemoteModels = async (providerId: string) => {
|
40
|
-
return lambdaClient.aiModel.clearRemoteModels.mutate({ providerId });
|
41
|
-
};
|
42
|
-
|
43
|
-
updateAiModelOrder = async (providerId: string, items: AiModelSortMap[]) => {
|
44
|
-
return lambdaClient.aiModel.updateAiModelOrder.mutate({ providerId, sortMap: items });
|
45
|
-
};
|
46
|
-
|
47
|
-
deleteAiModel = async (params: { id: string; providerId: string }) => {
|
48
|
-
return lambdaClient.aiModel.removeAiModel.mutate(params);
|
49
|
-
};
|
50
|
-
}
|
51
|
-
|
52
|
-
export const aiModelService = new AiModelService();
|
@@ -1,47 +0,0 @@
|
|
1
|
-
import { lambdaClient } from '@/libs/trpc/client';
|
2
|
-
import {
|
3
|
-
AiProviderRuntimeState,
|
4
|
-
AiProviderSortMap,
|
5
|
-
CreateAiProviderParams,
|
6
|
-
UpdateAiProviderConfigParams,
|
7
|
-
} from '@/types/aiProvider';
|
8
|
-
|
9
|
-
class AiProviderService {
|
10
|
-
createAiProvider = async (params: CreateAiProviderParams) => {
|
11
|
-
return lambdaClient.aiProvider.createAiProvider.mutate(params);
|
12
|
-
};
|
13
|
-
|
14
|
-
getAiProviderList = async () => {
|
15
|
-
return lambdaClient.aiProvider.getAiProviderList.query();
|
16
|
-
};
|
17
|
-
|
18
|
-
getAiProviderById = async (id: string) => {
|
19
|
-
return lambdaClient.aiProvider.getAiProviderById.query({ id });
|
20
|
-
};
|
21
|
-
|
22
|
-
toggleProviderEnabled = async (id: string, enabled: boolean) => {
|
23
|
-
return lambdaClient.aiProvider.toggleProviderEnabled.mutate({ enabled, id });
|
24
|
-
};
|
25
|
-
|
26
|
-
updateAiProvider = async (id: string, value: any) => {
|
27
|
-
return lambdaClient.aiProvider.updateAiProvider.mutate({ id, value });
|
28
|
-
};
|
29
|
-
|
30
|
-
updateAiProviderConfig = async (id: string, value: UpdateAiProviderConfigParams) => {
|
31
|
-
return lambdaClient.aiProvider.updateAiProviderConfig.mutate({ id, value });
|
32
|
-
};
|
33
|
-
|
34
|
-
updateAiProviderOrder = async (items: AiProviderSortMap[]) => {
|
35
|
-
return lambdaClient.aiProvider.updateAiProviderOrder.mutate({ sortMap: items });
|
36
|
-
};
|
37
|
-
|
38
|
-
deleteAiProvider = async (id: string) => {
|
39
|
-
return lambdaClient.aiProvider.removeAiProvider.mutate({ id });
|
40
|
-
};
|
41
|
-
|
42
|
-
getAiProviderRuntimeState = async (isLogin?: boolean): Promise<AiProviderRuntimeState> => {
|
43
|
-
return lambdaClient.aiProvider.getAiProviderRuntimeState.query({ isLogin });
|
44
|
-
};
|
45
|
-
}
|
46
|
-
|
47
|
-
export const aiProviderService = new AiProviderService();
|