@nocobase/plugin-ai 2.1.0-alpha.20 → 2.1.0-alpha.21
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/ai/tools/knowledge-base-retrieve.d.ts +10 -0
- package/dist/ai/tools/knowledge-base-retrieve.js +94 -0
- package/dist/client/486.77c26e2e7f8daf28.js +10 -0
- package/dist/client/646.ef9d7c2ea8641044.js +10 -0
- package/dist/client/ai-employees/chatbox/AIEmployeeSwitch.d.ts +3 -1
- package/dist/client/ai-employees/chatbox/HintMessageHeader.d.ts +10 -0
- package/dist/client/ai-employees/chatbox/ModelSwitcher.d.ts +3 -1
- package/dist/client/ai-employees/chatbox/SearchSwitch.d.ts +3 -1
- package/dist/client/ai-employees/chatbox/Upload.d.ts +3 -1
- package/dist/client/ai-employees/chatbox/conversations/ConversationsList.d.ts +27 -0
- package/dist/client/ai-employees/chatbox/conversations/WorkflowTasksList.d.ts +31 -0
- package/dist/client/ai-employees/chatbox/conversations/common.d.ts +43 -0
- package/dist/{server/document-loader/loader.worker.d.ts → client/ai-employees/chatbox/conversations/index.d.ts} +1 -1
- package/dist/client/ai-employees/chatbox/hooks/useWorkflowTasks.d.ts +24 -0
- package/dist/client/ai-employees/chatbox/stores/chat-box.d.ts +8 -0
- package/dist/client/ai-employees/chatbox/stores/chat-conversations.d.ts +4 -0
- package/dist/client/ai-employees/chatbox/stores/workflow-tasks.d.ts +41 -0
- package/dist/client/ai-employees/workflow-tasks/tools/index.d.ts +10 -0
- package/dist/client/ai-employees/workflow-tasks/ui/WorkflowTaskOutputCard.d.ts +11 -0
- package/dist/client/components/ListCollapse.d.ts +28 -0
- package/dist/client/index.js +7 -7
- package/dist/client/repositories/AIConfigRepository.d.ts +3 -2
- package/dist/client/workflow/nodes/employee/components/AIEmployeeSelect.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/components/assigness.d.ts +11 -0
- package/dist/client/workflow/nodes/employee/components/file-inputs.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/components/message-inputs.d.ts +12 -0
- package/dist/client/workflow/nodes/employee/components/model-options.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/components/skill-settings.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/components/structured-output.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/components/users-select.d.ts +15 -0
- package/dist/client/workflow/nodes/employee/components/web-search-options.d.ts +10 -0
- package/dist/client/workflow/nodes/employee/configuration.d.ts +12 -0
- package/dist/client/workflow/nodes/employee/flow-models/feedback.d.ts +13 -0
- package/dist/client/workflow/nodes/employee/flow-models/task.d.ts +13 -0
- package/dist/client/workflow/nodes/employee/index.d.ts +7 -31
- package/dist/externalVersion.js +14 -15
- package/dist/locale/en-US.json +44 -1
- package/dist/locale/zh-CN.json +45 -1
- package/dist/node_modules/fast-glob/out/index.js +8 -8
- package/dist/node_modules/fast-glob/package.json +1 -1
- package/dist/node_modules/flexsearch/dist/flexsearch.bundle.min.js +2 -2
- package/dist/node_modules/flexsearch/package.json +1 -1
- package/dist/node_modules/fs-extra/lib/index.js +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/nodejs_snowflake.js +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/index.js +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/index.cjs +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-conversations.d.ts +10 -4
- package/dist/server/ai-employees/ai-conversations.js +52 -14
- package/dist/server/ai-employees/ai-employee.d.ts +8 -10
- package/dist/server/ai-employees/ai-employee.js +130 -145
- package/dist/server/ai-employees/ai-knowledge-base.d.ts +28 -0
- package/dist/server/ai-employees/ai-knowledge-base.js +167 -0
- package/dist/server/ai-employees/middleware/index.d.ts +1 -0
- package/dist/server/ai-employees/middleware/index.js +3 -1
- package/dist/server/ai-employees/middleware/workflow-history.d.ts +22 -0
- package/dist/server/ai-employees/middleware/workflow-history.js +173 -0
- package/dist/server/collections/ai-conversations.js +12 -0
- package/dist/server/collections/ai-workflow-tasks.d.ts +10 -0
- package/dist/server/collections/ai-workflow-tasks.js +112 -0
- package/dist/server/collections/users-ai-workflow-tasks.d.ts +10 -0
- package/dist/server/collections/users-ai-workflow-tasks.js +44 -0
- package/dist/server/document-loader/constants.d.ts +1 -2
- package/dist/server/document-loader/constants.js +6 -1
- package/dist/server/document-loader/loader.d.ts +0 -1
- package/dist/server/document-loader/loader.js +2 -55
- package/dist/server/document-loader/types.d.ts +0 -1
- package/dist/server/llm-providers/provider.js +1 -1
- package/dist/server/manager/built-in-manager.js +5 -4
- package/dist/server/plugin.d.ts +2 -0
- package/dist/server/plugin.js +10 -0
- package/dist/server/resource/aiConversations.js +29 -35
- package/dist/server/resource/aiWorkflowTasks.d.ts +12 -0
- package/dist/server/resource/aiWorkflowTasks.js +290 -0
- package/dist/server/utils.js +3 -2
- package/dist/server/workflow/nodes/employee/files.d.ts +16 -0
- package/dist/server/workflow/nodes/employee/files.js +125 -0
- package/dist/server/workflow/nodes/employee/handler.d.ts +11 -0
- package/dist/server/workflow/nodes/employee/handler.js +107 -0
- package/dist/server/workflow/nodes/employee/index.d.ts +17 -0
- package/dist/server/workflow/nodes/employee/index.js +391 -0
- package/dist/server/workflow/nodes/employee/tools.d.ts +12 -0
- package/dist/server/workflow/nodes/employee/tools.js +133 -0
- package/dist/server/workflow/nodes/employee/types.d.ts +35 -0
- package/dist/server/workflow/nodes/employee/types.js +24 -0
- package/dist/server/workflow/utils.d.ts +14 -0
- package/dist/server/workflow/utils.js +111 -0
- package/package.json +2 -2
- package/dist/client/30.4f30511a3059c422.js +0 -10
- package/dist/server/document-loader/loader.worker.js +0 -68
- package/dist/server/document-loader/vendor/langchain/document_loaders/fs/text.d.ts +0 -20
- package/dist/server/document-loader/vendor/langchain/document_loaders/fs/text.js +0 -96
- /package/dist/client/ai-employees/chatbox/{Conversations.d.ts → conversations/Conversations.d.ts} +0 -0
|
@@ -45,8 +45,6 @@ var import_utils = require("../utils");
|
|
|
45
45
|
var import_prompts = require("./prompts");
|
|
46
46
|
var import_lodash = __toESM(require("lodash"));
|
|
47
47
|
var import_ai_chat_conversation = require("../manager/ai-chat-conversation");
|
|
48
|
-
var import_ai_feature_manager = require("../manager/ai-feature-manager");
|
|
49
|
-
var import_prompts2 = require("@langchain/core/prompts");
|
|
50
48
|
var import_middleware = require("./middleware");
|
|
51
49
|
var import_checkpoints = require("./checkpoints");
|
|
52
50
|
var import_langchain = require("langchain");
|
|
@@ -69,6 +67,8 @@ class AIEmployee {
|
|
|
69
67
|
webSearch;
|
|
70
68
|
model;
|
|
71
69
|
legacy;
|
|
70
|
+
tools;
|
|
71
|
+
inWorkflow;
|
|
72
72
|
constructor({
|
|
73
73
|
ctx,
|
|
74
74
|
employee,
|
|
@@ -78,7 +78,8 @@ class AIEmployee {
|
|
|
78
78
|
webSearch,
|
|
79
79
|
model,
|
|
80
80
|
legacy,
|
|
81
|
-
from = "main-agent"
|
|
81
|
+
from = "main-agent",
|
|
82
|
+
tools = []
|
|
82
83
|
}) {
|
|
83
84
|
this.employee = employee;
|
|
84
85
|
this.ctx = ctx;
|
|
@@ -91,6 +92,7 @@ class AIEmployee {
|
|
|
91
92
|
this.model = model;
|
|
92
93
|
this.legacy = legacy;
|
|
93
94
|
this.from = from;
|
|
95
|
+
this.tools = tools;
|
|
94
96
|
const builtInManager = this.plugin.builtInManager;
|
|
95
97
|
builtInManager.setupBuiltInInfo(ctx, this.employee);
|
|
96
98
|
this.webSearch = webSearch;
|
|
@@ -106,6 +108,14 @@ class AIEmployee {
|
|
|
106
108
|
});
|
|
107
109
|
return messages;
|
|
108
110
|
}
|
|
111
|
+
async isInWorkflow() {
|
|
112
|
+
if (this.inWorkflow !== void 0) {
|
|
113
|
+
return this.inWorkflow;
|
|
114
|
+
}
|
|
115
|
+
const conversation = await this.aiConversationsRepo.findByTargetKey(this.sessionId);
|
|
116
|
+
this.inWorkflow = (conversation == null ? void 0 : conversation.category) === "task";
|
|
117
|
+
return this.inWorkflow;
|
|
118
|
+
}
|
|
109
119
|
// === Chat flow ===
|
|
110
120
|
buildState(messages) {
|
|
111
121
|
return {
|
|
@@ -125,7 +135,7 @@ class AIEmployee {
|
|
|
125
135
|
historyMessages: [],
|
|
126
136
|
tools,
|
|
127
137
|
resolvedTools,
|
|
128
|
-
middleware: this.getMiddleware({ tools, baseToolNames, model, providerName }),
|
|
138
|
+
middleware: await this.getMiddleware({ tools, baseToolNames, model, providerName }),
|
|
129
139
|
config: void 0,
|
|
130
140
|
state: void 0
|
|
131
141
|
};
|
|
@@ -138,7 +148,7 @@ class AIEmployee {
|
|
|
138
148
|
historyMessages,
|
|
139
149
|
tools,
|
|
140
150
|
resolvedTools,
|
|
141
|
-
middleware: this.getMiddleware({
|
|
151
|
+
middleware: await this.getMiddleware({
|
|
142
152
|
tools,
|
|
143
153
|
baseToolNames,
|
|
144
154
|
model,
|
|
@@ -183,6 +193,12 @@ class AIEmployee {
|
|
|
183
193
|
userMessages = [],
|
|
184
194
|
userDecisions
|
|
185
195
|
}) {
|
|
196
|
+
await this.aiConversationsRepo.update({
|
|
197
|
+
values: { llmActiveState: "streaming" },
|
|
198
|
+
filter: {
|
|
199
|
+
sessionId: this.sessionId
|
|
200
|
+
}
|
|
201
|
+
});
|
|
186
202
|
try {
|
|
187
203
|
const { providerName, model, provider, chatContext, config, state } = await this.buildChatContext({
|
|
188
204
|
messageId,
|
|
@@ -209,6 +225,13 @@ class AIEmployee {
|
|
|
209
225
|
this.ctx.log.error(err);
|
|
210
226
|
this.sendErrorResponse(err.message || "Chat error warning");
|
|
211
227
|
return false;
|
|
228
|
+
} finally {
|
|
229
|
+
await this.aiConversationsRepo.update({
|
|
230
|
+
values: { llmActiveState: "idle" },
|
|
231
|
+
filter: {
|
|
232
|
+
sessionId: this.sessionId
|
|
233
|
+
}
|
|
234
|
+
});
|
|
212
235
|
}
|
|
213
236
|
}
|
|
214
237
|
async invoke({
|
|
@@ -218,29 +241,43 @@ class AIEmployee {
|
|
|
218
241
|
writer,
|
|
219
242
|
context
|
|
220
243
|
}) {
|
|
244
|
+
var _a;
|
|
245
|
+
await this.aiConversationsRepo.update({
|
|
246
|
+
values: { llmActiveState: "invoking" },
|
|
247
|
+
filter: {
|
|
248
|
+
sessionId: this.sessionId
|
|
249
|
+
}
|
|
250
|
+
});
|
|
221
251
|
try {
|
|
222
252
|
const { provider, chatContext, config, state } = await this.buildChatContext({
|
|
223
253
|
messageId,
|
|
224
254
|
userMessages,
|
|
225
255
|
userDecisions
|
|
226
256
|
});
|
|
257
|
+
const { threadId } = await this.getCurrentThread();
|
|
227
258
|
const invokeConfig = {
|
|
228
259
|
context: { ctx: this.ctx, decisions: chatContext.decisions, ...context },
|
|
229
260
|
recursionLimit: 100,
|
|
261
|
+
configurable: this.from === "main-agent" ? { thread_id: threadId } : void 0,
|
|
230
262
|
writer,
|
|
231
263
|
...config
|
|
232
264
|
};
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
return await this.agentInvoke(provider, chatContext, invokeConfig, state);
|
|
265
|
+
const invokeResult = await this.agentInvoke(provider, chatContext, invokeConfig, state);
|
|
266
|
+
await this.handleInterruptedToolCalls((_a = invokeResult == null ? void 0 : invokeResult.__interrupt__) == null ? void 0 : _a[0], () => invokeResult == null ? void 0 : invokeResult.messageId);
|
|
267
|
+
return invokeResult;
|
|
238
268
|
} catch (err) {
|
|
239
269
|
if (err.name === "GraphInterrupt") {
|
|
240
270
|
throw err;
|
|
241
271
|
}
|
|
242
272
|
this.ctx.log.error(err);
|
|
243
273
|
throw err;
|
|
274
|
+
} finally {
|
|
275
|
+
await this.aiConversationsRepo.update({
|
|
276
|
+
values: { llmActiveState: "idle" },
|
|
277
|
+
filter: {
|
|
278
|
+
sessionId: this.sessionId
|
|
279
|
+
}
|
|
280
|
+
});
|
|
244
281
|
}
|
|
245
282
|
}
|
|
246
283
|
// === Agent wiring & execution ===
|
|
@@ -322,7 +359,7 @@ class AIEmployee {
|
|
|
322
359
|
}
|
|
323
360
|
}
|
|
324
361
|
async processChatStream(stream, options) {
|
|
325
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
362
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
326
363
|
const aiMessageIdMap = /* @__PURE__ */ new Map();
|
|
327
364
|
const { signal, providerName, model, provider, responseMetadata, allowEmpty = false } = options;
|
|
328
365
|
let isReasoning = false;
|
|
@@ -384,35 +421,25 @@ class AIEmployee {
|
|
|
384
421
|
}
|
|
385
422
|
}
|
|
386
423
|
} else if (mode === "updates") {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
const { sessionId, from, username } = interruptAction.currentConversation;
|
|
398
|
-
const { id: toolCallId, name: toolCallName } = interruptAction.toolCall;
|
|
399
|
-
const messageId = aiMessageIdMap.get(sessionId);
|
|
400
|
-
if (!messageId) {
|
|
401
|
-
continue;
|
|
402
|
-
}
|
|
403
|
-
await this.updateToolCallInterrupted(sessionId, messageId, toolCallId, interruptId, interruptAction);
|
|
404
|
-
this.protocol.with(interruptAction.currentConversation).toolCallStatus({
|
|
424
|
+
const interrupt = (_b = chunks == null ? void 0 : chunks.__interrupt__) == null ? void 0 : _b[0];
|
|
425
|
+
if (interrupt) {
|
|
426
|
+
const toolsMap = await this.getToolsMap();
|
|
427
|
+
await this.handleInterruptedToolCalls(
|
|
428
|
+
interrupt,
|
|
429
|
+
(sessionId) => aiMessageIdMap.get(sessionId),
|
|
430
|
+
({ messageId, interruptAction, toolCall, currentConversation }) => {
|
|
431
|
+
this.protocol.with(currentConversation).toolCallStatus({
|
|
405
432
|
toolCall: {
|
|
406
433
|
messageId,
|
|
407
|
-
id:
|
|
408
|
-
name:
|
|
409
|
-
willInterrupt: this.shouldInterruptToolCall(toolsMap.get(
|
|
434
|
+
id: toolCall.id,
|
|
435
|
+
name: toolCall.name,
|
|
436
|
+
willInterrupt: this.shouldInterruptToolCall(toolsMap.get(toolCall.name))
|
|
410
437
|
},
|
|
411
438
|
invokeStatus: "interrupted",
|
|
412
439
|
interruptAction
|
|
413
440
|
});
|
|
414
441
|
}
|
|
415
|
-
|
|
442
|
+
);
|
|
416
443
|
}
|
|
417
444
|
} else if (mode === "custom") {
|
|
418
445
|
const { currentConversation } = chunks;
|
|
@@ -448,31 +475,31 @@ class AIEmployee {
|
|
|
448
475
|
this.protocol.with(currentConversation).toolCalls(chunks.body);
|
|
449
476
|
} else if (chunks.action === "beforeToolCall") {
|
|
450
477
|
const toolsMap = await this.getToolsMap();
|
|
451
|
-
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((
|
|
478
|
+
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_d = (_c = chunks.body) == null ? void 0 : _c.toolCall) == null ? void 0 : _d.name));
|
|
452
479
|
this.protocol.with(currentConversation).toolCallStatus({
|
|
453
480
|
toolCall: {
|
|
454
|
-
messageId: (
|
|
455
|
-
id: (
|
|
456
|
-
name: (
|
|
481
|
+
messageId: (_f = (_e = chunks.body) == null ? void 0 : _e.toolCall) == null ? void 0 : _f.messageId,
|
|
482
|
+
id: (_h = (_g = chunks.body) == null ? void 0 : _g.toolCall) == null ? void 0 : _h.id,
|
|
483
|
+
name: (_j = (_i = chunks.body) == null ? void 0 : _i.toolCall) == null ? void 0 : _j.name,
|
|
457
484
|
willInterrupt
|
|
458
485
|
},
|
|
459
486
|
invokeStatus: "pending"
|
|
460
487
|
});
|
|
461
488
|
} else if (chunks.action === "afterToolCall") {
|
|
462
489
|
const toolsMap = await this.getToolsMap();
|
|
463
|
-
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((
|
|
490
|
+
const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_l = (_k = chunks.body) == null ? void 0 : _k.toolCall) == null ? void 0 : _l.name));
|
|
464
491
|
this.protocol.with(currentConversation).toolCallStatus({
|
|
465
492
|
toolCall: {
|
|
466
|
-
messageId: (
|
|
467
|
-
id: (
|
|
468
|
-
name: (
|
|
493
|
+
messageId: (_n = (_m = chunks.body) == null ? void 0 : _m.toolCall) == null ? void 0 : _n.messageId,
|
|
494
|
+
id: (_p = (_o = chunks.body) == null ? void 0 : _o.toolCall) == null ? void 0 : _p.id,
|
|
495
|
+
name: (_r = (_q = chunks.body) == null ? void 0 : _q.toolCall) == null ? void 0 : _r.name,
|
|
469
496
|
willInterrupt
|
|
470
497
|
},
|
|
471
498
|
invokeStatus: "done",
|
|
472
|
-
status: (
|
|
473
|
-
invokeStartTime: (
|
|
474
|
-
invokeEndTime: (
|
|
475
|
-
content: (
|
|
499
|
+
status: (_t = (_s = chunks.body) == null ? void 0 : _s.toolCallResult) == null ? void 0 : _t.status,
|
|
500
|
+
invokeStartTime: (_v = (_u = chunks.body) == null ? void 0 : _u.toolCallResult) == null ? void 0 : _v.invokeStartTime,
|
|
501
|
+
invokeEndTime: (_x = (_w = chunks.body) == null ? void 0 : _w.toolCallResult) == null ? void 0 : _x.invokeEndTime,
|
|
502
|
+
content: (_z = (_y = chunks.body) == null ? void 0 : _y.toolCallResult) == null ? void 0 : _z.content
|
|
476
503
|
});
|
|
477
504
|
} else if (chunks.action === "beforeSendToolMessage") {
|
|
478
505
|
const { messageId, messages } = chunks.body ?? {};
|
|
@@ -524,6 +551,39 @@ class AIEmployee {
|
|
|
524
551
|
}
|
|
525
552
|
}
|
|
526
553
|
}
|
|
554
|
+
async handleInterruptedToolCalls(interrupt, getMessageId, onInterrupted) {
|
|
555
|
+
const interruptId = interrupt == null ? void 0 : interrupt.id;
|
|
556
|
+
const interruptActions = this.toInterruptActions(interrupt == null ? void 0 : interrupt.value);
|
|
557
|
+
if (!interruptId || !interruptActions.size) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
for (const interruptAction of interruptActions.values()) {
|
|
561
|
+
const currentConversation = interruptAction.currentConversation;
|
|
562
|
+
const toolCall = interruptAction.toolCall;
|
|
563
|
+
if (!currentConversation || !toolCall) {
|
|
564
|
+
this.logger.warn("currentConversation or toolCall not exist in __interrupt__", interruptAction);
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
const messageId = getMessageId(currentConversation.sessionId);
|
|
568
|
+
if (!messageId) {
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
await this.updateToolCallInterrupted(
|
|
572
|
+
currentConversation.sessionId,
|
|
573
|
+
messageId,
|
|
574
|
+
toolCall.id,
|
|
575
|
+
interruptId,
|
|
576
|
+
interruptAction
|
|
577
|
+
);
|
|
578
|
+
await (onInterrupted == null ? void 0 : onInterrupted({
|
|
579
|
+
messageId,
|
|
580
|
+
interruptId,
|
|
581
|
+
interruptAction,
|
|
582
|
+
toolCall,
|
|
583
|
+
currentConversation
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
586
|
+
}
|
|
527
587
|
// === Prompts & knowledge base ===
|
|
528
588
|
// Notice: employee.dataSourceSettings is not used in the current version.
|
|
529
589
|
getEmployeeDataSourceContext() {
|
|
@@ -567,10 +627,10 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
|
|
|
567
627
|
return message;
|
|
568
628
|
}
|
|
569
629
|
async getSystemPrompt(userMessages) {
|
|
570
|
-
var _a;
|
|
630
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
571
631
|
const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
|
|
572
632
|
filter: {
|
|
573
|
-
userId: (_a = this.ctx.auth) == null ? void 0 : _a.user.id,
|
|
633
|
+
userId: ((_a = this.ctx.auth) == null ? void 0 : _a.user.id) ?? 0,
|
|
574
634
|
aiEmployee: this.employee.username
|
|
575
635
|
}
|
|
576
636
|
});
|
|
@@ -596,14 +656,14 @@ ${workContextBackground.join("\n")}`;
|
|
|
596
656
|
${addSystemPrompt.map((it) => it.content).join("\n")}`;
|
|
597
657
|
}
|
|
598
658
|
let knowledgeBase;
|
|
599
|
-
|
|
659
|
+
const { knowledgeBaseManager } = this.plugin;
|
|
660
|
+
const employee = this.employee.toJSON();
|
|
661
|
+
if (await knowledgeBaseManager.isEnabledKnowledgeBase(employee) && employee.knowledgeBasePrompt && (userMessages == null ? void 0 : userMessages.length)) {
|
|
600
662
|
const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
|
|
601
663
|
if (lastUserMessage) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
knowledgeBase = import_lodash.default.isEmpty(knowledgeBaseData) ? void 0 : await promptTemplate.format({
|
|
606
|
-
knowledgeBaseData
|
|
664
|
+
knowledgeBase = await knowledgeBaseManager.retrievePrompt({
|
|
665
|
+
employee,
|
|
666
|
+
query: lastUserMessage.content.content
|
|
607
667
|
});
|
|
608
668
|
}
|
|
609
669
|
}
|
|
@@ -621,15 +681,15 @@ ${addSystemPrompt.map((it) => it.content).join("\n")}`;
|
|
|
621
681
|
dataSources: dataSourceMessage,
|
|
622
682
|
environment: {
|
|
623
683
|
database: this.db.sequelize.getDialect(),
|
|
624
|
-
locale: this.ctx.getCurrentLocale() || "en-US",
|
|
625
|
-
currentDateTime: getCurrentDateTimeForPrompt(this.ctx.getCurrentLocale(), getCurrentTimezone(this.ctx)),
|
|
684
|
+
locale: ((_c = (_b = this.ctx).getCurrentLocale) == null ? void 0 : _c.call(_b)) || "en-US",
|
|
685
|
+
currentDateTime: getCurrentDateTimeForPrompt((_e = (_d = this.ctx).getCurrentLocale) == null ? void 0 : _e.call(_d), getCurrentTimezone(this.ctx)),
|
|
626
686
|
timezone: getCurrentTimezone(this.ctx)
|
|
627
687
|
},
|
|
628
688
|
knowledgeBase,
|
|
629
689
|
availableSkills,
|
|
630
690
|
availableAIEmployees
|
|
631
691
|
});
|
|
632
|
-
const { important } = this.ctx.action.params.values || {};
|
|
692
|
+
const { important } = ((_g = (_f = this.ctx.action) == null ? void 0 : _f.params) == null ? void 0 : _g.values) || {};
|
|
633
693
|
if (important === "GraphRecursionError") {
|
|
634
694
|
const importantPrompt = `<Important>You have already called tools multiple times and gathered sufficient information.
|
|
635
695
|
First, provide a summary based on the existing information. Do not call additional tools.
|
|
@@ -639,92 +699,6 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
639
699
|
return systemPrompt;
|
|
640
700
|
}
|
|
641
701
|
}
|
|
642
|
-
async retrieveKnowledgeBase(userMessage) {
|
|
643
|
-
const vectorStoreProvider = this.plugin.features.vectorStoreProvider;
|
|
644
|
-
let queryResult = [];
|
|
645
|
-
const queryString = userMessage.content.content;
|
|
646
|
-
if (!queryString || import_lodash.default.isEmpty(queryString)) {
|
|
647
|
-
return queryResult;
|
|
648
|
-
}
|
|
649
|
-
const { topK, score } = this.getAIEmployeeKnowledgeBaseConfig();
|
|
650
|
-
const knowledgeBaseGroup = await this.getKnowledgeBaseGroup();
|
|
651
|
-
for (const entry of knowledgeBaseGroup) {
|
|
652
|
-
const { vectorStoreConfig, knowledgeBaseType, knowledgeBaseList } = entry;
|
|
653
|
-
if (!knowledgeBaseList || import_lodash.default.isEmpty(knowledgeBaseList)) {
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
if (knowledgeBaseType === "LOCAL") {
|
|
657
|
-
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
658
|
-
vectorStoreConfig.vectorStoreProvider,
|
|
659
|
-
[
|
|
660
|
-
{
|
|
661
|
-
key: "vectorStoreConfigId",
|
|
662
|
-
value: vectorStoreConfig.vectorStoreConfigId
|
|
663
|
-
}
|
|
664
|
-
]
|
|
665
|
-
);
|
|
666
|
-
const knowledgeBaseOuterIds = knowledgeBaseList.map((x) => x.knowledgeBaseOuterId);
|
|
667
|
-
const result = await vectorStoreService.search(queryString, {
|
|
668
|
-
topK,
|
|
669
|
-
score,
|
|
670
|
-
filter: {
|
|
671
|
-
knowledgeBaseOuterId: { in: knowledgeBaseOuterIds }
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
queryResult = [...queryResult, ...result];
|
|
675
|
-
} else if (knowledgeBaseType === "READONLY") {
|
|
676
|
-
for (const knowledgeBase of knowledgeBaseList) {
|
|
677
|
-
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
678
|
-
vectorStoreConfig.vectorStoreProvider,
|
|
679
|
-
[
|
|
680
|
-
...knowledgeBase.vectorStoreProps,
|
|
681
|
-
{
|
|
682
|
-
key: "vectorStoreConfigId",
|
|
683
|
-
value: vectorStoreConfig.vectorStoreConfigId
|
|
684
|
-
}
|
|
685
|
-
]
|
|
686
|
-
);
|
|
687
|
-
const result = await vectorStoreService.search(queryString, {
|
|
688
|
-
topK,
|
|
689
|
-
score
|
|
690
|
-
});
|
|
691
|
-
queryResult = [...queryResult, ...result];
|
|
692
|
-
}
|
|
693
|
-
} else if (knowledgeBaseType === "EXTERNAL") {
|
|
694
|
-
for (const knowledgeBase of knowledgeBaseList) {
|
|
695
|
-
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
696
|
-
vectorStoreConfig.vectorStoreProvider,
|
|
697
|
-
knowledgeBase.vectorStoreProps
|
|
698
|
-
);
|
|
699
|
-
const result = await vectorStoreService.search(queryString, {
|
|
700
|
-
topK,
|
|
701
|
-
score
|
|
702
|
-
});
|
|
703
|
-
queryResult = [...queryResult, ...result];
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
return queryResult;
|
|
708
|
-
}
|
|
709
|
-
isEnabledKnowledgeBase() {
|
|
710
|
-
const featureEnabled = this.plugin.features.isFeaturesEnabled(Object.values(import_ai_feature_manager.EEFeatures));
|
|
711
|
-
const knowledgeBaseEnabled = this.employee.enableKnowledgeBase;
|
|
712
|
-
return featureEnabled && knowledgeBaseEnabled;
|
|
713
|
-
}
|
|
714
|
-
getAIEmployeeKnowledgeBaseConfig() {
|
|
715
|
-
const { topK, score } = this.employee.knowledgeBase ?? {};
|
|
716
|
-
return {
|
|
717
|
-
topK,
|
|
718
|
-
score
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
async getKnowledgeBaseGroup() {
|
|
722
|
-
const { knowledgeBaseIds } = this.employee.knowledgeBase ?? {};
|
|
723
|
-
if (!knowledgeBaseIds || import_lodash.default.isEmpty(knowledgeBaseIds)) {
|
|
724
|
-
return [];
|
|
725
|
-
}
|
|
726
|
-
return await this.plugin.features.knowledgeBase.getKnowledgeBaseGroup(knowledgeBaseIds);
|
|
727
|
-
}
|
|
728
702
|
// === Tool calls ===
|
|
729
703
|
async initToolCall(transaction, messageId, toolCalls) {
|
|
730
704
|
const nowTime = /* @__PURE__ */ new Date();
|
|
@@ -1123,7 +1097,7 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1123
1097
|
toInterruptActions(interrupt) {
|
|
1124
1098
|
var _a;
|
|
1125
1099
|
const result = /* @__PURE__ */ new Map();
|
|
1126
|
-
const { actionRequests = [], reviewConfigs = [] } = interrupt;
|
|
1100
|
+
const { actionRequests = [], reviewConfigs = [] } = interrupt ?? {};
|
|
1127
1101
|
if (!actionRequests.length) {
|
|
1128
1102
|
return result;
|
|
1129
1103
|
}
|
|
@@ -1159,6 +1133,13 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1159
1133
|
const generalToolsNameSet = new Set(tools.map((x) => x.definition.name));
|
|
1160
1134
|
const toolMap = await this.getToolsMap();
|
|
1161
1135
|
const employeeTools = ((_a = this.employee.skillSettings) == null ? void 0 : _a.tools) ?? [];
|
|
1136
|
+
employeeTools.push(...this.tools);
|
|
1137
|
+
if (await this.plugin.knowledgeBaseManager.isEnabledKnowledgeBase(this.employee.toJSON())) {
|
|
1138
|
+
const knowledgeBaseRetrieveTool = await this.toolsManager.getTools("knowledge-base-retrieve");
|
|
1139
|
+
if (knowledgeBaseRetrieveTool) {
|
|
1140
|
+
employeeTools.push({ name: "knowledge-base-retrieve" });
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1162
1143
|
for (const toolSetting of employeeTools) {
|
|
1163
1144
|
if (generalToolsNameSet.has(toolSetting.name)) {
|
|
1164
1145
|
continue;
|
|
@@ -1255,14 +1236,16 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1255
1236
|
);
|
|
1256
1237
|
return availableAIEmployees;
|
|
1257
1238
|
}
|
|
1258
|
-
getMiddleware(options) {
|
|
1239
|
+
async getMiddleware(options) {
|
|
1259
1240
|
const { providerName, model, tools, baseToolNames, messageId, agentThread } = options;
|
|
1241
|
+
const inWorkflow = await this.isInWorkflow();
|
|
1260
1242
|
return [
|
|
1261
1243
|
(0, import_middleware.skillToolBindingMiddleware)(this, {
|
|
1262
1244
|
baseToolNames: Array.from(baseToolNames.values())
|
|
1263
1245
|
}),
|
|
1264
1246
|
(0, import_middleware.toolInteractionMiddleware)(this, tools),
|
|
1265
1247
|
(0, import_middleware.toolCallStatusMiddleware)(this),
|
|
1248
|
+
...inWorkflow ? [(0, import_middleware.workflowHistoryMiddleware)(this, this.db)] : [],
|
|
1266
1249
|
(0, import_middleware.conversationMiddleware)(this, { providerName, model, messageId, agentThread })
|
|
1267
1250
|
];
|
|
1268
1251
|
}
|
|
@@ -1288,7 +1271,9 @@ If information is missing, clearly state it in the summary.</Important>`;
|
|
|
1288
1271
|
throw new Error("Fail to create new agent thread");
|
|
1289
1272
|
}
|
|
1290
1273
|
async getToolsMap() {
|
|
1291
|
-
const tools = await this.listTools(
|
|
1274
|
+
const tools = await this.listTools({
|
|
1275
|
+
sessionId: this.sessionId
|
|
1276
|
+
});
|
|
1292
1277
|
return new Map(tools.map((tool) => [tool.definition.name, tool]));
|
|
1293
1278
|
}
|
|
1294
1279
|
listTools(filter) {
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
import { AIEmployee } from '../../collections/ai-employees';
|
|
10
|
+
import { DocumentSegmentedWithScore } from '../features';
|
|
11
|
+
import type PluginAIServer from '../plugin';
|
|
12
|
+
export type KnowledgeBaseRetrieveOptions = {
|
|
13
|
+
username?: string;
|
|
14
|
+
employee?: AIEmployee;
|
|
15
|
+
query: string;
|
|
16
|
+
};
|
|
17
|
+
export declare class KnowledgeBaseManager {
|
|
18
|
+
private readonly plugin;
|
|
19
|
+
constructor(plugin: PluginAIServer);
|
|
20
|
+
retrievePrompt({ username, employee, query }: KnowledgeBaseRetrieveOptions): Promise<string>;
|
|
21
|
+
retrieve({ username, employee, query }: KnowledgeBaseRetrieveOptions): Promise<DocumentSegmentedWithScore[]>;
|
|
22
|
+
isEnabledKnowledgeBase(username: string): Promise<boolean>;
|
|
23
|
+
isEnabledKnowledgeBase(employee: AIEmployee): Promise<boolean>;
|
|
24
|
+
private getAIEmployeeKnowledgeBaseConfig;
|
|
25
|
+
private getKnowledgeBaseGroup;
|
|
26
|
+
private getEmployee;
|
|
27
|
+
private get aiEmployeeRepo();
|
|
28
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
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 ai_knowledge_base_exports = {};
|
|
38
|
+
__export(ai_knowledge_base_exports, {
|
|
39
|
+
KnowledgeBaseManager: () => KnowledgeBaseManager
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(ai_knowledge_base_exports);
|
|
42
|
+
var import_prompts = require("@langchain/core/prompts");
|
|
43
|
+
var import_ai_feature_manager = require("../manager/ai-feature-manager");
|
|
44
|
+
var import_lodash = __toESM(require("lodash"));
|
|
45
|
+
class KnowledgeBaseManager {
|
|
46
|
+
constructor(plugin) {
|
|
47
|
+
this.plugin = plugin;
|
|
48
|
+
}
|
|
49
|
+
async retrievePrompt({ username, employee, query }) {
|
|
50
|
+
employee = employee ?? await this.getEmployee(username);
|
|
51
|
+
if (!employee) {
|
|
52
|
+
return "Specified knowledge base not existed";
|
|
53
|
+
}
|
|
54
|
+
const promptTemplate = import_prompts.ChatPromptTemplate.fromTemplate(employee.knowledgeBasePrompt);
|
|
55
|
+
const docs = await this.retrieve({
|
|
56
|
+
employee,
|
|
57
|
+
query
|
|
58
|
+
});
|
|
59
|
+
if (!(docs == null ? void 0 : docs.length)) {
|
|
60
|
+
return "No document match in knowledge base";
|
|
61
|
+
}
|
|
62
|
+
const knowledgeBaseData = docs.map((x) => x.content).join("\n");
|
|
63
|
+
return import_lodash.default.isEmpty(knowledgeBaseData) ? void 0 : await promptTemplate.format({
|
|
64
|
+
knowledgeBaseData
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async retrieve({ username, employee, query }) {
|
|
68
|
+
const vectorStoreProvider = this.plugin.features.vectorStoreProvider;
|
|
69
|
+
let queryResult = [];
|
|
70
|
+
if (!query || import_lodash.default.isEmpty(query)) {
|
|
71
|
+
return queryResult;
|
|
72
|
+
}
|
|
73
|
+
employee = employee ?? await this.getEmployee(username);
|
|
74
|
+
if (!employee) {
|
|
75
|
+
return queryResult;
|
|
76
|
+
}
|
|
77
|
+
const { topK, score } = this.getAIEmployeeKnowledgeBaseConfig(employee);
|
|
78
|
+
const knowledgeBaseGroup = await this.getKnowledgeBaseGroup(employee);
|
|
79
|
+
for (const entry of knowledgeBaseGroup) {
|
|
80
|
+
const { vectorStoreConfig, knowledgeBaseType, knowledgeBaseList } = entry;
|
|
81
|
+
if (!knowledgeBaseList || import_lodash.default.isEmpty(knowledgeBaseList)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (knowledgeBaseType === "LOCAL") {
|
|
85
|
+
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
86
|
+
vectorStoreConfig.vectorStoreProvider,
|
|
87
|
+
[
|
|
88
|
+
{
|
|
89
|
+
key: "vectorStoreConfigId",
|
|
90
|
+
value: vectorStoreConfig.vectorStoreConfigId
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
);
|
|
94
|
+
const knowledgeBaseOuterIds = knowledgeBaseList.map((x) => x.knowledgeBaseOuterId);
|
|
95
|
+
const result = await vectorStoreService.search(query, {
|
|
96
|
+
topK,
|
|
97
|
+
score,
|
|
98
|
+
filter: {
|
|
99
|
+
knowledgeBaseOuterId: { in: knowledgeBaseOuterIds }
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
queryResult = [...queryResult, ...result];
|
|
103
|
+
} else if (knowledgeBaseType === "READONLY") {
|
|
104
|
+
for (const knowledgeBase of knowledgeBaseList) {
|
|
105
|
+
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
106
|
+
vectorStoreConfig.vectorStoreProvider,
|
|
107
|
+
[
|
|
108
|
+
...knowledgeBase.vectorStoreProps,
|
|
109
|
+
{
|
|
110
|
+
key: "vectorStoreConfigId",
|
|
111
|
+
value: vectorStoreConfig.vectorStoreConfigId
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
);
|
|
115
|
+
const result = await vectorStoreService.search(query, {
|
|
116
|
+
topK,
|
|
117
|
+
score
|
|
118
|
+
});
|
|
119
|
+
queryResult = [...queryResult, ...result];
|
|
120
|
+
}
|
|
121
|
+
} else if (knowledgeBaseType === "EXTERNAL") {
|
|
122
|
+
for (const knowledgeBase of knowledgeBaseList) {
|
|
123
|
+
const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
|
|
124
|
+
vectorStoreConfig.vectorStoreProvider,
|
|
125
|
+
knowledgeBase.vectorStoreProps
|
|
126
|
+
);
|
|
127
|
+
const result = await vectorStoreService.search(query, {
|
|
128
|
+
topK,
|
|
129
|
+
score
|
|
130
|
+
});
|
|
131
|
+
queryResult = [...queryResult, ...result];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return queryResult;
|
|
136
|
+
}
|
|
137
|
+
async isEnabledKnowledgeBase(usernameOrEmployee) {
|
|
138
|
+
const featureEnabled = this.plugin.features.isFeaturesEnabled(Object.values(import_ai_feature_manager.EEFeatures));
|
|
139
|
+
const employee = typeof usernameOrEmployee === "string" ? await this.getEmployee(usernameOrEmployee) : usernameOrEmployee;
|
|
140
|
+
const knowledgeBaseEnabled = employee == null ? void 0 : employee.enableKnowledgeBase;
|
|
141
|
+
return featureEnabled && knowledgeBaseEnabled;
|
|
142
|
+
}
|
|
143
|
+
getAIEmployeeKnowledgeBaseConfig(employee) {
|
|
144
|
+
const { topK, score } = (employee == null ? void 0 : employee.knowledgeBase) ?? {};
|
|
145
|
+
return {
|
|
146
|
+
topK,
|
|
147
|
+
score
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
async getKnowledgeBaseGroup(employee) {
|
|
151
|
+
const { knowledgeBaseIds } = (employee == null ? void 0 : employee.knowledgeBase) ?? {};
|
|
152
|
+
if (!knowledgeBaseIds || import_lodash.default.isEmpty(knowledgeBaseIds)) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
return await this.plugin.features.knowledgeBase.getKnowledgeBaseGroup(knowledgeBaseIds);
|
|
156
|
+
}
|
|
157
|
+
async getEmployee(username) {
|
|
158
|
+
return await this.aiEmployeeRepo.findOne({ filter: { username } });
|
|
159
|
+
}
|
|
160
|
+
get aiEmployeeRepo() {
|
|
161
|
+
return this.plugin.db.getRepository("aiEmployees");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
165
|
+
0 && (module.exports = {
|
|
166
|
+
KnowledgeBaseManager
|
|
167
|
+
});
|