@nocobase/plugin-ai 2.1.0-beta.29 → 2.1.0-beta.32

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 (159) hide show
  1. package/client-v2.d.ts +1 -0
  2. package/client-v2.js +1 -0
  3. package/dist/ai/docs/nocobase/ai/index.md +1 -1
  4. package/dist/ai/docs/nocobase/ai-employees/built-in/atlas.md +24 -0
  5. package/dist/ai/docs/nocobase/ai-employees/built-in/dara.md +22 -0
  6. package/dist/ai/docs/nocobase/ai-employees/built-in/dex.md +32 -0
  7. package/dist/ai/docs/nocobase/ai-employees/built-in/ellis.md +22 -0
  8. package/dist/ai/docs/nocobase/ai-employees/built-in/index.md +25 -0
  9. package/dist/ai/docs/nocobase/ai-employees/built-in/lexi.md +26 -0
  10. package/dist/ai/docs/nocobase/ai-employees/built-in/lina.md +142 -0
  11. package/dist/ai/docs/nocobase/ai-employees/built-in/nathan.md +36 -0
  12. package/dist/ai/docs/nocobase/ai-employees/built-in/vera.md +22 -0
  13. package/dist/ai/docs/nocobase/ai-employees/built-in/viz.md +25 -0
  14. package/dist/ai/docs/nocobase/ai-employees/features/built-in-employee.md +1 -29
  15. package/dist/ai/docs/nocobase/ai-employees/features/collaborate.md +17 -7
  16. package/dist/ai/docs/nocobase/ai-employees/features/enable-ai-employee.md +4 -4
  17. package/dist/ai/docs/nocobase/ai-employees/features/model-settings.md +87 -0
  18. package/dist/ai/docs/nocobase/ai-employees/index.md +1 -1
  19. package/dist/ai/docs/nocobase/ai-employees/scenarios/localization-hy-mt.md +241 -0
  20. package/dist/ai/docs/nocobase/ai-employees/workflow/nodes/employee/configuration.md +1 -1
  21. package/dist/ai/docs/nocobase/api/cli/api/dynamic.md +7 -0
  22. package/dist/ai/docs/nocobase/api/cli/api/resource/index.md +3 -0
  23. package/dist/ai/docs/nocobase/api/cli/app/down.md +7 -3
  24. package/dist/ai/docs/nocobase/api/cli/app/index.md +1 -1
  25. package/dist/ai/docs/nocobase/api/cli/app/logs.md +3 -0
  26. package/dist/ai/docs/nocobase/api/cli/app/restart.md +4 -0
  27. package/dist/ai/docs/nocobase/api/cli/app/start.md +4 -0
  28. package/dist/ai/docs/nocobase/api/cli/app/stop.md +3 -0
  29. package/dist/ai/docs/nocobase/api/cli/app/upgrade.md +5 -0
  30. package/dist/ai/docs/nocobase/api/cli/env/add.md +11 -3
  31. package/dist/ai/docs/nocobase/api/cli/env/auth.md +1 -1
  32. package/dist/ai/docs/nocobase/api/cli/env/current.md +29 -0
  33. package/dist/ai/docs/nocobase/api/cli/env/index.md +22 -4
  34. package/dist/ai/docs/nocobase/api/cli/env/info.md +1 -5
  35. package/dist/ai/docs/nocobase/api/cli/env/list.md +11 -6
  36. package/dist/ai/docs/nocobase/api/cli/env/remove.md +4 -1
  37. package/dist/ai/docs/nocobase/api/cli/env/status.md +52 -0
  38. package/dist/ai/docs/nocobase/api/cli/env/update.md +1 -1
  39. package/dist/ai/docs/nocobase/api/cli/env/use.md +11 -1
  40. package/dist/ai/docs/nocobase/api/cli/index.md +13 -1
  41. package/dist/ai/docs/nocobase/api/cli/license/activate.md +4 -1
  42. package/dist/ai/docs/nocobase/api/cli/license/id.md +4 -0
  43. package/dist/ai/docs/nocobase/api/cli/license/plugins/clean.md +5 -1
  44. package/dist/ai/docs/nocobase/api/cli/license/plugins/list.md +4 -0
  45. package/dist/ai/docs/nocobase/api/cli/license/plugins/sync.md +5 -1
  46. package/dist/ai/docs/nocobase/api/cli/license/status.md +4 -0
  47. package/dist/ai/docs/nocobase/api/cli/plugin/disable.md +4 -0
  48. package/dist/ai/docs/nocobase/api/cli/plugin/enable.md +4 -0
  49. package/dist/ai/docs/nocobase/api/cli/plugin/list.md +4 -0
  50. package/dist/ai/docs/nocobase/api/cli/session/id.md +28 -0
  51. package/dist/ai/docs/nocobase/api/cli/session/index.md +41 -0
  52. package/dist/ai/docs/nocobase/api/cli/session/remove.md +35 -0
  53. package/dist/ai/docs/nocobase/api/cli/session/setup.md +47 -0
  54. package/dist/ai/docs/nocobase/interface-builder/actions/types/js-action.md +1 -1
  55. package/dist/ai/docs/nocobase/interface-builder/actions/types/js-item.md +1 -1
  56. package/dist/ai/docs/nocobase/interface-builder/blocks/other-blocks/js-block.md +1 -1
  57. package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-column.md +1 -1
  58. package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-field.md +1 -1
  59. package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-item.md +1 -1
  60. package/dist/ai/docs/nocobase/security/guide.md +13 -1
  61. package/dist/ai/docs/nocobase/system-management/localization/index.md +25 -1
  62. package/dist/client/119.c6bf8c6433167d81.js +10 -0
  63. package/dist/client/228.b4b709f93b86b6b9.js +10 -0
  64. package/dist/client/462.1708385b148779cd.js +10 -0
  65. package/dist/client/{486.afbed6b132b3c0dd.js → 486.dcac8f3fcec19c33.js} +1 -1
  66. package/dist/client/{559.39872901b9053629.js → 559.585f80c3bcea0bed.js} +1 -1
  67. package/dist/client/597.b0d64948d74cf6cb.js +10 -0
  68. package/dist/client/646.b0ed728921b007d4.js +10 -0
  69. package/dist/client/711.92cd94681fde7e05.js +10 -0
  70. package/dist/client/768.5177bff46ae71a5b.js +10 -0
  71. package/dist/client/792.abb57765453bcbcc.js +10 -0
  72. package/dist/client/820.f72ef2462b61d812.js +10 -0
  73. package/dist/client/927.d95c74ebb8fd51c9.js +10 -0
  74. package/dist/client/ai-employees/admin/ModelSettings.d.ts +10 -0
  75. package/dist/client/ai-employees/admin/hooks.d.ts +1 -1
  76. package/dist/client/ai-employees/avatars.d.ts +9 -783
  77. package/dist/client/ai-employees/chatbox/conversations/ConversationsList.d.ts +1 -15
  78. package/dist/client/ai-employees/chatbox/conversations/WorkflowTasksList.d.ts +1 -21
  79. package/dist/client/ai-employees/chatbox/hooks/useChat.d.ts +125 -0
  80. package/dist/client/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +1 -1
  81. package/dist/client/ai-employees/chatbox/hooks/useChatConversationActions.d.ts +13 -1
  82. package/dist/client/ai-employees/chatbox/hooks/useChatMessageActions.d.ts +8 -8
  83. package/dist/client/ai-employees/chatbox/model.d.ts +6 -3
  84. package/dist/client/ai-employees/chatbox/stores/chat-conversations.d.ts +4 -0
  85. package/dist/client/ai-employees/chatbox/stores/chat-messages.d.ts +77 -50
  86. package/dist/client/ai-employees/chatbox/stores/chat-tool-call.d.ts +24 -16
  87. package/dist/client/ai-employees/types.d.ts +24 -0
  88. package/dist/client/features/vector-database-provider.d.ts +1 -1
  89. package/dist/client/index.d.ts +2 -0
  90. package/dist/client/index.js +3 -3
  91. package/dist/client/llm-services/component/EnabledModelsSelect.d.ts +1 -14
  92. package/dist/client-v2/ai-employees/AIEmployeeShortcut.d.ts +21 -0
  93. package/dist/client-v2/ai-employees/ProfileCard.d.ts +17 -0
  94. package/dist/client-v2/ai-employees/avatars.d.ts +783 -0
  95. package/dist/client-v2/ai-employees/types.d.ts +20 -0
  96. package/dist/client-v2/index.d.ts +17 -0
  97. package/dist/client-v2/index.js +10 -0
  98. package/dist/client-v2/llm-services/model-label.d.ts +22 -0
  99. package/dist/collections/ai-employees.d.ts +2 -1
  100. package/dist/collections/ai-employees.js +1 -1
  101. package/dist/externalVersion.js +17 -16
  102. package/dist/locale/en-US.json +16 -1
  103. package/dist/locale/zh-CN.json +16 -1
  104. package/dist/node_modules/@langchain/xai/package.json +1 -1
  105. package/dist/node_modules/fs-extra/package.json +1 -1
  106. package/dist/node_modules/jsonrepair/package.json +1 -1
  107. package/dist/node_modules/just-bash/package.json +1 -1
  108. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  109. package/dist/node_modules/openai/package.json +1 -1
  110. package/dist/node_modules/zod/package.json +1 -1
  111. package/dist/server/ai-employees/ai-conversations.d.ts +4 -1
  112. package/dist/server/ai-employees/ai-conversations.js +44 -4
  113. package/dist/server/ai-employees/ai-employee.d.ts +31 -15
  114. package/dist/server/ai-employees/ai-employee.js +205 -52
  115. package/dist/server/ai-employees/ai-employees-manager.d.ts +4 -0
  116. package/dist/server/ai-employees/ai-employees-manager.js +41 -0
  117. package/dist/server/ai-employees/ai-knowledge-base.js +7 -7
  118. package/dist/server/ai-employees/middleware/conversation.d.ts +1 -0
  119. package/dist/server/ai-employees/middleware/conversation.js +15 -11
  120. package/dist/server/ai-employees/sub-agents/dispatcher.js +2 -4
  121. package/dist/server/ai-employees/utils.d.ts +6 -3
  122. package/dist/server/ai-employees/utils.js +7 -1
  123. package/dist/server/collections/ai-conversations.js +6 -0
  124. package/dist/server/features/knowledge-base.d.ts +3 -2
  125. package/dist/server/index.d.ts +2 -0
  126. package/dist/server/index.js +3 -0
  127. package/dist/server/llm-providers/common/reasoning.d.ts +2 -0
  128. package/dist/server/llm-providers/common/reasoning.js +15 -2
  129. package/dist/server/llm-providers/dashscope.d.ts +2 -1
  130. package/dist/server/llm-providers/dashscope.js +39 -0
  131. package/dist/server/llm-providers/deepseek.js +2 -0
  132. package/dist/server/llm-providers/provider.d.ts +15 -1
  133. package/dist/server/llm-providers/provider.js +21 -2
  134. package/dist/server/manager/ai-chat-conversation.js +3 -4
  135. package/dist/server/manager/ai-manager.d.ts +17 -0
  136. package/dist/server/manager/ai-manager.js +65 -0
  137. package/dist/server/manager/llm-stream-manager.d.ts +37 -0
  138. package/dist/server/manager/llm-stream-manager.js +142 -0
  139. package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.d.ts +14 -0
  140. package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.js +61 -0
  141. package/dist/server/plugin.d.ts +2 -0
  142. package/dist/server/plugin.js +3 -0
  143. package/dist/server/resource/ai.js +1 -41
  144. package/dist/server/resource/aiConversations.d.ts +8 -0
  145. package/dist/server/resource/aiConversations.js +141 -10
  146. package/dist/server/resource/aiEmployees.js +32 -1
  147. package/dist/server/types/knowledge-base.type.d.ts +3 -2
  148. package/dist/server/workflow/nodes/employee/index.js +4 -2
  149. package/package.json +2 -2
  150. package/dist/client/119.78774f3ad953af49.js +0 -10
  151. package/dist/client/228.a3df2921c8beb766.js +0 -10
  152. package/dist/client/343.6f36d97dd122c5b6.js +0 -10
  153. package/dist/client/597.aa363881a325b5c0.js +0 -10
  154. package/dist/client/646.217a40387efbd163.js +0 -10
  155. package/dist/client/711.266b8f1c520d467a.js +0 -10
  156. package/dist/client/768.973ce32e15099a48.js +0 -10
  157. package/dist/client/792.2e48eab4767d662a.js +0 -10
  158. package/dist/client/820.6a26239ea96c075a.js +0 -10
  159. package/dist/client/927.ff5cd05b14901ae6.js +0 -10
@@ -45,6 +45,7 @@ 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");
48
49
  var import_middleware = require("./middleware");
49
50
  var import_ai = require("@nocobase/ai");
50
51
  var import_checkpoints = require("./checkpoints");
@@ -70,6 +71,7 @@ class AIEmployee {
70
71
  legacy;
71
72
  tools;
72
73
  inWorkflow;
74
+ streamCached;
73
75
  constructor({
74
76
  ctx,
75
77
  employee,
@@ -94,10 +96,30 @@ class AIEmployee {
94
96
  this.legacy = legacy;
95
97
  this.from = from;
96
98
  this.tools = tools;
99
+ this.streamCached = this.plugin.llmStreamCachedManager.getCached(sessionId);
97
100
  const builtInManager = this.plugin.builtInManager;
98
101
  builtInManager.setupBuiltInInfo(ctx, this.employee);
99
102
  this.webSearch = webSearch;
100
- this.protocol = ChatStreamProtocol.fromContext(ctx);
103
+ this.protocol = ChatStreamProtocol.fromContext(ctx, async (chunk) => {
104
+ try {
105
+ await this.streamCached.append(chunk);
106
+ } catch (error) {
107
+ this.logger.warn("Failed to append LLM stream cache", { sessionId: this.sessionId, error });
108
+ }
109
+ });
110
+ }
111
+ get chatSettings() {
112
+ var _a, _b, _c;
113
+ return ((_b = (_a = this.employee) == null ? void 0 : _a.get) == null ? void 0 : _b.call(_a, "chatSettings")) ?? ((_c = this.employee) == null ? void 0 : _c.chatSettings) ?? {};
114
+ }
115
+ get systemPromptMode() {
116
+ return this.chatSettings.systemPromptMode ?? "default";
117
+ }
118
+ areSkillsEnabled() {
119
+ return this.chatSettings.enableSkills !== false;
120
+ }
121
+ areToolsEnabled() {
122
+ return this.chatSettings.enableTools !== false;
101
123
  }
102
124
  async getFormatMessages(userMessages) {
103
125
  const { provider } = await this.plugin.aiManager.getLLMService({
@@ -128,7 +150,7 @@ class AIEmployee {
128
150
  }
129
151
  };
130
152
  }
131
- async initSession({ messageId, provider, model, providerName }) {
153
+ async initSession({ messageId, provider, model, providerName, llmService }) {
132
154
  const { tools, baseToolNames } = await this.getAgentTools();
133
155
  const resolvedTools = provider.resolveTools(tools.map(import_utils.buildTool));
134
156
  if (!messageId && this.legacy !== true) {
@@ -136,7 +158,7 @@ class AIEmployee {
136
158
  historyMessages: [],
137
159
  tools,
138
160
  resolvedTools,
139
- middleware: await this.getMiddleware({ tools, baseToolNames, model, providerName }),
161
+ middleware: await this.getMiddleware({ tools, baseToolNames, model, providerName, llmService }),
140
162
  config: void 0,
141
163
  state: void 0
142
164
  };
@@ -154,6 +176,7 @@ class AIEmployee {
154
176
  baseToolNames,
155
177
  model,
156
178
  providerName,
179
+ llmService,
157
180
  messageId,
158
181
  agentThread
159
182
  }),
@@ -170,6 +193,7 @@ class AIEmployee {
170
193
  userMessages,
171
194
  userDecisions
172
195
  }) {
196
+ var _a, _b;
173
197
  const { provider, model, service } = await this.plugin.aiManager.getLLMService({
174
198
  ...this.model
175
199
  });
@@ -177,7 +201,8 @@ class AIEmployee {
177
201
  messageId,
178
202
  provider,
179
203
  model,
180
- providerName: service.provider
204
+ providerName: service.provider,
205
+ llmService: ((_a = service.get) == null ? void 0 : _a.call(service, "name")) || service.name
181
206
  });
182
207
  const chatContext = await this.aiChatConversation.getChatContext({
183
208
  userMessages: [...historyMessages, ...userMessages ?? []],
@@ -187,13 +212,22 @@ class AIEmployee {
187
212
  getSystemPrompt: (userMessages2) => this.getSystemPrompt(userMessages2),
188
213
  formatMessages: (messages) => this.formatMessages({ messages, provider })
189
214
  });
190
- return { providerName: service.provider, model, provider, chatContext, config, state };
215
+ return {
216
+ providerName: service.provider,
217
+ llmService: ((_b = service.get) == null ? void 0 : _b.call(service, "name")) || service.name,
218
+ model,
219
+ provider,
220
+ chatContext,
221
+ config,
222
+ state
223
+ };
191
224
  }
192
225
  async stream({
193
226
  messageId,
194
227
  userMessages = [],
195
228
  userDecisions
196
229
  }) {
230
+ await this.streamCached.clear();
197
231
  await this.aiConversationsRepo.update({
198
232
  values: { llmActiveState: "streaming" },
199
233
  filter: {
@@ -201,7 +235,7 @@ class AIEmployee {
201
235
  }
202
236
  });
203
237
  try {
204
- const { providerName, model, provider, chatContext, config, state } = await this.buildChatContext({
238
+ const { providerName, llmService, model, provider, chatContext, config, state } = await this.buildChatContext({
205
239
  messageId,
206
240
  userMessages,
207
241
  userDecisions
@@ -217,6 +251,7 @@ class AIEmployee {
217
251
  await this.processChatStream(stream, {
218
252
  signal,
219
253
  providerName,
254
+ llmService,
220
255
  model,
221
256
  provider,
222
257
  responseMetadata
@@ -228,11 +263,12 @@ class AIEmployee {
228
263
  return false;
229
264
  } finally {
230
265
  await this.aiConversationsRepo.update({
231
- values: { llmActiveState: "idle" },
266
+ values: { llmActiveState: "idle", read: false },
232
267
  filter: {
233
268
  sessionId: this.sessionId
234
269
  }
235
270
  });
271
+ await this.streamCached.clear();
236
272
  }
237
273
  }
238
274
  async invoke({
@@ -365,7 +401,7 @@ class AIEmployee {
365
401
  async processChatStream(stream, options) {
366
402
  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;
367
403
  const aiMessageIdMap = /* @__PURE__ */ new Map();
368
- const { signal, providerName, model, provider, responseMetadata, allowEmpty = false } = options;
404
+ const { signal, providerName, llmService, model, provider, responseMetadata, allowEmpty = false } = options;
369
405
  let isReasoning = false;
370
406
  let gathered;
371
407
  signal.addEventListener("abort", async () => {
@@ -374,6 +410,7 @@ class AIEmployee {
374
410
  const values = (0, import_utils2.convertAIMessage)({
375
411
  aiEmployee: this,
376
412
  providerName,
413
+ llmService,
377
414
  model,
378
415
  aiMessage: gathered
379
416
  });
@@ -386,6 +423,14 @@ class AIEmployee {
386
423
  }
387
424
  } catch (e) {
388
425
  this.logger.error("Fail to save message after conversation abort", gathered);
426
+ } finally {
427
+ await this.aiConversationsRepo.update({
428
+ values: { llmActiveState: "idle", read: true },
429
+ filter: {
430
+ sessionId: this.sessionId
431
+ }
432
+ });
433
+ await this.streamCached.clear();
389
434
  }
390
435
  });
391
436
  try {
@@ -394,7 +439,7 @@ class AIEmployee {
394
439
  from: this.from,
395
440
  username: this.employee.username
396
441
  };
397
- this.protocol.with(aiEmployeeConversation).startStream();
442
+ await this.protocol.with(aiEmployeeConversation).startStream();
398
443
  for await (const [mode, chunks] of stream) {
399
444
  if (mode === "messages") {
400
445
  const [chunk, metadata] = chunks;
@@ -404,24 +449,24 @@ class AIEmployee {
404
449
  if (chunk.content) {
405
450
  if (isReasoning) {
406
451
  isReasoning = false;
407
- this.protocol.with(currentConversation).stopReasoning();
452
+ await this.protocol.with(currentConversation).stopReasoning();
408
453
  }
409
454
  const parsedContent = provider.parseResponseChunk(chunk.content);
410
455
  if (parsedContent) {
411
- this.protocol.with(currentConversation).content(parsedContent);
456
+ await this.protocol.with(currentConversation).content(parsedContent);
412
457
  }
413
458
  }
414
459
  if ((_a = chunk.tool_call_chunks) == null ? void 0 : _a.length) {
415
- this.protocol.with(currentConversation).toolCallChunks(chunk.tool_call_chunks);
460
+ await this.protocol.with(currentConversation).toolCallChunks(chunk.tool_call_chunks);
416
461
  }
417
462
  const webSearch = provider.parseWebSearchAction(chunk);
418
463
  if (webSearch == null ? void 0 : webSearch.length) {
419
- this.protocol.with(currentConversation).webSearch(webSearch);
464
+ await this.protocol.with(currentConversation).webSearch(webSearch);
420
465
  }
421
466
  const reasoningContent = provider.parseReasoningContent(chunk);
422
467
  if (reasoningContent) {
423
468
  isReasoning = true;
424
- this.protocol.with(currentConversation).reasoning(reasoningContent);
469
+ await this.protocol.with(currentConversation).reasoning(reasoningContent);
425
470
  }
426
471
  }
427
472
  } else if (mode === "updates") {
@@ -431,8 +476,8 @@ class AIEmployee {
431
476
  await this.handleInterruptedToolCalls(
432
477
  interrupt,
433
478
  (sessionId) => aiMessageIdMap.get(sessionId),
434
- ({ messageId, interruptAction, toolCall, currentConversation }) => {
435
- this.protocol.with(currentConversation).toolCallStatus({
479
+ async ({ messageId, interruptAction, toolCall, currentConversation }) => {
480
+ await this.protocol.with(currentConversation).toolCallStatus({
436
481
  toolCall: {
437
482
  messageId,
438
483
  id: toolCall.id,
@@ -448,6 +493,7 @@ class AIEmployee {
448
493
  } else if (mode === "custom") {
449
494
  const { currentConversation } = chunks;
450
495
  if (chunks.action === "AfterAIMessageSaved") {
496
+ await this.streamCached.skipped();
451
497
  aiMessageIdMap.set(currentConversation.sessionId, chunks.body.messageId);
452
498
  const data = responseMetadata.get(chunks.body.id);
453
499
  if (data) {
@@ -476,11 +522,11 @@ class AIEmployee {
476
522
  }
477
523
  }
478
524
  } else if (chunks.action === "initToolCalls") {
479
- this.protocol.with(currentConversation).toolCalls(chunks.body);
525
+ await this.protocol.with(currentConversation).toolCalls(chunks.body);
480
526
  } else if (chunks.action === "beforeToolCall") {
481
527
  const toolsMap = await this.getToolsMap();
482
528
  const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_d = (_c = chunks.body) == null ? void 0 : _c.toolCall) == null ? void 0 : _d.name));
483
- this.protocol.with(currentConversation).toolCallStatus({
529
+ await this.protocol.with(currentConversation).toolCallStatus({
484
530
  toolCall: {
485
531
  messageId: (_f = (_e = chunks.body) == null ? void 0 : _e.toolCall) == null ? void 0 : _f.messageId,
486
532
  id: (_h = (_g = chunks.body) == null ? void 0 : _g.toolCall) == null ? void 0 : _h.id,
@@ -492,7 +538,7 @@ class AIEmployee {
492
538
  } else if (chunks.action === "afterToolCall") {
493
539
  const toolsMap = await this.getToolsMap();
494
540
  const willInterrupt = this.shouldInterruptToolCall(toolsMap.get((_l = (_k = chunks.body) == null ? void 0 : _k.toolCall) == null ? void 0 : _l.name));
495
- this.protocol.with(currentConversation).toolCallStatus({
541
+ await this.protocol.with(currentConversation).toolCallStatus({
496
542
  toolCall: {
497
543
  messageId: (_n = (_m = chunks.body) == null ? void 0 : _m.toolCall) == null ? void 0 : _n.messageId,
498
544
  id: (_p = (_o = chunks.body) == null ? void 0 : _o.toolCall) == null ? void 0 : _p.id,
@@ -516,7 +562,7 @@ class AIEmployee {
516
562
  for (const { metadata } of messages) {
517
563
  const tools = toolsMap.get(metadata.toolName);
518
564
  const toolCallResult = toolCallResultMap.get(metadata.toolCallId);
519
- this.protocol.with(currentConversation).toolCallStatus({
565
+ await this.protocol.with(currentConversation).toolCallStatus({
520
566
  toolCall: {
521
567
  messageId,
522
568
  id: metadata.toolCallId,
@@ -531,9 +577,9 @@ class AIEmployee {
531
577
  });
532
578
  }
533
579
  }
534
- this.protocol.with(currentConversation).newMessage();
580
+ await this.protocol.with(currentConversation).newMessage();
535
581
  } else if (chunks.action === "afterSubAgentInvoke") {
536
- this.protocol.with(currentConversation).subAgentCompleted();
582
+ await this.protocol.with(currentConversation).subAgentCompleted();
537
583
  }
538
584
  }
539
585
  }
@@ -541,7 +587,7 @@ class AIEmployee {
541
587
  this.sendErrorResponse("Empty message");
542
588
  return;
543
589
  }
544
- this.protocol.with(aiEmployeeConversation).endStream();
590
+ await this.protocol.with(aiEmployeeConversation).endStream();
545
591
  } catch (err) {
546
592
  this.ctx.log.error(err);
547
593
  if (err.name === "GraphRecursionError") {
@@ -632,13 +678,19 @@ Field: ${field.name}, Title: ${(_a = field.options.uiSchema) == null ? void 0 :
632
678
  }
633
679
  async getSystemPrompt(userMessages) {
634
680
  var _a, _b, _c, _d, _e, _f, _g;
681
+ if (this.systemPromptMode === "none") {
682
+ return "";
683
+ }
684
+ const about = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
685
+ if (this.systemPromptMode === "raw") {
686
+ return about;
687
+ }
635
688
  const userConfig = await this.db.getRepository("usersAiEmployees").findOne({
636
689
  filter: {
637
690
  userId: ((_a = this.ctx.auth) == null ? void 0 : _a.user.id) ?? 0,
638
691
  aiEmployee: this.employee.username
639
692
  }
640
693
  });
641
- const about = await (0, import_utils.parseVariables)(this.ctx, this.employee.about ?? this.employee.defaultPrompt ?? "");
642
694
  let background = "";
643
695
  if (this.systemMessage) {
644
696
  background = await (0, import_utils.parseVariables)(this.ctx, this.systemMessage);
@@ -702,6 +754,92 @@ If information is missing, clearly state it in the summary.</Important>`;
702
754
  return systemPrompt;
703
755
  }
704
756
  }
757
+ async retrieveKnowledgeBase(userMessage) {
758
+ const vectorStoreProvider = this.plugin.features.vectorStoreProvider;
759
+ let queryResult = [];
760
+ const queryString = userMessage.content.content;
761
+ if (!queryString || import_lodash.default.isEmpty(queryString)) {
762
+ return queryResult;
763
+ }
764
+ const { topK, score } = this.getAIEmployeeKnowledgeBaseConfig();
765
+ const knowledgeBaseGroup = await this.getKnowledgeBaseGroup();
766
+ for (const entry of knowledgeBaseGroup) {
767
+ const { vectorStoreConfig, knowledgeBaseType, knowledgeBaseList } = entry;
768
+ if (!knowledgeBaseList || import_lodash.default.isEmpty(knowledgeBaseList)) {
769
+ continue;
770
+ }
771
+ if (knowledgeBaseType === "LOCAL") {
772
+ const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
773
+ vectorStoreConfig.vectorStoreProvider,
774
+ [
775
+ {
776
+ key: "vectorStoreConfigKey",
777
+ value: vectorStoreConfig.vectorStoreConfigKey
778
+ }
779
+ ]
780
+ );
781
+ const knowledgeBaseOuterIds = knowledgeBaseList.map((x) => x.knowledgeBaseOuterId);
782
+ const result = await vectorStoreService.search(queryString, {
783
+ topK,
784
+ score,
785
+ filter: {
786
+ knowledgeBaseOuterId: { in: knowledgeBaseOuterIds }
787
+ }
788
+ });
789
+ queryResult = [...queryResult, ...result];
790
+ } else if (knowledgeBaseType === "READONLY") {
791
+ for (const knowledgeBase of knowledgeBaseList) {
792
+ const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
793
+ vectorStoreConfig.vectorStoreProvider,
794
+ [
795
+ ...knowledgeBase.vectorStoreProps,
796
+ {
797
+ key: "vectorStoreConfigKey",
798
+ value: vectorStoreConfig.vectorStoreConfigKey
799
+ }
800
+ ]
801
+ );
802
+ const result = await vectorStoreService.search(queryString, {
803
+ topK,
804
+ score
805
+ });
806
+ queryResult = [...queryResult, ...result];
807
+ }
808
+ } else if (knowledgeBaseType === "EXTERNAL") {
809
+ for (const knowledgeBase of knowledgeBaseList) {
810
+ const vectorStoreService = await vectorStoreProvider.createVectorStoreService(
811
+ vectorStoreConfig.vectorStoreProvider,
812
+ knowledgeBase.vectorStoreProps
813
+ );
814
+ const result = await vectorStoreService.search(queryString, {
815
+ topK,
816
+ score
817
+ });
818
+ queryResult = [...queryResult, ...result];
819
+ }
820
+ }
821
+ }
822
+ return queryResult;
823
+ }
824
+ isEnabledKnowledgeBase() {
825
+ const featureEnabled = this.plugin.features.isFeaturesEnabled(Object.values(import_ai_feature_manager.EEFeatures));
826
+ const knowledgeBaseEnabled = this.employee.enableKnowledgeBase;
827
+ return featureEnabled && knowledgeBaseEnabled;
828
+ }
829
+ getAIEmployeeKnowledgeBaseConfig() {
830
+ const { topK, score } = this.employee.knowledgeBase ?? {};
831
+ return {
832
+ topK,
833
+ score
834
+ };
835
+ }
836
+ async getKnowledgeBaseGroup() {
837
+ const { knowledgeBaseKeys } = this.employee.knowledgeBase ?? {};
838
+ if (!knowledgeBaseKeys || import_lodash.default.isEmpty(knowledgeBaseKeys)) {
839
+ return [];
840
+ }
841
+ return await this.plugin.features.knowledgeBase.getKnowledgeBaseGroup(knowledgeBaseKeys);
842
+ }
705
843
  // === Tool calls ===
706
844
  async initToolCall(transaction, messageId, toolCalls) {
707
845
  const nowTime = /* @__PURE__ */ new Date();
@@ -1128,6 +1266,9 @@ If information is missing, clearly state it in the summary.</Important>`;
1128
1266
  }
1129
1267
  async getAIEmployeeTools() {
1130
1268
  var _a;
1269
+ if (!this.areToolsEnabled()) {
1270
+ return [];
1271
+ }
1131
1272
  const tools = await this.listTools({ scope: "GENERAL" });
1132
1273
  if (this.webSearch === true) {
1133
1274
  const subAgentWebSearch = await this.toolsManager.getTools(import_ai.SYSTEM_TOOLS.WEB_SEARCH);
@@ -1172,6 +1313,9 @@ If information is missing, clearly state it in the summary.</Important>`;
1172
1313
  }
1173
1314
  async getAvailableSkills() {
1174
1315
  var _a;
1316
+ if (!this.areSkillsEnabled()) {
1317
+ return [];
1318
+ }
1175
1319
  const { skillsManager } = this.plugin.ai;
1176
1320
  const aIEmployeeTools = await this.getAIEmployeeTools();
1177
1321
  const getSkill = aIEmployeeTools.find((it) => it.definition.name === "getSkill");
@@ -1197,6 +1341,12 @@ If information is missing, clearly state it in the summary.</Important>`;
1197
1341
  }
1198
1342
  }
1199
1343
  async getAgentTools() {
1344
+ if (!this.areToolsEnabled()) {
1345
+ return {
1346
+ tools: [],
1347
+ baseToolNames: /* @__PURE__ */ new Set()
1348
+ };
1349
+ }
1200
1350
  const baseTools = await this.getAIEmployeeTools();
1201
1351
  const toolMap = await this.getToolsMap();
1202
1352
  const availableSkills = await this.getAvailableSkills();
@@ -1267,7 +1417,7 @@ If information is missing, clearly state it in the summary.</Important>`;
1267
1417
  return availableAIEmployees;
1268
1418
  }
1269
1419
  async getMiddleware(options) {
1270
- const { providerName, model, tools, baseToolNames, messageId, agentThread } = options;
1420
+ const { providerName, llmService, model, tools, baseToolNames, messageId, agentThread } = options;
1271
1421
  const inWorkflow = await this.isInWorkflow();
1272
1422
  return [
1273
1423
  (0, import_middleware.skillToolBindingMiddleware)(this, {
@@ -1276,7 +1426,7 @@ If information is missing, clearly state it in the summary.</Important>`;
1276
1426
  (0, import_middleware.toolInteractionMiddleware)(this, tools),
1277
1427
  (0, import_middleware.toolCallStatusMiddleware)(this),
1278
1428
  ...inWorkflow ? [(0, import_middleware.workflowHistoryMiddleware)(this, this.db)] : [],
1279
- (0, import_middleware.conversationMiddleware)(this, { providerName, model, messageId, agentThread })
1429
+ (0, import_middleware.conversationMiddleware)(this, { providerName, llmService, model, messageId, agentThread })
1280
1430
  ];
1281
1431
  }
1282
1432
  async getCurrentThread() {
@@ -1393,8 +1543,9 @@ class AgentThread {
1393
1543
  }
1394
1544
  }
1395
1545
  class ChatStreamProtocol {
1396
- constructor(streamConsumer) {
1546
+ constructor(streamConsumer, onWrite) {
1397
1547
  this.streamConsumer = streamConsumer;
1548
+ this.onWrite = onWrite;
1398
1549
  }
1399
1550
  _statistics = {
1400
1551
  sent: 0,
@@ -1405,43 +1556,45 @@ class ChatStreamProtocol {
1405
1556
  this._statistics.sent = 0;
1406
1557
  }
1407
1558
  };
1408
- static fromContext(ctx) {
1409
- return new ChatStreamProtocol(ctx.res);
1559
+ static fromContext(ctx, onWrite) {
1560
+ return new ChatStreamProtocol(ctx.res, onWrite);
1410
1561
  }
1411
1562
  with(conversation) {
1412
- const write = ({ type, body }) => {
1563
+ const write = async ({ type, body }) => {
1564
+ var _a;
1413
1565
  const { sessionId, from, username } = conversation;
1414
1566
  const data = `data: ${JSON.stringify({ sessionId, from, username, type, body })}
1415
1567
 
1416
1568
  `;
1569
+ await ((_a = this.onWrite) == null ? void 0 : _a.call(this, data));
1417
1570
  this.streamConsumer.write(data);
1418
1571
  this._statistics.addSent(data.length);
1419
1572
  };
1420
1573
  return {
1421
- startStream: () => {
1574
+ startStream: async () => {
1422
1575
  this._statistics.reset();
1423
- write({ type: "stream_start" });
1576
+ await write({ type: "stream_start" });
1424
1577
  },
1425
- endStream: () => {
1426
- write({ type: "stream_end" });
1578
+ endStream: async () => {
1579
+ await write({ type: "stream_end" });
1427
1580
  },
1428
- subAgentCompleted: () => {
1429
- write({ type: "sub_agent_completed" });
1581
+ subAgentCompleted: async () => {
1582
+ await write({ type: "sub_agent_completed" });
1430
1583
  },
1431
- newMessage: (content) => {
1432
- write({ type: "new_message", body: content });
1584
+ newMessage: async (content) => {
1585
+ await write({ type: "new_message", body: content });
1433
1586
  },
1434
- content: (content) => {
1435
- write({ type: "content", body: content });
1587
+ content: async (content) => {
1588
+ await write({ type: "content", body: content });
1436
1589
  },
1437
- webSearch: (content) => {
1438
- write({ type: "web_search", body: content });
1590
+ webSearch: async (content) => {
1591
+ await write({ type: "web_search", body: content });
1439
1592
  },
1440
- reasoning: (content) => {
1441
- write({ type: "reasoning", body: content });
1593
+ reasoning: async (content) => {
1594
+ await write({ type: "reasoning", body: content });
1442
1595
  },
1443
- stopReasoning: () => {
1444
- write({
1596
+ stopReasoning: async () => {
1597
+ await write({
1445
1598
  type: "reasoning",
1446
1599
  body: {
1447
1600
  status: "stop",
@@ -1449,13 +1602,13 @@ class ChatStreamProtocol {
1449
1602
  }
1450
1603
  });
1451
1604
  },
1452
- toolCallChunks: (content) => {
1453
- write({ type: "tool_call_chunks", body: content });
1605
+ toolCallChunks: async (content) => {
1606
+ await write({ type: "tool_call_chunks", body: content });
1454
1607
  },
1455
- toolCalls: (content) => {
1456
- write({ type: "tool_calls", body: content });
1608
+ toolCalls: async (content) => {
1609
+ await write({ type: "tool_calls", body: content });
1457
1610
  },
1458
- toolCallStatus: ({
1611
+ toolCallStatus: async ({
1459
1612
  toolCall,
1460
1613
  invokeStatus,
1461
1614
  status,
@@ -1464,7 +1617,7 @@ class ChatStreamProtocol {
1464
1617
  content,
1465
1618
  interruptAction
1466
1619
  }) => {
1467
- write({
1620
+ await write({
1468
1621
  type: "tool_call_status",
1469
1622
  body: {
1470
1623
  toolCall,
@@ -7,10 +7,14 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import PluginAIServer from '../plugin';
10
+ import type { Model } from '@nocobase/database';
11
+ import type { ModelRef } from './ai-employee';
10
12
  export declare class AIEmployeesManager {
11
13
  protected plugin: PluginAIServer;
12
14
  conversationController: Map<string, AbortController>;
13
15
  constructor(plugin: PluginAIServer);
16
+ getEmployee(username: string): Promise<Model | null>;
17
+ resolveModel(employee: Model, model?: ModelRef | null): Promise<ModelRef>;
14
18
  onAbortConversation(sessionId: string): boolean;
15
19
  abortConversation(sessionId: string): void;
16
20
  }
@@ -34,6 +34,47 @@ class AIEmployeesManager {
34
34
  this.plugin = plugin;
35
35
  }
36
36
  conversationController = /* @__PURE__ */ new Map();
37
+ async getEmployee(username) {
38
+ return await this.plugin.db.getRepository("aiEmployees").findOne({
39
+ filter: {
40
+ username
41
+ }
42
+ });
43
+ }
44
+ async resolveModel(employee, model) {
45
+ var _a;
46
+ const modelSettings = ((_a = employee.get) == null ? void 0 : _a.call(employee, "modelSettings")) || employee.modelSettings;
47
+ if (modelSettings == null ? void 0 : modelSettings.enabled) {
48
+ const models = Array.isArray(modelSettings.models) ? modelSettings.models : [];
49
+ const configuredModels = models.filter((item) => (item == null ? void 0 : item.llmService) && (item == null ? void 0 : item.model)).map((item) => ({
50
+ llmService: item.llmService,
51
+ model: item.model
52
+ }));
53
+ if (!configuredModels.length && modelSettings.llmService && modelSettings.model) {
54
+ configuredModels.push({
55
+ llmService: modelSettings.llmService,
56
+ model: modelSettings.model
57
+ });
58
+ }
59
+ if (!configuredModels.length) {
60
+ throw new Error("AI employee model not configured");
61
+ }
62
+ if ((model == null ? void 0 : model.llmService) && (model == null ? void 0 : model.model) && configuredModels.some((item) => item.llmService === model.llmService && item.model === model.model)) {
63
+ return model;
64
+ }
65
+ const firstModel = configuredModels[0];
66
+ if ((firstModel == null ? void 0 : firstModel.llmService) && (firstModel == null ? void 0 : firstModel.model)) {
67
+ return {
68
+ llmService: firstModel.llmService,
69
+ model: firstModel.model
70
+ };
71
+ }
72
+ }
73
+ if ((model == null ? void 0 : model.llmService) && (model == null ? void 0 : model.model)) {
74
+ return model;
75
+ }
76
+ return await this.plugin.aiManager.resolveModel();
77
+ }
37
78
  onAbortConversation(sessionId) {
38
79
  const controller = this.conversationController.get(sessionId);
39
80
  if (controller) {
@@ -86,8 +86,8 @@ class KnowledgeBaseManager {
86
86
  vectorStoreConfig.vectorStoreProvider,
87
87
  [
88
88
  {
89
- key: "vectorStoreConfigId",
90
- value: vectorStoreConfig.vectorStoreConfigId
89
+ key: "vectorStoreConfigKey",
90
+ value: vectorStoreConfig.vectorStoreConfigKey
91
91
  }
92
92
  ]
93
93
  );
@@ -107,8 +107,8 @@ class KnowledgeBaseManager {
107
107
  [
108
108
  ...knowledgeBase.vectorStoreProps,
109
109
  {
110
- key: "vectorStoreConfigId",
111
- value: vectorStoreConfig.vectorStoreConfigId
110
+ key: "vectorStoreConfigKey",
111
+ value: vectorStoreConfig.vectorStoreConfigKey
112
112
  }
113
113
  ]
114
114
  );
@@ -148,11 +148,11 @@ class KnowledgeBaseManager {
148
148
  };
149
149
  }
150
150
  async getKnowledgeBaseGroup(employee) {
151
- const { knowledgeBaseIds } = (employee == null ? void 0 : employee.knowledgeBase) ?? {};
152
- if (!knowledgeBaseIds || import_lodash.default.isEmpty(knowledgeBaseIds)) {
151
+ const { knowledgeBaseKeys } = (employee == null ? void 0 : employee.knowledgeBase) ?? {};
152
+ if (!knowledgeBaseKeys || import_lodash.default.isEmpty(knowledgeBaseKeys)) {
153
153
  return [];
154
154
  }
155
- return await this.plugin.features.knowledgeBase.getKnowledgeBaseGroup(knowledgeBaseIds);
155
+ return await this.plugin.features.knowledgeBase.getKnowledgeBaseGroup(knowledgeBaseKeys);
156
156
  }
157
157
  async getEmployee(username) {
158
158
  return await this.aiEmployeeRepo.findOne({ filter: { username } });
@@ -10,6 +10,7 @@ import { AIEmployee } from '../ai-employee';
10
10
  import z from 'zod';
11
11
  export declare const conversationMiddleware: (aiEmployee: AIEmployee, options: {
12
12
  providerName: string;
13
+ llmService?: string;
13
14
  model: string;
14
15
  messageId?: string;
15
16
  agentThread?: {