plugin-knowledge-base 1.0.1 → 1.0.4
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/dist/client/index.js +1 -1
- package/dist/externalVersion.js +1 -0
- package/dist/node_modules/@langchain/textsplitters/LICENSE +21 -0
- package/dist/node_modules/@langchain/textsplitters/dist/_virtual/rolldown_runtime.cjs +25 -0
- package/dist/node_modules/@langchain/textsplitters/dist/index.cjs +7 -0
- package/dist/node_modules/@langchain/textsplitters/dist/index.d.cts +2 -0
- package/dist/node_modules/@langchain/textsplitters/dist/index.d.ts +2 -0
- package/dist/node_modules/@langchain/textsplitters/dist/index.js +3 -0
- package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.cjs +539 -0
- package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.d.cts +84 -0
- package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.d.ts +84 -0
- package/dist/node_modules/@langchain/textsplitters/dist/text_splitter.js +532 -0
- package/dist/node_modules/@langchain/textsplitters/package.json +1 -0
- package/dist/server/actions/add-document.js +85 -0
- package/dist/server/features/vector-store-provider-impl.js +50 -15
- package/dist/server/pipeline/simple-embeddings.js +82 -0
- package/dist/server/pipeline/vectorization.js +28 -15
- package/dist/server/plugin.js +16 -0
- package/dist/server/request-context.js +54 -0
- package/dist/server/resources/ai-knowledge-base-documents.js +3 -3
- package/dist/server/resources/ai-knowledge-base.js +8 -8
- package/package.json +1 -1
|
@@ -75,9 +75,45 @@ class VectorStoreProviderImpl {
|
|
|
75
75
|
embeddings,
|
|
76
76
|
vectorDatabase.connectParams
|
|
77
77
|
);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
let accessLevel = propsMap.get("accessLevel");
|
|
79
|
+
let ownerId = propsMap.get("ownerId");
|
|
80
|
+
let allowedRoles;
|
|
81
|
+
if (!accessLevel) {
|
|
82
|
+
const knowledgeBases = await this.plugin.db.getRepository("aiKnowledgeBases").find({
|
|
83
|
+
filter: { vectorStoreId: vectorStoreConfigId }
|
|
84
|
+
});
|
|
85
|
+
const { getCurrentUserId, getCurrentUserRoles } = require("../request-context");
|
|
86
|
+
const hasPrivateKB = knowledgeBases.some(
|
|
87
|
+
(kb) => kb.accessLevel === "PRIVATE"
|
|
88
|
+
);
|
|
89
|
+
if (hasPrivateKB) {
|
|
90
|
+
accessLevel = "PRIVATE";
|
|
91
|
+
const currentUserId = getCurrentUserId();
|
|
92
|
+
if (currentUserId) {
|
|
93
|
+
ownerId = String(currentUserId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const sharedKBs = knowledgeBases.filter(
|
|
97
|
+
(kb) => kb.accessLevel === "SHARED"
|
|
98
|
+
);
|
|
99
|
+
if (sharedKBs.length > 0 && !hasPrivateKB) {
|
|
100
|
+
const currentRoles = getCurrentUserRoles();
|
|
101
|
+
const allAllowedRoles = /* @__PURE__ */ new Set();
|
|
102
|
+
for (const kb of sharedKBs) {
|
|
103
|
+
for (const role of kb.allowedRoles ?? []) {
|
|
104
|
+
allAllowedRoles.add(role);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const hasAccess = currentRoles.some((r) => allAllowedRoles.has(r)) || currentRoles.includes("root");
|
|
108
|
+
if (!hasAccess) {
|
|
109
|
+
accessLevel = "DENIED";
|
|
110
|
+
} else {
|
|
111
|
+
accessLevel = "SHARED";
|
|
112
|
+
allowedRoles = currentRoles;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return new DefaultVectorStoreService(vectorStore, { accessLevel, ownerId, allowedRoles });
|
|
81
117
|
}
|
|
82
118
|
async createEmbeddings(llmServiceName, embeddingModel) {
|
|
83
119
|
const llmServiceRecord = await this.plugin.db.getRepository("llmServices").findOne({
|
|
@@ -87,18 +123,13 @@ class VectorStoreProviderImpl {
|
|
|
87
123
|
throw new Error(`LLM service "${llmServiceName}" not found`);
|
|
88
124
|
}
|
|
89
125
|
const llmService = llmServiceRecord.toJSON();
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const embeddingProvider = new providerMeta.embedding({
|
|
97
|
-
app: this.plugin.app,
|
|
98
|
-
serviceOptions: llmService.options,
|
|
99
|
-
modelOptions: { model: embeddingModel }
|
|
126
|
+
const { SimpleHTTPEmbeddings } = require("../pipeline/simple-embeddings");
|
|
127
|
+
const serviceOpts = this.plugin.app.environment.renderJsonTemplate(llmService.options || {});
|
|
128
|
+
return new SimpleHTTPEmbeddings({
|
|
129
|
+
baseURL: serviceOpts.baseURL || serviceOpts.baseUrl || "",
|
|
130
|
+
apiKey: serviceOpts.apiKey || "",
|
|
131
|
+
model: embeddingModel
|
|
100
132
|
});
|
|
101
|
-
return embeddingProvider.createEmbedding();
|
|
102
133
|
}
|
|
103
134
|
}
|
|
104
135
|
class DefaultVectorStoreService {
|
|
@@ -111,8 +142,12 @@ class DefaultVectorStoreService {
|
|
|
111
142
|
}
|
|
112
143
|
async search(query, options) {
|
|
113
144
|
const { topK = 3, score, filter } = options ?? {};
|
|
145
|
+
const level = this.accessContext.accessLevel;
|
|
146
|
+
if (level === "DENIED") {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
114
149
|
let mergedFilter = filter;
|
|
115
|
-
if (
|
|
150
|
+
if ((level === "PRIVATE" || level === "BASIC") && this.accessContext.ownerId) {
|
|
116
151
|
mergedFilter = {
|
|
117
152
|
...filter,
|
|
118
153
|
userId: this.accessContext.ownerId
|
|
@@ -0,0 +1,82 @@
|
|
|
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 __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var simple_embeddings_exports = {};
|
|
38
|
+
__export(simple_embeddings_exports, {
|
|
39
|
+
SimpleHTTPEmbeddings: () => SimpleHTTPEmbeddings
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(simple_embeddings_exports);
|
|
42
|
+
var import_axios = __toESM(require("axios"));
|
|
43
|
+
class SimpleHTTPEmbeddings {
|
|
44
|
+
baseURL;
|
|
45
|
+
apiKey;
|
|
46
|
+
modelName;
|
|
47
|
+
constructor(opts) {
|
|
48
|
+
this.baseURL = opts.baseURL.replace(/\/$/, "");
|
|
49
|
+
this.apiKey = opts.apiKey;
|
|
50
|
+
this.modelName = opts.model;
|
|
51
|
+
}
|
|
52
|
+
async embedDocuments(texts) {
|
|
53
|
+
const results = [];
|
|
54
|
+
for (const text of texts) {
|
|
55
|
+
const result = await this.embedQuery(text);
|
|
56
|
+
results.push(result);
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
async embedQuery(text) {
|
|
61
|
+
var _a, _b, _c, _d;
|
|
62
|
+
const res = await import_axios.default.post(
|
|
63
|
+
`${this.baseURL}/embeddings`,
|
|
64
|
+
{ model: this.modelName, input: text },
|
|
65
|
+
{
|
|
66
|
+
headers: {
|
|
67
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
68
|
+
"Content-Type": "application/json"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
const embedding = (_c = (_b = (_a = res.data) == null ? void 0 : _a.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding;
|
|
73
|
+
if (!embedding) {
|
|
74
|
+
throw new Error(`Embedding API returned no data: ${JSON.stringify(((_d = res.data) == null ? void 0 : _d.error) || res.data).substring(0, 200)}`);
|
|
75
|
+
}
|
|
76
|
+
return embedding;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
80
|
+
0 && (module.exports = {
|
|
81
|
+
SimpleHTTPEmbeddings
|
|
82
|
+
});
|
|
@@ -35,6 +35,7 @@ class VectorizationPipeline {
|
|
|
35
35
|
this.plugin = plugin;
|
|
36
36
|
}
|
|
37
37
|
async processDocument(documentId, options) {
|
|
38
|
+
var _a;
|
|
38
39
|
const docRepo = this.plugin.db.getRepository("aiKnowledgeBaseDocuments");
|
|
39
40
|
await docRepo.update({
|
|
40
41
|
filter: { id: documentId },
|
|
@@ -63,11 +64,28 @@ class VectorizationPipeline {
|
|
|
63
64
|
rawText = textContent;
|
|
64
65
|
} else {
|
|
65
66
|
const aiPlugin = this.plugin.aiPlugin;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
if ((_a = aiPlugin.documentLoaders) == null ? void 0 : _a.cached) {
|
|
68
|
+
const parseResult = await aiPlugin.documentLoaders.cached.load(file);
|
|
69
|
+
if (!parseResult.supported) {
|
|
70
|
+
throw new Error(`File type not supported: ${file.filename}`);
|
|
71
|
+
}
|
|
72
|
+
rawText = parseResult.text || "";
|
|
73
|
+
} else {
|
|
74
|
+
const fs = require("fs");
|
|
75
|
+
const path = require("path");
|
|
76
|
+
let filePath = file.path || file.url;
|
|
77
|
+
if (!filePath) {
|
|
78
|
+
throw new Error(`Cannot resolve file path for: ${file.filename}`);
|
|
79
|
+
}
|
|
80
|
+
if (filePath.startsWith("/storage/") || filePath.startsWith("storage/")) {
|
|
81
|
+
const storageBase = path.resolve(process.cwd(), "storage");
|
|
82
|
+
filePath = path.resolve(storageBase, filePath.replace(/^\/?(storage\/)?/, ""));
|
|
83
|
+
}
|
|
84
|
+
if (!fs.existsSync(filePath)) {
|
|
85
|
+
throw new Error(`File not found at: ${filePath}`);
|
|
86
|
+
}
|
|
87
|
+
rawText = fs.readFileSync(filePath, "utf-8");
|
|
69
88
|
}
|
|
70
|
-
rawText = parseResult.text || "";
|
|
71
89
|
}
|
|
72
90
|
if (!rawText || rawText.trim().length === 0) {
|
|
73
91
|
await docRepo.update({
|
|
@@ -102,18 +120,13 @@ class VectorizationPipeline {
|
|
|
102
120
|
throw new Error(`LLM service "${vectorStore.llmService}" not found`);
|
|
103
121
|
}
|
|
104
122
|
const llmService = llmServiceRecord.toJSON();
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const embeddingProvider = new providerMeta.embedding({
|
|
112
|
-
app: this.plugin.app,
|
|
113
|
-
serviceOptions: llmService.options,
|
|
114
|
-
modelOptions: { model: vectorStore.embeddingModel }
|
|
123
|
+
const { SimpleHTTPEmbeddings } = require("./simple-embeddings");
|
|
124
|
+
const serviceOpts = this.plugin.app.environment.renderJsonTemplate(llmService.options || {});
|
|
125
|
+
const embeddings = new SimpleHTTPEmbeddings({
|
|
126
|
+
baseURL: serviceOpts.baseURL || serviceOpts.baseUrl || "",
|
|
127
|
+
apiKey: serviceOpts.apiKey || "",
|
|
128
|
+
model: vectorStore.embeddingModel
|
|
115
129
|
});
|
|
116
|
-
const embeddings = embeddingProvider.createEmbedding();
|
|
117
130
|
const vdbProvider = this.plugin.aiPlugin.features.vectorDatabaseProvider;
|
|
118
131
|
const vectorStoreInstance = await vdbProvider.createVectorStore(
|
|
119
132
|
vectorDatabase.provider,
|
package/dist/server/plugin.js
CHANGED
|
@@ -52,6 +52,8 @@ var import_ai_knowledge_base = __toESM(require("./resources/ai-knowledge-base"))
|
|
|
52
52
|
var import_ai_knowledge_base_documents = __toESM(require("./resources/ai-knowledge-base-documents"));
|
|
53
53
|
var import_ai_vector_stores = __toESM(require("./resources/ai-vector-stores"));
|
|
54
54
|
var import_ai_vector_databases = __toESM(require("./resources/ai-vector-databases"));
|
|
55
|
+
var import_add_document = require("./actions/add-document");
|
|
56
|
+
var import_request_context = __toESM(require("./request-context"));
|
|
55
57
|
class PluginKnowledgeBaseServer extends import_server.Plugin {
|
|
56
58
|
vectorizationPipeline;
|
|
57
59
|
_aiPlugin;
|
|
@@ -79,6 +81,18 @@ class PluginKnowledgeBaseServer extends import_server.Plugin {
|
|
|
79
81
|
});
|
|
80
82
|
this.vectorizationPipeline = new import_vectorization.VectorizationPipeline(this);
|
|
81
83
|
this.defineResources();
|
|
84
|
+
this.app.resourceManager.use(async (ctx, next) => {
|
|
85
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
86
|
+
const userId = ((_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id) ?? ((_d = (_c = ctx.state) == null ? void 0 : _c.currentUser) == null ? void 0 : _d.id);
|
|
87
|
+
if (userId) {
|
|
88
|
+
const userRoles = ((_g = (_f = (_e = ctx.state) == null ? void 0 : _e.currentUser) == null ? void 0 : _f.roles) == null ? void 0 : _g.map((r) => r.name || r)) ?? [];
|
|
89
|
+
if (userRoles.length === 0 && ((_h = ctx.state) == null ? void 0 : _h.currentRole)) {
|
|
90
|
+
userRoles.push(ctx.state.currentRole);
|
|
91
|
+
}
|
|
92
|
+
return import_request_context.default.run({ userId, userRoles }, () => next());
|
|
93
|
+
}
|
|
94
|
+
await next();
|
|
95
|
+
});
|
|
82
96
|
this.setPermissions();
|
|
83
97
|
this.app.resourceManager.use(
|
|
84
98
|
async (ctx, next) => {
|
|
@@ -101,6 +115,7 @@ class PluginKnowledgeBaseServer extends import_server.Plugin {
|
|
|
101
115
|
this.app.resourceManager.define(import_ai_knowledge_base_documents.default);
|
|
102
116
|
this.app.resourceManager.define(import_ai_vector_stores.default);
|
|
103
117
|
this.app.resourceManager.define(import_ai_vector_databases.default);
|
|
118
|
+
this.app.resourceManager.registerActionHandler("aiKnowledgeBase:addDocument", import_add_document.addDocumentAction);
|
|
104
119
|
}
|
|
105
120
|
setPermissions() {
|
|
106
121
|
this.app.acl.registerSnippet({
|
|
@@ -114,6 +129,7 @@ class PluginKnowledgeBaseServer extends import_server.Plugin {
|
|
|
114
129
|
});
|
|
115
130
|
this.app.acl.allow("aiKnowledgeBase", "list", "loggedIn");
|
|
116
131
|
this.app.acl.allow("aiKnowledgeBase", "get", "loggedIn");
|
|
132
|
+
this.app.acl.allow("aiKnowledgeBase", "addDocument", "loggedIn");
|
|
117
133
|
}
|
|
118
134
|
async install() {
|
|
119
135
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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 request_context_exports = {};
|
|
28
|
+
__export(request_context_exports, {
|
|
29
|
+
default: () => request_context_default,
|
|
30
|
+
getCurrentUserId: () => getCurrentUserId,
|
|
31
|
+
getCurrentUserRoles: () => getCurrentUserRoles,
|
|
32
|
+
runWithUserId: () => runWithUserId
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(request_context_exports);
|
|
35
|
+
var import_async_hooks = require("async_hooks");
|
|
36
|
+
const requestContext = new import_async_hooks.AsyncLocalStorage();
|
|
37
|
+
function getCurrentUserId() {
|
|
38
|
+
var _a;
|
|
39
|
+
return (_a = requestContext.getStore()) == null ? void 0 : _a.userId;
|
|
40
|
+
}
|
|
41
|
+
function getCurrentUserRoles() {
|
|
42
|
+
var _a;
|
|
43
|
+
return ((_a = requestContext.getStore()) == null ? void 0 : _a.userRoles) ?? [];
|
|
44
|
+
}
|
|
45
|
+
function runWithUserId(userId, fn) {
|
|
46
|
+
return requestContext.run({ userId }, fn);
|
|
47
|
+
}
|
|
48
|
+
var request_context_default = requestContext;
|
|
49
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
50
|
+
0 && (module.exports = {
|
|
51
|
+
getCurrentUserId,
|
|
52
|
+
getCurrentUserRoles,
|
|
53
|
+
runWithUserId
|
|
54
|
+
});
|
|
@@ -53,7 +53,7 @@ var ai_knowledge_base_documents_default = {
|
|
|
53
53
|
const repo = ctx.db.getRepository("aiKnowledgeBaseDocuments");
|
|
54
54
|
const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
|
|
55
55
|
const roles = ctx.state.currentRoles ?? [];
|
|
56
|
-
const
|
|
56
|
+
const isAdmin = roles.includes("root") || roles.includes("admin");
|
|
57
57
|
if (values.knowledgeBaseId) {
|
|
58
58
|
const kbRepo = ctx.db.getRepository("aiKnowledgeBases");
|
|
59
59
|
const kb = await kbRepo.findOne({ filter: { id: values.knowledgeBaseId } });
|
|
@@ -63,12 +63,12 @@ var ai_knowledge_base_documents_default = {
|
|
|
63
63
|
ctx.throw(403, "Only the owner can upload documents to a personal knowledge base");
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
|
-
if (kbData.accessLevel === "PUBLIC" && !
|
|
66
|
+
if (kbData.accessLevel === "PUBLIC" && !isAdmin) {
|
|
67
67
|
ctx.throw(403, "Only administrators can upload documents to a public knowledge base");
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
70
|
if (kbData.accessLevel === "SHARED") {
|
|
71
|
-
const canUpload =
|
|
71
|
+
const canUpload = isAdmin || ((_c = kbData.uploadRoles) == null ? void 0 : _c.some((r) => roles.includes(r)));
|
|
72
72
|
if (!canUpload) {
|
|
73
73
|
ctx.throw(403, "You do not have permission to upload documents to this knowledge base");
|
|
74
74
|
return;
|
|
@@ -39,8 +39,8 @@ async function checkKBPermission(ctx, filterByTk, action) {
|
|
|
39
39
|
const data = record.toJSON();
|
|
40
40
|
const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
|
|
41
41
|
const roles = ctx.state.currentRoles ?? [];
|
|
42
|
-
const
|
|
43
|
-
if (
|
|
42
|
+
const isAdmin = roles.includes("root") || roles.includes("admin");
|
|
43
|
+
if (isAdmin) {
|
|
44
44
|
return true;
|
|
45
45
|
}
|
|
46
46
|
if (data.accessLevel === "BASIC") {
|
|
@@ -63,8 +63,8 @@ var ai_knowledge_base_default = {
|
|
|
63
63
|
const { filter = {}, fields, sort, page, pageSize } = ctx.action.params;
|
|
64
64
|
const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
|
|
65
65
|
const roles = ctx.state.currentRoles ?? [];
|
|
66
|
-
const
|
|
67
|
-
if (!
|
|
66
|
+
const isAdmin = roles.includes("root") || roles.includes("admin");
|
|
67
|
+
if (!isAdmin) {
|
|
68
68
|
filter.$or = [
|
|
69
69
|
{ accessLevel: "PUBLIC" },
|
|
70
70
|
...userId ? [{ accessLevel: "BASIC", ownerId: userId }] : [],
|
|
@@ -93,8 +93,8 @@ var ai_knowledge_base_default = {
|
|
|
93
93
|
const data = record.toJSON();
|
|
94
94
|
const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
|
|
95
95
|
const roles = ctx.state.currentRoles ?? [];
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
96
|
+
const isAdmin = roles.includes("root") || roles.includes("admin");
|
|
97
|
+
if (!isAdmin) {
|
|
98
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
99
|
if (!hasAccess) {
|
|
100
100
|
ctx.throw(403, "Access denied");
|
|
@@ -112,8 +112,8 @@ var ai_knowledge_base_default = {
|
|
|
112
112
|
const repo = ctx.db.getRepository("aiKnowledgeBases");
|
|
113
113
|
const userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
|
|
114
114
|
const roles = ctx.state.currentRoles ?? [];
|
|
115
|
-
const
|
|
116
|
-
if (values.accessLevel === "PUBLIC" && !
|
|
115
|
+
const isAdmin = roles.includes("root") || roles.includes("admin");
|
|
116
|
+
if (values.accessLevel === "PUBLIC" && !isAdmin) {
|
|
117
117
|
ctx.throw(403, "Only administrators can create public knowledge bases");
|
|
118
118
|
return;
|
|
119
119
|
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Provides Knowledge Base management, Vector Store, Vector Database (PGVector), and RAG retrieval capabilities for AI Employees.",
|
|
7
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
8
|
"description.zh-CN": "为 AI 员工提供知识库管理、向量存储、向量数据库 (PGVector) 和 RAG 检索功能。",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.4",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"main": "./dist/server/index.js",
|
|
12
12
|
"files": [
|