@nocobase/plugin-ai 2.2.19 → 2.2.20

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 (119) hide show
  1. package/dist/ai/tools/knowledge-base-retrieve.js +13 -2
  2. package/dist/client/index.js +1 -1
  3. package/dist/client-v2/index.js +1 -1
  4. package/dist/externalVersion.js +16 -16
  5. package/dist/node_modules/@langchain/mistralai/dist/index.cjs +2 -2
  6. package/dist/node_modules/@langchain/mistralai/package.json +1 -1
  7. package/dist/node_modules/@langchain/xai/dist/index.cjs +2 -2
  8. package/dist/node_modules/@langchain/xai/package.json +1 -1
  9. package/dist/node_modules/fs-extra/package.json +1 -1
  10. package/dist/node_modules/jsonrepair/package.json +1 -1
  11. package/dist/node_modules/just-bash/dist/bundle/index.cjs +239 -239
  12. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/.gitattributes +4 -0
  13. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/angular-sprintf.min.js +3 -0
  14. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/sprintf.min.js +3 -0
  15. package/dist/node_modules/just-bash/node_modules/sprintf-js/package.json +35 -0
  16. package/dist/node_modules/just-bash/node_modules/sprintf-js/src/angular-sprintf.js +24 -0
  17. package/dist/node_modules/just-bash/node_modules/sprintf-js/src/sprintf.js +231 -0
  18. package/dist/node_modules/just-bash/package.json +1 -1
  19. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  20. package/dist/node_modules/openai/package.json +1 -1
  21. package/dist/node_modules/zod/package.json +1 -1
  22. package/dist/server/ai-employees/ai-employee.d.ts +15 -1
  23. package/dist/server/ai-employees/ai-employee.js +107 -38
  24. package/dist/server/ai-employees/ai-knowledge-base.d.ts +7 -1
  25. package/dist/server/ai-employees/ai-knowledge-base.js +30 -7
  26. package/dist/server/features/knowledge-base.d.ts +2 -1
  27. package/dist/server/types/knowledge-base.type.d.ts +6 -0
  28. package/package.json +2 -2
  29. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/bin/uuid +0 -2
  30. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/index.js +0 -104
  31. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/max.js +0 -7
  32. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/md5.js +0 -200
  33. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/native.js +0 -10
  34. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/nil.js +0 -7
  35. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/parse.js +0 -44
  36. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/regex.js +0 -7
  37. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/rng.js +0 -23
  38. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/sha1.js +0 -82
  39. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/stringify.js +0 -38
  40. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v1.js +0 -131
  41. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v1ToV6.js +0 -26
  42. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v3.js +0 -11
  43. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v35.js +0 -63
  44. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v4.js +0 -32
  45. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v5.js +0 -11
  46. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v6.js +0 -42
  47. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v6ToV1.js +0 -26
  48. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v7.js +0 -152
  49. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/validate.js +0 -12
  50. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/version.js +0 -15
  51. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/index.js +0 -14
  52. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/max.js +0 -1
  53. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/md5.js +0 -194
  54. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/native.js +0 -4
  55. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/nil.js +0 -1
  56. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/parse.js +0 -37
  57. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/regex.js +0 -1
  58. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/rng.js +0 -17
  59. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/sha1.js +0 -76
  60. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/stringify.js +0 -31
  61. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v1.js +0 -125
  62. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v1ToV6.js +0 -20
  63. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v3.js +0 -4
  64. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v35.js +0 -55
  65. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v4.js +0 -25
  66. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v5.js +0 -4
  67. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v6.js +0 -36
  68. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v6ToV1.js +0 -20
  69. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v7.js +0 -146
  70. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/validate.js +0 -5
  71. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/version.js +0 -8
  72. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/index.js +0 -14
  73. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/max.js +0 -1
  74. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/md5.js +0 -10
  75. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/native.js +0 -4
  76. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/nil.js +0 -1
  77. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/parse.js +0 -37
  78. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/regex.js +0 -1
  79. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/rng.js +0 -10
  80. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/sha1.js +0 -10
  81. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/stringify.js +0 -31
  82. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v1.js +0 -125
  83. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v1ToV6.js +0 -20
  84. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v3.js +0 -4
  85. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v35.js +0 -55
  86. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v4.js +0 -25
  87. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v5.js +0 -4
  88. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v6.js +0 -32
  89. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v6ToV1.js +0 -20
  90. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v7.js +0 -146
  91. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/validate.js +0 -5
  92. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/version.js +0 -8
  93. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/index.js +0 -104
  94. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/max.js +0 -7
  95. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/md5-browser.js +0 -200
  96. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/md5.js +0 -17
  97. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/native-browser.js +0 -10
  98. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/native.js +0 -11
  99. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/nil.js +0 -7
  100. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/parse.js +0 -44
  101. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/regex.js +0 -7
  102. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/rng-browser.js +0 -23
  103. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/rng.js +0 -17
  104. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/sha1-browser.js +0 -82
  105. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/sha1.js +0 -17
  106. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/stringify.js +0 -38
  107. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/uuid-bin.js +0 -75
  108. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v1.js +0 -131
  109. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v1ToV6.js +0 -26
  110. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v3.js +0 -11
  111. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v35.js +0 -63
  112. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v4.js +0 -32
  113. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v5.js +0 -11
  114. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v6.js +0 -38
  115. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v6ToV1.js +0 -26
  116. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v7.js +0 -152
  117. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/validate.js +0 -12
  118. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/version.js +0 -15
  119. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/package.json +0 -142
@@ -228,12 +228,14 @@ class AIEmployee {
228
228
  providerName: service.provider,
229
229
  llmService: ((_a = service.get) == null ? void 0 : _a.call(service, "name")) || service.name
230
230
  });
231
+ const contextMessages = [...historyMessages, ...userMessages ?? []];
232
+ const knowledgeBaseContext = await this.retrieveKnowledgeBase(contextMessages);
231
233
  const chatContext = await this.aiChatConversation.getChatContext({
232
- userMessages: [...historyMessages, ...userMessages ?? []],
234
+ userMessages: contextMessages,
233
235
  userDecisions,
234
236
  tools: resolvedTools,
235
237
  middleware,
236
- getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2),
238
+ getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2, knowledgeBaseContext),
237
239
  formatMessages: (messages) => this.formatMessages({ messages, provider })
238
240
  });
239
241
  return {
@@ -243,7 +245,8 @@ class AIEmployee {
243
245
  provider,
244
246
  chatContext,
245
247
  config,
246
- state
248
+ state,
249
+ knowledgeBaseDocuments: knowledgeBaseContext.documents
247
250
  };
248
251
  }
249
252
  async stream({
@@ -259,7 +262,7 @@ class AIEmployee {
259
262
  }
260
263
  });
261
264
  try {
262
- const { providerName, llmService, model, provider, chatContext, config, state } = await this.buildChatContext({
265
+ const { providerName, llmService, model, provider, chatContext, config, state, knowledgeBaseDocuments } = await this.buildChatContext({
263
266
  messageId,
264
267
  userMessages,
265
268
  userDecisions
@@ -278,7 +281,8 @@ class AIEmployee {
278
281
  llmService,
279
282
  model,
280
283
  provider,
281
- responseMetadata
284
+ responseMetadata,
285
+ knowledgeBaseDocuments
282
286
  });
283
287
  return true;
284
288
  } catch (err) {
@@ -428,7 +432,23 @@ class AIEmployee {
428
432
  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;
429
433
  const aiMessageIdMap = /* @__PURE__ */ new Map();
430
434
  const persistedAIMessageIdMap = /* @__PURE__ */ new Map();
431
- const { signal, providerName, llmService, model, provider, responseMetadata, allowEmpty = false } = options;
435
+ const {
436
+ signal,
437
+ providerName,
438
+ llmService,
439
+ model,
440
+ provider,
441
+ responseMetadata,
442
+ allowEmpty = false,
443
+ knowledgeBaseDocuments = []
444
+ } = options;
445
+ const knowledgeBaseReferences = /* @__PURE__ */ new Map();
446
+ const collectKnowledgeBaseReferences = (documents) => {
447
+ for (const document of documents) {
448
+ knowledgeBaseReferences.set(String(document.id), document);
449
+ }
450
+ };
451
+ let lastAIMessageId;
432
452
  const reasoningState = new import_reasoning_stream_state.ReasoningStreamState();
433
453
  const stopReasoning = async (conversation) => {
434
454
  if (reasoningState.stop(conversation)) {
@@ -449,7 +469,7 @@ class AIEmployee {
449
469
  try {
450
470
  await stopAllReasoning();
451
471
  if ((gathered == null ? void 0 : gathered.type) === "ai") {
452
- await this.finalizeAbortedAIMessage({
472
+ const result = await this.finalizeAbortedAIMessage({
453
473
  aiMessage: gathered,
454
474
  providerName,
455
475
  provider,
@@ -457,6 +477,9 @@ class AIEmployee {
457
477
  model,
458
478
  knownMessageId: persistedAIMessageIdMap.get(gathered.id)
459
479
  });
480
+ if (result) {
481
+ lastAIMessageId = result.message.messageId;
482
+ }
460
483
  }
461
484
  } catch (e) {
462
485
  this.logger.error("Fail to save message after conversation abort", gathered);
@@ -480,6 +503,10 @@ class AIEmployee {
480
503
  username: this.employee.username
481
504
  };
482
505
  await this.protocol.with(aiEmployeeConversation).startStream();
506
+ if (knowledgeBaseDocuments.length) {
507
+ collectKnowledgeBaseReferences(knowledgeBaseDocuments);
508
+ await this.protocol.with(aiEmployeeConversation).knowledgeBaseReferences({ documents: knowledgeBaseDocuments });
509
+ }
483
510
  for await (const [mode, chunks] of stream) {
484
511
  if (mode === "messages") {
485
512
  const [chunk, metadata] = chunks;
@@ -536,6 +563,9 @@ class AIEmployee {
536
563
  await this.streamCached.skipped();
537
564
  aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
538
565
  persistedAIMessageIdMap.set(chunks.body.id, chunks.body.messageId);
566
+ if (currentConversation.sessionId === this.sessionId) {
567
+ lastAIMessageId = chunks.body.messageId;
568
+ }
539
569
  const data = responseMetadata.get(chunks.body.id);
540
570
  if (data) {
541
571
  const savedMessage = await this.aiMessagesModel.findOne({
@@ -622,6 +652,13 @@ class AIEmployee {
622
652
  await this.protocol.with(currentConversation).newMessage();
623
653
  } else if (chunks.action === "afterSubAgentInvoke") {
624
654
  await this.protocol.with(currentConversation).subAgentCompleted();
655
+ } else if (chunks.action === "knowledgeBaseRetrieved") {
656
+ const { toolCallId, documents = [] } = chunks.body ?? {};
657
+ collectKnowledgeBaseReferences(documents);
658
+ await this.protocol.with({
659
+ ...currentConversation,
660
+ from: currentConversation.sessionId === this.sessionId ? this.from : "sub-agent"
661
+ }).knowledgeBaseReferences({ toolCallId, documents });
625
662
  }
626
663
  }
627
664
  }
@@ -641,11 +678,32 @@ class AIEmployee {
641
678
  }
642
679
  } finally {
643
680
  await abortFinalization;
681
+ await this.saveKnowledgeBaseReferences(lastAIMessageId, Array.from(knowledgeBaseReferences.values()));
644
682
  if (this.from === "main-agent") {
645
683
  this.ctx.res.end();
646
684
  }
647
685
  }
648
686
  }
687
+ async saveKnowledgeBaseReferences(messageId, documents) {
688
+ if (!messageId || !documents.length) {
689
+ return;
690
+ }
691
+ try {
692
+ const savedMessage = await this.aiMessagesModel.findOne({
693
+ where: { sessionId: this.sessionId, messageId }
694
+ });
695
+ if (!savedMessage) {
696
+ return;
697
+ }
698
+ const metadata = savedMessage.get("metadata") ?? {};
699
+ await this.aiMessagesModel.update(
700
+ { metadata: { ...metadata, knowledgeBaseReferences: documents } },
701
+ { where: { sessionId: this.sessionId, messageId } }
702
+ );
703
+ } catch (error) {
704
+ this.logger.error("Failed to save knowledge base references", { sessionId: this.sessionId, messageId, error });
705
+ }
706
+ }
649
707
  async handleInterruptedToolCalls(interrupt, getMessageId, onInterrupted) {
650
708
  const interruptId = interrupt == null ? void 0 : interrupt.id;
651
709
  const interruptActions = this.toInterruptActions(interrupt == null ? void 0 : interrupt.value);
@@ -721,14 +779,10 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
721
779
  }
722
780
  return message;
723
781
  }
724
- async getSystemPrompt(userMessages) {
725
- var _a, _b, _c, _d, _e, _f, _g, _h;
726
- if (this.systemPromptMode === "none") {
727
- return "";
728
- }
729
- const about = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
730
- if (this.systemPromptMode === "raw") {
731
- return about;
782
+ async retrieveKnowledgeBase(userMessages) {
783
+ var _a;
784
+ if (this.systemPromptMode !== "default") {
785
+ return { documents: [] };
732
786
  }
733
787
  const employee = this.getAIEmployeeRecord();
734
788
  const knowledgeBaseManager = this.plugin.knowledgeBaseManager;
@@ -737,9 +791,37 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
737
791
  const hasAccessibleKnowledgeBase = knowledgeBaseEnabled ? await knowledgeBaseManager.hasAccessibleKnowledgeBase({ employee, roleNames }) : false;
738
792
  const knowledgeBaseAccessDenied = knowledgeBaseEnabled && !hasAccessibleKnowledgeBase;
739
793
  const knowledgeBaseOnDemand = knowledgeBaseEnabled && hasAccessibleKnowledgeBase && (0, import_ai_knowledge_base.normalizeKnowledgeBaseRetrievalStrategy)((_a = employee.knowledgeBase) == null ? void 0 : _a.retrievalStrategy) === "onDemand";
794
+ let prompt;
795
+ let documents = [];
796
+ if (knowledgeBaseEnabled && hasAccessibleKnowledgeBase && !knowledgeBaseOnDemand && (userMessages == null ? void 0 : userMessages.length)) {
797
+ const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
798
+ if (lastUserMessage) {
799
+ ({ prompt, documents } = await knowledgeBaseManager.retrievePrompt({
800
+ employee,
801
+ query: lastUserMessage.content.content,
802
+ roleNames
803
+ }));
804
+ }
805
+ }
806
+ const backgroundPrompt = (0, import_ai_knowledge_base.getKnowledgeBaseBackgroundPrompt)({
807
+ accessDenied: knowledgeBaseAccessDenied,
808
+ onDemand: knowledgeBaseOnDemand,
809
+ preRetrieved: Boolean(prompt)
810
+ });
811
+ return { prompt, backgroundPrompt, documents };
812
+ }
813
+ async getSystemPrompt(userMessages, knowledgeBaseContext) {
814
+ var _a, _b, _c, _d, _e, _f, _g;
815
+ if (this.systemPromptMode === "none") {
816
+ return "";
817
+ }
818
+ const about = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
819
+ if (this.systemPromptMode === "raw") {
820
+ return about;
821
+ }
740
822
  const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
741
823
  filter: {
742
- userId: ((_b = this.ctx.auth) == null ? void 0 : _b.user.id) ?? 0,
824
+ userId: ((_a = this.ctx.auth) == null ? void 0 : _a.user.id) ?? 0,
743
825
  aiEmployee: this.employee.username
744
826
  }
745
827
  });
@@ -763,25 +845,9 @@ ${workContextBackground.join("\n")}`;
763
845
  background = `${background}
764
846
  ${addSystemPrompt.map((it) => it.content).join("\n")}`;
765
847
  }
766
- let knowledgeBase;
767
- if (knowledgeBaseEnabled && hasAccessibleKnowledgeBase && !knowledgeBaseOnDemand && (userMessages == null ? void 0 : userMessages.length)) {
768
- const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
769
- if (lastUserMessage) {
770
- knowledgeBase = await knowledgeBaseManager.retrievePrompt({
771
- employee,
772
- query: lastUserMessage.content.content,
773
- roleNames
774
- });
775
- }
776
- }
777
- const knowledgeBaseBackgroundPrompt = (0, import_ai_knowledge_base.getKnowledgeBaseBackgroundPrompt)({
778
- accessDenied: knowledgeBaseAccessDenied,
779
- onDemand: knowledgeBaseOnDemand,
780
- preRetrieved: Boolean(knowledgeBase)
781
- });
782
- if (knowledgeBaseBackgroundPrompt) {
848
+ if (knowledgeBaseContext == null ? void 0 : knowledgeBaseContext.backgroundPrompt) {
783
849
  background = `${background}
784
- ${knowledgeBaseBackgroundPrompt}`;
850
+ ${knowledgeBaseContext.backgroundPrompt}`;
785
851
  }
786
852
  const availableSkills = await this.getAvailableSkills();
787
853
  const availableAIEmployees = await this.getAvailableAIEmployees();
@@ -796,20 +862,20 @@ ${knowledgeBaseBackgroundPrompt}`;
796
862
  personal: userConfig == null ? void 0 : userConfig.prompt,
797
863
  environment: {
798
864
  database: this.db.sequelize.getDialect(),
799
- locale: ((_d = (_c = this.ctx).getCurrentLocale) == null ? void 0 : _d.call(_c)) || "en-US",
865
+ locale: ((_c = (_b = this.ctx).getCurrentLocale) == null ? void 0 : _c.call(_b)) || "en-US",
800
866
  currentDateTime: getCurrentDateTimeForPrompt(
801
867
  await this.aiChatConversation.getCreatedAt(),
802
- (_f = (_e = this.ctx).getCurrentLocale) == null ? void 0 : _f.call(_e),
868
+ (_e = (_d = this.ctx).getCurrentLocale) == null ? void 0 : _e.call(_d),
803
869
  getCurrentTimezone(this.ctx)
804
870
  ),
805
871
  timezone: getCurrentTimezone(this.ctx)
806
872
  },
807
- knowledgeBase,
873
+ knowledgeBase: knowledgeBaseContext == null ? void 0 : knowledgeBaseContext.prompt,
808
874
  availableSkills,
809
875
  availableAIEmployees,
810
876
  webSearch: this.webSearch
811
877
  });
812
- const { important } = ((_h = (_g = this.ctx.action) == null ? void 0 : _g.params) == null ? void 0 : _h.values) || {};
878
+ const { important } = ((_g = (_f = this.ctx.action) == null ? void 0 : _f.params) == null ? void 0 : _g.values) || {};
813
879
  if (important === "GraphRecursionError") {
814
880
  const importantPrompt = `<Important>You have already called tools multiple times and gathered sufficient information.
815
881
  First, provide a summary based on the existing information. Do not call additional tools.
@@ -1811,6 +1877,9 @@ class ChatStreamProtocol {
1811
1877
  subAgentCompleted: async () => {
1812
1878
  await write({ type: "sub_agent_completed" });
1813
1879
  },
1880
+ knowledgeBaseReferences: async (body) => {
1881
+ await write({ type: "knowledge_base_references", body });
1882
+ },
1814
1883
  newMessage: async (content) => {
1815
1884
  await write({ type: "new_message", body: content });
1816
1885
  },
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { AIEmployee } from '../../collections/ai-employees';
10
10
  import type PluginAIServer from '../plugin';
11
+ import type { KnowledgeBaseReference } from '../types';
11
12
  export declare const KNOWLEDGE_BASE_RETRIEVAL_STRATEGIES: readonly ["always", "onDemand"];
12
13
  export type KnowledgeBaseRetrievalStrategy = (typeof KNOWLEDGE_BASE_RETRIEVAL_STRATEGIES)[number];
13
14
  export declare const isKnowledgeBaseRetrievalStrategy: (value: unknown) => value is "always" | "onDemand";
@@ -28,6 +29,10 @@ export type KnowledgeBaseRetrieveOptions = {
28
29
  query: string;
29
30
  roleNames?: string[];
30
31
  };
32
+ export type KnowledgeBaseRetrieveResult = {
33
+ prompt: string;
34
+ documents: KnowledgeBaseReference[];
35
+ };
31
36
  export type KnowledgeBaseAccessOptions = {
32
37
  employee: AIEmployee;
33
38
  roleNames: string[];
@@ -35,7 +40,8 @@ export type KnowledgeBaseAccessOptions = {
35
40
  export declare class KnowledgeBaseManager {
36
41
  private readonly plugin;
37
42
  constructor(plugin: PluginAIServer);
38
- retrievePrompt({ username, employee, query, roleNames }: KnowledgeBaseRetrieveOptions): Promise<string>;
43
+ retrievePrompt({ username, employee, query, roleNames, }: KnowledgeBaseRetrieveOptions): Promise<KnowledgeBaseRetrieveResult>;
44
+ private getDocumentReferences;
39
45
  hasAccessibleKnowledgeBase({ employee, roleNames }: KnowledgeBaseAccessOptions): Promise<boolean>;
40
46
  isEnabledKnowledgeBase(username: string): Promise<boolean>;
41
47
  isEnabledKnowledgeBase(employee: AIEmployee): Promise<boolean>;
@@ -115,27 +115,50 @@ class KnowledgeBaseManager {
115
115
  constructor(plugin) {
116
116
  this.plugin = plugin;
117
117
  }
118
- async retrievePrompt({ username, employee, query, roleNames }) {
118
+ async retrievePrompt({
119
+ username,
120
+ employee,
121
+ query,
122
+ roleNames
123
+ }) {
119
124
  employee = employee ?? (username ? await this.getEmployee(username) : null);
120
125
  if (!employee) {
121
- return "Specified knowledge base not existed";
126
+ return { prompt: "Specified knowledge base not existed", documents: [] };
122
127
  }
123
128
  const { knowledgeBaseKeys = [], topK, score } = employee.knowledgeBase ?? {};
124
129
  const knowledgeBasePrompt = employee.knowledgeBasePrompt ?? "{knowledgeBaseData}";
125
130
  const docs = await this.plugin.features.knowledgeBase.search({ knowledgeBaseKeys, query, topK, score, roleNames });
126
131
  if (!(docs == null ? void 0 : docs.length)) {
127
- return "No document match in knowledge base";
132
+ return { prompt: "No document match in knowledge base", documents: [] };
128
133
  }
129
134
  const knowledgeBaseData = docs.map((doc) => buildKnowledgeBaseContent(doc.content, doc.metadata)).join("\n");
130
135
  if (import_lodash.default.isEmpty(knowledgeBaseData)) {
131
- return "No document match in knowledge base";
136
+ return { prompt: "No document match in knowledge base", documents: [] };
132
137
  }
138
+ const documents = await this.getDocumentReferences(docs);
133
139
  if (!(0, import_ai_employee_validation.hasKnowledgeBaseDataPlaceholder)(knowledgeBasePrompt)) {
134
- return `${knowledgeBasePrompt}
140
+ return { prompt: `${knowledgeBasePrompt}
135
141
 
136
- ${knowledgeBaseData}`;
142
+ ${knowledgeBaseData}`, documents };
137
143
  }
138
- return import_prompts.ChatPromptTemplate.fromTemplate(knowledgeBasePrompt).format({ knowledgeBaseData });
144
+ const prompt = await import_prompts.ChatPromptTemplate.fromTemplate(knowledgeBasePrompt).format({ knowledgeBaseData });
145
+ return { prompt, documents };
146
+ }
147
+ async getDocumentReferences(docs) {
148
+ const knowledgeBaseFeature = this.plugin.features.knowledgeBase;
149
+ if (!knowledgeBaseFeature.getDocumentReferences) {
150
+ return [];
151
+ }
152
+ const knowledgeBaseDocsIds = import_lodash.default.uniq(
153
+ docs.map((doc) => {
154
+ var _a;
155
+ return (_a = doc.metadata) == null ? void 0 : _a.knowledgeBaseDocsId;
156
+ }).filter((id) => typeof id === "number" || typeof id === "string" && id !== "")
157
+ );
158
+ if (!knowledgeBaseDocsIds.length) {
159
+ return [];
160
+ }
161
+ return await knowledgeBaseFeature.getDocumentReferences(knowledgeBaseDocsIds);
139
162
  }
140
163
  async hasAccessibleKnowledgeBase({ employee, roleNames }) {
141
164
  var _a;
@@ -6,11 +6,12 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import { DocumentSegmentedWithScore, KnowledgeBase, KnowledgeBaseGroup, SearchOptions } from '../types';
9
+ import { DocumentSegmentedWithScore, KnowledgeBase, KnowledgeBaseGroup, KnowledgeBaseReference, SearchOptions } from '../types';
10
10
  export type KnowledgeBaseAccessOptions = Pick<SearchOptions, 'knowledgeBaseKeys' | 'roleNames'>;
11
11
  export interface KnowledgeBaseFeature {
12
12
  getKnowledgeBase(knowledgeBaseKeys: string[]): Promise<KnowledgeBase[]>;
13
13
  getKnowledgeBaseGroup(knowledgeBaseKeys: string[]): Promise<KnowledgeBaseGroup[]>;
14
14
  getAccessibleKnowledgeBaseKeys(options: KnowledgeBaseAccessOptions): Promise<string[]>;
15
15
  search(options: SearchOptions): Promise<DocumentSegmentedWithScore[]>;
16
+ getDocumentReferences?(knowledgeBaseDocsIds: Array<number | string>): Promise<KnowledgeBaseReference[]>;
16
17
  }
@@ -51,3 +51,9 @@ export type SearchOptions = {
51
51
  score?: string;
52
52
  roleNames?: string[];
53
53
  };
54
+ export type KnowledgeBaseReference = {
55
+ id: number | string;
56
+ title: string;
57
+ extname: string;
58
+ url: string;
59
+ };
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Create AI employees with diverse skills to collaborate with humans, build systems, and handle business operations.",
7
7
  "description.ru-RU": "Поддержка интеграции с AI-сервисами: предоставляются AI-узлы для рабочих процессов, расширяя возможности бизнес-обработки.",
8
8
  "description.zh-CN": "创建各种技能的 AI 员工,与人类协同,搭建系统,处理业务。",
9
- "version": "2.2.19",
9
+ "version": "2.2.20",
10
10
  "main": "dist/server/index.js",
11
11
  "homepage": "https://docs.nocobase.com/handbook/action-ai",
12
12
  "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/action-ai",
@@ -66,5 +66,5 @@
66
66
  "keywords": [
67
67
  "AI"
68
68
  ],
69
- "gitHead": "0d4e2dc07729c32533e35c8e8e16c57815d6242a"
69
+ "gitHead": "d9c3d45cdca9571f6cef8781e0a2d86566dce11b"
70
70
  }
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- require('../uuid-bin');
@@ -1,104 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "MAX", {
7
- enumerable: true,
8
- get: function get() {
9
- return _max.default;
10
- }
11
- });
12
- Object.defineProperty(exports, "NIL", {
13
- enumerable: true,
14
- get: function get() {
15
- return _nil.default;
16
- }
17
- });
18
- Object.defineProperty(exports, "parse", {
19
- enumerable: true,
20
- get: function get() {
21
- return _parse.default;
22
- }
23
- });
24
- Object.defineProperty(exports, "stringify", {
25
- enumerable: true,
26
- get: function get() {
27
- return _stringify.default;
28
- }
29
- });
30
- Object.defineProperty(exports, "v1", {
31
- enumerable: true,
32
- get: function get() {
33
- return _v.default;
34
- }
35
- });
36
- Object.defineProperty(exports, "v1ToV6", {
37
- enumerable: true,
38
- get: function get() {
39
- return _v1ToV.default;
40
- }
41
- });
42
- Object.defineProperty(exports, "v3", {
43
- enumerable: true,
44
- get: function get() {
45
- return _v2.default;
46
- }
47
- });
48
- Object.defineProperty(exports, "v4", {
49
- enumerable: true,
50
- get: function get() {
51
- return _v3.default;
52
- }
53
- });
54
- Object.defineProperty(exports, "v5", {
55
- enumerable: true,
56
- get: function get() {
57
- return _v4.default;
58
- }
59
- });
60
- Object.defineProperty(exports, "v6", {
61
- enumerable: true,
62
- get: function get() {
63
- return _v5.default;
64
- }
65
- });
66
- Object.defineProperty(exports, "v6ToV1", {
67
- enumerable: true,
68
- get: function get() {
69
- return _v6ToV.default;
70
- }
71
- });
72
- Object.defineProperty(exports, "v7", {
73
- enumerable: true,
74
- get: function get() {
75
- return _v6.default;
76
- }
77
- });
78
- Object.defineProperty(exports, "validate", {
79
- enumerable: true,
80
- get: function get() {
81
- return _validate.default;
82
- }
83
- });
84
- Object.defineProperty(exports, "version", {
85
- enumerable: true,
86
- get: function get() {
87
- return _version.default;
88
- }
89
- });
90
- var _max = _interopRequireDefault(require("./max.js"));
91
- var _nil = _interopRequireDefault(require("./nil.js"));
92
- var _parse = _interopRequireDefault(require("./parse.js"));
93
- var _stringify = _interopRequireDefault(require("./stringify.js"));
94
- var _v = _interopRequireDefault(require("./v1.js"));
95
- var _v1ToV = _interopRequireDefault(require("./v1ToV6.js"));
96
- var _v2 = _interopRequireDefault(require("./v3.js"));
97
- var _v3 = _interopRequireDefault(require("./v4.js"));
98
- var _v4 = _interopRequireDefault(require("./v5.js"));
99
- var _v5 = _interopRequireDefault(require("./v6.js"));
100
- var _v6ToV = _interopRequireDefault(require("./v6ToV1.js"));
101
- var _v6 = _interopRequireDefault(require("./v7.js"));
102
- var _validate = _interopRequireDefault(require("./validate.js"));
103
- var _version = _interopRequireDefault(require("./version.js"));
104
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -1,7 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _default = exports.default = 'ffffffff-ffff-ffff-ffff-ffffffffffff';