@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
@@ -0,0 +1,142 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var llm_stream_manager_exports = {};
28
+ __export(llm_stream_manager_exports, {
29
+ LLMStreamCached: () => LLMStreamCached,
30
+ LLMStreamCachedManager: () => LLMStreamCachedManager
31
+ });
32
+ module.exports = __toCommonJS(llm_stream_manager_exports);
33
+ var import_utils = require("@nocobase/utils");
34
+ const CACHE_NAME = "ai-llm-stream-cache";
35
+ const LOCK_KEY_PREFIX = "ai-llm-stream-lock";
36
+ const WRITE_LOCK_TTL = 3e3;
37
+ const CACHE_TTL = 10 * 60 * 1e3;
38
+ const STREAM_END_MARK = '"type":"stream_end"';
39
+ const SKIPPED_MARK = "__skipped__";
40
+ const DEFAULT_POLL_INTERVAL = 50;
41
+ const DEFAULT_INITIAL_WAIT_TIMEOUT = 1e3;
42
+ class LLMStreamCachedManager {
43
+ constructor(plugin) {
44
+ this.plugin = plugin;
45
+ }
46
+ cachePromise;
47
+ getCached(sessionId) {
48
+ return new LLMStreamCached(sessionId, this);
49
+ }
50
+ async clear(sessionId) {
51
+ await this.withLock(sessionId, async () => {
52
+ const cache = await this.getCache();
53
+ await cache.del(sessionId);
54
+ });
55
+ }
56
+ async append(sessionId, chunk) {
57
+ await this.withLock(sessionId, async () => {
58
+ const cache = await this.getCache();
59
+ const chunks = await cache.get(sessionId) ?? [];
60
+ chunks.push(chunk);
61
+ await cache.set(sessionId, chunks, CACHE_TTL);
62
+ });
63
+ }
64
+ async *stream(sessionId, options) {
65
+ const pollInterval = (options == null ? void 0 : options.pollInterval) ?? DEFAULT_POLL_INTERVAL;
66
+ const initialWaitTimeout = (options == null ? void 0 : options.initialWaitTimeout) ?? DEFAULT_INITIAL_WAIT_TIMEOUT;
67
+ let offset = 0;
68
+ let waited = 0;
69
+ let completed = false;
70
+ while (!completed) {
71
+ const chunks = await this.getChunks(sessionId);
72
+ const lastSkippedIndex = chunks.lastIndexOf(SKIPPED_MARK);
73
+ if (lastSkippedIndex >= offset) {
74
+ offset = lastSkippedIndex + 1;
75
+ }
76
+ while (offset < chunks.length) {
77
+ const chunk = chunks[offset++];
78
+ yield chunk;
79
+ waited = 0;
80
+ if (chunk.includes(STREAM_END_MARK)) {
81
+ completed = true;
82
+ break;
83
+ }
84
+ }
85
+ if (completed) {
86
+ return;
87
+ }
88
+ if (!chunks.length) {
89
+ if (offset > 0) {
90
+ return;
91
+ }
92
+ if (waited >= initialWaitTimeout) {
93
+ return;
94
+ }
95
+ waited += pollInterval;
96
+ }
97
+ await (0, import_utils.sleep)(pollInterval);
98
+ }
99
+ }
100
+ async getChunks(sessionId) {
101
+ const cache = await this.getCache();
102
+ return await cache.get(sessionId) ?? [];
103
+ }
104
+ async getCache() {
105
+ this.cachePromise ??= this.plugin.app.cacheManager.createCache({
106
+ name: CACHE_NAME,
107
+ store: this.plugin.app.cacheManager.defaultStore
108
+ });
109
+ return this.cachePromise;
110
+ }
111
+ async withLock(sessionId, fn) {
112
+ return await this.plugin.app.lockManager.runExclusive(this.getLockKey(sessionId), fn, WRITE_LOCK_TTL);
113
+ }
114
+ getLockKey(sessionId) {
115
+ return `${LOCK_KEY_PREFIX}:${sessionId}`;
116
+ }
117
+ }
118
+ class LLMStreamCached {
119
+ constructor(sessionId, manager) {
120
+ this.sessionId = sessionId;
121
+ this.manager = manager;
122
+ }
123
+ async clear() {
124
+ await this.manager.clear(this.sessionId);
125
+ }
126
+ async append(chunk) {
127
+ await this.manager.append(this.sessionId, chunk);
128
+ }
129
+ async skipped() {
130
+ await this.append(SKIPPED_MARK);
131
+ }
132
+ async *stream(options) {
133
+ for await (const chunk of this.manager.stream(this.sessionId, options)) {
134
+ yield chunk;
135
+ }
136
+ }
137
+ }
138
+ // Annotate the CommonJS export names for ESM import in node:
139
+ 0 && (module.exports = {
140
+ LLMStreamCached,
141
+ LLMStreamCachedManager
142
+ });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Migration } from '@nocobase/server';
10
+ export default class extends Migration {
11
+ on: string;
12
+ appVersion: string;
13
+ up(): Promise<void>;
14
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var ai_employee_knowledge_base_add_key_exports = {};
28
+ __export(ai_employee_knowledge_base_add_key_exports, {
29
+ default: () => ai_employee_knowledge_base_add_key_default
30
+ });
31
+ module.exports = __toCommonJS(ai_employee_knowledge_base_add_key_exports);
32
+ var import_server = require("@nocobase/server");
33
+ class ai_employee_knowledge_base_add_key_default extends import_server.Migration {
34
+ on = "afterSync";
35
+ // 'beforeLoad' or 'afterLoad'
36
+ appVersion = "<2.1.0";
37
+ async up() {
38
+ var _a, _b, _c, _d;
39
+ const aiEmployeesRepo = this.app.db.getRepository("aiEmployees");
40
+ const aiEmployeeList = await aiEmployeesRepo.find();
41
+ for (const item of aiEmployeeList) {
42
+ if (!((_b = (_a = item.knowledgeBase) == null ? void 0 : _a.knowledgeBaseIds) == null ? void 0 : _b.length)) {
43
+ continue;
44
+ }
45
+ if ((_d = (_c = item.knowledgeBase) == null ? void 0 : _c.knowledgeBaseKeys) == null ? void 0 : _d.length) {
46
+ continue;
47
+ }
48
+ await aiEmployeesRepo.update({
49
+ values: {
50
+ knowledgeBase: {
51
+ ...item.knowledgeBase,
52
+ knowledgeBaseKeys: item.knowledgeBase.knowledgeBaseIds.map((it) => String(it))
53
+ }
54
+ },
55
+ filter: {
56
+ username: item.username
57
+ }
58
+ });
59
+ }
60
+ }
61
+ }
@@ -20,11 +20,13 @@ import { DocumentLoaders } from './document-loader';
20
20
  import type PluginFileManagerServer from '@nocobase/plugin-file-manager';
21
21
  import { SubAgentsDispatcher } from './ai-employees/sub-agents';
22
22
  import { KnowledgeBaseManager } from './ai-employees/ai-knowledge-base';
23
+ import { LLMStreamCachedManager } from './manager/llm-stream-manager';
23
24
  export declare class PluginAIServer extends Plugin {
24
25
  features: AIPluginFeatureManagerImpl;
25
26
  aiManager: AIManager;
26
27
  aiEmployeesManager: AIEmployeesManager;
27
28
  aiConversationsManager: AIConversationsManager;
29
+ llmStreamCachedManager: LLMStreamCachedManager;
28
30
  builtInManager: BuiltInManager;
29
31
  aiContextDatasourceManager: AIContextDatasourceManager;
30
32
  aiCodingManager: AICodingManager;
@@ -77,11 +77,13 @@ var import_mimo = require("./llm-providers/mimo");
77
77
  var import_sub_agents = require("./ai-employees/sub-agents");
78
78
  var import_employee = require("./workflow/nodes/employee");
79
79
  var import_ai_knowledge_base = require("./ai-employees/ai-knowledge-base");
80
+ var import_llm_stream_manager = require("./manager/llm-stream-manager");
80
81
  class PluginAIServer extends import_server.Plugin {
81
82
  features = new import_ai_feature_manager.AIPluginFeatureManagerImpl();
82
83
  aiManager = new import_ai_manager.AIManager(this);
83
84
  aiEmployeesManager = new import_ai_employees_manager.AIEmployeesManager(this);
84
85
  aiConversationsManager = new import_ai_conversations.AIConversationsManager(this);
86
+ llmStreamCachedManager = new import_llm_stream_manager.LLMStreamCachedManager(this);
85
87
  builtInManager = new import_built_in_manager.BuiltInManager(this);
86
88
  aiContextDatasourceManager = new import_ai_context_datasource_manager.AIContextDatasourceManager(this);
87
89
  aiCodingManager = new import_ai_coding_manager.AICodingManager(this);
@@ -135,6 +137,7 @@ class PluginAIServer extends import_server.Plugin {
135
137
  this.registerWorkflow();
136
138
  this.registerWorkContextResolveStrategy();
137
139
  (0, import_employee.registerAIEmployeeTaskNotification)(this);
140
+ (0, import_ai_conversations.registerAIConversationReadNotification)(this);
138
141
  (0, import_employee.registerOnJobAbortedHandler)(this);
139
142
  }
140
143
  registerLLMProviders() {
@@ -40,7 +40,6 @@ __export(ai_exports, {
40
40
  });
41
41
  module.exports = __toCommonJS(ai_exports);
42
42
  var import_lodash = __toESM(require("lodash"));
43
- var import_recommended_models = require("../../common/recommended-models");
44
43
  const aiResource = {
45
44
  name: "ai",
46
45
  actions: {
@@ -157,46 +156,7 @@ const aiResource = {
157
156
  },
158
157
  listAllEnabledModels: async (ctx, next) => {
159
158
  const plugin = ctx.app.pm.get("ai");
160
- const services = await ctx.db.getRepository("llmServices").find({ sort: "sort" });
161
- const llmServices = services.filter((service) => service.enabled !== false).map((service) => {
162
- const raw = service.enabledModels;
163
- let enabledModels;
164
- if (raw && typeof raw === "object" && !Array.isArray(raw) && raw.mode) {
165
- if (raw.mode === "recommended") {
166
- enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
167
- } else {
168
- enabledModels = (raw.models || []).filter((m) => m.value).map((m) => ({
169
- label: m.label || m.value,
170
- value: m.value
171
- }));
172
- }
173
- } else if (Array.isArray(raw)) {
174
- if (raw.length === 0) {
175
- enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
176
- } else {
177
- enabledModels = raw.map((id) => ({ label: id, value: id }));
178
- }
179
- } else {
180
- enabledModels = (0, import_recommended_models.getRecommendedModels)(service.provider);
181
- }
182
- if (enabledModels.length === 0) {
183
- return null;
184
- }
185
- const providerMeta = plugin.aiManager.llmProviders.get(service.provider);
186
- const P = providerMeta.provider;
187
- const p = new P({ app: ctx.app });
188
- const isToolConflict = p.isToolConflict();
189
- return {
190
- llmService: service.name,
191
- llmServiceTitle: service.title,
192
- provider: service.provider,
193
- providerTitle: providerMeta == null ? void 0 : providerMeta.title,
194
- enabledModels,
195
- supportWebSearch: (providerMeta == null ? void 0 : providerMeta.supportWebSearch) ?? false,
196
- isToolConflict
197
- };
198
- }).filter(Boolean);
199
- ctx.body = llmServices;
159
+ ctx.body = await plugin.aiManager.listAllEnabledModels();
200
160
  await next();
201
161
  }
202
162
  }
@@ -7,10 +7,17 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Context, Next } from '@nocobase/actions';
10
+ declare function parallelConversationsLimit(ctx: Context, next: Next): Promise<never>;
10
11
  declare const _default: {
11
12
  name: string;
13
+ middlewares: {
14
+ only: string[];
15
+ handler: typeof parallelConversationsLimit;
16
+ }[];
12
17
  actions: {
13
18
  list(ctx: Context, next: Next): Promise<void>;
19
+ unreadCount(ctx: Context, next: Next): Promise<never>;
20
+ unreadCounts(ctx: Context, next: Next): Promise<never>;
14
21
  create(ctx: Context, next: Next): Promise<never>;
15
22
  update(ctx: Context, next: Next): Promise<never>;
16
23
  updateOptions(ctx: Context, next: Next): Promise<never>;
@@ -19,6 +26,7 @@ declare const _default: {
19
26
  updateToolArgs(ctx: Context, next: Next): Promise<any>;
20
27
  sendMessages(ctx: Context, next: Next): Promise<any>;
21
28
  abort(ctx: Context, next: Next): Promise<never>;
29
+ resumeStream(ctx: Context, next: Next): Promise<never>;
22
30
  resendMessages(ctx: Context, next: Next): Promise<any>;
23
31
  updateUserDecision(ctx: Context, next: Next): Promise<never>;
24
32
  resumeToolCall(ctx: Context, next: Next): Promise<any>;
@@ -40,6 +40,7 @@ __export(aiConversations_exports, {
40
40
  });
41
41
  module.exports = __toCommonJS(aiConversations_exports);
42
42
  var import_actions = __toESM(require("@nocobase/actions"));
43
+ var import_database = require("@nocobase/database");
43
44
  var import_utils = require("../utils");
44
45
  var import_ai_employee = require("../ai-employees/ai-employee");
45
46
  async function getAIEmployee(ctx, username) {
@@ -66,8 +67,35 @@ function setupSSEHeaders(ctx) {
66
67
  function sendErrorResponse(ctx, errorMessage) {
67
68
  (0, import_utils.sendSSEError)(ctx, errorMessage);
68
69
  }
70
+ async function parallelConversationsLimit(ctx, next) {
71
+ var _a;
72
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
73
+ if (!userId) {
74
+ return ctx.throw(403);
75
+ }
76
+ const activeStreamCount = await ctx.db.getModel("aiConversations").count({
77
+ where: {
78
+ userId,
79
+ llmActiveState: "streaming",
80
+ updatedAt: {
81
+ [import_database.Op.gte]: new Date(Date.now() - 10 * 60 * 1e3)
82
+ }
83
+ }
84
+ });
85
+ if (activeStreamCount > 2) {
86
+ sendErrorResponse(ctx, ctx.t("There are conversations in progress. Please try again later."));
87
+ return;
88
+ }
89
+ await next();
90
+ }
69
91
  var aiConversations_default = {
70
92
  name: "aiConversations",
93
+ middlewares: [
94
+ {
95
+ only: ["sendMessages", "resendMessages", "resumeStream"],
96
+ handler: parallelConversationsLimit
97
+ }
98
+ ],
71
99
  actions: {
72
100
  async list(ctx, next) {
73
101
  var _a;
@@ -86,6 +114,53 @@ var aiConversations_default = {
86
114
  });
87
115
  return import_actions.default.list(ctx, next);
88
116
  },
117
+ async unreadCount(ctx, next) {
118
+ var _a;
119
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
120
+ if (!userId) {
121
+ return ctx.throw(403);
122
+ }
123
+ const count = await ctx.db.getModel("aiConversations").count({
124
+ where: {
125
+ userId,
126
+ read: false,
127
+ from: "main-agent",
128
+ category: "chat"
129
+ }
130
+ });
131
+ ctx.body = {
132
+ count
133
+ };
134
+ await next();
135
+ },
136
+ async unreadCounts(ctx, next) {
137
+ var _a;
138
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
139
+ if (!userId) {
140
+ return ctx.throw(403);
141
+ }
142
+ const [conversationUnreadCount, workflowTaskUnreadCount] = await Promise.all([
143
+ ctx.db.getModel("aiConversations").count({
144
+ where: {
145
+ userId,
146
+ read: false,
147
+ from: "main-agent",
148
+ category: "chat"
149
+ }
150
+ }),
151
+ ctx.db.getModel("usersAiWorkflowTasks").count({
152
+ where: {
153
+ userId,
154
+ read: false
155
+ }
156
+ })
157
+ ]);
158
+ ctx.body = {
159
+ conversationUnreadCount,
160
+ workflowTaskUnreadCount
161
+ };
162
+ await next();
163
+ },
89
164
  async create(ctx, next) {
90
165
  var _a;
91
166
  const plugin = ctx.app.pm.get("ai");
@@ -93,7 +168,7 @@ var aiConversations_default = {
93
168
  if (!userId) {
94
169
  return ctx.throw(403);
95
170
  }
96
- const { aiEmployee, systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
171
+ const { aiEmployee, systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
97
172
  const employee = await getAIEmployee(ctx, aiEmployee.username);
98
173
  if (!employee) {
99
174
  ctx.throw(400, "AI employee not found");
@@ -105,7 +180,8 @@ var aiConversations_default = {
105
180
  options: {
106
181
  systemMessage,
107
182
  skillSettings,
108
- conversationSettings
183
+ conversationSettings,
184
+ modelSettings
109
185
  }
110
186
  });
111
187
  } catch (error) {
@@ -139,15 +215,15 @@ var aiConversations_default = {
139
215
  if (!sessionId) {
140
216
  return ctx.throw(400, "invalid sessionId");
141
217
  }
142
- const { systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
143
- if (!systemMessage && !skillSettings && !conversationSettings) {
218
+ const { systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
219
+ if (!systemMessage && !skillSettings && !conversationSettings && !modelSettings) {
144
220
  return ctx.throw(400, "invalid options");
145
221
  }
146
222
  try {
147
223
  ctx.body = await plugin.aiConversationsManager.update({
148
224
  userId,
149
225
  sessionId,
150
- options: { systemMessage, skillSettings, conversationSettings }
226
+ options: { systemMessage, skillSettings, conversationSettings, modelSettings }
151
227
  });
152
228
  } catch (error) {
153
229
  if (error.message === "invalid sessionId") {
@@ -177,17 +253,19 @@ var aiConversations_default = {
177
253
  if (!userId) {
178
254
  return ctx.throw(403);
179
255
  }
180
- const { sessionId, cursor } = ctx.action.params || {};
256
+ const { sessionId, cursor, updateRead: originalUpdateRead } = ctx.action.params || {};
181
257
  if (!sessionId) {
182
258
  ctx.throw(400);
183
259
  }
184
260
  const paginate = ((_b = ctx.action.params) == null ? void 0 : _b.paginate) === "false" ? false : true;
261
+ const updateRead = originalUpdateRead === "true" || originalUpdateRead === true;
185
262
  try {
186
263
  ctx.body = await plugin.aiConversationsManager.getMessages({
187
264
  userId,
188
265
  sessionId,
189
266
  cursor,
190
- paginate
267
+ paginate,
268
+ updateRead
191
269
  });
192
270
  } catch (error) {
193
271
  if (error.message === "invalid sessionId") {
@@ -317,6 +395,7 @@ var aiConversations_default = {
317
395
  return next();
318
396
  }
319
397
  const legacy = conversation.thread === 0;
398
+ const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
320
399
  const aiEmployee = new import_ai_employee.AIEmployee({
321
400
  ctx,
322
401
  employee,
@@ -325,7 +404,7 @@ var aiConversations_default = {
325
404
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
326
405
  tools: (_d = conversation.options) == null ? void 0 : _d.tools,
327
406
  webSearch,
328
- model,
407
+ model: resolvedModel,
329
408
  legacy
330
409
  });
331
410
  if (!editingMessageId) {
@@ -391,6 +470,56 @@ var aiConversations_default = {
391
470
  plugin.aiEmployeesManager.abortConversation(sessionId);
392
471
  await next();
393
472
  },
473
+ async resumeStream(ctx, next) {
474
+ var _a, _b, _c, _d, _e;
475
+ const plugin = ctx.app.pm.get("ai");
476
+ const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
477
+ if (!userId) {
478
+ return ctx.throw(403);
479
+ }
480
+ setupSSEHeaders(ctx);
481
+ const sessionId = ((_b = ctx.action.params) == null ? void 0 : _b.sessionId) || ((_d = (_c = ctx.action.params) == null ? void 0 : _c.values) == null ? void 0 : _d.sessionId) || ((_e = ctx.action.params) == null ? void 0 : _e.filterByTk);
482
+ if (!sessionId) {
483
+ sendErrorResponse(ctx, "sessionId is required");
484
+ return;
485
+ }
486
+ try {
487
+ const conversation = await plugin.aiConversationsManager.getConversation({
488
+ sessionId,
489
+ userId
490
+ });
491
+ if (!conversation) {
492
+ sendErrorResponse(ctx, "conversation not found");
493
+ return;
494
+ }
495
+ let hasChunks = false;
496
+ for await (const chunk of plugin.llmStreamCachedManager.getCached(sessionId).stream()) {
497
+ hasChunks = true;
498
+ ctx.res.write(chunk);
499
+ }
500
+ if (!hasChunks) {
501
+ const currentConversation = await plugin.aiConversationsManager.getConversation({
502
+ sessionId,
503
+ userId
504
+ });
505
+ const llmActiveState = currentConversation == null ? void 0 : currentConversation.llmActiveState;
506
+ if (llmActiveState && llmActiveState !== "idle") {
507
+ ctx.res.write(`data: ${JSON.stringify({ type: "chunks_cache_missing", body: { llmActiveState } })}
508
+
509
+ `);
510
+ }
511
+ }
512
+ } catch (err) {
513
+ ctx.log.error(err);
514
+ sendErrorResponse(ctx, err.message || "Resume stream error");
515
+ return;
516
+ } finally {
517
+ if (!ctx.res.writableEnded) {
518
+ ctx.res.end();
519
+ }
520
+ await next();
521
+ }
522
+ },
394
523
  async resendMessages(ctx, next) {
395
524
  var _a, _b, _c, _d;
396
525
  const plugin = ctx.app.pm.get("ai");
@@ -453,6 +582,7 @@ var aiConversations_default = {
453
582
  sendErrorResponse(ctx, "AI employee not found");
454
583
  return next();
455
584
  }
585
+ const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
456
586
  const aiEmployee = new import_ai_employee.AIEmployee({
457
587
  ctx,
458
588
  employee,
@@ -461,7 +591,7 @@ var aiConversations_default = {
461
591
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
462
592
  tools: (_d = conversation.options) == null ? void 0 : _d.tools,
463
593
  webSearch,
464
- model
594
+ model: resolvedModel
465
595
  });
466
596
  await aiEmployee.stream({ messageId, userMessages: resendMessages.length ? resendMessages : void 0 });
467
597
  } catch (err) {
@@ -601,6 +731,7 @@ var aiConversations_default = {
601
731
  sendErrorResponse(ctx, "No tool calls found");
602
732
  return next();
603
733
  }
734
+ const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
604
735
  const aiEmployee = new import_ai_employee.AIEmployee({
605
736
  ctx,
606
737
  employee,
@@ -609,7 +740,7 @@ var aiConversations_default = {
609
740
  skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
610
741
  tools: (_d = conversation.options) == null ? void 0 : _d.tools,
611
742
  webSearch,
612
- model
743
+ model: resolvedModel
613
744
  });
614
745
  const userDecisions = await plugin.aiConversationsManager.getUserDecisions(messageId);
615
746
  await aiEmployee.stream({
@@ -45,7 +45,9 @@ module.exports = __toCommonJS(aiEmployees_exports);
45
45
  var import_actions = __toESM(require("@nocobase/actions"));
46
46
  var templates = __toESM(require("../ai-employees/templates"));
47
47
  var import_lodash = __toESM(require("lodash"));
48
+ var import_ai_feature_manager = require("../manager/ai-feature-manager");
48
49
  const list = async (ctx, next) => {
50
+ var _a, _b;
49
51
  const { paginate } = ctx.action.params || {};
50
52
  const plugin = ctx.app.pm.get("ai");
51
53
  const builtInManager = plugin.builtInManager;
@@ -58,9 +60,36 @@ const list = async (ctx, next) => {
58
60
  });
59
61
  await import_actions.default.list(ctx, () => {
60
62
  });
61
- let data = ctx.body.rows;
63
+ let data;
62
64
  if (paginate === "false" || paginate === false) {
65
+ ctx.body = ctx.body.map((it) => it.toJSON());
63
66
  data = ctx.body;
67
+ } else {
68
+ ctx.body.rows = ctx.body.rows.map((it) => it.toJSON());
69
+ data = ctx.body.rows;
70
+ }
71
+ const featureEnabled = plugin.features.isFeaturesEnabled(Object.values(import_ai_feature_manager.EEFeatures));
72
+ if (featureEnabled) {
73
+ const knowledgeBaseKeys = import_lodash.default.uniq(
74
+ data.map((it) => {
75
+ var _a2;
76
+ return ((_a2 = it.knowledgeBase) == null ? void 0 : _a2.knowledgeBaseKeys) ?? [];
77
+ }).flatMap((it) => it)
78
+ );
79
+ const knowledgeBaseList = await plugin.features.knowledgeBase.getKnowledgeBase(knowledgeBaseKeys);
80
+ const existedKnowledgeBaseKeys = (knowledgeBaseList == null ? void 0 : knowledgeBaseList.map((it) => it.key)) ?? [];
81
+ for (const row of data) {
82
+ row.missingKnowledgeBaseKeys = [];
83
+ if (!((_b = (_a = row.knowledgeBase) == null ? void 0 : _a.knowledgeBaseKeys) == null ? void 0 : _b.length)) {
84
+ continue;
85
+ }
86
+ for (const k of row.knowledgeBase.knowledgeBaseKeys) {
87
+ if (existedKnowledgeBaseKeys.includes(k)) {
88
+ continue;
89
+ }
90
+ row.missingKnowledgeBaseKeys.push(k);
91
+ }
92
+ }
64
93
  }
65
94
  data.forEach((row) => {
66
95
  if (row.builtIn) {
@@ -153,6 +182,8 @@ const listByUser = async (ctx, next) => {
153
182
  prompt: (_b = (_a = row.userConfigs) == null ? void 0 : _a[0]) == null ? void 0 : _b.prompt
154
183
  },
155
184
  skillSettings,
185
+ chatSettings: row.chatSettings,
186
+ modelSettings: row.modelSettings,
156
187
  builtIn: row.builtIn,
157
188
  category: row.category,
158
189
  deprecated: row.deprecated
@@ -15,16 +15,17 @@ export type VectorStoreProp = {
15
15
  export type KnowledgeBase = {
16
16
  knowledgeBaseType: KnowledgeBaseType;
17
17
  knowledgeBaseOuterId: string;
18
+ key: string;
18
19
  name: string;
19
20
  description: string;
20
21
  vectorStoreProvider: string;
21
- vectorStoreConfigId?: string;
22
+ vectorStoreConfigKey?: string;
22
23
  vectorStoreProps?: VectorStoreProp[];
23
24
  enabled: boolean;
24
25
  };
25
26
  export type VectorStoreConfig = {
26
27
  vectorStoreProvider: string;
27
- vectorStoreConfigId?: string;
28
+ vectorStoreConfigKey?: string;
28
29
  };
29
30
  export type KnowledgeBaseGroup = {
30
31
  vectorStoreConfig: VectorStoreConfig;