@nocobase/plugin-ai 2.2.18 → 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 (146) hide show
  1. package/dist/ai/tools/knowledge-base-retrieve.js +13 -2
  2. package/dist/ai/tools/subAgentWebSearch.js +10 -6
  3. package/dist/client/index.js +1 -1
  4. package/dist/client-v2/index.js +1 -1
  5. package/dist/externalVersion.js +16 -16
  6. package/dist/node_modules/@langchain/mistralai/dist/index.cjs +2 -2
  7. package/dist/node_modules/@langchain/mistralai/package.json +1 -1
  8. package/dist/node_modules/@langchain/xai/dist/index.cjs +2 -2
  9. package/dist/node_modules/@langchain/xai/package.json +1 -1
  10. package/dist/node_modules/fs-extra/package.json +1 -1
  11. package/dist/node_modules/jsonrepair/package.json +1 -1
  12. package/dist/node_modules/just-bash/dist/bundle/index.cjs +239 -239
  13. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/.gitattributes +4 -0
  14. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/angular-sprintf.min.js +3 -0
  15. package/dist/node_modules/just-bash/node_modules/sprintf-js/dist/sprintf.min.js +3 -0
  16. package/dist/node_modules/just-bash/node_modules/sprintf-js/package.json +35 -0
  17. package/dist/node_modules/just-bash/node_modules/sprintf-js/src/angular-sprintf.js +24 -0
  18. package/dist/node_modules/just-bash/node_modules/sprintf-js/src/sprintf.js +231 -0
  19. package/dist/node_modules/just-bash/package.json +1 -1
  20. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  21. package/dist/node_modules/openai/package.json +1 -1
  22. package/dist/node_modules/zod/package.json +1 -1
  23. package/dist/server/ai-employees/ai-employee.d.ts +15 -1
  24. package/dist/server/ai-employees/ai-employee.js +125 -47
  25. package/dist/server/ai-employees/ai-knowledge-base.d.ts +7 -1
  26. package/dist/server/ai-employees/ai-knowledge-base.js +30 -7
  27. package/dist/server/features/knowledge-base.d.ts +2 -1
  28. package/dist/server/index.d.ts +1 -1
  29. package/dist/server/index.js +2 -0
  30. package/dist/server/llm-providers/anthropic.js +4 -0
  31. package/dist/server/llm-providers/dashscope.js +2 -1
  32. package/dist/server/llm-providers/deepseek/provider.d.ts +2 -1
  33. package/dist/server/llm-providers/deepseek/provider.js +16 -6
  34. package/dist/server/llm-providers/deepseek/reasoning.d.ts +36 -1
  35. package/dist/server/llm-providers/deepseek/reasoning.js +41 -4
  36. package/dist/server/llm-providers/google-genai.js +4 -2
  37. package/dist/server/llm-providers/kimi/provider.js +2 -1
  38. package/dist/server/llm-providers/mimo.js +2 -1
  39. package/dist/server/llm-providers/mistral.d.ts +1 -0
  40. package/dist/server/llm-providers/mistral.js +17 -1
  41. package/dist/server/llm-providers/ollama.js +3 -1
  42. package/dist/server/llm-providers/openai/completions.js +2 -1
  43. package/dist/server/llm-providers/openai/responses.js +2 -1
  44. package/dist/server/llm-providers/orcarouter.js +2 -2
  45. package/dist/server/llm-providers/provider.d.ts +10 -0
  46. package/dist/server/llm-providers/provider.js +34 -1
  47. package/dist/server/llm-providers/shengsuanyun.js +5 -1
  48. package/dist/server/llm-providers/xai.js +6 -1
  49. package/dist/server/manager/ai-manager.d.ts +2 -2
  50. package/dist/server/manager/ai-manager.js +3 -2
  51. package/dist/server/resource/ai.js +4 -0
  52. package/dist/server/types/knowledge-base.type.d.ts +6 -0
  53. package/dist/server/workflow/nodes/llm/index.d.ts +2 -2
  54. package/dist/server/workflow/nodes/llm/index.js +10 -3
  55. package/package.json +2 -2
  56. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/bin/uuid +0 -2
  57. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/index.js +0 -104
  58. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/max.js +0 -7
  59. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/md5.js +0 -200
  60. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/native.js +0 -10
  61. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/nil.js +0 -7
  62. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/parse.js +0 -44
  63. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/regex.js +0 -7
  64. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/rng.js +0 -23
  65. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/sha1.js +0 -82
  66. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/stringify.js +0 -38
  67. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v1.js +0 -131
  68. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v1ToV6.js +0 -26
  69. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v3.js +0 -11
  70. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v35.js +0 -63
  71. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v4.js +0 -32
  72. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v5.js +0 -11
  73. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v6.js +0 -42
  74. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v6ToV1.js +0 -26
  75. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/v7.js +0 -152
  76. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/validate.js +0 -12
  77. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/commonjs-browser/version.js +0 -15
  78. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/index.js +0 -14
  79. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/max.js +0 -1
  80. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/md5.js +0 -194
  81. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/native.js +0 -4
  82. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/nil.js +0 -1
  83. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/parse.js +0 -37
  84. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/regex.js +0 -1
  85. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/rng.js +0 -17
  86. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/sha1.js +0 -76
  87. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/stringify.js +0 -31
  88. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v1.js +0 -125
  89. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v1ToV6.js +0 -20
  90. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v3.js +0 -4
  91. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v35.js +0 -55
  92. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v4.js +0 -25
  93. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v5.js +0 -4
  94. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v6.js +0 -36
  95. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v6ToV1.js +0 -20
  96. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/v7.js +0 -146
  97. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/validate.js +0 -5
  98. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-browser/version.js +0 -8
  99. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/index.js +0 -14
  100. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/max.js +0 -1
  101. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/md5.js +0 -10
  102. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/native.js +0 -4
  103. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/nil.js +0 -1
  104. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/parse.js +0 -37
  105. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/regex.js +0 -1
  106. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/rng.js +0 -10
  107. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/sha1.js +0 -10
  108. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/stringify.js +0 -31
  109. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v1.js +0 -125
  110. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v1ToV6.js +0 -20
  111. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v3.js +0 -4
  112. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v35.js +0 -55
  113. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v4.js +0 -25
  114. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v5.js +0 -4
  115. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v6.js +0 -32
  116. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v6ToV1.js +0 -20
  117. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/v7.js +0 -146
  118. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/validate.js +0 -5
  119. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/esm-node/version.js +0 -8
  120. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/index.js +0 -104
  121. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/max.js +0 -7
  122. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/md5-browser.js +0 -200
  123. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/md5.js +0 -17
  124. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/native-browser.js +0 -10
  125. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/native.js +0 -11
  126. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/nil.js +0 -7
  127. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/parse.js +0 -44
  128. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/regex.js +0 -7
  129. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/rng-browser.js +0 -23
  130. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/rng.js +0 -17
  131. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/sha1-browser.js +0 -82
  132. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/sha1.js +0 -17
  133. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/stringify.js +0 -38
  134. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/uuid-bin.js +0 -75
  135. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v1.js +0 -131
  136. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v1ToV6.js +0 -26
  137. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v3.js +0 -11
  138. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v35.js +0 -63
  139. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v4.js +0 -32
  140. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v5.js +0 -11
  141. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v6.js +0 -38
  142. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v6ToV1.js +0 -26
  143. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/v7.js +0 -152
  144. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/validate.js +0 -12
  145. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/dist/version.js +0 -15
  146. package/dist/node_modules/@langchain/mistralai/node_modules/uuid/package.json +0 -142
@@ -133,9 +133,12 @@ class AIEmployee {
133
133
  return this.employee.toJSON();
134
134
  }
135
135
  async getFormatMessages(userMessages) {
136
- const { provider } = await this.plugin.aiManager.getLLMService({
137
- ...this.model
138
- });
136
+ const { provider } = await this.plugin.aiManager.getLLMService(
137
+ {
138
+ ...this.model
139
+ },
140
+ { sessionId: this.sessionId }
141
+ );
139
142
  const { messages } = await this.aiChatConversation.getChatContext({
140
143
  userMessages,
141
144
  formatMessages: (messages2) => this.formatMessages({ messages: messages2, provider })
@@ -211,9 +214,12 @@ class AIEmployee {
211
214
  userDecisions
212
215
  }) {
213
216
  var _a, _b;
214
- const { provider, model, service } = await this.plugin.aiManager.getLLMService({
215
- ...this.model
216
- });
217
+ const { provider, model, service } = await this.plugin.aiManager.getLLMService(
218
+ {
219
+ ...this.model
220
+ },
221
+ { sessionId: this.sessionId }
222
+ );
217
223
  this.userMessageCount = (userMessages ?? []).filter((message) => message.role === "user").length;
218
224
  const { historyMessages, tools, resolvedTools, middleware, config, state } = await this.initSession({
219
225
  messageId,
@@ -222,12 +228,14 @@ class AIEmployee {
222
228
  providerName: service.provider,
223
229
  llmService: ((_a = service.get) == null ? void 0 : _a.call(service, "name")) || service.name
224
230
  });
231
+ const contextMessages = [...historyMessages, ...userMessages ?? []];
232
+ const knowledgeBaseContext = await this.retrieveKnowledgeBase(contextMessages);
225
233
  const chatContext = await this.aiChatConversation.getChatContext({
226
- userMessages: [...historyMessages, ...userMessages ?? []],
234
+ userMessages: contextMessages,
227
235
  userDecisions,
228
236
  tools: resolvedTools,
229
237
  middleware,
230
- getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2),
238
+ getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2, knowledgeBaseContext),
231
239
  formatMessages: (messages) => this.formatMessages({ messages, provider })
232
240
  });
233
241
  return {
@@ -237,7 +245,8 @@ class AIEmployee {
237
245
  provider,
238
246
  chatContext,
239
247
  config,
240
- state
248
+ state,
249
+ knowledgeBaseDocuments: knowledgeBaseContext.documents
241
250
  };
242
251
  }
243
252
  async stream({
@@ -253,7 +262,7 @@ class AIEmployee {
253
262
  }
254
263
  });
255
264
  try {
256
- const { providerName, llmService, model, provider, chatContext, config, state } = await this.buildChatContext({
265
+ const { providerName, llmService, model, provider, chatContext, config, state, knowledgeBaseDocuments } = await this.buildChatContext({
257
266
  messageId,
258
267
  userMessages,
259
268
  userDecisions
@@ -272,7 +281,8 @@ class AIEmployee {
272
281
  llmService,
273
282
  model,
274
283
  provider,
275
- responseMetadata
284
+ responseMetadata,
285
+ knowledgeBaseDocuments
276
286
  });
277
287
  return true;
278
288
  } catch (err) {
@@ -422,7 +432,23 @@ class AIEmployee {
422
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;
423
433
  const aiMessageIdMap = /* @__PURE__ */ new Map();
424
434
  const persistedAIMessageIdMap = /* @__PURE__ */ new Map();
425
- 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;
426
452
  const reasoningState = new import_reasoning_stream_state.ReasoningStreamState();
427
453
  const stopReasoning = async (conversation) => {
428
454
  if (reasoningState.stop(conversation)) {
@@ -443,7 +469,7 @@ class AIEmployee {
443
469
  try {
444
470
  await stopAllReasoning();
445
471
  if ((gathered == null ? void 0 : gathered.type) === "ai") {
446
- await this.finalizeAbortedAIMessage({
472
+ const result = await this.finalizeAbortedAIMessage({
447
473
  aiMessage: gathered,
448
474
  providerName,
449
475
  provider,
@@ -451,6 +477,9 @@ class AIEmployee {
451
477
  model,
452
478
  knownMessageId: persistedAIMessageIdMap.get(gathered.id)
453
479
  });
480
+ if (result) {
481
+ lastAIMessageId = result.message.messageId;
482
+ }
454
483
  }
455
484
  } catch (e) {
456
485
  this.logger.error("Fail to save message after conversation abort", gathered);
@@ -474,6 +503,10 @@ class AIEmployee {
474
503
  username: this.employee.username
475
504
  };
476
505
  await this.protocol.with(aiEmployeeConversation).startStream();
506
+ if (knowledgeBaseDocuments.length) {
507
+ collectKnowledgeBaseReferences(knowledgeBaseDocuments);
508
+ await this.protocol.with(aiEmployeeConversation).knowledgeBaseReferences({ documents: knowledgeBaseDocuments });
509
+ }
477
510
  for await (const [mode, chunks] of stream) {
478
511
  if (mode === "messages") {
479
512
  const [chunk, metadata] = chunks;
@@ -530,6 +563,9 @@ class AIEmployee {
530
563
  await this.streamCached.skipped();
531
564
  aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
532
565
  persistedAIMessageIdMap.set(chunks.body.id, chunks.body.messageId);
566
+ if (currentConversation.sessionId === this.sessionId) {
567
+ lastAIMessageId = chunks.body.messageId;
568
+ }
533
569
  const data = responseMetadata.get(chunks.body.id);
534
570
  if (data) {
535
571
  const savedMessage = await this.aiMessagesModel.findOne({
@@ -616,6 +652,13 @@ class AIEmployee {
616
652
  await this.protocol.with(currentConversation).newMessage();
617
653
  } else if (chunks.action === "afterSubAgentInvoke") {
618
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 });
619
662
  }
620
663
  }
621
664
  }
@@ -635,11 +678,32 @@ class AIEmployee {
635
678
  }
636
679
  } finally {
637
680
  await abortFinalization;
681
+ await this.saveKnowledgeBaseReferences(lastAIMessageId, Array.from(knowledgeBaseReferences.values()));
638
682
  if (this.from === "main-agent") {
639
683
  this.ctx.res.end();
640
684
  }
641
685
  }
642
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
+ }
643
707
  async handleInterruptedToolCalls(interrupt, getMessageId, onInterrupted) {
644
708
  const interruptId = interrupt == null ? void 0 : interrupt.id;
645
709
  const interruptActions = this.toInterruptActions(interrupt == null ? void 0 : interrupt.value);
@@ -715,14 +779,10 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
715
779
  }
716
780
  return message;
717
781
  }
718
- async getSystemPrompt(userMessages) {
719
- var _a, _b, _c, _d, _e, _f, _g, _h;
720
- if (this.systemPromptMode === "none") {
721
- return "";
722
- }
723
- const about = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
724
- if (this.systemPromptMode === "raw") {
725
- return about;
782
+ async retrieveKnowledgeBase(userMessages) {
783
+ var _a;
784
+ if (this.systemPromptMode !== "default") {
785
+ return { documents: [] };
726
786
  }
727
787
  const employee = this.getAIEmployeeRecord();
728
788
  const knowledgeBaseManager = this.plugin.knowledgeBaseManager;
@@ -731,9 +791,37 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
731
791
  const hasAccessibleKnowledgeBase = knowledgeBaseEnabled ? await knowledgeBaseManager.hasAccessibleKnowledgeBase({ employee, roleNames }) : false;
732
792
  const knowledgeBaseAccessDenied = knowledgeBaseEnabled && !hasAccessibleKnowledgeBase;
733
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
+ }
734
822
  const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
735
823
  filter: {
736
- 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,
737
825
  aiEmployee: this.employee.username
738
826
  }
739
827
  });
@@ -757,25 +845,9 @@ ${workContextBackground.join("\n")}`;
757
845
  background = `${background}
758
846
  ${addSystemPrompt.map((it) => it.content).join("\n")}`;
759
847
  }
760
- let knowledgeBase;
761
- if (knowledgeBaseEnabled && hasAccessibleKnowledgeBase && !knowledgeBaseOnDemand && (userMessages == null ? void 0 : userMessages.length)) {
762
- const lastUserMessage = userMessages.filter((x) => x.role === "user").at(-1);
763
- if (lastUserMessage) {
764
- knowledgeBase = await knowledgeBaseManager.retrievePrompt({
765
- employee,
766
- query: lastUserMessage.content.content,
767
- roleNames
768
- });
769
- }
770
- }
771
- const knowledgeBaseBackgroundPrompt = (0, import_ai_knowledge_base.getKnowledgeBaseBackgroundPrompt)({
772
- accessDenied: knowledgeBaseAccessDenied,
773
- onDemand: knowledgeBaseOnDemand,
774
- preRetrieved: Boolean(knowledgeBase)
775
- });
776
- if (knowledgeBaseBackgroundPrompt) {
848
+ if (knowledgeBaseContext == null ? void 0 : knowledgeBaseContext.backgroundPrompt) {
777
849
  background = `${background}
778
- ${knowledgeBaseBackgroundPrompt}`;
850
+ ${knowledgeBaseContext.backgroundPrompt}`;
779
851
  }
780
852
  const availableSkills = await this.getAvailableSkills();
781
853
  const availableAIEmployees = await this.getAvailableAIEmployees();
@@ -790,20 +862,20 @@ ${knowledgeBaseBackgroundPrompt}`;
790
862
  personal: userConfig == null ? void 0 : userConfig.prompt,
791
863
  environment: {
792
864
  database: this.db.sequelize.getDialect(),
793
- 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",
794
866
  currentDateTime: getCurrentDateTimeForPrompt(
795
867
  await this.aiChatConversation.getCreatedAt(),
796
- (_f = (_e = this.ctx).getCurrentLocale) == null ? void 0 : _f.call(_e),
868
+ (_e = (_d = this.ctx).getCurrentLocale) == null ? void 0 : _e.call(_d),
797
869
  getCurrentTimezone(this.ctx)
798
870
  ),
799
871
  timezone: getCurrentTimezone(this.ctx)
800
872
  },
801
- knowledgeBase,
873
+ knowledgeBase: knowledgeBaseContext == null ? void 0 : knowledgeBaseContext.prompt,
802
874
  availableSkills,
803
875
  availableAIEmployees,
804
876
  webSearch: this.webSearch
805
877
  });
806
- 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) || {};
807
879
  if (important === "GraphRecursionError") {
808
880
  const importantPrompt = `<Important>You have already called tools multiple times and gathered sufficient information.
809
881
  First, provide a summary based on the existing information. Do not call additional tools.
@@ -1186,9 +1258,12 @@ If information is missing, clearly state it in the summary.</Important>`;
1186
1258
  if (!toolMessages || import_lodash.default.isEmpty(toolMessages)) {
1187
1259
  return;
1188
1260
  }
1189
- const { model, service } = await this.plugin.aiManager.getLLMService({
1190
- ...this.model
1191
- });
1261
+ const { model, service } = await this.plugin.aiManager.getLLMService(
1262
+ {
1263
+ ...this.model
1264
+ },
1265
+ { sessionId: this.sessionId }
1266
+ );
1192
1267
  const toolCallMap = await this.getToolCallMap(messageId);
1193
1268
  const now = /* @__PURE__ */ new Date();
1194
1269
  const toolMessageContent = "The user ignored the application for tools usage and will continued to ask questions";
@@ -1802,6 +1877,9 @@ class ChatStreamProtocol {
1802
1877
  subAgentCompleted: async () => {
1803
1878
  await write({ type: "sub_agent_completed" });
1804
1879
  },
1880
+ knowledgeBaseReferences: async (body) => {
1881
+ await write({ type: "knowledge_base_references", body });
1882
+ },
1805
1883
  newMessage: async (content) => {
1806
1884
  await write({ type: "new_message", body: content });
1807
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
  }
@@ -7,7 +7,7 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  export { default } from './plugin';
10
- export { LLMProvider, LLMProviderOptions } from './llm-providers/provider';
10
+ export { LLMProvider, LLMProviderOptions, LLMProviderRequestContext } from './llm-providers/provider';
11
11
  export { LLMProviderMeta } from './manager/ai-manager';
12
12
  export { ToolOptions } from './manager/tool-manager';
13
13
  export { DocumentLoader } from './document-loader';
@@ -41,6 +41,7 @@ __export(server_exports, {
41
41
  LLMProvider: () => import_provider.LLMProvider,
42
42
  LLMProviderMeta: () => import_ai_manager.LLMProviderMeta,
43
43
  LLMProviderOptions: () => import_provider.LLMProviderOptions,
44
+ LLMProviderRequestContext: () => import_provider.LLMProviderRequestContext,
44
45
  ToolOptions: () => import_tool_manager.ToolOptions,
45
46
  default: () => import_plugin.default
46
47
  });
@@ -58,5 +59,6 @@ var import_ai_employee = require("./ai-employees/ai-employee");
58
59
  LLMProvider,
59
60
  LLMProviderMeta,
60
61
  LLMProviderOptions,
62
+ LLMProviderRequestContext,
61
63
  ToolOptions
62
64
  });
@@ -72,6 +72,9 @@ class AnthropicProvider extends import_provider.LLMProvider {
72
72
  ...sanitizedModelOptions,
73
73
  model,
74
74
  anthropicApiUrl: this.getResolvedBaseURL(),
75
+ clientOptions: {
76
+ defaultHeaders: this.getDefaultHeaders()
77
+ },
75
78
  verbose: false
76
79
  });
77
80
  }
@@ -96,6 +99,7 @@ class AnthropicProvider extends import_provider.LLMProvider {
96
99
  method: "GET",
97
100
  url,
98
101
  headers: {
102
+ ...this.getDefaultHeaders(),
99
103
  "x-api-key": apiKey,
100
104
  "anthropic-version": "2023-06-01"
101
105
  }
@@ -83,7 +83,8 @@ class DashscopeProvider extends import_provider.LLMProvider {
83
83
  ...reasoningOptions.modelKwargs || {}
84
84
  },
85
85
  configuration: {
86
- baseURL: this.getResolvedBaseURL()
86
+ baseURL: this.getResolvedBaseURL(),
87
+ defaultHeaders: this.getDefaultHeaders()
87
88
  },
88
89
  verbose: false
89
90
  });
@@ -12,6 +12,7 @@ import { ChatOpenAI } from '@langchain/openai';
12
12
  import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
13
13
  import type OpenAI from 'openai';
14
14
  import { Model } from '@nocobase/database';
15
+ import type { AttachmentModel } from '@nocobase/plugin-file-manager';
15
16
  import { LLMProvider, ReasoningOptions, ResolvedReasoningOptions } from '../provider';
16
17
  import { LLMProviderMeta } from '../../manager/ai-manager';
17
18
  import { DeepSeekReasoningConfig } from './reasoning';
@@ -51,7 +52,7 @@ export declare class DeepSeekProvider extends LLMProvider {
51
52
  }[];
52
53
  protected resolveReasoningOptions(reasoning?: ReasoningOptions): ResolvedReasoningOptions;
53
54
  isToolConflict(): boolean;
54
- protected isApiSupportedAttachment(): boolean;
55
+ protected isApiSupportedAttachment(attachment: AttachmentModel): boolean;
55
56
  }
56
57
  export declare const deepseekProviderOptions: LLMProviderMeta;
57
58
  export {};
@@ -166,7 +166,8 @@ class DeepSeekProvider extends import_provider.LLMProvider {
166
166
  ...reasoningParams
167
167
  },
168
168
  configuration: {
169
- baseURL: this.getResolvedBaseURL()
169
+ baseURL: this.getResolvedBaseURL(),
170
+ defaultHeaders: this.getDefaultHeaders()
170
171
  },
171
172
  verbose: false
172
173
  };
@@ -190,7 +191,8 @@ class DeepSeekProvider extends import_provider.LLMProvider {
190
191
  ...modelOptions,
191
192
  modelKwargs,
192
193
  configuration: {
193
- baseURL: this.getResolvedBaseURL()
194
+ baseURL: this.getResolvedBaseURL(),
195
+ defaultHeaders: this.getDefaultHeaders()
194
196
  },
195
197
  verbose: false
196
198
  },
@@ -299,18 +301,26 @@ class DeepSeekProvider extends import_provider.LLMProvider {
299
301
  isToolConflict() {
300
302
  return false;
301
303
  }
302
- isApiSupportedAttachment() {
303
- return false;
304
+ isApiSupportedAttachment(attachment) {
305
+ var _a, _b;
306
+ const capabilities = (0, import_reasoning2.getDeepSeekModelCapabilities)(String((_a = this.modelOptions) == null ? void 0 : _a.model));
307
+ return (capabilities == null ? void 0 : capabilities.supportsImageInput) === true && (((_b = attachment == null ? void 0 : attachment.mimetype) == null ? void 0 : _b.startsWith("image/")) ?? false);
304
308
  }
305
309
  }
306
310
  const deepseekProviderOptions = {
307
311
  title: "DeepSeek",
308
312
  supportedModel: [import_ai_manager.SupportedModel.LLM],
309
313
  models: {
310
- [import_ai_manager.SupportedModel.LLM]: ["deepseek-v4-pro", "deepseek-v4-flash", "deepseek-chat", "deepseek-reasoner"]
314
+ [import_ai_manager.SupportedModel.LLM]: [
315
+ "deepseek-v4-pro",
316
+ "deepseek-flash",
317
+ "deepseek-v4-flash",
318
+ "deepseek-chat",
319
+ "deepseek-reasoner"
320
+ ]
311
321
  },
312
322
  supportWebSearch: true,
313
- webSearchModels: ["deepseek-v4-flash", "deepseek-v4-pro"],
323
+ webSearchModels: ["deepseek-v4-pro"],
314
324
  provider: DeepSeekProvider
315
325
  };
316
326
  // Annotate the CommonJS export names for ESM import in node:
@@ -20,6 +20,7 @@ type DeepSeekModelCapabilities = {
20
20
  supportsFunctionTools: boolean;
21
21
  supportsStructuredOutput: boolean;
22
22
  supportsWebSearch: boolean;
23
+ supportsImageInput: boolean;
23
24
  };
24
25
  export type DeepSeekReasoningConfig = {
25
26
  protocol: DeepSeekApiProtocol;
@@ -34,6 +35,16 @@ type ReasoningSource = {
34
35
  response_metadata?: Record<string, unknown>;
35
36
  };
36
37
  export declare const DEEPSEEK_MODEL_CAPABILITIES: {
38
+ readonly 'deepseek-flash': {
39
+ readonly protocol: "responses";
40
+ readonly reasoning: "switchable";
41
+ readonly defaultThinking: "enabled";
42
+ readonly efforts: Set<DeepSeekReasoningEffort>;
43
+ readonly supportsFunctionTools: true;
44
+ readonly supportsStructuredOutput: true;
45
+ readonly supportsWebSearch: false;
46
+ readonly supportsImageInput: true;
47
+ };
37
48
  readonly 'deepseek-v4-flash': {
38
49
  readonly protocol: "responses";
39
50
  readonly reasoning: "switchable";
@@ -41,7 +52,28 @@ export declare const DEEPSEEK_MODEL_CAPABILITIES: {
41
52
  readonly efforts: Set<DeepSeekReasoningEffort>;
42
53
  readonly supportsFunctionTools: true;
43
54
  readonly supportsStructuredOutput: true;
44
- readonly supportsWebSearch: true;
55
+ readonly supportsWebSearch: false;
56
+ readonly supportsImageInput: true;
57
+ };
58
+ readonly 'deepseek-v4-flash-vision-exp': {
59
+ readonly protocol: "responses";
60
+ readonly reasoning: "switchable";
61
+ readonly defaultThinking: "enabled";
62
+ readonly efforts: Set<DeepSeekReasoningEffort>;
63
+ readonly supportsFunctionTools: true;
64
+ readonly supportsStructuredOutput: true;
65
+ readonly supportsWebSearch: false;
66
+ readonly supportsImageInput: true;
67
+ };
68
+ readonly 'deepseek-v4.1-flash': {
69
+ readonly protocol: "responses";
70
+ readonly reasoning: "switchable";
71
+ readonly defaultThinking: "enabled";
72
+ readonly efforts: Set<DeepSeekReasoningEffort>;
73
+ readonly supportsFunctionTools: true;
74
+ readonly supportsStructuredOutput: true;
75
+ readonly supportsWebSearch: false;
76
+ readonly supportsImageInput: true;
45
77
  };
46
78
  readonly 'deepseek-v4-pro': {
47
79
  readonly protocol: "responses";
@@ -51,6 +83,7 @@ export declare const DEEPSEEK_MODEL_CAPABILITIES: {
51
83
  readonly supportsFunctionTools: true;
52
84
  readonly supportsStructuredOutput: true;
53
85
  readonly supportsWebSearch: true;
86
+ readonly supportsImageInput: false;
54
87
  };
55
88
  readonly 'deepseek-chat': {
56
89
  readonly protocol: "chat-completions";
@@ -60,6 +93,7 @@ export declare const DEEPSEEK_MODEL_CAPABILITIES: {
60
93
  readonly supportsFunctionTools: true;
61
94
  readonly supportsStructuredOutput: true;
62
95
  readonly supportsWebSearch: false;
96
+ readonly supportsImageInput: false;
63
97
  };
64
98
  readonly 'deepseek-reasoner': {
65
99
  readonly protocol: "chat-completions";
@@ -69,6 +103,7 @@ export declare const DEEPSEEK_MODEL_CAPABILITIES: {
69
103
  readonly supportsFunctionTools: true;
70
104
  readonly supportsStructuredOutput: true;
71
105
  readonly supportsWebSearch: false;
106
+ readonly supportsImageInput: false;
72
107
  };
73
108
  };
74
109
  export type OfficialDeepSeekModel = keyof typeof DEEPSEEK_MODEL_CAPABILITIES;