@nocobase/plugin-ai 2.1.0-alpha.33 → 2.1.0-alpha.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client-v2.d.ts +1 -0
- package/client-v2.js +1 -0
- package/dist/ai/docs/nocobase/ai/index.md +1 -1
- package/dist/ai/docs/nocobase/ai-employees/built-in/atlas.md +24 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/dara.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/dex.md +32 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/ellis.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/index.md +25 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/lexi.md +26 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/lina.md +142 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/nathan.md +36 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/vera.md +22 -0
- package/dist/ai/docs/nocobase/ai-employees/built-in/viz.md +25 -0
- package/dist/ai/docs/nocobase/ai-employees/features/built-in-employee.md +1 -29
- package/dist/ai/docs/nocobase/ai-employees/features/collaborate.md +17 -7
- package/dist/ai/docs/nocobase/ai-employees/features/enable-ai-employee.md +4 -4
- package/dist/ai/docs/nocobase/ai-employees/features/model-settings.md +87 -0
- package/dist/ai/docs/nocobase/ai-employees/index.md +1 -1
- package/dist/ai/docs/nocobase/ai-employees/scenarios/localization-hy-mt.md +241 -0
- package/dist/ai/docs/nocobase/ai-employees/workflow/nodes/employee/configuration.md +1 -1
- package/dist/ai/docs/nocobase/cluster-mode/index.md +5 -1
- package/dist/ai/docs/nocobase/cluster-mode/preparations.md +58 -3
- package/dist/ai/docs/nocobase/get-started/deployment/how-to-deploy-nocobase-faster.mdx +384 -0
- package/dist/ai/docs/nocobase/get-started/upgrading/docker.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/actions/types/js-action.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/actions/types/js-item.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/blocks/other-blocks/js-block.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-column.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-field.md +1 -1
- package/dist/ai/docs/nocobase/interface-builder/fields/specific/js-item.md +1 -1
- package/dist/ai/docs/nocobase/security/guide.md +13 -1
- package/dist/ai/docs/nocobase/system-management/localization/index.md +25 -1
- package/dist/client/119.c6bf8c6433167d81.js +10 -0
- package/dist/client/228.b4b709f93b86b6b9.js +10 -0
- package/dist/client/462.1708385b148779cd.js +10 -0
- package/dist/client/{486.afbed6b132b3c0dd.js → 486.dcac8f3fcec19c33.js} +1 -1
- package/dist/client/{559.39872901b9053629.js → 559.585f80c3bcea0bed.js} +1 -1
- package/dist/client/597.b0d64948d74cf6cb.js +10 -0
- package/dist/client/646.b0ed728921b007d4.js +10 -0
- package/dist/client/711.92cd94681fde7e05.js +10 -0
- package/dist/client/768.5177bff46ae71a5b.js +10 -0
- package/dist/client/792.abb57765453bcbcc.js +10 -0
- package/dist/client/820.f72ef2462b61d812.js +10 -0
- package/dist/client/927.d95c74ebb8fd51c9.js +10 -0
- package/dist/client/ai-employees/admin/ModelSettings.d.ts +10 -0
- package/dist/client/ai-employees/admin/hooks.d.ts +1 -1
- package/dist/client/ai-employees/avatars.d.ts +9 -783
- package/dist/client/ai-employees/chatbox/conversations/ConversationsList.d.ts +1 -15
- package/dist/client/ai-employees/chatbox/conversations/WorkflowTasksList.d.ts +1 -21
- package/dist/client/ai-employees/chatbox/hooks/useChat.d.ts +125 -0
- package/dist/client/ai-employees/chatbox/hooks/useChatBoxActions.d.ts +1 -1
- package/dist/client/ai-employees/chatbox/hooks/useChatConversationActions.d.ts +13 -1
- package/dist/client/ai-employees/chatbox/hooks/useChatMessageActions.d.ts +8 -8
- package/dist/client/ai-employees/chatbox/model.d.ts +6 -3
- package/dist/client/ai-employees/chatbox/stores/chat-conversations.d.ts +4 -0
- package/dist/client/ai-employees/chatbox/stores/chat-messages.d.ts +77 -50
- package/dist/client/ai-employees/chatbox/stores/chat-tool-call.d.ts +24 -16
- package/dist/client/ai-employees/types.d.ts +24 -0
- package/dist/client/features/vector-database-provider.d.ts +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +3 -3
- package/dist/client/llm-services/component/EnabledModelsSelect.d.ts +1 -14
- package/dist/client-v2/ai-employees/AIEmployeeShortcut.d.ts +21 -0
- package/dist/client-v2/ai-employees/ProfileCard.d.ts +17 -0
- package/dist/client-v2/ai-employees/avatars.d.ts +783 -0
- package/dist/client-v2/ai-employees/types.d.ts +20 -0
- package/dist/client-v2/index.d.ts +17 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/llm-services/model-label.d.ts +22 -0
- package/dist/collections/ai-employees.d.ts +2 -1
- package/dist/collections/ai-employees.js +1 -1
- package/dist/externalVersion.js +17 -16
- package/dist/locale/en-US.json +16 -1
- package/dist/locale/zh-CN.json +16 -1
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-conversations.d.ts +4 -1
- package/dist/server/ai-employees/ai-conversations.js +44 -4
- package/dist/server/ai-employees/ai-employee.d.ts +31 -15
- package/dist/server/ai-employees/ai-employee.js +205 -52
- package/dist/server/ai-employees/ai-employees-manager.d.ts +4 -0
- package/dist/server/ai-employees/ai-employees-manager.js +41 -0
- package/dist/server/ai-employees/ai-knowledge-base.js +7 -7
- package/dist/server/ai-employees/middleware/conversation.d.ts +1 -0
- package/dist/server/ai-employees/middleware/conversation.js +15 -11
- package/dist/server/ai-employees/sub-agents/dispatcher.js +2 -4
- package/dist/server/ai-employees/utils.d.ts +6 -3
- package/dist/server/ai-employees/utils.js +7 -1
- package/dist/server/collections/ai-conversations.js +6 -0
- package/dist/server/features/knowledge-base.d.ts +3 -2
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +3 -0
- package/dist/server/llm-providers/common/reasoning.d.ts +2 -0
- package/dist/server/llm-providers/common/reasoning.js +15 -2
- package/dist/server/llm-providers/dashscope.d.ts +2 -1
- package/dist/server/llm-providers/dashscope.js +39 -0
- package/dist/server/llm-providers/deepseek.js +2 -0
- package/dist/server/llm-providers/provider.d.ts +15 -1
- package/dist/server/llm-providers/provider.js +21 -2
- package/dist/server/manager/ai-chat-conversation.js +3 -4
- package/dist/server/manager/ai-manager.d.ts +17 -0
- package/dist/server/manager/ai-manager.js +65 -0
- package/dist/server/manager/llm-stream-manager.d.ts +43 -0
- package/dist/server/manager/llm-stream-manager.js +236 -0
- package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.d.ts +14 -0
- package/dist/server/migrations/20260407170416-ai-employee-knowledge-base-add-key.js +61 -0
- package/dist/server/plugin.d.ts +2 -0
- package/dist/server/plugin.js +3 -0
- package/dist/server/resource/ai.js +1 -41
- package/dist/server/resource/aiConversations.d.ts +14 -7
- package/dist/server/resource/aiConversations.js +236 -101
- package/dist/server/resource/aiEmployees.js +32 -1
- package/dist/server/types/knowledge-base.type.d.ts +3 -2
- package/dist/server/utils.d.ts +4 -0
- package/dist/server/utils.js +9 -0
- package/dist/server/workflow/nodes/employee/index.js +4 -2
- package/package.json +2 -2
- package/dist/client/119.78774f3ad953af49.js +0 -10
- package/dist/client/228.a3df2921c8beb766.js +0 -10
- package/dist/client/343.6f36d97dd122c5b6.js +0 -10
- package/dist/client/597.aa363881a325b5c0.js +0 -10
- package/dist/client/646.217a40387efbd163.js +0 -10
- package/dist/client/711.266b8f1c520d467a.js +0 -10
- package/dist/client/768.973ce32e15099a48.js +0 -10
- package/dist/client/792.2e48eab4767d662a.js +0 -10
- package/dist/client/820.6a26239ea96c075a.js +0 -10
- package/dist/client/927.ff5cd05b14901ae6.js +0 -10
|
@@ -40,8 +40,10 @@ __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");
|
|
46
|
+
var import_ai_chat_conversation = require("../manager/ai-chat-conversation");
|
|
45
47
|
async function getAIEmployee(ctx, username) {
|
|
46
48
|
var _a;
|
|
47
49
|
const filter = {
|
|
@@ -66,15 +68,52 @@ function setupSSEHeaders(ctx) {
|
|
|
66
68
|
function sendErrorResponse(ctx, errorMessage) {
|
|
67
69
|
(0, import_utils.sendSSEError)(ctx, errorMessage);
|
|
68
70
|
}
|
|
71
|
+
async function loginInCheck(ctx, next) {
|
|
72
|
+
var _a;
|
|
73
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
74
|
+
if (!userId) {
|
|
75
|
+
return ctx.throw(403);
|
|
76
|
+
}
|
|
77
|
+
await next();
|
|
78
|
+
}
|
|
79
|
+
const isReachParallelLimit = async (ctx) => {
|
|
80
|
+
var _a;
|
|
81
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
82
|
+
const activeStreamCount = await ctx.db.getModel("aiConversations").count({
|
|
83
|
+
where: {
|
|
84
|
+
userId,
|
|
85
|
+
llmActiveState: "streaming",
|
|
86
|
+
updatedAt: {
|
|
87
|
+
[import_database.Op.gte]: new Date(Date.now() - 10 * 60 * 1e3)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return activeStreamCount > 2;
|
|
92
|
+
};
|
|
93
|
+
const saveUserMessages = async (ctx, sessionId, messages, messageId) => {
|
|
94
|
+
const userMessages = messages.filter((message) => message.role === "user");
|
|
95
|
+
if (!userMessages.length) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const aiChatConversation = (0, import_ai_chat_conversation.createAIChatConversation)(ctx, sessionId);
|
|
99
|
+
await aiChatConversation.withTransaction(async (conversation) => {
|
|
100
|
+
if (messageId && await conversation.getMessage(messageId)) {
|
|
101
|
+
await conversation.removeMessages({ messageId });
|
|
102
|
+
}
|
|
103
|
+
await conversation.addMessages(userMessages);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
69
106
|
var aiConversations_default = {
|
|
70
107
|
name: "aiConversations",
|
|
108
|
+
middlewares: [
|
|
109
|
+
{
|
|
110
|
+
handler: loginInCheck
|
|
111
|
+
}
|
|
112
|
+
],
|
|
71
113
|
actions: {
|
|
72
114
|
async list(ctx, next) {
|
|
73
115
|
var _a;
|
|
74
116
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
75
|
-
if (!userId) {
|
|
76
|
-
return ctx.throw(403);
|
|
77
|
-
}
|
|
78
117
|
const filter = ctx.action.params.filter || {};
|
|
79
118
|
ctx.action.mergeParams({
|
|
80
119
|
filter: {
|
|
@@ -86,14 +125,52 @@ var aiConversations_default = {
|
|
|
86
125
|
});
|
|
87
126
|
return import_actions.default.list(ctx, next);
|
|
88
127
|
},
|
|
128
|
+
async unreadCount(ctx, next) {
|
|
129
|
+
var _a;
|
|
130
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
131
|
+
const count = await ctx.db.getModel("aiConversations").count({
|
|
132
|
+
where: {
|
|
133
|
+
userId,
|
|
134
|
+
read: false,
|
|
135
|
+
from: "main-agent",
|
|
136
|
+
category: "chat"
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
ctx.body = {
|
|
140
|
+
count
|
|
141
|
+
};
|
|
142
|
+
await next();
|
|
143
|
+
},
|
|
144
|
+
async unreadCounts(ctx, next) {
|
|
145
|
+
var _a;
|
|
146
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
147
|
+
const [conversationUnreadCount, workflowTaskUnreadCount] = await Promise.all([
|
|
148
|
+
ctx.db.getModel("aiConversations").count({
|
|
149
|
+
where: {
|
|
150
|
+
userId,
|
|
151
|
+
read: false,
|
|
152
|
+
from: "main-agent",
|
|
153
|
+
category: "chat"
|
|
154
|
+
}
|
|
155
|
+
}),
|
|
156
|
+
ctx.db.getModel("usersAiWorkflowTasks").count({
|
|
157
|
+
where: {
|
|
158
|
+
userId,
|
|
159
|
+
read: false
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
]);
|
|
163
|
+
ctx.body = {
|
|
164
|
+
conversationUnreadCount,
|
|
165
|
+
workflowTaskUnreadCount
|
|
166
|
+
};
|
|
167
|
+
await next();
|
|
168
|
+
},
|
|
89
169
|
async create(ctx, next) {
|
|
90
170
|
var _a;
|
|
91
171
|
const plugin = ctx.app.pm.get("ai");
|
|
92
172
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
93
|
-
|
|
94
|
-
return ctx.throw(403);
|
|
95
|
-
}
|
|
96
|
-
const { aiEmployee, systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
|
|
173
|
+
const { aiEmployee, systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
97
174
|
const employee = await getAIEmployee(ctx, aiEmployee.username);
|
|
98
175
|
if (!employee) {
|
|
99
176
|
ctx.throw(400, "AI employee not found");
|
|
@@ -105,7 +182,8 @@ var aiConversations_default = {
|
|
|
105
182
|
options: {
|
|
106
183
|
systemMessage,
|
|
107
184
|
skillSettings,
|
|
108
|
-
conversationSettings
|
|
185
|
+
conversationSettings,
|
|
186
|
+
modelSettings
|
|
109
187
|
}
|
|
110
188
|
});
|
|
111
189
|
} catch (error) {
|
|
@@ -120,9 +198,6 @@ var aiConversations_default = {
|
|
|
120
198
|
var _a;
|
|
121
199
|
const plugin = ctx.app.pm.get("ai");
|
|
122
200
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
123
|
-
if (!userId) {
|
|
124
|
-
return ctx.throw(403);
|
|
125
|
-
}
|
|
126
201
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
127
202
|
const { title } = ctx.action.params.values || {};
|
|
128
203
|
ctx.body = await plugin.aiConversationsManager.update({ userId, sessionId, title });
|
|
@@ -132,22 +207,19 @@ var aiConversations_default = {
|
|
|
132
207
|
var _a;
|
|
133
208
|
const plugin = ctx.app.pm.get("ai");
|
|
134
209
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
135
|
-
if (!userId) {
|
|
136
|
-
return ctx.throw(403);
|
|
137
|
-
}
|
|
138
210
|
const { filterByTk: sessionId } = ctx.action.params;
|
|
139
211
|
if (!sessionId) {
|
|
140
212
|
return ctx.throw(400, "invalid sessionId");
|
|
141
213
|
}
|
|
142
|
-
const { systemMessage, skillSettings, conversationSettings } = ctx.action.params.values || {};
|
|
143
|
-
if (!systemMessage && !skillSettings && !conversationSettings) {
|
|
214
|
+
const { systemMessage, skillSettings, conversationSettings, modelSettings } = ctx.action.params.values || {};
|
|
215
|
+
if (!systemMessage && !skillSettings && !conversationSettings && !modelSettings) {
|
|
144
216
|
return ctx.throw(400, "invalid options");
|
|
145
217
|
}
|
|
146
218
|
try {
|
|
147
219
|
ctx.body = await plugin.aiConversationsManager.update({
|
|
148
220
|
userId,
|
|
149
221
|
sessionId,
|
|
150
|
-
options: { systemMessage, skillSettings, conversationSettings }
|
|
222
|
+
options: { systemMessage, skillSettings, conversationSettings, modelSettings }
|
|
151
223
|
});
|
|
152
224
|
} catch (error) {
|
|
153
225
|
if (error.message === "invalid sessionId") {
|
|
@@ -160,9 +232,6 @@ var aiConversations_default = {
|
|
|
160
232
|
async destroy(ctx, next) {
|
|
161
233
|
var _a;
|
|
162
234
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
163
|
-
if (!userId) {
|
|
164
|
-
return ctx.throw(403);
|
|
165
|
-
}
|
|
166
235
|
ctx.action.mergeParams({
|
|
167
236
|
filter: {
|
|
168
237
|
userId
|
|
@@ -174,20 +243,19 @@ var aiConversations_default = {
|
|
|
174
243
|
var _a, _b;
|
|
175
244
|
const plugin = ctx.app.pm.get("ai");
|
|
176
245
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
177
|
-
|
|
178
|
-
return ctx.throw(403);
|
|
179
|
-
}
|
|
180
|
-
const { sessionId, cursor } = ctx.action.params || {};
|
|
246
|
+
const { sessionId, cursor, updateRead: originalUpdateRead } = ctx.action.params || {};
|
|
181
247
|
if (!sessionId) {
|
|
182
248
|
ctx.throw(400);
|
|
183
249
|
}
|
|
184
250
|
const paginate = ((_b = ctx.action.params) == null ? void 0 : _b.paginate) === "false" ? false : true;
|
|
251
|
+
const updateRead = originalUpdateRead === "true" || originalUpdateRead === true;
|
|
185
252
|
try {
|
|
186
253
|
ctx.body = await plugin.aiConversationsManager.getMessages({
|
|
187
254
|
userId,
|
|
188
255
|
sessionId,
|
|
189
256
|
cursor,
|
|
190
|
-
paginate
|
|
257
|
+
paginate,
|
|
258
|
+
updateRead
|
|
191
259
|
});
|
|
192
260
|
} catch (error) {
|
|
193
261
|
if (error.message === "invalid sessionId") {
|
|
@@ -201,9 +269,6 @@ var aiConversations_default = {
|
|
|
201
269
|
var _a;
|
|
202
270
|
const plugin = ctx.app.pm.get("ai");
|
|
203
271
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
204
|
-
if (!userId) {
|
|
205
|
-
return ctx.throw(403);
|
|
206
|
-
}
|
|
207
272
|
const {
|
|
208
273
|
sessionId,
|
|
209
274
|
messageId,
|
|
@@ -242,11 +307,8 @@ var aiConversations_default = {
|
|
|
242
307
|
},
|
|
243
308
|
async sendMessages(ctx, next) {
|
|
244
309
|
var _a, _b, _c, _d;
|
|
245
|
-
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
246
|
-
if (!userId) {
|
|
247
|
-
return ctx.throw(403);
|
|
248
|
-
}
|
|
249
310
|
const plugin = ctx.app.pm.get("ai");
|
|
311
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
250
312
|
const {
|
|
251
313
|
sessionId,
|
|
252
314
|
aiEmployee: employeeName,
|
|
@@ -260,38 +322,27 @@ var aiConversations_default = {
|
|
|
260
322
|
if (shouldStream) {
|
|
261
323
|
setupSSEHeaders(ctx);
|
|
262
324
|
}
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
} else {
|
|
267
|
-
ctx.status = 400;
|
|
268
|
-
ctx.body = { error: "sessionId is required" };
|
|
325
|
+
try {
|
|
326
|
+
if (!sessionId) {
|
|
327
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
269
328
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
} else {
|
|
277
|
-
ctx.status = 400;
|
|
278
|
-
ctx.body = { error: "user message is required" };
|
|
329
|
+
if (!Array.isArray(messages)) {
|
|
330
|
+
throw new import_utils.ResourceActionError(400, ctx.t("messages must be an array"));
|
|
331
|
+
}
|
|
332
|
+
const userMessage = messages.find((message) => message.role === "user");
|
|
333
|
+
if (!userMessage) {
|
|
334
|
+
throw new import_utils.ResourceActionError(400, ctx.t("user message is required"));
|
|
279
335
|
}
|
|
280
|
-
return next();
|
|
281
|
-
}
|
|
282
|
-
try {
|
|
283
336
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
284
337
|
sessionId,
|
|
285
338
|
userId
|
|
286
339
|
});
|
|
287
340
|
if (!conversation) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
return next();
|
|
341
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
342
|
+
}
|
|
343
|
+
const employee = await getAIEmployee(ctx, employeeName);
|
|
344
|
+
if (!employee) {
|
|
345
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
295
346
|
}
|
|
296
347
|
if (!conversation.title) {
|
|
297
348
|
const textUserMessage = messages.find(
|
|
@@ -306,17 +357,12 @@ var aiConversations_default = {
|
|
|
306
357
|
await conversation.save();
|
|
307
358
|
}
|
|
308
359
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
313
|
-
} else {
|
|
314
|
-
ctx.status = 404;
|
|
315
|
-
ctx.body = { error: "AI employee not found" };
|
|
316
|
-
}
|
|
317
|
-
return next();
|
|
360
|
+
if (await isReachParallelLimit(ctx)) {
|
|
361
|
+
await saveUserMessages(ctx, sessionId, messages, editingMessageId);
|
|
362
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
318
363
|
}
|
|
319
364
|
const legacy = conversation.thread === 0;
|
|
365
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
320
366
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
321
367
|
ctx,
|
|
322
368
|
employee,
|
|
@@ -325,7 +371,7 @@ var aiConversations_default = {
|
|
|
325
371
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
326
372
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
327
373
|
webSearch,
|
|
328
|
-
model,
|
|
374
|
+
model: resolvedModel,
|
|
329
375
|
legacy
|
|
330
376
|
});
|
|
331
377
|
if (!editingMessageId) {
|
|
@@ -363,11 +409,19 @@ var aiConversations_default = {
|
|
|
363
409
|
}
|
|
364
410
|
} catch (err) {
|
|
365
411
|
ctx.log.error(err);
|
|
412
|
+
let status = 500;
|
|
413
|
+
let message = ctx.t("Server unexpected error occur");
|
|
414
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
415
|
+
status = err.status;
|
|
416
|
+
message = err.message;
|
|
417
|
+
} else if (err instanceof Error) {
|
|
418
|
+
status = 500;
|
|
419
|
+
message = err.message;
|
|
420
|
+
}
|
|
366
421
|
if (shouldStream) {
|
|
367
|
-
sendErrorResponse(ctx,
|
|
422
|
+
sendErrorResponse(ctx, message);
|
|
368
423
|
} else {
|
|
369
|
-
ctx.status
|
|
370
|
-
ctx.body = { error: err.message || "Tool call error" };
|
|
424
|
+
ctx.throw(status, message);
|
|
371
425
|
}
|
|
372
426
|
} finally {
|
|
373
427
|
await next();
|
|
@@ -376,9 +430,6 @@ var aiConversations_default = {
|
|
|
376
430
|
async abort(ctx, next) {
|
|
377
431
|
var _a;
|
|
378
432
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
379
|
-
if (!userId) {
|
|
380
|
-
return ctx.throw(403);
|
|
381
|
-
}
|
|
382
433
|
const { sessionId } = ctx.action.params.values || {};
|
|
383
434
|
const plugin = ctx.app.pm.get("ai");
|
|
384
435
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
@@ -391,28 +442,99 @@ var aiConversations_default = {
|
|
|
391
442
|
plugin.aiEmployeesManager.abortConversation(sessionId);
|
|
392
443
|
await next();
|
|
393
444
|
},
|
|
394
|
-
async
|
|
395
|
-
var _a, _b, _c, _d;
|
|
445
|
+
async resumeStream(ctx, next) {
|
|
446
|
+
var _a, _b, _c, _d, _e;
|
|
396
447
|
const plugin = ctx.app.pm.get("ai");
|
|
397
448
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
449
|
+
const abortController = new AbortController();
|
|
450
|
+
const abortStream = () => abortController.abort();
|
|
451
|
+
const shouldStopStream = () => abortController.signal.aborted || ctx.res.destroyed || ctx.res.writableEnded;
|
|
401
452
|
setupSSEHeaders(ctx);
|
|
402
|
-
const
|
|
403
|
-
let { messageId } = ctx.action.params.values || {};
|
|
453
|
+
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);
|
|
404
454
|
if (!sessionId) {
|
|
405
455
|
sendErrorResponse(ctx, "sessionId is required");
|
|
406
|
-
return
|
|
456
|
+
return;
|
|
407
457
|
}
|
|
458
|
+
ctx.req.once("aborted", abortStream);
|
|
459
|
+
ctx.res.once("close", abortStream);
|
|
408
460
|
try {
|
|
409
461
|
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
410
462
|
sessionId,
|
|
411
463
|
userId
|
|
412
464
|
});
|
|
465
|
+
if (shouldStopStream()) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
413
468
|
if (!conversation) {
|
|
414
469
|
sendErrorResponse(ctx, "conversation not found");
|
|
415
|
-
return
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const reachLimit = await isReachParallelLimit(ctx);
|
|
473
|
+
if (shouldStopStream()) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
let hasChunks = false;
|
|
477
|
+
if (!reachLimit) {
|
|
478
|
+
for await (const chunk of plugin.llmStreamCachedManager.getCached(sessionId).stream({ signal: abortController.signal })) {
|
|
479
|
+
if (shouldStopStream()) {
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
hasChunks = true;
|
|
483
|
+
ctx.res.write(chunk);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (!hasChunks && !shouldStopStream()) {
|
|
487
|
+
const currentConversation = await plugin.aiConversationsManager.getConversation({
|
|
488
|
+
sessionId,
|
|
489
|
+
userId
|
|
490
|
+
});
|
|
491
|
+
const llmActiveState = currentConversation == null ? void 0 : currentConversation.llmActiveState;
|
|
492
|
+
if (llmActiveState && llmActiveState !== "idle") {
|
|
493
|
+
ctx.res.write(`data: ${JSON.stringify({ type: "chunks_cache_missing", body: { llmActiveState } })}
|
|
494
|
+
|
|
495
|
+
`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
} catch (err) {
|
|
499
|
+
if (shouldStopStream()) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
ctx.log.error(err);
|
|
503
|
+
sendErrorResponse(ctx, err.message || "Resume stream error");
|
|
504
|
+
return;
|
|
505
|
+
} finally {
|
|
506
|
+
ctx.req.off("aborted", abortStream);
|
|
507
|
+
ctx.res.off("close", abortStream);
|
|
508
|
+
if (!shouldStopStream()) {
|
|
509
|
+
ctx.res.end();
|
|
510
|
+
}
|
|
511
|
+
await next();
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
async resendMessages(ctx, next) {
|
|
515
|
+
var _a, _b, _c, _d;
|
|
516
|
+
const plugin = ctx.app.pm.get("ai");
|
|
517
|
+
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
518
|
+
const { sessionId, webSearch, model, stream = true } = ctx.action.params.values || {};
|
|
519
|
+
let { messageId } = ctx.action.params.values || {};
|
|
520
|
+
const shouldStream = stream !== false;
|
|
521
|
+
if (shouldStream) {
|
|
522
|
+
setupSSEHeaders(ctx);
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
if (!sessionId) {
|
|
526
|
+
throw new import_utils.ResourceActionError(400, ctx.t("sessionId is required"));
|
|
527
|
+
}
|
|
528
|
+
const conversation = await plugin.aiConversationsManager.getConversation({
|
|
529
|
+
sessionId,
|
|
530
|
+
userId
|
|
531
|
+
});
|
|
532
|
+
if (!conversation) {
|
|
533
|
+
throw new import_utils.ResourceActionError(400, ctx.t("conversation not found"));
|
|
534
|
+
}
|
|
535
|
+
const employee = await getAIEmployee(ctx, conversation.aiEmployeeUsername);
|
|
536
|
+
if (!employee) {
|
|
537
|
+
throw new import_utils.ResourceActionError(400, ctx.t("AI employee not found"));
|
|
416
538
|
}
|
|
417
539
|
const resendMessages = [];
|
|
418
540
|
if (messageId) {
|
|
@@ -422,8 +544,7 @@ var aiConversations_default = {
|
|
|
422
544
|
}
|
|
423
545
|
});
|
|
424
546
|
if (!message) {
|
|
425
|
-
|
|
426
|
-
return next();
|
|
547
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
427
548
|
}
|
|
428
549
|
} else {
|
|
429
550
|
const message = await ctx.db.getRepository("aiConversations.messages", sessionId).findOne({
|
|
@@ -433,8 +554,7 @@ var aiConversations_default = {
|
|
|
433
554
|
sort: ["-messageId"]
|
|
434
555
|
});
|
|
435
556
|
if (!message) {
|
|
436
|
-
|
|
437
|
-
return next();
|
|
557
|
+
throw new import_utils.ResourceActionError(400, ctx.t("message not found"));
|
|
438
558
|
}
|
|
439
559
|
messageId = message.messageId;
|
|
440
560
|
if (["user", "tool"].includes(message.role)) {
|
|
@@ -448,11 +568,10 @@ var aiConversations_default = {
|
|
|
448
568
|
});
|
|
449
569
|
}
|
|
450
570
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
sendErrorResponse(ctx, "AI employee not found");
|
|
454
|
-
return next();
|
|
571
|
+
if (await isReachParallelLimit(ctx)) {
|
|
572
|
+
throw new import_utils.ResourceActionError(400, ctx.t("There are conversations in progress. Please try again later."));
|
|
455
573
|
}
|
|
574
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
456
575
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
457
576
|
ctx,
|
|
458
577
|
employee,
|
|
@@ -461,22 +580,40 @@ var aiConversations_default = {
|
|
|
461
580
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
462
581
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
463
582
|
webSearch,
|
|
464
|
-
model
|
|
583
|
+
model: resolvedModel
|
|
465
584
|
});
|
|
466
|
-
|
|
585
|
+
if (shouldStream) {
|
|
586
|
+
await aiEmployee.stream({ messageId, userMessages: resendMessages.length ? resendMessages : void 0 });
|
|
587
|
+
} else {
|
|
588
|
+
ctx.body = await aiEmployee.invoke({
|
|
589
|
+
messageId,
|
|
590
|
+
userMessages: resendMessages.length ? resendMessages : void 0
|
|
591
|
+
});
|
|
592
|
+
}
|
|
467
593
|
} catch (err) {
|
|
468
594
|
ctx.log.error(err);
|
|
469
|
-
|
|
595
|
+
let status = 500;
|
|
596
|
+
let message = ctx.t("Server unexpected error occur");
|
|
597
|
+
if (err instanceof import_utils.ResourceActionError) {
|
|
598
|
+
status = err.status;
|
|
599
|
+
message = err.message;
|
|
600
|
+
} else if (err instanceof Error) {
|
|
601
|
+
status = 500;
|
|
602
|
+
message = err.message;
|
|
603
|
+
}
|
|
604
|
+
if (shouldStream) {
|
|
605
|
+
sendErrorResponse(ctx, message);
|
|
606
|
+
} else {
|
|
607
|
+
ctx.throw(status, message);
|
|
608
|
+
}
|
|
609
|
+
} finally {
|
|
610
|
+
await next();
|
|
470
611
|
}
|
|
471
|
-
await next();
|
|
472
612
|
},
|
|
473
613
|
async updateUserDecision(ctx, next) {
|
|
474
614
|
var _a;
|
|
475
615
|
const plugin = ctx.app.pm.get("ai");
|
|
476
616
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
477
|
-
if (!userId) {
|
|
478
|
-
return ctx.throw(403);
|
|
479
|
-
}
|
|
480
617
|
const { sessionId, messageId, toolCallId, userDecision } = ctx.action.params.values || {};
|
|
481
618
|
if (!sessionId) {
|
|
482
619
|
ctx.throw(400);
|
|
@@ -556,9 +693,6 @@ var aiConversations_default = {
|
|
|
556
693
|
async resumeToolCall(ctx, next) {
|
|
557
694
|
var _a, _b, _c, _d;
|
|
558
695
|
const userId = (_a = ctx.auth) == null ? void 0 : _a.user.id;
|
|
559
|
-
if (!userId) {
|
|
560
|
-
return ctx.throw(403);
|
|
561
|
-
}
|
|
562
696
|
setupSSEHeaders(ctx);
|
|
563
697
|
const plugin = ctx.app.pm.get("ai");
|
|
564
698
|
const { sessionId, messageId, model, webSearch } = ctx.action.params.values || {};
|
|
@@ -601,6 +735,7 @@ var aiConversations_default = {
|
|
|
601
735
|
sendErrorResponse(ctx, "No tool calls found");
|
|
602
736
|
return next();
|
|
603
737
|
}
|
|
738
|
+
const resolvedModel = await plugin.aiEmployeesManager.resolveModel(employee, model);
|
|
604
739
|
const aiEmployee = new import_ai_employee.AIEmployee({
|
|
605
740
|
ctx,
|
|
606
741
|
employee,
|
|
@@ -609,7 +744,7 @@ var aiConversations_default = {
|
|
|
609
744
|
skillSettings: (_c = conversation.options) == null ? void 0 : _c.skillSettings,
|
|
610
745
|
tools: (_d = conversation.options) == null ? void 0 : _d.tools,
|
|
611
746
|
webSearch,
|
|
612
|
-
model
|
|
747
|
+
model: resolvedModel
|
|
613
748
|
});
|
|
614
749
|
const userDecisions = await plugin.aiConversationsManager.getUserDecisions(messageId);
|
|
615
750
|
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
|
|
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
|
-
|
|
22
|
+
vectorStoreConfigKey?: string;
|
|
22
23
|
vectorStoreProps?: VectorStoreProp[];
|
|
23
24
|
enabled: boolean;
|
|
24
25
|
};
|
|
25
26
|
export type VectorStoreConfig = {
|
|
26
27
|
vectorStoreProvider: string;
|
|
27
|
-
|
|
28
|
+
vectorStoreConfigKey?: string;
|
|
28
29
|
};
|
|
29
30
|
export type KnowledgeBaseGroup = {
|
|
30
31
|
vectorStoreConfig: VectorStoreConfig;
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -21,3 +21,7 @@ export declare function encodeLocalFile(url: string): Promise<string>;
|
|
|
21
21
|
export declare function encodeFile(ctx: Context, url: string): Promise<string>;
|
|
22
22
|
export declare function parseVariables(ctx: Context, value: string): Promise<any>;
|
|
23
23
|
export declare const buildTool: (toolsEntry: ToolsEntry) => import("@langchain/core/dist/tools").DynamicTool<any>;
|
|
24
|
+
export declare class ResourceActionError extends Error {
|
|
25
|
+
readonly status: number;
|
|
26
|
+
constructor(status: number, message: string, options?: ErrorOptions);
|
|
27
|
+
}
|
package/dist/server/utils.js
CHANGED
|
@@ -36,6 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
37
|
var utils_exports = {};
|
|
38
38
|
__export(utils_exports, {
|
|
39
|
+
ResourceActionError: () => ResourceActionError,
|
|
39
40
|
buildTool: () => buildTool,
|
|
40
41
|
encodeFile: () => encodeFile,
|
|
41
42
|
encodeLocalFile: () => encodeLocalFile,
|
|
@@ -179,8 +180,16 @@ const buildTool = (toolsEntry) => {
|
|
|
179
180
|
}
|
|
180
181
|
);
|
|
181
182
|
};
|
|
183
|
+
class ResourceActionError extends Error {
|
|
184
|
+
constructor(status, message, options) {
|
|
185
|
+
super(message, options);
|
|
186
|
+
this.status = status;
|
|
187
|
+
this.name = "ResourceActionError";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
182
190
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
191
|
0 && (module.exports = {
|
|
192
|
+
ResourceActionError,
|
|
184
193
|
buildTool,
|
|
185
194
|
encodeFile,
|
|
186
195
|
encodeLocalFile,
|