plugin-knowledge-base 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +24 -0
  2. package/client.d.ts +2 -0
  3. package/client.js +1 -0
  4. package/dist/client/index.js +10 -0
  5. package/dist/externalVersion.js +22 -0
  6. package/dist/index.js +48 -0
  7. package/dist/locale/en-US.json +44 -0
  8. package/dist/locale/vi-VN.json +44 -0
  9. package/dist/node_modules/@langchain/textsplitters/LICENSE +21 -0
  10. package/dist/node_modules/@langchain/textsplitters/dist/_virtual/rolldown_runtime.cjs +25 -0
  11. package/dist/node_modules/@langchain/textsplitters/dist/index.cjs +7 -0
  12. package/dist/node_modules/@langchain/textsplitters/dist/index.d.cts +2 -0
  13. package/dist/node_modules/@langchain/textsplitters/dist/index.d.ts +2 -0
  14. package/dist/node_modules/@langchain/textsplitters/dist/index.js +3 -0
  15. package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.cjs +539 -0
  16. package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.d.cts +84 -0
  17. package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.d.ts +84 -0
  18. package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.js +532 -0
  19. package/dist/node_modules/@langchain/textsplitters/package.json +1 -0
  20. package/dist/server/collections/ai-knowledge-base-documents.js +88 -0
  21. package/dist/server/collections/ai-knowledge-bases.js +105 -0
  22. package/dist/server/collections/ai-vector-databases.js +63 -0
  23. package/dist/server/collections/ai-vector-stores.js +72 -0
  24. package/dist/server/features/knowledge-base-impl.js +94 -0
  25. package/dist/server/features/vector-database-impl.js +75 -0
  26. package/dist/server/features/vector-database-provider-impl.js +63 -0
  27. package/dist/server/features/vector-store-provider-impl.js +141 -0
  28. package/dist/server/index.js +49 -0
  29. package/dist/server/pipeline/text-splitter.js +69 -0
  30. package/dist/server/pipeline/vectorization.js +144 -0
  31. package/dist/server/plugin.js +131 -0
  32. package/dist/server/providers/pgvector.js +134 -0
  33. package/dist/server/resources/ai-knowledge-base-documents.js +134 -0
  34. package/dist/server/resources/ai-knowledge-base.js +168 -0
  35. package/dist/server/resources/ai-vector-databases.js +122 -0
  36. package/dist/server/resources/ai-vector-stores.js +95 -0
  37. package/package.json +40 -0
  38. package/server.d.ts +2 -0
  39. package/server.js +1 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var ai_knowledge_base_exports = {};
28
+ __export(ai_knowledge_base_exports, {
29
+ default: () => ai_knowledge_base_default
30
+ });
31
+ module.exports = __toCommonJS(ai_knowledge_base_exports);
32
+ async function checkKBPermission(ctx, filterByTk, action) {
33
+ var _a, _b;
34
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
35
+ const record = await repo.findOne({ filterByTk });
36
+ if (!record) {
37
+ return true;
38
+ }
39
+ const data = record.toJSON();
40
+ const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
41
+ const roles = ctx.state.currentRoles ?? [];
42
+ const isRoot = roles.includes("root");
43
+ if (isRoot) {
44
+ return true;
45
+ }
46
+ if (data.accessLevel === "BASIC") {
47
+ return data.ownerId === userId;
48
+ }
49
+ if (data.accessLevel === "PUBLIC") {
50
+ return false;
51
+ }
52
+ if (data.accessLevel === "SHARED") {
53
+ return false;
54
+ }
55
+ return false;
56
+ }
57
+ var ai_knowledge_base_default = {
58
+ name: "aiKnowledgeBase",
59
+ actions: {
60
+ async list(ctx, next) {
61
+ var _a, _b;
62
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
63
+ const { filter = {}, fields, sort, page, pageSize } = ctx.action.params;
64
+ const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
65
+ const roles = ctx.state.currentRoles ?? [];
66
+ const isRoot = roles.includes("root");
67
+ if (!isRoot) {
68
+ filter.$or = [
69
+ { accessLevel: "PUBLIC" },
70
+ ...userId ? [{ accessLevel: "BASIC", ownerId: userId }] : [],
71
+ ...roles.length ? [{ accessLevel: "SHARED", "allowedRoles.$anyOf": roles }] : []
72
+ ];
73
+ }
74
+ ctx.body = await repo.find({
75
+ filter,
76
+ fields,
77
+ sort: sort ?? ["-createdAt"],
78
+ limit: pageSize,
79
+ offset: page ? (page - 1) * (pageSize || 20) : 0,
80
+ appends: ["vectorStore"]
81
+ });
82
+ await next();
83
+ },
84
+ async get(ctx, next) {
85
+ var _a, _b, _c;
86
+ const { filterByTk } = ctx.action.params;
87
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
88
+ const record = await repo.findOne({
89
+ filterByTk,
90
+ appends: ["vectorStore", "documents"]
91
+ });
92
+ if (record) {
93
+ const data = record.toJSON();
94
+ const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
95
+ const roles = ctx.state.currentRoles ?? [];
96
+ const isRoot = roles.includes("root");
97
+ if (!isRoot) {
98
+ const hasAccess = data.accessLevel === "PUBLIC" || data.accessLevel === "BASIC" && data.ownerId === userId || data.accessLevel === "SHARED" && ((_c = data.allowedRoles) == null ? void 0 : _c.some((r) => roles.includes(r)));
99
+ if (!hasAccess) {
100
+ ctx.throw(403, "Access denied");
101
+ return;
102
+ }
103
+ }
104
+ }
105
+ ctx.body = record;
106
+ await next();
107
+ },
108
+ async create(ctx, next) {
109
+ var _a, _b;
110
+ const rawValues = ctx.action.params.values || {};
111
+ const values = rawValues.values || rawValues;
112
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
113
+ const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
114
+ const roles = ctx.state.currentRoles ?? [];
115
+ const isRoot = roles.includes("root");
116
+ if (values.accessLevel === "PUBLIC" && !isRoot) {
117
+ ctx.throw(403, "Only administrators can create public knowledge bases");
118
+ return;
119
+ }
120
+ if (values.accessLevel === "BASIC") {
121
+ values.ownerId = userId;
122
+ }
123
+ ctx.body = await repo.create({ values });
124
+ if (values.vectorStoreId) {
125
+ await ctx.db.sequelize.query(
126
+ `UPDATE "aiKnowledgeBases" SET "vectorStoreId" = $1 WHERE id = $2`,
127
+ { bind: [values.vectorStoreId, ctx.body.get("id")] }
128
+ );
129
+ }
130
+ await next();
131
+ },
132
+ async update(ctx, next) {
133
+ const { filterByTk } = ctx.action.params;
134
+ const rawValues = ctx.action.params.values || {};
135
+ const values = rawValues.values || rawValues;
136
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
137
+ const allowed = await checkKBPermission(ctx, filterByTk, "update");
138
+ if (!allowed) {
139
+ ctx.throw(403, "You do not have permission to update this knowledge base");
140
+ return;
141
+ }
142
+ ctx.body = await repo.update({
143
+ filterByTk,
144
+ values
145
+ });
146
+ if (values.vectorStoreId) {
147
+ await ctx.db.sequelize.query(
148
+ `UPDATE "aiKnowledgeBases" SET "vectorStoreId" = $1 WHERE id = $2`,
149
+ { bind: [values.vectorStoreId, filterByTk] }
150
+ );
151
+ }
152
+ await next();
153
+ },
154
+ // Fix #3: destroy with permission checks
155
+ async destroy(ctx, next) {
156
+ const { filterByTk } = ctx.action.params;
157
+ const repo = ctx.db.getRepository("aiKnowledgeBases");
158
+ const allowed = await checkKBPermission(ctx, filterByTk, "destroy");
159
+ if (!allowed) {
160
+ ctx.throw(403, "You do not have permission to delete this knowledge base");
161
+ return;
162
+ }
163
+ await repo.destroy({ filterByTk });
164
+ ctx.body = { success: true };
165
+ await next();
166
+ }
167
+ }
168
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var ai_vector_databases_exports = {};
28
+ __export(ai_vector_databases_exports, {
29
+ default: () => ai_vector_databases_default
30
+ });
31
+ module.exports = __toCommonJS(ai_vector_databases_exports);
32
+ var ai_vector_databases_default = {
33
+ name: "aiVectorDatabase",
34
+ actions: {
35
+ async list(ctx, next) {
36
+ const { filter, fields, sort, page, pageSize } = ctx.action.params;
37
+ const repo = ctx.db.getRepository("aiVectorDatabases");
38
+ ctx.body = await repo.find({
39
+ filter,
40
+ fields,
41
+ sort: sort ?? ["-createdAt"],
42
+ limit: pageSize,
43
+ offset: page ? (page - 1) * (pageSize || 20) : 0
44
+ });
45
+ await next();
46
+ },
47
+ async get(ctx, next) {
48
+ const { filterByTk } = ctx.action.params;
49
+ const repo = ctx.db.getRepository("aiVectorDatabases");
50
+ ctx.body = await repo.findOne({ filterByTk });
51
+ await next();
52
+ },
53
+ async create(ctx, next) {
54
+ const rawValues = ctx.action.params.values || {};
55
+ const values = rawValues.values || rawValues;
56
+ const repo = ctx.db.getRepository("aiVectorDatabases");
57
+ ctx.body = await repo.create({ values });
58
+ await next();
59
+ },
60
+ async update(ctx, next) {
61
+ const { filterByTk } = ctx.action.params;
62
+ const rawValues = ctx.action.params.values || {};
63
+ const values = rawValues.values || rawValues;
64
+ const repo = ctx.db.getRepository("aiVectorDatabases");
65
+ ctx.body = await repo.update({
66
+ filterByTk,
67
+ values
68
+ });
69
+ await next();
70
+ },
71
+ async destroy(ctx, next) {
72
+ const { filterByTk } = ctx.action.params;
73
+ const repo = ctx.db.getRepository("aiVectorDatabases");
74
+ await repo.destroy({ filterByTk });
75
+ ctx.body = { success: true };
76
+ await next();
77
+ },
78
+ async test(ctx, next) {
79
+ const rawValues = ctx.action.params.values || {};
80
+ const values = rawValues.values || rawValues;
81
+ const { provider, connectParams } = values;
82
+ if (!provider || !connectParams) {
83
+ ctx.body = { success: false, error: "Provider and connectParams are required" };
84
+ await next();
85
+ return;
86
+ }
87
+ const kbPlugin = ctx.app.pm.get("@nocobase/plugin-knowledge-base");
88
+ if (!kbPlugin) {
89
+ ctx.body = { success: false, error: "Knowledge base plugin not found" };
90
+ await next();
91
+ return;
92
+ }
93
+ try {
94
+ const { Client } = require("pg");
95
+ const client = new Client({
96
+ host: connectParams.host,
97
+ port: connectParams.port || 5432,
98
+ user: connectParams.username,
99
+ password: connectParams.password,
100
+ database: connectParams.database
101
+ });
102
+ await client.connect();
103
+ await client.query("SELECT 1");
104
+ const extResult = await client.query(
105
+ "SELECT * FROM pg_available_extensions WHERE name = 'vector'"
106
+ );
107
+ await client.end();
108
+ if (extResult.rows.length === 0) {
109
+ ctx.body = {
110
+ success: false,
111
+ error: "pgvector extension is not available. Use pgvector/pgvector Docker image."
112
+ };
113
+ } else {
114
+ ctx.body = { success: true };
115
+ }
116
+ } catch (error) {
117
+ ctx.body = { success: false, error: error.message };
118
+ }
119
+ await next();
120
+ }
121
+ }
122
+ };
@@ -0,0 +1,95 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var ai_vector_stores_exports = {};
28
+ __export(ai_vector_stores_exports, {
29
+ default: () => ai_vector_stores_default
30
+ });
31
+ module.exports = __toCommonJS(ai_vector_stores_exports);
32
+ var ai_vector_stores_default = {
33
+ name: "aiVectorStore",
34
+ actions: {
35
+ async list(ctx, next) {
36
+ const { filter, fields, sort, page, pageSize } = ctx.action.params;
37
+ const repo = ctx.db.getRepository("aiVectorStores");
38
+ ctx.body = await repo.find({
39
+ filter,
40
+ fields,
41
+ sort: sort ?? ["-createdAt"],
42
+ limit: pageSize,
43
+ offset: page ? (page - 1) * (pageSize || 20) : 0,
44
+ appends: ["vectorDatabase"]
45
+ });
46
+ await next();
47
+ },
48
+ async get(ctx, next) {
49
+ const { filterByTk } = ctx.action.params;
50
+ const repo = ctx.db.getRepository("aiVectorStores");
51
+ ctx.body = await repo.findOne({
52
+ filterByTk,
53
+ appends: ["vectorDatabase"]
54
+ });
55
+ await next();
56
+ },
57
+ async create(ctx, next) {
58
+ const rawValues = ctx.action.params.values || {};
59
+ const values = rawValues.values || rawValues;
60
+ const repo = ctx.db.getRepository("aiVectorStores");
61
+ ctx.body = await repo.create({ values });
62
+ if (values.vectorDatabaseId) {
63
+ await ctx.db.sequelize.query(
64
+ `UPDATE "aiVectorStores" SET "vectorDatabaseId" = $1 WHERE id = $2`,
65
+ { bind: [values.vectorDatabaseId, ctx.body.get("id")] }
66
+ );
67
+ }
68
+ await next();
69
+ },
70
+ async update(ctx, next) {
71
+ const { filterByTk } = ctx.action.params;
72
+ const rawValues = ctx.action.params.values || {};
73
+ const values = rawValues.values || rawValues;
74
+ const repo = ctx.db.getRepository("aiVectorStores");
75
+ ctx.body = await repo.update({
76
+ filterByTk,
77
+ values
78
+ });
79
+ if (values.vectorDatabaseId) {
80
+ await ctx.db.sequelize.query(
81
+ `UPDATE "aiVectorStores" SET "vectorDatabaseId" = $1 WHERE id = $2`,
82
+ { bind: [values.vectorDatabaseId, filterByTk] }
83
+ );
84
+ }
85
+ await next();
86
+ },
87
+ async destroy(ctx, next) {
88
+ const { filterByTk } = ctx.action.params;
89
+ const repo = ctx.db.getRepository("aiVectorStores");
90
+ await repo.destroy({ filterByTk });
91
+ ctx.body = { success: true };
92
+ await next();
93
+ }
94
+ }
95
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "plugin-knowledge-base",
3
+ "displayName": "AI Knowledge Base",
4
+ "displayName.vi-VN": "Cơ sở tri thức AI",
5
+ "displayName.zh-CN": "AI 知识库",
6
+ "description": "Provides Knowledge Base management, Vector Store, Vector Database (PGVector), and RAG retrieval capabilities for AI Employees.",
7
+ "description.vi-VN": "Cung cấp quản lý Cơ sở tri thức, Vector Store, Vector Database (PGVector), và khả năng truy xuất RAG cho nhân viên AI.",
8
+ "description.zh-CN": "为 AI 员工提供知识库管理、向量存储、向量数据库 (PGVector) 和 RAG 检索功能。",
9
+ "version": "1.0.0",
10
+ "license": "Apache-2.0",
11
+ "main": "./dist/server/index.js",
12
+ "files": [
13
+ "dist",
14
+ "client.js",
15
+ "client.d.ts",
16
+ "server.js",
17
+ "server.d.ts",
18
+ "README.md"
19
+ ],
20
+ "dependencies": {
21
+ "pg": "^8.13.0"
22
+ },
23
+ "peerDependencies": {
24
+ "@nocobase/client": "2.x",
25
+ "@nocobase/server": "2.x",
26
+ "@nocobase/database": "2.x",
27
+ "@nocobase/plugin-ai": "2.x",
28
+ "@nocobase/plugin-file-manager": "2.x",
29
+ "@nocobase/test": "2.x",
30
+ "@langchain/community": "^1.1.0",
31
+ "@langchain/core": "^1.1.24",
32
+ "@langchain/textsplitters": "^0.1.0"
33
+ },
34
+ "keywords": [
35
+ "AI",
36
+ "knowledge-base",
37
+ "RAG",
38
+ "vector-store"
39
+ ]
40
+ }
package/server.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './dist/server';
2
+ export { default } from './dist/server';
package/server.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/server');